1 /*
2 * Copyright (c) 2019-2022 Rockchip Eletronics Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "RkAiqAlscHandle.h"
17
18 #include "RkAiqCore.h"
19
20 namespace RkCam {
21
22 DEFINE_HANDLE_REGISTER_TYPE(RkAiqAlscHandleInt);
23
init()24 void RkAiqAlscHandleInt::init() {
25 ENTER_ANALYZER_FUNCTION();
26
27 RkAiqHandle::deInit();
28 mConfig = (RkAiqAlgoCom*)(new RkAiqAlgoConfigAlsc());
29 mProcInParam = (RkAiqAlgoCom*)(new RkAiqAlgoProcAlsc());
30 mProcOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoProcResAlsc());
31
32 EXIT_ANALYZER_FUNCTION();
33 }
34
updateConfig(bool needSync)35 XCamReturn RkAiqAlscHandleInt::updateConfig(bool needSync) {
36 ENTER_ANALYZER_FUNCTION();
37
38 XCamReturn ret = XCAM_RETURN_NO_ERROR;
39
40 #ifndef DISABLE_HANDLE_ATTRIB
41 if (needSync) mCfgMutex.lock();
42 // if something changed
43 if (updateAtt) {
44 mCurAtt = mNewAtt;
45 rk_aiq_uapi_alsc_SetAttrib(mAlgoCtx, mCurAtt, false);
46 updateAtt = false;
47 sendSignal(mCurAtt.sync.sync_mode);
48 }
49
50 if (needSync) mCfgMutex.unlock();
51 #endif
52
53 EXIT_ANALYZER_FUNCTION();
54 return ret;
55 }
56
setAttrib(rk_aiq_lsc_attrib_t att)57 XCamReturn RkAiqAlscHandleInt::setAttrib(rk_aiq_lsc_attrib_t att) {
58 ENTER_ANALYZER_FUNCTION();
59
60 XCamReturn ret = XCAM_RETURN_NO_ERROR;
61 mCfgMutex.lock();
62
63 // check if there is different between att & mCurAtt(sync)/mNewAtt(async)
64 // if something changed, set att to mNewAtt, and
65 // the new params will be effective later when updateConfig
66 // called by RkAiqCore
67 #ifdef DISABLE_HANDLE_ATTRIB
68 ret = rk_aiq_uapi_alsc_SetAttrib(mAlgoCtx, att, false);
69 #else
70 bool isChanged = false;
71 if (att.sync.sync_mode == RK_AIQ_UAPI_MODE_ASYNC && \
72 memcmp(&mNewAtt, &att, sizeof(att)))
73 isChanged = true;
74 else if (att.sync.sync_mode != RK_AIQ_UAPI_MODE_ASYNC && \
75 memcmp(&mCurAtt, &att, sizeof(att)))
76 isChanged = true;
77
78 // if something changed
79 if (isChanged) {
80 mNewAtt = att;
81 updateAtt = true;
82 waitSignal(att.sync.sync_mode);
83 }
84 #endif
85 mCfgMutex.unlock();
86
87 EXIT_ANALYZER_FUNCTION();
88 return ret;
89 }
90
getAttrib(rk_aiq_lsc_attrib_t * att)91 XCamReturn RkAiqAlscHandleInt::getAttrib(rk_aiq_lsc_attrib_t* att) {
92 ENTER_ANALYZER_FUNCTION();
93
94 XCamReturn ret = XCAM_RETURN_NO_ERROR;
95
96 #ifdef DISABLE_HANDLE_ATTRIB
97 mCfgMutex.lock();
98 ret = rk_aiq_uapi_alsc_GetAttrib(mAlgoCtx, att);
99 mCfgMutex.unlock();
100 return ret;
101 #else
102 if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_SYNC) {
103 mCfgMutex.lock();
104 rk_aiq_uapi_alsc_GetAttrib(mAlgoCtx, att);
105 att->sync.done = true;
106 mCfgMutex.unlock();
107 } else {
108 if (updateAtt) {
109 memcpy(att, &mNewAtt, sizeof(updateAtt));
110 att->sync.done = false;
111 } else {
112 rk_aiq_uapi_alsc_GetAttrib(mAlgoCtx, att);
113 att->sync.sync_mode = mNewAtt.sync.sync_mode;
114 att->sync.done = true;
115 }
116 }
117 #endif
118
119 EXIT_ANALYZER_FUNCTION();
120 return ret;
121 }
122
queryLscInfo(rk_aiq_lsc_querry_info_t * lsc_querry_info)123 XCamReturn RkAiqAlscHandleInt::queryLscInfo(rk_aiq_lsc_querry_info_t* lsc_querry_info) {
124 ENTER_ANALYZER_FUNCTION();
125
126 XCamReturn ret = XCAM_RETURN_NO_ERROR;
127
128 rk_aiq_uapi_alsc_QueryLscInfo(mAlgoCtx, lsc_querry_info);
129
130 EXIT_ANALYZER_FUNCTION();
131 return ret;
132 }
133
134 RkAiqBayerPattern_t
getBayerPattern(uint32_t pixelformat)135 RkAiqAlscHandleInt::getBayerPattern(uint32_t pixelformat)
136 {
137 ENTER_ANALYZER_FUNCTION();
138 RkAiqBayerPattern_t bayerPattern = RK_AIQ_BAYER_INVALID;
139
140 switch (pixelformat) {
141 case V4L2_PIX_FMT_SRGGB8:
142 case V4L2_PIX_FMT_SRGGB10:
143 case V4L2_PIX_FMT_SRGGB12:
144 bayerPattern = RK_AIQ_BAYER_RGGB;
145 break;
146 case V4L2_PIX_FMT_SBGGR8:
147 case V4L2_PIX_FMT_SBGGR10:
148 case V4L2_PIX_FMT_SBGGR12:
149 bayerPattern = RK_AIQ_BAYER_BGGR;
150 break;
151 case V4L2_PIX_FMT_SGBRG8:
152 case V4L2_PIX_FMT_SGBRG10:
153 case V4L2_PIX_FMT_SGBRG12:
154 bayerPattern = RK_AIQ_BAYER_GBRG;
155 break;
156 case V4L2_PIX_FMT_SGRBG8:
157 case V4L2_PIX_FMT_SGRBG10:
158 case V4L2_PIX_FMT_SGRBG12:
159 bayerPattern = RK_AIQ_BAYER_GRBG;
160 break;
161 default:
162 LOGD_ALSC("%s no support pixelformat:0x%x\n", __func__, pixelformat);
163 }
164
165 EXIT_ANALYZER_FUNCTION();
166 return bayerPattern;
167 }
168
prepare()169 XCamReturn RkAiqAlscHandleInt::prepare() {
170 ENTER_ANALYZER_FUNCTION();
171
172 XCamReturn ret = XCAM_RETURN_NO_ERROR;
173
174 ret = RkAiqHandle::prepare();
175 RKAIQCORE_CHECK_RET(ret, "alsc handle prepare failed");
176
177 RkAiqAlgoConfigAlsc* alsc_config_int = (RkAiqAlgoConfigAlsc*)mConfig;
178 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
179 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
180 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
181
182 alsc_config_int->alsc_sw_info.bayerPattern= getBayerPattern(sharedCom->snsDes.sensor_pixelformat);
183 if (sharedCom->snsDes.otp_lsc && sharedCom->snsDes.otp_lsc->flag) {
184 alsc_config_int->alsc_sw_info.otpInfo.flag = sharedCom->snsDes.otp_lsc->flag;
185 alsc_config_int->alsc_sw_info.otpInfo.width = sharedCom->snsDes.otp_lsc->width;
186 alsc_config_int->alsc_sw_info.otpInfo.height = sharedCom->snsDes.otp_lsc->height;
187 alsc_config_int->alsc_sw_info.otpInfo.table_size = sharedCom->snsDes.otp_lsc->table_size;
188 alsc_config_int->alsc_sw_info.otpInfo.lsc_r = sharedCom->snsDes.otp_lsc->lsc_r;
189 alsc_config_int->alsc_sw_info.otpInfo.lsc_b = sharedCom->snsDes.otp_lsc->lsc_b;
190 alsc_config_int->alsc_sw_info.otpInfo.lsc_gr = sharedCom->snsDes.otp_lsc->lsc_gr;
191 alsc_config_int->alsc_sw_info.otpInfo.lsc_gb = sharedCom->snsDes.otp_lsc->lsc_gb;
192 } else {
193 alsc_config_int->alsc_sw_info.otpInfo.flag = 0;
194 }
195
196 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
197 ret = des->prepare(mConfig);
198 RKAIQCORE_CHECK_RET(ret, "alsc algo prepare failed");
199
200 EXIT_ANALYZER_FUNCTION();
201 return XCAM_RETURN_NO_ERROR;
202 }
203
preProcess()204 XCamReturn RkAiqAlscHandleInt::preProcess() {
205 ENTER_ANALYZER_FUNCTION();
206
207 XCamReturn ret = XCAM_RETURN_NO_ERROR;
208 #if 0
209 RkAiqAlgoPreAlsc* alsc_pre_int = (RkAiqAlgoPreAlsc*)mPreInParam;
210 RkAiqAlgoPreResAlsc* alsc_pre_res_int = (RkAiqAlgoPreResAlsc*)mPreOutParam;
211 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
212 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
213 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
214
215 ret = RkAiqHandle::preProcess();
216 if (ret) {
217 RKAIQCORE_CHECK_RET(ret, "alsc handle preProcess failed");
218 }
219
220 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
221 ret = des->pre_process(mPreInParam, mPreOutParam);
222 RKAIQCORE_CHECK_RET(ret, "alsc algo pre_process failed");
223
224 EXIT_ANALYZER_FUNCTION();
225 #endif
226 return XCAM_RETURN_NO_ERROR;
227 }
228
processing()229 XCamReturn RkAiqAlscHandleInt::processing() {
230 ENTER_ANALYZER_FUNCTION();
231
232 XCamReturn ret = XCAM_RETURN_NO_ERROR;
233
234 RkAiqAlgoProcAlsc* alsc_proc_int = (RkAiqAlgoProcAlsc*)mProcInParam;
235 RkAiqAlgoProcResAlsc* alsc_proc_res_int = (RkAiqAlgoProcResAlsc*)mProcOutParam;
236 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
237 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
238 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
239
240 if (!shared->fullParams || !shared->fullParams->mLscParams.ptr()) {
241 LOGE_ALSC("[%d]: no lsc buf !", shared->frameId);
242 return XCAM_RETURN_BYPASS;
243 }
244
245 alsc_proc_res_int->alsc_hw_conf = &shared->fullParams->mLscParams->data()->result;
246
247 ret = RkAiqHandle::processing();
248 if (ret) {
249 RKAIQCORE_CHECK_RET(ret, "alsc handle processing failed");
250 }
251
252 alsc_proc_int->tx = shared->tx;
253 XCamVideoBuffer* awb_proc_res = shared->res_comb.awb_proc_res;
254 if (awb_proc_res) {
255 RkAiqAlgoProcResAwbShared_t* awb_res =
256 (RkAiqAlgoProcResAwbShared_t*)awb_proc_res->map(awb_proc_res);
257 if (awb_res) {
258 if (awb_res->awb_gain_algo.grgain < DIVMIN || awb_res->awb_gain_algo.gbgain < DIVMIN) {
259 LOGW("get wrong awb gain from AWB module ,use default value ");
260 } else {
261 alsc_proc_int->alsc_sw_info.awbGain[0] =
262 awb_res->awb_gain_algo.rgain / awb_res->awb_gain_algo.grgain;
263
264 alsc_proc_int->alsc_sw_info.awbGain[1] =
265 awb_res->awb_gain_algo.bgain / awb_res->awb_gain_algo.gbgain;
266 }
267 alsc_proc_int->alsc_sw_info.awbIIRDampCoef = awb_res->awb_smooth_factor;
268 alsc_proc_int->alsc_sw_info.varianceLuma = awb_res->varianceLuma;
269 alsc_proc_int->alsc_sw_info.awbConverged = awb_res->awbConverged;
270 } else {
271 LOGW("fail to get awb gain form AWB module,use default value ");
272 }
273 } else {
274 LOGW("fail to get awb gain form AWB module,use default value ");
275 }
276
277 RKAiqAecExpInfo_t* pCurExp = &shared->curExp;
278 if (pCurExp) {
279 if ((rk_aiq_working_mode_t)sharedCom->working_mode == RK_AIQ_WORKING_MODE_NORMAL) {
280 alsc_proc_int->alsc_sw_info.sensorGain =
281 pCurExp->LinearExp.exp_real_params.analog_gain *
282 pCurExp->LinearExp.exp_real_params.digital_gain *
283 pCurExp->LinearExp.exp_real_params.isp_dgain;
284 } else if ((rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2 &&
285 (rk_aiq_working_mode_t)sharedCom->working_mode < RK_AIQ_WORKING_MODE_ISP_HDR3) {
286 LOGD("sensor gain choose from second hdr frame for alsc");
287 alsc_proc_int->alsc_sw_info.sensorGain =
288 pCurExp->HdrExp[1].exp_real_params.analog_gain *
289 pCurExp->HdrExp[1].exp_real_params.digital_gain *
290 pCurExp->HdrExp[1].exp_real_params.isp_dgain;
291 } else if ((rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2 &&
292 (rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR3) {
293 LOGD("sensor gain choose from third hdr frame for alsc");
294 alsc_proc_int->alsc_sw_info.sensorGain =
295 pCurExp->HdrExp[2].exp_real_params.analog_gain *
296 pCurExp->HdrExp[2].exp_real_params.digital_gain *
297 pCurExp->HdrExp[2].exp_real_params.isp_dgain;
298 } else {
299 LOGW(
300 "working_mode (%d) is invaild ,fail to get sensor gain form AE module,use default "
301 "value ",
302 sharedCom->working_mode);
303 }
304 } else {
305 LOGW("fail to get sensor gain form AE module,use default value ");
306 }
307
308 #ifdef DISABLE_HANDLE_ATTRIB
309 mCfgMutex.lock();
310 #endif
311 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
312 ret = des->processing(mProcInParam, mProcOutParam);
313 #ifdef DISABLE_HANDLE_ATTRIB
314 mCfgMutex.unlock();
315 #endif
316 RKAIQCORE_CHECK_RET(ret, "alsc algo processing failed");
317
318 EXIT_ANALYZER_FUNCTION();
319 return ret;
320 }
321
postProcess()322 XCamReturn RkAiqAlscHandleInt::postProcess() {
323 ENTER_ANALYZER_FUNCTION();
324
325 XCamReturn ret = XCAM_RETURN_NO_ERROR;
326 #if 0
327 RkAiqAlgoPostAlsc* alsc_post_int = (RkAiqAlgoPostAlsc*)mPostInParam;
328 RkAiqAlgoPostResAlsc* alsc_post_res_int = (RkAiqAlgoPostResAlsc*)mPostOutParam;
329 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
330 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
331 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
332
333 ret = RkAiqHandle::postProcess();
334 if (ret) {
335 RKAIQCORE_CHECK_RET(ret, "alsc handle postProcess failed");
336 return ret;
337 }
338
339 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
340 ret = des->post_process(mPostInParam, mPostOutParam);
341 RKAIQCORE_CHECK_RET(ret, "alsc algo post_process failed");
342
343 EXIT_ANALYZER_FUNCTION();
344 #endif
345 return ret;
346 }
347
genIspResult(RkAiqFullParams * params,RkAiqFullParams * cur_params)348 XCamReturn RkAiqAlscHandleInt::genIspResult(RkAiqFullParams* params, RkAiqFullParams* cur_params) {
349 ENTER_ANALYZER_FUNCTION();
350
351 XCamReturn ret = XCAM_RETURN_NO_ERROR;
352 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
353 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
354 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
355 RkAiqAlgoProcResAlsc* alsc_com = (RkAiqAlgoProcResAlsc*)mProcOutParam;
356 rk_aiq_isp_lsc_params_v20_t* lsc_param = params->mLscParams->data().ptr();
357
358 if (!alsc_com) {
359 LOGD_ANALYZER("no alsc result");
360 return XCAM_RETURN_NO_ERROR;
361 }
362
363 RkAiqAlgoProcResAlsc* alsc_rk = (RkAiqAlgoProcResAlsc*)alsc_com;
364 if (sharedCom->init) {
365 lsc_param->frame_id = 0;
366 } else {
367 lsc_param->frame_id = shared->frameId;
368 }
369 #if 0//moved to processing out params
370 lsc_param->result = alsc_rk->alsc_hw_conf;
371 #endif
372
373 if (alsc_com->res_com.cfg_update) {
374 mSyncFlag = shared->frameId;
375 lsc_param->sync_flag = mSyncFlag;
376 // copy from algo result
377 // set as the latest result
378 cur_params->mLscParams = params->mLscParams;
379 lsc_param->is_update = true;
380 LOGD_ALSC("[%d] params from algo", mSyncFlag);
381 } else if (mSyncFlag != lsc_param->sync_flag) {
382 lsc_param->sync_flag = mSyncFlag;
383 // copy from latest result
384 if (cur_params->mLscParams.ptr()) {
385 lsc_param->result = cur_params->mLscParams->data()->result;
386 lsc_param->is_update = true;
387 } else {
388 LOGE_ALSC("no latest params !");
389 lsc_param->is_update = false;
390 }
391 LOGD_ALSC("[%d] params from latest [%d]", shared->frameId, mSyncFlag);
392 } else {
393 // do nothing, result in buf needn't update
394 lsc_param->is_update = false;
395 LOGD_ALSC("[%d] params needn't update", shared->frameId);
396 }
397
398 if (sharedCom->sns_mirror && lsc_param->is_update) {
399 for (int i = 0; i < LSC_DATA_TBL_V_SIZE; i++) {
400 for (int j = 0; j < LSC_DATA_TBL_H_SIZE; j++) {
401 SWAP(unsigned short, lsc_param->result.r_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
402 lsc_param->result
403 .r_data_tbl[i * LSC_DATA_TBL_H_SIZE + (LSC_DATA_TBL_H_SIZE - 1 - j)]);
404 SWAP(unsigned short, lsc_param->result.gr_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
405 lsc_param->result
406 .gr_data_tbl[i * LSC_DATA_TBL_H_SIZE + (LSC_DATA_TBL_H_SIZE - 1 - j)]);
407 SWAP(unsigned short, lsc_param->result.gb_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
408 lsc_param->result
409 .gb_data_tbl[i * LSC_DATA_TBL_H_SIZE + (LSC_DATA_TBL_H_SIZE - 1 - j)]);
410 SWAP(unsigned short, lsc_param->result.b_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
411 lsc_param->result
412 .b_data_tbl[i * LSC_DATA_TBL_H_SIZE + (LSC_DATA_TBL_H_SIZE - 1 - j)]);
413 }
414 }
415 }
416 if (sharedCom->sns_flip && lsc_param->is_update) {
417 for (int i = 0; i < LSC_DATA_TBL_V_SIZE; i++) {
418 for (int j = 0; j < LSC_DATA_TBL_H_SIZE; j++) {
419 SWAP(unsigned short, lsc_param->result.r_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
420 lsc_param->result
421 .r_data_tbl[(LSC_DATA_TBL_V_SIZE - 1 - i) * LSC_DATA_TBL_H_SIZE + j]);
422 SWAP(unsigned short, lsc_param->result.gr_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
423 lsc_param->result
424 .gr_data_tbl[(LSC_DATA_TBL_V_SIZE - 1 - i) * LSC_DATA_TBL_H_SIZE + j]);
425 SWAP(unsigned short, lsc_param->result.gb_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
426 lsc_param->result
427 .gb_data_tbl[(LSC_DATA_TBL_V_SIZE - 1 - i) * LSC_DATA_TBL_H_SIZE + j]);
428 SWAP(unsigned short, lsc_param->result.b_data_tbl[i * LSC_DATA_TBL_H_SIZE + j],
429 lsc_param->result
430 .b_data_tbl[(LSC_DATA_TBL_V_SIZE - 1 - i) * LSC_DATA_TBL_H_SIZE + j]);
431 }
432 }
433 }
434
435 EXIT_ANALYZER_FUNCTION();
436
437 return ret;
438 }
439
440 } // namespace RkCam
441