xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/aiq_core/algo_handlers/RkAiqA3dlutHandle.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 "RkAiqA3dlutHandle.h"
17 
18 #include "RkAiqCore.h"
19 
20 namespace RkCam {
21 
22 DEFINE_HANDLE_REGISTER_TYPE(RkAiqA3dlutHandleInt);
23 
init()24 void RkAiqA3dlutHandleInt::init() {
25     ENTER_ANALYZER_FUNCTION();
26 
27     RkAiqHandle::deInit();
28     mConfig       = (RkAiqAlgoCom*)(new RkAiqAlgoConfigA3dlut());
29     mProcInParam  = (RkAiqAlgoCom*)(new RkAiqAlgoProcA3dlut());
30     mProcOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoProcResA3dlut());
31 
32     EXIT_ANALYZER_FUNCTION();
33 }
34 
updateConfig(bool needSync)35 XCamReturn RkAiqA3dlutHandleInt::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         mCurAtt = mNewAtt;
44         // TODO
45         rk_aiq_uapi_a3dlut_SetAttrib(mAlgoCtx, &mCurAtt, false);
46         updateAtt = false;
47         sendSignal(mCurAtt.sync.sync_mode);
48     }
49 
50     if (needSync) mCfgMutex.unlock();
51 #endif
52     EXIT_ANALYZER_FUNCTION();
53     return ret;
54 }
55 
setAttrib(const rk_aiq_lut3d_attrib_t * att)56 XCamReturn RkAiqA3dlutHandleInt::setAttrib(const rk_aiq_lut3d_attrib_t* att) {
57     ENTER_ANALYZER_FUNCTION();
58 
59     XCAM_ASSERT(att != nullptr);
60 
61     XCamReturn ret = XCAM_RETURN_NO_ERROR;
62     mCfgMutex.lock();
63 
64     // check if there is different between att & mCurAtt(sync)/mNewAtt(async)
65     // if something changed, set att to mNewAtt, and
66     // the new params will be effective later when updateConfig
67     // called by RkAiqCore
68 #ifdef DISABLE_HANDLE_ATTRIB
69     ret = rk_aiq_uapi_a3dlut_SetAttrib(mAlgoCtx, att, false);
70 #else
71     bool isChanged = false;
72     if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_ASYNC && \
73         memcmp(&mNewAtt, att, sizeof(*att)))
74         isChanged = true;
75     else if (att->sync.sync_mode != RK_AIQ_UAPI_MODE_ASYNC && \
76              memcmp(&mCurAtt, att, sizeof(*att)))
77         isChanged = true;
78 
79     // if something changed
80     if (isChanged) {
81         mNewAtt   = *att;
82         updateAtt = true;
83         waitSignal(att->sync.sync_mode);
84     }
85 #endif
86 
87     mCfgMutex.unlock();
88 
89     EXIT_ANALYZER_FUNCTION();
90     return ret;
91 }
92 
getAttrib(rk_aiq_lut3d_attrib_t * att)93 XCamReturn RkAiqA3dlutHandleInt::getAttrib(rk_aiq_lut3d_attrib_t* att) {
94     ENTER_ANALYZER_FUNCTION();
95 
96     XCAM_ASSERT(att != nullptr);
97 
98     XCamReturn ret = XCAM_RETURN_NO_ERROR;
99 #ifdef DISABLE_HANDLE_ATTRIB
100       mCfgMutex.lock();
101       ret = rk_aiq_uapi_a3dlut_GetAttrib(mAlgoCtx, att);
102       mCfgMutex.unlock();
103       return ret;
104 #else
105 
106     if (att->sync.sync_mode == RK_AIQ_UAPI_MODE_SYNC) {
107         mCfgMutex.lock();
108         rk_aiq_uapi_a3dlut_GetAttrib(mAlgoCtx, att);
109         att->sync.done = true;
110         mCfgMutex.unlock();
111     } else {
112         if (updateAtt) {
113             memcpy(att, &mNewAtt, sizeof(mNewAtt));
114             att->sync.done = false;
115         } else {
116             rk_aiq_uapi_a3dlut_GetAttrib(mAlgoCtx, att);
117             att->sync.sync_mode = mNewAtt.sync.sync_mode;
118             att->sync.done      = true;
119         }
120     }
121 #endif
122 
123     EXIT_ANALYZER_FUNCTION();
124     return ret;
125 }
126 
query3dlutInfo(rk_aiq_lut3d_querry_info_t * lut3d_querry_info)127 XCamReturn RkAiqA3dlutHandleInt::query3dlutInfo(rk_aiq_lut3d_querry_info_t* lut3d_querry_info) {
128     ENTER_ANALYZER_FUNCTION();
129 
130     XCAM_ASSERT(lut3d_querry_info != nullptr);
131 
132     XCamReturn ret = XCAM_RETURN_NO_ERROR;
133 
134     rk_aiq_uapi_a3dlut_Query3dlutInfo(mAlgoCtx, lut3d_querry_info);
135 
136     EXIT_ANALYZER_FUNCTION();
137     return ret;
138 }
139 
prepare()140 XCamReturn RkAiqA3dlutHandleInt::prepare() {
141     ENTER_ANALYZER_FUNCTION();
142 
143     XCamReturn ret = XCAM_RETURN_NO_ERROR;
144 
145     ret = RkAiqHandle::prepare();
146     RKAIQCORE_CHECK_RET(ret, "a3dlut handle prepare failed");
147 
148     RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
149     ret                       = des->prepare(mConfig);
150     RKAIQCORE_CHECK_RET(ret, "a3dlut algo prepare failed");
151 
152     EXIT_ANALYZER_FUNCTION();
153     return XCAM_RETURN_NO_ERROR;
154 }
155 
preProcess()156 XCamReturn RkAiqA3dlutHandleInt::preProcess() {
157     ENTER_ANALYZER_FUNCTION();
158 
159     XCamReturn ret = XCAM_RETURN_NO_ERROR;
160 #if 0
161     ret = RkAiqHandle::preProcess();
162     if (ret) {
163         RKAIQCORE_CHECK_RET(ret, "a3dlut handle preProcess failed");
164     }
165 
166     RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
167     ret                       = des->pre_process(mPreInParam, mPreOutParam);
168     RKAIQCORE_CHECK_RET(ret, "a3dlut algo pre_process failed");
169 
170     EXIT_ANALYZER_FUNCTION();
171 #endif
172     return XCAM_RETURN_NO_ERROR;
173 }
174 
processing()175 XCamReturn RkAiqA3dlutHandleInt::processing() {
176     ENTER_ANALYZER_FUNCTION();
177 
178     XCamReturn ret = XCAM_RETURN_NO_ERROR;
179 
180     RkAiqAlgoProcA3dlut* a3dlut_proc_int        = (RkAiqAlgoProcA3dlut*)mProcInParam;
181     RkAiqAlgoProcResA3dlut* a3dlut_proc_res_int = (RkAiqAlgoProcResA3dlut*)mProcOutParam;
182     RkAiqCore::RkAiqAlgosGroupShared_t* shared =
183         (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
184     RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
185 
186     if (!shared->fullParams || !shared->fullParams->mLut3dParams.ptr()) {
187         LOGE_A3DLUT("[%d]: no 3dlut buf !", shared->frameId);
188         return XCAM_RETURN_BYPASS;
189     }
190 
191     a3dlut_proc_res_int->lut3d_hw_conf = &shared->fullParams->mLut3dParams->data()->result;
192 
193     ret = RkAiqHandle::processing();
194     if (ret) {
195         RKAIQCORE_CHECK_RET(ret, "a3dlut handle processing failed");
196     }
197 
198     XCamVideoBuffer* xCamAwbProcRes = shared->res_comb.awb_proc_res;
199     if (xCamAwbProcRes) {
200         RkAiqAlgoProcResAwbShared_t* awb_res =
201             (RkAiqAlgoProcResAwbShared_t*)xCamAwbProcRes->map(xCamAwbProcRes);
202         if (awb_res) {
203             if (awb_res->awb_gain_algo.grgain < DIVMIN || awb_res->awb_gain_algo.gbgain < DIVMIN) {
204                 LOGE("get wrong awb gain from AWB module ,use default value ");
205             } else {
206                 a3dlut_proc_int->awbGain[0] =
207                     awb_res->awb_gain_algo.rgain / awb_res->awb_gain_algo.grgain;
208 
209                 a3dlut_proc_int->awbGain[1] =
210                     awb_res->awb_gain_algo.bgain / awb_res->awb_gain_algo.gbgain;
211             }
212             a3dlut_proc_int->awbIIRDampCoef = awb_res->awb_smooth_factor;
213             a3dlut_proc_int->awbConverged   = awb_res->awbConverged;
214         } else {
215             LOGW("fail to get awb gain form AWB module,use default value ");
216         }
217     } else {
218         LOGW("fail to get awb gain form AWB module,use default value ");
219     }
220     RKAiqAecExpInfo_t* pCurExp = &shared->curExp;
221     if (pCurExp) {
222         if ((rk_aiq_working_mode_t)sharedCom->working_mode == RK_AIQ_WORKING_MODE_NORMAL) {
223             a3dlut_proc_int->sensorGain = pCurExp->LinearExp.exp_real_params.analog_gain *
224                                           pCurExp->LinearExp.exp_real_params.digital_gain *
225                                           pCurExp->LinearExp.exp_real_params.isp_dgain;
226         } else if ((rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2 &&
227                    (rk_aiq_working_mode_t)sharedCom->working_mode < RK_AIQ_WORKING_MODE_ISP_HDR3) {
228             LOGD("sensor gain choose from second hdr frame for a3dlut");
229             a3dlut_proc_int->sensorGain = pCurExp->HdrExp[1].exp_real_params.analog_gain *
230                                           pCurExp->HdrExp[1].exp_real_params.digital_gain *
231                                           pCurExp->HdrExp[1].exp_real_params.isp_dgain;
232         } else if ((rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR2 &&
233                    (rk_aiq_working_mode_t)sharedCom->working_mode >= RK_AIQ_WORKING_MODE_ISP_HDR3) {
234             LOGD("sensor gain choose from third hdr frame for a3dlut");
235             a3dlut_proc_int->sensorGain = pCurExp->HdrExp[2].exp_real_params.analog_gain *
236                                           pCurExp->HdrExp[2].exp_real_params.digital_gain *
237                                           pCurExp->HdrExp[2].exp_real_params.isp_dgain;
238         } else {
239             LOGE(
240                 "working_mode (%d) is invaild ,fail to get sensor gain form AE module,use default "
241                 "value ",
242                 sharedCom->working_mode);
243         }
244     } else {
245         LOGE("fail to get sensor gain form AE module,use default value ");
246     }
247 
248 #if RKAIQ_HAVE_BLC_V32
249     if (shared->res_comb.ablcV32_proc_res->blc_ob_enable) {
250         if (shared->res_comb.ablcV32_proc_res->isp_ob_predgain >= 1.0f) {
251             a3dlut_proc_int->sensorGain *=  shared->res_comb.ablcV32_proc_res->isp_ob_predgain;
252         }
253     }
254 #endif
255 
256 #ifdef DISABLE_HANDLE_ATTRIB
257     mCfgMutex.lock();
258 #endif
259     RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
260     ret                       = des->processing(mProcInParam, mProcOutParam);
261 #ifdef DISABLE_HANDLE_ATTRIB
262     mCfgMutex.unlock();
263 #endif
264     RKAIQCORE_CHECK_RET(ret, "a3dlut algo processing failed");
265 
266     EXIT_ANALYZER_FUNCTION();
267     return ret;
268 }
269 
postProcess()270 XCamReturn RkAiqA3dlutHandleInt::postProcess() {
271     ENTER_ANALYZER_FUNCTION();
272 
273     XCamReturn ret = XCAM_RETURN_NO_ERROR;
274 
275 #if 0
276     RkAiqAlgoPostA3dlut* a3dlut_post_int        = (RkAiqAlgoPostA3dlut*)mPostInParam;
277     RkAiqAlgoPostResA3dlut* a3dlut_post_res_int = (RkAiqAlgoPostResA3dlut*)mPostOutParam;
278     RkAiqCore::RkAiqAlgosGroupShared_t* shared =
279         (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
280 
281     ret = RkAiqHandle::postProcess();
282     if (ret) {
283         RKAIQCORE_CHECK_RET(ret, "a3dlut handle postProcess failed");
284         return ret;
285     }
286 
287     RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes;
288     ret                       = des->post_process(mPostInParam, mPostOutParam);
289     RKAIQCORE_CHECK_RET(ret, "a3dlut algo post_process failed");
290 
291     EXIT_ANALYZER_FUNCTION();
292 #endif
293     return ret;
294 }
295 
genIspResult(RkAiqFullParams * params,RkAiqFullParams * cur_params)296 XCamReturn RkAiqA3dlutHandleInt::genIspResult(RkAiqFullParams* params,
297                                               RkAiqFullParams* cur_params) {
298     ENTER_ANALYZER_FUNCTION();
299 
300     XCamReturn ret                = XCAM_RETURN_NO_ERROR;
301     RkAiqCore::RkAiqAlgosGroupShared_t* shared =
302         (RkAiqCore::RkAiqAlgosGroupShared_t*)(getGroupShared());
303     RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams;
304     RkAiqAlgoProcResA3dlut* a3dlut_com = (RkAiqAlgoProcResA3dlut*)mProcOutParam;
305     rk_aiq_isp_lut3d_params_v20_t* lut3d_param = params->mLut3dParams->data().ptr();
306 
307     if (sharedCom->init) {
308         lut3d_param->frame_id = 0;
309     } else {
310         lut3d_param->frame_id = shared->frameId;
311     }
312 
313     if (!a3dlut_com) {
314         LOGD_ANALYZER("no a3dlut result");
315         return XCAM_RETURN_NO_ERROR;
316     }
317 
318 #if 0//moved to processing out params
319     RkAiqAlgoProcResA3dlut* a3dlut_rk = (RkAiqAlgoProcResA3dlut*)a3dlut_com;
320     if (!a3dlut_rk->lut3d_hw_conf.enable || a3dlut_rk->lut3d_hw_conf.bypass_en) {
321         lut3d_param->result.enable = a3dlut_rk->lut3d_hw_conf.enable;
322         lut3d_param->result.bypass_en = a3dlut_rk->lut3d_hw_conf.bypass_en;
323     } else
324         lut3d_param->result               = a3dlut_rk->lut3d_hw_conf;
325 #endif
326     if (a3dlut_com->res_com.cfg_update) {
327         mSyncFlag = shared->frameId;
328         lut3d_param->sync_flag = mSyncFlag;
329         // copy from algo result
330         // set as the latest result
331         cur_params->mLut3dParams = params->mLut3dParams;
332         lut3d_param->is_update = true;
333         LOGD_A3DLUT("[%d] params from algo", mSyncFlag);
334     } else if (mSyncFlag != lut3d_param->sync_flag) {
335         lut3d_param->sync_flag = mSyncFlag;
336         // copy from latest result
337         if (cur_params->mLut3dParams.ptr()) {
338             lut3d_param->result = cur_params->mLut3dParams->data()->result;
339             lut3d_param->is_update = true;
340         } else {
341             LOGE_A3DLUT("no latest params !");
342             lut3d_param->is_update = false;
343         }
344         LOGD_A3DLUT("[%d] params from latest [%d]", shared->frameId, mSyncFlag);
345    } else {
346         // do nothing, result in buf needn't update
347         lut3d_param->is_update = false;
348         LOGD_A3DLUT("[%d] params needn't update", shared->frameId);
349     }
350 
351     EXIT_ANALYZER_FUNCTION();
352 
353     return ret;
354 }
355 
356 }  // namespace RkCam
357