/* * rkisp_aiq_core.h * * Copyright (c) 2019 Rockchip Corporation * * 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 "RkAiqAnalyzeGroupManager.h" #include #include #include #include "smart_buffer_priv.h" #define ANALYZER_SUBM (0x1) namespace RkCam { RkAiqAnalyzerGroup::RkAiqAnalyzerGroup(RkAiqCore* aiqCore, enum rk_aiq_core_analyze_type_e type, const uint64_t flag, const RkAiqGrpConditions_t* grpConds) : mAiqCore(aiqCore), mGroupType(type), mDepsFlag(flag) { if (grpConds) mGrpConds = *grpConds; std::stringstream ss; ss << "g-" << std::hex << mGroupType << std::hex << ":" << mDepsFlag; mRkAiqGroupMsgHdlTh = new RkAiqAnalyzeGroupMsgHdlThread(ss.str().c_str(), this); } XCamReturn RkAiqAnalyzerGroup::start() { mRkAiqGroupMsgHdlTh->triger_start(); mRkAiqGroupMsgHdlTh->start(); return XCAM_RETURN_NO_ERROR; } void RkAiqAnalyzerGroup::msgReduction(std::map& msgMap) { // TODO(Cody): Workaround for current implementation // Should let message thread handle the reduction if (mGroupMsgMap.size() > 0) { const auto originalSize = mGroupMsgMap.size(); const int numToErase = originalSize - 5; if (numToErase > 0) { int32_t unreadyFlag = mDepsFlag & ~mGroupMsgMap.begin()->second.msg_flags; // print missing params std::string missing_conds; uint32_t i = 0; while (unreadyFlag) { if (unreadyFlag % 2) { missing_conds.append(MessageType2Str[i]); missing_conds.append(","); } unreadyFlag >>= 1; i++; } LOGE_ANALYZER_SUBM(ANALYZER_SUBM, "group(%s): id[%d] map size is %d, erase %d, element, missing conditions: %s", AnalyzerGroupType2Str[mGroupType], mGroupMsgMap.begin()->first, originalSize, numToErase, missing_conds.c_str()); auto eraseIter = mGroupMsgMap.begin(); std::advance(eraseIter, numToErase); mGroupMsgMap.erase(mGroupMsgMap.begin(), eraseIter); } } } bool RkAiqAnalyzerGroup::pushMsg(const SmartPtr& msg) { //msgReduction(mGroupMsgMap); mRkAiqGroupMsgHdlTh->push_msg(msg); return true; } int8_t RkAiqAnalyzerGroup::getMsgDelayCnt(XCamMessageType &msg_id) { uint32_t i = 0, delayCnt = 0; for (i = 0; i < mGrpConds.size; i++) { if (mGrpConds.conds[i].cond == msg_id) return mGrpConds.conds[i].delay; } if (i == mGrpConds.size) LOGE_ANALYZER_SUBM(ANALYZER_SUBM, "don't match msgId(0x%x) in mGrpConds", msg_id); return 0; } XCamReturn RkAiqAnalyzerGroup::msgHandle(const SmartPtr& msg) { if (!msg.ptr()) { LOGW_ANALYZER_SUBM(ANALYZER_SUBM, "msg is nullptr!"); return XCAM_RETURN_ERROR_PARAM; } uint32_t delayCnt = getMsgDelayCnt(msg->msg_id); uint32_t userId = msg->frame_id + delayCnt; GroupMessage& msgWrapper = mGroupMsgMap[userId]; msgWrapper.msg_flags |= 1 << msg->msg_id; msgWrapper.msgList.push_back(msg); LOGD_ANALYZER_SUBM(ANALYZER_SUBM, "group(%s): id[%d] push msg(%s), msg delayCnt(%d), map size is %d\n", AnalyzerGroupType2Str[mGroupType], msg->frame_id, MessageType2Str[msg->msg_id], delayCnt, mGroupMsgMap.size()); uint64_t msg_flags = msgWrapper.msg_flags; if (!(msg_flags ^ mDepsFlag)) { for (auto it = mGroupMsgMap.begin(); it != mGroupMsgMap.end();) { if ((*it).first < userId) { it = mGroupMsgMap.erase(it); } else { break;//it++; } } std::list>& msgList = msgWrapper.msgList; mHandler(msgList, userId); mGroupMsgMap.erase(userId); LOGD_ANALYZER("%s, erase frame(%d) msg map\n", __FUNCTION__, msg->frame_id); } else { msgReduction(mGroupMsgMap); return XCAM_RETURN_BYPASS; } return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzerGroup::stop() { mRkAiqGroupMsgHdlTh->triger_stop(); mRkAiqGroupMsgHdlTh->stop(); mGroupMsgMap.clear(); return XCAM_RETURN_NO_ERROR; } bool RkAiqAnalyzeGroupMsgHdlThread::loop() { ENTER_ANALYZER_FUNCTION(); const static int32_t timeout = -1; //XCAM_STATIC_FPS_CALCULATION(GROUPMSGTH, 100); SmartPtr msg = mMsgsQueue.pop(timeout); if (!msg.ptr()) { LOGW_ANALYZER_SUBM(ANALYZER_SUBM, "RkAiqAnalyzeGroupMsgHdlThread got empty msg, stop thread"); return false; } XCamReturn ret = mRkAiqAnalyzerGroup->msgHandle(msg); if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT || XCAM_RETURN_BYPASS) return true; EXIT_ANALYZER_FUNCTION(); return false; } RkAiqAnalyzeGroupManager::RkAiqAnalyzeGroupManager(RkAiqCore* aiqCore) : mAiqCore(aiqCore) {} XCamReturn RkAiqAnalyzeGroupManager::start() { for (auto& it : mGroupMap) { it.second->start(); } return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::stop() { for (auto& it : mGroupMap) { it.second->stop(); } return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::aeGroupMessageHandler( std::list>& msgs, uint32_t& id) { XCamVideoBuffer* aecStatsBuf = NULL; list>* msgList = &msgs; list>::iterator listIt; //XCAM_STATIC_FPS_CALCULATION(AEHANDLER, 100); for (listIt = msgList->begin(); listIt != msgList->end();) { if ((*listIt)->msg_id == XCAM_MESSAGE_AEC_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) aecStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (aecStatsBuf) { mAiqCore->aeGroupAnalyze(id, aecStatsBuf); aecStatsBuf->unref(aecStatsBuf); } return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::awbGroupMessageHandler( std::list>& msgs, uint32_t& id) { // 3. determine if all the required messages have been received XCamReturn ret = XCAM_RETURN_NO_ERROR; XCamVideoBuffer* awbStatsBuf = nullptr; XCamVideoBuffer* aePreRes = nullptr; list>* msgList = &msgs; list>::iterator listIt; //XCAM_STATIC_FPS_CALCULATION(AWBHANDLER, 100); for (listIt = msgList->begin(); listIt != msgList->end();) { if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PRE_RES_OK) { SmartPtr vdBufMsg; vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) aePreRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AWB_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) awbStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (aePreRes != nullptr && awbStatsBuf != nullptr) mAiqCore->awbGroupAnalyze(id, aePreRes, awbStatsBuf); else ret = XCAM_RETURN_BYPASS; if (aePreRes) aePreRes->unref(aePreRes); if (awbStatsBuf) awbStatsBuf->unref(awbStatsBuf); return ret; } XCamReturn RkAiqAnalyzeGroupManager::measGroupMessageHandler( std::list>& msgs, uint32_t& id) { // 3. determine if all the required messages have been received SmartPtr IspStatsMsg = nullptr; XCamVideoBuffer* aePreRes = NULL; list>* msgList = &msgs; list>::iterator listIt; //XCAM_STATIC_FPS_CALCULATION(MEASHANDLER, 100); for (listIt = msgList->begin(); listIt != msgList->end();) { if ((*listIt)->msg_id == XCAM_MESSAGE_ISP_STATS_OK) { IspStatsMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PRE_RES_OK) { SmartPtr vdBufMsg; vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { aePreRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } } listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (IspStatsMsg.ptr()) mAiqCore->measGroupAnalyze(id, IspStatsMsg, aePreRes); if (aePreRes) aePreRes->unref(aePreRes); return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::otherGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(OTHERHANDLER, 100); SmartPtr sofInfoMsg = msgs.front().dynamic_cast_ptr(); msgs.pop_front(); // 1. clear the excess elements // 2. add msg to group msg map // 3. determine if all the required messages have been received // 4. start executing algorithm module flow mAiqCore->otherGroupAnalye(id, sofInfoMsg); return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::amdGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(AMDHANDLER, 100); XCamReturn ret = XCAM_RETURN_NO_ERROR; // 3. determine if all the required messages have been received XCamVideoBuffer* sp = NULL; XCamVideoBuffer* ispGain = NULL; SmartPtr sofInfoMsg = nullptr; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { sofInfoMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISP_POLL_SP_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) sp = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISP_GAIN_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) ispGain = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (sofInfoMsg.ptr() && sp != NULL && ispGain != NULL) mAiqCore->amdGroupAnalyze(id, sofInfoMsg, sp, ispGain); else ret = XCAM_RETURN_BYPASS; if (sp) sp->unref(sp); if (ispGain) ispGain->unref(ispGain); return ret; } XCamReturn RkAiqAnalyzeGroupManager::thumbnailsGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(THUMBHANDLER, 100); rkaiq_image_source_t thumbnailsSrc; SmartPtr msg = msgs.front(); SmartPtr vdBufMsg = msg.dynamic_cast_ptr(); if (!vdBufMsg.ptr()) return XCAM_RETURN_BYPASS; if (msg->msg_id == XCAM_MESSAGE_ISP_POLL_SP_OK) { XCamVideoBuffer* sp = NULL; sp = convert_to_XCamVideoBuffer(vdBufMsg->msg); thumbnailsSrc.frame_id = msg->frame_id; thumbnailsSrc.src_type = RKISP20_STREAM_SP; thumbnailsSrc.image_source = sp; } else if (msg->msg_id == XCAM_MESSAGE_NR_IMG_OK) { XCamVideoBuffer* nrImg = NULL; nrImg = convert_to_XCamVideoBuffer(vdBufMsg->msg); thumbnailsSrc.frame_id = msg->frame_id; thumbnailsSrc.src_type = RKISP20_STREAM_NR; thumbnailsSrc.image_source = nrImg; } mAiqCore->thumbnailsGroupAnalyze(thumbnailsSrc); return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::lscGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(LSCHANDLER, 100); // 3. determine if all the required messages have been received XCamVideoBuffer* tx = NULL; XCamVideoBuffer* awbProcRes = NULL; XCamVideoBuffer* aeProcRes = NULL; SmartPtr sofInfoMsg = nullptr; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_AWB_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) awbProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISP_POLL_TX_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { tx = convert_to_XCamVideoBuffer(vdBufMsg->msg); } } else if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { sofInfoMsg = (*listIt).dynamic_cast_ptr(); } #if 1 else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { aeProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); RkAiqAlgoProcResAeInt* ae_proc_res = (RkAiqAlgoProcResAeInt*)aeProcRes->map(aeProcRes); aeProcRes->unref(aeProcRes); } } #endif listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (awbProcRes != NULL && tx != NULL && sofInfoMsg.ptr()) mAiqCore->lscGroupAnalyze(id, sofInfoMsg, awbProcRes, tx); else return XCAM_RETURN_BYPASS; return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::amfnrGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(FMNRHANDLER, 100); XCamReturn ret = XCAM_RETURN_NO_ERROR; SmartPtr sofInfoMsg = nullptr; XCamVideoBuffer* ispGain = nullptr; XCamVideoBuffer* kgGain = nullptr; XCamVideoBuffer* xCamAmdProcRes = nullptr; RkAiqAlgoProcResAmdInt* amdProcRes = nullptr; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { sofInfoMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISP_GAIN_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { ispGain = convert_to_XCamVideoBuffer(vdBufMsg->msg); } } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISPP_GAIN_KG_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { kgGain = convert_to_XCamVideoBuffer(vdBufMsg->msg); } } else if ((*listIt)->msg_id == XCAM_MESSAGE_AMD_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { xCamAmdProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); if (xCamAmdProcRes) amdProcRes = (RkAiqAlgoProcResAmdInt*)xCamAmdProcRes->map(xCamAmdProcRes); } } listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (sofInfoMsg.ptr() /* && ispGain != nullptr */ && kgGain != nullptr /* && amdProcRes != nullptr */) mAiqCore->mfnrGroupAnalyze(id, sofInfoMsg, ispGain, kgGain, amdProcRes->amd_proc_res_com.amd_proc_res); else ret = XCAM_RETURN_BYPASS; if (ispGain) ispGain->unref(ispGain); if (kgGain) kgGain->unref(kgGain); if (xCamAmdProcRes) xCamAmdProcRes->unref(xCamAmdProcRes); return ret; } XCamReturn RkAiqAnalyzeGroupManager::aynrGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(YNRHANDLER, 100); XCamReturn ret = XCAM_RETURN_NO_ERROR; SmartPtr sofInfoMsg = nullptr; XCamVideoBuffer* ispGain = nullptr; XCamVideoBuffer* wrGain = nullptr; XCamVideoBuffer* xCamAmdProcRes = nullptr; RkAiqAlgoProcResAmdInt* amdProcRes = nullptr; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { sofInfoMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISP_GAIN_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { ispGain = convert_to_XCamVideoBuffer(vdBufMsg->msg); } } else if ((*listIt)->msg_id == XCAM_MESSAGE_ISPP_GAIN_WR_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { wrGain = convert_to_XCamVideoBuffer(vdBufMsg->msg); } } else if ((*listIt)->msg_id == XCAM_MESSAGE_AMD_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) { xCamAmdProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); if (xCamAmdProcRes) amdProcRes = (RkAiqAlgoProcResAmdInt*)xCamAmdProcRes->map(xCamAmdProcRes); } } listIt = msgList->erase(listIt); } // 4. start executing algorithm module flow if (sofInfoMsg.ptr() && /* ispGain != nullptr && */ wrGain != nullptr /* && amdProcRes != nullptr */) mAiqCore->ynrGroupAnalyze(id, sofInfoMsg, ispGain, wrGain, amdProcRes->amd_proc_res_com.amd_proc_res); else ret = XCAM_RETURN_BYPASS; if (ispGain) ispGain->unref(ispGain); if (wrGain) wrGain->unref(wrGain); if (xCamAmdProcRes) xCamAmdProcRes->unref(xCamAmdProcRes); return XCAM_RETURN_NO_ERROR; } XCamReturn RkAiqAnalyzeGroupManager::grp0MessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(GRP0HANDLER, 100); // 3. determine if all the required messages have been received XCamReturn ret = XCAM_RETURN_NO_ERROR; grp0AnalyzerInParams_t inParams = { .sofInfoMsg = nullptr, .aecStatsBuf = nullptr, .awbStatsBuf = nullptr, .afStatsBuf = nullptr, .aePreRes = nullptr, .aeProcRes = nullptr, }; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { inParams.sofInfoMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PRE_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aePreRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aeProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AEC_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aecStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AWB_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.awbStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AF_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.afStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } inParams.id = id; // 4. start executing algorithm module flow if (inParams.sofInfoMsg.ptr() && inParams.aePreRes && inParams.aeProcRes && \ inParams.aecStatsBuf && inParams.awbStatsBuf) mAiqCore->grp0Analyze(inParams); else ret = XCAM_RETURN_BYPASS; if (inParams.aePreRes) inParams.aePreRes->unref(inParams.aePreRes); if (inParams.aeProcRes) inParams.aeProcRes->unref(inParams.aeProcRes); if (inParams.aecStatsBuf) inParams.aecStatsBuf->unref(inParams.aecStatsBuf); if (inParams.awbStatsBuf) inParams.awbStatsBuf->unref(inParams.awbStatsBuf); if (inParams.afStatsBuf) inParams.afStatsBuf->unref(inParams.afStatsBuf); return ret; } XCamReturn RkAiqAnalyzeGroupManager::grp1MessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(GRP1HANDLER, 100); // 3. determine if all the required messages have been received XCamReturn ret = XCAM_RETURN_NO_ERROR; grp1AnalyzerInParams_t inParams = { .sofInfoMsg = nullptr, .aecStatsBuf = nullptr, .awbStatsBuf = nullptr, .afStatsBuf = nullptr, .aePreRes = nullptr, .awbProcRes = nullptr, }; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { inParams.sofInfoMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PRE_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aePreRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AWB_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.awbProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AEC_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aecStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AWB_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.awbStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AF_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.afStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } inParams.id = id; // 4. start executing algorithm module flow if (inParams.sofInfoMsg.ptr() && inParams.awbProcRes) mAiqCore->grp1Analyze(inParams); else ret = XCAM_RETURN_BYPASS; if (inParams.aePreRes) inParams.aePreRes->unref(inParams.aePreRes); if (inParams.awbProcRes) inParams.awbProcRes->unref(inParams.awbProcRes); if (inParams.aecStatsBuf) inParams.aecStatsBuf->unref(inParams.aecStatsBuf); if (inParams.awbStatsBuf) inParams.awbStatsBuf->unref(inParams.awbStatsBuf); if (inParams.afStatsBuf) inParams.afStatsBuf->unref(inParams.afStatsBuf); return ret; } XCamReturn RkAiqAnalyzeGroupManager::afMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(AFHANDLER, 100); // 3. determine if all the required messages have been received XCamReturn ret = XCAM_RETURN_NO_ERROR; afAnalyzerInParams_t inParams = { .expInfo = nullptr, .aecStatsBuf = nullptr, .afStatsBuf = nullptr, .aePreRes = nullptr, .aeProcRes = nullptr, }; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { inParams.expInfo = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PRE_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aePreRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AE_PROC_RES_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aeProcRes = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AEC_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.aecStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_AF_STATS_OK) { SmartPtr vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) inParams.afStatsBuf = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } inParams.id = id; // 4. start executing algorithm module flow if (inParams.expInfo.ptr() && inParams.aecStatsBuf && inParams.afStatsBuf && \ inParams.aePreRes && inParams.aeProcRes) mAiqCore->afAnalyze(inParams); else ret = XCAM_RETURN_BYPASS; if (inParams.aePreRes) inParams.aePreRes->unref(inParams.aePreRes); if (inParams.aeProcRes) inParams.aeProcRes->unref(inParams.aeProcRes); if (inParams.aecStatsBuf) inParams.aecStatsBuf->unref(inParams.aecStatsBuf); if (inParams.afStatsBuf) inParams.afStatsBuf->unref(inParams.afStatsBuf); return ret; } XCamReturn RkAiqAnalyzeGroupManager::eisGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(EISHANDLER, 100); XCamReturn ret = XCAM_RETURN_NO_ERROR; SmartPtr sofInfoMsg = nullptr; XCamVideoBuffer* orbStats = nullptr; XCamVideoBuffer* nrImg = nullptr; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_SOF_INFO_OK) { sofInfoMsg = (*listIt).dynamic_cast_ptr(); } else if ((*listIt)->msg_id == XCAM_MESSAGE_ORB_STATS_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) orbStats = convert_to_XCamVideoBuffer(vdBufMsg->msg); } else if ((*listIt)->msg_id == XCAM_MESSAGE_NR_IMG_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) nrImg = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } if (sofInfoMsg.ptr() && orbStats) ret = mAiqCore->eisGroupAnalyze(id, sofInfoMsg, orbStats, nrImg); else ret = XCAM_RETURN_BYPASS; orbStats->unref(orbStats); nrImg->unref(nrImg); return ret; } XCamReturn RkAiqAnalyzeGroupManager::orbGroupMessageHandler( std::list>& msgs, uint32_t& id) { //XCAM_STATIC_FPS_CALCULATION(ORBHANDLER, 100); XCamReturn ret = XCAM_RETURN_NO_ERROR; XCamVideoBuffer* orbStats = nullptr; list>* msgList = &msgs; list>::iterator listIt; for (listIt = msgList->begin(); listIt != msgList->end();) { SmartPtr vdBufMsg; if ((*listIt)->msg_id == XCAM_MESSAGE_ORB_STATS_OK) { vdBufMsg = (*listIt).dynamic_cast_ptr(); if (vdBufMsg.ptr()) orbStats = convert_to_XCamVideoBuffer(vdBufMsg->msg); } listIt = msgList->erase(listIt); } if (orbStats) ret = mAiqCore->orbGroupAnalyze(id, orbStats); else ret = XCAM_RETURN_BYPASS; orbStats->unref(orbStats); return ret; } void RkAiqAnalyzeGroupManager::parseAlgoGroup(const struct RkAiqAlgoDesCommExt* algoDes) { // clang-format off std::map concreteHandlerMap = { { RK_AIQ_CORE_ANALYZE_MEAS, std::bind(&RkAiqAnalyzeGroupManager::measGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_OTHER, std::bind(&RkAiqAnalyzeGroupManager::otherGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_AMD, std::bind(&RkAiqAnalyzeGroupManager::amdGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_THUMBNAILS, std::bind(&RkAiqAnalyzeGroupManager::thumbnailsGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_LSC, std::bind(&RkAiqAnalyzeGroupManager::lscGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_AE, std::bind(&RkAiqAnalyzeGroupManager::aeGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_AMFNR, std::bind(&RkAiqAnalyzeGroupManager::amfnrGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_AYNR, std::bind(&RkAiqAnalyzeGroupManager::aynrGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_AWB, std::bind(&RkAiqAnalyzeGroupManager::awbGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_GRP0, std::bind(&RkAiqAnalyzeGroupManager::grp0MessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_GRP1, std::bind(&RkAiqAnalyzeGroupManager::grp1MessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_AF, std::bind(&RkAiqAnalyzeGroupManager::afMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_EIS, std::bind(&RkAiqAnalyzeGroupManager::eisGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, { RK_AIQ_CORE_ANALYZE_ORB, std::bind(&RkAiqAnalyzeGroupManager::orbGroupMessageHandler, this, std::placeholders::_1, std::placeholders::_2)}, }; // clang-format on uint64_t enAlgosMask = mAiqCore->getCustomEnAlgosMask(); for (size_t i = 0; algoDes[i].des != NULL; i++) { int algo_type = algoDes[i].des->type; if (!(1 << algo_type & enAlgosMask)) continue; int deps_flag = 0; for (size_t j = 0; j < algoDes[i].grpConds.size; j++) deps_flag |= 1 << algoDes[i].grpConds.conds[j].cond; rk_aiq_core_analyze_type_e group = algoDes[i].group; mGroupAlgoListMap[group].push_back(algo_type); mGroupAlgoListMap[RK_AIQ_CORE_ANALYZE_ALL].push_back(algo_type); if (mGroupMap.count(deps_flag)) { continue; } mGroupMap[deps_flag] = new RkAiqAnalyzerGroup(mAiqCore, group, deps_flag, &algoDes[i].grpConds); mGroupMap[deps_flag]->setConcreteHandler(concreteHandlerMap[group]); LOGD_ANALYZER_SUBM(ANALYZER_SUBM, "Created group %" PRIx64 " for dep flags %" PRIx64"", deps_flag, group); } } XCamReturn RkAiqAnalyzeGroupManager::handleMessage(const SmartPtr &msg) { //XCAM_STATIC_FPS_CALCULATION(HANDLEMSG, 100); for (auto& it : mGroupMap) { if ((it.first & (1 << msg->msg_id)) != 0) { LOGD_ANALYZER_SUBM(ANALYZER_SUBM, "Handle message(%s) id[%d] on group(%s), flags %" PRIx64 "", MessageType2Str[msg->msg_id], msg->frame_id, AnalyzerGroupType2Str[it.second->getType()], it.second->getDepsFlag()); it.second->pushMsg(msg); } } return XCAM_RETURN_NO_ERROR; } }; // namespace RkCam