1 /*
2 * Copyright (c) 2019-2022 Rockchip Eletronics Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "rk_aiq_again_algo_gain_v2.h"
18
19
gain_get_setting_by_name_json_V2(CalibDbV2_GainV2_t * pCalibdb,char * name,int * tuning_idx)20 Again_result_V2_t gain_get_setting_by_name_json_V2(CalibDbV2_GainV2_t* pCalibdb, char *name, int *tuning_idx)
21 {
22 int i = 0;
23 Again_result_V2_t res = AGAINV2_RET_SUCCESS;
24
25 if(pCalibdb == NULL || name == NULL || tuning_idx == NULL) {
26 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
27 return AGAINV2_RET_INVALID_PARM;
28 }
29
30 for(i = 0; i < pCalibdb->TuningPara.Setting_len; i++) {
31 if(strncmp(name, pCalibdb->TuningPara.Setting[i].SNR_Mode, strlen(name)*sizeof(char)) == 0) {
32 break;
33 }
34 }
35
36 if(i < pCalibdb->TuningPara.Setting_len) {
37 *tuning_idx = i;
38 } else {
39 *tuning_idx = 0;
40 }
41
42 LOGD_ANR("%s:%d snr_name:%s snr_idx:%d i:%d \n", __FUNCTION__, __LINE__, name, *tuning_idx, i);
43 return res;
44
45
46 }
47
48
gain_init_params_json_V2(RK_GAIN_Params_V2_t * pParams,CalibDbV2_GainV2_t * pCalibdb,int tuning_idx)49 Again_result_V2_t gain_init_params_json_V2(RK_GAIN_Params_V2_t *pParams, CalibDbV2_GainV2_t* pCalibdb, int tuning_idx)
50 {
51 Again_result_V2_t res = AGAINV2_RET_SUCCESS;
52 CalibDbV2_GainV2_T_ISO_t *pTuningIso = NULL;
53
54 LOGI_ANR("%s:(%d) oyyf bayerner xml config start\n", __FUNCTION__, __LINE__);
55 if(pParams == NULL || pCalibdb == NULL) {
56 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
57 return AGAINV2_RET_INVALID_PARM;
58 }
59
60 pParams->hdrgain_ctrl_enable = pCalibdb->TuningPara.hdrgain_ctrl_enable;
61
62 if(tuning_idx < pCalibdb->TuningPara.Setting_len) {
63 for(int i = 0; i < pCalibdb->TuningPara.Setting[tuning_idx].Tuning_ISO_len && i < RK_GAIN_V2_MAX_ISO_NUM; i++) {
64 pTuningIso = &pCalibdb->TuningPara.Setting[tuning_idx].Tuning_ISO[i];
65 pParams->iso[i] = pTuningIso->iso;
66 pParams->iso_params[i].hdr_gain_scale_s = pTuningIso->hdr_gain_scale_s;
67 pParams->iso_params[i].hdr_gain_scale_m = pTuningIso->hdr_gain_scale_m;
68 LOGD_ANR("iso[%d]:%d hdr_gain_scale:%f %f\n",
69 i,
70 pParams->iso[i],
71 pParams->iso_params[i].hdr_gain_scale_s,
72 pParams->iso_params[i].hdr_gain_scale_m);
73 }
74 }
75
76 LOGI_ANR("%s:(%d) oyyf bayerner xml config end! \n", __FUNCTION__, __LINE__);
77
78 return res;
79 }
80
81
gain_config_setting_param_json_V2(RK_GAIN_Params_V2_t * pParams,CalibDbV2_GainV2_t * pCalibdbV2,char * param_mode,char * snr_name)82 Again_result_V2_t gain_config_setting_param_json_V2(RK_GAIN_Params_V2_t *pParams, CalibDbV2_GainV2_t* pCalibdbV2, char* param_mode, char * snr_name)
83 {
84 Again_result_V2_t res = AGAINV2_RET_SUCCESS;
85 int calib_idx = 0;
86 int tuning_idx = 0;
87
88 if(pParams == NULL || pCalibdbV2 == NULL
89 || param_mode == NULL || snr_name == NULL) {
90 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
91 return AGAINV2_RET_INVALID_PARM;
92 }
93
94 res = gain_get_setting_by_name_json_V2(pCalibdbV2, snr_name, &tuning_idx);
95 if(res != AGAINV2_RET_SUCCESS) {
96 LOGW_ANR("%s(%d): error!!! can't find setting in iq files, use 0 instead\n", __FUNCTION__, __LINE__);
97
98 }
99
100 res = gain_init_params_json_V2(pParams, pCalibdbV2, tuning_idx);
101
102 return res;
103
104 }
105
gain_select_params_by_ISO_V2(RK_GAIN_Params_V2_t * pParams,RK_GAIN_Select_V2_t * pSelect,Again_ExpInfo_V2_t * pExpInfo)106 Again_result_V2_t gain_select_params_by_ISO_V2(RK_GAIN_Params_V2_t *pParams, RK_GAIN_Select_V2_t *pSelect, Again_ExpInfo_V2_t *pExpInfo)
107 {
108 Again_result_V2_t res = AGAINV2_RET_SUCCESS;
109 int iso = 50;
110
111 if(pParams == NULL) {
112 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
113 return AGAINV2_RET_INVALID_PARM;
114 }
115
116 if(pSelect == NULL) {
117 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
118 return AGAINV2_RET_INVALID_PARM;
119 }
120
121 if(pExpInfo == NULL) {
122 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
123 return AGAINV2_RET_INVALID_PARM;
124 }
125
126 iso = pExpInfo->arIso[pExpInfo->hdr_mode];
127
128 LOGD_ANR("%s:%d iso:%d \n", __FUNCTION__, __LINE__, iso);
129
130 int isoGainStd[RK_GAIN_V2_MAX_ISO_NUM];
131 int isoGain = MAX(int(iso / 50), 1);
132 int isoGainLow = 0;
133 int isoGainHig = 0;
134 int isoGainCorrect = 1;
135 int isoLevelLow = 0;
136 int isoLevelHig = 0;
137 int isoLevelCorrect = 0;
138 int i, j;
139 float tmpf;
140
141 #ifndef RK_SIMULATOR_HW
142 for(int i = 0; i < RK_GAIN_V2_MAX_ISO_NUM; i++) {
143 isoGainStd[i] = pParams->iso[i] / 50;
144 }
145 #else
146 for(int i = 0; i < RK_GAIN_V2_MAX_ISO_NUM; i++) {
147 isoGainStd[i] = 1 * (1 << i);
148 }
149 #endif
150
151 for (i = 0; i < RK_GAIN_V2_MAX_ISO_NUM - 1; i++)
152 {
153 if (isoGain >= isoGainStd[i] && isoGain <= isoGainStd[i + 1])
154 {
155 isoGainLow = isoGainStd[i];
156 isoGainHig = isoGainStd[i + 1];
157 isoLevelLow = i;
158 isoLevelHig = i + 1;
159 isoGainCorrect = ((isoGain - isoGainStd[i]) <= (isoGainStd[i + 1] - isoGain)) ? isoGainStd[i] : isoGainStd[i + 1];
160 isoLevelCorrect = ((isoGain - isoGainStd[i]) <= (isoGainStd[i + 1] - isoGain)) ? i : (i + 1);
161 }
162 }
163
164 if(isoGain > isoGainStd[RK_GAIN_V2_MAX_ISO_NUM - 1]) {
165 isoGainLow = isoGainStd[RK_GAIN_V2_MAX_ISO_NUM - 2];
166 isoGainHig = isoGainStd[RK_GAIN_V2_MAX_ISO_NUM - 1];
167 isoLevelLow = RK_GAIN_V2_MAX_ISO_NUM - 2;
168 isoLevelHig = RK_GAIN_V2_MAX_ISO_NUM - 1;
169 }
170
171 if(isoGain < isoGainStd[1]) {
172 isoGainLow = isoGainStd[0];
173 isoGainHig = isoGainStd[1];
174 isoLevelLow = 0;
175 isoLevelHig = 1;
176 }
177
178 pExpInfo->isoLevelLow = isoLevelLow;
179 pExpInfo->isoLevelHig = isoLevelHig;
180 pSelect->hdrgain_ctrl_enable = pParams->hdrgain_ctrl_enable;
181
182 float ratio = 0;
183 ratio = float(isoGain - isoGainLow) / float(isoGainHig - isoGainLow) ;
184
185 pSelect->hdr_gain_scale_s = ratio * ( pParams->iso_params[isoLevelHig].hdr_gain_scale_s - pParams->iso_params[isoLevelLow].hdr_gain_scale_s)
186 + pParams->iso_params[isoLevelLow].hdr_gain_scale_s;
187
188
189 pSelect->hdr_gain_scale_m = ratio * ( pParams->iso_params[isoLevelHig].hdr_gain_scale_m - pParams->iso_params[isoLevelLow].hdr_gain_scale_m)
190 + pParams->iso_params[isoLevelLow].hdr_gain_scale_m;
191
192 LOGD_ANR("%s:%d iso:%d high:%d low:%d hdr_gain_scale:%f %f\n",
193 __FUNCTION__, __LINE__,
194 isoGain, isoGainHig, isoGainLow,
195 pSelect->hdr_gain_scale_s,
196 pSelect->hdr_gain_scale_m);
197 return res;
198 }
199
gain_float_lim2_int(float In,int bit_deci_dst,int type)200 uint32_t gain_float_lim2_int(float In, int bit_deci_dst, int type)
201 {
202 uint8_t *in_u8 = reinterpret_cast<uint8_t *>(&In);
203 int exp_val = ((in_u8[3] << 1) & (in_u8[2] >> 7) & 0xff);
204 uint32_t dst;
205 int shf_bit;
206 if (exp_val - 127 <= bit_deci_dst || type == 1)
207 {
208 shf_bit = bit_deci_dst - (exp_val - 127);
209 dst = ROUND_F(In * (1 << bit_deci_dst));
210 }
211 else
212 {
213 shf_bit = (exp_val - 127) - bit_deci_dst;
214 dst = ROUND_F(In / (1 << bit_deci_dst));
215 }
216 return dst;
217 }
218
gain_fix_transfer_v2(RK_GAIN_Select_V2_t * pSelect,RK_GAIN_Fix_V2_t * pGainFix,Again_ExpInfo_V2_t * pExpInfo,float gain_ratio)219 Again_result_V2_t gain_fix_transfer_v2( RK_GAIN_Select_V2_t *pSelect, RK_GAIN_Fix_V2_t* pGainFix, Again_ExpInfo_V2_t *pExpInfo, float gain_ratio)
220 {
221 int i;
222 double max_val = 0;
223
224
225 LOGI_ANR("%s:(%d) enter\n", __FUNCTION__, __LINE__);
226
227 if(pSelect == NULL) {
228 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
229 return AGAINV2_RET_NULL_POINTER;
230 }
231
232 if(pGainFix == NULL) {
233 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
234 return AGAINV2_RET_NULL_POINTER;
235 }
236
237 if(pExpInfo == NULL) {
238 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
239 return AGAINV2_RET_NULL_POINTER;
240 }
241
242
243 #if 1
244 pGainFix->sw_gain2ddr_mode = 0;
245 pGainFix->sw_gain2ddr_wr_en = 0;
246 pGainFix->sw_3dlut_gain_en = 1;
247 pGainFix->sw_dhaz_gain_en = 1;
248 pGainFix->sw_adrc_gain_en = 1;
249 pGainFix->sw_lsc_gain_en = 1;
250 pGainFix->sw_gain_module_free_mode = 0;
251 pGainFix->sw_gain_dmard_mode_en = 0;
252 pGainFix->sw_bayer3dnr_gain_en = 1;
253 pGainFix->sw_gain_mp_pipe_dis = 0;
254 pGainFix->sw_gain_gate_always_on = 0;
255 pGainFix->sw_mge_gain_en = 1;
256 pGainFix->sw_gain_en = 1;
257 #endif
258
259
260 float exp_time[3];
261 float exp_gain[3];
262 float dGain[3];
263 float frameiso[3];
264 float frameEt[3];
265 // frame_gain_in
266 float frame_exp_val[3];
267 float frame_exp_ratio[3];
268 int HDR_frame_num = pExpInfo->hdr_mode + 1;
269
270 // get exposure time and gain information (store as float number)
271 for (int i = 0; i < 3; ++i)
272 {
273 exp_gain[i] = pExpInfo->arAGain[i] * pExpInfo->arDGain[i];
274 frameEt[i] = pExpInfo->arTime[i];
275 frameiso[i] = pExpInfo->arIso[i];
276 if (i >= HDR_frame_num)
277 {
278 exp_gain[i] = pExpInfo->arAGain[HDR_frame_num - 1] * pExpInfo->arDGain[HDR_frame_num - 1];
279 frameEt[i] = pExpInfo->arTime[HDR_frame_num - 1];
280 frameiso[i] = pExpInfo->arIso[HDR_frame_num - 1];
281 }
282 frame_exp_val[i] = frameiso[i] * frameEt[i];
283
284 LOGD_ANR("again: idx:%d gain:%d time:%f HDR_frame_num:%d exp: %f %f %f \n",
285 i, pExpInfo->arIso[i], pExpInfo->arTime[i], HDR_frame_num,
286 frameiso[i], frameEt[i], frame_exp_val[i]);
287 }
288
289
290 // calculate exposure ratio (store as float number)
291 for (int i = 0; i < 3; i++)
292 {
293 frame_exp_ratio[i] = frame_exp_val[HDR_frame_num - 1] / frame_exp_val[i];
294 }
295
296 // calculate the fixed gain number {12i, 6f}
297 for (int i = 2; i >= 0; i--)
298 {
299 uint32_t a = (1 << (GAIN_HDR_MERGE_IN2_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1;
300 dGain[i] = (frame_exp_ratio[i] * exp_gain[i]) / exp_gain[2];
301 pGainFix->sw_gain[i] = gain_float_lim2_int(dGain[i], GAIN_HDR_MERGE_IN_FIX_BITS_DECI, 1); // 12:6
302
303 if(pExpInfo->hdr_mode == 0) {
304 if (i == 0)
305 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN2_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
306 else if (i == 1)
307 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN1_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
308 else
309 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN0_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
310 } else if(pExpInfo->hdr_mode == 1) {
311 LOGD_ANR("enter 2fram hdr mode, scale_s:%f\n", pSelect->hdr_gain_scale_s);
312 if (i == 0) {
313 if(pSelect->hdrgain_ctrl_enable) {
314 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i] * pSelect->hdr_gain_scale_s, (1 << (GAIN_HDR_MERGE_IN2_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
315 } else {
316 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN2_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
317 }
318 } else if (i == 1)
319 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN1_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
320 else
321 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN0_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
322 } else if(pExpInfo->hdr_mode == 2) {
323 if (i == 0) {
324 if(pSelect->hdrgain_ctrl_enable) {
325 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i] * pSelect->hdr_gain_scale_s, (1 << (GAIN_HDR_MERGE_IN2_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
326 } else {
327 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN2_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
328 }
329 } else if (i == 1) {
330 if(pSelect->hdrgain_ctrl_enable) {
331 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i] * pSelect->hdr_gain_scale_m, (1 << (GAIN_HDR_MERGE_IN1_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
332 } else {
333 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN1_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
334 }
335 } else
336 pGainFix->sw_gain[i] = MIN(pGainFix->sw_gain[i], (1 << (GAIN_HDR_MERGE_IN0_FIX_BITS_INTE + GAIN_HDR_MERGE_IN_FIX_BITS_DECI)) - 1);
337 }
338
339 }
340
341 gain_fix_Printf_v2(pGainFix);
342 LOGI_ANR("%s:(%d) exit\n", __FUNCTION__, __LINE__);
343
344 return AGAINV2_RET_SUCCESS;
345
346 }
347
348
gain_fix_Printf_v2(RK_GAIN_Fix_V2_t * pFix)349 Again_result_V2_t gain_fix_Printf_v2(RK_GAIN_Fix_V2_t * pFix)
350 {
351 LOGI_ANR("%s:(%d) enter\n", __FUNCTION__, __LINE__);
352
353 if(pFix == NULL) {
354 LOGE_ANR("%s(%d): null pointer\n", __FUNCTION__, __LINE__);
355 return AGAINV2_RET_NULL_POINTER;
356 }
357
358
359 LOGD_ANR("0x3f00: sw_gain2ddr_mode:0x%x sw_gain2ddr_wr_en:0x%x sw_3dlut_gain_en:0x%x sw_dhaz_gain_en:0x%x sw_adrc_gain_en:0x%x sw_lsc_gain_en:0x%x\n",
360 pFix->sw_gain2ddr_mode,
361 pFix->sw_gain2ddr_wr_en,
362 pFix->sw_3dlut_gain_en,
363 pFix->sw_dhaz_gain_en,
364 pFix->sw_adrc_gain_en,
365 pFix->sw_lsc_gain_en);
366
367 LOGD_ANR("0x3f00: sw_gain_module_free_mode:0x%x sw_gain_dmard_mode_en:0x%x sw_bayer3dnr_gain_en:0x%x sw_gain_mp_pipe_dis:0x%x sw_gain_gate_always_on:%d sw_mge_gain_en:0x%x sw_gain_en:0x%x\n",
368 pFix->sw_gain_module_free_mode,
369 pFix->sw_gain_dmard_mode_en,
370 pFix->sw_bayer3dnr_gain_en,
371 pFix->sw_gain_mp_pipe_dis,
372 pFix->sw_gain_gate_always_on,
373 pFix->sw_mge_gain_en,
374 pFix->sw_gain_en);
375
376 LOGD_ANR("0x3f04: sw_gain: 0x%x 0x%x 0x%x\n",
377 pFix->sw_gain[0],
378 pFix->sw_gain[1],
379 pFix->sw_gain[2]);
380
381 LOGI_ANR("%s:(%d) exit\n", __FUNCTION__, __LINE__);
382
383 return AGAINV2_RET_SUCCESS;
384
385 }
386
387
388
389
390
391
392