/* * RkAiqAeisHandle.h * * Copyright (c) 2019-2021 Rockchip Eletronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "RkAiqCore.h" #include "RkAiqHandle.h" #include "RkAiqHandleInt.h" namespace RkCam { XCamReturn RkAiqAeisHandleInt::prepare() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; ret = RkAiqAeisHandle::prepare(); RKAIQCORE_CHECK_RET(ret, "aeis handle prepare failed"); RkAiqAlgoConfigAeisInt* aeis_config_int = (RkAiqAlgoConfigAeisInt*)mConfig; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; aeis_config_int->mem_ops = mAiqCore->mShareMemOps; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; ret = des->prepare(mConfig); RKAIQCORE_CHECK_RET(ret, "aeis algo prepare failed"); EXIT_ANALYZER_FUNCTION(); return XCAM_RETURN_NO_ERROR; } void RkAiqAeisHandleInt::init() { ENTER_ANALYZER_FUNCTION(); RkAiqAeisHandle::deInit(); mConfig = (RkAiqAlgoCom*)(new RkAiqAlgoConfigAeisInt()); mPreInParam = (RkAiqAlgoCom*)(new RkAiqAlgoPreAeisInt()); mPreOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoPreResAeisInt()); mProcInParam = (RkAiqAlgoCom*)(new RkAiqAlgoProcAeisInt()); mProcOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoProcResAeisInt()); mPostInParam = (RkAiqAlgoCom*)(new RkAiqAlgoPostAeisInt()); mPostOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoPostResAeisInt()); EXIT_ANALYZER_FUNCTION(); } XCamReturn RkAiqAeisHandleInt::preProcess() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoPreAeisInt* aeis_pre_int = (RkAiqAlgoPreAeisInt*)mPreInParam; RkAiqAlgoPreResAeisInt* aeis_pre_res_int = (RkAiqAlgoPreResAeisInt*)mPreOutParam; RkAiqCore::RkAiqAlgosGroupShared_t* shared = nullptr; int groupId = mAiqCore->getGroupId(RK_AIQ_ALGO_TYPE_ADRC); if (groupId >= 0) { if (mAiqCore->getGroupSharedParams(groupId, shared) != XCAM_RETURN_NO_ERROR) return XCAM_RETURN_BYPASS; } else return XCAM_RETURN_BYPASS; RkAiqPreResComb* comb = &shared->preResComb; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; RkAiqIspStats* ispStats = shared->ispStats; ret = RkAiqAeisHandle::preProcess(); if (ret) { comb->aeis_pre_res = NULL; RKAIQCORE_CHECK_RET(ret, "aeis handle preProcess failed"); } comb->aeis_pre_res = NULL; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; ret = des->pre_process(mPreInParam, mPreOutParam); RKAIQCORE_CHECK_RET(ret, "aeis algo pre_process failed"); // set result to mAiqCore comb->aeis_pre_res = (RkAiqAlgoPreResAeis*)aeis_pre_res_int; EXIT_ANALYZER_FUNCTION(); return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAeisHandleInt::processing() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoProcAeisInt* aeis_proc_int = (RkAiqAlgoProcAeisInt*)mProcInParam; RkAiqAlgoProcResAeisInt* aeis_proc_res_int = (RkAiqAlgoProcResAeisInt*)mProcOutParam; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; RkAiqCore::RkAiqAlgosGroupShared_t* shared = nullptr; int groupId = mAiqCore->getGroupId(RK_AIQ_ALGO_TYPE_AEIS); if (groupId >= 0) { if (mAiqCore->getGroupSharedParams(groupId, shared) != XCAM_RETURN_NO_ERROR) return XCAM_RETURN_BYPASS; } else return XCAM_RETURN_BYPASS; RkAiqProcResComb* comb = &shared->procResComb; aeis_proc_int->orb_stats_buf = shared->orbStats; aeis_proc_int->nr_img_buf = shared->nrImg; aeis_proc_int->common.sof = shared->sof; // Formula: // ΔTs : reset time duration per row // ΔTr : readout time duration per row // ΔTe : expsure time duration per row // M : image sensor total row count // Y : the Yth row, 1 < Y < M // Ts(y) : the reset time(point) of Y row // Tr(y) : the readout time(point) of Y row // Ts(y) = Tr(y) - ΔTe - ΔTr - ΔTs // // ΔTv-blanking : Vertical Blanking Time // ΔTv-blanking = Tr((N-1)last) - Tr((N)first) // ΔTframe = Tr((N-1)first) - Tr((N)first) // // ΔTline = HTS / PCLK // PPL : Pixels Per Line // LPF : Lines Per Frame // HTS : Horizental Total Size // VTS : Vertical Total Size // // PCLK = VTS * HTS * FPS // ΔTskew : Rolling Shutter Skew // ΔTline : line readout time // ΔTskew = ΔTline * height constexpr const uint64_t nano_seconds_per_second = 1000000000ULL; // TODO(Cody): Assume that the sensor is a seamless sensor // HDR, Coded Rolling Shutter is not included in this case aeis_proc_int->common.rolling_shutter_skew = sharedCom->snsDes.line_length_pck * nano_seconds_per_second / sharedCom->snsDes.vt_pix_clk_freq_hz * sharedCom->snsDes.sensor_output_height; // TODO(Cody): The exposure time is identical to integration time aeis_proc_int->common.integration_time = shared->curExp.LinearExp.exp_real_params.integration_time; aeis_proc_int->common.analog_gain = shared->curExp.LinearExp.exp_real_params.analog_gain; aeis_proc_int->common.frame_width = sharedCom->snsDes.sensor_output_width; aeis_proc_int->common.frame_height = sharedCom->snsDes.sensor_output_height; ret = RkAiqAeisHandle::processing(); if (ret) { comb->aeis_proc_res = NULL; RKAIQCORE_CHECK_RET(ret, "aeis handle processing failed"); } comb->aeis_proc_res = NULL; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; ret = des->processing(mProcInParam, mProcOutParam); RKAIQCORE_CHECK_RET(ret, "aeis algo processing failed"); comb->aeis_proc_res = (RkAiqAlgoProcResAeis*)aeis_proc_res_int; EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandleInt::postProcess() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoPostAeisInt* aeis_post_int = (RkAiqAlgoPostAeisInt*)mPostInParam; RkAiqAlgoPostResAeisInt* aeis_post_res_int = (RkAiqAlgoPostResAeisInt*)mPostOutParam; RkAiqCore::RkAiqAlgosGroupShared_t* shared = nullptr; int groupId = mAiqCore->getGroupId(RK_AIQ_ALGO_TYPE_AEIS); if (groupId >= 0) { if (mAiqCore->getGroupSharedParams(groupId, shared) != XCAM_RETURN_NO_ERROR) return XCAM_RETURN_BYPASS; } else return XCAM_RETURN_BYPASS; RkAiqPostResComb* comb = &shared->postResComb; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; RkAiqIspStats* ispStats = shared->ispStats; ret = RkAiqAeisHandle::postProcess(); if (ret) { comb->aeis_post_res = NULL; RKAIQCORE_CHECK_RET(ret, "aeis handle postProcess failed"); return ret; } comb->aeis_post_res = NULL; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; ret = des->post_process(mPostInParam, mPostOutParam); RKAIQCORE_CHECK_RET(ret, "aeis algo post_process failed"); // set result to mAiqCore comb->aeis_post_res = (RkAiqAlgoPostResAeis*)aeis_post_res_int; EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandleInt::updateConfig(bool needSync) { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; if (needSync) mCfgMutex.lock(); // if something changed if (updateAtt) { mCurAtt = mNewAtt; updateAtt = false; // TODO rk_aiq_uapi_aeis_SetAttrib(mAlgoCtx, mCurAtt, false); sendSignal(); } if (needSync) mCfgMutex.unlock(); EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandleInt::setAttrib(rk_aiq_eis_attrib_t att) { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; mCfgMutex.lock(); // TODO // check if there is different between att & mCurAtt // if something changed, set att to mNewAtt, and // the new params will be efeistive later when updateConfig // called by RkAiqCore // if something changed if (0 != memcmp(&mCurAtt, &att, sizeof(rk_aiq_eis_attrib_t))) { mNewAtt = att; updateAtt = true; waitSignal(); } mCfgMutex.unlock(); EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandleInt::getAttrib(rk_aiq_eis_attrib_t* att) { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; rk_aiq_uapi_aeis_GetAttrib(mAlgoCtx, att); EXIT_ANALYZER_FUNCTION(); return ret; } void RkAiqAeisHandle::init() { ENTER_ANALYZER_FUNCTION(); deInit(); mConfig = (RkAiqAlgoCom*)(new RkAiqAlgoConfigAeis()); mPreInParam = (RkAiqAlgoCom*)(new RkAiqAlgoPreAeis()); mPreOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoPreResAeis()); mProcInParam = (RkAiqAlgoCom*)(new RkAiqAlgoProcAeis()); mProcOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoProcResAeis()); mPostInParam = (RkAiqAlgoCom*)(new RkAiqAlgoPostAeis()); mPostOutParam = (RkAiqAlgoResCom*)(new RkAiqAlgoPostResAeis()); EXIT_ANALYZER_FUNCTION(); } XCamReturn RkAiqAeisHandle::prepare() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; ret = RkAiqHandle::prepare(); RKAIQCORE_CHECK_RET(ret, "aorb handle prepare failed"); // TODO config aeis common params RkAiqAlgoConfigAeis* aeis_config = (RkAiqAlgoConfigAeis*)mConfig; aeis_config->mems_sensor_intf = mAiqCore->getMemsSensorIntf(); // id != 0 means the thirdparty's algo if (mDes->id != 0) { ret = des->prepare(mConfig); RKAIQCORE_CHECK_RET(ret, "aorb algo prepare failed"); } EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandle::preProcess() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; RkAiqAlgoPreAeis* aeis_pre = (RkAiqAlgoPreAeis*)mPreInParam; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; RkAiqCore::RkAiqAlgosGroupShared_t* shared = nullptr; int groupId = mAiqCore->getGroupId(RK_AIQ_ALGO_TYPE_AEIS); if (groupId >= 0) { if (mAiqCore->getGroupSharedParams(groupId, shared) != XCAM_RETURN_NO_ERROR) return XCAM_RETURN_BYPASS; } else return XCAM_RETURN_BYPASS; RkAiqIspStats* ispStats = shared->ispStats; ret = RkAiqHandle::preProcess(); RKAIQCORE_CHECK_RET(ret, "aeis handle preProcess failed"); if (!shared->orbStats && !sharedCom->init) { LOGE_AEIS("no orb stats, ignore!"); return XCAM_RETURN_BYPASS; } // TODO config common aeis preprocess params // id != 0 means the thirdparty's algo if (mDes->id != 0) { ret = des->pre_process(mPreInParam, mPreOutParam); RKAIQCORE_CHECK_RET(ret, "aorb handle pre_process failed"); } EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandle::processing() { XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; RkAiqAlgoProcAeis* aeis_pre = (RkAiqAlgoProcAeis*)mProcInParam; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; RkAiqCore::RkAiqAlgosGroupShared_t* shared = nullptr; int groupId = mAiqCore->getGroupId(RK_AIQ_ALGO_TYPE_AEIS); if (groupId >= 0) { if (mAiqCore->getGroupSharedParams(groupId, shared) != XCAM_RETURN_NO_ERROR) return XCAM_RETURN_BYPASS; } else return XCAM_RETURN_BYPASS; RkAiqIspStats* ispStats = shared->ispStats; ret = RkAiqHandle::processing(); RKAIQCORE_CHECK_RET(ret, "aorb handle processing failed"); if (!shared->orbStats && !sharedCom->init) { LOGE("no orb stats, ignore!"); return XCAM_RETURN_BYPASS; } // TODO config common aeis processing params // id != 0 means the thirdparty's algo if (mDes->id != 0) { ret = des->processing(mProcInParam, mProcOutParam); RKAIQCORE_CHECK_RET(ret, "aorb algo processing failed"); } EXIT_ANALYZER_FUNCTION(); return ret; } XCamReturn RkAiqAeisHandle::postProcess() { ENTER_ANALYZER_FUNCTION(); XCamReturn ret = XCAM_RETURN_NO_ERROR; RkAiqAlgoDescription* des = (RkAiqAlgoDescription*)mDes; RkAiqAlgoPostAeis* aeis_pre = (RkAiqAlgoPostAeis*)mPostInParam; RkAiqCore::RkAiqAlgosComShared_t* sharedCom = &mAiqCore->mAlogsComSharedParams; RkAiqCore::RkAiqAlgosGroupShared_t* shared = nullptr; int groupId = mAiqCore->getGroupId(RK_AIQ_ALGO_TYPE_AEIS); if (groupId >= 0) { if (mAiqCore->getGroupSharedParams(groupId, shared) != XCAM_RETURN_NO_ERROR) return XCAM_RETURN_BYPASS; } else return XCAM_RETURN_BYPASS; RkAiqIspStats* ispStats = shared->ispStats; ret = RkAiqHandle::postProcess(); RKAIQCORE_CHECK_RET(ret, "aorb handle postProcess failed"); if (!shared->orbStats && !sharedCom->init) { LOGE("no orb stats, ignore!"); return XCAM_RETURN_BYPASS; } // TODO config common aeis postProcess params // id != 0 means the thirdparty's algo if (mDes->id != 0) { ret = des->post_process(mPostInParam, mPostOutParam); RKAIQCORE_CHECK_RET(ret, "aorb algo postProcess failed"); } EXIT_ANALYZER_FUNCTION(); return ret; } }; // namespace RkCam