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