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