xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/algos/alsc/rk_aiq_alsc_algo.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 = &para->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