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 "abayer2dnr2/rk_aiq_abayer2dnr_algo_itf_v2.h"
21 #include "abayer2dnr2/rk_aiq_abayer2dnr_algo_v2.h"
22 #include "rk_aiq_algo_types.h"
23 
24 RKAIQ_BEGIN_DECLARE
25 
26 typedef struct _RkAiqAlgoContext {
27     Abayer2dnr_Context_V2_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_V2_t* pAbayernrCtx = NULL;
40 #if (ABAYER2DNR_USE_JSON_FILE_V2)
41     Abayer2dnr_result_V2_t ret = Abayer2dnr_Init_V2(&pAbayernrCtx, cfg->calibv2);
42 #else
43     Abayer2dnr_result_V2_t ret = Abayer2dnr_Init_V2(&pAbayernrCtx, cfg->calib);
44 #endif
45     if(ret != ABAYER2DNR_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_V2_t* pAbayernrCtx = (Abayer2dnr_Context_V2_t*)context;
66     Abayer2dnr_result_V2_t ret = Abayer2dnr_Release_V2(pAbayernrCtx);
67     if(ret != ABAYER2DNR_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_V2_t* pAbayernrCtx = (Abayer2dnr_Context_V2_t *)params->ctx;
85     RkAiqAlgoConfigAbayer2dnrV2* pCfgParam = (RkAiqAlgoConfigAbayer2dnrV2*)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_V2
90         void *pCalibDbV2 = (void*)(pCfgParam->com.u.prepare.calibv2);
91         CalibDbV2_Bayer2dnrV2_t *bayernr_v2 = (CalibDbV2_Bayer2dnrV2_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDbV2, bayer2dnr_v2));
92         pAbayernrCtx->bayernr_v2 = *bayernr_v2;
93 #else
94         void *pCalibDb = (void*)(pCfgParam->com.u.prepare.calib);
95         pAbayernrCtx->list_bayernr_v2 =
96             (struct list_head*)(CALIBDB_GET_MODULE_PTR((void*)pCalibDb, list_bayernr_v2));
97 #endif
98         pAbayernrCtx->isIQParaUpdate = true;
99         pAbayernrCtx->isReCalculate |= 1;
100     }
101 
102     Abayer2dnr_result_V2_t ret = Abayer2dnr_Prepare_V2(pAbayernrCtx, &pCfgParam->stArawnrConfig);
103     if(ret != ABAYER2DNR_RET_SUCCESS) {
104         result = XCAM_RETURN_ERROR_FAILED;
105         LOGE_ANR("%s: config ANR failed (%d)\n", __FUNCTION__, ret);
106     }
107 
108     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
109     return result;
110 }
111 
112 static XCamReturn
pre_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)113 pre_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
114 {
115     XCamReturn result = XCAM_RETURN_NO_ERROR;
116     bool oldGrayMode = false;
117 
118     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
119     Abayer2dnr_Context_V2_t* pAbayernrCtx = (Abayer2dnr_Context_V2_t *)inparams->ctx;
120 
121     RkAiqAlgoPreAbayer2dnrV2* pAbayernrPreParams = (RkAiqAlgoPreAbayer2dnrV2*)inparams;
122 
123     oldGrayMode = pAbayernrCtx->isGrayMode;
124     if (pAbayernrPreParams->com.u.proc.gray_mode) {
125         pAbayernrCtx->isGrayMode = true;
126     } else {
127         pAbayernrCtx->isGrayMode = false;
128     }
129 
130     if(oldGrayMode != pAbayernrCtx->isGrayMode) {
131         pAbayernrCtx->isReCalculate |= 1;
132     }
133 
134     Abayer2dnr_result_V2_t ret = Abayer2dnr_PreProcess_V2(pAbayernrCtx);
135     if(ret != ABAYER2DNR_RET_SUCCESS) {
136         result = XCAM_RETURN_ERROR_FAILED;
137         LOGE_ANR("%s: ANRPreProcess failed (%d)\n", __FUNCTION__, ret);
138     }
139 
140     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
141     return result;
142 }
143 
144 static XCamReturn
processing(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)145 processing(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
146 {
147     XCamReturn result = XCAM_RETURN_NO_ERROR;
148     int delta_iso = 0;
149 
150     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
151 
152 #if 1
153     RkAiqAlgoProcAbayer2dnrV2* pAbayernrProcParams = (RkAiqAlgoProcAbayer2dnrV2*)inparams;
154     RkAiqAlgoProcResAbayer2dnrV2* pAbayernrProcResParams = (RkAiqAlgoProcResAbayer2dnrV2*)outparams;
155     Abayer2dnr_Context_V2_t* pAbayernrCtx = (Abayer2dnr_Context_V2_t *)inparams->ctx;
156     Abayer2dnr_ExpInfo_V2_t stExpInfo;
157     memset(&stExpInfo, 0x00, sizeof(Abayer2dnr_ExpInfo_V2_t));
158 
159     LOGD_ANR("%s:%d init:%d hdr mode:%d  \n",
160              __FUNCTION__, __LINE__,
161              inparams->u.proc.init,
162              pAbayernrProcParams->hdr_mode);
163 
164     stExpInfo.hdr_mode = 0; //pAnrProcParams->hdr_mode;
165     for(int i = 0; i < 3; i++) {
166         stExpInfo.arIso[i] = 50;
167         stExpInfo.arAGain[i] = 1.0;
168         stExpInfo.arDGain[i] = 1.0;
169         stExpInfo.arTime[i] = 0.01;
170     }
171 
172     if(pAbayernrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
173         stExpInfo.hdr_mode = 0;
174     } else if(pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR
175               || pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR ) {
176         stExpInfo.hdr_mode = 1;
177     } else if(pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR
178               || pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR ) {
179         stExpInfo.hdr_mode = 2;
180     }
181     stExpInfo.snr_mode = 0;
182     stExpInfo.gray_mode = pAbayernrCtx->isGrayMode;
183 
184 #if 0// TODO Merge:
185     XCamVideoBuffer* xCamAePreRes = pAbayernrProcParams->com.u.proc.res_comb->ae_pre_res;
186     RkAiqAlgoPreResAe* pAEPreRes = nullptr;
187     if (xCamAePreRes) {
188         // xCamAePreRes->ref(xCamAePreRes);
189         pAEPreRes = (RkAiqAlgoPreResAe*)xCamAePreRes->map(xCamAePreRes);
190         if (!pAEPreRes) {
191             LOGE_ANR("ae pre result is null");
192         } else {
193 
194         }
195     }
196 #endif
197 
198     RKAiqAecExpInfo_t *curExp = pAbayernrProcParams->com.u.proc.curExp;
199     if(curExp != NULL) {
200         stExpInfo.snr_mode = curExp->CISFeature.SNR;
201         if(pAbayernrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
202             stExpInfo.hdr_mode = 0;
203             if(curExp->LinearExp.exp_real_params.analog_gain < 1.0) {
204                 stExpInfo.arAGain[0] = 1.0;
205                 LOGW_ANR("leanr mode again is wrong, use 1.0 instead\n");
206             } else {
207                 stExpInfo.arAGain[0] = curExp->LinearExp.exp_real_params.analog_gain;
208             }
209             if(curExp->LinearExp.exp_real_params.digital_gain < 1.0) {
210                 stExpInfo.arDGain[0] = 1.0;
211                 LOGW_ANR("leanr mode dgain is wrong, use 1.0 instead\n");
212             } else {
213                 stExpInfo.arDGain[0] = curExp->LinearExp.exp_real_params.digital_gain;
214             }
215             if(curExp->LinearExp.exp_real_params.isp_dgain < 1.0) {
216                 stExpInfo.arDGain[0] *= 1.0;
217                 LOGW_ANR("leanr mode dgain is wrong, use 1.0 instead\n");
218             } else {
219                 stExpInfo.arDGain[0] *= curExp->LinearExp.exp_real_params.isp_dgain;
220             }
221             stExpInfo.arTime[0] = curExp->LinearExp.exp_real_params.integration_time;
222             stExpInfo.arIso[0] = stExpInfo.arAGain[0] * stExpInfo.arDGain[0] * 50;
223         } else {
224             for(int i = 0; i < 3; i++) {
225                 if(curExp->HdrExp[i].exp_real_params.analog_gain < 1.0) {
226                     stExpInfo.arAGain[i] = 1.0;
227                     LOGW_ANR("hdr mode again is wrong, use 1.0 instead\n");
228                 } else {
229                     stExpInfo.arAGain[i] = curExp->HdrExp[i].exp_real_params.analog_gain;
230                 }
231                 if(curExp->HdrExp[i].exp_real_params.digital_gain < 1.0) {
232                     stExpInfo.arDGain[i] = 1.0;
233                 } else {
234                     LOGW_ANR("hdr mode dgain is wrong, use 1.0 instead\n");
235                     stExpInfo.arDGain[i] = curExp->HdrExp[i].exp_real_params.digital_gain;
236                 }
237                 stExpInfo.arTime[i] = curExp->HdrExp[i].exp_real_params.integration_time;
238                 stExpInfo.arIso[i] = stExpInfo.arAGain[i] * stExpInfo.arDGain[i] * 50;
239 
240                 LOGD_ANR("%s:%d index:%d again:%f dgain:%f time:%f iso:%d hdr_mode:%d\n",
241                          __FUNCTION__, __LINE__,
242                          i,
243                          stExpInfo.arAGain[i],
244                          stExpInfo.arDGain[i],
245                          stExpInfo.arTime[i],
246                          stExpInfo.arIso[i],
247                          stExpInfo.hdr_mode);
248             }
249         }
250     } else {
251         LOGE_ANR("%s:%d curExp is NULL, so use default instead \n", __FUNCTION__, __LINE__);
252     }
253 
254 
255 #if 0
256     static int anr_cnt = 0;
257     anr_cnt++;
258 
259     if(anr_cnt % 50 == 0) {
260         for(int i = 0; i < stExpInfo.hdr_mode + 1; i++) {
261             printf("%s:%d index:%d again:%f dgain:%f time:%f iso:%d hdr_mode:%d snr_mode:%d\n",
262                    __FUNCTION__, __LINE__,
263                    i,
264                    stExpInfo.arAGain[i],
265                    stExpInfo.arDGain[i],
266                    stExpInfo.arTime[i],
267                    stExpInfo.arIso[i],
268                    stExpInfo.hdr_mode,
269                    stExpInfo.snr_mode);
270         }
271     }
272 #endif
273     delta_iso = abs(stExpInfo.arIso[stExpInfo.hdr_mode] - pAbayernrCtx->stExpInfo.arIso[stExpInfo.hdr_mode]);
274     if(delta_iso > ABAYER2DNRV2_DELTA_ISO) {
275         pAbayernrCtx->isReCalculate |= 1;
276     }
277 
278     if(pAbayernrCtx->isReCalculate) {
279         Abayer2dnr_result_V2_t ret = Abayer2dnr_Process_V2(pAbayernrCtx, &stExpInfo);
280         if(ret != ABAYER2DNR_RET_SUCCESS) {
281             result = XCAM_RETURN_ERROR_FAILED;
282             LOGE_ANR("%s: processing ANR failed (%d)\n", __FUNCTION__, ret);
283         }
284 
285         Abayer2dnr_GetProcResult_V2(pAbayernrCtx, &pAbayernrProcResParams->stArawnrProcResult);
286 
287         LOGD_ANR("recalculate: %d delta_iso:%d \n ", pAbayernrCtx->isReCalculate, delta_iso);
288 
289         pAbayernrProcResParams->res_com.cfg_update = true;
290     } else {
291         pAbayernrProcResParams->res_com.cfg_update = false;
292     }
293 
294     pAbayernrCtx->isReCalculate = 0;
295 
296 #endif
297 
298     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
299     return XCAM_RETURN_NO_ERROR;
300 }
301 
302 static XCamReturn
post_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)303 post_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
304 {
305     LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
306 
307     //nothing todo now
308 
309     LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
310     return XCAM_RETURN_NO_ERROR;
311 }
312 
313 RkAiqAlgoDescription g_RkIspAlgoDescAbayer2dnrV2 = {
314     .common = {
315         .version = RKISP_ALGO_ABAYER2DNR_VERSION_V2,
316         .vendor  = RKISP_ALGO_ABAYER2DNR_VENDOR_V2,
317         .description = RKISP_ALGO_ABAYER2DNR_DESCRIPTION_V2,
318         .type    = RK_AIQ_ALGO_TYPE_ARAWNR,
319         .id      = 0,
320         .create_context  = create_context,
321         .destroy_context = destroy_context,
322     },
323     .prepare = prepare,
324     .pre_process = pre_process,
325     .processing = processing,
326     .post_process = post_process,
327 };
328 
329 RKAIQ_END_DECLARE
330