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