xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/algos/amerge/rk_aiq_algo_amerge_itf.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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