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