xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/aiq_core/algo_handlers/RkAiqAccmHandle.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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