1 /*
2 * rk_aiq_algo_camgroup_amerge_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 "rk_aiq_algo_camgroup_types.h"
21 #include "xcam_log.h"
22 #if RKAIQ_HAVE_MERGE_V10
23 #include "amerge/rk_aiq_amerge_algo_v10.h"
24 #endif
25 #if RKAIQ_HAVE_MERGE_V11
26 #include "amerge/rk_aiq_amerge_algo_v11.h"
27 #endif
28 #if RKAIQ_HAVE_MERGE_V12
29 #include "amerge/rk_aiq_amerge_algo_v12.h"
30 #endif
31 #include "algos/amerge/rk_aiq_types_amerge_algo_prvt.h"
32 #include "algos/amerge/rk_aiq_algo_amerge_itf.h"
33
34
35
36 RKAIQ_BEGIN_DECLARE
37
38
AmergeCreateCtx(RkAiqAlgoContext ** context,const AlgoCtxInstanceCfg * cfg)39 static XCamReturn AmergeCreateCtx(RkAiqAlgoContext **context, const AlgoCtxInstanceCfg* cfg)
40 {
41 LOG1_AMERGE("%s:Enter!\n", __FUNCTION__);
42 XCamReturn ret = XCAM_RETURN_NO_ERROR;
43
44 AlgoCtxInstanceCfgCamGroup* instanc_int = (AlgoCtxInstanceCfgCamGroup*)cfg;
45 AmergeContext_t* pAmergeGrpCtx = NULL;
46
47 ret = AmergeInit(&pAmergeGrpCtx, (CamCalibDbV2Context_t*)(instanc_int->s_calibv2));
48
49 if (ret != XCAM_RETURN_NO_ERROR) {
50 LOGE_AMERGE("%s(%d) Amerge Init failed: %d", __FUNCTION__, __LINE__, ret);
51 return(XCAM_RETURN_ERROR_FAILED);
52 }
53 *context = (RkAiqAlgoContext *)(pAmergeGrpCtx);
54
55 LOG1_AMERGE("%s:Exit!\n", __FUNCTION__);
56 return(ret);
57 }
58
AmergeDestroyCtx(RkAiqAlgoContext * context)59 static XCamReturn AmergeDestroyCtx(RkAiqAlgoContext *context)
60 {
61 LOG1_AMERGE("%s:Enter!\n", __FUNCTION__);
62 XCamReturn ret = XCAM_RETURN_NO_ERROR;
63
64 if(context != NULL) {
65 AmergeContext_t* pAmergeGrpCtx = (AmergeContext_t*)context;
66 ret = AmergeRelease(pAmergeGrpCtx);
67 if (ret != XCAM_RETURN_NO_ERROR) {
68 LOGE_AMERGE("%s(%d) Amerge Release failed: %d", __FUNCTION__, __LINE__, ret);
69 return(XCAM_RETURN_ERROR_FAILED);
70 }
71 context = NULL;
72 }
73
74 LOG1_AMERGE("%s:Exit!\n", __FUNCTION__);
75 return(ret);
76 }
77
AmergePrepare(RkAiqAlgoCom * params)78 static XCamReturn AmergePrepare(RkAiqAlgoCom* params)
79 {
80 LOG1_AMERGE("%s:Enter!\n", __FUNCTION__);
81 XCamReturn ret = XCAM_RETURN_NO_ERROR;
82
83 AmergeContext_t* pAmergeGrpCtx = (AmergeContext_t*)params->ctx;
84 RkAiqAlgoCamGroupPrepare* pAmergePrepParams = (RkAiqAlgoCamGroupPrepare*)params;
85 const CamCalibDbV2Context_t* pCalibDb = pAmergePrepParams->s_calibv2;
86
87 if (pAmergePrepParams->gcom.com.u.prepare.working_mode < RK_AIQ_WORKING_MODE_ISP_HDR2)
88 pAmergeGrpCtx->FrameNumber = LINEAR_NUM;
89 else if (pAmergePrepParams->gcom.com.u.prepare.working_mode < RK_AIQ_WORKING_MODE_ISP_HDR3 &&
90 pAmergePrepParams->gcom.com.u.prepare.working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2)
91 pAmergeGrpCtx->FrameNumber = HDR_2X_NUM;
92 else
93 pAmergeGrpCtx->FrameNumber = HDR_3X_NUM;
94
95 if (pAmergeGrpCtx->FrameNumber == HDR_2X_NUM || pAmergeGrpCtx->FrameNumber == HDR_3X_NUM) {
96 if (!!(params->u.prepare.conf_type & RK_AIQ_ALGO_CONFTYPE_UPDATECALIB)) {
97 LOGI_AMERGE("%s: Amerge Reload Para!\n", __FUNCTION__);
98 #if RKAIQ_HAVE_MERGE_V10
99 CalibDbV2_merge_v10_t* calibv2_amerge_calib =
100 (CalibDbV2_merge_v10_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDb, amerge_calib));
101 memcpy(&pAmergeGrpCtx->mergeAttrV10.stAuto, calibv2_amerge_calib,
102 sizeof(CalibDbV2_merge_v10_t));
103 #endif
104 #if RKAIQ_HAVE_MERGE_V11
105 CalibDbV2_merge_v11_t* calibv2_amerge_calib =
106 (CalibDbV2_merge_v11_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDb, amerge_calib));
107 memcpy(&pAmergeGrpCtx->mergeAttrV11.stAuto, calibv2_amerge_calib,
108 sizeof(CalibDbV2_merge_v11_t));
109 #endif
110 #if RKAIQ_HAVE_MERGE_V12
111 CalibDbV2_merge_v12_t* calibv2_amerge_calib =
112 (CalibDbV2_merge_v12_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDb, amerge_calib));
113 memcpy(&pAmergeGrpCtx->mergeAttrV12.stAuto, calibv2_amerge_calib,
114 sizeof(CalibDbV2_merge_v12_t));
115 #endif
116 pAmergeGrpCtx->ifReCalcStAuto = true;
117 } else if (params->u.prepare.conf_type & RK_AIQ_ALGO_CONFTYPE_CHANGERES) {
118 pAmergeGrpCtx->isCapture = true;
119 }
120
121 if (/* !params->u.prepare.reconfig*/ true) {
122 AmergeStop(pAmergeGrpCtx); // stop firstly for re-preapre
123 ret = AmergeStart(pAmergeGrpCtx);
124 if (ret != XCAM_RETURN_NO_ERROR) {
125 LOGE_AMERGE("%s(%d) Amerge Start failed: %d\n", __FUNCTION__, __LINE__, ret);
126 return (XCAM_RETURN_ERROR_FAILED);
127 }
128 }
129 }
130
131 LOG1_AMERGE("%s:Exit!\n", __FUNCTION__);
132 return(ret);
133 }
134
AmergeProcess(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)135 static XCamReturn AmergeProcess(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
136 {
137 LOG1_AMERGE("%s:Enter!\n", __FUNCTION__);
138 XCamReturn ret = XCAM_RETURN_NO_ERROR;
139 bool bypass_tuning_process = true;
140 bool bypass_expo_process = true;
141
142 AmergeContext_t* pAmergeGrpCtx = (AmergeContext_t*)inparams->ctx;
143 pAmergeGrpCtx->FrameID = inparams->frame_id;
144 RkAiqAlgoCamGroupProcIn* pAmergeGrpParams = (RkAiqAlgoCamGroupProcIn*)inparams;
145 RkAiqAlgoCamGroupProcOut* pAmergeGrpProcRes = (RkAiqAlgoCamGroupProcOut*)outparams;
146
147 if (pAmergeGrpCtx->FrameNumber == HDR_2X_NUM || pAmergeGrpCtx->FrameNumber == HDR_3X_NUM) {
148 LOGD_AMERGE("/#####################################Amerge Group Start#####################################/ \n");
149
150 if (pAmergeGrpCtx->isCapture) {
151 LOGD_AMERGE("%s: It's capturing, using pre frame params\n", __func__);
152 pAmergeGrpCtx->isCapture = false;
153 } else {
154 // get LongFrmMode
155 RkAiqAlgoProcResAeShared_t* pAEProcRes = &pAmergeGrpParams->camgroupParmasArray[0]->aec._aeProcRes;
156 pAmergeGrpCtx->NextData.CtrlData.ExpoData.LongFrmMode =
157 pAEProcRes->LongFrmMode &&
158 (pAmergeGrpCtx->FrameNumber != LINEAR_NUM);
159
160 // get ae pre res
161 XCamVideoBuffer* xCamAePreRes = pAmergeGrpParams->camgroupParmasArray[0]->aec._aePreRes;
162 RkAiqAlgoPreResAe* pAEPreRes = NULL;
163 if (xCamAePreRes) {
164 pAEPreRes = (RkAiqAlgoPreResAe*)xCamAePreRes->map(xCamAePreRes);
165 if (pAmergeGrpCtx->FrameNumber == LINEAR_NUM)
166 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv =
167 pAEPreRes->ae_pre_res_rk.GlobalEnvLv[0];
168 else if (pAmergeGrpCtx->FrameNumber == HDR_2X_NUM ||
169 pAmergeGrpCtx->FrameNumber == HDR_3X_NUM)
170 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv =
171 pAEPreRes->ae_pre_res_rk.GlobalEnvLv[1];
172 else
173 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv = ENVLVMIN;
174 // Normalize the current envLv for AEC
175 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv =
176 (pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv - MIN_ENV_LV) /
177 (MAX_ENV_LV - MIN_ENV_LV);
178 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv = LIMIT_VALUE(
179 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv, ENVLVMAX, ENVLVMIN);
180 } else {
181 pAmergeGrpCtx->NextData.CtrlData.ExpoData.EnvLv = ENVLVMIN;
182 LOGW_AMERGE("%s: ae Pre result is null!!!\n", __FUNCTION__);
183 }
184
185 // get motion coef
186 pAmergeGrpCtx->NextData.CtrlData.MoveCoef = MOVE_COEF_DEFAULT;
187
188 // get bypass_tuning_process
189 bypass_tuning_process = AmergeByPassProcessing(pAmergeGrpCtx);
190
191 // expo para process
192 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SGain =
193 pAmergeGrpParams->camgroupParmasArray[0]
194 ->aec._effAecExpInfo.HdrExp[0]
195 .exp_real_params.analog_gain *
196 pAmergeGrpParams->camgroupParmasArray[0]
197 ->aec._effAecExpInfo.HdrExp[0]
198 .exp_real_params.digital_gain *
199 pAmergeGrpParams->camgroupParmasArray[0]
200 ->aec._effAecExpInfo.HdrExp[0]
201 .exp_real_params.isp_dgain;
202 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MGain =
203 pAmergeGrpParams->camgroupParmasArray[0]
204 ->aec._effAecExpInfo.HdrExp[1]
205 .exp_real_params.analog_gain *
206 pAmergeGrpParams->camgroupParmasArray[0]
207 ->aec._effAecExpInfo.HdrExp[1]
208 .exp_real_params.digital_gain *
209 pAmergeGrpParams->camgroupParmasArray[0]
210 ->aec._effAecExpInfo.HdrExp[1]
211 .exp_real_params.isp_dgain;
212
213 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SExpo =
214 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SGain *
215 pAmergeGrpParams->camgroupParmasArray[0]
216 ->aec._effAecExpInfo.HdrExp[0]
217 .exp_real_params.integration_time;
218 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MExpo =
219 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MGain *
220 pAmergeGrpParams->camgroupParmasArray[0]
221 ->aec._effAecExpInfo.HdrExp[1]
222 .exp_real_params.integration_time;
223 if (pAmergeGrpCtx->FrameNumber == HDR_2X_NUM) {
224 pAmergeGrpCtx->NextData.CtrlData.ExpoData.LExpo =
225 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MExpo;
226 } else if (pAmergeGrpCtx->FrameNumber == HDR_3X_NUM) {
227 pAmergeGrpCtx->NextData.CtrlData.ExpoData.LExpo =
228 pAmergeGrpParams->camgroupParmasArray[0]
229 ->aec._effAecExpInfo.HdrExp[2]
230 .exp_real_params.analog_gain *
231 pAmergeGrpParams->camgroupParmasArray[0]
232 ->aec._effAecExpInfo.HdrExp[2]
233 .exp_real_params.digital_gain *
234 pAmergeGrpParams->camgroupParmasArray[0]
235 ->aec._effAecExpInfo.HdrExp[2]
236 .exp_real_params.isp_dgain *
237 pAmergeGrpParams->camgroupParmasArray[0]
238 ->aec._effAecExpInfo.HdrExp[2]
239 .exp_real_params.integration_time;
240 }
241 pAmergeGrpCtx->NextData.CtrlData.ExpoData.ISO =
242 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MGain * ISOMIN;
243 pAmergeGrpCtx->NextData.CtrlData.ExpoData.ISO =
244 LIMIT_VALUE(pAmergeGrpCtx->NextData.CtrlData.ExpoData.ISO, ISOMAX, ISOMIN);
245 LOGV_AMERGE("%s: nextFrame: sexp: %f-%f, mexp: %f-%f, lexp: %f-%f\n", __FUNCTION__,
246 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SGain,
247 pAmergeGrpParams->camgroupParmasArray[0]
248 ->aec._effAecExpInfo.HdrExp[0]
249 .exp_real_params.integration_time,
250 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MGain,
251 pAmergeGrpParams->camgroupParmasArray[0]
252 ->aec._effAecExpInfo.HdrExp[1]
253 .exp_real_params.integration_time,
254 pAmergeGrpParams->camgroupParmasArray[0]
255 ->aec._effAecExpInfo.HdrExp[2]
256 .exp_real_params.analog_gain *
257 pAmergeGrpParams->camgroupParmasArray[0]
258 ->aec._effAecExpInfo.HdrExp[2]
259 .exp_real_params.digital_gain *
260 pAmergeGrpParams->camgroupParmasArray[0]
261 ->aec._effAecExpInfo.HdrExp[2]
262 .exp_real_params.isp_dgain,
263 pAmergeGrpParams->camgroupParmasArray[0]
264 ->aec._effAecExpInfo.HdrExp[2]
265 .exp_real_params.integration_time);
266 if (pAmergeGrpCtx->NextData.CtrlData.ExpoData.SExpo > FLT_EPSILON)
267 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS =
268 pAmergeGrpCtx->NextData.CtrlData.ExpoData.LExpo /
269 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SExpo;
270 else
271 LOGE_AMERGE("%s(%d): Short frame for merge expo sync is ERROR!!!\n", __FUNCTION__,
272 __LINE__);
273 if (pAmergeGrpCtx->NextData.CtrlData.ExpoData.MExpo > FLT_EPSILON)
274 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM =
275 pAmergeGrpCtx->NextData.CtrlData.ExpoData.LExpo /
276 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MExpo;
277 else
278 LOGE_AMERGE("%s(%d): Middle frame for merge expo sync is ERROR!!!\n", __FUNCTION__,
279 __LINE__);
280 //clip for long frame mode
281 if (pAmergeGrpCtx->NextData.CtrlData.ExpoData.LongFrmMode) {
282 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS = LONG_FRAME_MODE_RATIO;
283 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM = LONG_FRAME_MODE_RATIO;
284 }
285
286 if (pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS >= RATIO_DEFAULT &&
287 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM >= RATIO_DEFAULT) {
288 if (pAmergeGrpCtx->FrameID <= INIT_CALC_PARAMS_NUM)
289 bypass_expo_process = false;
290 else if (pAmergeGrpCtx->ifReCalcStAuto || pAmergeGrpCtx->ifReCalcStManual)
291 bypass_expo_process = false;
292 else if (!pAmergeGrpCtx->CurrData.CtrlData.ExpoData.LongFrmMode !=
293 !pAmergeGrpCtx->NextData.CtrlData.ExpoData.LongFrmMode)
294 bypass_expo_process = false;
295 #if RKAIQ_HAVE_MERGE_V10
296 else if ((pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLS -
297 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS) > FLT_EPSILON ||
298 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLS -
299 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS) < -FLT_EPSILON ||
300 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLM -
301 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM) > FLT_EPSILON ||
302 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLM -
303 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM) < -FLT_EPSILON)
304 bypass_expo_process = false;
305 #endif
306 #if RKAIQ_HAVE_MERGE_V11 || RKAIQ_HAVE_MERGE_V12
307 else if ((pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLS -
308 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS) > FLT_EPSILON ||
309 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLS -
310 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS) < -FLT_EPSILON ||
311 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLM -
312 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM) > FLT_EPSILON ||
313 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.RatioLM -
314 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM) < -FLT_EPSILON ||
315 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.SGain -
316 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SGain) > FLT_EPSILON ||
317 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.SGain -
318 pAmergeGrpCtx->NextData.CtrlData.ExpoData.SGain) < -FLT_EPSILON ||
319 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.MGain -
320 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MGain) > FLT_EPSILON ||
321 (pAmergeGrpCtx->CurrData.CtrlData.ExpoData.MGain -
322 pAmergeGrpCtx->NextData.CtrlData.ExpoData.MGain) < -FLT_EPSILON)
323 bypass_expo_process = false;
324 #endif
325 else
326 bypass_expo_process = true;
327 } else {
328 LOGE_AMERGE("%s(%d): AE RatioLS:%f RatioLM:%f for drc expo sync is under one!!!\n",
329 __FUNCTION__, __LINE__, pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLS,
330 pAmergeGrpCtx->NextData.CtrlData.ExpoData.RatioLM);
331 bypass_expo_process = true;
332 }
333
334 // get tuning para process
335 if (!bypass_tuning_process)
336 AmergeTuningProcessing(pAmergeGrpCtx,
337 pAmergeGrpProcRes->camgroupParmasArray[0]->_amergeConfig);
338 // get expo para process
339 if (!bypass_expo_process || !bypass_tuning_process)
340 AmergeExpoProcessing(pAmergeGrpCtx, &pAmergeGrpCtx->NextData.CtrlData.ExpoData,
341 pAmergeGrpProcRes->camgroupParmasArray[0]->_amergeConfig);
342
343 if (pAmergeGrpCtx->ifReCalcStAuto) pAmergeGrpCtx->ifReCalcStAuto = false;
344 if (pAmergeGrpCtx->ifReCalcStManual) pAmergeGrpCtx->ifReCalcStManual = false;
345 outparams->cfg_update =
346 !bypass_tuning_process || !bypass_expo_process;
347 }
348
349 LOGD_AMERGE(
350 "/#####################################Amerge Group "
351 "Over#####################################/ \n");
352 } else {
353 LOGD_AMERGE("%s FrameID:%d, It's in Linear Mode, Merge function bypass_tuning_process\n",
354 __FUNCTION__, pAmergeGrpCtx->FrameID);
355 }
356
357 for (int i = 1; i < pAmergeGrpProcRes->arraySize; i++) {
358 memcpy(pAmergeGrpProcRes->camgroupParmasArray[i]->_amergeConfig,
359 pAmergeGrpProcRes->camgroupParmasArray[0]->_amergeConfig,
360 sizeof(RkAiqAmergeProcResult_t));
361 IS_UPDATE_MEM((pAmergeGrpProcRes->camgroupParmasArray[i]->_amergeConfig), pAmergeGrpParams->_offset_is_update) =
362 outparams->cfg_update;
363 }
364
365 LOG1_AMERGE("%s:Exit!\n", __FUNCTION__);
366 return(ret);
367 }
368
369 RkAiqAlgoDescription g_RkIspAlgoDescCamgroupAmerge = {
370 .common = {
371 .version = RKISP_ALGO_AMERGE_VERSION,
372 .vendor = RKISP_ALGO_AMERGE_VENDOR,
373 .description = RKISP_ALGO_AMERGE_DESCRIPTION,
374 .type = RK_AIQ_ALGO_TYPE_AMERGE,
375 .id = 0,
376 .create_context = AmergeCreateCtx,
377 .destroy_context = AmergeDestroyCtx,
378 },
379 .prepare = AmergePrepare,
380 .pre_process = NULL,
381 .processing = AmergeProcess,
382 .post_process = NULL,
383 };
384
385 RKAIQ_END_DECLARE
386