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 "arawnr2/rk_aiq_abayernr_algo_itf_v2.h"
21 #include "arawnr2/rk_aiq_abayernr_algo_v2.h"
22 #include "rk_aiq_algo_types.h"
23 #include "RkAiqCalibDbV2Helper.h"
24
25 RKAIQ_BEGIN_DECLARE
26
27 typedef struct _RkAiqAlgoContext {
28 Abayernr_Context_V2_t AbayernrCtx;
29 } RkAiqAlgoContext;
30
31
32 static XCamReturn
create_context(RkAiqAlgoContext ** context,const AlgoCtxInstanceCfg * cfg)33 create_context(RkAiqAlgoContext **context, const AlgoCtxInstanceCfg* cfg)
34 {
35
36 XCamReturn result = XCAM_RETURN_NO_ERROR;
37 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
38
39 #if 1
40 Abayernr_Context_V2_t* pAbayernrCtx = NULL;
41 #if (ABAYERNR_USE_JSON_FILE_V2)
42 Abayernr_result_t ret = Abayernr_Init_V2(&pAbayernrCtx, cfg->calibv2);
43 #else
44 Abayernr_result_t ret = Abayernr_Init_V2(&pAbayernrCtx, cfg->calib);
45 #endif
46 if(ret != ABAYERNR_RET_SUCCESS) {
47 result = XCAM_RETURN_ERROR_FAILED;
48 LOGE_ANR("%s: Initializaion ANR failed (%d)\n", __FUNCTION__, ret);
49 } else {
50 *context = (RkAiqAlgoContext *)(pAbayernrCtx);
51 }
52 #endif
53
54 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
55 return result;
56 }
57
58 static XCamReturn
destroy_context(RkAiqAlgoContext * context)59 destroy_context(RkAiqAlgoContext *context)
60 {
61 XCamReturn result = XCAM_RETURN_NO_ERROR;
62
63 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
64
65 #if 1
66 Abayernr_Context_V2_t* pAbayernrCtx = (Abayernr_Context_V2_t*)context;
67 Abayernr_result_t ret = Abayernr_Release_V2(pAbayernrCtx);
68 if(ret != ABAYERNR_RET_SUCCESS) {
69 result = XCAM_RETURN_ERROR_FAILED;
70 LOGE_ANR("%s: release ANR failed (%d)\n", __FUNCTION__, ret);
71 }
72 #endif
73
74 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
75 return result;
76 }
77
78 static XCamReturn
prepare(RkAiqAlgoCom * params)79 prepare(RkAiqAlgoCom* params)
80 {
81 XCamReturn result = XCAM_RETURN_NO_ERROR;
82
83 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
84
85 Abayernr_Context_V2_t* pAbayernrCtx = (Abayernr_Context_V2_t *)params->ctx;
86 RkAiqAlgoConfigArawnrV2* pCfgParam = (RkAiqAlgoConfigArawnrV2*)params;
87 pAbayernrCtx->prepare_type = params->u.prepare.conf_type;
88
89 if(!!(params->u.prepare.conf_type & RK_AIQ_ALGO_CONFTYPE_UPDATECALIB )) {
90 #if ABAYERNR_USE_JSON_FILE_V2
91 void *pCalibDbV2 = (void*)(pCfgParam->com.u.prepare.calibv2);
92 CalibDbV2_BayerNrV2_t *bayernr_v2 = (CalibDbV2_BayerNrV2_t*)(CALIBDBV2_GET_MODULE_PTR((void*)pCalibDbV2, bayernr_v2));
93 pAbayernrCtx->bayernr_v2 = *bayernr_v2;
94 #else
95 void *pCalibDb = (void*)(pCfgParam->com.u.prepare.calib);
96 pAbayernrCtx->list_bayernr_v2 =
97 (struct list_head*)(CALIBDB_GET_MODULE_PTR((void*)pCalibDb, list_bayernr_v2));
98 #endif
99 pAbayernrCtx->isIQParaUpdate = true;
100 pAbayernrCtx->isReCalculate |= 1;
101 }
102
103 Abayernr_result_t ret = Abayernr_Prepare_V2(pAbayernrCtx, &pCfgParam->stArawnrConfig);
104 if(ret != ABAYERNR_RET_SUCCESS) {
105 result = XCAM_RETURN_ERROR_FAILED;
106 LOGE_ANR("%s: config ANR failed (%d)\n", __FUNCTION__, ret);
107 }
108
109 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
110 return result;
111 }
112
113 static XCamReturn
pre_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)114 pre_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
115 {
116 XCamReturn result = XCAM_RETURN_NO_ERROR;
117 bool oldGrayMode = false;
118
119 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
120 Abayernr_Context_V2_t* pAbayernrCtx = (Abayernr_Context_V2_t *)inparams->ctx;
121
122 RkAiqAlgoPreArawnrV2* pAbayernrPreParams = (RkAiqAlgoPreArawnrV2*)inparams;
123
124 oldGrayMode = pAbayernrCtx->isGrayMode;
125 if (pAbayernrPreParams->com.u.proc.gray_mode) {
126 pAbayernrCtx->isGrayMode = true;
127 } else {
128 pAbayernrCtx->isGrayMode = false;
129 }
130
131 if(oldGrayMode != pAbayernrCtx->isGrayMode) {
132 pAbayernrCtx->isReCalculate |= 1;
133 }
134
135 Abayernr_result_t ret = Abayernr_PreProcess_V2(pAbayernrCtx);
136 if(ret != ABAYERNR_RET_SUCCESS) {
137 result = XCAM_RETURN_ERROR_FAILED;
138 LOGE_ANR("%s: ANRPreProcess failed (%d)\n", __FUNCTION__, ret);
139 }
140
141 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
142 return result;
143 }
144
145 static XCamReturn
processing(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)146 processing(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
147 {
148 XCamReturn result = XCAM_RETURN_NO_ERROR;
149 int delta_iso = 0;
150
151 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
152
153 #if 1
154 RkAiqAlgoProcArawnrV2* pAbayernrProcParams = (RkAiqAlgoProcArawnrV2*)inparams;
155 RkAiqAlgoProcResArawnrV2* pAbayernrProcResParams = (RkAiqAlgoProcResArawnrV2*)outparams;
156 Abayernr_Context_V2_t* pAbayernrCtx = (Abayernr_Context_V2_t *)inparams->ctx;
157 Abayernr_ExpInfo_t stExpInfo;
158 memset(&stExpInfo, 0x00, sizeof(Abayernr_ExpInfo_t));
159
160 LOGD_ANR("%s:%d init:%d hdr mode:%d \n",
161 __FUNCTION__, __LINE__,
162 inparams->u.proc.init,
163 pAbayernrProcParams->hdr_mode);
164
165 stExpInfo.hdr_mode = 0; //pAnrProcParams->hdr_mode;
166 for(int i = 0; i < 3; i++) {
167 stExpInfo.arIso[i] = 50;
168 stExpInfo.arAGain[i] = 1.0;
169 stExpInfo.arDGain[i] = 1.0;
170 stExpInfo.arTime[i] = 0.01;
171 }
172
173 if(pAbayernrProcParams->hdr_mode == RK_AIQ_WORKING_MODE_NORMAL) {
174 stExpInfo.hdr_mode = 0;
175 } else if(pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_FRAME_HDR
176 || pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_2_LINE_HDR ) {
177 stExpInfo.hdr_mode = 1;
178 } else if(pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_FRAME_HDR
179 || pAbayernrProcParams->hdr_mode == RK_AIQ_ISP_HDR_MODE_3_LINE_HDR ) {
180 stExpInfo.hdr_mode = 2;
181 }
182 stExpInfo.snr_mode = 0;
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 stExpInfo.arAGain[0] = curExp->LinearExp.exp_real_params.analog_gain;
204 stExpInfo.arDGain[0] = curExp->LinearExp.exp_real_params.digital_gain;
205 stExpInfo.arTime[0] = curExp->LinearExp.exp_real_params.integration_time;
206 stExpInfo.arIso[0] = stExpInfo.arAGain[0] * stExpInfo.arDGain[0] * 50;
207 } else {
208 for(int i = 0; i < 3; i++) {
209 stExpInfo.arAGain[i] = curExp->HdrExp[i].exp_real_params.analog_gain;
210 stExpInfo.arDGain[i] = curExp->HdrExp[i].exp_real_params.digital_gain;
211 stExpInfo.arTime[i] = curExp->HdrExp[i].exp_real_params.integration_time;
212 stExpInfo.arIso[i] = stExpInfo.arAGain[i] * stExpInfo.arDGain[i] * 50;
213
214 LOGD_ANR("%s:%d index:%d again:%f dgain:%f time:%f iso:%d hdr_mode:%d\n",
215 __FUNCTION__, __LINE__,
216 i,
217 stExpInfo.arAGain[i],
218 stExpInfo.arDGain[i],
219 stExpInfo.arTime[i],
220 stExpInfo.arIso[i],
221 stExpInfo.hdr_mode);
222 }
223 }
224 } else {
225 LOGE_ANR("%s:%d curExp is NULL, so use default instead \n", __FUNCTION__, __LINE__);
226 }
227
228
229 #if 0
230 static int anr_cnt = 0;
231 anr_cnt++;
232
233 if(anr_cnt % 50 == 0) {
234 for(int i = 0; i < stExpInfo.hdr_mode + 1; i++) {
235 printf("%s:%d index:%d again:%f dgain:%f time:%f iso:%d hdr_mode:%d snr_mode:%d\n",
236 __FUNCTION__, __LINE__,
237 i,
238 stExpInfo.arAGain[i],
239 stExpInfo.arDGain[i],
240 stExpInfo.arTime[i],
241 stExpInfo.arIso[i],
242 stExpInfo.hdr_mode,
243 stExpInfo.snr_mode);
244 }
245 }
246 #endif
247 delta_iso = abs(stExpInfo.arIso[stExpInfo.hdr_mode] - pAbayernrCtx->stExpInfo.arIso[stExpInfo.hdr_mode]);
248 if(delta_iso > ABAYERNRV2_DELTA_ISO) {
249 pAbayernrCtx->isReCalculate |= 1;
250 }
251
252 if(pAbayernrCtx->isReCalculate) {
253 Abayernr_result_t ret = Abayernr_Process_V2(pAbayernrCtx, &stExpInfo);
254 if(ret != ABAYERNR_RET_SUCCESS) {
255 result = XCAM_RETURN_ERROR_FAILED;
256 LOGE_ANR("%s: processing ANR failed (%d)\n", __FUNCTION__, ret);
257 }
258
259 Abayernr_GetProcResult_V2(pAbayernrCtx, &pAbayernrProcResParams->stArawnrProcResult);
260
261 LOGD_ANR("recalculate: %d delta_iso:%d \n ", pAbayernrCtx->isReCalculate, delta_iso);
262
263 outparams->cfg_update = true;
264 } else {
265 outparams->cfg_update = false;
266 }
267
268 pAbayernrCtx->isReCalculate = 0;
269
270 #endif
271
272 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
273 return XCAM_RETURN_NO_ERROR;
274 }
275
276 static XCamReturn
post_process(const RkAiqAlgoCom * inparams,RkAiqAlgoResCom * outparams)277 post_process(const RkAiqAlgoCom* inparams, RkAiqAlgoResCom* outparams)
278 {
279 LOGI_ANR("%s: (enter)\n", __FUNCTION__ );
280
281 //nothing todo now
282
283 LOGI_ANR("%s: (exit)\n", __FUNCTION__ );
284 return XCAM_RETURN_NO_ERROR;
285 }
286
287 RkAiqAlgoDescription g_RkIspAlgoDescArawnrV2 = {
288 .common = {
289 .version = RKISP_ALGO_ABAYERNR_VERSION_V2,
290 .vendor = RKISP_ALGO_ABAYERNR_VENDOR_V2,
291 .description = RKISP_ALGO_ABAYERNR_DESCRIPTION_V2,
292 .type = RK_AIQ_ALGO_TYPE_ARAWNR,
293 .id = 0,
294 .create_context = create_context,
295 .destroy_context = destroy_context,
296 },
297 .prepare = prepare,
298 .pre_process = pre_process,
299 .processing = processing,
300 .post_process = post_process,
301 };
302
303 RKAIQ_END_DECLARE
304