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