xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/algos/aldch/rk_aiq_ldch_generate_mesh.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * rk_aiq_ldch_generate_mesh.cpp
3  *
4  *  Copyright (c) 2019 Rockchip Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 
20 #include "xcam_log.h"
21 #include "rk_aiq_ldch_generate_mesh.h"
22 
23 #define LDCH_CUSTOM_MESH "ldch_custom_mesh.bin"
24 
25 RKAIQ_BEGIN_DECLARE
26 
27 
alloc_ldch_buf(LDCHContext_t * ldchCtx)28 static XCamReturn alloc_ldch_buf(LDCHContext_t* ldchCtx)
29 {
30     if (!ldchCtx->hasAllocShareMem.load(std::memory_order_acquire)) {
31         LOGD_ALDCH("alloc ldch buf");
32         release_ldch_buf(ldchCtx);
33         rk_aiq_share_mem_config_t share_mem_config;
34         share_mem_config.alloc_param.width =  ldchCtx->dst_width;
35         share_mem_config.alloc_param.height = ldchCtx->dst_height;
36         share_mem_config.mem_type = MEM_TYPE_LDCH;
37         ldchCtx->share_mem_ops->alloc_mem(0, ldchCtx->share_mem_ops,
38                 &share_mem_config,
39                 &ldchCtx->share_mem_ctx);
40         if (ldchCtx->share_mem_ctx) {
41             ldchCtx->hasAllocShareMem.store(true, std::memory_order_release);
42         } else {
43             LOGE_ALDCH("Failed to alloc shared mem");
44             return XCAM_RETURN_ERROR_MEM;
45         }
46     }
47 
48     return XCAM_RETURN_NO_ERROR;
49 }
50 
release_ldch_buf(LDCHContext_t * ldchCtx)51 XCamReturn release_ldch_buf(LDCHContext_t* ldchCtx)
52 {
53     if (ldchCtx->hasAllocShareMem.load(std::memory_order_acquire)) {
54         LOGD_ALDCH("release ldch buf");
55         if (ldchCtx->share_mem_ctx)
56             ldchCtx->share_mem_ops->release_mem(0, ldchCtx->share_mem_ctx);
57         ldchCtx->hasAllocShareMem.store(false, std::memory_order_release);
58     }
59 
60     return XCAM_RETURN_NO_ERROR;
61 }
62 
get_ldch_buf(LDCHContext_t * ldchCtx)63 XCamReturn get_ldch_buf(LDCHContext_t* ldchCtx)
64 {
65     if (alloc_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
66         LOGE_ALDCH("Failed to alloc ldch buf\n");
67         return XCAM_RETURN_ERROR_MEM;
68     }
69 
70     ldchCtx->ldch_mem_info = (rk_aiq_ldch_share_mem_info_t *)
71             ldchCtx->share_mem_ops->get_free_item(0, ldchCtx->share_mem_ctx);
72     if (ldchCtx->ldch_mem_info == NULL || \
73         (ldchCtx->ldch_mem_info && \
74          ldchCtx->ldch_mem_info->state[0] != MESH_BUF_INIT)) {
75         LOGE_ALDCH("%s: no free ldch buf", __FUNCTION__);
76         return XCAM_RETURN_ERROR_MEM;
77     }
78     ldchCtx->ldch_mem_info->state[0] = MESH_BUF_WAIT2CHIP; //mark that this buf is using.
79 
80     LOGD_ALDCH("LDCH get buf: fd %d, addr %p, size %d",
81             ldchCtx->ldch_mem_info->fd,
82             ldchCtx->ldch_mem_info->addr,
83             ldchCtx->ldch_mem_info->size);
84 
85     return XCAM_RETURN_NO_ERROR;
86 }
87 
put_ldch_buf(LDCHContext_t * ldchCtx)88 void put_ldch_buf(LDCHContext_t* ldchCtx)
89 {
90     if (ldchCtx->ldch_mem_info && ldchCtx->ldch_mem_info->state[0] == MESH_BUF_WAIT2CHIP) {
91         ldchCtx->ldch_mem_info->state[0] = MESH_BUF_INIT;
92         LOGD_ALDCH("LDCH put buf: fd %d, addr %p, size %d",
93                 ldchCtx->ldch_mem_info->fd,
94                 ldchCtx->ldch_mem_info->addr,
95                 ldchCtx->ldch_mem_info->size);
96 
97         ldchCtx->ldch_mem_info = NULL;
98     }
99 }
100 
101 bool
read_mesh_from_file(LDCHContext_t * ldchCtx,const char * fileName)102 read_mesh_from_file(LDCHContext_t* ldchCtx, const char* fileName)
103 {
104     FILE* ofp;
105     ofp = fopen(fileName, "rb");
106     if (ofp != NULL) {
107         unsigned short hpic, vpic, hsize, vsize, hstep, vstep = 0;
108         uint32_t lut_size = 0;
109 
110         fread(&hpic, sizeof(unsigned short), 1, ofp);
111         fread(&vpic, sizeof(unsigned short), 1, ofp);
112         fread(&hsize, sizeof(unsigned short), 1, ofp);
113         fread(&vsize, sizeof(unsigned short), 1, ofp);
114         fread(&hstep, sizeof(unsigned short), 1, ofp);
115         fread(&vstep, sizeof(unsigned short), 1, ofp);
116 
117         lut_size = hsize * vsize *  sizeof(uint16_t);
118         LOGW_ALDCH("lut info: [%d-%d-%d-%d-%d-%d]", hpic, vpic, hsize, vsize, hstep, vstep);
119         unsigned int num = fread(ldchCtx->ldch_mem_info->addr, 1, lut_size, ofp);
120         fclose(ofp);
121 
122         if (num != lut_size) {
123             LOGE_ALDCH("mismatched lut calib file");
124             return false;
125         }
126 
127         if (ldchCtx->src_width != hpic || ldchCtx->src_height != vpic) {
128             LOGE_ALDCH("mismatched lut pic resolution: src %dx%d, lut %dx%d",
129                     ldchCtx->src_width, ldchCtx->src_height, hpic, vpic);
130             return false;
131         }
132 
133         ldchCtx->lut_h_size = hsize;
134         ldchCtx->lut_v_size = vsize;
135         ldchCtx->lut_mapxy_size = lut_size;
136         ldchCtx->lut_h_size = hsize / 2; //word unit
137 
138         LOGW_ALDCH("check file, size: %d, num: %d", ldchCtx->lut_mapxy_size, num);
139     } else {
140         LOGE_ALDCH("lut file %s not exist", fileName);
141         return false;
142     }
143 
144     return true;
145 }
146 
147 
148 #if GENMESH_ONLINE
aiqGenLdchMeshInit(LDCHContext_t * ldchCtx)149 XCamReturn aiqGenLdchMeshInit(LDCHContext_t* ldchCtx)
150 {
151     XCamReturn ret = XCAM_RETURN_NO_ERROR;
152 
153     if (ldchCtx->genLdchMeshInit) {
154         LOGW_ALDCH("genLDCHMesh has been initialized!!\n");
155         if (get_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
156             LOGE_ALDCH("Failed to get ldch buf\n");
157             return XCAM_RETURN_ERROR_MEM;
158         }
159         return XCAM_RETURN_NO_ERROR;
160     }
161 
162     ldchCtx->ldchParams.isLdchOld = 1;
163     ldchCtx->ldchParams.saveMeshX = false;
164     if (ldchCtx->ldchParams.saveMeshX) {
165         sprintf(ldchCtx->ldchParams.meshPath, "/tmp/");
166     }
167 	genLdchMeshInit(ldchCtx->src_width, ldchCtx->src_height,
168                     ldchCtx->dst_width, ldchCtx->dst_height,
169                     ldchCtx->ldchParams, ldchCtx->camCoeff);
170 
171     ldchCtx->lut_h_size = (ldchCtx->ldchParams.meshSizeW + 1) / 2; //word unit
172     ldchCtx->lut_v_size = ldchCtx->ldchParams.meshSizeH;
173     ldchCtx->lut_mapxy_size = ldchCtx->ldchParams.meshSize * sizeof(unsigned short);
174     LOGI_ALDCH("ldch en %d, h/v size(%dx%d), mapxy size(%d), correct_level: %d",
175                ldchCtx->ldch_en,
176                ldchCtx->lut_h_size,
177                ldchCtx->lut_v_size,
178                ldchCtx->lut_mapxy_size ,
179                ldchCtx->correct_level);
180 
181     if (get_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
182         LOGE_ALDCH("Failed to get ldch buf\n");
183         ret = XCAM_RETURN_ERROR_MEM;
184     }
185 
186     ldchCtx->genLdchMeshInit = true;
187 
188     return ret;
189 }
190 
aiqGenLdchMeshDeInit(LDCHContext_t * ldchCtx)191 XCamReturn aiqGenLdchMeshDeInit(LDCHContext_t* ldchCtx)
192 {
193     if (!ldchCtx->genLdchMeshInit) {
194         return XCAM_RETURN_NO_ERROR;
195     }
196 
197 	genLdchMeshDeInit(ldchCtx->ldchParams);
198     release_ldch_buf(ldchCtx);
199 
200     ldchCtx->genLdchMeshInit = false;
201 
202     return XCAM_RETURN_NO_ERROR;
203 }
204 
aiqGenMesh(LDCHContext_t * ldchCtx,int32_t level)205 bool aiqGenMesh(LDCHContext_t* ldchCtx, int32_t level)
206 {
207     bool success = false;
208 
209     if (level == 0) {
210         char filename[512];
211         sprintf(filename, "%s/%s",
212                 ldchCtx->resource_path,
213                 LDCH_CUSTOM_MESH);
214         success = read_mesh_from_file(ldchCtx, filename);
215         if (success) {
216             LOGW_ALDCH("read mesh from %s", filename);
217         }
218     }
219 
220     if (!success && ldchCtx->ldch_mem_info)
221         success = genLDCMeshNLevel(ldchCtx->ldchParams, ldchCtx->camCoeff,
222                                    level, (uint16_t *)ldchCtx->ldch_mem_info->addr);
223 
224     return success;
225 }
226 #endif
227 
228 RKAIQ_END_DECLARE
229