xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/algos/aldch/rk_aiq_algo_aldch_v21_itf.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * rk_aiq_algo_aldch_itf.c
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 "aldch/rk_aiq_algo_aldch_itf.h"
21 #include "aldch/rk_aiq_types_aldch_algo_prvt.h"
22 #include "rk_aiq_algo_types.h"
23 #include "RkAiqCalibDbV2Helper.h"
24 #include "xcam_log.h"
25 #include "rk_aiq_ldch_generate_mesh.h"
26 #include "aldch/rk_aiq_uapi_aldch_v21_int.h"
27 
28 
29 RKAIQ_BEGIN_DECLARE
30 
31 static const uint8_t default_bic_table[9][4] = {
32     {0x00, 0x80, 0x00, 0x00}, // table0: 0, 0, 128, 0
33     {0xfc, 0x7f, 0x05, 0x00}, // table1: 0, 5, 127, -4
34     {0xfa, 0x7b, 0x0c, 0xff}, // table2: -1, 12, 123, -6
35     {0xf8, 0x76, 0x14, 0xfe}, // table3: -2, 20, 118, -8
36     {0xf7, 0x6f, 0x1d, 0xfd}, // table4: -3, 29, 111, -9
37     {0xf7, 0x66, 0x27, 0xfc}, // table4: -4, 39, 102, -9
38     {0xf7, 0x5d, 0x32, 0xfa}, // table4: -6, 50, 93, -9
39     {0xf7, 0x53, 0x3d, 0xf9}, // table4: -7, 61, 83, -9
40     {0xf8, 0x48, 0x48, 0xf8}, // table4: -8, 72, 72, -8
41 };
42 
43 static XCamReturn
updateCalibConfig(RkAiqAlgoCom * params)44 updateCalibConfig(RkAiqAlgoCom* params)
45 {
46     LDCHHandle_t hLDCH = (LDCHHandle_t)params->ctx->hLDCH;
47     LDCHContext_t* ldchCtx = (LDCHContext_t*)hLDCH;
48     RkAiqAlgoConfigAldch* rkaiqAldchConfig = (RkAiqAlgoConfigAldch*)params;
49 
50     CalibDbV2_LDCH_t* calib_ldch_db =
51         (CalibDbV2_LDCH_t*)(CALIBDBV2_GET_MODULE_PTR(rkaiqAldchConfig->com.u.prepare.calibv2, aldch));
52     CalibDbV2_Ldch_Param_t* calib_ldch = &calib_ldch_db->param;
53 
54     ldchCtx->camCoeff.cx = calib_ldch->light_center[0];
55     ldchCtx->camCoeff.cy = calib_ldch->light_center[1];
56     ldchCtx->camCoeff.a0 = calib_ldch->coefficient[0];
57     ldchCtx->camCoeff.a2 = calib_ldch->coefficient[1];
58     ldchCtx->camCoeff.a3 = calib_ldch->coefficient[2];
59     ldchCtx->camCoeff.a4 = calib_ldch->coefficient[3];
60     memcpy(ldchCtx->meshfile, calib_ldch->meshfile, sizeof(ldchCtx->meshfile));
61 
62     if (calib_ldch->ldch_en) {
63         if ((!ldchCtx->ldch_en || calib_ldch->correct_level != hLDCH->correct_level) && \
64             ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_ON_LINE) {
65             if (aiqGenLdchMeshInit(hLDCH) != XCAM_RETURN_NO_ERROR) {
66                 LOGE_ALDCH("Failed to init gen mesh");
67                 return XCAM_RETURN_ERROR_FAILED;
68             }
69 
70             bool success = aiqGenMesh(hLDCH, calib_ldch->correct_level);
71             if (!success) {
72                 LOGE_ALDCH("lut is not exist");
73                 put_ldch_buf(hLDCH);
74                 return XCAM_RETURN_ERROR_PARAM;
75             }
76 
77             if (ldchCtx->ldch_mem_info)
78                 hLDCH->ready_lut_mem_fd = ldchCtx->ldch_mem_info->fd;
79 
80             ldchCtx->isLutUpdated.store(true, std::memory_order_release);
81         }
82     }
83 
84     ldchCtx->user_config.en =  calib_ldch->ldch_en;
85     ldchCtx->user_config.correct_level = calib_ldch->correct_level;
86 
87 
88     LOGI_ALDCH("update calib en(%d), level(%d-%d), coeff(%f, %f, %f, %f, %f, %f)",
89             calib_ldch->ldch_en,
90             calib_ldch->correct_level,
91             calib_ldch->correct_level_max,
92             calib_ldch->light_center[0],
93             calib_ldch->light_center[1],
94             calib_ldch->coefficient[0],
95             calib_ldch->coefficient[1],
96             calib_ldch->coefficient[2],
97             calib_ldch->coefficient[3]);
98 
99     return XCAM_RETURN_NO_ERROR;
100 }
101 
update_custom_lut_from_file(LDCHContext_t * ldchCtx)102 static XCamReturn update_custom_lut_from_file(LDCHContext_t* ldchCtx)
103 {
104     XCamReturn ret = XCAM_RETURN_NO_ERROR;
105 
106     if (get_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
107         LOGE_ALDCH("Failed to get ldch buf\n");
108         ret = XCAM_RETURN_ERROR_MEM;
109     } else {
110         rk_aiq_ldch_lut_external_file_t *lut = &ldchCtx->user_config.lut.u.file;
111 
112         char filename[200] = {0};
113         sprintf(filename, "%s/%s",
114                 lut->config_file_dir,
115                 lut->mesh_file_name);
116 
117         LOGD_ALDCH("read lut file name: %s/%s\n",
118                 lut->config_file_dir,
119                 lut->mesh_file_name);
120 
121         bool ret1 = read_mesh_from_file(ldchCtx, filename);
122         if (!ret1) {
123             LOGE_ALDCH("Failed to read mesh, disable ldch!");
124             ldchCtx->ldch_en = ldchCtx->user_config.en = false;
125             put_ldch_buf(ldchCtx);
126             ret = XCAM_RETURN_ERROR_FILE;
127         } else {
128             uint16_t *addr = (uint16_t *)ldchCtx->ldch_mem_info->addr;
129             LOGD_ALDCH("lut[0:15]: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
130                     addr[0], addr[1], addr[2], addr[3],
131                     addr[4], addr[5], addr[6], addr[7],
132                     addr[8], addr[9], addr[10], addr[11],
133                     addr[12], addr[13], addr[14], addr[15]);
134         }
135 
136         if (ldchCtx->ldch_mem_info) {
137             ldchCtx->ready_lut_mem_fd = ldchCtx->ldch_mem_info->fd;
138             ldchCtx->update_lut_mem_fd = ldchCtx->ready_lut_mem_fd;
139         }
140 
141         LOGD_ALDCH("update custom lut from external file, lut_mem_fd %d\n", ldchCtx->update_lut_mem_fd);
142     }
143 
144     return ret;
145 }
146 
update_custom_lut_from_external_buffer(LDCHContext_t * ldchCtx)147 static XCamReturn update_custom_lut_from_external_buffer(LDCHContext_t* ldchCtx)
148 {
149     XCamReturn ret = XCAM_RETURN_NO_ERROR;
150 
151     if (!ldchCtx->_lutCache->GetBuffer()) {
152         LOGE_ALDCH("Failed to get ldch lut cache\n");
153         ret = XCAM_RETURN_ERROR_MEM;
154     }
155 
156     if (get_ldch_buf(ldchCtx) != XCAM_RETURN_NO_ERROR) {
157         LOGE_ALDCH("Failed to get ldch buf\n");
158         ret = XCAM_RETURN_ERROR_MEM;
159     } else {
160         uint16_t hpic, vpic, hsize, vsize, hstep, vstep;
161         uint32_t lut_size = 0;
162         uint16_t *addr = (uint16_t *)ldchCtx->_lutCache->GetBuffer();
163 
164         hpic    = *addr++;
165         vpic    = *addr++;
166         hsize   = *addr++;
167         vsize   = *addr++;
168         hstep   = *addr++;
169         vstep   = *addr++;
170 
171         lut_size = hsize * vsize *  sizeof(uint16_t);
172         LOGD_ALDCH("lut info: [%d-%d-%d-%d-%d-%d]", hpic, vpic, hsize, vsize, hstep, vstep);
173 
174         if (ldchCtx->src_width != hpic || ldchCtx->src_height != vpic || \
175             lut_size > (uint32_t)ldchCtx->ldch_mem_info->size) {
176             LOGE_ALDCH("mismatched lut pic resolution: src %dx%d, lut %dx%d, disable ldch",
177                     ldchCtx->src_width, ldchCtx->src_height, hpic, vpic);
178             LOGE_ALDCH("Invalid lut buffer size %zu, ldch drv bufer size is %u, disable ldch",
179                        lut_size, ldchCtx->ldch_mem_info->size);
180             ldchCtx->ldch_en = ldchCtx->user_config.en = false;
181             put_ldch_buf(ldchCtx);
182             ret = XCAM_RETURN_ERROR_PARAM;
183         } else {
184             ldchCtx->lut_h_size = hsize;
185             ldchCtx->lut_v_size = vsize;
186             ldchCtx->lut_mapxy_size = lut_size;
187             ldchCtx->lut_h_size = hsize / 2; //word unit
188 
189             memcpy(ldchCtx->ldch_mem_info->addr, addr, ldchCtx->lut_mapxy_size);
190             LOGD_ALDCH("lut[0:15]: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
191                     addr[0], addr[1], addr[2], addr[3],
192                     addr[4], addr[5], addr[6], addr[7],
193                     addr[8], addr[9], addr[10], addr[11],
194                     addr[12], addr[13], addr[14], addr[15]);
195             ldchCtx->_lutCache.release();
196             ldchCtx->_lutCache = nullptr;
197         }
198 
199         if (ldchCtx->ldch_mem_info) {
200             ldchCtx->ready_lut_mem_fd = ldchCtx->ldch_mem_info->fd;
201             ldchCtx->update_lut_mem_fd = ldchCtx->ready_lut_mem_fd;
202         }
203 
204         LOGD_ALDCH("update custom lut from external buffer, lut_mem_fd %d\n", ldchCtx->update_lut_mem_fd);
205     }
206 
207     return ret;
208 }
209 
update_uapi_attribute(LDCHContext_t * ldchCtx)210 static XCamReturn update_uapi_attribute(LDCHContext_t* ldchCtx)
211 {
212     XCamReturn ret = XCAM_RETURN_NO_ERROR;
213 
214     if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_FROM_EXTERNAL_FILE) {
215         if (ldchCtx->user_config.en) {
216             if (ldchCtx->user_config.lut.update_flag) {
217                 if (update_custom_lut_from_file(ldchCtx) < 0) {
218                     LOGE_ALDCH("Failed update custom lut\n");
219                     return XCAM_RETURN_ERROR_FAILED;
220                 } else {
221                     ldchCtx->user_config.lut.update_flag = false;
222                 }
223             }
224         } else {
225             ldchCtx->ldch_en = false;
226             LOGD_ALDCH("disable ldch by user api\n");
227         }
228 
229         ldchCtx->isAttribUpdated = false;
230     } else if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_ON_LINE) {
231         if (ldchCtx->user_config.en) {
232             SmartPtr<rk_aiq_ldch_v21_attrib_t> attrPtr = new rk_aiq_ldch_v21_attrib_t;
233             if (attrPtr.ptr()) {
234                 memcpy(attrPtr.ptr(), &ldchCtx->user_config, sizeof(ldchCtx->user_config));
235 
236                 ldchCtx->aldchReadMeshThread->push_attr(attrPtr);
237                 ldchCtx->isAttribUpdated = false;
238             } else {
239                 LOGE_ALDCH("Failed to new ldch attr, don't update attrib\n");
240             }
241         } else {
242             ldchCtx->ldch_en = false;
243             ldchCtx->isAttribUpdated = false;
244         }
245     } else if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_FROM_EXTERNAL_BUFFER) {
246         if (ldchCtx->user_config.en) {
247             if (ldchCtx->user_config.lut.update_flag) {
248                 if (update_custom_lut_from_external_buffer(ldchCtx) < 0) {
249                     LOGE_ALDCH("Failed update custom lut from external buffer\n");
250                 } else {
251                     ldchCtx->user_config.lut.update_flag = false;
252                 }
253             }
254         } else {
255             ldchCtx->ldch_en = false;
256             LOGD_ALDCH("disable ldch by user api\n");
257         }
258 
259         ldchCtx->isAttribUpdated = false;
260     } else {
261         LOGE_ALDCH("unknow updating lut mode %d\n", ldchCtx->user_config.update_lut_mode);
262         ldchCtx->isAttribUpdated = false;
263         ret = XCAM_RETURN_ERROR_PARAM;
264     }
265 
266     // update user params after lut is generated by RKAiqAldchThread in online mode
267     if (ret ==  XCAM_RETURN_NO_ERROR && \
268         ldchCtx->user_config.update_lut_mode != RK_AIQ_LDCH_UPDATE_LUT_ON_LINE) {
269         ldchCtx->ldch_en          = ldchCtx->user_config.en;
270         ldchCtx->correct_level    = ldchCtx->user_config.correct_level;
271         ldchCtx->zero_interp_en   = ldchCtx->user_config.zero_interp_en;
272         ldchCtx->sample_avr_en    = ldchCtx->user_config.sample_avr_en;
273         ldchCtx->bic_mode_en      = ldchCtx->user_config.bic_mode_en;
274         memcpy(ldchCtx->bicubic, ldchCtx->user_config.bic_weight, sizeof(ldchCtx->bicubic));
275     }
276 
277     return ret;
278 }
279 
280 static XCamReturn
create_context(RkAiqAlgoContext ** context,const AlgoCtxInstanceCfg * cfg)281 create_context(RkAiqAlgoContext **context, const AlgoCtxInstanceCfg* cfg)
282 {
283     XCamReturn result = XCAM_RETURN_NO_ERROR;
284 
285     LOG1_ALDCH("%s: (enter)\n", __FUNCTION__ );
286     RkAiqAlgoContext *ctx = new RkAiqAlgoContext();
287     if (ctx == NULL) {
288         LOGE_ALDCH( "%s: create aldch context fail!\n", __FUNCTION__);
289         return XCAM_RETURN_ERROR_MEM;
290     }
291     ctx->hLDCH = new LDCHContext_t;
292     if (ctx->hLDCH == NULL) {
293         LOGE_ALDCH( "%s: create aldch handle fail!\n", __FUNCTION__);
294         return XCAM_RETURN_ERROR_MEM;
295     }
296     /* setup config */
297     memset((void *)(ctx->hLDCH), 0, sizeof(LDCHContext_t) );
298 
299     /* return handle */
300     *context = ctx;
301 
302     ctx->hLDCH->isAttribUpdated = false;
303     ctx->hLDCH->aldchReadMeshThread = new RKAiqAldchThread(ctx->hLDCH);
304     ctx->hLDCH->isLutUpdated.store(false, std::memory_order_release);
305 
306     LDCHHandle_t ldchCtx = ctx->hLDCH;
307     CalibDbV2_LDCH_t* calib_ldch_db =
308             (CalibDbV2_LDCH_t*)(CALIBDBV2_GET_MODULE_PTR(cfg->calibv2, aldch));
309     CalibDbV2_Ldch_Param_t* calib_ldch = &calib_ldch_db->param;
310 
311     ldchCtx->ldch_en = calib_ldch->ldch_en;
312     memcpy(ldchCtx->meshfile, calib_ldch->meshfile, sizeof(ldchCtx->meshfile));
313 
314     ldchCtx->camCoeff.cx = calib_ldch->light_center[0];
315     ldchCtx->camCoeff.cy = calib_ldch->light_center[1];
316     ldchCtx->camCoeff.a0 = calib_ldch->coefficient[0];
317     ldchCtx->camCoeff.a2 = calib_ldch->coefficient[1];
318     ldchCtx->camCoeff.a3 = calib_ldch->coefficient[2];
319     ldchCtx->camCoeff.a4 = calib_ldch->coefficient[3];
320     LOGD_ALDCH("(%s) len light center(%.16f, %.16f)\n",
321             __FUNCTION__,
322             ldchCtx->camCoeff.cx, ldchCtx->camCoeff.cy);
323     LOGD_ALDCH("(%s) len coefficient(%.16f, %.16f, %.16f, %.16f)\n",
324             __FUNCTION__,
325             ldchCtx->camCoeff.a0, ldchCtx->camCoeff.a2,
326             ldchCtx->camCoeff.a3, ldchCtx->camCoeff.a4);
327 
328     ldchCtx->correct_level = calib_ldch->correct_level;
329     ldchCtx->correct_level_max = calib_ldch->correct_level_max;
330 
331     memset(&ldchCtx->user_config, 0, sizeof(ldchCtx->user_config));
332     ldchCtx->user_config.en             = ldchCtx->ldch_en;
333     ldchCtx->user_config.correct_level  = ldchCtx->correct_level;
334     ldchCtx->user_config.bic_mode_en = 1;
335     memcpy(ldchCtx->user_config.bic_weight, default_bic_table, sizeof(default_bic_table));
336 
337     ldchCtx->frm_end_dis    = 0;
338     ldchCtx->zero_interp_en = 0;
339     ldchCtx->sample_avr_en  = 0;
340     ldchCtx->bic_mode_en    = 1;
341     ldchCtx->force_map_en   = 0;
342     ldchCtx->map13p3_en     = 0;
343     memcpy(ldchCtx->bicubic, default_bic_table, sizeof(default_bic_table));
344 
345     ldchCtx->update_lut_mem_fd = -1;
346     ldchCtx->ready_lut_mem_fd = -1;
347 
348     ldchCtx->hasAllocShareMem.store(false, std::memory_order_release);
349     ldchCtx->_lutCache = nullptr;
350 
351     LOGD_ALDCH("bic table0: 0x%x, table1: 0x%x, table2: 0x%x, table3: 0x%x,",
352                *(uint32_t *)ldchCtx->bicubic,
353                *(uint32_t *)(ldchCtx->bicubic + 4),
354                *(uint32_t *)(ldchCtx->bicubic + 8),
355                *(uint32_t *)(ldchCtx->bicubic + 12));
356     LOGD_ALDCH("bic table4: 0x%x, table5: 0x%x, table6: 0x%x, table7: 0x%x,",
357                *(uint32_t *)(ldchCtx->bicubic + 16),
358                *(uint32_t *)(ldchCtx->bicubic + 20),
359                *(uint32_t *)(ldchCtx->bicubic + 24),
360                *(uint32_t *)(ldchCtx->bicubic + 28));
361     LOGD_ALDCH("bic table8: 0x%x, bic_mode_en: %d", *(uint32_t *)(ldchCtx->bicubic + 32), ldchCtx->bic_mode_en);
362 
363     LOGD_ALDCH("ldch en %d, meshfile: %s, correct_level-max: %d-%d from xml file",
364                calib_ldch->ldch_en,
365                ldchCtx->meshfile,
366                ldchCtx->correct_level,
367                ldchCtx->correct_level_max);
368 
369     return XCAM_RETURN_NO_ERROR;
370 }
371 
372 static XCamReturn
destroy_context(RkAiqAlgoContext * context)373 destroy_context(RkAiqAlgoContext *context)
374 {
375     LDCHHandle_t hLDCH = (LDCHHandle_t)context->hLDCH;
376     LDCHContext_t* ldchCtx = (LDCHContext_t*)hLDCH;
377 
378     if (ldchCtx->aldchReadMeshThread->is_running()) {
379         ldchCtx->aldchReadMeshThread->triger_stop();
380         ldchCtx->aldchReadMeshThread->stop();
381     }
382 
383     if (!hLDCH->aldchReadMeshThread->is_empty()) {
384         hLDCH->aldchReadMeshThread->clear_attr();
385     }
386 
387     if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_ON_LINE) {
388         genLdchMeshDeInit(ldchCtx->ldchParams);
389     }
390 
391     release_ldch_buf(ldchCtx);
392     delete context->hLDCH;
393     context->hLDCH = NULL;
394     delete context;
395     context = NULL;
396     return XCAM_RETURN_NO_ERROR;
397 }
398 
399 static XCamReturn
prepare(RkAiqAlgoCom * params)400 prepare(RkAiqAlgoCom* params)
401 {
402     LDCHHandle_t hLDCH = (LDCHHandle_t)params->ctx->hLDCH;
403     LDCHContext_t* ldchCtx = (LDCHContext_t*)hLDCH;
404     RkAiqAlgoConfigAldch* rkaiqAldchConfig = (RkAiqAlgoConfigAldch*)params;
405 
406     ldchCtx->src_width = params->u.prepare.sns_op_width;
407     ldchCtx->src_height = params->u.prepare.sns_op_height;
408     ldchCtx->dst_width = params->u.prepare.sns_op_width;
409     ldchCtx->dst_height = params->u.prepare.sns_op_height;
410     ldchCtx->resource_path = rkaiqAldchConfig->resource_path;
411     ldchCtx->share_mem_ops = rkaiqAldchConfig->mem_ops_ptr;
412 
413     LOGD_ALDCH("update_lut_mode %d\n", ldchCtx->user_config.update_lut_mode);
414 
415     // 1.update cailb
416     bool config_calib = !!(params->u.prepare.conf_type & RK_AIQ_ALGO_CONFTYPE_UPDATECALIB);
417     if (config_calib) {
418         if(updateCalibConfig(params) != XCAM_RETURN_NO_ERROR) {
419             LOGW_ALDCH("Failed to update calib config");
420         }
421 
422         return XCAM_RETURN_NO_ERROR;
423     }
424 
425     // 2.process the new attrib set before prepare
426     if (ldchCtx->aldchReadMeshThread->is_running()) {
427         hLDCH->aldchReadMeshThread->triger_stop();
428         hLDCH->aldchReadMeshThread->stop();
429     }
430 
431     if (!hLDCH->aldchReadMeshThread->is_empty()) {
432         hLDCH->aldchReadMeshThread->clear_attr();
433     }
434 
435     // discard the lut generated ReadMeshThread in before aiq prepare
436     if (ldchCtx->isLutUpdated.load(std::memory_order_acquire)) {
437         put_ldch_buf(hLDCH);
438         ldchCtx->isLutUpdated.store(false, std::memory_order_release);
439     }
440 
441     // 3.update uapi attribute
442     if (ldchCtx->isAttribUpdated) {
443         ldchCtx->ldch_en            = ldchCtx->user_config.en;
444         ldchCtx->correct_level      = ldchCtx->user_config.correct_level;
445         ldchCtx->zero_interp_en     = ldchCtx->user_config.zero_interp_en;
446         ldchCtx->sample_avr_en      = ldchCtx->user_config.sample_avr_en;
447         ldchCtx->bic_mode_en        = ldchCtx->user_config.bic_mode_en;
448         memcpy(ldchCtx->bicubic, ldchCtx->user_config.bic_weight, sizeof(ldchCtx->bicubic));
449 
450         ldchCtx->isAttribUpdated = false;
451     }
452 
453     // 4.update ldch result
454     if (ldchCtx->ldch_en) {
455         if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_FROM_EXTERNAL_FILE) {
456             if (ldchCtx->user_config.lut.update_flag) {
457                 if (update_custom_lut_from_file(ldchCtx) < 0) {
458                     LOGE_ALDCH("Failed update custom lut from file\n");
459                     ldchCtx->ldch_en = false;
460                 } else {
461                     ldchCtx->user_config.lut.update_flag = false;
462                 }
463             }
464         } else if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_ON_LINE) {
465             if (aiqGenLdchMeshInit(ldchCtx) == XCAM_RETURN_NO_ERROR) {
466                 bool success = aiqGenMesh(hLDCH, ldchCtx->correct_level);
467                 if (!success) {
468                     LOGW_ALDCH("lut is not exist, disable ldch!");
469                     put_ldch_buf(hLDCH);
470                     ldchCtx->ldch_en = false;
471                 }
472 
473                 if (ldchCtx->ldch_mem_info)
474                     hLDCH->ready_lut_mem_fd = ldchCtx->ldch_mem_info->fd;
475             }
476         } else if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_FROM_EXTERNAL_BUFFER) {
477             if (ldchCtx->user_config.lut.update_flag) {
478                 if (update_custom_lut_from_external_buffer(ldchCtx) < 0) {
479                     LOGE_ALDCH("Failed update custom lut from external buffer\n");
480                     ldchCtx->ldch_en = false;
481                 } else {
482                     ldchCtx->user_config.lut.update_flag = false;
483                 }
484             }
485         } else {
486             LOGE_ALDCH("unknow updating lut mode %d\n", ldchCtx->user_config.update_lut_mode);
487         }
488     }
489 
490     if (ldchCtx->user_config.update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_ON_LINE) {
491         hLDCH->aldchReadMeshThread->triger_start();
492         hLDCH->aldchReadMeshThread->start();
493     }
494 
495     return XCAM_RETURN_NO_ERROR;
496 }
497 
498 static XCamReturn
pre_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)499 pre_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
500 {
501     return XCAM_RETURN_NO_ERROR;
502 }
503 
504 static XCamReturn
processing(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)505 processing(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
506 {
507     LDCHHandle_t hLDCH = (LDCHHandle_t)inparams->ctx->hLDCH;
508     LDCHContext_t* ldchCtx = (LDCHContext_t*)hLDCH;
509     RkAiqAlgoProcResAldchV21* ldchPreOut = (RkAiqAlgoProcResAldchV21*)outparams;
510     bool update_params = false;
511 
512     // 1.initial state processing or updating uapi attrib after lut is generated by RKAiqAldchThread
513     if (inparams->u.proc.init) {
514         if (ldchCtx->ready_lut_mem_fd >= 0) {
515             ldchCtx->update_lut_mem_fd = ldchCtx->ready_lut_mem_fd;
516         }
517         update_params = true;
518     } else if (ldchCtx->isLutUpdated.load(std::memory_order_acquire)) {
519         // update user params after lut is generated by RKAiqAldchThread
520         ldchCtx->ldch_en          = ldchCtx->user_config.en;
521         ldchCtx->correct_level    = ldchCtx->user_config.correct_level;
522         ldchCtx->zero_interp_en   = ldchCtx->user_config.zero_interp_en;
523         ldchCtx->sample_avr_en    = ldchCtx->user_config.sample_avr_en;
524         ldchCtx->bic_mode_en      = ldchCtx->user_config.bic_mode_en;
525         memcpy(ldchCtx->bicubic, ldchCtx->user_config.bic_weight, sizeof(ldchCtx->bicubic));
526 
527         if (ldchCtx->ready_lut_mem_fd >= 0)
528             ldchCtx->update_lut_mem_fd = ldchCtx->ready_lut_mem_fd;
529         LOGD_ALDCH("update update_lut_mem_fd %d\n", ldchCtx->update_lut_mem_fd);
530 
531         update_params = true;
532         ldchCtx->isLutUpdated.store(false, std::memory_order_release);
533     }
534 
535     // 2.update uapi attribute
536     if (ldchCtx->isAttribUpdated) {
537         if (update_uapi_attribute(ldchCtx) < 0) {
538             LOGE_ALDCH("Failed to update uapi attribute %d", ldchCtx->update_lut_mem_fd);
539         }
540 
541         // update params asynchronously after lut is generated by RKAiqAldchThread
542         // in online mode
543         auto update_lut_mode = ldchCtx->user_config.update_lut_mode;
544         if (update_lut_mode != RK_AIQ_LDCH_UPDATE_LUT_ON_LINE ||
545             (update_lut_mode == RK_AIQ_LDCH_UPDATE_LUT_ON_LINE && !ldchCtx->ldch_en)) {
546             update_params = true;
547         }
548     }
549 
550     // 3.update ldch result
551     if (ldchCtx->ldch_en) {
552         if (ldchCtx->update_lut_mem_fd < 0) {
553             LOGE_ALDCH("no available ldch buf, lut fd: %d", ldchCtx->update_lut_mem_fd);
554             if (inparams->u.proc.init) {
555                 LOGE_ALDCH("mesh buf is invalid, disable LDCH!");
556                 ldchCtx->ldch_en = ldchCtx->user_config.en = false;
557                 ldchPreOut->ldch_result->base.sw_ldch_en = false;
558                 outparams->cfg_update = true;
559             } else {
560                 outparams->cfg_update = false;
561             }
562             return XCAM_RETURN_NO_ERROR;
563         }
564 
565         ldchPreOut->ldch_result->base.lut_mapxy_buf_fd = ldchCtx->update_lut_mem_fd;
566         ldchPreOut->ldch_result->base.lut_h_size = ldchCtx->lut_h_size;
567         ldchPreOut->ldch_result->base.lut_v_size = ldchCtx->lut_v_size;
568         ldchPreOut->ldch_result->base.lut_map_size = ldchCtx->lut_mapxy_size;
569 
570         ldchPreOut->ldch_result->frm_end_dis = ldchCtx->frm_end_dis;
571         ldchPreOut->ldch_result->zero_interp_en = ldchCtx->zero_interp_en;
572         ldchPreOut->ldch_result->sample_avr_en = ldchCtx->sample_avr_en;
573         ldchPreOut->ldch_result->bic_mode_en = ldchCtx->bic_mode_en;
574         ldchPreOut->ldch_result->force_map_en = ldchCtx->force_map_en;
575         ldchPreOut->ldch_result->map13p3_en = ldchCtx->map13p3_en;
576         memcpy(ldchPreOut->ldch_result->bicubic, ldchCtx->bicubic, sizeof(ldchCtx->bicubic));
577     }
578 
579     ldchPreOut->ldch_result->base.sw_ldch_en = ldchCtx->ldch_en;
580     outparams->cfg_update = update_params;
581 
582     LOGV_ALDCH("en:%d, level:%d, h/v: %dx%d, interp_en:%d, avr_en:%d, bic_en:%d, force_map_en:%d, map13p3_en:%d\n",
583             ldchCtx->ldch_en,
584             ldchCtx->correct_level,
585             ldchCtx->lut_h_size,
586             ldchCtx->lut_v_size,
587             ldchCtx->zero_interp_en,
588             ldchCtx->sample_avr_en,
589             ldchCtx->bic_mode_en,
590             ldchCtx->force_map_en,
591             ldchCtx->map13p3_en);
592 
593     LOGV_ALDCH("update_lut_mode %d, lut fd %d, cfg_update %d\n",
594             ldchCtx->user_config.update_lut_mode,
595             ldchPreOut->ldch_result->base.lut_mapxy_buf_fd,
596             outparams->cfg_update);
597 
598     return XCAM_RETURN_NO_ERROR;
599 }
600 
601 static XCamReturn
post_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)602 post_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
603 {
604     return XCAM_RETURN_NO_ERROR;
605 }
606 
607 RkAiqAlgoDescription g_RkIspAlgoDescAldch = {
608     .common = {
609         .version = RKISP_ALGO_ALDCH_VERSION,
610         .vendor  = RKISP_ALGO_ALDCH_VENDOR,
611         .description = RKISP_ALGO_ALDCH_DESCRIPTION,
612         .type    = RK_AIQ_ALGO_TYPE_ALDCH,
613         .id      = 0,
614         .create_context  = create_context,
615         .destroy_context = destroy_context,
616     },
617     .prepare = prepare,
618     .pre_process = pre_process,
619     .processing = processing,
620     .post_process = post_process,
621 };
622 
623 RKAIQ_END_DECLARE
624 
625 
loop()626 bool RKAiqAldchThread::loop()
627 {
628     XCamReturn ret = XCAM_RETURN_NO_ERROR;
629     ENTER_ANALYZER_FUNCTION();
630 
631     const static int32_t timeout = -1;
632     SmartPtr<rk_aiq_ldch_v21_cfg_t> attrib = mAttrQueue.pop (timeout);
633 
634     if (!attrib.ptr()) {
635         LOGW_ALDCH("RKAiqAldchThread got empty attrib, stop thread");
636         return false;
637     }
638 
639     if (!hLDCH->ldch_en || attrib->correct_level != hLDCH->correct_level) {
640         if (aiqGenLdchMeshInit(hLDCH) == XCAM_RETURN_NO_ERROR) {
641             bool success = aiqGenMesh(hLDCH, attrib->correct_level);
642             if (!success) {
643                 LOGW_ALDCH("lut is not exist");
644                 ret = XCAM_RETURN_ERROR_PARAM;
645                 put_ldch_buf(hLDCH);
646                 return true;
647             }
648         } else {
649             LOGE_ALDCH("Failed to init gen mesh");
650             ret = XCAM_RETURN_ERROR_PARAM;
651             return true;
652         }
653     }
654 
655     if (ret == XCAM_RETURN_NO_ERROR) {
656         if (hLDCH->ldch_mem_info)
657             hLDCH->ready_lut_mem_fd = hLDCH->ldch_mem_info->fd;
658         hLDCH->isLutUpdated.store(true, std::memory_order_release);
659 
660         LOGD_ALDCH("ldch update attrib en(%d), level(%d), ready lut fd%d\n",
661                 attrib->en, attrib->correct_level, hLDCH->ready_lut_mem_fd);
662 
663         return true;
664     }
665 
666     LOGE_ALDCH("RKAiqAldchThread failed to read mesh table!");
667 
668     EXIT_ANALYZER_FUNCTION();
669 
670     return true;
671 }
672