1 /*
2 * rk_aiq_alsc_algo.cpp
3
4 * for rockchip v2.0.0
5 *
6 * Copyright (c) 2019 Rockchip Corporation
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21 /* for rockchip v2.0.0*/
22
23 #include "rk_aiq_algo_types.h"
24 #include "alsc/rk_aiq_alsc_algo.h"
25 #include "xcam_log.h"
26 #include "interpolation.h"
27 #include "RkAiqCalibDbV2Helper.h"
28 #include "rk_aiq_alsc_convert_otp.h"
29
30 RKAIQ_BEGIN_DECLARE
31
32
33 /******************************************************************************
34 * Test Function
35 ******************************************************************************/
36 #define _TEST_LSC_VALID_ON_HARDWARE 0
37 #if _TEST_LSC_VALID_ON_HARDWARE
38 /** @brief set lsc 4 channel table to the given value*/
_memset_lsc(rk_aiq_lsc_cfg_t & tb,uint16_t value)39 static void _memset_lsc(rk_aiq_lsc_cfg_t& tb, uint16_t value) {
40 for (uint32_t i = 0; i < sizeof(tb.r_data_tbl)/sizeof(tb.r_data_tbl[0]); i++)
41 {
42 tb.r_data_tbl[i] = value;
43 }
44 for (uint32_t i = 0; i < sizeof(tb.gr_data_tbl)/sizeof(tb.gr_data_tbl[0]); i++)
45 {
46 tb.gr_data_tbl[i] = value;
47 }
48 for (uint32_t i = 0; i < sizeof(tb.gb_data_tbl)/sizeof(tb.gb_data_tbl[0]); i++)
49 {
50 tb.gb_data_tbl[i] = value;
51 }
52 for (uint32_t i = 0; i < sizeof(tb.b_data_tbl)/sizeof(tb.b_data_tbl[0]); i++)
53 {
54 tb.b_data_tbl[i] = value;
55 }
56 }
57
58 /** @brief test function: if lsc config is valid in hardware, you will see blink on liveview.*/
_test_if_hw_lsc_valid(alsc_handle_t hAlsc)59 static void _test_if_hw_lsc_valid(alsc_handle_t hAlsc)
60 {
61 #define ONE_TIME_STATE 1
62 #define THREE_TIME_STATE 3
63
64 static int cur_state = ONE_TIME_STATE;
65 int next_state = cur_state;
66
67 switch (cur_state)
68 {
69 case ONE_TIME_STATE: {
70 next_state = THREE_TIME_STATE;
71 _memset_lsc(hAlsc->lscHwConf, 1024);
72 } break;
73
74 case THREE_TIME_STATE: {
75 next_state = ONE_TIME_STATE;
76 _memset_lsc(hAlsc->lscHwConf, 3072);
77 } break;
78
79 default:
80 break;
81 }
82 cur_state = next_state;
83 }
84 #endif
85
genLscMatrixToHwConf(lsc_matrix_t * dampedLscMatrixTable,rk_aiq_lsc_cfg_t * lscHwConf,alsc_otp_grad_t * otpGrad)86 static void genLscMatrixToHwConf(lsc_matrix_t *dampedLscMatrixTable, rk_aiq_lsc_cfg_t *lscHwConf, alsc_otp_grad_t *otpGrad)
87 {
88 if (!dampedLscMatrixTable || !lscHwConf) {
89 LOGE_ALSC("%s: input params is error!\n", __func__);
90 return;
91 }
92
93 // apply sensor lsc otp
94 for (int32_t i = 0; i < LSC_DATA_TBL_SIZE; i++) {
95 lscHwConf->r_data_tbl[i] = dampedLscMatrixTable->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[i] * \
96 (float(otpGrad->lsc_r[i]) / 1024) + 0.5;
97 lscHwConf->gr_data_tbl[i] = dampedLscMatrixTable->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[i] * \
98 (float(otpGrad->lsc_gr[i]) / 1024) + 0.5;
99 lscHwConf->gb_data_tbl[i] = dampedLscMatrixTable->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[i] * \
100 (float(otpGrad->lsc_gb[i]) / 1024) + 0.5;
101 lscHwConf->b_data_tbl[i] = dampedLscMatrixTable->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[i] * \
102 (float(otpGrad->lsc_b[i]) / 1024) + 0.5;
103 }
104 }
105
illuminant_index_estimation(alsc_mode_data_t & alsc_mode_data,float awbGain[2],uint32_t & illu_case_id)106 XCamReturn illuminant_index_estimation(alsc_mode_data_t& alsc_mode_data, float awbGain[2], uint32_t& illu_case_id)
107 {
108 LOG1_ALSC( "%s: (enter)\n", __FUNCTION__);
109 XCamReturn ret = XCAM_RETURN_ERROR_FAILED;
110 float minDist = 9999999;
111 float dist;
112 float& nRG = awbGain[0]; //current R/G gain
113 float& nBG = awbGain[1]; //current B/G gain
114
115 for(uint32_t index = 0; index < alsc_mode_data.illu_case_count; index++)
116 {
117 pIlluCase_t illu_case = alsc_mode_data.illu_case[index];
118 float refRG = illu_case->alsc_cof->wbGain[0];
119 float refBG = illu_case->alsc_cof->wbGain[1];
120 dist = sqrt((nRG - refRG) * (nRG - refRG) + (nBG - refBG) * (nBG - refBG));
121 if(dist < minDist)
122 {
123 minDist = dist;
124 illu_case_id = index;
125 ret = XCAM_RETURN_NO_ERROR;
126 }
127 }
128 if(ret != XCAM_RETURN_NO_ERROR) {
129 LOGE_ALSC("fail to estimate illuminant!!!\n");
130 }
131
132 LOGD_ALSC( "wbGain:%f,%f, estimation illuminant is %s(%d) \n", awbGain[0], awbGain[1],
133 alsc_mode_data.illu_case[illu_case_id]->alsc_cof->name, illu_case_id);
134 LOG1_ALSC( "%s: (exit)\n", __FUNCTION__);
135 return ret;
136 }
137
OrderLscProfilesByVignetting(pLscTableProfile_t * pLscProfiles,const uint32_t cnt)138 static XCamReturn OrderLscProfilesByVignetting
139 (
140 pLscTableProfile_t* pLscProfiles,
141 const uint32_t cnt
142 ) {
143 uint32_t i, j;
144
145 for (i = 0; i < (cnt - 1); ++i) {
146 for (j = 0; j < (cnt - i - 1); ++j) {
147 if (pLscProfiles[j]->vignetting < pLscProfiles[j + 1]->vignetting) {
148 pLscTableProfile_t temp = pLscProfiles[j];
149 pLscProfiles[j] = pLscProfiles[j + 1];
150 pLscProfiles[j + 1] = temp;
151 }
152 }
153 }
154
155 return (XCAM_RETURN_NO_ERROR);
156 }
157
158 /** @brief assume that the vignetting is from large to small*/
VignSelectLscProfiles(alsc_illu_case_t * illu_case,const float fVignetting,pLscTableProfile_t & ceilling,pLscTableProfile_t & floor)159 static XCamReturn VignSelectLscProfiles
160 (
161 alsc_illu_case_t* illu_case,
162 const float fVignetting,
163 pLscTableProfile_t &ceilling,
164 pLscTableProfile_t &floor
165 ) {
166 XCamReturn XCamReturn = XCAM_RETURN_NO_ERROR;
167 alsc_illu_case_resolution_t& current_res = illu_case->res_group[illu_case->current_res_idx];
168
169 if (fVignetting >= current_res.lsc_table_group[0]->vignetting) {
170 floor = current_res.lsc_table_group[0];
171 ceilling = floor;
172 LOGD_ALSC( "select:%s \n", floor->name);
173 XCamReturn = XCAM_RETURN_ERROR_OUTOFRANGE;
174 } else {
175 uint32_t nLast = current_res.lsc_table_count - 1;
176 if (fVignetting <= current_res.lsc_table_group[nLast]->vignetting) {
177 ceilling = current_res.lsc_table_group[nLast];
178 floor = ceilling;
179 LOGD_ALSC( "select:%s \n", ceilling->name);
180 XCamReturn = XCAM_RETURN_ERROR_OUTOFRANGE;
181 } else {
182 uint32_t n = 0;
183
184 /* find the segment */
185 while ((n <= nLast) && (fVignetting <= current_res.lsc_table_group[n]->vignetting)) {
186 n++;
187 }
188
189 if (n > 0)
190 n--;
191
192 ceilling = current_res.lsc_table_group[n];
193 floor = current_res.lsc_table_group[n + 1];
194
195 }
196 }
197
198 return (XCamReturn);
199 }
200
201
202
203 /******************************************************************************
204 * InterpolateMatrices
205 *****************************************************************************/
VignInterpolateMatrices(const float fVignetting,pLscTableProfile_t pLscProfile1,pLscTableProfile_t pLscProfile2,lsc_matrix_t * pResMatrix)206 static XCamReturn VignInterpolateMatrices
207 (
208 const float fVignetting,
209 pLscTableProfile_t pLscProfile1,
210 pLscTableProfile_t pLscProfile2,
211 lsc_matrix_t* pResMatrix
212 ) {
213 XCamReturn iXCamReturn = XCAM_RETURN_ERROR_PARAM;
214
215 if ((pLscProfile1 != NULL) && (pLscProfile2 != NULL) && (pResMatrix != NULL)) {
216 float fVigA = pLscProfile1->vignetting;
217 float fVigB = pLscProfile2->vignetting;
218
219 float f1 = (fVigB - fVignetting) / (fVigB - fVigA);
220 /* FLOAT f2 = ( fVigB - fVignetting ) / ( fVigB - fVigA ); */
221 float f2 = 1.0f - f1;
222 LOGD_ALSC( "select:%s :%f and %s :%f", pLscProfile1->name,
223 f1, pLscProfile2->name, f2);
224
225 /* left shift 16 */
226 uint32_t f1_ = (uint32_t)(f1 * 65536.0f);
227 uint32_t f2_ = (uint32_t)(f2 * 65536.0f);
228
229 int16_t i;
230
231 uint32_t red;
232 uint32_t greenr;
233 uint32_t greenb;
234 uint32_t blue;
235
236 for (i = 0; i < (LSC_DATA_TBL_SIZE); i++) {
237 red = (f1_ * (uint32_t)pLscProfile1->lsc_samples_red.uCoeff[i])
238 + (f2_ * (uint32_t)pLscProfile2->lsc_samples_red.uCoeff[i]);
239
240 greenr = (f1_ * (uint32_t)pLscProfile1->lsc_samples_greenR.uCoeff[i])
241 + (f2_ * (uint32_t)pLscProfile2->lsc_samples_greenR.uCoeff[i]);
242
243 greenb = (f1_ * (uint32_t)pLscProfile1->lsc_samples_greenB.uCoeff[i])
244 + (f2_ * (uint32_t)pLscProfile2->lsc_samples_greenB.uCoeff[i]);
245
246 blue = (f1_ * (uint32_t)pLscProfile1->lsc_samples_blue.uCoeff[i])
247 + (f2_ * (uint32_t)pLscProfile2->lsc_samples_blue.uCoeff[i]);
248
249 /* with round up (add 65536/2 <=> 0.5) before right shift */
250 pResMatrix->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[i] = (uint16_t)((red + (65536 >> 1)) >> 16);
251 pResMatrix->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[i] = (uint16_t)((greenr + (65536 >> 1)) >> 16);
252 pResMatrix->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[i] = (uint16_t)((greenb + (65536 >> 1)) >> 16);
253 pResMatrix->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[i] = (uint16_t)((blue + (65536 >> 1)) >> 16);
254 }
255
256 iXCamReturn = XCAM_RETURN_NO_ERROR;
257 }
258
259 return (iXCamReturn);
260 }
261
262
263 /******************************************************************************
264 * Damping
265 *****************************************************************************/
Damping(float damp,lsc_matrix_t * pMatrixUndamped,rk_aiq_lsc_cfg_t * lscHwConf,bool * converge)266 static XCamReturn Damping
267 (
268 float damp, /**< damping coefficient */
269 lsc_matrix_t* pMatrixUndamped, /**< undamped new computed matrices */
270 rk_aiq_lsc_cfg_t *lscHwConf,
271 bool* converge
272 ) {
273 XCamReturn XCamReturn = XCAM_RETURN_ERROR_PARAM;
274
275 if ((pMatrixUndamped != NULL) && (lscHwConf != NULL)) {
276 /* left shift 16 */
277 uint32_t f1_ = (uint32_t)(damp * 65536.0f);
278 uint32_t f2_ = (uint32_t)(65536U - f1_);
279
280 int16_t i;
281
282 uint32_t red;
283 uint32_t greenr;
284 uint32_t greenb;
285 uint32_t blue;
286 float dis=0;
287 float dis_th=0.015;
288 bool speedDamp = true;
289 dis = (float)(lscHwConf->r_data_tbl[0]-
290 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0])/
291 (lscHwConf->r_data_tbl[0]+
292 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0]);
293 speedDamp = fabs(dis)<dis_th;
294 dis = (float)(lscHwConf->b_data_tbl[LSC_DATA_TBL_SIZE-1]-
295 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[LSC_DATA_TBL_SIZE-1])/
296 (lscHwConf->b_data_tbl[LSC_DATA_TBL_SIZE-1]+
297 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[LSC_DATA_TBL_SIZE-1]);
298 speedDamp &= fabs(dis)<dis_th;
299 if(speedDamp){
300 damp = 0;
301 f1_ = 0;
302 f2_ = 65536;
303 }
304
305 for (i = 0; i < (LSC_DATA_TBL_SIZE); i++) {
306 red = (f1_ * (uint32_t)lscHwConf->r_data_tbl[i])
307 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[i]);
308
309 greenr = (f1_ * (uint32_t)lscHwConf->gr_data_tbl[i])
310 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[i]);
311
312 greenb = (f1_ * (uint32_t)lscHwConf->gb_data_tbl[i])
313 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[i]);
314
315 blue = (f1_ * (uint32_t)lscHwConf->b_data_tbl[i])
316 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[i]);
317
318 /* with round up (add 65536/2 <=> 0.5) before right shift */
319 lscHwConf->r_data_tbl[i] = (uint16_t)((red + (65536 >> 1)) >> 16);
320 lscHwConf->gr_data_tbl[i] = (uint16_t)((greenr + (65536 >> 1)) >> 16);
321 lscHwConf->gb_data_tbl[i] = (uint16_t)((greenb + (65536 >> 1)) >> 16);
322 lscHwConf->b_data_tbl[i] = (uint16_t)((blue + (65536 >> 1)) >> 16);
323 }
324 LOGD_ALSC( "dampfactor:%f", damp);
325 LOGD_ALSC( " undampedLscMatrix r[0:3]:%d,%d,%d,%d, gr[0:3]:%d,%d,%d,%d, gb[0:3]:%d,%d,%d,%d, b[0:3]:%d,%d,%d,%d\n",
326 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0],
327 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[1],
328 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[2],
329 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[3],
330 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[0],
331 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[1],
332 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[2],
333 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[3],
334 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[0],
335 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[1],
336 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[2],
337 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[3],
338 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[0],
339 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[1],
340 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[2],
341 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[3]
342 );
343 LOGD_ALSC( " dampedLscMatrix r[0:3]:%d,%d,%d,%d, gr[0:3]:%d,%d,%d,%d, gb[0:3]:%d,%d,%d,%d, b[0:3]:%d,%d,%d,%d\n",
344 lscHwConf->r_data_tbl[0],
345 lscHwConf->r_data_tbl[1],
346 lscHwConf->r_data_tbl[2],
347 lscHwConf->r_data_tbl[3],
348 lscHwConf->gr_data_tbl[0],
349 lscHwConf->gr_data_tbl[1],
350 lscHwConf->gr_data_tbl[2],
351 lscHwConf->gr_data_tbl[3],
352 lscHwConf->gb_data_tbl[0],
353 lscHwConf->gb_data_tbl[1],
354 lscHwConf->gb_data_tbl[2],
355 lscHwConf->gb_data_tbl[3],
356 lscHwConf->b_data_tbl[0],
357 lscHwConf->b_data_tbl[1],
358 lscHwConf->b_data_tbl[2],
359 lscHwConf->b_data_tbl[3]
360 );
361
362 *converge = speedDamp;
363 XCamReturn = XCAM_RETURN_NO_ERROR;
364 }
365
366 return (XCamReturn);
367 }
368
DampingandOtp(float damp,lsc_matrix_t * pMatrixUndamped,lsc_matrix_t * pMatrixDamped,alsc_otp_grad_t * otpGrad,rk_aiq_lsc_cfg_t * lscHwConf,bool * converge)369 static XCamReturn DampingandOtp
370 (
371 float damp, /**< damping coefficient */
372 lsc_matrix_t* pMatrixUndamped, /**< undamped new computed matrices */
373 lsc_matrix_t* pMatrixDamped, /**< old matrices and XCamReturn */
374 alsc_otp_grad_t *otpGrad,
375 rk_aiq_lsc_cfg_t *lscHwConf,
376 bool* converge
377 ) {
378 XCamReturn XCamReturn = XCAM_RETURN_ERROR_PARAM;
379
380 if ((pMatrixUndamped != NULL) && (pMatrixDamped != NULL)) {
381 /* left shift 16 */
382 uint32_t f1_ = (uint32_t)(damp * 65536.0f);
383 uint32_t f2_ = (uint32_t)(65536U - f1_);
384
385 int16_t i;
386
387 uint32_t red;
388 uint32_t greenr;
389 uint32_t greenb;
390 uint32_t blue;
391 float dis=0;
392 float dis_th=0.015;
393 bool speedDamp = true;
394 dis = (float)(pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0]-
395 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0])/
396 (pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0]+
397 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0]);
398 speedDamp = fabs(dis)<dis_th;
399 dis = (float)(pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[LSC_DATA_TBL_SIZE-1]-
400 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[LSC_DATA_TBL_SIZE-1])/
401 (pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[LSC_DATA_TBL_SIZE-1]+
402 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[LSC_DATA_TBL_SIZE-1]);
403 speedDamp &= fabs(dis)<dis_th;
404 if(speedDamp){
405 damp = 0;
406 f1_ = 0;
407 f2_ = 65536;
408 }
409
410 for (i = 0; i < (LSC_DATA_TBL_SIZE); i++) {
411 red = (f1_ * (uint32_t)pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[i])
412 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[i]);
413
414 greenr = (f1_ * (uint32_t)pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[i])
415 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[i]);
416
417 greenb = (f1_ * (uint32_t)pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[i])
418 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[i]);
419
420 blue = (f1_ * (uint32_t)pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[i])
421 + (f2_ * (uint32_t)pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[i]);
422
423 /* with round up (add 65536/2 <=> 0.5) before right shift */
424 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[i] = (uint16_t)((red + (65536 >> 1)) >> 16);
425 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[i] = (uint16_t)((greenr + (65536 >> 1)) >> 16);
426 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[i] = (uint16_t)((greenb + (65536 >> 1)) >> 16);
427 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[i] = (uint16_t)((blue + (65536 >> 1)) >> 16);
428 }
429
430 genLscMatrixToHwConf(pMatrixDamped, lscHwConf, otpGrad);
431
432 LOGD_ALSC( "dampfactor:%f", damp);
433 LOGD_ALSC( " undampedLscMatrix r[0:3]:%d,%d,%d,%d, gr[0:3]:%d,%d,%d,%d, gb[0:3]:%d,%d,%d,%d, b[0:3]:%d,%d,%d,%d\n",
434 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0],
435 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[1],
436 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[2],
437 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[3],
438 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[0],
439 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[1],
440 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[2],
441 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[3],
442 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[0],
443 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[1],
444 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[2],
445 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[3],
446 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[0],
447 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[1],
448 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[2],
449 pMatrixUndamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[3]
450 );
451 LOGD_ALSC( " dampedLscMatrix r[0:3]:%d,%d,%d,%d, gr[0:3]:%d,%d,%d,%d, gb[0:3]:%d,%d,%d,%d, b[0:3]:%d,%d,%d,%d\n",
452 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[0],
453 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[1],
454 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[2],
455 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_RED].uCoeff[3],
456 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[0],
457 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[1],
458 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[2],
459 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR].uCoeff[3],
460 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[0],
461 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[1],
462 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[2],
463 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB].uCoeff[3],
464 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[0],
465 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[1],
466 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[2],
467 pMatrixDamped->LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE].uCoeff[3]
468 );
469
470 *converge = speedDamp;
471 XCamReturn = XCAM_RETURN_NO_ERROR;
472 }
473
474 return (XCamReturn);
475 }
476
CamCalibDbGetLscProfileByName(const CalibDbV2_LSC_t * calib2_lsc,char * name,pLscTableProfile_t & pLscTableProfile)477 static XCamReturn CamCalibDbGetLscProfileByName
478 (
479 const CalibDbV2_LSC_t *calib2_lsc,
480 char* name,
481 pLscTableProfile_t &pLscTableProfile
482 ){
483 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
484
485 XCamReturn ret = XCAM_RETURN_ERROR_FAILED;
486
487 for(int i = 0; i < calib2_lsc->tbl.tableAll_len; i++) {
488 if(strcmp(calib2_lsc->tbl.tableAll[i].name, name) == 0) {
489 pLscTableProfile = &calib2_lsc->tbl.tableAll[i];
490 ret = XCAM_RETURN_NO_ERROR;
491 break;
492 }
493 }
494 if(ret != XCAM_RETURN_NO_ERROR) {
495 LOGD_ALSC("%s: can't find %s in tableAll\n", __func__, name);
496 }
497 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
498
499 return ret;
500 }
501
GetLscResIdxByName(alsc_illu_case_t * illu_case,char * name,uint32_t & resIdx)502 static XCamReturn GetLscResIdxByName(alsc_illu_case_t* illu_case, char* name, uint32_t &resIdx)
503 {
504 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
505
506 XCamReturn ret = XCAM_RETURN_ERROR_FAILED;
507
508 for(uint32_t i = 0; i < illu_case->res_count; i++) {
509 if(strcmp(illu_case->res_group[i].resolution.name, name) == 0) {
510 resIdx = i;
511 illu_case->current_res_idx = i;
512 ret = XCAM_RETURN_NO_ERROR;
513 break;
514 }
515 }
516 if(ret != XCAM_RETURN_NO_ERROR) {
517 LOGE_ALSC("can't find %s in lscResName\n", name);
518 }
519 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
520
521 return ret;
522 }
523
UpdateDominateIlluList(struct list_head * l_head,int illu,int listMaxSize)524 void UpdateDominateIlluList(struct list_head* l_head, int illu, int listMaxSize)
525 {
526 illu_node_t* pCurNode, * pNode0;
527 if (listMaxSize == 0) {
528 return;
529 }
530 int sizeList = get_list_num(l_head);
531 if (sizeList < listMaxSize) {
532 pCurNode = (illu_node_t*)malloc(sizeof(illu_node_t));
533 pCurNode->value = illu;
534 list_prepare_item(&pCurNode->node);
535 list_add_tail((struct list_head*)(&pCurNode->node), l_head);
536 }
537 else {
538 // input list
539 // |-------------------------|
540 // head<->n0<->n1<->n2<->n3
541 // output list
542 // |-------------------------|
543 // n0'<->head<->n1<->n2<->n3
544 // n0'->value = illu;
545 pNode0 = (illu_node_t*)(l_head->next);
546 pNode0->value = illu;
547 struct list_head* nodeH = l_head;
548 struct list_head* node0 = nodeH->next;
549 list_swap_item(nodeH, node0);
550
551 }
552 }
553
StableIlluEstimation(struct list_head * head,int listSize,int illuNum,uint32_t & newIllu)554 void StableIlluEstimation(struct list_head * head, int listSize, int illuNum, uint32_t& newIllu)
555 {
556 int sizeList = get_list_num(head);
557 if (sizeList < listSize || listSize == 0) {
558 return;
559 }
560
561 struct list_head* pNextNode = head->next;
562 illu_node_t* pL;
563 int* illuSet = (int*)malloc(illuNum * sizeof(int));
564 memset(illuSet, 0, illuNum * sizeof(int));
565 while (head != pNextNode)
566 {
567 pL = (illu_node_t*)pNextNode;
568 illuSet[pL->value]++;
569 pNextNode = pNextNode->next;
570 }
571 int max_count = 0;
572 for (int i = 0; i < illuNum; i++) {
573 LOGV_ALSC("illu(%d), count(%d)\n", i, illuSet[i]);
574 if (illuSet[i] > max_count) {
575 max_count = illuSet[i];
576 newIllu = i;
577 }
578 }
579 free(illuSet);
580
581 }
582
583
ClearContext(alsc_handle_t hAlsc)584 static void ClearContext(alsc_handle_t hAlsc)
585 {
586 clear_list(&hAlsc->alscRest.dominateIlluList);
587
588 for (uint32_t mode_id = 0; mode_id < USED_FOR_CASE_MAX; mode_id++) {
589 if (hAlsc->alsc_mode[mode_id].illu_case != nullptr)
590 free(hAlsc->alsc_mode[mode_id].illu_case);
591 }
592
593 if (hAlsc->illu_case) {
594 for (uint32_t id = 0; id < hAlsc->illu_case_count; id++)
595 {
596 alsc_illu_case_t& illu_case = hAlsc->illu_case[id];
597 if (illu_case.res_group) {
598 for (uint32_t res_id = 0; res_id < illu_case.res_count; res_id++)
599 {
600 if (illu_case.res_group[res_id].lsc_table_group) {
601 free(illu_case.res_group[res_id].lsc_table_group);
602 illu_case.res_group[res_id].lsc_table_group = NULL;
603 } else {
604 LOGI_ALSC("%s: free: res_group[%d].lsc_table_group is already NULL!\n", __func__, res_id);
605 }
606 }
607 free(illu_case.res_group);
608 illu_case.res_group = NULL;
609 } else {
610 LOGI_ALSC("%s: free: illu_case.res_group is already NULL!\n", __func__);
611 }
612 }
613 free(hAlsc->illu_case);
614 hAlsc->illu_case = NULL;
615 hAlsc->illu_case_count = 0;
616 } else {
617 LOGI_ALSC("%s: free: hAlsc->illu_case is already NULL!\n", __func__);
618 }
619
620 if (hAlsc->res_grad) {
621 free(hAlsc->res_grad);
622 hAlsc->res_grad = NULL;
623 hAlsc->res_grad_count = 0;
624 } else {
625 LOGI_ALSC("%s: free: hAlsc->res_grad is already NULL!\n", __func__);
626 }
627
628 }
629
convertSensorLscOTP(resolution_t * cur_res,alsc_otp_grad_t * otpGrad,RkAiqBayerPattern_t bayerPattern)630 XCamReturn convertSensorLscOTP(resolution_t *cur_res, alsc_otp_grad_t *otpGrad,
631 RkAiqBayerPattern_t bayerPattern)
632 {
633 XCamReturn ret = XCAM_RETURN_NO_ERROR;
634
635 if (!cur_res || !otpGrad)
636 return XCAM_RETURN_BYPASS;
637
638 if (!otpGrad->flag)
639 return XCAM_RETURN_BYPASS;
640
641 if ((cur_res->width >= otpGrad->width && \
642 cur_res->height >= otpGrad->height) || \
643 (cur_res->width <= otpGrad->width && \
644 cur_res->height <= otpGrad->height)) {
645 convertLscTableParameter(cur_res, otpGrad, bayerPattern);
646 }
647
648 return ret;
649 }
650
alscGetOtpInfo(RkAiqAlgoCom * params)651 XCamReturn alscGetOtpInfo(RkAiqAlgoCom* params)
652 {
653 if (!params)
654 return XCAM_RETURN_BYPASS;
655
656 alsc_handle_t hAlsc = (alsc_handle_t)(params->ctx->alsc_para);
657 RkAiqAlgoConfigAlsc *para = (RkAiqAlgoConfigAlsc *)params;
658
659 alsc_sw_info_t *alscSwInfo = ¶->alsc_sw_info;
660 if (alscSwInfo->otpInfo.flag) {
661 hAlsc->otpGrad.flag = alscSwInfo->otpInfo.flag;
662 hAlsc->otpGrad.width = alscSwInfo->otpInfo.width;
663 hAlsc->otpGrad.height = alscSwInfo->otpInfo.height;
664 hAlsc->otpGrad.table_size = alscSwInfo->otpInfo.table_size;
665 memcpy(hAlsc->otpGrad.lsc_r, alscSwInfo->otpInfo.lsc_r, sizeof(hAlsc->otpGrad.lsc_r));
666 memcpy(hAlsc->otpGrad.lsc_gr, alscSwInfo->otpInfo.lsc_gr, sizeof(hAlsc->otpGrad.lsc_gr));
667 memcpy(hAlsc->otpGrad.lsc_gb, alscSwInfo->otpInfo.lsc_gb, sizeof(hAlsc->otpGrad.lsc_gb));
668 memcpy(hAlsc->otpGrad.lsc_b, alscSwInfo->otpInfo.lsc_b, sizeof(hAlsc->otpGrad.lsc_b));
669 } else {
670 hAlsc->alscSwInfo.otpInfo.flag = 0;
671 }
672
673 LOGD_ALSC("otp: flag %d, WxH: %dx%d, table_size: %d\n",
674 hAlsc->otpGrad.flag,
675 hAlsc->otpGrad.width,
676 hAlsc->otpGrad.height,
677 hAlsc->otpGrad.table_size);
678
679 LOGD_ALSC( "otp LscMatrix r[0:3]:%d,%d,%d,%d, gr[0:3]:%d,%d,%d,%d, gb[0:3]:%d,%d,%d,%d, b[0:3]:%d,%d,%d,%d\n",
680 hAlsc->otpGrad.lsc_r[0],
681 hAlsc->otpGrad.lsc_r[1],
682 hAlsc->otpGrad.lsc_r[2],
683 hAlsc->otpGrad.lsc_r[3],
684 hAlsc->otpGrad.lsc_gr[0],
685 hAlsc->otpGrad.lsc_gr[1],
686 hAlsc->otpGrad.lsc_gr[2],
687 hAlsc->otpGrad.lsc_gr[3],
688 hAlsc->otpGrad.lsc_gb[0],
689 hAlsc->otpGrad.lsc_gb[1],
690 hAlsc->otpGrad.lsc_gb[2],
691 hAlsc->otpGrad.lsc_gb[3],
692 hAlsc->otpGrad.lsc_b[0],
693 hAlsc->otpGrad.lsc_b[1],
694 hAlsc->otpGrad.lsc_b[2],
695 hAlsc->otpGrad.lsc_b[3]);
696
697 return XCAM_RETURN_NO_ERROR;
698 }
699
700 /** @brief called to arrange data to fill alsc_mode_data_t from CalibDb */
UpdateLscCalibPara(alsc_handle_t hAlsc)701 static XCamReturn UpdateLscCalibPara(alsc_handle_t hAlsc)
702 {
703 const CalibDbV2_LSC_t* calib2 = hAlsc->calibLscV2;
704 const CalibDbV2_AlscCof_ill_t* alsc_cof_tmp;
705 uint32_t mode_count[USED_FOR_CASE_MAX];
706 memset(mode_count, 0, sizeof(mode_count));
707
708 hAlsc->illu_case_count = calib2->alscCoef.illAll_len;
709 hAlsc->illu_case = (alsc_illu_case_t*)malloc(hAlsc->illu_case_count * sizeof(alsc_illu_case_t));
710 memset(hAlsc->illu_case, 0, hAlsc->illu_case_count * sizeof(alsc_illu_case_t));
711
712 // update hAlsc->illu_case
713 for(uint32_t ill_id = 0; ill_id < hAlsc->illu_case_count; ill_id++)
714 {
715 alsc_illu_case_t& illu_case = hAlsc->illu_case[ill_id];
716 alsc_cof_tmp = &(calib2->alscCoef.illAll[ill_id]);
717
718 illu_case.alsc_cof = alsc_cof_tmp;
719 illu_case.res_count = calib2->common.resolutionAll_len;
720 illu_case.res_group = (alsc_illu_case_resolution_t*)malloc
721 (illu_case.res_count * sizeof(alsc_illu_case_resolution_t));
722 memset(illu_case.res_group, 0, illu_case.res_count * sizeof(alsc_illu_case_resolution_t));
723
724 for(uint32_t res_id = 0; res_id < illu_case.res_count; res_id++)
725 {
726 alsc_illu_case_resolution_t& illu_case_res = illu_case.res_group[res_id];
727 strcpy(illu_case_res.resolution.name, calib2->common.resolutionAll[res_id].name);
728 //TODO: illu_case.resolution.width & height
729 illu_case_res.lsc_table_count = alsc_cof_tmp->tableUsed_len;
730 illu_case_res.lsc_table_group = (pLscTableProfile_t*)malloc(
731 illu_case_res.lsc_table_count * sizeof(pLscTableProfile_t));
732
733 for (int used_id = 0; used_id < alsc_cof_tmp->tableUsed_len; used_id++)
734 {
735 char profile_name[64];
736 memset(profile_name, 0, sizeof(profile_name));
737 sprintf(profile_name, "%s_%s", illu_case_res.resolution.name,
738 alsc_cof_tmp->tableUsed[used_id].name);
739 XCamReturn ret = CamCalibDbGetLscProfileByName(calib2,
740 profile_name, illu_case_res.lsc_table_group[used_id]);
741 if (XCAM_RETURN_NO_ERROR != ret) {
742 LOGE_ALSC("%s: CamCalibDbGetLscProfileByName failed\n", __func__);
743 return ret;
744 }
745 }
746 OrderLscProfilesByVignetting(illu_case_res.lsc_table_group, illu_case_res.lsc_table_count);
747 }
748
749 mode_count[alsc_cof_tmp->usedForCase]++;
750 }
751
752 // malloc hAlsc->alsc_mode_data_t
753 for (uint32_t mode_id = 0; mode_id < USED_FOR_CASE_MAX; mode_id++)
754 {
755 hAlsc->alsc_mode[mode_id].illu_case_count = mode_count[mode_id];
756 if (mode_count[mode_id] == 0) {
757 hAlsc->alsc_mode[mode_id].illu_case = NULL;
758 } else {
759 hAlsc->alsc_mode[mode_id].illu_case = (pIlluCase_t*)malloc(
760 mode_count[mode_id] * sizeof(pIlluCase_t));
761 }
762 }
763
764 // update hAlsc->alsc_mode_data_t
765 uint32_t update_count[USED_FOR_CASE_MAX];
766 memset(update_count, 0, sizeof(update_count));
767 for(uint32_t ill_id = 0; ill_id < hAlsc->illu_case_count; ill_id++)
768 {
769 uint32_t used_case = hAlsc->illu_case[ill_id].alsc_cof->usedForCase;
770 if (used_case >= USED_FOR_CASE_MAX) {
771 LOGE_ALSC("%s: used_case=%d\n", __func__, used_case);
772 return XCAM_RETURN_ERROR_PARAM;
773 }
774 uint32_t update_id = update_count[used_case];
775 if (update_id >= hAlsc->alsc_mode[used_case].illu_case_count) {
776 LOGE_ALSC("%s: update_id=%d\n", __func__, update_id);
777 return XCAM_RETURN_ERROR_PARAM;
778 }
779 hAlsc->alsc_mode[used_case].illu_case[update_id] = &(hAlsc->illu_case[ill_id]);
780 update_count[used_case]++;
781 }
782
783 // molloc & calculate the grad table
784 hAlsc->res_grad_count = calib2->common.resolutionAll_len;
785 hAlsc->res_grad = (alsc_grad_t*)malloc(hAlsc->res_grad_count * sizeof(alsc_grad_t));
786 memset(hAlsc->res_grad, 0, hAlsc->res_grad_count * sizeof(alsc_grad_t));
787 for (uint32_t res_id = 0; res_id < hAlsc->res_grad_count; res_id++) {
788 CalibDbV2_Lsc_Resolution_t& src = calib2->common.resolutionAll[res_id];
789 alsc_grad_t& dst = hAlsc->res_grad[res_id];
790 strcpy(dst.resolution.name, src.name);
791 uint32_t x_size = sizeof(src.lsc_sect_size_x) / sizeof(src.lsc_sect_size_x[0]);
792 uint32_t y_size = sizeof(src.lsc_sect_size_y) / sizeof(src.lsc_sect_size_y[0]);
793 for (uint32_t i = 0; i < x_size; i++) {
794 if (0 < src.lsc_sect_size_x[i]) {
795 dst.LscXGradTbl[i] = (uint16_t)((double)(1UL << 15) / src.lsc_sect_size_x[i] + 0.5);
796 } else {
797 LOGE_ALSC("%s: src.lsc_sect_size_x[%d]=0\n", __func__, i);
798 return XCAM_RETURN_ERROR_PARAM;
799 }
800 }
801 for (uint32_t i = 0; i < y_size; i++) {
802 if (0 < src.lsc_sect_size_y[i]) {
803 dst.LscYGradTbl[i] = (uint16_t)((double)(1UL << 15) / src.lsc_sect_size_y[i] + 0.5);
804 } else {
805 LOGE_ALSC("%s: src.lsc_sect_size_y[%d]=0\n", __func__, i);
806 return XCAM_RETURN_ERROR_PARAM;
807 }
808 }
809 }
810
811 return XCAM_RETURN_NO_ERROR;
812 }
813
814 #if ARCHER_DEBUG
print_alsc_illu_case(alsc_illu_case_t & illu_case)815 static void print_alsc_illu_case(alsc_illu_case_t& illu_case) {
816 const CalibDbV2_AlscCof_ill_t *alsc_cof = illu_case.alsc_cof;
817 char tmp[256] = {0};
818 COUT(alsc_cof->usedForCase);
819 COUT(alsc_cof->name);
820 COUT(alsc_cof->wbGain[0]);
821 COUT(alsc_cof->wbGain[1]);
822 for (int i = 0; i < alsc_cof->tableUsed_len; i++) {
823 COUT(i);
824 COUT(alsc_cof->tableUsed[i].name);
825 }
826 array2str(alsc_cof->gains, alsc_cof->gains_len, tmp);
827 COUT2(alsc_cof->gains, tmp);
828 memset(tmp, 0, sizeof(tmp));
829 array2str(alsc_cof->vig, alsc_cof->vig_len, tmp);
830 COUT2(alsc_cof->vig, tmp);
831 ENDL;
832
833 for (int i = 0; i < illu_case.res_count; i++) {
834 alsc_illu_case_resolution_t& res = illu_case.res_group[i];
835 COUT(res.resolution.name);
836 COUT(res.lsc_table_count);
837 for (int k = 0; k < res.lsc_table_count; k++) {
838 COUT(k);
839 COUT(res.lsc_table_group[k]->name);
840 COUT(res.lsc_table_group[k]->resolution);
841 COUT(res.lsc_table_group[k]->illumination);
842 COUT(res.lsc_table_group[k]->vignetting);
843 }
844 }
845 COUT(illu_case.current_res_idx);
846
847 ENDL;
848 ENDL;
849 }
850
print_alsc(alsc_handle_t hAlsc)851 static void print_alsc(alsc_handle_t hAlsc)
852 {
853 for (int case_id = 0; case_id < USED_FOR_CASE_MAX; case_id++)
854 {
855 alsc_mode_data_t& mode = hAlsc->alsc_mode[case_id];
856 if (mode.illu_case_count == 0) {
857 continue;
858 }
859 for (uint32_t ill_id = 0; ill_id < mode.illu_case_count; ill_id++)
860 {
861 alsc_illu_case_t& illu_case = mode.illu_case[ill_id];
862 print_alsc_illu_case(illu_case);
863 }
864 }
865 COUT(hAlsc->calibLscV2->common.enable);
866 COUT(hAlsc->calibLscV2->common.resolutionAll_len);
867 COUT(hAlsc->calibLscV2->alscCoef.damp_enable);
868 COUT(hAlsc->calibLscV2->alscCoef.illAll_len);
869 COUT(hAlsc->calibLscV2->tableAll_len);
870 }
871 #endif
872
AlscAutoConfig(alsc_handle_t hAlsc)873 XCamReturn AlscAutoConfig(alsc_handle_t hAlsc)
874 {
875 if (hAlsc == NULL) {
876 return XCAM_RETURN_ERROR_PARAM;
877 }
878 XCamReturn ret = XCAM_RETURN_NO_ERROR;
879 LOG1_ALSC("%s: (enter) count:%d\n", __FUNCTION__, hAlsc->count);
880
881 uint32_t caseIndex = hAlsc->alscRest.caseIndex;
882 if (caseIndex >= USED_FOR_CASE_MAX) {
883 return XCAM_RETURN_ERROR_PARAM;
884 }
885
886 alsc_mode_data_t& alsc_mode_now = hAlsc->alsc_mode[caseIndex];
887 if (alsc_mode_now.illu_case == NULL) {
888 return XCAM_RETURN_ERROR_PARAM;
889 }
890
891 //1) Estimate best(nearest) illuminant case;
892 uint32_t estimateIlluCaseIdx;
893 int dominateIlluListSize = 15;//to do from xml;
894 //float varianceLumaTh = 0.006;//to do from xml;
895 ret = illuminant_index_estimation(alsc_mode_now, hAlsc->alscSwInfo.awbGain, estimateIlluCaseIdx);
896 RETURN_RESULT_IF_DIFFERENT(ret, XCAM_RETURN_NO_ERROR);
897 UpdateDominateIlluList(&hAlsc->alscRest.dominateIlluList, estimateIlluCaseIdx, dominateIlluListSize);
898 //TODO: working mode which has only one illuminant case, like gray mode, does not need to estimate index.
899 StableIlluEstimation(&hAlsc->alscRest.dominateIlluList, dominateIlluListSize,
900 alsc_mode_now.illu_case_count, estimateIlluCaseIdx);
901
902 alsc_illu_case_t* illu_case = alsc_mode_now.illu_case[estimateIlluCaseIdx];
903
904 // 2) get resolution index;
905 uint32_t resIdx;
906 ret = GetLscResIdxByName(illu_case, hAlsc->cur_res.name, resIdx);
907 RETURN_RESULT_IF_DIFFERENT(ret, XCAM_RETURN_NO_ERROR);
908
909 // 3) calculate vignetting from sensor gain;
910 float sensorGain = hAlsc->alscSwInfo.sensorGain;
911 float fVignetting;
912 interpolation(illu_case->alsc_cof->gains,
913 illu_case->alsc_cof->vig,
914 illu_case->alsc_cof->vig_len,
915 sensorGain, &fVignetting);
916 /* *************
917 * if (fVignetting/estimateIlluCaseIdx/resIdx changed || forceRunFlag)
918 * Select LscProfiles by vig
919 * if (forceRunFlag || pLscProfile1/2 changed)
920 * Interpolate tbl by vig
921 * update hAlsc->alscRest.pLscProfile1/2
922 * **************/
923 hAlsc->isReCal_ = fabs(hAlsc->alscRest.fVignetting - fVignetting) > DIVMIN ||
924 hAlsc->alscRest.estimateIlluCaseIdx != estimateIlluCaseIdx ||
925 hAlsc->alscRest.resIdx != resIdx ||
926 hAlsc->smartRunRes.forceRunFlag; //forceRunFlag: prepare(init or calib/res/graymode change) or updateAttr
927 LOGD_ALSC("hAlsc->isReCal_: %d = fVignetting(%f->%f)/estimateIlluCaseIdx(%d->%d)/resIdx(%d->%d) changed or forceRunFlag",
928 hAlsc->isReCal_, hAlsc->alscRest.fVignetting, fVignetting, hAlsc->alscRest.estimateIlluCaseIdx, estimateIlluCaseIdx,
929 hAlsc->alscRest.resIdx, resIdx, hAlsc->smartRunRes.forceRunFlag);
930 if (hAlsc->isReCal_) {
931 hAlsc->alscRest.estimateIlluCaseIdx = estimateIlluCaseIdx;
932 hAlsc->alscRest.resIdx = resIdx;
933 hAlsc->alscRest.fVignetting = fVignetting;
934
935 // 4) select vignetting section and get the lsc matrix table;
936 pLscTableProfile_t pLscProfile1 = NULL;
937 pLscTableProfile_t pLscProfile2 = NULL;
938 ret = VignSelectLscProfiles(illu_case, fVignetting, pLscProfile1, pLscProfile2);
939 if (pLscProfile1 && pLscProfile2) {
940 hAlsc->isReCal_ = hAlsc->smartRunRes.forceRunFlag ||
941 strcmp(pLscProfile1->name, hAlsc->alscRest.pLscProfile1->name) ||
942 strcmp(pLscProfile2->name, hAlsc->alscRest.pLscProfile2->name);
943 LOGD_ALSC("hAlsc->isReCal_: %d = forceRunFlag(%d) || pLscProfile1/2 changed", hAlsc->isReCal_, hAlsc->smartRunRes.forceRunFlag);
944 } else {
945 LOGE_ALSC("check %s %s pLscProfile: %p %p \n", hAlsc->cur_res.name, illu_case->alsc_cof->name, pLscProfile1, pLscProfile2);
946 return XCAM_RETURN_ERROR_PARAM;
947 }
948 if (hAlsc->isReCal_) {
949 if (ret == XCAM_RETURN_NO_ERROR) {
950 LOGD_ALSC("fVignetting: %f (%f .. %f)\n", fVignetting, pLscProfile1->vignetting, pLscProfile2->vignetting);
951
952 ret = VignInterpolateMatrices(fVignetting, pLscProfile1, pLscProfile2,
953 &hAlsc->alscRest.undampedLscMatrixTable);
954 if (ret != XCAM_RETURN_NO_ERROR) {
955 return (ret);
956 }
957 } else if (ret == XCAM_RETURN_ERROR_OUTOFRANGE) {
958 /* we don't need to interpolate */
959 LOGD_ALSC("fVignetting: %f (%f)\n", fVignetting, pLscProfile1->vignetting);
960 memcpy(&hAlsc->alscRest.undampedLscMatrixTable.LscMatrix[CAM_4CH_COLOR_COMPONENT_RED],
961 &pLscProfile1->lsc_samples_red, sizeof(Cam17x17UShortMatrix_t));
962 memcpy(&hAlsc->alscRest.undampedLscMatrixTable.LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENR],
963 &pLscProfile1->lsc_samples_greenR, sizeof(Cam17x17UShortMatrix_t));
964 memcpy(&hAlsc->alscRest.undampedLscMatrixTable.LscMatrix[CAM_4CH_COLOR_COMPONENT_GREENB],
965 &pLscProfile1->lsc_samples_greenB, sizeof(Cam17x17UShortMatrix_t));
966 memcpy(&hAlsc->alscRest.undampedLscMatrixTable.LscMatrix[CAM_4CH_COLOR_COMPONENT_BLUE],
967 &pLscProfile1->lsc_samples_blue, sizeof(Cam17x17UShortMatrix_t));
968 }
969 hAlsc->alscRest.pLscProfile1 = pLscProfile1;
970 hAlsc->alscRest.pLscProfile2 = pLscProfile2;
971 }
972 }
973
974 // 5) . Damping
975 /* if (isReCal_ || tblConverge==0) update hwconf
976 * else keep last hwconf */
977
978 float dampCoef = (hAlsc->calibLscV2->alscCoef.damp_enable && hAlsc->count > 1) ? hAlsc->alscSwInfo.awbIIRDampCoef : 0;
979 if (!hAlsc->isReCal_ && hAlsc->smartRunRes.lscTableConverge) {
980 hAlsc->isReCal_ = false;
981 } else {
982 if (hAlsc->otpGrad.flag && hAlsc->otpGrad.table_size > 0){
983 ret = DampingandOtp(dampCoef, &hAlsc->alscRest.undampedLscMatrixTable,
984 &hAlsc->alscRest.dampedLscMatrixTable,
985 &hAlsc->otpGrad,
986 &hAlsc->lscHwConf,
987 &hAlsc->smartRunRes.lscTableConverge);
988 } else {
989 ret = Damping(dampCoef, &hAlsc->alscRest.undampedLscMatrixTable,
990 &hAlsc->lscHwConf,
991 &hAlsc->smartRunRes.lscTableConverge);
992 }
993 hAlsc->isReCal_ = true;
994 }
995
996 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
997
998 return (ret);
999 }
1000
AlscManualConfig(alsc_handle_t hAlsc)1001 XCamReturn AlscManualConfig
1002 (
1003 alsc_handle_t hAlsc
1004 ) {
1005 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
1006
1007 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1008
1009 memcpy(hAlsc->lscHwConf.x_size_tbl, hAlsc->mCurAtt.stManual.lsc_sect_size_x,
1010 sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_x));
1011 memcpy(hAlsc->lscHwConf.y_size_tbl, hAlsc->mCurAtt.stManual.lsc_sect_size_y,
1012 sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_y));
1013 memcpy(hAlsc->lscHwConf.r_data_tbl, hAlsc->mCurAtt.stManual.r_data_tbl,
1014 sizeof(hAlsc->mCurAtt.stManual.r_data_tbl));
1015 memcpy(hAlsc->lscHwConf.gr_data_tbl, hAlsc->mCurAtt.stManual.gr_data_tbl,
1016 sizeof(hAlsc->mCurAtt.stManual.gr_data_tbl));
1017 memcpy(hAlsc->lscHwConf.gb_data_tbl, hAlsc->mCurAtt.stManual.gb_data_tbl,
1018 sizeof(hAlsc->mCurAtt.stManual.gb_data_tbl));
1019 memcpy(hAlsc->lscHwConf.b_data_tbl, hAlsc->mCurAtt.stManual.b_data_tbl,
1020 sizeof(hAlsc->mCurAtt.stManual.b_data_tbl));
1021
1022 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
1023 return ret;
1024
1025 }
1026
AlscManualGrad(alsc_handle_t hAlsc)1027 XCamReturn AlscManualGrad(alsc_handle_t hAlsc) {
1028 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
1029 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1030
1031 uint32_t x_size = sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_x) /
1032 sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_x[0]);
1033 uint32_t y_size = sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_y) /
1034 sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_y[0]);
1035
1036 for (uint32_t i = 0; i < x_size; i++) {
1037 if (0 < hAlsc->mCurAtt.stManual.lsc_sect_size_x[i]) {
1038 hAlsc->lscHwConf.x_grad_tbl[i] =
1039 (uint16_t)((double)(1UL << 15) / hAlsc->mCurAtt.stManual.lsc_sect_size_x[i] + 0.5);
1040 } else {
1041 LOGE_ALSC("%s: src.lsc_sect_size_x[%d]=0\n", __func__, i);
1042 return XCAM_RETURN_ERROR_PARAM;
1043 }
1044 }
1045 for (uint32_t i = 0; i < y_size; i++) {
1046 if (0 < hAlsc->mCurAtt.stManual.lsc_sect_size_y[i]) {
1047 hAlsc->lscHwConf.y_grad_tbl[i] =
1048 (uint16_t)((double)(1UL << 15) / hAlsc->mCurAtt.stManual.lsc_sect_size_y[i] + 0.5);
1049 } else {
1050 LOGE_ALSC("%s: src.lsc_sect_size_y[%d]=0\n", __func__, i);
1051 return XCAM_RETURN_ERROR_PARAM;
1052 }
1053 }
1054
1055 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
1056 return ret;
1057 }
1058
1059
JudgeAutoRun(alsc_handle_t hAlsc)1060 void JudgeAutoRun
1061 (
1062 alsc_handle_t hAlsc
1063
1064 ) {
1065 bool gainStable;
1066 bool wbgainStable;
1067 float wb_th = hAlsc->smartRunCfg.wbgain_th*hAlsc->smartRunCfg.wbgain_th;
1068 if (fabs(hAlsc->alscSwInfo.sensorGain - hAlsc->smartRunRes.last_gain) > hAlsc->smartRunCfg.gain_th) {
1069 hAlsc->smartRunRes.last_gain = hAlsc->alscSwInfo.sensorGain;
1070 gainStable = false;
1071 } else {
1072 gainStable = true;
1073 }
1074
1075 if ((hAlsc->smartRunRes.last_awbGain[0]-hAlsc->alscSwInfo.awbGain[0])*(hAlsc->smartRunRes.last_awbGain[0]-hAlsc->alscSwInfo.awbGain[0])
1076 + (hAlsc->smartRunRes.last_awbGain[1]-hAlsc->alscSwInfo.awbGain[1])*(hAlsc->smartRunRes.last_awbGain[1]-hAlsc->alscSwInfo.awbGain[1]) > wb_th) {
1077 hAlsc->smartRunRes.last_awbGain[0] = hAlsc->alscSwInfo.awbGain[0];
1078 hAlsc->smartRunRes.last_awbGain[1] = hAlsc->alscSwInfo.awbGain[1];
1079 wbgainStable = false;
1080 LOGD_ALSC("update wbgain: %f, %f\n", hAlsc->alscSwInfo.awbGain[0], hAlsc->alscSwInfo.awbGain[1]);
1081 } else {
1082 wbgainStable = true;
1083 hAlsc->alscSwInfo.awbGain[0] = hAlsc->smartRunRes.last_awbGain[0];
1084 hAlsc->alscSwInfo.awbGain[1] = hAlsc->smartRunRes.last_awbGain[1];
1085 }
1086
1087 hAlsc->smartRunRes.res3aChg = !(wbgainStable && gainStable);
1088 LOGD_ALSC("awbStable(%d),aeStable(%d),lscTableConverge(%d),forceRunFlag(%d)",
1089 wbgainStable,gainStable,hAlsc->smartRunRes.lscTableConverge,hAlsc->smartRunRes.forceRunFlag);
1090
1091 /* bool notRunflag = wbgainStable && gainStable
1092 && hAlsc->smartRunRes.lscTableConverge
1093 && !(hAlsc->smartRunRes.forceRunFlag);
1094 hAlsc->smartRunRes.samrtRunFlag = !notRunflag;
1095 LOGD_ALSC("smartRun(%d),awbStable(%d),aeStable(%d),lscTableConverge(%d),forceRunFlag(%d)",hAlsc->smartRunRes.samrtRunFlag,
1096 wbgainStable,gainStable,hAlsc->smartRunRes.lscTableConverge,hAlsc->smartRunRes.forceRunFlag);
1097 hAlsc->smartRunRes.forceRunFlag =false; */
1098 }
1099
1100
AlscConfig(alsc_handle_t hAlsc)1101 XCamReturn AlscConfig
1102 (
1103 alsc_handle_t hAlsc
1104 ) {
1105 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
1106
1107 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1108
1109 LOGD_ALSC("%s: updateAtt: %d\n", __FUNCTION__, hAlsc->updateAtt);
1110 hAlsc->alscRest.caseIndex = USED_FOR_CASE_NORMAL;
1111 if((hAlsc->alscSwInfo.grayMode == true && hAlsc->alscRest.caseIndex != USED_FOR_CASE_GRAY)||
1112 (hAlsc->alscSwInfo.grayMode == false && hAlsc->alscRest.caseIndex == USED_FOR_CASE_GRAY)){
1113 hAlsc->smartRunRes.forceRunFlag = true;
1114 clear_list(&hAlsc->alscRest.dominateIlluList);
1115 }
1116 if(hAlsc->alscSwInfo.grayMode){
1117 hAlsc->alscRest.caseIndex = USED_FOR_CASE_GRAY;
1118 }
1119 if(hAlsc->updateAtt) {
1120 //hAlsc->mCurAtt = hAlsc->mNewAtt;
1121 if (hAlsc->mCurAtt.mode == RK_AIQ_LSC_MODE_AUTO) {
1122 AlscAutoParamFree(hAlsc);
1123 AlscAutoParamClone(hAlsc);
1124 AlscPrepare(hAlsc);
1125 } else if (hAlsc->mCurAtt.mode == RK_AIQ_LSC_MODE_MANUAL)
1126 {
1127 AlscManualGrad(hAlsc);
1128 } else {
1129 LOGE_ALSC("%s: hAlsc->mCurAtt.mode(%d) is invalid \n", __FUNCTION__, hAlsc->mCurAtt.mode);
1130 }
1131 }
1132 LOGD_ALSC("%s: byPass: %d mode:%d used for case: %d\n", __FUNCTION__,
1133 hAlsc->mCurAtt.byPass, hAlsc->mCurAtt.mode,hAlsc->alscRest.caseIndex);
1134 if(hAlsc->mCurAtt.byPass != true) {
1135 hAlsc->lscHwConf.lsc_en = true;
1136 if(hAlsc->mCurAtt.mode == RK_AIQ_LSC_MODE_AUTO) {
1137 JudgeAutoRun(hAlsc);
1138 if (hAlsc->smartRunRes.res3aChg || !hAlsc->smartRunRes.lscTableConverge
1139 || hAlsc->smartRunRes.forceRunFlag) {
1140 AlscAutoConfig(hAlsc);
1141 }
1142 } else if(hAlsc->mCurAtt.mode == RK_AIQ_LSC_MODE_MANUAL && hAlsc->updateAtt) {
1143 AlscManualConfig(hAlsc);
1144 hAlsc->isReCal_ = true;
1145 } else {
1146 LOGE_ALSC("%s: hAlsc->mCurAtt.mode(%d) is invalid \n", __FUNCTION__, hAlsc->mCurAtt.mode);
1147 }
1148 #if 0
1149 memcpy(hAlsc->mCurAtt.stManual.lsc_sect_size_x, hAlsc->lscHwConf.x_size_tbl,
1150 sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_x));
1151 memcpy(hAlsc->mCurAtt.stManual.lsc_sect_size_y, hAlsc->lscHwConf.y_size_tbl,
1152 sizeof(hAlsc->mCurAtt.stManual.lsc_sect_size_y));
1153 memcpy(hAlsc->mCurAtt.stManual.r_data_tbl, hAlsc->lscHwConf.r_data_tbl,
1154 sizeof(hAlsc->mCurAtt.stManual.r_data_tbl));
1155 memcpy(hAlsc->mCurAtt.stManual.gr_data_tbl, hAlsc->lscHwConf.gr_data_tbl,
1156 sizeof(hAlsc->mCurAtt.stManual.gr_data_tbl));
1157 memcpy(hAlsc->mCurAtt.stManual.gb_data_tbl, hAlsc->lscHwConf.gb_data_tbl,
1158 sizeof(hAlsc->mCurAtt.stManual.gb_data_tbl));
1159 memcpy(hAlsc->mCurAtt.stManual.b_data_tbl, hAlsc->lscHwConf.b_data_tbl,
1160 sizeof(hAlsc->mCurAtt.stManual.b_data_tbl));
1161 #endif
1162 } else {
1163 hAlsc->lscHwConf.lsc_en = false;
1164 // if api/calib set bypass=true, then hAlsc->isReCal_ = true
1165 hAlsc->isReCal_ = hAlsc->updateAtt || hAlsc->smartRunRes.forceRunFlag;
1166 }
1167 LOGD_ALSC("Final hAlsc->isReCal_: %d, lscTableConverge: %d\n", hAlsc->isReCal_, hAlsc->smartRunRes.lscTableConverge);
1168 hAlsc->updateAtt = false;
1169 hAlsc->smartRunRes.forceRunFlag = false;
1170 hAlsc->count = ((hAlsc->count + 2) > (65536)) ? 2 : (hAlsc->count + 1);
1171 LOGD_ALSC( "set to ic LscMatrix r[0:3]:%d,%d,%d,%d, gr[0:3]:%d,%d,%d,%d, gb[0:3]:%d,%d,%d,%d, b[0:3]:%d,%d,%d,%d\n",
1172 hAlsc->lscHwConf.r_data_tbl[0],
1173 hAlsc->lscHwConf.r_data_tbl[1],
1174 hAlsc->lscHwConf.r_data_tbl[2],
1175 hAlsc->lscHwConf.r_data_tbl[3],
1176 hAlsc->lscHwConf.gr_data_tbl[0],
1177 hAlsc->lscHwConf.gr_data_tbl[1],
1178 hAlsc->lscHwConf.gr_data_tbl[2],
1179 hAlsc->lscHwConf.gr_data_tbl[3],
1180 hAlsc->lscHwConf.gb_data_tbl[0],
1181 hAlsc->lscHwConf.gb_data_tbl[1],
1182 hAlsc->lscHwConf.gb_data_tbl[2],
1183 hAlsc->lscHwConf.gb_data_tbl[3],
1184 hAlsc->lscHwConf.b_data_tbl[0],
1185 hAlsc->lscHwConf.b_data_tbl[1],
1186 hAlsc->lscHwConf.b_data_tbl[2],
1187 hAlsc->lscHwConf.b_data_tbl[3]
1188 );
1189
1190 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
1191 return ret;
1192
1193 }
1194
AlscInit(alsc_handle_t * hAlsc,const CamCalibDbV2Context_t * calib2)1195 XCamReturn AlscInit(alsc_handle_t *hAlsc, const CamCalibDbV2Context_t* calib2)
1196 {
1197 LOGI_ALSC("%s: (enter)\n", __FUNCTION__);
1198
1199 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1200 *hAlsc = (alsc_context_t*)malloc(sizeof(alsc_context_t));
1201 //*hAlsc = new alsc_context_t(); //TODO: use this
1202 alsc_context_t* alsc_context = *hAlsc;
1203 memset(alsc_context, 0, sizeof(alsc_context_t));
1204
1205 if(calib2 == NULL) {
1206 return XCAM_RETURN_ERROR_FAILED;
1207 }
1208 const CalibDbV2_LSC_t *calib2_lsc =
1209 (CalibDbV2_LSC_t*)(CALIBDBV2_GET_MODULE_PTR((void*)calib2, lsc_v2));
1210 alsc_context->calibLscV2 = calib2_lsc;
1211
1212 alsc_context->alscSwInfo.sensorGain = 1.0;
1213 alsc_context->alscSwInfo.awbIIRDampCoef = 0;
1214 alsc_context->alscSwInfo.grayMode = false;
1215 alsc_context->alscSwInfo.varianceLuma = 255;
1216 alsc_context->alscSwInfo.awbConverged = false;
1217
1218 alsc_context->alscRest.caseIndex = USED_FOR_CASE_NORMAL;
1219 alsc_context->updateAtt = false;
1220 alsc_context->mCurAtt.byPass = !calib2_lsc->common.enable;
1221 alsc_context->count = 0;
1222 alsc_context->mCurAtt.mode = RK_AIQ_LSC_MODE_AUTO;
1223 alsc_context->smartRunCfg.enable = true;
1224 alsc_context->smartRunCfg.wbgain_th= 0.05;
1225 alsc_context->smartRunCfg.gain_th= 0.2;
1226 alsc_context->smartRunRes.last_gain = -1;
1227 alsc_context->smartRunRes.last_awbGain[0]= -1;
1228 alsc_context->smartRunRes.last_awbGain[1]= -1;
1229 alsc_context->smartRunRes.forceRunFlag = true;
1230 //alsc_context->alscSwInfo.prepare_type = RK_AIQ_ALGO_CONFTYPE_UPDATECALIB | RK_AIQ_ALGO_CONFTYPE_NEEDRESET;
1231 //ret = UpdateLscCalibPara(alsc_context);
1232 //print_alsc(alsc_context);
1233 memset(&alsc_context->otpGrad, 0, sizeof(alsc_context->otpGrad));
1234 INIT_LIST_HEAD(&alsc_context->alscRest.dominateIlluList);
1235 LOGI_ALSC("%s: (exit)\n", __FUNCTION__);
1236 return(ret);
1237 }
1238
AlscRelease(alsc_handle_t hAlsc)1239 XCamReturn AlscRelease(alsc_handle_t hAlsc)
1240 {
1241 LOGI_ALSC("%s: (enter)\n", __FUNCTION__);
1242 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1243
1244 ClearContext(hAlsc);
1245
1246 if (hAlsc) {
1247 free(hAlsc);
1248 hAlsc = NULL;
1249 } else {
1250 LOGI_ALSC("%s: free: hAlsc is already NULL!\n", __func__);
1251 }
1252
1253 LOGI_ALSC("%s: (exit)\n", __FUNCTION__);
1254 return(ret);
1255
1256 }
1257
AlscPrepare(alsc_handle_t hAlsc)1258 XCamReturn AlscPrepare(alsc_handle_t hAlsc)
1259 {
1260 LOGI_ALSC("%s: (enter)\n", __FUNCTION__);
1261
1262 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1263 ClearContext(hAlsc);
1264 ret = UpdateLscCalibPara(hAlsc);
1265 if (XCAM_RETURN_NO_ERROR != ret) {
1266 LOGE_ALSC("%s: UpdateLscCalibPara failed\n", __FUNCTION__);
1267 return ret;
1268 }
1269
1270 hAlsc->mCurAtt.byPass = !hAlsc->calibLscV2->common.enable;
1271 hAlsc->smartRunRes.forceRunFlag = true;
1272 const CalibDbV2_Lsc_Common_t& lsc_com = hAlsc->calibLscV2->common;
1273 const CalibDbV2_Lsc_Resolution_t* calib_lsc_res = nullptr;
1274 for(int i = 0; i < lsc_com.resolutionAll_len; i++) {
1275 if (strcmp(lsc_com.resolutionAll[i].name, hAlsc->cur_res.name) == 0) {
1276 calib_lsc_res = &lsc_com.resolutionAll[i];
1277 break;
1278 }
1279 }
1280 if (calib_lsc_res != nullptr) {
1281 memcpy(hAlsc->lscHwConf.x_size_tbl, calib_lsc_res->lsc_sect_size_x, sizeof(calib_lsc_res->lsc_sect_size_x));
1282 memcpy(hAlsc->lscHwConf.y_size_tbl, calib_lsc_res->lsc_sect_size_y, sizeof(calib_lsc_res->lsc_sect_size_y));
1283 } else {
1284 ret = XCAM_RETURN_ERROR_PARAM;
1285 }
1286
1287 const alsc_grad_t* cur_grad = NULL;
1288 for (uint32_t i = 0; i < hAlsc->res_grad_count; i++) {
1289 if (0 == strcmp(hAlsc->res_grad[i].resolution.name, hAlsc->cur_res.name)) {
1290 cur_grad = &(hAlsc->res_grad[i]);
1291 break;
1292 }
1293 }
1294 if (cur_grad != NULL) {
1295 memcpy(hAlsc->lscHwConf.x_grad_tbl, cur_grad->LscXGradTbl, sizeof(cur_grad->LscXGradTbl));
1296 memcpy(hAlsc->lscHwConf.y_grad_tbl, cur_grad->LscYGradTbl, sizeof(cur_grad->LscYGradTbl));
1297 } else {
1298 ret = XCAM_RETURN_ERROR_PARAM;
1299 }
1300
1301 #ifdef ARCHER_DEBUG
1302 LOGE_ALSC( "%s\n", PRT_ARRAY(cur_grad->LscXGradTbl) );
1303 LOGE_ALSC( "%s\n", PRT_ARRAY(cur_grad->LscYGradTbl) );
1304 LOGE_ALSC( "%s\n", PRT_ARRAY(hAlsc->lscHwConf.x_grad_tbl) );
1305 LOGE_ALSC( "%s\n", PRT_ARRAY(hAlsc->lscHwConf.y_grad_tbl) );
1306 #endif
1307
1308 LOGI_ALSC("%s: (exit)\n", __FUNCTION__);
1309 return ret;
1310 }
1311
AlscAutoParamClone(alsc_handle_t hAlsc)1312 XCamReturn AlscAutoParamClone(alsc_handle_t hAlsc)
1313 {
1314 LOGI_ALSC("%s: (enter)\n", __FUNCTION__);
1315 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1316
1317 hAlsc->fixed_calib.common.enable = hAlsc->mCurAtt.stAuto.common.enable;
1318 hAlsc->fixed_calib.common.resolutionAll = (CalibDbV2_Lsc_Resolution_t*)hAlsc->mCurAtt.stAuto.common.resolutionAll;
1319 hAlsc->fixed_calib.common.resolutionAll_len = hAlsc->mCurAtt.stAuto.common.resolutionAll_len;
1320
1321 hAlsc->fixed_calib.alscCoef.damp_enable = hAlsc->mCurAtt.stAuto.alscCoef.damp_enable;
1322 hAlsc->fixed_calib.alscCoef.illAll_len = hAlsc->mCurAtt.stAuto.alscCoef.illAll_len;
1323 if (!hAlsc->fixed_calib.alscCoef.illAll_len) {
1324 return XCAM_RETURN_ERROR_PARAM;
1325 }
1326 if (hAlsc->fixed_calib.alscCoef.illAll == NULL)
1327 hAlsc->fixed_calib.alscCoef.illAll = (CalibDbV2_AlscCof_ill_t*)malloc(
1328 sizeof(CalibDbV2_AlscCof_ill_t) * hAlsc->fixed_calib.alscCoef.illAll_len);
1329
1330 for (int i = 0; i < hAlsc->fixed_calib.alscCoef.illAll_len; i++) {
1331 hAlsc->fixed_calib.alscCoef.illAll[i].usedForCase =
1332 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].usedForCase;
1333
1334 memcpy(hAlsc->fixed_calib.alscCoef.illAll[i].name,
1335 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].name,
1336 sizeof(hAlsc->fixed_calib.alscCoef.illAll[i].name));
1337
1338 memcpy(hAlsc->fixed_calib.alscCoef.illAll[i].wbGain,
1339 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].wbGain,
1340 sizeof(hAlsc->fixed_calib.alscCoef.illAll[i].wbGain));
1341
1342 hAlsc->fixed_calib.alscCoef.illAll[i].tableUsed =
1343 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].tableUsed;
1344 hAlsc->fixed_calib.alscCoef.illAll[i].tableUsed_len =
1345 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].tableUsed_len;
1346 hAlsc->fixed_calib.alscCoef.illAll[i].gains =
1347 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].gains;
1348 hAlsc->fixed_calib.alscCoef.illAll[i].gains_len =
1349 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].gains_len;
1350 hAlsc->fixed_calib.alscCoef.illAll[i].vig = hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].vig;
1351 hAlsc->fixed_calib.alscCoef.illAll[i].vig_len =
1352 hAlsc->mCurAtt.stAuto.alscCoef.illAll[i].vig_len;
1353 }
1354
1355 hAlsc->fixed_calib.tbl.tableAll = hAlsc->mCurAtt.stAuto.tbl.tableAll;
1356 hAlsc->fixed_calib.tbl.tableAll_len = hAlsc->mCurAtt.stAuto.tbl.tableAll_len;
1357
1358 hAlsc->calibLscV2 = &hAlsc->fixed_calib;
1359
1360 LOGI_ALSC("%s: (exit)\n", __FUNCTION__);
1361 return ret;
1362 }
1363
AlscAutoParamFree(alsc_handle_t hAlsc)1364 XCamReturn AlscAutoParamFree(alsc_handle_t hAlsc)
1365 {
1366 LOGI_ALSC("%s: (enter)\n", __FUNCTION__);
1367 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1368
1369 if (hAlsc->fixed_calib.alscCoef.illAll &&
1370 (hAlsc->mCurAtt.stAuto.tbl.tableAll_len !=
1371 hAlsc->fixed_calib.alscCoef.illAll_len)) {
1372 free(hAlsc->fixed_calib.alscCoef.illAll);
1373 hAlsc->fixed_calib.alscCoef.illAll = NULL;
1374 }
1375
1376 LOGI_ALSC("%s: (exit)\n", __FUNCTION__);
1377 return ret;
1378 }
1379
AlscPreProc(alsc_handle_t hAlsc)1380 XCamReturn AlscPreProc(alsc_handle_t hAlsc)
1381 {
1382
1383 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
1384
1385 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1386
1387 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
1388 return(ret);
1389
1390 }
AlscProcessing(alsc_handle_t hAlsc)1391 XCamReturn AlscProcessing(alsc_handle_t hAlsc)
1392 {
1393 LOG1_ALSC("%s: (enter)\n", __FUNCTION__);
1394
1395 XCamReturn ret = XCAM_RETURN_NO_ERROR;
1396
1397 #if _TEST_LSC_VALID_ON_HARDWARE
1398 _test_if_hw_lsc_valid(hAlsc);
1399 #endif
1400
1401 LOG1_ALSC("%s: (exit)\n", __FUNCTION__);
1402 return(ret);
1403 }
1404
1405
1406
1407
1408 RKAIQ_END_DECLARE
1409
1410
1411