xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/algos/afec/rk_aiq_algo_afec_itf.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * rk_aiq_algo_afec_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 "afec/rk_aiq_algo_afec_itf.h"
21 #include "afec/rk_aiq_types_afec_algo_prvt.h"
22 #include "rk_aiq_algo_types.h"
23 #include "RkAiqCalibDbV2Helper.h"
24 #include "xcam_log.h"
25 
26 #define EPSINON 0.0000001
27 
28 RKAIQ_BEGIN_DECLARE
29 
30 static XCamReturn release_fec_buf(FECContext_t* fecCtx);
alloc_fec_buf(FECContext_t * fecCtx)31 static XCamReturn alloc_fec_buf(FECContext_t* fecCtx)
32 {
33     // release-first
34     release_fec_buf(fecCtx);
35     rk_aiq_share_mem_config_t share_mem_config;
36     share_mem_config.alloc_param.width =  fecCtx->dst_width;
37     share_mem_config.alloc_param.height = fecCtx->dst_height;
38     share_mem_config.alloc_param.reserved[0] = fecCtx->mesh_density;
39     share_mem_config.mem_type = MEM_TYPE_FEC;
40     fecCtx->share_mem_ops->alloc_mem(0, fecCtx->share_mem_ops,
41                                      &share_mem_config,
42                                      &fecCtx->share_mem_ctx);
43     return XCAM_RETURN_NO_ERROR;
44 }
45 
release_fec_buf(FECContext_t * fecCtx)46 static XCamReturn release_fec_buf(FECContext_t* fecCtx)
47 {
48     if (fecCtx->share_mem_ctx)
49         fecCtx->share_mem_ops->release_mem(0, fecCtx->share_mem_ctx);
50 
51     return XCAM_RETURN_NO_ERROR;
52 }
53 
get_fec_buf(FECContext_t * fecCtx)54 static XCamReturn get_fec_buf(FECContext_t* fecCtx)
55 {
56     fecCtx->fec_mem_info = (rk_aiq_fec_share_mem_info_t *)
57             fecCtx->share_mem_ops->get_free_item(0, fecCtx->share_mem_ctx);
58     if (fecCtx->fec_mem_info == NULL) {
59         LOGE_AFEC( "%s(%d): no free fec buf", __FUNCTION__, __LINE__);
60         return XCAM_RETURN_ERROR_MEM;
61     } else {
62         LOGD_AFEC("get buf fd=%d\n",fecCtx->fec_mem_info->fd);
63         fecCtx->meshxi = fecCtx->fec_mem_info->meshxi;
64         fecCtx->meshxf = fecCtx->fec_mem_info->meshxf;
65         fecCtx->meshyi = fecCtx->fec_mem_info->meshyi;
66         fecCtx->meshyf = fecCtx->fec_mem_info->meshyf;
67     }
68     return XCAM_RETURN_NO_ERROR;
69 }
70 
71 static XCamReturn
gen_mesh_table(float k1,float k2,float p1,float p2,float k3,int src_width,int src_height,int mesh_h_size,int mesh_v_size,int * meshxi,int * meshxf,int * meshyi,int * meshyf)72 gen_mesh_table(
73     float k1, float k2, float p1, float p2, float k3,
74     int src_width, int src_height,
75     int mesh_h_size, int mesh_v_size,
76     int* meshxi, int* meshxf, int* meshyi, int* meshyf) {
77     //TODO::implement mesh table generation function
78     return XCAM_RETURN_NO_ERROR;
79 }
80 
81 static XCamReturn
create_context(RkAiqAlgoContext ** context,const AlgoCtxInstanceCfg * cfg)82 create_context(RkAiqAlgoContext **context, const AlgoCtxInstanceCfg* cfg)
83 {
84     RkAiqAlgoContext *ctx = new RkAiqAlgoContext();
85     if (ctx == NULL) {
86         LOGE_AFEC( "%s: create afec context fail!\n", __FUNCTION__);
87         return XCAM_RETURN_ERROR_MEM;
88     }
89     ctx->hFEC = new FECContext_t();
90     if (ctx->hFEC == NULL) {
91         LOGE_AFEC( "%s: create afec handle fail!\n", __FUNCTION__);
92         return XCAM_RETURN_ERROR_MEM;
93     }
94     memset((void *)(ctx->hFEC), 0, sizeof(FECContext_t));
95     *context = ctx;
96 
97     FECHandle_t fecCtx = ctx->hFEC;
98 
99     CalibDbV2_FEC_t* calib_fec_db =
100             (CalibDbV2_FEC_t*)(CALIBDBV2_GET_MODULE_PTR(cfg->calibv2, afec));
101     if (!calib_fec_db) {
102         LOGE_AFEC("%s: Could not get fec iq calib!\n", __FUNCTION__);
103         return XCAM_RETURN_ERROR_MEM;
104     }
105     CalibDbV2_Fec_Param_t* calib_fec = &calib_fec_db->param;
106 
107     memset(&fecCtx->user_config, 0, sizeof(fecCtx->user_config));
108 #if RKAIQ_HAVE_EIS_V1
109     CalibDbV2_Eis_t* calib_eis =
110                 (CalibDbV2_Eis_t*)(CALIBDBV2_GET_MODULE_PTR(cfg->calibv2, eis_calib));
111     fecCtx->fec_en = fecCtx->user_config.en = calib_eis->enable ? 0 : calib_fec->fec_en;
112     if (!fecCtx->fec_en) {
113         if (calib_eis->enable) {
114             LOGE_AFEC("FEC diabled because of EIS");
115         }
116         return XCAM_RETURN_NO_ERROR;
117     }
118 #else
119     fecCtx->fec_en = fecCtx->user_config.en = calib_fec->fec_en;
120     if (!fecCtx->fec_en) {
121         return XCAM_RETURN_NO_ERROR;
122     }
123 #endif
124 
125 #if GENMESH_ONLINE
126     ctx->hFEC->isAttribUpdated = false;
127     ctx->hFEC->afecReadMeshThread = new RKAiqAfecThread(ctx->hFEC);
128 #endif
129 
130     memcpy(fecCtx->meshfile, calib_fec->meshfile, sizeof(fecCtx->meshfile));
131 #if GENMESH_ONLINE
132     fecCtx->camCoeff.cx = calib_fec->light_center[0];
133     fecCtx->camCoeff.cy = calib_fec->light_center[1];
134     fecCtx->camCoeff.a0 = calib_fec->coefficient[0];
135     fecCtx->camCoeff.a2 = calib_fec->coefficient[1];
136     fecCtx->camCoeff.a3 = calib_fec->coefficient[2];
137     fecCtx->camCoeff.a4 = calib_fec->coefficient[3];
138     LOGI_AFEC("(%s) len light center(%.16f, %.16f)\n",
139             __FUNCTION__,
140             fecCtx->camCoeff.cx, fecCtx->camCoeff.cy);
141     LOGI_AFEC("(%s) len coefficient(%.16f, %.16f, %.16f, %.16f)\n",
142             __FUNCTION__,
143             fecCtx->camCoeff.a0, fecCtx->camCoeff.a2,
144             fecCtx->camCoeff.a3, fecCtx->camCoeff.a4);
145 #endif
146     fecCtx->correct_level = calib_fec->correct_level;
147     fecCtx->correct_level = fecCtx->user_config.correct_level = calib_fec->correct_level;
148     fecCtx->correct_direction = fecCtx->user_config.direction = FEC_CORRECT_DIRECTION_XY;
149     fecCtx->fecParams.correctX = 1;
150     fecCtx->fecParams.correctY = 1;
151     fecCtx->fecParams.saveMesh4bin = 0;
152 
153     ctx->hFEC->eState = FEC_STATE_INVALID;
154 
155     return XCAM_RETURN_NO_ERROR;
156 }
157 
158 static XCamReturn
destroy_context(RkAiqAlgoContext * context)159 destroy_context(RkAiqAlgoContext *context)
160 {
161     FECHandle_t hFEC = (FECHandle_t)context->hFEC;
162     FECContext_t* fecCtx = (FECContext_t*)hFEC;
163 #if GENMESH_ONLINE
164     if (fecCtx->fec_en) {
165         fecCtx->afecReadMeshThread->triger_stop();
166         fecCtx->afecReadMeshThread->stop();
167         //    if (fecCtx->meshxi != NULL || fecCtx->meshyi != NULL ||
168         //        fecCtx->meshxf != NULL || fecCtx->meshyf != NULL)
169         //        freeFecMesh(fecCtx->meshxi, fecCtx->meshxf,
170         //                fecCtx->meshyi, fecCtx->meshyf);
171         genFecMeshDeInit(fecCtx->fecParams);
172     }
173 #else
174 //    if (fecCtx->meshxi != NULL) {
175 //        free(fecCtx->meshxi);
176 //        fecCtx->meshxi = NULL;
177 //    }
178 
179 //    if (fecCtx->meshyi != NULL) {
180 //        free(fecCtx->meshyi);
181 //        fecCtx->meshyi = NULL;
182 //    }
183 
184 //    if (fecCtx->meshxf != NULL) {
185 //        free(fecCtx->meshxf);
186 //        fecCtx->meshxf = NULL;
187 //    }
188 //
189 //    if (fecCtx->meshyf != NULL) {
190 //        free(fecCtx->meshyf);
191 //        fecCtx->meshyf = NULL;
192 //    }
193 #endif
194     release_fec_buf(fecCtx);
195     delete context->hFEC;
196     context->hFEC = NULL;
197     delete context;
198     context = NULL;
199     return XCAM_RETURN_NO_ERROR;
200 }
201 
202 #define __ALIGN_MASK(x,mask)    (((x)+(mask))&~(mask))
203 #define ALIGN(x,a)      __ALIGN_MASK(x, a-1)
204 
cal_fec_mesh(uint32_t width,uint32_t height,uint32_t mode,uint32_t & meshw,uint32_t & meshh)205 uint32_t cal_fec_mesh(uint32_t width, uint32_t height, uint32_t mode, uint32_t &meshw, uint32_t &meshh)
206 {
207     uint32_t mesh_size, mesh_left_height;
208     uint32_t w = ALIGN(width, 32);
209     uint32_t h = ALIGN(height, 32);
210     uint32_t spb_num = (h + 127) >> 7;
211     uint32_t left_height = h & 127;
212     uint32_t mesh_width = mode ? (w / 32 + 1) : (w / 16 + 1);
213     uint32_t mesh_height = mode ? 9 : 17;
214 
215     if (!left_height)
216         left_height = 128;
217     mesh_left_height = mode ? (left_height / 16 + 1) :
218                        (left_height / 8 + 1);
219     mesh_size = (spb_num - 1) * mesh_width * mesh_height +
220                 mesh_width * mesh_left_height;
221 
222     meshw = mesh_width;
223     meshh = (spb_num - 1) * mesh_height + (spb_num - 1);
224     return mesh_size;
225 }
226 
227 static XCamReturn
read_mesh_table(FECContext_t * fecCtx,unsigned int correct_level)228 read_mesh_table(FECContext_t* fecCtx, unsigned int correct_level)
229 {
230     bool ret;
231 #if OPENCV_SUPPORT
232     gen_default_mesh_table(fecCtx->src_width, fecCtx->src_height, fecCtx->mesh_density,
233                            fecCtx->meshxi, fecCtx->meshyi, fecCtx->meshxf, fecCtx->meshyf);
234 #elif GENMESH_ONLINE
235     ret = genFECMeshNLevel(fecCtx->fecParams, fecCtx->camCoeff, correct_level, fecCtx->meshxi,
236                            fecCtx->meshxf, fecCtx->meshyi, fecCtx->meshyf);
237     if (!ret) {
238         LOGE_AFEC("afec gen mesh false!");
239         return XCAM_RETURN_ERROR_FAILED;
240     }
241 #else
242     FILE* ofp;
243     char filename[512];
244     sprintf(filename, "%s/%s/meshxi_level%d.bin",
245             fecCtx->resource_path,
246             fecCtx->meshfile,
247             correct_level);
248     ofp = fopen(filename, "rb");
249     if (ofp != NULL) {
250         unsigned int num = fread(fecCtx->meshxi, 1, fecCtx->fec_mesh_size * sizeof(unsigned short), ofp);
251         fclose(ofp);
252 
253         if (num != fecCtx->fec_mesh_size * sizeof(unsigned short)) {
254             fecCtx->fec_en = 0;
255             LOGE_AFEC("mismatched mesh XI file");
256         }
257     } else {
258         LOGE_AFEC("mesh XI file %s not exist", filename);
259         fecCtx->fec_en = 0;
260     }
261 
262     sprintf(filename, "%s/%s/meshxf_level%d.bin",
263             fecCtx->resource_path,
264             fecCtx->meshfile,
265             correct_level);
266     ofp = fopen(filename, "rb");
267     if (ofp != NULL) {
268         unsigned int num = fread(fecCtx->meshxf, 1, fecCtx->fec_mesh_size * sizeof(unsigned char), ofp);
269         fclose(ofp);
270         if (num != fecCtx->fec_mesh_size * sizeof(unsigned char)) {
271             fecCtx->fec_en = 0;
272             LOGE_AFEC("mismatched mesh XF file");
273         }
274     } else {
275         LOGE_AFEC("mesh XF file %s not exist", filename);
276         fecCtx->fec_en = 0;
277     }
278 
279     sprintf(filename, "%s/%s/meshyi_level%d.bin",
280             fecCtx->resource_path,
281             fecCtx->meshfile,
282             correct_level);
283     ofp = fopen(filename, "rb");
284     if (ofp != NULL) {
285         unsigned int num = fread(fecCtx->meshyi, 1, fecCtx->fec_mesh_size * sizeof(unsigned short), ofp);
286         fclose(ofp);
287         if (num != fecCtx->fec_mesh_size * sizeof(unsigned short)) {
288             fecCtx->fec_en = 0;
289             LOGE_AFEC("mismatched mesh YI file");
290         }
291     } else {
292         LOGE_AFEC("mesh YI file %s not exist", filename);
293         fecCtx->fec_en = 0;
294     }
295 
296     sprintf(filename, "%s/%s/meshyf_level%d.bin",
297             fecCtx->resource_path,
298             fecCtx->meshfile,
299             correct_level);
300     ofp = fopen(filename, "rb");
301     if (ofp != NULL) {
302         unsigned int num = fread(fecCtx->meshyf, 1, fecCtx->fec_mesh_size * sizeof(unsigned char), ofp);
303         fclose(ofp);
304         if (num != fecCtx->fec_mesh_size * sizeof(unsigned char)) {
305             fecCtx->fec_en = 0;
306             LOGE_AFEC("mismatched mesh YF file");
307         }
308     } else {
309         LOGE_AFEC("mesh YF file %s not exist", filename);
310         fecCtx->fec_en = 0;
311     }
312 #endif
313 
314     return XCAM_RETURN_NO_ERROR;
315 }
316 
317 static XCamReturn
prepare(RkAiqAlgoCom * params)318 prepare(RkAiqAlgoCom* params)
319 {
320     FECHandle_t hFEC = (FECHandle_t)params->ctx->hFEC;
321     FECContext_t* fecCtx = (FECContext_t*)hFEC;
322     RkAiqAlgoConfigAfec* rkaiqAfecConfig = (RkAiqAlgoConfigAfec*)params;
323 
324     if (!fecCtx->fec_en)
325         return XCAM_RETURN_NO_ERROR;
326 
327 #if 0 //moved to create_ctx
328     fecCtx->fec_en = rkaiqAfecConfig->afec_calib_cfg.fec_en;
329     memcpy(fecCtx->meshfile, rkaiqAfecConfig->afec_calib_cfg.meshfile, sizeof(fecCtx->meshfile));
330     fecCtx->camCoeff.cx = rkaiqAfecConfig->afec_calib_cfg.light_center[0];
331     fecCtx->camCoeff.cy = rkaiqAfecConfig->afec_calib_cfg.light_center[1];
332     fecCtx->camCoeff.a0 = rkaiqAfecConfig->afec_calib_cfg.coefficient[0];
333     fecCtx->camCoeff.a2 = rkaiqAfecConfig->afec_calib_cfg.coefficient[1];
334     fecCtx->camCoeff.a3 = rkaiqAfecConfig->afec_calib_cfg.coefficient[2];
335     fecCtx->camCoeff.a4 = rkaiqAfecConfig->afec_calib_cfg.coefficient[3];
336     LOGI_AFEC("(%s) len light center(%.16f, %.16f)\n",
337             __FUNCTION__,
338             fecCtx->camCoeff.cx, fecCtx->camCoeff.cy);
339     LOGI_AFEC("(%s) len coefficient(%.16f, %.16f, %.16f, %.16f)\n",
340             __FUNCTION__,
341             fecCtx->camCoeff.a0, fecCtx->camCoeff.a2,
342             fecCtx->camCoeff.a3, fecCtx->camCoeff.a4);
343 #endif
344     fecCtx->share_mem_ops = rkaiqAfecConfig->mem_ops_ptr;
345     fecCtx->src_width = params->u.prepare.sns_op_width;
346     fecCtx->src_height = params->u.prepare.sns_op_height;
347     fecCtx->resource_path = rkaiqAfecConfig->resource_path;
348     fecCtx->dst_width = params->u.prepare.sns_op_width;
349     fecCtx->dst_height = params->u.prepare.sns_op_height;
350 
351     if (fecCtx->src_width <= 1920) {
352         fecCtx->mesh_density = 0;
353     } else {
354         fecCtx->mesh_density = 1;
355     }
356 
357 #if GENMESH_ONLINE
358     // process the new attrib set before prepare
359     fecCtx->afecReadMeshThread->triger_stop();
360     fecCtx->afecReadMeshThread->stop();
361     if (!fecCtx->afecReadMeshThread->is_empty()) {
362         fecCtx->afecReadMeshThread->clear_attr();
363         fecCtx->isAttribUpdated = true;
364     }
365 #endif
366 
367     double correct_level = fecCtx->correct_level;
368     if (fecCtx->isAttribUpdated) {
369         fecCtx->fec_en = fecCtx->user_config.en;
370         if (fecCtx->user_config.bypass)
371             correct_level = 0;
372         correct_level = fecCtx->user_config.correct_level;
373         switch (fecCtx->user_config.direction) {
374         case FEC_CORRECT_DIRECTION_X:
375             fecCtx->fecParams.correctY = 0;
376             fecCtx->correct_direction = fecCtx->user_config.direction;
377             break;
378         case FEC_CORRECT_DIRECTION_Y:
379             fecCtx->fecParams.correctX = 0;
380             fecCtx->correct_direction = fecCtx->user_config.direction;
381             break;
382         default:
383             break;
384         }
385 
386         fecCtx->mode = fecCtx->user_config.mode;
387         switch (fecCtx->mode) {
388         case FEC_COMPRES_IMAGE_KEEP_FOV:
389             fecCtx->fecParams.saveMaxFovX = 1;
390             break;
391         case FEC_KEEP_ASPECT_RATIO_REDUCE_FOV:
392             fecCtx->fecParams.saveMaxFovX = 0;
393             break;
394         case FEC_ALTER_ASPECT_RATIO_KEEP_FOV:
395             break;
396         default:
397             break;
398         }
399 
400         if (fecCtx->fecParams.saveMesh4bin)
401             sprintf(fecCtx->fecParams.mesh4binPath, "/tmp/");
402 
403         fecCtx->isAttribUpdated = false;
404     } else {
405         fecCtx->user_config.en = fecCtx->fec_en;
406     }
407     fecCtx->user_config.correct_level = correct_level;
408 
409 #if GENMESH_ONLINE
410     // deinit firtly
411     if (fecCtx->fecParams.pMeshXY)
412         genFecMeshDeInit(fecCtx->fecParams);
413 
414     //if (fecCtx->meshxi != NULL || fecCtx->meshyi != NULL ||
415     //    fecCtx->meshxf != NULL || fecCtx->meshyf != NULL)
416     //    freeFecMesh(fecCtx->meshxi, fecCtx->meshxf,
417     //            fecCtx->meshyi, fecCtx->meshyf);
418 
419     fecCtx->fecParams.isFecOld = 1;
420     genFecMeshInit(fecCtx->src_width, fecCtx->src_height, fecCtx->dst_width,
421             fecCtx->dst_height, fecCtx->fecParams, fecCtx->camCoeff);
422     //mallocFecMesh(fecCtx->fecParams.meshSize4bin, &fecCtx->meshxi,
423     //        &fecCtx->meshxf, &fecCtx->meshyi, &fecCtx->meshyf);
424     fecCtx->fec_mesh_h_size = fecCtx->fecParams.meshSizeW;
425     fecCtx->fec_mesh_v_size = fecCtx->fecParams.meshSizeH;
426     alloc_fec_buf(fecCtx);
427     get_fec_buf(fecCtx);
428     fecCtx->fec_mesh_size = fecCtx->fecParams.meshSize4bin;
429     LOGI_AFEC("en: %d, mode(%d), bypass(%d), correct_level(%d), direction(%d), dimen(%d-%d), mesh dimen(%d-%d), size(%d)",
430               fecCtx->fec_en,
431               fecCtx->mode,
432               fecCtx->user_config.bypass,
433               fecCtx->user_config.correct_level,
434               fecCtx->correct_direction,
435               fecCtx->src_width, fecCtx->src_height,
436               fecCtx->fec_mesh_h_size, fecCtx->fec_mesh_v_size,
437               fecCtx->fec_mesh_size);
438 
439     fecCtx->afecReadMeshThread->triger_start();
440     fecCtx->afecReadMeshThread->start();
441     if (!fecCtx->fec_en)
442         return XCAM_RETURN_NO_ERROR;
443 #else
444     fecCtx->fec_mesh_size =
445         cal_fec_mesh(fecCtx->src_width, fecCtx->src_height, fecCtx->mesh_density,
446                      fecCtx->fec_mesh_h_size, fecCtx->fec_mesh_v_size);
447 
448     LOGI_AFEC("(%s) en: %d, user_en: %d, correct_level: %d, dimen: %d-%d, mesh dimen: %d-%d, size: %d",
449               fecCtx->meshfile, fecCtx->fec_en,
450               fecCtx->user_config.en, fecCtx->user_config.correct_level,
451               fecCtx->src_width, fecCtx->src_height,
452               fecCtx->fec_mesh_h_size, fecCtx->fec_mesh_v_size,
453               fecCtx->fec_mesh_size);
454     if (!fecCtx->fec_en)
455         return XCAM_RETURN_NO_ERROR;
456 
457     // need realloc ?
458     if (fecCtx->meshxi) {
459         free(fecCtx->meshxi);
460         fecCtx->meshxi = NULL;
461     }
462     if (fecCtx->meshxf) {
463         free(fecCtx->meshxf);
464         fecCtx->meshxf = NULL;
465     }
466     if (fecCtx->meshyi) {
467         free(fecCtx->meshyi);
468         fecCtx->meshyi = NULL;
469     }
470     if (fecCtx->meshyf) {
471         free(fecCtx->meshyf);
472         fecCtx->meshyf = NULL;
473     }
474     fecCtx->meshxi = (unsigned short*)malloc(fecCtx->fec_mesh_size * sizeof(unsigned short));
475     fecCtx->meshxf = (unsigned char*)malloc(fecCtx->fec_mesh_size * sizeof(unsigned char));
476     fecCtx->meshyi = (unsigned short*)malloc(fecCtx->fec_mesh_size * sizeof(unsigned short));
477     fecCtx->meshyf = (unsigned char*)malloc(fecCtx->fec_mesh_size * sizeof(unsigned char));
478 
479 #endif
480     read_mesh_table(fecCtx, fecCtx->user_config.correct_level);
481     fecCtx->eState = FEC_STATE_INITIALIZED;
482 
483     return XCAM_RETURN_NO_ERROR;
484 }
485 
486 static XCamReturn
pre_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)487 pre_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
488 {
489     return XCAM_RETURN_NO_ERROR;
490 }
491 
492 static XCamReturn
processing(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)493 processing(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
494 {
495     FECHandle_t hFEC = (FECHandle_t)inparams->ctx->hFEC;
496     FECContext_t* fecCtx = (FECContext_t*)hFEC;
497     RkAiqAlgoProcAfec* fecProcParams = (RkAiqAlgoProcAfec*)inparams;
498     RkAiqAlgoProcResAfec* fecPreOut = (RkAiqAlgoProcResAfec*)outparams;
499 
500     if (!fecCtx->fec_en)
501         return XCAM_RETURN_NO_ERROR;
502 
503     fecPreOut->afec_result->sw_fec_en = fecCtx->fec_en;
504     fecPreOut->afec_result->crop_en = 0;
505     fecPreOut->afec_result->crop_width = 0;
506     fecPreOut->afec_result->crop_height = 0;
507     fecPreOut->afec_result->mesh_density = fecCtx->mesh_density;
508     fecPreOut->afec_result->mesh_size = fecCtx->fec_mesh_size;
509     // TODO: should check the fec mode,
510     // if mode == RK_AIQ_ISPP_STATIC_FEC_WORKING_MODE_STABLIZATION
511     // params may be changed
512     fecCtx->eState = FEC_STATE_RUNNING;
513 
514     if (inparams->u.proc.init) {
515         outparams->cfg_update = true;
516     } else {
517 
518         if (fecCtx->isAttribUpdated) {
519             fecCtx->isAttribUpdated = false;
520             outparams->cfg_update = true;
521         } else {
522             outparams->cfg_update = false;
523         }
524 
525         LOGV_AFEC("en(%d), bypass(%d), level(%d), direction(%d), result update(%d)\n",
526                 fecCtx->fec_en,
527                 fecCtx->user_config.bypass,
528                 fecCtx->correct_level,
529                 fecCtx->correct_direction,
530                 outparams->cfg_update);
531     }
532 
533     if (outparams->cfg_update) {
534         //memcpy(fecPreOut->afec_result.meshxi, fecCtx->meshxi,
535         //       fecCtx->fec_mesh_size * sizeof(unsigned short));
536         //memcpy(fecPreOut->afec_result.meshxf, fecCtx->meshxf,
537         //       fecCtx->fec_mesh_size * sizeof(unsigned char));
538         //memcpy(fecPreOut->afec_result.meshyi, fecCtx->meshyi,
539         //       fecCtx->fec_mesh_size * sizeof(unsigned short));
540         //memcpy(fecPreOut->afec_result.meshyf, fecCtx->meshyf,
541         //       fecCtx->fec_mesh_size * sizeof(unsigned char));
542 
543         if (fecCtx->fec_mem_info == NULL) {
544             LOGE_AFEC("%s: no available fec buf!", __FUNCTION__);
545             outparams->cfg_update = false;
546             return XCAM_RETURN_NO_ERROR;
547         }
548         fecPreOut->afec_result->mesh_buf_fd = fecCtx->fec_mem_info->fd;
549         fecCtx->fec_mem_info->state[0] = 1; //mark that this buf is using.
550     }
551 
552     return XCAM_RETURN_NO_ERROR;
553 }
554 
555 static XCamReturn
post_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)556 post_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
557 {
558     return XCAM_RETURN_NO_ERROR;
559 }
560 
561 RkAiqAlgoDescription g_RkIspAlgoDescAfec = {
562     .common = {
563         .version = RKISP_ALGO_AFEC_VERSION,
564         .vendor  = RKISP_ALGO_AFEC_VENDOR,
565         .description = RKISP_ALGO_AFEC_DESCRIPTION,
566         .type    = RK_AIQ_ALGO_TYPE_AFEC,
567         .id      = 0,
568         .create_context  = create_context,
569         .destroy_context = destroy_context,
570     },
571     .prepare = prepare,
572     .pre_process = NULL,
573     .processing = processing,
574     .post_process = NULL,
575 };
576 
577 RKAIQ_END_DECLARE
578 
loop()579 bool RKAiqAfecThread::loop()
580 {
581     XCamReturn ret = XCAM_RETURN_NO_ERROR;
582     ENTER_ANALYZER_FUNCTION();
583 
584     const static int32_t timeout = -1;
585     SmartPtr<rk_aiq_fec_cfg_t> attrib = mAttrQueue.pop (timeout);
586 
587     if (!attrib.ptr()) {
588         LOGW_ANALYZER("RKAiqAfecThread got empty attrib, stop thread");
589         return false;
590     }
591 
592     if (hFEC->eState != FEC_STATE_RUNNING) {
593         hFEC->isAttribUpdated = true;
594         return true;
595     }
596     get_fec_buf(hFEC);
597     if (hFEC->user_config.bypass) {
598         ret = read_mesh_table(hFEC, 0);
599     } else {
600         ret = read_mesh_table(hFEC, attrib->correct_level);
601         hFEC->correct_level = attrib->correct_level;
602     }
603 
604     if (ret == XCAM_RETURN_NO_ERROR) {
605         hFEC->isAttribUpdated = true;
606         return true;
607     }
608 
609     LOGE_ANALYZER("RKAiqAfecThread failed to read mesh table!");
610 
611     EXIT_ANALYZER_FUNCTION();
612 
613     return false;
614 }
615