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 "acnrV30/rk_aiq_acnr_algo_itf_v30.h"
21 #include "acnrV30/rk_aiq_acnr_algo_v30.h"
22 #include "rk_aiq_algo_types.h"
23
24 RKAIQ_BEGIN_DECLARE
25
26 typedef struct _RkAiqAlgoContext {
27 Acnr_Context_V30_t AcnrCtx;
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 Acnr_Context_V30_t* pAcnrCtx = NULL;
40 #if ACNR_USE_JSON_FILE_V30
41 AcnrV30_result_t ret = Acnr_Init_V30(&pAcnrCtx, cfg->calibv2);
42 #endif
43
44 if(ret != ACNRV30_RET_SUCCESS) {
45 result = XCAM_RETURN_ERROR_FAILED;
46 LOGE_ANR("%s: Initializaion ANR failed (%d)\n", __FUNCTION__, ret);
47 } else {
48 *context = (RkAiqAlgoContext *)(pAcnrCtx);
49 }
50 #endif
51
52 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
53 return result;
54 }
55
56 static XCamReturn
destroy_context(RkAiqAlgoContext * context)57 destroy_context(RkAiqAlgoContext *context)
58 {
59 XCamReturn result = XCAM_RETURN_NO_ERROR;
60
61 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
62
63 #if 1
64 Acnr_Context_V30_t* pAcnrCtx = (Acnr_Context_V30_t*)context;
65 AcnrV30_result_t ret = Acnr_Release_V30(pAcnrCtx);
66 if(ret != ACNRV30_RET_SUCCESS) {
67 result = XCAM_RETURN_ERROR_FAILED;
68 LOGE_ANR("%s: release ANR failed (%d)\n", __FUNCTION__, ret);
69 }
70 #endif
71
72 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
73 return result;
74 }
75
76 static XCamReturn
prepare(RkAiqAlgoCom * params)77 prepare(RkAiqAlgoCom* params)
78 {
79 XCamReturn result = XCAM_RETURN_NO_ERROR;
80
81 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
82
83 Acnr_Context_V30_t* pAcnrCtx = (Acnr_Context_V30_t *)params->ctx;
84 RkAiqAlgoConfigAcnrV30* pCfgParam = (RkAiqAlgoConfigAcnrV30*)params;
85 pAcnrCtx->prepare_type = params->u.prepare.conf_type;
86
87 if(!!(params->u.prepare.conf_type & RK_AIQ_ALGO_CONFTYPE_UPDATECALIB )) {
88 #if ACNR_USE_JSON_FILE_V30
89 void *pCalibDbV2 = (void*)(pCfgParam->com.u.prepare.calibv2);
90 CalibDbV2_CNRV30_t *cnr_v30 =
91 (CalibDbV2_CNRV30_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDbV2, cnr_v30));
92 pAcnrCtx->cnr_v30 = *cnr_v30;
93 #endif
94 pAcnrCtx->isIQParaUpdate = true;
95 pAcnrCtx->isReCalculate |= 1;
96
97 }
98 AcnrV30_result_t ret = Acnr_Prepare_V30(pAcnrCtx, &pCfgParam->stAcnrConfig);
99 if(ret != ACNRV30_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 Acnr_Context_V30_t* pAcnrCtx = (Acnr_Context_V30_t *)inparams->ctx;
116
117 RkAiqAlgoPreAcnrV30* pAnrPreParams = (RkAiqAlgoPreAcnrV30*)inparams;
118
119 oldGrayMode = pAcnrCtx->isGrayMode;
120 if (pAnrPreParams->com.u.proc.gray_mode) {
121 pAcnrCtx->isGrayMode = true;
122 } else {
123 pAcnrCtx->isGrayMode = false;
124 }
125
126 if(oldGrayMode != pAcnrCtx->isGrayMode) {
127 pAcnrCtx->isReCalculate |= 1;
128 }
129
130 AcnrV30_result_t ret = Acnr_PreProcess_V30(pAcnrCtx);
131 if(ret != ACNRV30_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 DeltaISO = 0;
145 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
146
147 #if 1
148 RkAiqAlgoProcAcnrV30* pAcnrProcParams = (RkAiqAlgoProcAcnrV30*)inparams;
149 RkAiqAlgoProcResAcnrV30* pAcnrProcResParams = (RkAiqAlgoProcResAcnrV30*)outparams;
150 Acnr_Context_V30_t* pAcnrCtx = (Acnr_Context_V30_t *)inparams->ctx;
151 AcnrV30_ExpInfo_t stExpInfo;
152 memset(&stExpInfo, 0x00, sizeof(AcnrV30_ExpInfo_t));
153
154 bool oldGrayMode = false;
155 oldGrayMode = pAcnrCtx->isGrayMode;
156 if (inparams->u.proc.gray_mode) {
157 pAcnrCtx->isGrayMode = true;
158 } else {
159 pAcnrCtx->isGrayMode = false;
160 }
161
162 if(oldGrayMode != pAcnrCtx->isGrayMode) {
163 pAcnrCtx->isReCalculate |= 1;
164 }
165
166 AcnrV30_result_t ret = Acnr_PreProcess_V30(pAcnrCtx);
167 if(ret != ACNRV30_RET_SUCCESS) {
168 result = XCAM_RETURN_ERROR_FAILED;
169 LOGE_ANR("%s: ANRPreProcess failed (%d)\n", __FUNCTION__, ret);
170 }
171
172 LOGD_ANR("%s:%d init:%d hdr mode:%d \n",
173 __FUNCTION__, __LINE__,
174 inparams->u.proc.init,
175 pAcnrProcParams->hdr_mode);
176
177 stExpInfo.hdr_mode = 0; //pAnrProcParams->hdr_mode;
178 for(int i = 0; i < 3; i++) {
179 stExpInfo.arIso[i] = 50;
180 stExpInfo.arAGain[i] = 1.0;
181 stExpInfo.arDGain[i] = 1.0;
182 stExpInfo.arTime[i] = 0.01;
183 }
184
185 if(pAcnrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
186 stExpInfo.hdr_mode = 0;
187 } else if(pAcnrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR
188 || pAcnrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR ) {
189 stExpInfo.hdr_mode = 1;
190 } else if(pAcnrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR
191 || pAcnrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR ) {
192 stExpInfo.hdr_mode = 2;
193 }
194 stExpInfo.snr_mode = 0;
195
196 stExpInfo.blc_ob_predgain = 1.0;
197 if(pAcnrProcParams != NULL) {
198 stExpInfo.blc_ob_predgain = pAcnrProcParams->stAblcV32_proc_res->isp_ob_predgain;
199 if(stExpInfo.blc_ob_predgain != pAcnrCtx->stExpInfo.blc_ob_predgain) {
200 pAcnrCtx->isReCalculate |= 1;
201 }
202 }
203
204 #if 0// TODO Merge:
205 XCamVideoBuffer* xCamAePreRes = pAcnrProcParams->com.u.proc.res_comb->ae_pre_res;
206 RkAiqAlgoPreResAe* pAEPreRes = nullptr;
207 if (xCamAePreRes) {
208 // xCamAePreRes->ref(xCamAePreRes);
209 pAEPreRes = (RkAiqAlgoPreResAe*)xCamAePreRes->map(xCamAePreRes);
210 if (!pAEPreRes) {
211 LOGE_ANR("ae pre result is null");
212 } else {
213 }
214 // xCamAePreRes->unref(xCamAePreRes);
215 }
216 #endif
217
218
219 RKAiqAecExpInfo_t *curExp = pAcnrProcParams->com.u.proc.curExp;
220 if(curExp != NULL) {
221 stExpInfo.snr_mode = curExp->CISFeature.SNR;
222 if(pAcnrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
223 stExpInfo.hdr_mode = 0;
224 if(curExp->LinearExp.exp_real_params.analog_gain < 1.0) {
225 stExpInfo.arAGain[0] = 1.0;
226 LOGW_ANR("leanr mode again is wrong, use 1.0 instead\n");
227 } else {
228 stExpInfo.arAGain[0] = curExp->LinearExp.exp_real_params.analog_gain;
229 }
230 if(curExp->LinearExp.exp_real_params.digital_gain < 1.0) {
231 stExpInfo.arDGain[0] = 1.0;
232 LOGW_ANR("leanr mode dgain is wrong, use 1.0 instead\n");
233 } else {
234 stExpInfo.arDGain[0] = curExp->LinearExp.exp_real_params.digital_gain;
235 }
236 if(curExp->LinearExp.exp_real_params.isp_dgain < 1.0) {
237 stExpInfo.isp_dgain[0] = 1.0;
238 LOGW_ANR("leanr mode isp_dgain is wrong, use 1.0 instead\n");
239 } else {
240 stExpInfo.isp_dgain[0] = curExp->LinearExp.exp_real_params.isp_dgain;
241 }
242 if(stExpInfo.blc_ob_predgain < 1.0) {
243 stExpInfo.blc_ob_predgain = 1.0;
244 }
245 // stExpInfo.arAGain[0] = 64.0;
246 stExpInfo.arTime[0] = curExp->LinearExp.exp_real_params.integration_time;
247 stExpInfo.arIso[0] = stExpInfo.arAGain[0] * stExpInfo.arDGain[0] * stExpInfo.blc_ob_predgain * 50 * stExpInfo.isp_dgain[0];
248 } else {
249 for(int i = 0; i < 3; i++) {
250 if(curExp->HdrExp[i].exp_real_params.analog_gain < 1.0) {
251 stExpInfo.arAGain[i] = 1.0;
252 LOGW_ANR("hdr mode again is wrong, use 1.0 instead\n");
253 } else {
254 stExpInfo.arAGain[i] = curExp->HdrExp[i].exp_real_params.analog_gain;
255 }
256 if(curExp->HdrExp[i].exp_real_params.digital_gain < 1.0) {
257 stExpInfo.arDGain[i] = 1.0;
258 LOGW_ANR("hdr mode dgain is wrong, use 1.0 instead\n");
259 } else {
260 stExpInfo.arDGain[i] = curExp->HdrExp[i].exp_real_params.digital_gain;
261 }
262 if(curExp->HdrExp[i].exp_real_params.isp_dgain < 1.0) {
263 stExpInfo.isp_dgain[i] = 1.0;
264 LOGW_ANR("hdr mode isp_dgain is wrong, use 1.0 instead\n");
265 } else {
266 stExpInfo.isp_dgain[i] = curExp->HdrExp[i].exp_real_params.isp_dgain;
267 }
268 stExpInfo.blc_ob_predgain = 1.0;
269 stExpInfo.arTime[i] = curExp->HdrExp[i].exp_real_params.integration_time;
270 stExpInfo.arIso[i] = stExpInfo.arAGain[i] * stExpInfo.arDGain[i] * 50 * stExpInfo.isp_dgain[i];
271
272 LOGD_ANR("%s:%d index:%d again:%f dgain:%f isp_dgain:%f time:%f iso:%d hdr_mode:%d\n",
273 __FUNCTION__, __LINE__,
274 i,
275 stExpInfo.arAGain[i],
276 stExpInfo.arDGain[i],
277 stExpInfo.isp_dgain[i],
278 stExpInfo.arTime[i],
279 stExpInfo.arIso[i],
280 stExpInfo.hdr_mode);
281 }
282 }
283 } else {
284 LOGE_ANR("%s:%d curExp is NULL, so use default instead \n", __FUNCTION__, __LINE__);
285 }
286
287 #if 0
288 static int anr_cnt = 0;
289 anr_cnt++;
290
291 if(anr_cnt % 1 == 0) {
292 for(int i = 0; i < stExpInfo.hdr_mode + 1; i++) {
293 printf("%s:%d index:%d again:%f dgain:%f time:%f iso:%d hdr_mode:%d snr_mode:%d\n",
294 __FUNCTION__, __LINE__,
295 i,
296 stExpInfo.arAGain[i],
297 stExpInfo.arDGain[i],
298 stExpInfo.arTime[i],
299 stExpInfo.arIso[i],
300 stExpInfo.hdr_mode,
301 stExpInfo.snr_mode);
302 }
303 }
304 #endif
305
306 DeltaISO = abs(stExpInfo.arIso[stExpInfo.hdr_mode] - pAcnrCtx->stExpInfo.arIso[pAcnrCtx->stExpInfo.hdr_mode]);
307 if(DeltaISO > ACNRV30_RECALCULATE_DELTA_ISO) {
308 pAcnrCtx->isReCalculate |= 1;
309 }
310
311 if(pAcnrCtx->isReCalculate) {
312 AcnrV30_result_t ret = Acnr_Process_V30(pAcnrCtx, &stExpInfo);
313 if(ret != ACNRV30_RET_SUCCESS) {
314 result = XCAM_RETURN_ERROR_FAILED;
315 LOGE_ANR("%s: processing ANR failed (%d)\n", __FUNCTION__, ret);
316 }
317
318 Acnr_GetProcResult_V30(pAcnrCtx, &pAcnrProcResParams->stAcnrProcResult);
319 outparams->cfg_update = true;
320 LOGD_ANR("recalculate: %d delta_iso:%d \n ", pAcnrCtx->isReCalculate, DeltaISO);
321 } else {
322 outparams->cfg_update = false;
323 }
324 #endif
325
326 pAcnrCtx->isReCalculate = 0;
327 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
328 return XCAM_RETURN_NO_ERROR;
329 }
330
331 static XCamReturn
post_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)332 post_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
333 {
334 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
335
336 //nothing todo now
337
338 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
339 return XCAM_RETURN_NO_ERROR;
340 }
341
342 RkAiqAlgoDescription g_RkIspAlgoDescAcnrV30 = {
343 .common = {
344 .version = RKISP_ALGO_ACNR_VERSION_V30,
345 .vendor = RKISP_ALGO_ACNR_VENDOR_V30,
346 .description = RKISP_ALGO_ACNR_DESCRIPTION_V30,
347 .type = RK_AIQ_ALGO_TYPE_ACNR,
348 .id = 0,
349 .create_context = create_context,
350 .destroy_context = destroy_context,
351 },
352 .prepare = prepare,
353 .pre_process = NULL,
354 .processing = processing,
355 .post_process = NULL,
356 };
357
358 RKAIQ_END_DECLARE
359