1 /*
2  * rk_aiq_algo_anr_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 "abayer2dnrV23/rk_aiq_abayer2dnr_algo_itf_v23.h"
21 #include "abayer2dnrV23/rk_aiq_abayer2dnr_algo_v23.h"
22 #include "rk_aiq_algo_types.h"
23 
24 RKAIQ_BEGIN_DECLARE
25 
26 typedef struct _RkAiqAlgoContext {
27     Abayer2dnr_Context_V23_t AbayernrCtx;
28 } RkAiqAlgoContext;
29 
30 
31 static XCamReturn
create_context(RkAiqAlgoContext ** context,const AlgoCtxInstanceCfg * cfg)32 create_context(RkAiqAlgoContext **context, const AlgoCtxInstanceCfg* cfg)
33 {
34 
35     XCamReturn result = XCAM_RETURN_NO_ERROR;
36     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
37 
38 #if 1
39     Abayer2dnr_Context_V23_t* pAbayernrCtx = NULL;
40 #if (ABAYER2DNR_USE_JSON_FILE_V23)
41     Abayer2dnr_result_V23_t ret = Abayer2dnr_Init_V23(&pAbayernrCtx, cfg->calibv2);
42 #else
43     Abayer2dnr_result_V23_t ret = Abayer2dnr_Init_V23(&pAbayernrCtx, cfg->calib);
44 #endif
45     if(ret != ABAYER2DNR_V23_RET_SUCCESS) {
46         result = XCAM_RETURN_ERROR_FAILED;
47         LOGE_ANR("%s: Initializaion ANR failed (%d)\n", __FUNCTION__, ret);
48     } else {
49         *context = (RkAiqAlgoContext *)(pAbayernrCtx);
50     }
51 #endif
52 
53     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
54     return result;
55 }
56 
57 static XCamReturn
destroy_context(RkAiqAlgoContext * context)58 destroy_context(RkAiqAlgoContext *context)
59 {
60     XCamReturn result = XCAM_RETURN_NO_ERROR;
61 
62     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
63 
64 #if 1
65     Abayer2dnr_Context_V23_t* pAbayernrCtx = (Abayer2dnr_Context_V23_t*)context;
66     Abayer2dnr_result_V23_t ret = Abayer2dnr_Release_V23(pAbayernrCtx);
67     if(ret != ABAYER2DNR_V23_RET_SUCCESS) {
68         result = XCAM_RETURN_ERROR_FAILED;
69         LOGE_ANR("%s: release ANR failed (%d)\n", __FUNCTION__, ret);
70     }
71 #endif
72 
73     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
74     return result;
75 }
76 
77 static XCamReturn
prepare(RkAiqAlgoCom * params)78 prepare(RkAiqAlgoCom* params)
79 {
80     XCamReturn result = XCAM_RETURN_NO_ERROR;
81 
82     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
83 
84     Abayer2dnr_Context_V23_t* pAbayernrCtx = (Abayer2dnr_Context_V23_t *)params->ctx;
85     RkAiqAlgoConfigAbayer2dnrV23* pCfgParam = (RkAiqAlgoConfigAbayer2dnrV23*)params;
86     pAbayernrCtx->prepare_type = params->u.prepare.conf_type;
87 
88     if(!!(params->u.prepare.conf_type & RK_AIQ_ALGO_CONFTYPE_UPDATECALIB )) {
89 #if ABAYER2DNR_USE_JSON_FILE_V23
90         void *pCalibDbV2 = (void*)(pCfgParam->com.u.prepare.calibv2);
91         CalibDbV2_Bayer2dnrV23_t *bayernr_v23 = (CalibDbV2_Bayer2dnrV23_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDbV2, bayer2dnr_v23));
92         pAbayernrCtx->bayernr_v23 = *bayernr_v23;
93 #endif
94         pAbayernrCtx->isIQParaUpdate = true;
95         pAbayernrCtx->isReCalculate |= 1;
96     }
97 
98     Abayer2dnr_result_V23_t ret = Abayer2dnr_Prepare_V23(pAbayernrCtx, &pCfgParam->stArawnrConfig);
99     if(ret != ABAYER2DNR_V23_RET_SUCCESS) {
100         result = XCAM_RETURN_ERROR_FAILED;
101         LOGE_ANR("%s: config ANR failed (%d)\n", __FUNCTION__, ret);
102     }
103 
104     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
105     return result;
106 }
107 #if 0
108 static XCamReturn
109 pre_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
110 {
111     XCamReturn result = XCAM_RETURN_NO_ERROR;
112     bool oldGrayMode = false;
113 
114     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
115     Abayer2dnr_Context_V23_t* pAbayernrCtx = (Abayer2dnr_Context_V23_t *)inparams->ctx;
116 
117     RkAiqAlgoPreAbayer2dnrV23* pAbayernrPreParams = (RkAiqAlgoPreAbayer2dnrV23*)inparams;
118 
119     oldGrayMode = pAbayernrCtx->isGrayMode;
120     if (pAbayernrPreParams->com.u.proc.gray_mode) {
121         pAbayernrCtx->isGrayMode = true;
122     } else {
123         pAbayernrCtx->isGrayMode = false;
124     }
125 
126     if(oldGrayMode != pAbayernrCtx->isGrayMode) {
127         pAbayernrCtx->isReCalculate |= 1;
128     }
129 
130     Abayer2dnr_result_V23_t ret = Abayer2dnr_PreProcess_V23(pAbayernrCtx);
131     if(ret != ABAYER2DNR_V23_RET_SUCCESS) {
132         result = XCAM_RETURN_ERROR_FAILED;
133         LOGE_ANR("%s: ANRPreProcess failed (%d)\n", __FUNCTION__, ret);
134     }
135 
136     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
137     return result;
138 }
139 #endif
140 static XCamReturn
processing(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)141 processing(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
142 {
143     XCamReturn result = XCAM_RETURN_NO_ERROR;
144     int delta_iso = 0;
145 
146     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
147 
148 #if 1
149     RkAiqAlgoProcAbayer2dnrV23* pAbayernrProcParams = (RkAiqAlgoProcAbayer2dnrV23*)inparams;
150     RkAiqAlgoProcResAbayer2dnrV23* pAbayernrProcResParams = (RkAiqAlgoProcResAbayer2dnrV23*)outparams;
151     Abayer2dnr_Context_V23_t* pAbayernrCtx = (Abayer2dnr_Context_V23_t *)inparams->ctx;
152     Abayer2dnr_ExpInfo_V23_t stExpInfo;
153     memset(&stExpInfo, 0x00, sizeof(Abayer2dnr_ExpInfo_V23_t));
154 
155     bool oldGrayMode = false;
156     oldGrayMode = pAbayernrCtx->isGrayMode;
157     if (inparams->u.proc.gray_mode) {
158         pAbayernrCtx->isGrayMode = true;
159     } else {
160         pAbayernrCtx->isGrayMode = false;
161     }
162 
163     if(oldGrayMode != pAbayernrCtx->isGrayMode) {
164         pAbayernrCtx->isReCalculate |= 1;
165     }
166 
167     Abayer2dnr_result_V23_t ret = Abayer2dnr_PreProcess_V23(pAbayernrCtx);
168     if(ret != ABAYER2DNR_V23_RET_SUCCESS) {
169         result = XCAM_RETURN_ERROR_FAILED;
170         LOGE_ANR("%s: ANRPreProcess failed (%d)\n", __FUNCTION__, ret);
171     }
172 
173     LOGD_ANR("%s:%d init:%d hdr mode:%d  \n",
174              __FUNCTION__, __LINE__,
175              inparams->u.proc.init,
176              pAbayernrProcParams->hdr_mode);
177 
178     stExpInfo.hdr_mode = 0; //pAnrProcParams->hdr_mode;
179     for(int i = 0; i < 3; i++) {
180         stExpInfo.arIso[i] = 50;
181         stExpInfo.arAGain[i] = 1.0;
182         stExpInfo.arDGain[i] = 1.0;
183         stExpInfo.arTime[i] = 0.01;
184     }
185     stExpInfo.blc_ob_predgain = 1.0;
186     stExpInfo.bayertnr_en = 1;
187 
188     if(pAbayernrProcParams != NULL) {
189         stExpInfo.blc_ob_predgain = pAbayernrProcParams->stAblcV32_proc_res->isp_ob_predgain;
190         stExpInfo.bayertnr_en = pAbayernrProcParams->bayertnr_en;
191         if(stExpInfo.blc_ob_predgain != pAbayernrCtx->stExpInfo.blc_ob_predgain
192                 || stExpInfo.bayertnr_en != pAbayernrCtx->stExpInfo.bayertnr_en) {
193             pAbayernrCtx->isReCalculate |= 1;
194         }
195     }
196 
197     if(pAbayernrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
198         stExpInfo.hdr_mode = 0;
199     } else if(pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR
200               || pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR ) {
201         stExpInfo.hdr_mode = 1;
202     } else if(pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR
203               || pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR ) {
204         stExpInfo.hdr_mode = 2;
205     }
206     stExpInfo.snr_mode = 0;
207     stExpInfo.gray_mode = pAbayernrCtx->isGrayMode;
208 
209 #if 0// TODO Merge:
210     XCamVideoBuffer* xCamAePreRes = pAbayernrProcParams->com.u.proc.res_comb->ae_pre_res;
211     RkAiqAlgoPreResAe* pAEPreRes = nullptr;
212     if (xCamAePreRes) {
213         // xCamAePreRes->ref(xCamAePreRes);
214         pAEPreRes = (RkAiqAlgoPreResAe*)xCamAePreRes->map(xCamAePreRes);
215         if (!pAEPreRes) {
216             LOGE_ANR("ae pre result is null");
217         } else {
218 
219         }
220     }
221 #endif
222 
223     RKAiqAecExpInfo_t *curExp = pAbayernrProcParams->com.u.proc.curExp;
224     if(curExp != NULL) {
225         stExpInfo.snr_mode = curExp->CISFeature.SNR;
226         if(pAbayernrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
227             stExpInfo.hdr_mode = 0;
228             if(curExp->LinearExp.exp_real_params.analog_gain < 1.0) {
229                 stExpInfo.arAGain[0] = 1.0;
230                 LOGW_ANR("leanr mode again is wrong, use 1.0 instead\n");
231             } else {
232                 stExpInfo.arAGain[0] = curExp->LinearExp.exp_real_params.analog_gain;
233             }
234             if(curExp->LinearExp.exp_real_params.digital_gain < 1.0) {
235                 stExpInfo.arDGain[0] = 1.0;
236                 LOGW_ANR("leanr mode dgain is wrong, use 1.0 instead\n");
237             } else {
238                 stExpInfo.arDGain[0] = curExp->LinearExp.exp_real_params.digital_gain;
239             }
240             if(curExp->LinearExp.exp_real_params.isp_dgain < 1.0) {
241                 stExpInfo.isp_dgain[0] = 1.0;
242                 LOGW_ANR("leanr mode isp_dgain is wrong, use 1.0 instead\n");
243             } else {
244                 stExpInfo.isp_dgain[0] = curExp->LinearExp.exp_real_params.isp_dgain;
245             }
246             float tmp_preDgain = stExpInfo.blc_ob_predgain;
247             if(tmp_preDgain < 1.0) {
248                 tmp_preDgain = 1.0;
249             }
250             // stExpInfo.arAGain[0] = 64.0;
251             stExpInfo.arTime[0] = curExp->LinearExp.exp_real_params.integration_time;
252             stExpInfo.arIso[0] = stExpInfo.arAGain[0] * stExpInfo.arDGain[0] * tmp_preDgain * 50 * stExpInfo.isp_dgain[0];
253         } else {
254             for(int i = 0; i < 3; i++) {
255                 if(curExp->HdrExp[i].exp_real_params.analog_gain < 1.0) {
256                     stExpInfo.arAGain[i] = 1.0;
257                     LOGW_ANR("hdr mode again is wrong, use 1.0 instead\n");
258                 } else {
259                     stExpInfo.arAGain[i] = curExp->HdrExp[i].exp_real_params.analog_gain;
260                 }
261                 if(curExp->HdrExp[i].exp_real_params.digital_gain < 1.0) {
262                     stExpInfo.arDGain[i] = 1.0;
263                     LOGW_ANR("hdr mode dgain is wrong, use 1.0 instead\n");
264                 } else {
265                     stExpInfo.arDGain[i] = curExp->HdrExp[i].exp_real_params.digital_gain;
266                 }
267                 if(curExp->HdrExp[i].exp_real_params.isp_dgain < 1.0) {
268                     stExpInfo.isp_dgain[i] = 1.0;
269                     LOGW_ANR("hdr mode isp_dgain is wrong, use 1.0 instead\n");
270                 } else {
271                     stExpInfo.isp_dgain[i] = curExp->HdrExp[i].exp_real_params.isp_dgain;
272                 }
273                 stExpInfo.blc_ob_predgain = 1.0;
274                 stExpInfo.arTime[i] = curExp->HdrExp[i].exp_real_params.integration_time;
275                 stExpInfo.arIso[i] = stExpInfo.arAGain[i] * stExpInfo.arDGain[i] * 50 * stExpInfo.isp_dgain[i];
276 
277                 LOGD_ANR("%s:%d index:%d again:%f dgain:%f isp_dgain:%f time:%f iso:%d hdr_mode:%d\n",
278                          __FUNCTION__, __LINE__,
279                          i,
280                          stExpInfo.arAGain[i],
281                          stExpInfo.arDGain[i],
282                          stExpInfo.isp_dgain[i],
283                          stExpInfo.arTime[i],
284                          stExpInfo.arIso[i],
285                          stExpInfo.hdr_mode);
286             }
287         }
288     } else {
289         LOGE_ANR("%s:%d curExp is NULL, so use default instead \n", __FUNCTION__, __LINE__);
290     }
291 
292 
293 #if 0
294     static int anr_cnt = 0;
295     anr_cnt++;
296 
297     if(anr_cnt % 50 == 0) {
298         for(int i = 0; i < stExpInfo.hdr_mode + 1; i++) {
299             printf("%s:%d index:%d again:%f dgain:%f time:%f iso:%d hdr_mode:%d snr_mode:%d\n",
300                    __FUNCTION__, __LINE__,
301                    i,
302                    stExpInfo.arAGain[i],
303                    stExpInfo.arDGain[i],
304                    stExpInfo.arTime[i],
305                    stExpInfo.arIso[i],
306                    stExpInfo.hdr_mode,
307                    stExpInfo.snr_mode);
308         }
309     }
310 #endif
311     delta_iso = abs(stExpInfo.arIso[stExpInfo.hdr_mode] - pAbayernrCtx->stExpInfo.arIso[stExpInfo.hdr_mode]);
312     if(delta_iso > ABAYER2DNRV23_RECALCULATE_DELTA_ISO) {
313         pAbayernrCtx->isReCalculate |= 1;
314     }
315 
316     if(pAbayernrCtx->isReCalculate) {
317         Abayer2dnr_result_V23_t ret = Abayer2dnr_Process_V23(pAbayernrCtx, &stExpInfo);
318         if(ret != ABAYER2DNR_V23_RET_SUCCESS) {
319             result = XCAM_RETURN_ERROR_FAILED;
320             LOGE_ANR("%s: processing ANR failed (%d)\n", __FUNCTION__, ret);
321         }
322 
323         Abayer2dnr_GetProcResult_V23(pAbayernrCtx, &pAbayernrProcResParams->stArawnrProcResult);
324 
325         LOGD_ANR("recalculate: %d delta_iso:%d \n ", pAbayernrCtx->isReCalculate, delta_iso);
326 
327         pAbayernrProcResParams->res_com.cfg_update = true;
328     } else {
329         pAbayernrProcResParams->res_com.cfg_update = false;
330     }
331 
332     pAbayernrCtx->isReCalculate = 0;
333 
334 #endif
335 
336     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
337     return XCAM_RETURN_NO_ERROR;
338 }
339 
340 static XCamReturn
post_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)341 post_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
342 {
343     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
344 
345     //nothing todo now
346 
347     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
348     return XCAM_RETURN_NO_ERROR;
349 }
350 
351 RkAiqAlgoDescription g_RkIspAlgoDescAbayer2dnrV23 = {
352     .common = {
353         .version = RKISP_ALGO_ABAYER2DNR_VERSION_V23,
354         .vendor  = RKISP_ALGO_ABAYER2DNR_VENDOR_V23,
355         .description = RKISP_ALGO_ABAYER2DNR_DESCRIPTION_V23,
356         .type    = RK_AIQ_ALGO_TYPE_ARAWNR,
357         .id      = 0,
358         .create_context  = create_context,
359         .destroy_context = destroy_context,
360     },
361     .prepare = prepare,
362     .pre_process = NULL,
363     .processing = processing,
364     .post_process = NULL,
365 };
366 
367 RKAIQ_END_DECLARE
368