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 "RkAiqAccmHandle.h"
17
18 #include "RkAiqCore.h"
19
20 namespace RkCam {
21
22 DEFINE_HANDLE_REGISTER_TYPE(RkAiqAccmHandleInt);
23
init()24 void RkAiqAccmHandleInt::init() {
25 ENTER_ANALYZER_FUNCTION();
26
27 RkAiqHandle::deInit();
28 mConfig = (RkAiqAlgoCom*)(new RkAiqAlgoConfigAccm());
29 mProcInParam = (RkAiqAlgoCom*)(new RkAiqAlgoProcAccm());
30 mProcOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoProcResAccm());
31
32 EXIT_ANALYZER_FUNCTION();
33 }
34
updateConfig(bool needSync)35 XCamReturn RkAiqAccmHandleInt::updateConfig(bool needSync) {
36 ENTER_ANALYZER_FUNCTION();
37
38 XCamReturn ret = XCAM_RETURN_NO_ERROR;
39 #ifndef DISABLE_HANDLE_ATTRIB
40 if (needSync) mCfgMutex.lock();
41 // if something changed
42 if (updateAtt) {
43 #if RKAIQ_HAVE_CCM_V1
44 mCurAtt = mNewAtt;
45 // TODO
46 rk_aiq_uapi_accm_SetAttrib(mAlgoCtx, &mCurAtt, false);
47 updateAtt = false;
48 sendSignal(mCurAtt.sync.sync_mode);
49 #endif
50 #if RKAIQ_HAVE_CCM_V2
51 mCurAttV2 = mNewAttV2;
52 // TODO
53 rk_aiq_uapi_accm_v2_SetAttrib(mAlgoCtx, &mCurAttV2, false);
54 updateAtt = false;
55 sendSignal(mCurAttV2.sync.sync_mode);
56 #endif
57 }
58
59 if (needSync) mCfgMutex.unlock();
60 #endif
61
62 EXIT_ANALYZER_FUNCTION();
63 return ret;
64 }
65
66 #if RKAIQ_HAVE_CCM_V1
setAttrib(const rk_aiq_ccm_attrib_t * att)67 XCamReturn RkAiqAccmHandleInt::setAttrib(const rk_aiq_ccm_attrib_t* att) {
68 ENTER_ANALYZER_FUNCTION();
69
70 XCAM_ASSERT(att != nullptr);
71
72 XCamReturn ret = XCAM_RETURN_NO_ERROR;
73 mCfgMutex.lock();
74 #ifdef DISABLE_HANDLE_ATTRIB
75 ret = rk_aiq_uapi_accm_SetAttrib(mAlgoCtx, att, false);
76 #else
77
78 // check if there is different between att & mCurAtt(sync)/mNewAtt(async)
79 // if something changed, set att to mNewAtt, and
80 // the new params will be effective later when updateConfig
81 // called by RkAiqCore
82 bool isChanged = false;
83 if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_ASYNC && \
84 memcmp(&mNewAtt, att, sizeof(*att)))
85 isChanged = true;
86 else if (att->sync.sync_mode != RK_AIQ_UAPI_MODE_ASYNC && \
87 memcmp(&mCurAtt, att, sizeof(*att)))
88 isChanged = true;
89
90 // if something changed
91 if (isChanged) {
92 mNewAtt = *att;
93 updateAtt = true;
94 waitSignal(att->sync.sync_mode);
95 }
96 #endif
97
98 mCfgMutex.unlock();
99
100 EXIT_ANALYZER_FUNCTION();
101 return ret;
102 }
103
getAttrib(rk_aiq_ccm_attrib_t * att)104 XCamReturn RkAiqAccmHandleInt::getAttrib(rk_aiq_ccm_attrib_t* att) {
105 ENTER_ANALYZER_FUNCTION();
106
107 XCAM_ASSERT(att != nullptr);
108
109 XCamReturn ret = XCAM_RETURN_NO_ERROR;
110 #ifdef DISABLE_HANDLE_ATTRIB
111 mCfgMutex.lock();
112 rk_aiq_uapi_accm_GetAttrib(mAlgoCtx, att);
113 mCfgMutex.unlock();
114 #else
115 if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_SYNC) {
116 mCfgMutex.lock();
117 rk_aiq_uapi_accm_GetAttrib(mAlgoCtx, att);
118 att->sync.done = true;
119 mCfgMutex.unlock();
120 } else {
121 if (updateAtt) {
122 memcpy(att, &mNewAtt, sizeof(mNewAtt));
123 att->sync.done = false;
124 } else {
125 rk_aiq_uapi_accm_GetAttrib(mAlgoCtx, att);
126 att->sync.sync_mode = mNewAtt.sync.sync_mode;
127 att->sync.done = true;
128 }
129 }
130 #endif
131
132 EXIT_ANALYZER_FUNCTION();
133 return ret;
134 }
135 #endif
136
137 #if RKAIQ_HAVE_CCM_V2
setAttribV2(const rk_aiq_ccm_v2_attrib_t * att)138 XCamReturn RkAiqAccmHandleInt::setAttribV2(const rk_aiq_ccm_v2_attrib_t* att) {
139 ENTER_ANALYZER_FUNCTION();
140
141 XCAM_ASSERT(att != nullptr);
142
143 XCamReturn ret = XCAM_RETURN_NO_ERROR;
144 mCfgMutex.lock();
145
146 // check if there is different between att & mCurAtt(sync)/mNewAtt(async)
147 // if something changed, set att to mNewAtt, and
148 // the new params will be effective later when updateConfig
149 // called by RkAiqCore
150 #ifdef DISABLE_HANDLE_ATTRIB
151 ret = rk_aiq_uapi_accm_v2_SetAttrib(mAlgoCtx, att, false);
152 #else
153 bool isChanged = false;
154 if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_ASYNC && \
155 memcmp(&mNewAttV2, att, sizeof(*att)))
156 isChanged = true;
157 else if (att->sync.sync_mode != RK_AIQ_UAPI_MODE_ASYNC && \
158 memcmp(&mCurAttV2, att, sizeof(*att)))
159 isChanged = true;
160
161 // if something changed
162 if (isChanged) {
163 mNewAttV2 = *att;
164 updateAtt = true;
165 waitSignal(att->sync.sync_mode);
166 }
167 #endif
168
169 mCfgMutex.unlock();
170
171 EXIT_ANALYZER_FUNCTION();
172 return ret;
173 }
174
getAttribV2(rk_aiq_ccm_v2_attrib_t * att)175 XCamReturn RkAiqAccmHandleInt::getAttribV2(rk_aiq_ccm_v2_attrib_t* att) {
176 ENTER_ANALYZER_FUNCTION();
177
178 XCAM_ASSERT(att != nullptr);
179
180 XCamReturn ret = XCAM_RETURN_NO_ERROR;
181 #ifdef DISABLE_HANDLE_ATTRIB
182 mCfgMutex.lock();
183 rk_aiq_uapi_accm_v2_GetAttrib(mAlgoCtx, att);
184 mCfgMutex.unlock();
185 #else
186
187 if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_SYNC) {
188 mCfgMutex.lock();
189 rk_aiq_uapi_accm_v2_GetAttrib(mAlgoCtx, att);
190 att->sync.done = true;
191 mCfgMutex.unlock();
192 } else {
193 if (updateAtt) {
194 memcpy(att, &mNewAttV2, sizeof(mNewAttV2));
195 att->sync.done = false;
196 } else {
197 rk_aiq_uapi_accm_v2_GetAttrib(mAlgoCtx, att);
198 att->sync.sync_mode = mNewAttV2.sync.sync_mode;
199 att->sync.done = true;
200 }
201 }
202 #endif
203
204 EXIT_ANALYZER_FUNCTION();
205 return ret;
206 }
207 #endif
208
queryCcmInfo(rk_aiq_ccm_querry_info_t * ccm_querry_info)209 XCamReturn RkAiqAccmHandleInt::queryCcmInfo(rk_aiq_ccm_querry_info_t* ccm_querry_info) {
210 ENTER_ANALYZER_FUNCTION();
211
212 XCAM_ASSERT(ccm_querry_info != nullptr);
213
214 XCamReturn ret = XCAM_RETURN_NO_ERROR;
215
216 rk_aiq_uapi_accm_QueryCcmInfo(mAlgoCtx, ccm_querry_info);
217
218 EXIT_ANALYZER_FUNCTION();
219 return ret;
220 }
221
prepare()222 XCamReturn RkAiqAccmHandleInt::prepare() {
223 ENTER_ANALYZER_FUNCTION();
224
225 XCamReturn ret = XCAM_RETURN_NO_ERROR;
226
227 ret = RkAiqHandle::prepare();
228 RKAIQCORE_CHECK_RET(ret, "accm handle prepare failed");
229
230 RkAiqAlgoConfigAccm* accm_config_int = (RkAiqAlgoConfigAccm*)mConfig;
231 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
232 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
233
234 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
235 ret = des->prepare(mConfig);
236 RKAIQCORE_CHECK_RET(ret, "accm algo prepare failed");
237
238 EXIT_ANALYZER_FUNCTION();
239 return XCAM_RETURN_NO_ERROR;
240 }
241
preProcess()242 XCamReturn RkAiqAccmHandleInt::preProcess() {
243 ENTER_ANALYZER_FUNCTION();
244
245 XCamReturn ret = XCAM_RETURN_NO_ERROR;
246 #if 0
247 RkAiqAlgoPreAccm* accm_pre_int = (RkAiqAlgoPreAccm*)mPreInParam;
248 RkAiqAlgoPreResAccm* accm_pre_res_int = (RkAiqAlgoPreResAccm*)mPreOutParam;
249 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
250 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
251 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
252
253 ret = RkAiqHandle::preProcess();
254 if (ret) {
255 RKAIQCORE_CHECK_RET(ret, "accm handle preProcess failed");
256 }
257
258 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
259 ret = des->pre_process(mPreInParam, mPreOutParam);
260 RKAIQCORE_CHECK_RET(ret, "accm algo pre_process failed");
261
262 EXIT_ANALYZER_FUNCTION();
263 #endif
264 return XCAM_RETURN_NO_ERROR;
265 }
266
processing()267 XCamReturn RkAiqAccmHandleInt::processing() {
268 ENTER_ANALYZER_FUNCTION();
269
270 XCamReturn ret = XCAM_RETURN_NO_ERROR;
271
272 RkAiqAlgoProcAccm* accm_proc_int = (RkAiqAlgoProcAccm*)mProcInParam;
273 RkAiqAlgoProcResAccm* accm_proc_res_int = (RkAiqAlgoProcResAccm*)mProcOutParam;
274 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
275 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
276 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
277
278 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
279 if (!shared->fullParams || !shared->fullParams->mCcmV32Params.ptr()) {
280 #else
281 if (!shared->fullParams || !shared->fullParams->mCcmParams.ptr()) {
282 #endif
283 LOGE_ALSC("[%d]: no gic buf !", shared->frameId);
284 return XCAM_RETURN_BYPASS;
285 }
286
287 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
288 accm_proc_res_int->accm_hw_conf_v2 = &shared->fullParams->mCcmV32Params->data()->result;
289 #else
290 accm_proc_res_int->accm_hw_conf = &shared->fullParams->mCcmParams->data()->result;
291 #endif
292
293 ret = RkAiqHandle::processing();
294 if (ret) {
295 RKAIQCORE_CHECK_RET(ret, "accm handle processing failed");
296 }
297
298 // TODO should check if the rk awb algo used
299 XCamVideoBuffer* xCamAwbProcRes = shared->res_comb.awb_proc_res;
300 if (xCamAwbProcRes) {
301 RkAiqAlgoProcResAwbShared_t* awb_res =
302 (RkAiqAlgoProcResAwbShared_t*)xCamAwbProcRes->map(xCamAwbProcRes);
303 if (awb_res) {
304 if (awb_res->awb_gain_algo.grgain < DIVMIN || awb_res->awb_gain_algo.gbgain < DIVMIN) {
305 LOGW("get wrong awb gain from AWB module ,use default value ");
306 } else {
307 accm_proc_int->accm_sw_info.awbGain[0] =
308 awb_res->awb_gain_algo.rgain / awb_res->awb_gain_algo.grgain;
309
310 accm_proc_int->accm_sw_info.awbGain[1] =
311 awb_res->awb_gain_algo.bgain / awb_res->awb_gain_algo.gbgain;
312 }
313 accm_proc_int->accm_sw_info.awbIIRDampCoef = awb_res->awb_smooth_factor;
314 accm_proc_int->accm_sw_info.varianceLuma = awb_res->varianceLuma;
315 accm_proc_int->accm_sw_info.awbConverged = awb_res->awbConverged;
316 } else {
317 LOGW("fail to get awb gain form AWB module,use default value ");
318 }
319 } else {
320 LOGW("fail to get awb gain form AWB module,use default value ");
321 }
322 RKAiqAecExpInfo_t* pCurExp = &shared->curExp;
323 if (pCurExp) {
324 if ((rk_aiq_working_mode_t)sharedCom->working_mode == RK_AIQ_WORKING_MODE_NORMAL) {
325 accm_proc_int->accm_sw_info.sensorGain =
326 pCurExp->LinearExp.exp_real_params.analog_gain *
327 pCurExp->LinearExp.exp_real_params.digital_gain *
328 pCurExp->LinearExp.exp_real_params.isp_dgain;
329 } else if ((rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2 &&
330 (rk_aiq_working_mode_t)sharedCom->working_mode < RK_AIQ_WORKING_MODE_ISP_HDR3) {
331 LOGD("sensor gain choose from second hdr frame for accm");
332 accm_proc_int->accm_sw_info.sensorGain =
333 pCurExp->HdrExp[1].exp_real_params.analog_gain *
334 pCurExp->HdrExp[1].exp_real_params.digital_gain *
335 pCurExp->HdrExp[1].exp_real_params.isp_dgain;
336 } else if ((rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2 &&
337 (rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR3) {
338 LOGD("sensor gain choose from third hdr frame for accm");
339 accm_proc_int->accm_sw_info.sensorGain =
340 pCurExp->HdrExp[2].exp_real_params.analog_gain *
341 pCurExp->HdrExp[2].exp_real_params.digital_gain *
342 pCurExp->HdrExp[2].exp_real_params.isp_dgain;
343 } else {
344 LOGE(
345 "working_mode (%d) is invaild ,fail to get sensor gain form AE module,use default "
346 "value ",
347 sharedCom->working_mode);
348 }
349 } else {
350 LOGE("fail to get sensor gain form AE module,use default value ");
351 }
352
353 #if RKAIQ_HAVE_BLC_V32
354 if (shared->res_comb.ablcV32_proc_res->blc_ob_enable) {
355 if (shared->res_comb.ablcV32_proc_res->isp_ob_predgain >= 1.0f) {
356 accm_proc_int->accm_sw_info.sensorGain *= shared->res_comb.ablcV32_proc_res->isp_ob_predgain;
357 }
358 }
359 #endif
360
361 #ifdef DISABLE_HANDLE_ATTRIB
362 mCfgMutex.lock();
363 #endif
364 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
365 ret = des->processing(mProcInParam, mProcOutParam);
366 #ifdef DISABLE_HANDLE_ATTRIB
367 mCfgMutex.unlock();
368 #endif
369 RKAIQCORE_CHECK_RET(ret, "accm algo processing failed");
370
371 EXIT_ANALYZER_FUNCTION();
372 return ret;
373 }
374
375 XCamReturn RkAiqAccmHandleInt::postProcess() {
376 ENTER_ANALYZER_FUNCTION();
377
378 XCamReturn ret = XCAM_RETURN_NO_ERROR;
379
380 #if 0
381 RkAiqAlgoPostAccm* accm_post_int = (RkAiqAlgoPostAccm*)mPostInParam;
382 RkAiqAlgoPostResAccm* accm_post_res_int = (RkAiqAlgoPostResAccm*)mPostOutParam;
383 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
384 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
385 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
386
387 ret = RkAiqHandle::postProcess();
388 if (ret) {
389 RKAIQCORE_CHECK_RET(ret, "accm handle postProcess failed");
390 return ret;
391 }
392
393 RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
394 ret = des->post_process(mPostInParam, mPostOutParam);
395 RKAIQCORE_CHECK_RET(ret, "accm algo post_process failed");
396
397 EXIT_ANALYZER_FUNCTION();
398 #endif
399 return ret;
400 }
401
402 XCamReturn RkAiqAccmHandleInt::genIspResult(RkAiqFullParams* params, RkAiqFullParams* cur_params) {
403 ENTER_ANALYZER_FUNCTION();
404
405 XCamReturn ret = XCAM_RETURN_NO_ERROR;
406 RkAiqCore::RkAiqAlgosGroupShared_t* shared =
407 (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
408 RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
409 RkAiqAlgoProcResAccm* accm_com = (RkAiqAlgoProcResAccm*)mProcOutParam;
410 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
411 rk_aiq_isp_ccm_params_v32_t* ccm_param = params->mCcmV32Params->data().ptr();
412 #else
413 rk_aiq_isp_ccm_params_v20_t* ccm_param = params->mCcmParams->data().ptr();
414 #endif
415
416 if (!accm_com) {
417 LOGD_ANALYZER("no accm result");
418 return XCAM_RETURN_NO_ERROR;
419 }
420
421 RkAiqAlgoProcResAccm* accm_rk = (RkAiqAlgoProcResAccm*)accm_com;
422
423 if (sharedCom->init) {
424 ccm_param->frame_id = 0;
425 } else {
426 ccm_param->frame_id = shared->frameId;
427 }
428
429 #if 0//moved to processing out params
430 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
431 ccm_param->result = accm_rk->accm_hw_conf_v2;
432 #else
433 ccm_param->result = accm_rk->accm_hw_conf;
434 #endif
435 #endif
436
437 if (accm_com->res_com.cfg_update) {
438 mSyncFlag = shared->frameId;
439 ccm_param->sync_flag = mSyncFlag;
440 // copy from algo result
441 // set as the latest result
442 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
443 cur_params->mCcmV32Params = params->mCcmV32Params;
444 #else
445 cur_params->mCcmParams = params->mCcmParams;
446 #endif
447 ccm_param->is_update = true;
448 LOGD_ACCM("[%d] params from algo", mSyncFlag);
449 } else if (mSyncFlag != ccm_param->sync_flag) {
450 ccm_param->sync_flag = mSyncFlag;
451 // copy from latest result
452 #if defined(ISP_HW_V32) || defined(ISP_HW_V32_LITE)
453 if (cur_params->mCcmV32Params.ptr()) {
454 ccm_param->result = cur_params->mCcmV32Params->data()->result;
455 ccm_param->is_update = true;
456 } else {
457 LOGE_ACCM("no latest params !");
458 ccm_param->is_update = false;
459 }
460 #else
461 if (cur_params->mCcmParams.ptr()) {
462 ccm_param->result = cur_params->mCcmParams->data()->result;
463 ccm_param->is_update = true;
464 } else {
465 LOGE_ACCM("no latest params !");
466 ccm_param->is_update = false;
467 }
468 #endif
469 LOGD_ACCM("[%d] params from latest [%d]", shared->frameId, mSyncFlag);
470 } else {
471 // do nothing, result in buf needn't update
472 ccm_param->is_update = false;
473 LOGD_ACCM("[%d] params needn't update", shared->frameId);
474 }
475
476 EXIT_ANALYZER_FUNCTION();
477
478 return ret;
479 }
480
481 } // namespace RkCam
482