blob: 08daceccf395cd5ffad2ab17098cc162a5407238 [file] [log] [blame]
/*
* Copyright (C) 2019 MediaTek Inc.
*
* 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.
*/
#define LOG_TAG "MtkCam/P1NodeImp"
//
#include <algorithm>
#include <memory>
#include "mtkcam/pipeline/hwnode/p1/P1NodeImp.h"
#include "P1TaskCtrl.h"
#include "P1DeliverMgr.h"
#include <mtkcam/aaa/aaa_utils.h>
#include <mtkcam/feature/eis/EisInfo.h>
#include <mtkcam/utils/hw/HwTransform.h>
#include <property_lib.h>
#include <string>
#include <vector>
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
namespace NSCam {
namespace v3 {
namespace NSP1Node {
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/******************************************************************************
*
******************************************************************************/
P1NodeImp::P1NodeImp()
: BaseNode(),
P1Node(),
mInit(MTRUE)
//
,
mPowerNotify(MFALSE)
//
,
mStartState(NSP1Node::START_STATE_NULL)
//
,
mpStreamPool_full(nullptr),
mpStreamPool_resizer(nullptr),
mpStreamPool_lcso(nullptr),
mpStreamPool_rsso(nullptr),
mBurstNum(1),
mDepthNum(1),
mMeta_PatMode(0),
mRawPostProcSupport(MTRUE),
mRawProcessed(MFALSE),
mRawSetDefType(RAW_DEF_TYPE_AUTO),
mRawDefType(EPipe_PURE_RAW),
mRawOption(0),
mDisableFrontalBinning(MFALSE),
mDisableDynamicTwin(MFALSE),
mEnableLCSO(MFALSE),
mEnableRSSO(MFALSE),
mEnableUniForcedOn(MFALSE),
mDisableHLR(MFALSE),
mPipeMode(PIPE_MODE_NORMAL),
mPipeBit(CAM_Pipeline_12BITS),
mResizeQuality(RESIZE_QUALITY_UNKNOWN),
mTgNum(0)
//
,
mRawFormat(P1_IMGO_DEF_FMT),
mRawStride(0),
mRawLength(0)
//
,
mReceiveMode(REV_MODE_NORMAL),
mSensorFormatOrder(SENSOR_FORMAT_ORDER_NONE),
mQualitySwitching(MFALSE),
m3AProcessedDepth(3),
mNumHardwareBuffer(3),
mDelayframe(3),
mLastNum(1),
mLastSofIdx(P1SOFIDX_NULL_VAL),
mLastSetNum(0),
mActive(MFALSE),
mReady(MFALSE)
#if (USING_DRV_IO_PIPE_EVENT)
,
mIoPipeEvtState(IO_PIPE_EVT_STATE_NONE),
mIoPipeEvtWaiting(MFALSE),
mIoPipeEvtOpAcquired(MFALSE),
mIoPipeEvtOpLeaving(MFALSE),
mspIoPipeEvtHandleAcquire(nullptr),
mspIoPipeEvtHandleRelease(nullptr)
#endif
,
mCamIOVersion(0),
mpCamIO(nullptr),
mp3A(nullptr),
mpLCS(nullptr)
//
,
mPixelMode(0)
//
,
mConfigPort(CONFIG_PORT_NONE),
mConfigPortNum(0),
mIsBinEn(MFALSE),
mIsDynamicTwinEn(MFALSE),
mIsLegacyStandbyMode(MFALSE),
mForceStandbyMode(0)
//
,
mResizeRatioMax(RESIZE_RATIO_MAX_100X)
//
,
mLastFrmReqNumLock(),
mLastFrmNum(P1_FRM_NUM_NULL),
mLastReqNum(P1_REQ_NUM_NULL),
mLastCbCnt(0)
//
,
mMonitorTime(0)
//
,
mDebugScanLineMask(0),
mpDebugScanLine(nullptr)
//
,
mIvMs(0),
mpIndependentVerification(nullptr)
//
,
mFrameSetAlready(MFALSE)
//
,
mFirstReceived(MFALSE)
//
,
mStartCaptureState(START_CAP_STATE_NONE),
mStartCaptureType(NS3Av3::E_CAPTURE_NORMAL),
mStartCaptureIdx(0),
mStartCaptureExp(0),
mTransferJobIdx(P1ACT_ID_NULL),
mTransferJobWaiting(MFALSE)
//
//
,
mDequeThreadProfile("P1Node::deque", 30000000LL),
mInFlightRequestCnt(0)
//
,
mpDeliverMgr(nullptr)
//
,
mpConnectLMV(NULL)
//
,
mpConCtrl(nullptr)
//
,
mpHwStateCtrl(nullptr)
//
,
mpTimingCheckerMgr(nullptr),
mTimingFactor(1)
//
,
mspSyncHelper(nullptr),
mSyncHelperReady(MFALSE)
//
,
mspResConCtrl(nullptr),
mResConClient(IResourceConcurrency::CLIENT_HANDLER_NULL),
mIsResConGot(MFALSE)
//
//
,
mLogLevel(0),
mLogLevelI(0),
mSysLevel(P1_SYS_LV_DEFAULT),
mMetaLogOp(0),
mMetaLogTag(0),
mCamDumpEn(0),
mEnableDumpRaw(0),
mDisableAEEIS(0)
//
,
mNoteRelease(P1NODE_FRAME_NOTE_SLOT_SIZE_DEF),
mNoteDispatch(P1NODE_FRAME_NOTE_SLOT_SIZE_DEF)
//
,
mInitReqSet(0),
mInitReqNum(0),
mInitReqCnt(0),
mInitReqOff(MFALSE)
//
,
mEnableCaptureFlow(MFALSE),
mEnableFrameSync(MFALSE),
mExitPending(MFALSE) {
pthread_rwlock_init(&mConfigRWLock, NULL);
#if (USING_DRV_IO_PIPE_EVENT)
pthread_rwlock_init(&mIoPipeEvtStateLock, NULL);
#endif
mNodeName = "P1Node"; // default name
MINT32 cam_log = ::property_get_int32("vendor.debug.camera.log", 0);
MINT32 p1_log = ::property_get_int32("vendor.debug.camera.log.p1node", 1);
MINT32 p1_logi = ::property_get_int32("vendor.debug.camera.log.p1nodei", 0);
MINT32 g_log = ::property_get_int32("persist.vendor.mtk.camera.log_level",
0); // global log level control
MINT32 g_log_lv =
(g_log >= 2) ? (g_log - 2) : (0); // 2:I:USER 3:D:USERDEBUG 4:V:ENG
mLogLevel = MAX(cam_log, p1_log);
#if 0 // force to enable all p1 node log
#warning "[FIXME] force to enable P1Node log"
if (mLogLevel < 2) {
mLogLevel = 2;
}
#endif
MBOOL buildLogD = MFALSE;
MBOOL buildLogI = MFALSE;
#if (IS_P1_LOGI)
// #warning "IS_P1_LOGI build LogI"
mLogLevelI = (mLogLevel > 0) ? (mLogLevel - 1) : (mLogLevel);
buildLogI = MTRUE;
#endif
#if (IS_P1_LOGD)
// #warning "IS_P1_LOGD build LogD"
mLogLevelI = mLogLevel;
buildLogD = MTRUE;
#endif
if (p1_log > 1) {
mLogLevelI = mLogLevel;
}
//
if (p1_logi > 0) {
mLogLevelI = p1_logi;
}
mLogLevel = MAX(mLogLevel, g_log_lv);
mLogLevelI = MAX(mLogLevelI, g_log_lv);
//
MINT32 g_sys = P1_SYS_LV_DEFAULT;
MINT32 g_sys_set = 1;
#if 1 // decide by global-setting
g_sys_set = ::property_get_int32("vendor.debug.mtkcam.systrace.level",
MTKCAM_SYSTRACE_LEVEL_DEFAULT);
#endif
g_sys = (g_sys_set > 0) ? P1_SYS_LV_DEFAULT : P1_SYS_LV_CRITICAL;
mSysLevel = g_sys;
MINT32 p1sys = ::property_get_int32("vendor.debug.camera.log.p1nodesys", 9);
if (p1sys < 9) { // update by manual-setting
// =0 : forced-off all P1_TRACE
// =1 : basic-on P1_TRACE-Lv==1 (P1_SYS_LV_BASIC)
// =2 : critical-on P1_TRACE-Lv<=2 (P1_SYS_LV_CRITICAL)
// =3 : default-on P1_TRACE-Lv<=3 (P1_SYS_LV_DEFAULT)
// >3 : manually-on
mSysLevel = p1sys;
}
//
MINT32 pMetaLogOp =
property_get_int32("vendor.debug.camera.log.p1nodemeta", 0);
MINT32 pMetaLogTag =
property_get_int32("vendor.debug.camera.log.p1nodemetatag", 0);
mMetaLogOp = pMetaLogOp;
mMetaLogTag = pMetaLogTag;
if (mMetaLogTag != 0) {
mMetaLogOp = 1;
}
//
mCamDumpEn = property_get_int32("vendor.debug.camera.dump.en", 0);
//
mEnableDumpRaw =
property_get_int32("vendor.debug.feature.forceEnableIMGO", 0);
//
mDisableAEEIS = property_get_int32("vendor.debug.eis.disableae", 0);
//
mDebugScanLineMask =
::property_get_int32("vendor.debug.camera.scanline.p1", 0);
if (mDebugScanLineMask != 0) {
mpDebugScanLine = std::make_unique<DebugScanLineImp>();
}
//
mIvMs = property_get_int32(
"vendor.debug.camera.log.p1independentverification", 0);
//
#if (SUPPORT_BUFFER_TUNING_DUMP)
MY_LOGI("SUPPORT_BUFFER_TUNING_DUMP CamDumpEn(%d)", mCamDumpEn);
#else
if (mCamDumpEn > 0) {
MY_LOGI("NOT-SUPPORT_BUFFER_TUNING_DUMP CamDumpEn(%d)", mCamDumpEn);
}
mCamDumpEn = 0;
#endif
//
#if (P1NODE_BUILD_LOG_LEVEL_DEFAULT > 3)
mTimingFactor = 32; // for ENG build
#elif P1NODE_BUILD_LOG_LEVEL_DEFAULT > 2
mTimingFactor = 2; // for USERDEBUG build
#else
mTimingFactor = 1; // for USER build
mIvMs = 0;
#endif
//
MY_LOGI(
"LOGD[%d](%d) LOGI[%d](%d) prop(cam:%d pl:%d pi:%d g:%d:%d) - "
" SYS[%d-%d:%d](%d) - "
"MetaLog(p:%d/%d m:%d/x%X) DumpRaw(%d) DataDump(%d) DrawLine(%d) - "
"TF(%d) - IV(%d)",
buildLogD, mLogLevel, buildLogI, mLogLevelI, cam_log, p1_log, p1_logi,
g_log, g_log_lv, g_sys_set, g_sys, p1sys, mSysLevel, pMetaLogOp,
pMetaLogTag, mMetaLogOp, mMetaLogTag, mEnableDumpRaw, mCamDumpEn,
mDebugScanLineMask, mTimingFactor, mIvMs);
}
/******************************************************************************
*
******************************************************************************/
P1NodeImp::~P1NodeImp() {
MY_LOGI("");
pthread_rwlock_destroy(&mConfigRWLock);
#if (USING_DRV_IO_PIPE_EVENT)
pthread_rwlock_destroy(&mIoPipeEvtStateLock);
#endif
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::init(InitParams const& rParams) {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:init");
std::lock_guard<std::mutex> _l(mPublicLock);
{
pthread_rwlock_wrlock(&mConfigRWLock);
//
mOpenId = rParams.openId;
mNodeId = rParams.nodeId;
mNodeName = rParams.nodeName;
pthread_rwlock_unlock(&mConfigRWLock);
}
//
if (mIvMs > 0) {
mpIndependentVerification =
std::make_unique<P1NodeImp::IndependentVerification>(
mLogLevel, mLogLevelI, (MUINT32)mIvMs, shared_from_this());
if (mpIndependentVerification == nullptr) {
MY_LOGE("IndependentVerification create fail");
return NO_MEMORY;
}
}
// Select CamIO version
{
auto pModule = getNormalPipeModule();
if (!pModule) {
MY_LOGE("getNormalPipeModule() fail");
return UNKNOWN_ERROR;
}
MUINT32 const* version = nullptr;
size_t count = 0;
int err = pModule->get_sub_module_api_version(&version, &count);
if (err < 0 || !count || !version) {
MY_LOGE(
"[%d] INormalPipeModule::get_sub_module_api_version - err:%#x "
"count:%zu version:%p",
mOpenId, err, count, version);
return UNKNOWN_ERROR;
}
mCamIOVersion = *(version + count - 1); // Select max. version
MY_LOGD("[%d] count:%zu Selected CamIO Version:%0#x", mOpenId, count,
mCamIOVersion);
}
#if (USING_DRV_IO_PIPE_EVENT)
{
std::lock_guard<std::mutex> _l(mIoPipeEvtOpLock);
mIoPipeEvtOpLeaving = MFALSE;
NSCam::NSIoPipe::IoPipeEventSystem& evtSystem =
NSCam::NSIoPipe::IoPipeEventSystem::getGlobal();
if (mspIoPipeEvtHandleAcquire != nullptr) {
mspIoPipeEvtHandleAcquire->unsubscribe();
mspIoPipeEvtHandleAcquire = nullptr;
}
mspIoPipeEvtHandleAcquire = evtSystem.subscribe(
NSCam::NSIoPipe::EVT_IPRAW_P1_ACQUIRING, onEvtCtrlAcquiring, this);
if (mspIoPipeEvtHandleAcquire == nullptr) {
MY_LOGE("IoPipeEventSystem subscribe EVT_IPRAW_P1_ACQUIRING fail");
return UNKNOWN_ERROR;
}
if (mspIoPipeEvtHandleRelease != nullptr) {
mspIoPipeEvtHandleRelease->unsubscribe();
mspIoPipeEvtHandleRelease = nullptr;
}
mspIoPipeEvtHandleRelease = evtSystem.subscribe(
NSCam::NSIoPipe::EVT_IPRAW_P1_RELEASED, onEvtCtrlReleasing, this);
if (mspIoPipeEvtHandleRelease == nullptr) {
MY_LOGE("IoPipeEventSystem subscribe EVT_IPRAW_P1_RELEASED fail");
return UNKNOWN_ERROR;
}
}
#endif
mStuffBufMgr.setLog(getOpenId(), mLogLevel, mLogLevelI);
mLongExp.config(getOpenId(), mLogLevel, mLogLevelI);
mpConCtrl =
std::make_shared<ConcurrenceControl>(mLogLevel, mLogLevelI, mSysLevel);
if (mpConCtrl == nullptr || mpConCtrl->getStageCtrl() == nullptr) {
MY_LOGE("ConcurrenceControl create fail");
return NO_MEMORY;
}
mpHwStateCtrl = std::make_shared<HardwareStateControl>();
if (mpHwStateCtrl == nullptr) {
MY_LOGE("HardwareStateControl create fail");
return NO_MEMORY;
}
mpConnectLMV = std::make_shared<P1ConnectLMV>(getOpenId(), mLogLevel,
mLogLevelI, mSysLevel);
if (mpConnectLMV == NULL) {
MY_LOGE("ConnectLMV create fail Log(%d)(%d) Id(%d)", mLogLevel, mLogLevelI,
getOpenId());
return NO_MEMORY;
}
mpTimingCheckerMgr = std::make_shared<TimingCheckerMgr>(
mTimingFactor, getOpenId(), mLogLevel, mLogLevelI);
if (mpTimingCheckerMgr == nullptr) {
MY_LOGE("TimingCheckerMgr create fail");
return NO_MEMORY;
}
mThread = std::thread(std::bind(&P1NodeImp::threadLoop, this));
mpDeliverMgr = std::make_shared<P1DeliverMgr>();
if (mpDeliverMgr != nullptr) {
mpDeliverMgr->init(shared_from_this());
} else {
MY_LOGE("DeliverMgr create fail");
return NO_MEMORY;
}
mpRegisterNotify = std::make_shared<P1RegisterNotify>(shared_from_this());
if (mpRegisterNotify != nullptr) {
mpRegisterNotify->init();
} else {
MY_LOGE("RegisterNotify create fail");
return NO_MEMORY;
}
mpTaskCtrl = std::make_shared<P1TaskCtrl>(shared_from_this());
if (mpTaskCtrl == nullptr) {
MY_LOGE("TaskCtrl create fail");
return NO_MEMORY;
}
mpTaskCollector = std::make_shared<P1TaskCollector>(mpTaskCtrl);
if (mpTaskCollector == nullptr) {
MY_LOGE("TaskCollector create fail");
return NO_MEMORY;
}
mpAccDetector = std::make_unique<cros::NSCam::AccelerationDetector>();
mpAccDetector->prepare();
FUNCTION_OUT;
return NO_ERROR;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::uninit() {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:uninit");
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_API_UNINIT_BGN,
LogInfo::CP_API_UNINIT_END);
#if (USING_DRV_IO_PIPE_EVENT)
{
std::lock_guard<std::mutex> _l(mIoPipeEvtOpLock);
mIoPipeEvtOpLeaving = MTRUE;
if (mspIoPipeEvtHandleAcquire != nullptr) {
mspIoPipeEvtHandleAcquire->unsubscribe();
mspIoPipeEvtHandleAcquire = nullptr;
}
if (mspIoPipeEvtHandleRelease != nullptr) {
mspIoPipeEvtHandleRelease->unsubscribe();
mspIoPipeEvtHandleRelease = nullptr;
}
}
#endif
std::lock_guard<std::mutex> _l(mPublicLock);
// flush the left frames if exist
onHandleFlush(MFALSE);
requestExit();
// mvStreamMeta.clear();
for (int stream = STREAM_ITEM_START; stream < STREAM_META_NUM; stream++) {
mvStreamMeta[stream] = nullptr;
}
// mvStreamImg.clear();
for (int stream = STREAM_ITEM_START; stream < STREAM_IMG_NUM; stream++) {
mvStreamImg[stream] = nullptr;
}
mspSyncHelper = nullptr;
if (mspResConCtrl != nullptr) {
P1NODE_RES_CON_RETURN(mspResConCtrl, mResConClient);
mspResConCtrl = nullptr;
}
if (mpDeliverMgr != nullptr) {
mpDeliverMgr->uninit();
mpDeliverMgr = nullptr;
}
if (mpRegisterNotify != nullptr) {
mpRegisterNotify->uninit();
mpRegisterNotify = nullptr;
}
mpTaskCollector = nullptr;
mpTaskCtrl = nullptr;
mpTimingCheckerMgr = nullptr;
mpHwStateCtrl = nullptr;
mpConCtrl = nullptr;
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::check_config(ConfigParams const& rParams) {
P1_TRACE_AUTO(SLG_S, "P1:check_config");
if (rParams.pInAppMeta == nullptr) {
MY_LOGE("in app metadata is null");
return BAD_VALUE;
}
if (rParams.pInHalMeta == nullptr) {
MY_LOGE("in hal metadata is null");
return BAD_VALUE;
}
if (rParams.pOutAppMeta == nullptr) {
MY_LOGE("out app metadata is null");
return BAD_VALUE;
}
if (rParams.pOutHalMeta == nullptr) {
MY_LOGE("out hal metadata is null");
return BAD_VALUE;
}
if (rParams.pvOutImage_full.size() == 0 &&
rParams.pOutImage_resizer == nullptr) {
MY_LOGE("image is empty");
return BAD_VALUE;
}
if (rParams.pStreamPool_full != nullptr &&
rParams.pvOutImage_full.size() == 0) {
MY_LOGE("wrong full input");
return BAD_VALUE;
}
if (rParams.pStreamPool_resizer != nullptr &&
rParams.pOutImage_resizer == nullptr) {
MY_LOGE("wrong resizer input");
return BAD_VALUE;
}
if (rParams.pStreamPool_lcso != nullptr &&
rParams.pOutImage_lcso == nullptr) {
MY_LOGE("wrong resizer input");
return BAD_VALUE;
}
if (rParams.enableLCS == MTRUE && rParams.pOutImage_lcso == nullptr) {
MY_LOGE("wrong resizer input");
return BAD_VALUE;
}
//
if (mpDeliverMgr != nullptr && mpDeliverMgr->runningGet() /*isRunning()*/) {
MY_LOGI("DeliverMgr thread is running");
mpDeliverMgr->requestExit();
mpDeliverMgr->trigger();
mpDeliverMgr->join();
mpDeliverMgr->runningSet(MFALSE);
}
// Get sensor format
IHalSensorList* const pIHalSensorList = GET_HalSensorList();
if (pIHalSensorList) {
MUINT32 sensorDev =
(MUINT32)pIHalSensorList->querySensorDevIdx(getOpenId());
NSCam::SensorStaticInfo sensorStaticInfo;
memset(&sensorStaticInfo, 0, sizeof(NSCam::SensorStaticInfo));
pIHalSensorList->querySensorStaticInfo(sensorDev, &sensorStaticInfo);
mSensorFormatOrder = sensorStaticInfo.sensorFormatOrder;
MY_LOGI("SensorFormatOrder %d", mSensorFormatOrder);
}
//
{
pthread_rwlock_wrlock(&mConfigRWLock);
//
for (int meta = STREAM_ITEM_START; meta < STREAM_META_NUM; meta++) {
mvStreamMeta[meta] = nullptr;
}
if (rParams.pInAppMeta != nullptr) {
mvStreamMeta[STREAM_META_IN_APP] = rParams.pInAppMeta;
}
if (rParams.pInHalMeta != nullptr) {
mvStreamMeta[STREAM_META_IN_HAL] = rParams.pInHalMeta;
}
if (rParams.pOutAppMeta != nullptr) {
mvStreamMeta[STREAM_META_OUT_APP] = rParams.pOutAppMeta;
}
if (rParams.pOutHalMeta != nullptr) {
mvStreamMeta[STREAM_META_OUT_HAL] = rParams.pOutHalMeta;
}
//
for (int img = STREAM_ITEM_START; img < STREAM_IMG_NUM; img++) {
mvStreamImg[img] = nullptr;
}
//
if (rParams.pInImage_yuv != nullptr) {
mvStreamImg[STREAM_IMG_IN_YUV] = rParams.pInImage_yuv;
}
if (rParams.pInImage_opaque != nullptr) {
mvStreamImg[STREAM_IMG_IN_OPAQUE] = rParams.pInImage_opaque;
}
if (rParams.pOutImage_opaque != nullptr) {
mvStreamImg[STREAM_IMG_OUT_OPAQUE] = rParams.pOutImage_opaque;
}
for (size_t i = 0; i < rParams.pvOutImage_full.size(); i++) {
if (rParams.pvOutImage_full[i] != nullptr) { // pick the first item
mvStreamImg[STREAM_IMG_OUT_FULL] = rParams.pvOutImage_full[i];
break;
}
}
if (rParams.pOutImage_resizer != nullptr) {
mvStreamImg[STREAM_IMG_OUT_RESIZE] = rParams.pOutImage_resizer;
}
if (rParams.pOutImage_lcso != nullptr) {
mvStreamImg[STREAM_IMG_OUT_LCS] = rParams.pOutImage_lcso;
mEnableLCSO = MTRUE;
}
//
mpStreamPool_full = rParams.pStreamPool_full;
mpStreamPool_resizer = rParams.pStreamPool_resizer;
mpStreamPool_lcso = rParams.pStreamPool_lcso;
//
#if 0
#warning "[FIXME] force to change p1 not use pool"
{
MUINT8 no_pool =
::property_get_int32("vendor.debug.camera.p1nopool", 0);
if (no_pool > 0) {
mpStreamPool_full = NULL;
mpStreamPool_resizer = NULL;
mpStreamPool_lcso = NULL;
mpStreamPool_rsso = NULL;
}
MY_LOGI("debug.camera.p1nopool = %d", no_pool);
}
#endif
//
{ mspSyncHelper = rParams.pSyncHelper; }
//
{
if (mspResConCtrl != nullptr) {
P1NODE_RES_CON_RETURN(mspResConCtrl, mResConClient);
mspResConCtrl = nullptr;
}
mspResConCtrl = rParams.pResourceConcurrency;
if (mspResConCtrl != nullptr) {
mResConClient = IResourceConcurrency::CLIENT_HANDLER_NULL;
mIsResConGot = MFALSE;
}
}
//
mBurstNum = MAX(rParams.burstNum, 1);
#if (ENABLE_CHECK_CONFIG_COMMON_PORPERTY || (0)) // for SMVR IT
#warning "[FIXME] force to change p1 burst number"
{
MUINT8 burst_num = ::property_get_int32("vendor.debug.camera.p1burst", 0);
if (burst_num > 0) {
mBurstNum = burst_num;
}
MY_LOGI("debug.camera.p1burst = %d - BurstNum = %d", burst_num,
mBurstNum);
}
#endif
//
mReceiveMode = rParams.receiveMode;
#if (ENABLE_CHECK_CONFIG_COMMON_PORPERTY || (0)) // receive mode IT
#warning "[FIXME] force to change p1 receive mode"
{
MUINT8 rev_mode = ::property_get_int32("vendor.debug.camera.p1rev", 0);
if (rev_mode > 0) {
mReceiveMode = (REV_MODE)rev_mode;
}
MY_LOGI("debug.camera.p1rev = %d - RevMode=%d BurstNum=%d", rev_mode,
mReceiveMode, mBurstNum);
}
#endif
//
// #warning "force to change standby mode"
{
MINT8 standby_mode =
::property_get_int32("vendor.debug.camera.p1standbymode", 0);
if (standby_mode > 0) {
mForceStandbyMode = standby_mode;
MY_LOGI("debug.camera.standbymode = %d - ForceStandbyMode = %d",
standby_mode, mForceStandbyMode);
}
}
//
std::string meta_str("");
mCfgAppMeta.clear();
if (rParams.cfgAppMeta.count() > 0) {
mCfgAppMeta = rParams.cfgAppMeta;
if (1 <= mLogLevelI) {
base::StringAppendF(&meta_str, " -- ConfigParams.cfgAppMeta[%d] ",
rParams.cfgAppMeta.count());
for (MUINT32 i = 0; i < rParams.cfgAppMeta.count(); i++) {
generateMetaInfoStr(rParams.cfgAppMeta.entryAt(i), &meta_str);
}
}
}
mCfgHalMeta.clear();
if (rParams.cfgHalMeta.count() > 0) {
mCfgHalMeta = rParams.cfgHalMeta;
if (1 <= mLogLevelI) {
base::StringAppendF(&meta_str, " -- ConfigParams.cfgHalMeta[%d] ",
rParams.cfgHalMeta.count());
for (MUINT32 i = 0; i < rParams.cfgHalMeta.count(); i++) {
generateMetaInfoStr(rParams.cfgHalMeta.entryAt(i), &meta_str);
}
}
}
if (!meta_str.empty()) {
MY_LOGI("%s", meta_str.c_str());
}
//
mSensorParams = rParams.sensorParams;
//
mRawProcessed = rParams.rawProcessed;
mRawSetDefType = rParams.rawDefType;
//
mTgNum = rParams.tgNum;
//
mPipeMode = rParams.pipeMode;
//
mPipeBit = rParams.pipeBit;
//
mResizeQuality = rParams.resizeQuality;
//
mDisableHLR = rParams.disableHLR;
//
mDisableFrontalBinning = rParams.disableFrontalBinning;
//
mDisableDynamicTwin = rParams.disableDynamicTwin;
//
mEnableUniForcedOn = rParams.enableUNI;
//
if (IS_LMV(mpConnectLMV)) {
mEnableEISO = rParams.enableEIS;
mForceSetEIS = rParams.forceSetEIS;
mPackedEisInfo = rParams.packedEisInfo;
}
mEnableCaptureFlow = rParams.enableCaptureFlow;
mEnableFrameSync = rParams.enableFrameSync;
if (EN_START_CAP) { // disable - acquire init buffer from pool
mpStreamPool_full = nullptr;
mpStreamPool_resizer = nullptr;
}
//
{
mInitReqSet = rParams.initRequest;
#if (ENABLE_CHECK_CONFIG_COMMON_PORPERTY) // init request set IT
#warning "[FIXME] force to set init request"
{
MUINT8 init_req = ::property_get_int32("vendor.debug.camera.p1init", 0);
if (init_req > 0) {
mInitReqSet = init_req;
}
MY_LOGI("debug.camera.p1init = %d - mInitReq=%d BurstNum=%d", init_req,
mInitReqSet, mBurstNum);
}
#endif
if (EN_INIT_REQ_CFG && mInitReqSet <= P1NODE_DEF_SHUTTER_DELAY) {
MY_LOGE("INVALID init request value (%d)", mInitReqSet);
pthread_rwlock_unlock(&mConfigRWLock);
return INVALID_OPERATION;
}
mInitReqNum =
mInitReqSet *
mBurstNum; // the InitReq setting will re-assign as re-configure
mInitReqCnt = 0;
mInitReqOff = MFALSE;
if (EN_INIT_REQ_CFG) {
MY_LOGI("InitReq Set:%d Num:%d Cnt:%d Off:%d", mInitReqSet, mInitReqNum,
mInitReqCnt, mInitReqOff);
}
}
//
if (IS_BURST_ON) {
mDepthNum = 2;
} else if (isRevMode(REV_MODE_CONSERVATIVE)) {
mDepthNum = 2;
} else {
mDepthNum = 1;
}
//
{
if (((EN_BURST_MODE) &&
(EN_INIT_REQ_CFG || EN_START_CAP || EN_REPROCESSING)) ||
(EN_INIT_REQ_CFG && EN_START_CAP)) {
MY_LOGE(
"[Check_Config_Conflict] P1Node::ConfigParams:: "
"burstNum(%d) enableCaptureFlow(%d) initRequest(%d) "
"pInImage_opaque[%#" PRIx64
"] "
"pInImage_yuv[%#" PRIx64 "] ",
rParams.burstNum, rParams.enableCaptureFlow, rParams.initRequest,
((mvStreamImg[STREAM_IMG_IN_OPAQUE] == nullptr)
? (StreamId_T)(-1)
: mvStreamImg[STREAM_IMG_IN_OPAQUE]->getStreamId()),
((mvStreamImg[STREAM_IMG_IN_YUV] == nullptr)
? (StreamId_T)(-1)
: mvStreamImg[STREAM_IMG_IN_YUV]->getStreamId()));
pthread_rwlock_unlock(&mConfigRWLock);
return INVALID_OPERATION;
}
}
pthread_rwlock_unlock(&mConfigRWLock);
}
//
if (mvStreamImg[STREAM_IMG_OUT_OPAQUE] != nullptr) {
if (mvStreamImg[STREAM_IMG_OUT_FULL] != nullptr) {
mRawFormat = mvStreamImg[STREAM_IMG_OUT_FULL]->getImgFormat();
mRawStride =
mvStreamImg[STREAM_IMG_OUT_FULL]->getBufPlanes()[0].rowStrideInBytes;
mRawLength =
mvStreamImg[STREAM_IMG_OUT_FULL]->getBufPlanes()[0].sizeInBytes;
} else {
mRawFormat = P1_IMGO_DEF_FMT;
NormalPipe_QueryInfo queryRst;
getNormalPipeModule()->query(PORT_IMGO.index, ENPipeQueryCmd_STRIDE_BYTE,
(EImageFormat)mRawFormat,
mSensorParams.size.w, &queryRst);
mRawStride = queryRst.stride_byte;
mRawLength = mRawStride * mSensorParams.size.h;
}
}
//
{
std::shared_ptr<IMetadataProvider> pMetadataProvider =
NSMetadataProviderManager::valueFor(getOpenId());
if (!pMetadataProvider.get()) {
MY_LOGE(" ! pMetadataProvider.get() ");
return DEAD_OBJECT;
}
IMetadata static_meta = pMetadataProvider->getMtkStaticCharacteristics();
if (tryGetMetadata<MRect>(&static_meta, MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION,
&mActiveArray)) {
MY_LOGD_IF(mLogLevel > 1, "active array(%d, %d, %dx%d)", mActiveArray.p.x,
mActiveArray.p.y, mActiveArray.s.w, mActiveArray.s.h);
} else {
MY_LOGE("no static info: MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION");
#if (P1NODE_USING_MTK_LDVT > 0)
mActiveArray = MRect(mSensorParams.size.w, mSensorParams.size.h);
MY_LOGI("set sensor size to active array(%d, %d, %dx%d)",
mActiveArray.p.x, mActiveArray.p.y, mActiveArray.s.w,
mActiveArray.s.h);
#else
return UNKNOWN_ERROR;
#endif
}
}
//
if (mvStreamImg[STREAM_IMG_OUT_FULL] != nullptr) {
if (mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize() != mSensorParams.size) {
MY_LOGE(
"[Check_Config_Conflict] IMGO_Stream.ImgSize(%dx%d) != "
"SensorParam.Size(%d,%d) - P1Node::ConfigParams:: "
"IMGO_StreamID:%#" PRIx64
"_ImgFormat[0x%x]-ImgSize(%dx%d) "
"SensorParam_mode(%d)_fps(%d)_pixelMode(%d)_vhdrMode(%d)_"
"size(%dx%d)",
mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize().w,
mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize().h,
mSensorParams.size.w, mSensorParams.size.h,
mvStreamImg[STREAM_IMG_OUT_FULL]->getStreamId(),
mvStreamImg[STREAM_IMG_OUT_FULL]->getImgFormat(),
mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize().w,
mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize().h, mSensorParams.mode,
mSensorParams.fps, mSensorParams.pixelMode, mSensorParams.vhdrMode,
mSensorParams.size.w, mSensorParams.size.h);
return INVALID_OPERATION;
}
}
//
{
MERROR res = checkConstraint();
if (res != OK) {
return res;
}
}
//
mLogInfo.config(getOpenId(), mLogLevel, mLogLevelI, mBurstNum);
mLogInfo.setActive(MFALSE);
//
{
MBOOL deliver_mgr_send = MTRUE;
MY_LOGD("USE DeliverMgr Thread Loop : %d", deliver_mgr_send);
if (deliver_mgr_send) {
if (mpDeliverMgr != nullptr) {
mpDeliverMgr->config();
if (NO_ERROR == mpDeliverMgr->run()) {
MY_LOGD("RUN DeliverMgr Thread OK");
mpDeliverMgr->runningSet(MTRUE);
} else {
MY_LOGE("RUN DeliverMgr Thread FAIL");
return BAD_VALUE;
}
}
}
}
//
if (mpTaskCtrl != nullptr) {
mpTaskCtrl->config();
}
if (mpTaskCollector != nullptr) {
mpTaskCollector->config();
}
if (mpRegisterNotify != nullptr) {
mpRegisterNotify->config();
}
//
{
MUINT32 queReserve = mBurstNum * P1NODE_DEF_QUEUE_DEPTH;
{
std::lock_guard<std::mutex> _ll(mDropQueueLock);
mDropQueue.clear();
mDropQueue.reserve(queReserve);
}
{
std::lock_guard<std::mutex> _ll(mRequestQueueLock);
mRequestQueue.clear();
mRequestQueue.reserve(queReserve);
}
{
std::lock_guard<std::mutex> _ll(mProcessingQueueLock);
mProcessingQueue.clear();
mProcessingQueue.reserve(queReserve);
}
}
#if (IS_P1_LOGI)
{
std::string strInfo("");
strInfo += base::StringPrintf("Cam::%d ", getOpenId());
//
strInfo += base::StringPrintf(
"Param["
"N:m%d,p%d,q%d,t%d,b%d,i%d,r%d,w%d,v%" PRId64
"_"
"B:p%d,b%d,t%d,h%d,u%d,e%d,l%d,v%d] ",
// Param-iNt/eNum
rParams.pipeMode /*m*/, rParams.pipeBit /*p*/,
rParams.resizeQuality /*q*/, rParams.tgNum /*t*/,
rParams.burstNum /*b*/, rParams.initRequest /*i*/,
rParams.receiveMode /*r*/, rParams.rawDefType /*w*/,
rParams.packedEisInfo /*v*/ /*EisInfo::getMode(mPackedEisInfo)*/,
// Param-Bool
rParams.rawProcessed /*p*/, rParams.disableFrontalBinning /*b*/,
rParams.disableDynamicTwin /*t*/, rParams.disableHLR /*h*/,
rParams.enableUNI /*u*/, rParams.enableEIS /*e*/,
rParams.enableLCS /*l*/, rParams.forceSetEIS /*v*/);
//
strInfo += base::StringPrintf(
"S(%d,%d,%d,%d,x%x,%dx%d) ", mSensorParams.mode, mSensorParams.fps,
mSensorParams.pixelMode, mSensorParams.vhdrMode, mSensorFormatOrder,
mSensorParams.size.w, mSensorParams.size.h);
strInfo += base::StringPrintf("R(0x%x-%d-%d,%d-%d-%d,%d-0x%x) ", mRawFormat,
mRawStride, mRawLength, mRawPostProcSupport,
mRawProcessed, mRawSetDefType, mRawDefType,
mRawOption);
strInfo +=
base::StringPrintf("D(b%d,t%d,h%d) ", mDisableFrontalBinning /*b*/,
mDisableDynamicTwin /*t*/, mDisableHLR /*h*/);
strInfo +=
base::StringPrintf("E(l%d,r%d,u%d,c%d,f%d) ", mEnableLCSO /*l*/,
mEnableRSSO /*r*/, mEnableUniForcedOn /*u*/,
mEnableCaptureFlow /*c*/, mEnableFrameSync /*f*/);
strInfo += base::StringPrintf(
"M(m0x%x,p0x%x,q%d,t%d,b%d,d%d,r%d,i%d", mPipeMode /*m*/,
mPipeBit /*p*/, mResizeQuality /*q*/, mTgNum /*t*/, mBurstNum /*b*/,
mDepthNum /*d*/, mReceiveMode /*r*/, mInitReqSet /*i*/
/*v*/ /*EisInfo::getMode(mPackedEisInfo)*/);
strInfo += base::StringPrintf("Dm(%d) ", mpDeliverMgr->runningGet());
strInfo += base::StringPrintf("Rc(%p) ", mspResConCtrl.get());
strInfo += base::StringPrintf("Sh(%p) ", mspSyncHelper.get());
strInfo += base::StringPrintf(
"Pool(IMG%p,RRZ%p,LCS%p,RSS%p) ",
(mpStreamPool_full != NULL) ? (mpStreamPool_full.get()) : (NULL),
(mpStreamPool_resizer != NULL) ? (mpStreamPool_resizer.get()) : (NULL),
(mpStreamPool_lcso != NULL) ? (mpStreamPool_lcso.get()) : (NULL),
(mpStreamPool_rsso != NULL) ? (mpStreamPool_rsso.get()) : (NULL));
strInfo += base::StringPrintf(
"Meta%s_%d:%#" PRIx64 " Meta%s_%d:%#" PRIx64
" "
"Meta%s_%d:%#" PRIx64 " Meta%s_%d:%#" PRIx64 " ",
maStreamMetaName[STREAM_META_IN_APP], STREAM_META_IN_APP,
(mvStreamMeta[STREAM_META_IN_APP] == nullptr)
? (StreamId_T)(-1)
: mvStreamMeta[STREAM_META_IN_APP]->getStreamId(),
maStreamMetaName[STREAM_META_IN_HAL], STREAM_META_IN_HAL,
(mvStreamMeta[STREAM_META_IN_HAL] == nullptr)
? (StreamId_T)(-1)
: mvStreamMeta[STREAM_META_IN_HAL]->getStreamId(),
maStreamMetaName[STREAM_META_OUT_APP], STREAM_META_OUT_APP,
(mvStreamMeta[STREAM_META_OUT_APP] == nullptr)
? (StreamId_T)(-1)
: mvStreamMeta[STREAM_META_OUT_APP]->getStreamId(),
maStreamMetaName[STREAM_META_OUT_HAL], STREAM_META_OUT_HAL,
(mvStreamMeta[STREAM_META_OUT_HAL] == nullptr)
? (StreamId_T)(-1)
: mvStreamMeta[STREAM_META_OUT_HAL]->getStreamId());
//
for (int i = STREAM_ITEM_START; i < STREAM_IMG_NUM; i++) {
if (mvStreamImg[i] != nullptr) {
strInfo += base::StringPrintf(
"Img%s_%d:%#" PRIx64 "(%dx%d)[0x%x] ", (maStreamImgName[i]), i,
mvStreamImg[i]->getStreamId(), mvStreamImg[i]->getImgSize().w,
mvStreamImg[i]->getImgSize().h, mvStreamImg[i]->getImgFormat());
}
}
//
strInfo += base::StringPrintf(
"Meta(APP:%d=%d,HAL:%d=%d) ", rParams.cfgAppMeta.count(),
mCfgAppMeta.count(), rParams.cfgHalMeta.count(), mCfgHalMeta.count());
//
if (mvStreamImg[STREAM_IMG_OUT_RESIZE] != nullptr) {
strInfo += base::StringPrintf(
"RR(%d) ", getResizeMaxRatio(
mvStreamImg[STREAM_IMG_OUT_RESIZE]->getImgFormat()));
}
//
strInfo += base::StringPrintf("AA(%d,%d-%dx%d) ", mActiveArray.p.x,
mActiveArray.p.y, mActiveArray.s.w,
mActiveArray.s.h);
//
MY_LOGI("%s", strInfo.c_str());
}
#endif
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::checkConstraint() {
auto pModule = getNormalPipeModule();
if (!pModule) {
MY_LOGE("getNormalPipeModule() fail");
return UNKNOWN_ERROR;
}
// check raw type
{ mRawPostProcSupport = isPostProcRawSupported(); }
if (mPipeMode == PIPE_MODE_NORMAL_SV) { // only support pure raw
mRawDefType = EPipe_PURE_RAW;
mRawOption = (1 << EPipe_PURE_RAW);
if (mRawSetDefType == RAW_DEF_TYPE_PROCESSED_RAW) {
MY_LOGE(
"INVALID Raw-Default-Type option, "
"P1Node::ConfigParams::PipeMode(%d) is PIPE_MODE_NORMAL_SV - "
"it will reject the P1Node::ConfigParams::rawDefType(%d) "
"A.K.A. RAW_DEF_TYPE_PROCESSED_RAW",
mPipeMode, mRawSetDefType);
return INVALID_OPERATION;
}
if (mRawProcessed == MTRUE) {
MY_LOGE(
"INVALID Raw-Processed option, "
"P1Node::ConfigParams::PipeMode(%d) is PIPE_MODE_NORMAL_SV - "
"it will reject the P1Node::ConfigParams::rawProcessed(%d) ",
mPipeMode, mRawProcessed);
return INVALID_OPERATION;
}
} else if (mRawPostProcSupport) {
mRawDefType = EPipe_PURE_RAW;
mRawOption = (1 << EPipe_PURE_RAW);
if (mRawProcessed == MTRUE) {
// DualPD, raw type will be selected by driver
mRawDefType = EPipe_PROCESSED_RAW;
mRawOption |= (1 << EPipe_PROCESSED_RAW);
}
if (mRawSetDefType == RAW_DEF_TYPE_AUTO) {
// by previous decision
} else if (mRawSetDefType == RAW_DEF_TYPE_PURE_RAW) {
mRawDefType = EPipe_PURE_RAW; // accepted
} else if (mRawSetDefType == RAW_DEF_TYPE_PROCESSED_RAW) {
if (mRawProcessed == MTRUE) {
mRawDefType = EPipe_PROCESSED_RAW; // accepted
} else {
MY_LOGE(
"INVALID Raw-Default-Type option, "
"P1Node::ConfigParams::rawProcessed(%d) not enabled - "
"it will reject the P1Node::ConfigParams::rawDefType(%d) "
"A.K.A. RAW_DEF_TYPE_PROCESSED_RAW",
mRawProcessed, mRawSetDefType);
return INVALID_OPERATION;
}
} else {
MY_LOGE(
"INVALID Raw-Default-Type option, "
"P1Node::ConfigParams::rawProcessed(%d) - "
"P1Node::ConfigParams::rawDefType(%d) "
"UNKNOWN type",
mRawProcessed, mRawSetDefType);
return INVALID_OPERATION;
}
} else { // i.e. the platform without HW PostProc raw support
// ignore mRawProcessed value
mRawOption = (1 << EPipe_PURE_RAW) | (1 << EPipe_PROCESSED_RAW);
if (mRawSetDefType == RAW_DEF_TYPE_AUTO ||
mRawSetDefType == RAW_DEF_TYPE_PROCESSED_RAW) {
mRawDefType = EPipe_PROCESSED_RAW; // accepted
} else if (mRawSetDefType == RAW_DEF_TYPE_PURE_RAW) {
mRawDefType = EPipe_PURE_RAW;
MY_LOGW(
"WARNING Raw-Default-Type option, "
"use default-pure-raw without post-proc-raw-support - "
"P1Node::ConfigParams::rawDefType(%d)",
mRawSetDefType);
// return INVALID_OPERATION;
} else {
MY_LOGE(
"INVALID Raw-Default-Type option, "
"P1Node::ConfigParams::rawDefType(%d) "
"UNKNOWN type",
mRawSetDefType);
return INVALID_OPERATION;
}
}
//
// check Burst Mode
if (mBurstNum > 1) {
MBOOL ret = MFALSE;
sCAM_QUERY_BURST_NUM res;
res.QueryOutput = 0x0;
ret = pModule->query(ENPipeQueryCmd_BURST_NUM, (MUINTPTR)(&res));
if (!ret) {
MY_LOGE("[Cam::%d] Cannot query ENPipeQueryCmd_BURST_NUM", getOpenId());
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return BAD_VALUE;
#endif
} else if ((res.QueryOutput & (0x1 << mBurstNum)) == 0x0) {
MY_LOGE(
"[Cam::%d] ENPipeQueryCmd_BURST_NUM - support (0x%X) ,"
" but BurstNum set as (0x%X)",
getOpenId(), res.QueryOutput, mBurstNum);
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return INVALID_OPERATION;
#endif
}
}
//
// check Raw Pattern
mCfg.mPattern = eCAM_NORMAL;
{
if (mSensorParams.vhdrMode == SENSOR_VHDR_MODE_ZVHDR) {
// ZVHDR Mode, pass ZVHDR relative enum to P1 driver
mCfg.mPattern = (eCAM_ZVHDR);
} else if (mSensorParams.vhdrMode == SENSOR_VHDR_MODE_IVHDR) {
// IVHDR Mode, pass IVHDR relative enum to P1 driver
mCfg.mPattern = (eCAM_IVHDR);
} else {
mCfg.mPattern = (eCAM_NORMAL); // EPipe_Normal
}
}
if (mCfg.mPattern != eCAM_NORMAL) {
MBOOL ret = MFALSE;
sCAM_QUERY_SUPPORT_PATTERN res;
res.QueryOutput = 0x0;
ret = pModule->query(ENPipeQueryCmd_SUPPORT_PATTERN, (MUINTPTR)(&res));
if (!ret) {
MY_LOGE("[Cam::%d] Cannot query ENPipeQueryCmd_SUPPORT_PATTERN",
getOpenId());
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return BAD_VALUE;
#endif
} else if ((res.QueryOutput & (0x1 << mCfg.mPattern)) == 0x0) {
MY_LOGE(
"[Cam::%d] ENPipeQueryCmd_IQ_LEVEL - support (0x%X) ,"
" but Pattern set as (0x%X) - by "
" VhdrMode(%d)",
getOpenId(), res.QueryOutput, mCfg.mPattern, mSensorParams.vhdrMode);
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return INVALID_OPERATION;
#endif
}
}
//
// check IQ Level
mCfg.mQualityLv = eCamIQ_MAX;
{
switch (mResizeQuality) {
case RESIZE_QUALITY_H:
mCfg.mQualityLv = eCamIQ_H;
break;
case RESIZE_QUALITY_L:
mCfg.mQualityLv = eCamIQ_L;
break;
default:
break;
}
}
if (mCfg.mQualityLv != eCamIQ_MAX) {
MBOOL ret = MFALSE;
sCAM_QUERY_IQ_LEVEL res;
res.QueryOutput = MFALSE;
ret = pModule->query(ENPipeQueryCmd_IQ_LEVEL, (MUINTPTR)(&res));
if (!ret) {
MY_LOGE("[Cam::%d] Cannot query ENPipeQueryCmd_IQ_LEVEL", getOpenId());
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return BAD_VALUE;
#endif
} else if (res.QueryOutput == MFALSE) {
MY_LOGE(
"[Cam::%d] ENPipeQueryCmd_IQ_LEVEL - not support ,"
" but Quality-Level set as (%d)",
getOpenId(), mCfg.mQualityLv);
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return INVALID_OPERATION;
#endif
}
}
//
// check Dynamic Twin
mCfg.mSupportDynamicTwin = MFALSE;
{
MBOOL ret = MFALSE;
sCAM_QUERY_D_Twin res;
res.QueryOutput = MFALSE;
ret = pModule->query(ENPipeQueryCmd_D_Twin, (MUINTPTR)(&res));
if (!ret) {
MY_LOGE("[Cam::%d] Cannot query ENPipeQueryCmd_D_Twin", getOpenId());
#if USING_DRV_QUERY_CAPABILITY_EXP_SKIP
MY_LOGW("USING_DRV_QUERY_CAPABILITY_EXP_SKIP go-on");
#else
return BAD_VALUE;
#endif
}
mCfg.mSupportDynamicTwin = res.QueryOutput;
}
//
mIsLegacyStandbyMode = (mCfg.mSupportDynamicTwin) ? MFALSE : MTRUE;
mIsDynamicTwinEn =
(mCfg.mSupportDynamicTwin && (!mDisableDynamicTwin)) ? MTRUE : MFALSE;
//
// check Sensor-TG Number
mCfg.mSensorNum = E_1_SEN;
switch (mTgNum) {
case 0:
case 1:
mCfg.mSensorNum = E_1_SEN;
break;
case 2:
default:
mCfg.mSensorNum = E_2_SEN;
break;
}
//
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::config(ConfigParams const& rParams) {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:config");
std::lock_guard<std::mutex> _l(mPublicLock);
if (getActive()) {
MY_LOGD("active=%d", getActive());
onHandleFlush(MFALSE);
}
// (1) check
if (mpTimingCheckerMgr != nullptr) {
mpTimingCheckerMgr->setEnable(MTRUE);
}
//
MERROR err = check_config(rParams);
if (err != OK) {
MY_LOGE("Config Param - Check fail (%d)", err);
return err;
}
// (2) configure hardware
if (mpConCtrl != nullptr &&
(!EN_INIT_REQ_RUN)) { // init-request, no aid-start
mpConCtrl->setAidUsage(MTRUE);
}
//
if (mpTimingCheckerMgr != nullptr) {
mpTimingCheckerMgr->waitReady();
}
//
mpTaskCtrl->reset();
//
err = hardwareOps_start();
if ((!(EN_START_CAP || EN_INIT_REQ_RUN)) || (err != OK)) {
if (mpConCtrl != nullptr && mpConCtrl->getAidUsage() == MTRUE) {
mpConCtrl->cleanAidStage();
}
if (mpTimingCheckerMgr != nullptr) {
mpTimingCheckerMgr->setEnable(MFALSE);
}
}
if (err != OK) {
MY_LOGE("Config Param - HW start fail (%d)", err);
return err;
}
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::fetchJob(P1QueJob* rOutJob) {
if (CC_UNLIKELY(mpTaskCtrl == nullptr || mpTaskCollector == nullptr)) {
return BAD_VALUE;
}
rOutJob->clear();
MINT cnt = 0;
mpTaskCtrl->sessionLock();
cnt = mpTaskCollector->requireJob(rOutJob);
mTagList.set(cnt);
if (rOutJob->empty()) {
MY_LOGI("using-dummy-request");
if (2 <= mLogLevelI) {
mpTaskCollector->dumpRoll();
}
//
P1TaskCollector dummyCollector(mpTaskCtrl);
for (int i = 0; i < mBurstNum; i++) {
P1QueAct newAct;
dummyCollector.enrollAct(&newAct);
createAction(&newAct, nullptr, REQ_TYPE_DUMMY);
dummyCollector.verifyAct(&newAct);
}
dummyCollector.requireJob(rOutJob);
}
mpTaskCtrl->sessionUnLock();
if (!rOutJob->ready()) {
MY_LOGE("job-not-ready");
mpTaskCtrl->dumpActPool();
return BAD_VALUE;
}
return OK;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setRequest(MBOOL initial) {
FUNCTION_IN;
//
std::lock_guard<std::mutex> _ll(mFrameSetLock);
if (CC_UNLIKELY(!initial && !mFrameSetAlready)) {
MY_LOGI("frame set not init complete");
return;
}
if (CC_UNLIKELY(!getActive())) {
MY_LOGI("not-active-return");
return;
}
//
P1QueJob job(mBurstNum);
//
{
if (OK != fetchJob(&job)) {
MY_LOGE("job-fetch-fail");
return;
}
if (mpHwStateCtrl != nullptr && mpHwStateCtrl->isLegacyStandby() &&
mpHwStateCtrl->checkReceiveRestreaming()) {
P1Act pAct = GET_ACT_PTR(pAct, job.edit(0), RET_VOID);
if (pAct->ctrlSensorStatus == SENSOR_STATUS_CTRL_STREAMING) {
mpHwStateCtrl->checkRestreamingNum(pAct->getNum());
}
}
}
//
if (!initial) {
beckonRequest();
}
//
if (IS_BURST_OFF && // exclude burst mode
(job.size() >= 1)) { // check control callback
attemptCtrlSetting(&(job.edit(0)));
}
//
#if USING_CTRL_3A_LIST
List<NS3Av3::MetaSet_T> ctrlList;
generateCtrlList(&ctrlList, &job);
MY_LOGD("CtrlList[%zu]", ctrlList.size());
#else
std::vector<NS3Av3::MetaSet_T*> ctrlQueue;
ctrlQueue.clear();
ctrlQueue.reserve(job.size());
generateCtrlQueue(&ctrlQueue, &job);
MY_LOGD("CtrlQueue[%zu]", ctrlQueue.size());
#endif
//
mLastSetNum = job.getLastNum();
mTagSet.set(mLastSetNum);
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
mRequestQueue.push_back(job);
}
P1QueAct* qAct = (job.ready()) ? (job.getLastAct()) : (nullptr);
if (qAct == nullptr) {
MY_LOGW("job-not-ready [%zu] < [%d]", job.size(), job.getMax());
return;
}
P1Act pAct = GET_ACT_PTR(pAct, (*qAct), RET_VOID);
#if SUPPORT_3A
if (mp3A) {
MINT32 p_key = qAct->id();
MINT32 m_num = pAct->magicNum;
MINT32 f_num = pAct->frmNum;
MINT32 r_num = pAct->reqNum;
if (initial) {
mLogInfo.setMemo(LogInfo::CP_START_SET_BGN, LogInfo::START_SET_GENERAL,
m_num);
}
mLogInfo.setMemo(LogInfo::CP_SET_BGN, p_key, m_num, f_num, r_num);
P1_TRACE_F_BEGIN(SLG_I, "P1:3A-set|Pkey:%d Mnum:%d Fnum:%d Rnum:%d", p_key,
m_num, f_num, r_num);
MY_LOGD("mp3A->set[%d](%d) +++", p_key, m_num);
#if USING_CTRL_3A_LIST
mp3A->set(ctrlList);
#else
mp3A->set(ctrlQueue);
#endif
MY_LOGD("mp3A->set[%d](%d) ---", p_key, m_num);
P1_TRACE_C_END(SLG_I); // "P1:3A-set"
mLogInfo.setMemo(LogInfo::CP_SET_END, p_key, m_num, f_num, r_num);
if (initial) {
mLogInfo.setMemo(LogInfo::CP_START_SET_END, LogInfo::START_SET_GENERAL,
m_num);
}
mFrameSetAlready = MTRUE;
}
if (1 <= mLogLevelI) {
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::SET_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
pAct->magicNum, pAct->sofIdx, pAct->frmNum, pAct->reqNum,
pAct->flushSet);
std::string str("");
MINT32 num = 0;
size_t idx = 0;
#if USING_CTRL_3A_LIST
size_t size = ctrlList.size();
List<NS3Av3::MetaSet_T>::iterator it = ctrlList.begin();
for (; it != ctrlList.end(); it++) {
num = it->MagicNum;
if ((idx > 0) && (idx % mBurstNum == 0)) {
str += base::StringPrintf(", ");
}
str += base::StringPrintf("%d ", num);
idx++;
}
#else
size_t size = ctrlQueue.size();
std::vector<NS3Av3::MetaSet_T*>::iterator it = ctrlQueue.begin();
for (; it != ctrlQueue.end(); it++) {
num = ((*it) != nullptr) ? ((*it)->MagicNum) : (0);
str += base::StringPrintf("%d ", num);
idx++;
}
#endif
P1_LOGI(1, "[P1::SET]" P1INFO_ACT_STR " Num[%d] Ctrl[%zu]=[ %s]",
P1INFO_ACT_VAR(*pAct), num, size, str.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::SET_LOG"
}
#endif
FUNCTION_OUT;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::acceptRequest(std::shared_ptr<IPipelineFrame> pFrame,
MUINT32* rRevResult) {
FUNCTION_IN;
*rRevResult = (MUINT32)REQ_REV_RES_ACCEPT_AVAILABLE;
#if (USING_DRV_IO_PIPE_EVENT)
{
pthread_rwlock_rdlock(&mIoPipeEvtStateLock);
if (mIoPipeEvtState != IO_PIPE_EVT_STATE_NONE) {
*rRevResult = (MUINT32)REQ_REV_RES_REJECT_IO_PIPE_EVT;
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
return MFALSE;
}
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
#endif
if ((!getReady()) || (!mFirstReceived)) {
return MTRUE;
}
// check-bypass-request
if (pFrame != nullptr) {
MBOOL isBypass = pFrame->IsReprocessFrame();
if (isBypass) {
*rRevResult = (MUINT32)REQ_REV_RES_ACCEPT_BYPASS;
MY_LOGI("Num[F:%d,R:%d] - BypassFrame", P1GET_FRM_NUM(pFrame),
P1GET_REQ_NUM(pFrame));
return MTRUE;
}
}
//
MINT cnt = 0;
MBOOL isAccept = checkReqCnt(&cnt);
MY_LOGI("Num[F:%d,R:%d] - Cnt(%d) Accept(%d)", P1GET_FRM_NUM(pFrame),
P1GET_REQ_NUM(pFrame), cnt, isAccept);
if (!isAccept) {
*rRevResult = (MUINT32)REQ_REV_RES_REJECT_NOT_AVAILABLE;
}
FUNCTION_OUT;
return isAccept;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::beckonRequest() {
FUNCTION_IN;
MINT cnt = 0;
if (CC_LIKELY(checkReqCnt(&cnt))) {
MINT32 frmNum = P1_FRM_NUM_NULL;
MINT32 reqNum = P1_REQ_NUM_NULL;
MINT32 cnt = lastFrameRequestInfoNotice(&frmNum, &reqNum, 1);
MBOOL exeCb = MTRUE;
{
std::lock_guard<std::mutex> _l(mPipelineCbLock);
std::shared_ptr<INodeCallbackToPipeline> spCb = mwpPipelineCb.lock();
if (CC_LIKELY(spCb != nullptr)) {
MY_LOGI("Pipeline_CB (F:%d,R:%d) CbButNotQueCnt:%d +++", frmNum, reqNum,
cnt);
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_REQ_NOTIFY_BGN,
LogInfo::CP_REQ_NOTIFY_END, frmNum, reqNum, cnt);
INodeCallbackToPipeline::CallBackParams param;
param.nodeId = getNodeId();
param.lastFrameNum = frmNum;
spCb->onCallback(param);
MY_LOGI("Pipeline_CB (F:%d,R:%d) CbButNotQueCnt:%d ---", frmNum, reqNum,
cnt);
} else {
exeCb = MFALSE;
}
}
if (CC_UNLIKELY(!exeCb)) {
cnt = lastFrameRequestInfoNotice(&frmNum, &reqNum, (-1)); // reset count
MY_LOGI("Pipeline_CB not exist (F:%d,R:%d) CbButNotQueCnt:%d", frmNum,
reqNum, cnt);
}
return MTRUE;
} else {
MY_LOGI("not-callback - cnt(%d)", cnt);
}
FUNCTION_OUT;
return MFALSE;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::checkReqCnt(MINT32* cnt) {
FUNCTION_IN;
if (CC_UNLIKELY(mpTaskCtrl == nullptr || mpTaskCollector == nullptr)) {
MY_LOGE("Task Controller or Collector not acceptable");
return MFALSE;
}
//
MINT depth = mDepthNum;
MINT cnt_num = depth * mBurstNum;
MINT que_num = 0;
MBOOL isAccept = MTRUE;
mpTaskCtrl->sessionLock();
if ((que_num = mpTaskCollector->remainder()) >= cnt_num) {
isAccept = MFALSE;
}
mpTaskCtrl->sessionUnLock();
MY_LOGI("Que(%d) < Cnt(%d)=(%d*%d) : Accept(%d)", que_num, cnt_num, depth,
mBurstNum, isAccept);
*cnt = que_num;
FUNCTION_OUT;
return isAccept;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::setNodeCallBack(std::weak_ptr<INodeCallbackToPipeline> pCallback) {
std::lock_guard<std::mutex> _l(mPipelineCbLock);
MY_LOGI("PipelineNodeCallBack=%d", pCallback.expired());
mwpPipelineCb = pCallback;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::queue(std::shared_ptr<IPipelineFrame> pFrame) {
FUNCTION_IN;
mLogInfo.setMemo(LogInfo::CP_REQ_ARRIVE, P1GET_FRM_NUM(pFrame),
P1GET_REQ_NUM(pFrame));
std::lock_guard<std::mutex> _l(mPublicLock);
//
MUINT32 revResult = (MUINT32)REQ_REV_RES_UNKNOWN;
if (!acceptRequest(pFrame, &revResult)) {
mLogInfo.setMemo(LogInfo::CP_REQ_ACCEPT, P1GET_FRM_NUM(pFrame),
P1GET_REQ_NUM(pFrame), MFALSE, revResult);
FUNCTION_OUT;
return FAILED_TRANSACTION;
}
mLogInfo.setMemo(LogInfo::CP_REQ_ACCEPT, P1GET_FRM_NUM(pFrame),
P1GET_REQ_NUM(pFrame), MTRUE, revResult);
//
lastFrameRequestInfoUpdate(P1GET_FRM_NUM(pFrame), P1GET_REQ_NUM(pFrame));
//
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_REQ_REV, LogInfo::CP_REQ_RET,
P1GET_FRM_NUM(pFrame), P1GET_REQ_NUM(pFrame));
P1_TRACE_F_BEGIN(SLG_I, "P1:queue|Fnum:%d Rnum:%d", P1GET_FRM_NUM(pFrame),
P1GET_REQ_NUM(pFrame));
MY_LOGD("active=%d", getActive());
//
MBOOL isStartSet = MFALSE;
int32_t currReqCnt = 0;
currReqCnt = std::atomic_fetch_add_explicit(&mInFlightRequestCnt, 1,
std::memory_order_release);
P1_TRACE_INT(SLG_B, "P1_request_cnt",
std::atomic_load_explicit(&mInFlightRequestCnt,
std::memory_order_acquire));
MY_LOGD("InFlightRequestCount++ (%d) => (%d)", currReqCnt,
std::atomic_load_explicit(&mInFlightRequestCnt,
std::memory_order_acquire));
//
if (EN_INIT_REQ_RUN) {
if (mInitReqCnt <= (mInitReqNum + mBurstNum)) {
mInitReqCnt++;
}
}
//
MINT cnt = 0;
if (EN_INIT_REQ_RUN && (mInitReqCnt < mInitReqNum)) {
P1QueAct newAct;
mpTaskCtrl->sessionLock();
mpTaskCollector->enrollAct(&newAct);
createAction(&newAct, pFrame);
cnt = mpTaskCollector->verifyAct(&newAct);
mTagList.set(cnt);
mpTaskCtrl->sessionUnLock();
// else if (mInitReqCnt == mInitReqNum) go-on the following flow
} else { // for REV_MODE_NORMAL/REV_MODE_CONSERVATIVE
#if 1 // restart while queue ready
if (!getActive()) {
MY_LOGI("HW start +++");
if (mpConCtrl != nullptr &&
(!EN_INIT_REQ_RUN)) { // init-request, no aid-start
mpConCtrl->setAidUsage(MTRUE);
}
MERROR err = hardwareOps_start();
if ((!(EN_START_CAP || EN_INIT_REQ_RUN)) || (err != OK)) {
if (mpConCtrl != nullptr && mpConCtrl->getAidUsage() == MTRUE) {
mpConCtrl->cleanAidStage();
}
if (mpTimingCheckerMgr != nullptr) {
mpTimingCheckerMgr->setEnable(MFALSE);
}
}
if (err != OK) {
MY_LOGE("Queue Frame - HW start fail (%d)", err);
P1_TRACE_C_END(SLG_I); // "P1:queue"
return err;
}
MY_LOGI("HW start ---");
}
#endif
if (mpTaskCtrl == nullptr || mpTaskCollector == nullptr) {
MY_LOGE("Task Controller or Collector not ready");
P1_TRACE_C_END(SLG_I); // "P1:queue"
return BAD_VALUE;
}
P1QueAct newAct;
P1QueAct setAct;
NS3Av3::MetaSet_T preSet;
P1Act pSetAct = nullptr;
mpTaskCtrl->sessionLock();
//
mpTaskCollector->enrollAct(&newAct);
createAction(&newAct, pFrame);
cnt = mpTaskCollector->verifyAct(&newAct);
//
P1Act pAct = GET_ACT_PTR(pAct, newAct, BAD_VALUE);
if (pAct->ctrlSensorStatus == SENSOR_STATUS_CTRL_STANDBY) {
MY_LOGI("receive-standby-control");
} else if (pAct->ctrlSensorStatus == SENSOR_STATUS_CTRL_STREAMING) {
MY_LOGI("receive-streaming-control");
hardwareOps_streaming();
}
//
if ((mFirstReceived) && (pAct->reqType == REQ_TYPE_YUV)) {
P1QueAct paddingAct;
mpTaskCollector->enrollAct(&paddingAct);
createAction(&paddingAct, nullptr, REQ_TYPE_PADDING);
cnt = mpTaskCollector->verifyAct(&paddingAct);
MY_LOGI("add-padding-for-YUV-stall Id:%d Num:%d Type:%d", paddingAct.id(),
paddingAct.getNum(), paddingAct.getType());
}
mTagList.set(cnt);
if (IS_BURST_OFF && mFirstReceived && pAct->getType() == ACT_TYPE_NORMAL) {
mpTaskCollector->queryAct(&setAct);
pSetAct = setAct.ptr(); // GET_ACT_PTR(pSetAct, firstAct, BAD_VALUE);
if (pSetAct !=
nullptr) { // for the consideration of session locking peroid with 3A
// CB and preset, duplicate this MetaSet
preSet = pSetAct->metaSet;
} else {
MY_LOGW("no act ready to PreSet");
}
}
mpTaskCtrl->sessionUnLock();
if (mp3A && IS_BURST_OFF && mFirstReceived && (pSetAct != nullptr)) {
if (preSet.PreSetKey <= P1_PRESET_KEY_NULL) {
MY_LOGW("Pre-Set-Meta NOT ready (%d)", preSet.PreSetKey);
} else {
if (preSet.Dummy > 0) {
MY_LOGI("Pre-Set-Meta is dummy (%d)", preSet.Dummy);
}
MINT32 f_Num = pSetAct->frmNum;
MINT32 r_Num = pSetAct->reqNum;
std::vector<NS3Av3::MetaSet_T*> ctrlQueue; // only insert once
ctrlQueue.push_back(&preSet);
if (mMetaLogOp > 0 && ctrlQueue.size() > 0) {
P1_LOG_META(*pSetAct, &(ctrlQueue[0]->appMeta), "3A.PreSet-APP");
P1_LOG_META(*pSetAct, &(ctrlQueue[0]->halMeta), "3A.PreSet-HAL");
}
mLogInfo.setMemo(LogInfo::CP_PRE_SET_BGN, preSet.PreSetKey,
preSet.Dummy, f_Num, r_Num);
P1_TRACE_F_BEGIN(SLG_I, "P1:3A-preset|Pkey:%d Fnum:%d Rnum:%d",
preSet.PreSetKey, f_Num, r_Num);
MY_LOGD("mp3A->preset[%d] +++", preSet.PreSetKey);
mp3A->preset(ctrlQueue);
MY_LOGD("mp3A->preset[%d] ---", preSet.PreSetKey);
P1_TRACE_C_END(SLG_I); // "P1:3A-preset"
mLogInfo.setMemo(LogInfo::CP_PRE_SET_END, preSet.PreSetKey,
preSet.Dummy, f_Num, r_Num);
if (1 <= mLogLevelI) { // P1_LOGI(1)
pAct->msg += base::StringPrintf(
" | [PreSet][Key:%d] Num(%d) "
"Dummy(%d) MetaCnt[APP:%d,HAL:%d]",
preSet.PreSetKey, preSet.MagicNum, preSet.Dummy,
preSet.appMeta.count(), preSet.halMeta.count());
}
}
}
//
if (!mFirstReceived) {
if (cnt >= mBurstNum) {
mFirstReceived = MTRUE;
isStartSet = MTRUE;
} // else not-start and not-wait, then try to receive more requests
}
//
if (1 <= mLogLevelI) { // P1_LOGI(1)
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::REQ_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
pAct->magicNum, pAct->sofIdx, pAct->frmNum, pAct->reqNum,
pAct->flushSet);
pAct->msg += base::StringPrintf(
" | [Rev:%d] depth(%d) burst(%d) "
"Que[%d]",
mReceiveMode, mDepthNum, mBurstNum, mpTaskCollector->remainder());
P1_LOGI(1, "%s", pAct->msg.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::REQ_LOG"
}
}
//
#if 1 // SET_REQUEST_BEFORE_FIRST_DONE
if (isStartSet) {
if (EN_INIT_REQ_RUN && (!getReady())) {
MY_LOGI("HW request +++");
MERROR err = hardwareOps_request();
if (mpConCtrl != nullptr && mpConCtrl->getAidUsage() == MTRUE) {
mpConCtrl->cleanAidStage();
}
if (mpTimingCheckerMgr != nullptr) {
mpTimingCheckerMgr->setEnable(MFALSE);
}
if (err != OK) {
MY_LOGE("Queue Frame - HW request fail (%d)", err);
P1_TRACE_C_END(SLG_I); // "P1:queue"
return err;
}
MY_LOGI("HW request ---");
} else if (EN_START_CAP && (!getReady())) {
MY_LOGI("HW capture +++");
MERROR err = hardwareOps_capture();
if (mpConCtrl != nullptr && mpConCtrl->getAidUsage() == MTRUE) {
mpConCtrl->cleanAidStage();
}
if (mpTimingCheckerMgr != nullptr) {
mpTimingCheckerMgr->setEnable(MFALSE);
}
if (err != OK) {
MY_LOGE("Queue Frame - HW capture fail (%d)", err);
P1_TRACE_C_END(SLG_I); // "P1:queue"
return err;
}
MY_LOGI("HW capture ---");
} else {
// onRequestFrameSet(MTRUE);
setRequest(MTRUE);
}
}
#endif
//
if (mpHwStateCtrl != nullptr) {
mpHwStateCtrl->checkRequest();
}
//
inflightMonitoring(IMT_REQ);
//
P1_TRACE_C_END(SLG_I); // "P1:queue"
//
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::kick() {
FUNCTION_IN;
//
if ((!getActive()) || (!getReady())) {
MY_LOGI("return OK - active(%d) ready(%d)", getActive(), getReady());
return OK;
}
if (IS_BURST_ON) {
MY_LOGI("return OK - BurstNum(%d)", mBurstNum);
return OK;
}
if (CC_UNLIKELY(mpTaskCtrl == nullptr || mpTaskCollector == nullptr)) {
return BAD_VALUE;
}
//
{
mpTaskCtrl->sessionLock();
MINT cnt = mpTaskCollector->remainder();
P1_TRACE_F_BEGIN(SLG_E, "P1:kick(%d)", cnt);
MY_LOGI("cnt(%d)", cnt);
while (cnt > 0) {
P1QueAct qAct;
cnt = mpTaskCollector->requireAct(&qAct);
if (qAct.id() > P1ACT_ID_NULL) {
P1Act act = GET_ACT_PTR(act, qAct, BAD_VALUE);
if (act->ctrlSensorStatus != SENSOR_STATUS_CTRL_NONE) {
MY_LOGI("Cannot KICK Standby Ctrl Request - " P1INFO_ACT_STR,
P1INFO_ACT_VAR(*act));
} else {
MY_LOGI("KICK - " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
onReturnFrame(&qAct, FLUSH_KICK, MTRUE);
/* DO NOT use this P1QueAct after onReturnFrame() */
}
}
}
mTagList.set(cnt);
P1_TRACE_C_END(SLG_E); // "P1:kick"
mpTaskCtrl->sessionUnLock();
}
//
FUNCTION_OUT;
//
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::flush(std::shared_ptr<IPipelineFrame> const& pFrame) {
return BaseNode::flush(pFrame);
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::flush() {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:flush");
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_API_FLUSH_BGN,
LogInfo::CP_API_FLUSH_END);
kick();
std::lock_guard<std::mutex> _l(mPublicLock);
onHandleFlush(MFALSE);
// wait until deque thread going back to waiting state;
// in case next node receives queue() after flush()
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
void P1NodeImp::requestExit() {
FUNCTION_IN;
// let deque thread back
{
std::lock_guard<std::mutex> _l(mThreadLock);
mExitPending = MTRUE;
mThreadCond.notify_all();
}
//
if (mThread.joinable()) {
mThread.join();
}
// let cb thread back
{
std::lock_guard<std::mutex> _l(mStartLock);
mStartCond.notify_all();
}
FUNCTION_OUT;
}
/******************************************************************************
*
******************************************************************************/
status_t P1NodeImp::readyToRun() {
MY_LOGD("readyToRun P1NodeImp thread");
//
return OK;
}
/******************************************************************************
*
******************************************************************************/
bool P1NodeImp::threadLoop() {
while (this->_threadLoop() == true) {
}
MY_LOGI("threadLoop exit");
return true;
}
/******************************************************************************
*
******************************************************************************/
bool P1NodeImp::_threadLoop() {
// check if going to leave thread
P1_TRACE_FUNC(SLG_B); // P1_TRACE_AUTO(SLG_B, "P1:threadLoop");
//
{
std::unique_lock<std::mutex> lck(mThreadLock);
if (!getActive()) {
P1_TRACE_S_BEGIN(SLG_S, "P1:wait_active");
MY_LOGD("wait active+");
mThreadCond.wait(lck);
MY_LOGD("wait active-");
P1_TRACE_C_END(SLG_S); // "P1:wait_active"
}
if (mExitPending) {
MY_LOGD("leaving active");
return false;
}
}
//
if (mpConCtrl != nullptr && mpConCtrl->getAidUsage()) {
procedureAid_start();
}
//
{
std::unique_lock<std::mutex> lck(mThreadLock);
if (getActive() && !getReady()) {
P1_TRACE_S_BEGIN(SLG_S, "P1:wait_ready");
MY_LOGD("wait ready+");
mThreadCond.wait(lck);
MY_LOGD("wait ready-");
P1_TRACE_C_END(SLG_S); // "P1:wait_ready"
}
if (mExitPending) {
MY_LOGD("leaving ready");
return false;
}
}
if (mpHwStateCtrl != nullptr) {
mpHwStateCtrl->checkThreadStandby();
}
// deque buffer, and handle frame and metadata
onProcessDequeFrame();
if (!getActive()) {
MY_LOGI_IF(getInit(), "HW stopped , exit init");
setInit(MFALSE);
}
// trigger point for the first time
{
if (getInit()) {
setInit(MFALSE);
}
}
if ((mpDeliverMgr != nullptr) && (mpDeliverMgr->runningGet())) {
onProcessDropFrame(MTRUE);
}
return true;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setActive(MBOOL active) {
std::lock_guard<std::mutex> _l(mActiveLock);
mActive = active;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::getActive(void) {
std::lock_guard<std::mutex> _l(mActiveLock);
return mActive;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setReady(MBOOL ready) {
std::lock_guard<std::mutex> _l(mReadyLock);
mReady = ready;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::getReady(void) {
std::lock_guard<std::mutex> _l(mReadyLock);
return mReady;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setInit(MBOOL init) {
std::lock_guard<std::mutex> _l(mInitLock);
mInit = init;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::getInit(void) {
std::lock_guard<std::mutex> _l(mInitLock);
return mInit;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setPowerNotify(MBOOL notify) {
std::lock_guard<std::mutex> _l(mPowerNotifyLock);
mPowerNotify = notify;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::getPowerNotify(void) {
std::lock_guard<std::mutex> _l(mPowerNotifyLock);
return mPowerNotify;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setStartState(MUINT8 state) {
std::lock_guard<std::mutex> _l(mStartStateLock);
mStartState = state;
}
/******************************************************************************
*
******************************************************************************/
MUINT8
P1NodeImp::getStartState(void) {
std::lock_guard<std::mutex> _l(mStartStateLock);
return mStartState;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setQualitySwitching(MBOOL switching) {
std::lock_guard<std::mutex> _l(mQualitySwitchLock);
mQualitySwitching = switching;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::getQualitySwitching(void) {
std::lock_guard<std::mutex> _l(mQualitySwitchLock);
return mQualitySwitching;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::setCurrentBinSize(MSize size) {
std::lock_guard<std::mutex> _l(mCurBinLock);
mCurBinSize = size;
}
/******************************************************************************
*
******************************************************************************/
MSize P1NodeImp::getCurrentBinSize(void) {
std::lock_guard<std::mutex> _l(mCurBinLock);
return mCurBinSize;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::lastFrameRequestInfoUpdate(MINT32 const frameNum,
MINT32 const requestNum) {
std::lock_guard<std::mutex> _l(mLastFrmReqNumLock);
mLastFrmNum = frameNum;
mLastReqNum = requestNum;
mLastCbCnt = 0;
return;
}
/******************************************************************************
*
******************************************************************************/
MINT32
P1NodeImp::lastFrameRequestInfoNotice(MINT32* frameNum,
MINT32* requestNum,
MINT32 const addCbCnt) {
std::lock_guard<std::mutex> _l(mLastFrmReqNumLock);
*frameNum = mLastFrmNum;
*requestNum = mLastReqNum;
if (addCbCnt != 0) {
mLastCbCnt += (addCbCnt);
}
return mLastCbCnt;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::syncHelperStart() {
std::lock_guard<std::mutex> _l(mSyncHelperLock);
if (!mSyncHelperReady) {
if (mspSyncHelper != nullptr) {
status_t res = mspSyncHelper->start(getOpenId());
if (res == OK) {
mSyncHelperReady = MTRUE;
}
}
}
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::syncHelperStop() {
std::lock_guard<std::mutex> _l(mSyncHelperLock);
if (mSyncHelperReady) {
if (mspSyncHelper != nullptr) {
status_t res = mspSyncHelper->stop(getOpenId());
if (res == OK) {
mSyncHelperReady = MFALSE;
}
}
}
return;
}
/******************************************************************************
*
******************************************************************************/
void P1NodeImp::ensureStartReady(MUINT8 infoType, MINT32 infoNum) {
std::cv_status res;
MUINT32 needRetry = P1NODE_START_READY_WAIT_CNT_MAX;
if (getActive()) {
std::unique_lock<std::mutex> lck(mStartLock);
while ((!getReady()) && (needRetry != 0) &&
((getStartState() != NSP1Node::START_STATE_READY) &&
(getStartState() >= NSP1Node::START_STATE_DRV_START))) {
res = mStartCond.wait_for(
lck, std::chrono::nanoseconds(P1NODE_START_READY_WAIT_INV_NS));
needRetry--;
MY_LOGI(
"Type(%d) Num(%d) - EnStartCap(%d) EnInitReqRun(%d) - "
"StartState(%d) WaitStatus(%d) NeedRetry(%d)",
infoType, infoNum, EN_START_CAP, EN_INIT_REQ_RUN, getStartState(),
res, needRetry);
if (!getActive()) {
MY_LOGI("Not Active");
break;
}
if (res != std::cv_status::timeout) {
MY_LOGI("Got Ready");
break;
}
}
}
if ((getActive()) && (!getReady())) {
MY_LOGE(
"Wait StartReady Timeout (%d*%d ms) - "
"Type(%d) Num(%d) - EnStartCap(%d) EnInitReqRun(%d) - "
"StartState(%d) WaitStatus(%d) NeedRetry(%d)",
P1NODE_START_READY_WAIT_CNT_MAX,
(MUINT32)(P1NODE_START_READY_WAIT_INV_NS / ONE_MS_TO_NS), infoType,
infoNum, EN_START_CAP, EN_INIT_REQ_RUN, getStartState(), res,
needRetry);
}
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::onSyncEnd() {
FUNCTION_IN;
//
{
NS3Av3::IpcPeriSensorData_T data;
if (mpAccDetector->getAcceleration(data.acceleration))
mp3A->send3ACtrl(NS3Av3::E3ACtrl_IPC_SetPeriSensorData,
reinterpret_cast<MINTPTR>(&data), 0);
}
MBOOL toSet = MFALSE;
if (mpHwStateCtrl != nullptr) {
if (mpHwStateCtrl->checkSkipSync()) {
MY_LOGI("SyncEND was paused");
return;
}
MBOOL first = mpHwStateCtrl->checkFirstSync();
MY_LOGI_IF(first, "Got first CB after re-streaming");
if (first && IS_BURST_ON) {
toSet = MTRUE;
}
}
//
{
std::lock_guard<std::mutex> _ll(mFrameSetLock);
if (!mFrameSetAlready) {
MY_LOGI("should not callback before first set");
return;
}
if (EN_START_CAP && (!getReady())) {
std::lock_guard<std::mutex> _l(mStartCaptureLock);
MY_LOGD("StartCaptureState(%d)", mStartCaptureState);
if (mStartCaptureState != START_CAP_STATE_READY) {
MY_LOGI("should not callback before capture ready (%d)",
mStartCaptureState);
return;
}
}
}
//
if (getInit()) {
MY_LOGI("sync before frame done");
}
//
if ((getActive()) && (!getReady())) {
ensureStartReady(IHal3ACb::eID_NOTIFY_VSYNC_DONE);
}
//
P1_TRACE_F_BEGIN(SLG_I, "P1:onSyncEnd|TheLastSet-Mnum:%d", mLastSetNum);
//
if (IS_BURST_OFF || toSet) {
setRequest(MFALSE);
}
//
P1_TRACE_C_END(SLG_I); // "P1:onSyncEnd"
//
FUNCTION_OUT;
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::onSyncBegin(MBOOL initial,
NS3Av3::RequestSet_T* reqSet,
MUINT32 sofIdx,
NS3Av3::CapParam_T* capParam) {
FUNCTION_IN;
if (mpHwStateCtrl != nullptr) {
if (mpHwStateCtrl->checkSkipSync()) {
MY_LOGI("SyncBGN was paused");
return;
}
MBOOL first = mpHwStateCtrl->checkFirstSync();
MY_LOGI_IF(first, "Got first CB after re-streaming");
}
//
{
std::lock_guard<std::mutex> _ll(mFrameSetLock);
if (!mFrameSetAlready) {
MY_LOGI("should not callback before first set");
return;
}
//
if (EN_START_CAP && (!getReady())) {
std::lock_guard<std::mutex> _l(mStartCaptureLock);
MY_LOGD("StartCaptureState(%d)", mStartCaptureState);
if (mStartCaptureState == START_CAP_STATE_WAIT_CB) {
if (capParam != nullptr) {
mStartCaptureType = capParam->u4CapType;
mStartCaptureIdx = sofIdx;
mStartCaptureExp = MAX(capParam->i8ExposureTime, 0);
if (reqSet != nullptr && reqSet->vNumberSet.size() > 0 &&
IS_BURST_OFF) {
mLongExp.set(reqSet->vNumberSet[0], mStartCaptureExp);
}
}
mStartCaptureState = START_CAP_STATE_READY;
mStartCaptureCond.notify_all();
MY_LOGI(
"StartCaptureReady @%d init(%d) Cap-Type(%d)-Idx(%d)"
"-Exp(%" PRId64 "ns)",
sofIdx, getInit(), mStartCaptureType, mStartCaptureIdx,
mStartCaptureExp);
return;
} else if (mStartCaptureState == START_CAP_STATE_WAIT_REQ) {
MY_LOGI("should not callback before capture set (%d)",
mStartCaptureState);
return;
}
}
}
//
if (getInit()) {
MY_LOGI("sync before frame done");
}
//
MINT32 magicNum = P1_MAGIC_NUM_NULL;
if (reqSet != nullptr && reqSet->vNumberSet.size() > 0) {
magicNum = reqSet->vNumberSet[0];
}
//
if ((getActive()) && (!getReady())) {
ensureStartReady(IHal3ACb::eID_NOTIFY_3APROC_FINISH, magicNum);
}
//
P1_TRACE_F_BEGIN(SLG_I,
"P1:onSyncBegin|"
"CB Mnum:%d SofIdx:%d Exp(ns):%" PRId64 " Type:%d",
magicNum, sofIdx, capParam->i8ExposureTime,
capParam->u4CapType);
//
// (1)
if ((!initial) && (getReady())) {
P1QueJob job(mBurstNum);
bool exist = false;
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
Que_T::iterator it = mRequestQueue.begin();
for (; it != mRequestQueue.end(); it++) {
if ((*it).getIdx() == magicNum) {
job = *it;
for (MUINT8 i = 0; i < job.size(); i++) {
P1Act act = GET_ACT_PTR(act, job.edit(i), RET_VOID);
act->sofIdx = sofIdx;
if (capParam != nullptr) {
act->capType = capParam->u4CapType;
act->frameExpDuration = MAX(capParam->i8ExposureTime, 0);
if (act->capType == NS3Av3::E_CAPTURE_HIGH_QUALITY_CAPTURE
/*&& mRawPostProcSupport == MFALSE*/) { // no matter
// legacy/non-legacy
// platform, HQC need
// pure raw
if (act->fullRawType != EPipe_PURE_RAW) {
act->isRawTypeChanged = MTRUE;
MY_LOGI(
"HQC (%d) - full raw type change"
" (%d => %d)",
mRawPostProcSupport, act->fullRawType, EPipe_PURE_RAW);
}
act->fullRawType = EPipe_PURE_RAW;
}
if (IS_BURST_OFF) {
mLongExp.set(act->magicNum, act->frameExpDuration);
}
MY_LOGI_IF(((capParam->i8ExposureTime >= 400000000) ||
(capParam->i8ExposureTime <= 0)),
"check CB "
"num(%d) cap(%d) exp(%" PRId64 "ns)",
magicNum, capParam->u4CapType,
capParam->i8ExposureTime);
if ((act->capType != NS3Av3::E_CAPTURE_NORMAL) &&
(act->appFrame != nullptr)) {
MY_LOGI("Job(%d) - Cap(%d)(%" PRId64 "ns) - " P1INFO_ACT_STR,
job.getIdx(), capParam->u4CapType,
capParam->i8ExposureTime, P1INFO_ACT_VAR(*act));
}
} else {
MY_LOGW("cannot find cap param (%d)", magicNum);
}
}
//
if (it != mRequestQueue.begin()) {
std::string str;
str += base::StringPrintf(
"MissingCallback from 3A : "
"this CB Mnum(%d) ; current ReqQ[%d] = [ ",
magicNum, static_cast<int>(mRequestQueue.size()));
Que_T::iterator it = mRequestQueue.begin();
for (; it != mRequestQueue.end(); it++) {
str += base::StringPrintf("%d ", (*it).getIdx());
}
str += base::StringPrintf("] @ SOF(%d)", sofIdx);
MY_LOGW("%s", str.c_str());
}
//
mRequestQueue.erase(it);
exist = true;
break;
}
}
}
if (exist) {
{
std::lock_guard<std::mutex> _ll(mTransferJobLock);
mTransferJobIdx = job.getIdx();
}
//
if (OK != onProcessEnqueFrame(&job)) {
MY_LOGE("frame en-queue fail (%d)", magicNum);
for (MUINT8 i = 0; i < job.size(); i++) {
onReturnFrame(&job.edit(i), FLUSH_FAIL, MTRUE);
/* DO NOT use this P1QueAct after onReturnFrame() */
}
} else {
if ( // IS_BURST_OFF && // exclude burst mode
(job.size() >= 1)) {
P1Act act = GET_ACT_PTR(act, job.edit(0), RET_VOID);
if ((act->reqType == REQ_TYPE_NORMAL && act->appFrame != nullptr) &&
(capParam != nullptr && capParam->metadata.count() > 0)) {
requestMetadataEarlyCallback(&(job.edit(0)), STREAM_META_OUT_HAL,
&(capParam->metadata));
}
}
//
P1Act pAct = GET_ACT_PTR(pAct, job.edit(0), RET_VOID);
if (mpHwStateCtrl != nullptr &&
pAct->ctrlSensorStatus == SENSOR_STATUS_CTRL_STANDBY) {
MBOOL isAct = MFALSE;
isAct = mpHwStateCtrl->checkCtrlStandby(pAct->getNum());
// it might call doNotifyDropframe() in DRV->suspend()
if ((isAct) &&
((mpDeliverMgr != nullptr) && (mpDeliverMgr->runningGet()))) {
MY_LOGI("DRV-suspend executed : check drop-frame");
onProcessDropFrame(MTRUE);
}
}
}
//
{
std::lock_guard<std::mutex> _ll(mTransferJobLock);
mTransferJobIdx = P1ACT_ID_NULL;
if (CC_UNLIKELY(mTransferJobWaiting)) {
mTransferJobCond.notify_all();
}
}
} else {
#if (IS_P1_LOGI)
std::lock_guard<std::mutex> _l(mRequestQueueLock);
std::string str;
str += base::StringPrintf("[req(%d)/size(%d)]: ", magicNum,
static_cast<int>(mRequestQueue.size()));
Que_T::iterator it = mRequestQueue.begin();
for (; it != mRequestQueue.end(); it++) {
str += base::StringPrintf("%d ", (*it).getIdx());
}
MY_LOGI("%s", str.c_str());
#endif
}
}
//
if (IS_BURST_ON) {
MBOOL skip = MFALSE;
if (mpHwStateCtrl != nullptr) {
skip = mpHwStateCtrl->checkSkipSync();
}
if (skip) {
MY_LOGI("FrameSet was paused");
} else {
setRequest(MFALSE);
}
}
//
P1_TRACE_C_END(SLG_I); // "P1:onSyncBegin"
//
inflightMonitoring(IMT_ENQ);
//
FUNCTION_OUT;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::onProcessEnqueFrame(P1QueJob* job) {
FUNCTION_IN;
// (1) todo
// pass request directly if it's a reprocessing one
//
// if( mInHalMeta == NULL) {
// onDispatchFrame(pFrame);
// return;
// }
// (2)
MERROR status = hardwareOps_enque(job);
FUNCTION_OUT;
return status;
}
/******************************************************************************
*
******************************************************************************/
P1QueJob P1NodeImp::getProcessingFrame_ByNumber(MINT32 magicNum) {
FUNCTION_IN;
P1QueJob job(mBurstNum);
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
if (mProcessingQueue.empty()) {
MY_LOGE("mProcessingQueue is empty");
return job;
}
Que_T::iterator it = mProcessingQueue.begin();
for (; it != mProcessingQueue.end(); it++) {
if ((*it).getIdx() == magicNum) {
break;
}
}
if (it == mProcessingQueue.end()) {
MY_LOGI("cannot find the right act for num: %d", magicNum);
job.clear();
return job;
} else {
job = *it;
mProcessingQueue.erase(it);
mProcessingQueueCond.notify_all();
}
FUNCTION_OUT;
//
return job;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::getProcessingFrame_ByAddr(IImageBuffer* const imgBuffer,
MINT32 magicNum,
P1QueJob* job) {
FUNCTION_IN;
MBOOL ret = MFALSE;
if (imgBuffer == nullptr) {
MY_LOGE("imgBuffer == NULL");
return ret;
}
// get the right act from mProcessingQueue
MINT32 gotNum = 0;
std::vector<MINT32>
vStoreNum; // not reserve since it will not insert in the most case
vStoreNum.clear();
{
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
if (mProcessingQueue.empty()) {
MY_LOGE("ProQ is empty");
return ret;
}
//
Que_T::iterator it = mProcessingQueue.begin();
for (; it != mProcessingQueue.end(); it++) {
P1Act act = GET_ACT_PTR(act, (*it).edit(0), MFALSE);
if (imgBuffer == act->streamBufImg[STREAM_IMG_OUT_FULL].spImgBuf.get() ||
imgBuffer ==
act->streamBufImg[STREAM_IMG_OUT_OPAQUE].spImgBuf.get() ||
imgBuffer ==
act->streamBufImg[STREAM_IMG_OUT_RESIZE].spImgBuf.get() ||
imgBuffer == act->streamBufImg[STREAM_IMG_OUT_LCS].spImgBuf.get() ||
imgBuffer == act->streamBufImg[STREAM_IMG_OUT_RSS].spImgBuf.get()) {
gotNum = (*it).getIdx();
if ((*it).getIdx() == magicNum) {
ret = MTRUE;
} else {
#if SUPPORT_PERFRAME_CTRL
MY_LOGE("magicNum from driver(%d), should(%d)", magicNum,
(*it).getIdx());
#else
if ((magicNum & P1NODE_COMMON_MAGICNUM_MASK) != 0) {
MY_LOGW("magicNum from driver(0x%x) is uncertain", magicNum);
ret = MFALSE;
} else {
ret = MTRUE;
MY_LOGW("magicNum from driver(%d), should(%d)", magicNum,
(*it).getIdx());
}
#endif
// reset act from 3A info
for (size_t i = 0; i < (*it).size(); i++) {
P1Act pAct = GET_ACT_PTR(pAct, (*it).edit(i), MFALSE);
pAct->capType = NS3Av3::E_CAPTURE_NORMAL;
pAct->frameExpDuration = 0;
}
}
break;
}
}
//
if (it == mProcessingQueue.end()) {
MY_LOGE("no act with imagebuf(%p), num(%d)", imgBuffer, magicNum);
#if 1 // dump ProcessingQ info
char const* str[STREAM_IMG_NUM] = {"YUV-in", "RAW-in", "OPQ", "IMG",
"RRZ", "LCS", "RSS"};
for (Que_T::iterator j = mProcessingQueue.begin();
j != mProcessingQueue.end(); j++) {
for (size_t i = 0; i < (*j).size(); i++) {
P1Act act = GET_ACT_PTR(act, (*j).edit(i), MFALSE);
MY_LOGW("[ProQ] [%zu] : num(%d)", i, act->magicNum);
for (int s = STREAM_ITEM_START; s < STREAM_IMG_NUM; s++) {
if (act->streamBufImg[s].bExist && act->streamBufImg[s].spImgBuf) {
std::shared_ptr<IImageBuffer> pBuf =
act->streamBufImg[s].spImgBuf;
MY_LOGW("[ProQ] [%zu] : %s(%p)(P:%p)(V:%p)", i,
((str[s] != nullptr) ? str[s] : "UNKNOWN"),
reinterpret_cast<void*>(pBuf.get()),
reinterpret_cast<void*>(pBuf->getBufPA(0)),
reinterpret_cast<void*>(pBuf->getBufVA(0)));
}
}
}
}
#endif
} else {
//
if (it != mProcessingQueue.begin()) {
size_t queSize = mProcessingQueue.size();
MINT queNum = 0;
Que_T::iterator it_stored = mProcessingQueue.begin();
for (; it_stored < it; it_stored++) {
for (size_t i = 0; i < (*it_stored).size(); i++) {
queNum = ((*it_stored).edit(i).getNum());
vStoreNum.push_back(queNum);
MY_LOGI(
"Non-Dequeued frame(Mnum:%d) in ProcQue[%zu] "
"current(%d)",
queNum, queSize, gotNum);
}
}
}
*job = *it;
mProcessingQueue.erase(it);
mProcessingQueueCond.notify_all();
MY_LOGD("magic: %d", magicNum);
}
} // mProcessingQueueLock.unlock();
// avoid to execute mpHwStateCtrl functions under mProcessingQueueLock
MBOOL isPauseDrop = MFALSE;
if (mpHwStateCtrl != nullptr) {
if (CC_UNLIKELY(gotNum > 0 && mpHwStateCtrl->checkDoneNum(gotNum))) {
for (size_t idx = 0; idx < vStoreNum.size(); idx++) {
MY_LOGI("DropStoreNum[%zu] : %d", idx, vStoreNum[idx]);
mpHwStateCtrl->setDropNum(vStoreNum[idx]);
}
isPauseDrop = MTRUE;
}
}
if (CC_UNLIKELY((!vStoreNum.empty()) && (!isPauseDrop))) {
size_t nSize = vStoreNum.size();
if (nSize > 0 && (vStoreNum[0] + P1NODE_DEF_PROCESS_DEPTH) < gotNum) {
MY_LOGW(
"[De-queued Frame Skipped] NonDequeuedFrameCount[%zu]:(%d)"
" - CurrentDequeuedFrameMnum(%d)"
" - Please Check the DRV Dequeue/Drop Flow",
nSize, vStoreNum[0], gotNum);
}
for (size_t idx = 0; idx < nSize; idx++) {
MY_LOGI("NonDequeued[%zu/%zu] = FrameMnum(%d) - current(%d)", idx, nSize,
vStoreNum[idx], gotNum);
}
}
//
FUNCTION_OUT;
//
return ret;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::onCheckDropFrame(void) {
MUINT cnt = 0;
MINT32 num = 0;
if (mpHwStateCtrl != nullptr) {
do {
num = mpHwStateCtrl->getDropNum();
if (num > 0) {
std::lock_guard<std::mutex> _l(mDropQueueLock);
mDropQueue.push_back(num);
cnt++;
}
} while (num > 0);
}
if ((cnt > 0) && (mpDeliverMgr != nullptr) && (mpDeliverMgr->runningGet())) {
MY_LOGI("check drop frame (%d)", cnt);
onProcessDropFrame(MTRUE);
}
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::onProcessDropFrame(MBOOL isTrigger) {
mDropQueueLock.lock();
if (mDropQueue.empty()) {
mDropQueueLock.unlock();
return OK;
}
std::vector<P1QueAct>
actQ; // not reserve since it will not insert in the most case
for (size_t i = 0; i < mDropQueue.size(); i++) {
P1QueJob job = getProcessingFrame_ByNumber(mDropQueue[i]);
// if getProcessingFrame_ByNumber can not find the job
// the job set size is 0
for (MUINT8 i = 0; i < job.size(); i++) {
P1QueAct act = job.edit(i);
actQ.push_back(act);
}
MY_LOGI("drop[%zu/%zu]: %d", i, mDropQueue.size(), mDropQueue[i]);
P1_LOGI(0, "DropQueue[%zu/%zu] = %d", i, mDropQueue.size(), mDropQueue[i]);
}
mDropQueue.clear();
mDropQueueLock.unlock();
//
for (size_t i = 0; i < actQ.size(); i++) {
//
P1Act pAct = GET_ACT_PTR(pAct, actQ.at(i), BAD_VALUE);
if (IS_BURST_OFF) {
mLongExp.reset(pAct->magicNum);
}
if (IS_LMV(mpConnectLMV) && (pAct->buffer_eiso != NULL) && getActive()) {
MY_LOGD("processDropFrame");
mpConnectLMV->processDropFrame(&(pAct->buffer_eiso));
}
pAct->exeState = EXE_STATE_DONE;
onReturnFrame(&actQ.at(i), FLUSH_DROP,
((isTrigger) && (i == (actQ.size() - 1))) ? MTRUE : MFALSE);
/* DO NOT use this P1QueAct after onReturnFrame() */
}
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::onProcessDequeFrame() {
#if 0
// [FIXME] temp-WA for DRV currently not implement self-signal
// the dequeue might be blocked while en-queue empty
// it should be removed after DRV self-signal ready
{
std::lock_guard<std::mutex> _ll(mProcessingQueueLock);
if (mProcessingQueue.empty()) {
return OK;
}
}
#endif
FUNCTION_IN;
MERROR ret = OK;
QBufInfo deqBuf;
if (hardwareOps_deque(&deqBuf) != OK) {
MY_LOGW("hardwareOps_deque error");
return BAD_VALUE;
}
if (deqBuf.mvOut.size() == 0) {
MBOOL normal_case = (!getActive());
if ((!normal_case) && (mpHwStateCtrl != nullptr)) {
normal_case = (mpHwStateCtrl->checkBufferState());
}
MY_LOGI("DeqBuf Out Size is 0 (act:%d,%d)", getActive(), normal_case);
return ((normal_case) ? OK : BAD_VALUE);
}
MY_LOGI("HwLockProcessWait +++");
std::lock_guard<std::mutex> _l(mHardwareLock);
MY_LOGI("HwLockProcessWait ---");
P1QueJob job(mBurstNum);
MBOOL match = getProcessingFrame_ByAddr(
deqBuf.mvOut[0].mBuffer, deqBuf.mvOut[0].mMetaData.mMagicNum_hal, &job);
{
std::unique_lock<std::mutex> _ll(mTransferJobLock);
std::cv_status res;
MUINT32 needRetry = P1NODE_TRANSFER_JOB_WAIT_CNT_MAX;
while ((match) && (mTransferJobIdx != P1ACT_ID_NULL) &&
(mTransferJobIdx == job.getIdx()) && (needRetry != 0)) {
mTransferJobWaiting = MTRUE;
res = mTransferJobCond.wait_for(
_ll, std::chrono::nanoseconds(P1NODE_TRANSFER_JOB_WAIT_INV_NS));
needRetry--;
MY_LOGI(
"TransferJob(%d) ThisJob(%d) - WaitStatus(%d) "
"NeedRetry(%d)",
mTransferJobIdx, job.getIdx(), res, needRetry);
if (res != std::cv_status::timeout) {
MY_LOGI("Got Job");
break;
}
}
mTransferJobWaiting = MFALSE;
if ((res == std::cv_status::timeout) && (mTransferJobIdx == job.getIdx())) {
MY_LOGE("TransferJob(%d) Not-Ready : (%d)", mTransferJobIdx, res);
}
}
onCheckDropFrame(); // must call after getProcessingFrame_ByAddr()
//
if (IS_BURST_OFF) {
mLongExp.reset(deqBuf.mvOut[0].mMetaData.mMagicNum_hal);
}
//
if (!findPortBufIndex(deqBuf, &job)) {
return BAD_VALUE;
}
//
for (MUINT8 i = 0; i < (MUINT8)job.size(); i++) {
P1QueAct qAct = job.edit(i);
P1Act act = GET_ACT_PTR(act, qAct, BAD_VALUE);
NS3Av3::MetaSet_T result3A;
// camera display systrace - DeQ
if (act->appFrame != nullptr) {
MINT64 const timestamp = deqBuf.mvOut[i].mMetaData.mTimeStamp;
P1_TRACE_F_BEGIN(
SLG_B, // add information
"Cam:%d:IspP1:deq|timestamp(ns):%" PRId64 " duration(ns):%" PRId64
" request:%d frame:%d",
getOpenId(), timestamp, NSCam::Utils::getTimeInNs() - timestamp,
act->appFrame->getRequestNo(), act->appFrame->getFrameNo());
P1_TRACE_C_END(SLG_B); // "IspP1:deq"
}
MY_LOGD("job(%d)[%d] = act(%d)", job.getIdx(), i, act->magicNum);
mTagDeq.set(qAct.getNum());
#if SUPPORT_3A
{
std::lock_guard<std::mutex> _ssl(mStopSttLock);
if (getActive() && mp3A && act->reqType == REQ_TYPE_NORMAL) {
MBOOL drop_notify = MFALSE;
MINT32 ret = 0;
mp3A->notifyP1Done(act->magicNum);
if (match && act->capType == NS3Av3::E_CAPTURE_HIGH_QUALITY_CAPTURE) {
P1_TRACE_F_BEGIN(SLG_I,
"P1:3A-getCur|"
"Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, act->frmNum,
act->reqNum);
MY_LOGD("mp3A->getCur(%d) +++", act->magicNum);
ret = mp3A->getCur(act->magicNum, &result3A);
if (ret < 0) { // 0:success
drop_notify = MTRUE;
MY_LOGI("drop-frame by 3A GetC(%d) @ (%d)(%d:%d)", ret,
act->magicNum, act->frmNum, act->reqNum);
}
MY_LOGD("mp3A->getCur(%d) ---", act->magicNum);
P1_TRACE_C_END(SLG_I); // "P1:3A-getCur"
} else {
P1_TRACE_F_BEGIN(SLG_I,
"P1:3A-get|"
"Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, act->frmNum,
act->reqNum);
MY_LOGD("mp3A->get(%d) +++", act->magicNum);
ret = mp3A->get(act->magicNum, &result3A);
if (ret < 0) { // 0:success
drop_notify = MTRUE;
MY_LOGI("drop-frame by 3A Get(%d) @ (%d)(%d:%d)", ret,
act->magicNum, act->frmNum, act->reqNum);
}
MY_LOGD("mp3A->get(%d) ---", act->magicNum);
P1_TRACE_C_END(SLG_I); // "P1:3A-get"
}
IMetadata::IEntry entry;
entry = result3A.appMeta.entryFor(MTK_TONEMAP_START);
if (entry.tag() != IMetadata::IEntry::BAD_TAG) {
MY_LOGD("find the entry for MTK_TONEMAP_START *****");
MUINT32 t;
for (t = MTK_TONEMAP_START; t < MTK_TONEMAP_MODE; t++) {
result3A.appMeta.remove(t);
}
}
entry = result3A.appMeta.entryFor(MTK_EDGE_MODE);
if (entry.tag() != IMetadata::IEntry::BAD_TAG) {
result3A.appMeta.remove(MTK_EDGE_MODE);
}
entry = result3A.appMeta.entryFor(MTK_NOISE_REDUCTION_MODE);
if (entry.tag() != IMetadata::IEntry::BAD_TAG) {
result3A.appMeta.remove(MTK_NOISE_REDUCTION_MODE);
}
entry = result3A.appMeta.entryFor(MTK_JPEG_QUALITY);
if (entry.tag() != IMetadata::IEntry::BAD_TAG) {
result3A.appMeta.remove(MTK_JPEG_QUALITY);
}
entry = result3A.appMeta.entryFor(MTK_JPEG_THUMBNAIL_QUALITY);
if (entry.tag() != IMetadata::IEntry::BAD_TAG) {
result3A.appMeta.remove(MTK_JPEG_THUMBNAIL_QUALITY);
}
P1_LOG_META(*act, &(result3A.appMeta), "3A.Get-APP");
P1_LOG_META(*act, &(result3A.halMeta), "3A.Get-HAL");
if (!match) {
act->setFlush(FLUSH_MIS_BUFFER);
}
if (drop_notify) {
act->setFlush(FLUSH_MIS_RESULT);
match = MFALSE;
}
}
}
#endif
// check the ReqExpRec
if (match && (act->expRec != EXP_REC_NONE)) {
switch (act->reqType) {
case REQ_TYPE_NORMAL:
MY_LOGI("check ExpRec " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
break;
default: // REQ_TYPE_INITIAL/REQ_TYPE_DUMMY/REQ_TYPE_PADDING
MY_LOGI("ExpRec " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
break;
}
}
// check the result of raw type
if (match) {
MUINT32 port_index = act->portBufIndex[P1_OUTPUT_PORT_IMGO];
if (port_index != P1_PORT_BUF_IDX_NONE) {
MBOOL raw_match = MTRUE;
MUINT32 res_raw = deqBuf.mvOut[port_index].mMetaData.mRawType;
MINT64 set_raw = (res_raw == (MUINT32)EPipe_PROCESSED_RAW)
? (MINT64)(eIMAGE_DESC_RAW_TYPE_PROCESSED)
: (MINT64)(eIMAGE_DESC_RAW_TYPE_PURE);
if ((act->fullRawType == EPipe_PROCESSED_RAW) &&
res_raw != (MUINT32)EPipe_PROCESSED_RAW) {
raw_match = MFALSE;
// only check Processed-Raw with (mRawType == EPipe_PROCESSED_RAW)
// in Pure-Raw, it would be EPipe_PURE_RAW or others
}
if (!raw_match) {
MY_LOGE("RawType mismatch DEQ(%d) REQ(%d)" P1INFO_ACT_STR, res_raw,
act->fullRawType, P1INFO_ACT_VAR(*act));
#if 1 // flush this frame
act->setFlush(FLUSH_MIS_RAW);
match = MFALSE;
#endif
} else {
IImageBuffer* pBuf = deqBuf.mvOut[port_index].mBuffer;
if (pBuf != nullptr) {
MBOOL res =
pBuf->setImgDesc(eIMAGE_DESC_ID_RAW_TYPE, set_raw, MTRUE);
MY_LOGD("ImgBufRawType(%" PRId64 ") %d", set_raw, res);
}
}
}
}
act->frameTimeStamp = deqBuf.mvOut[i].mMetaData.mTimeStamp;
act->frameTimeStampBoot = deqBuf.mvOut[i].mMetaData.mTimeStamp_B;
act->exeState = EXE_STATE_DONE;
act->isReadoutReady = MTRUE;
if (1 <= mLogLevelI) {
MUINT32 index = i;
std::string strInfo("");
strInfo += base::StringPrintf("[P1::DEQ]" P1INFO_ACT_STR " job(%d/%d) ",
P1INFO_ACT_VAR(*act), index, mBurstNum);
for (size_t n = index; n < deqBuf.mvOut.size(); n += mBurstNum) {
if (deqBuf.mvOut[n].mPortID.index == PORT_IMGO.index) {
strInfo += base::StringPrintf(
"IMG(%s) ",
(deqBuf.mvOut[n].mMetaData.mRawType == EPipe_PROCESSED_RAW)
? "proc"
: "pure");
} else if (deqBuf.mvOut[n].mPortID.index == PORT_RRZO.index) {
MRect crop_s = deqBuf.mvOut[n].mMetaData.mCrop_s;
MRect crop_d = deqBuf.mvOut[n].mMetaData.mCrop_d;
MSize size_d = deqBuf.mvOut[n].mMetaData.mDstSize;
strInfo += base::StringPrintf(
"RRZ%d(%d-%d-%dx%d)(%d-%d-%dx%d)(%dx%d) ", mIsBinEn, crop_s.p.x,
crop_s.p.y, crop_s.s.w, crop_s.s.h, crop_d.p.x, crop_d.p.y,
crop_d.s.w, crop_d.s.h, size_d.w, size_d.h);
}
}
strInfo += base::StringPrintf(
"T-ns(EXP: %" PRId64
")"
"(SOF: m_%" PRId64 " b_%" PRId64 ")(SS: %" PRId64 ") ",
act->frameExpDuration, act->frameTimeStamp, act->frameTimeStampBoot,
((act->frameTimeStampBoot != 0)
? (act->frameTimeStampBoot - act->frameExpDuration)
: ((act->frameTimeStamp != 0)
? (act->frameTimeStamp - act->frameExpDuration)
: (0))));
act->res.clear();
act->res += strInfo;
}
if (!match || act->getType() == ACT_TYPE_INTERNAL || !getActive()) {
FLUSH_TYPE type = FLUSH_MIS_UNCERTAIN;
if (!act->getFlush()) { // if flush type did not set
if (act->getType() == ACT_TYPE_INTERNAL) {
if (act->reqType == REQ_TYPE_INITIAL) {
type = FLUSH_INITIAL;
} else if (act->reqType == REQ_TYPE_PADDING) {
type = FLUSH_PADDING;
} else if (act->reqType == REQ_TYPE_DUMMY) {
type = FLUSH_DUMMY;
} else {
type = FLUSH_MIS_UNCERTAIN;
}
} else {
type = FLUSH_INACTIVE;
}
}
onReturnFrame(&qAct, type, MTRUE);
/* DO NOT use this P1QueAct after onReturnFrame() */
ret = BAD_VALUE;
} else {
IMetadata resultAppend;
IMetadata inAPP, inHAL;
//
if (IS_LMV(mpConnectLMV)) {
MBOOL enEIS = IS_PORT(CONFIG_PORT_EISO, mConfigPort);
MBOOL enRRZ = IS_PORT(CONFIG_PORT_RRZO, mConfigPort);
MUINT32 idxEIS = act->portBufIndex[P1_OUTPUT_PORT_EISO];
MUINT32 idxRRZ = act->portBufIndex[P1_OUTPUT_PORT_RRZO];
if (OK == act->frameMetadataGet(STREAM_META_IN_APP, &inAPP) &&
OK == act->frameMetadataGet(STREAM_META_IN_HAL, &inHAL)) {
MBOOL bIsBinEn =
(act->refBinSize == mSensorParams.size) ? MFALSE : MTRUE;
mpConnectLMV->processResult(
bIsBinEn, enEIS, enRRZ, &inAPP, &inHAL, &result3A, mp3A,
act->magicNum, act->sofIdx, mLastSofIdx, act->uniSwitchState,
deqBuf, idxEIS, idxRRZ, &resultAppend);
} else {
}
}
#if 1 // for RSSO update buffer
if (IS_OUT(REQ_OUT_RSSO, act->reqOutSet) &&
(!IS_EXP(EXP_EVT_NOBUF_RSSO, act->expRec))) {
MUINT32 port_index = act->portBufIndex[P1_OUTPUT_PORT_RSSO];
std::shared_ptr<IImageBuffer> spImgBuf =
act->streamBufImg[STREAM_IMG_OUT_RSS].spImgBuf;
if (port_index != P1_PORT_BUF_IDX_NONE && spImgBuf != nullptr) {
MSize size = deqBuf.mvOut[port_index].mMetaData.mDstSize;
MY_LOGD("RSSO data size (%dx%d)", size.w, size.h);
IMetadata::IEntry entry(MTK_P1NODE_RSS_SIZE);
entry.push_back(size, Type2Type<MSize>());
resultAppend.update(MTK_P1NODE_RSS_SIZE, entry);
}
}
#endif
#if SUPPORT_FSC
if (mpFSC != nullptr) {
MBOOL bIsBinEn =
(act->refBinSize == mSensorParams.size) ? MFALSE : MTRUE;
MUINT32 idxRSS = P1_PORT_BUF_IDX_NONE;
MUINT32 idxRRZ = act->portBufIndex[P1_OUTPUT_PORT_RRZO];
if (IS_OUT(REQ_OUT_RSSO, act->reqOutSet) &&
(!IS_EXP(EXP_EVT_NOBUF_RSSO, act->expRec)) &&
act->streamBufImg[STREAM_IMG_OUT_RSS].spImgBuf != nullptr) {
idxRSS = act->portBufIndex[P1_OUTPUT_PORT_RSSO];
}
act->frameMetadataGet(STREAM_META_IN_APP, &inAPP);
act->frameMetadataGet(STREAM_META_IN_HAL, &inHAL);
mpFSC->processResult(bIsBinEn, &inAPP, &inHAL, &result3A, mp3A,
act->magicNum, deqBuf, idxRSS, idxRRZ, i,
&resultAppend); // get FSC resultAppend
}
#endif
mLastSofIdx = act->sofIdx;
onProcessResult(&qAct, deqBuf, result3A, resultAppend, i);
/* DO NOT use this P1QueAct/P1Act after onProcessResult() */
ret = OK;
}
}
if (IS_PORT(CONFIG_PORT_EISO, mConfigPort) && getActive()) {
if (IS_LMV(mpConnectLMV)) {
mpConnectLMV->processDequeFrame(&deqBuf);
}
}
//
inflightMonitoring(IMT_DEQ);
FUNCTION_OUT;
return ret;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::onHandleFlush(MBOOL wait, MBOOL isInitReqOff) {
FUNCTION_IN;
P1_TRACE_S_BEGIN(SLG_S, "P1:HandleFlush");
// wake up cb thread.
{
std::lock_guard<std::mutex> _l(mStartLock);
mStartCond.notify_all();
}
// stop hardware
if (CC_LIKELY(!wait)) {
hardwareOps_stop(); // include hardware and 3A
}
// check the state
if (CC_UNLIKELY(!mFirstReceived)) {
if (EN_START_CAP) {
MY_LOGE(
"REQUEST-NOT-READY in start capture flow - "
"enableCaptureFlow(%d)",
mEnableCaptureFlow);
mLogInfo.inspect(LogInfo::IT_STOP_NO_REQ_IN_CAPTURE);
}
if (EN_INIT_REQ_RUN) {
MY_LOGE(
"REQUEST-NOT-READY in initial request flow - "
"initRequest(%d) : ReceivedCnt(%d) < RequiredNum(%d)",
mInitReqSet, mInitReqCnt, mInitReqNum);
mLogInfo.inspect(LogInfo::IT_STOP_NO_REQ_IN_REQUEST);
}
if ((!EN_START_CAP) && (!EN_INIT_REQ_RUN)) {
MY_LOGI("Request Not Received");
mLogInfo.inspect(LogInfo::IT_STOP_NO_REQ_IN_GENERAL);
}
}
{
// by flush() or uninit() or eventStreamingOff()
if (EN_INIT_REQ_CFG) { // in flush() -> queue() flow, for fast switching,
// it will run InitReq flow again,
mInitReqNum =
mInitReqSet *
mBurstNum; // exclude eventStreamingOn case (by mInitReqOff = MTRUE)
mInitReqCnt = 0;
mInitReqOff = isInitReqOff;
if (!EN_INIT_REQ_RUN) {
MY_LOGI("Disable - InitReq Set:%d Num:%d Cnt:%d Off:%d", mInitReqSet,
mInitReqNum, mInitReqCnt, mInitReqOff);
}
}
}
//
{
mpTaskCtrl->sessionLock();
MINT cnt = mpTaskCollector->remainder();
while (cnt > 0) {
P1QueAct qAct;
cnt = mpTaskCollector->requireAct(&qAct);
if (qAct.id() > P1ACT_ID_NULL) {
onReturnFrame(&qAct, FLUSH_COLLECTOR, MFALSE);
/* DO NOT use this P1QueAct after onReturnFrame() */
}
}
mTagList.set(cnt);
mpTaskCtrl->sessionUnLock();
}
// (1) clear request queue
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
// P1_LOGD("Check-RQ (%d)", mRequestQueue.size());
while (!mRequestQueue.empty()) {
P1QueJob job = *mRequestQueue.begin();
mRequestQueue.erase(mRequestQueue.begin());
for (MUINT8 i = 0; i < job.size(); i++) {
P1QueAct qAct = job.edit(i);
onReturnFrame(&qAct, FLUSH_REQUESTQ, MFALSE);
/* DO NOT use this P1QueAct after onReturnFrame() */
}
}
}
// (2) clear processing queue
// wait until processing frame coming out
if (CC_UNLIKELY(wait)) {
std::unique_lock<std::mutex> _lck(mProcessingQueueLock);
while (!mProcessingQueue.empty()) {
mProcessingQueueCond.wait(_lck);
}
} else {
// must guarantee hardware has been stopped.
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
while (!mProcessingQueue.empty()) {
P1QueJob job = *mProcessingQueue.begin();
mProcessingQueue.erase(mProcessingQueue.begin());
for (MUINT8 i = 0; i < job.size(); i++) {
P1QueAct qAct = job.edit(i);
onReturnFrame(&qAct, FLUSH_PROCESSQ, MFALSE);
/* DO NOT use this P1QueAct after onReturnFrame() */
}
}
}
// (3) TODO:clear dummy queue
// (4) clear drop frame queue
onProcessDropFrame();
if (CC_UNLIKELY(mpDeliverMgr != nullptr && !mpDeliverMgr->waitFlush(MTRUE))) {
MY_LOGW("request not done");
}
// (5) clear all
mRequestQueue.clear(); // suppose already clear
mProcessingQueue.clear(); // suppose already clear
mpTaskCtrl->reset();
mLastNum = 1;
P1_TRACE_C_END(SLG_S); // "P1:HandleFlush"
FUNCTION_OUT;
}
/******************************************************************************
*
******************************************************************************/
void P1NodeImp::doNotifyCb(MINT32 _msgType,
MINTPTR _ext1,
MINTPTR _ext2,
MINTPTR _ext3) {
FUNCTION_IN;
//
if (_msgType == IHal3ACb::eID_NOTIFY_3APROC_FINISH) {
MINT32 magicNum = P1_MAGIC_NUM_NULL;
NS3Av3::RequestSet_T* pReqSet =
reinterpret_cast<NS3Av3::RequestSet_T*>(_ext1);
if (pReqSet != nullptr && pReqSet->vNumberSet.size() > 0) {
magicNum = pReqSet->vNumberSet[0];
}
MUINT32 sofIdx = (MUINT32)(_ext2);
mLogInfo.setMemo(LogInfo::CP_CB_PROC_REV, _msgType, magicNum, sofIdx);
} else if (_msgType == IHal3ACb::eID_NOTIFY_VSYNC_DONE) {
mLogInfo.setMemo(LogInfo::CP_CB_SYNC_REV, _msgType);
}
MY_LOGD("P1 doNotifyCb(%d) %zd %zd %zd", _msgType, _ext1, _ext2, _ext3);
//
if (CC_UNLIKELY(!getActive())) {
MY_LOGI("not-active-return");
if (_msgType == IHal3ACb::eID_NOTIFY_3APROC_FINISH) {
mLogInfo.setMemo(LogInfo::CP_CB_PROC_RET, _msgType, MTRUE);
} else if (_msgType == IHal3ACb::eID_NOTIFY_VSYNC_DONE) {
mLogInfo.setMemo(LogInfo::CP_CB_SYNC_RET, _msgType, MTRUE);
}
return;
}
switch (_msgType) {
case IHal3ACb::eID_NOTIFY_3APROC_FINISH:
if (_ext3 == 0) {
MY_LOGE("CapParam NULL (%d) %zd %zd", _msgType, _ext1, _ext2);
} else {
NS3Av3::RequestSet_T set =
*reinterpret_cast<NS3Av3::RequestSet_T*>(_ext1);
NS3Av3::CapParam_T param =
*reinterpret_cast<NS3Av3::CapParam_T*>(_ext3);
onSyncBegin(MFALSE, &set, (MUINT32)_ext2, &param);
}
mLogInfo.setMemo(LogInfo::CP_CB_PROC_RET, _msgType, MFALSE);
break;
case IHal3ACb::eID_NOTIFY_CURR_RESULT:
break;
case IHal3ACb::eID_NOTIFY_VSYNC_DONE:
onSyncEnd();
mLogInfo.setMemo(LogInfo::CP_CB_SYNC_RET, _msgType, MFALSE);
break;
default:
break;
}
//
FUNCTION_OUT;
}
/******************************************************************************
*
******************************************************************************/
void P1NodeImp::doNotifyDropframe(MUINT magicNum, void* cookie) {
MY_LOGI("notify drop frame (%d)", magicNum);
if (cookie == nullptr) {
MY_LOGE("return cookie is NULL");
return;
}
MINT32 mSysLevel = reinterpret_cast<P1NodeImp*>(cookie)->mSysLevel;
P1_TRACE_F_BEGIN(SLG_E, "P1:DRV-drop(%d)", magicNum);
{
std::lock_guard<std::mutex> _l(
reinterpret_cast<P1NodeImp*>(cookie)->mDropQueueLock);
reinterpret_cast<P1NodeImp*>(cookie)->mDropQueue.push_back(magicNum);
MY_LOGI("[Cam::%d] receive drop frame (%d)",
reinterpret_cast<P1NodeImp*>(cookie)->getOpenId(), magicNum);
}
if ((reinterpret_cast<P1NodeImp*>(cookie)->mpDeliverMgr != nullptr) &&
(reinterpret_cast<P1NodeImp*>(cookie)->mpDeliverMgr->runningGet())) {
MY_LOGI("[Cam::%d] process drop frame (%d)",
reinterpret_cast<P1NodeImp*>(cookie)->getOpenId(), magicNum);
reinterpret_cast<P1NodeImp*>(cookie)->mpDeliverMgr->trigger();
}
P1_TRACE_C_END(SLG_E); // "P1:DRV-drop"
}
#if (USING_DRV_IO_PIPE_EVENT)
/******************************************************************************
*
******************************************************************************/
NSCam::NSIoPipe::IoPipeEventCtrl P1NodeImp::onEvtCtrlAcquiring(
P1NodeImp* user, NSCam::NSIoPipe::IpRawP1AcquiringEvent* evt) {
if (CC_UNLIKELY(user == nullptr)) {
MY_LOGW("user is NULL");
(*evt).setResult((NSCam::NSIoPipe::IoPipeEvent::ResultType)
NSCam::NSIoPipe::IoPipeEvent::RESULT_ERROR);
return NSCam::NSIoPipe::IoPipeEventCtrl::STOP_BROADCASTING;
}
std::lock_guard<std::mutex> _l(user->mIoPipeEvtOpLock);
if (CC_UNLIKELY(user->mIoPipeEvtOpLeaving)) {
MY_LOGI("[Cam::%d] IoPipeEvtOpLeaving return", user->mOpenId);
return NSCam::NSIoPipe::IoPipeEventCtrl::OK;
}
if (CC_UNLIKELY(user->mIoPipeEvtOpAcquired == MTRUE)) {
MY_LOGI("[Cam::%d] IoPipeEvtOpAcquired:1 return", user->mOpenId);
(*evt).setResult((NSCam::NSIoPipe::IoPipeEvent::ResultType)
NSCam::NSIoPipe::IoPipeEvent::RESULT_REJECT);
return NSCam::NSIoPipe::IoPipeEventCtrl::STOP_BROADCASTING;
}
user->eventStreamingOff();
user->mIoPipeEvtOpAcquired = MTRUE;
return NSCam::NSIoPipe::IoPipeEventCtrl::OK;
}
/******************************************************************************
*
******************************************************************************/
NSCam::NSIoPipe::IoPipeEventCtrl P1NodeImp::onEvtCtrlReleasing(
P1NodeImp* user, NSCam::NSIoPipe::IpRawP1ReleasedEvent* evt) {
if (CC_UNLIKELY(user == nullptr)) {
MY_LOGW("user is NULL");
(*evt).setResult((NSCam::NSIoPipe::IoPipeEvent::ResultType)
NSCam::NSIoPipe::IoPipeEvent::RESULT_ERROR);
return NSCam::NSIoPipe::IoPipeEventCtrl::STOP_BROADCASTING;
}
std::lock_guard<std::mutex> _l(user->mIoPipeEvtOpLock);
if (CC_UNLIKELY(user->mIoPipeEvtOpLeaving)) {
MY_LOGI("[Cam::%d] IoPipeEvtOpLeaving return", user->mOpenId);
return NSCam::NSIoPipe::IoPipeEventCtrl::OK;
}
if (CC_UNLIKELY(user->mIoPipeEvtOpAcquired == MFALSE)) {
MY_LOGI("[Cam::%d] IoPipeEvtOpAcquired:0 return", user->mOpenId);
(*evt).setResult((NSCam::NSIoPipe::IoPipeEvent::ResultType)
NSCam::NSIoPipe::IoPipeEvent::RESULT_REJECT);
return NSCam::NSIoPipe::IoPipeEventCtrl::STOP_BROADCASTING;
}
user->eventStreamingOn();
user->mIoPipeEvtOpAcquired = MFALSE;
return NSCam::NSIoPipe::IoPipeEventCtrl::OK;
}
#endif
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::createStuffBuffer(
std::shared_ptr<IImageBuffer>* imageBuffer,
std::shared_ptr<IImageStreamInfo> const& streamInfo,
NSCam::MSize::value_type const changeHeight) {
std::vector<MUINT32> vStride;
vStride.clear();
vStride.reserve(streamInfo->getBufPlanes().size());
for (size_t i = 0; i < streamInfo->getBufPlanes().size(); i++) {
vStride.push_back(
(MUINT32)(streamInfo->getBufPlanes()[i].rowStrideInBytes));
}
//
MSize size = streamInfo->getImgSize();
// change the height while changeHeight > 0
if (changeHeight > 0) {
size.h = changeHeight;
}
//
return createStuffBuffer(imageBuffer, streamInfo->getStreamName(),
streamInfo->getImgFormat(), size, vStride);
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::createStuffBuffer(std::shared_ptr<IImageBuffer>* imageBuffer,
char const* szName,
MINT32 format,
MSize size,
std::vector<MUINT32> vStride) {
return mStuffBufMgr.acquireStoreBuffer(
imageBuffer, szName, format, size, vStride, mBurstNum,
(mDebugScanLineMask != 0) ? MTRUE : MFALSE);
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::destroyStuffBuffer(std::shared_ptr<IImageBuffer>* imageBuffer) {
if (imageBuffer == nullptr) {
MY_LOGW("Stuff ImageBuffer not exist");
return BAD_VALUE;
}
return mStuffBufMgr.releaseStoreBuffer(imageBuffer);
}
#if (USING_DRV_IO_PIPE_EVENT)
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::eventStreamingInform() {
{
pthread_rwlock_rdlock(&mIoPipeEvtStateLock);
if (CC_LIKELY(mIoPipeEvtState != IO_PIPE_EVT_STATE_ACQUIRING)) {
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
return;
}
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
//
{
std::lock_guard<std::mutex> _l(mIoPipeEvtWaitLock);
if (CC_LIKELY(mIoPipeEvtWaiting)) {
if ((mpDeliverMgr != nullptr) && (mpDeliverMgr->runningGet()) &&
(mpDeliverMgr->isActListEmpty())) {
mIoPipeEvtWaitCond.notify_all();
MY_LOGI("action list is empty");
}
}
}
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::eventStreamingOn() {
P1_TRACE_AUTO(SLG_E, "P1:eventStreamingOn");
MY_LOGI("StreamingOn +");
std::lock_guard<std::mutex> _l(mPublicLock);
{
pthread_rwlock_rdlock(&mIoPipeEvtStateLock);
if (CC_UNLIKELY(mIoPipeEvtState != IO_PIPE_EVT_STATE_ACQUIRED)) {
MY_LOGI("StreamingOn return - state(%d)", mIoPipeEvtState);
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
return;
}
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
{
pthread_rwlock_wrlock(&mIoPipeEvtStateLock);
mIoPipeEvtState = IO_PIPE_EVT_STATE_NONE;
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
//
beckonRequest();
MY_LOGI("StreamingOn -");
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::eventStreamingOff() {
P1_TRACE_AUTO(SLG_E, "P1:eventStreamingOff");
MY_LOGI("StreamingOff +");
std::lock_guard<std::mutex> _l(mPublicLock);
{
pthread_rwlock_rdlock(&mIoPipeEvtStateLock);
if (CC_UNLIKELY(mIoPipeEvtState != IO_PIPE_EVT_STATE_NONE)) {
MY_LOGI("StreamingOff return - state(%d)", mIoPipeEvtState);
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
return;
}
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
{
pthread_rwlock_wrlock(&mIoPipeEvtStateLock);
mIoPipeEvtState = IO_PIPE_EVT_STATE_ACQUIRING;
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
//
// wait for the last NORMAL/BYPASS action done
MBOOL bWaitDrain = MTRUE;
#if 1
{
MINT32 nWaitDrain =
property_get_int32("vendor.debug.camera.log.p1nodefasthqc", 0);
if (nWaitDrain > 0) {
MY_LOGI("p1node-fast-hqc:%d", nWaitDrain);
bWaitDrain = MFALSE;
}
}
#endif
if (bWaitDrain && (mpDeliverMgr != nullptr) && (mpDeliverMgr->runningGet())) {
std::unique_lock<std::mutex> lck(mIoPipeEvtWaitLock);
mIoPipeEvtWaiting = MTRUE;
while (!mpDeliverMgr->isActListEmpty()) {
std::cv_status res = mIoPipeEvtWaitCond.wait_for(
lck, std::chrono::nanoseconds(P1NODE_EVT_DRAIN_WAIT_INV_NS));
if (res != std::cv_status::timeout) {
MY_LOGI("all actions done");
break;
} else {
MY_LOGI("actions not finish - res(%d) empty(%d)", res,
mpDeliverMgr->isActListEmpty());
mpDeliverMgr->dumpInfo();
mLogInfo.inspect(LogInfo::IT_EVT_WAIT_DRAIN_TIMEOUT);
}
}
mIoPipeEvtWaiting = MFALSE;
} else {
MY_LOGI("stop and flush directly, WaitDrain(%d)", bWaitDrain);
}
// In InitReq Flow (EN_INIT_REQ), mInitReqOff re-assign by eventStreamingOff()
// via onHandleFlush(). While eventStreamingOn(), by mInitReqOff to disable
// the init-request-flow as the next first request arrival.
onHandleFlush(MFALSE, MTRUE); // disable InitReq flow
//
{
pthread_rwlock_wrlock(&mIoPipeEvtStateLock);
mIoPipeEvtState = IO_PIPE_EVT_STATE_ACQUIRED;
pthread_rwlock_unlock(&mIoPipeEvtStateLock);
}
MY_LOGI("StreamingOff -");
return;
}
#endif
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_start() {
#if SUPPORT_ISP
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:hardwareOps_start");
MERROR err = OK;
mLogInfo.setMemo(LogInfo::CP_OP_START_BGN, mBurstNum, mEnableCaptureFlow,
(EN_INIT_REQ_RUN) ? mInitReqSet : 0);
std::lock_guard<std::mutex> _l(mHardwareLock);
mTagReq.clear();
mTagSet.clear();
mTagEnq.clear();
mTagDeq.clear();
mTagOut.clear();
mTagList.clear();
{
MINT64 currentTime = (MINT64)(NSCam::Utils::getTimeInNs());
{
std::lock_guard<std::mutex> _l(mMonitorLock);
mMonitorTime = currentTime;
}
}
{
std::lock_guard<std::mutex> _l(mThreadLock);
setActive(MTRUE);
mThreadCond.notify_all();
}
setStartState(NSP1Node::START_STATE_NULL);
#if USING_CTRL_3A_LIST_PREVIOUS
mPreviousCtrlList.clear();
#endif
setInit(MTRUE);
mLastSofIdx = P1SOFIDX_NULL_VAL;
mLastSetNum = 0;
{
std::lock_guard<std::mutex> _ll(mTransferJobLock);
mTransferJobIdx = P1ACT_ID_NULL;
mTransferJobWaiting = MFALSE;
}
mConfigPort = CONFIG_PORT_NONE;
mConfigPortNum = 0;
mFirstReceived = MFALSE;
//
{
std::lock_guard<std::mutex> _ll(mFrameSetLock);
mFrameSetAlready = MFALSE;
}
//
mDequeThreadProfile.reset();
//
EImageFormat resizer_fmt = eImgFmt_FG_BAYER10;
//
if (mspResConCtrl != nullptr) {
P1NODE_RES_CON_ACQUIRE(mspResConCtrl, mResConClient, mIsResConGot);
}
//
{
EPipeSelect ps = EPipeSelect_Normal;
if (mPipeMode == PIPE_MODE_NORMAL_SV) {
ps = EPipeSelect_NormalSv;
}
int selectedVersion = 0;
const unsigned int* version = nullptr;
size_t count = 0;
err = getNormalPipeModule()->get_sub_module_api_version(&version, &count);
if (err < 0 || !count || !version) {
MY_LOGE(
"[%d] INormalPipeModule::get_sub_module_api_version - err:%#x "
"count:%zu version:%p",
getOpenId(), err, count, version);
} else {
selectedVersion = *(version + count - 1); // Select max. version
}
MY_LOGI("[%d] count:%zu Selected CamIO Version:%0#x", getOpenId(), count,
selectedVersion);
mpCamIO = getNormalPipeModule()->getSubModule(
kPipeNormal, getOpenId(), getNodeName(), selectedVersion);
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_START_DRV_INIT_BGN,
LogInfo::CP_OP_START_DRV_INIT_END);
}
#if SUPPORT_LCS
err = lcsInit();
if (err != OK) {
MY_LOGE("lcsInit fail");
return err;
}
#endif
MSize sensorSize = mSensorParams.size;
MSize rrzoSize = mvStreamImg[STREAM_IMG_OUT_RESIZE]->getImgSize();
err = lmvInit(sensorSize, rrzoSize);
if (err != OK) {
MY_LOGE("lmvInit fail");
return err;
}
MUINT32 AETargetMode = MFALSE; // vHDR OFF mode
NS3Av3::AEInitExpoSetting_T initExpoSetting;
::memset(&initExpoSetting, 0, sizeof(initExpoSetting));
initExpoSetting.u4SensorMode = mSensorParams.mode;
initExpoSetting.u4AETargetMode = AETargetMode;
// set shutter/gain 0 as ::memset
#if SUPPORT_3A
err = getAEInitExpoSetting(&initExpoSetting);
if (err != OK) {
MY_LOGE("getAEInitExpoSetting fail");
return err;
}
#endif
#if MTKCAM_HAVE_SANDBOX_SUPPORT
v4l2DeviceStart();
#endif
//
PipeTag pipe_tag = kPipeTag_Out2_Tuning;
std::vector<PortInfo> vPortInfo;
vPortInfo.clear();
vPortInfo.reserve(P1_OUTPUT_PORT_TOTAL);
addConfigPort(&vPortInfo, &resizer_fmt);
//
IHalSensor::ConfigParam sensorCfg;
::memset(&sensorCfg, 0, sizeof(IHalSensor::ConfigParam));
QInitParam halCamIOinitParam =
prepareQInitParam(&sensorCfg, initExpoSetting, vPortInfo);
//
MSize binInfoSize = mSensorParams.size;
setCurrentBinSize(mSensorParams.size);
mIsBinEn = false;
MSize rawSize[2];
MSize* pSizeProc = &rawSize[0]; // 0 = EPipe_PROCESSED_RAW
MSize* pSizePure = &rawSize[1]; // 1 = EPipe_PURE_RAW
*pSizeProc = MSize(0, 0);
*pSizePure = MSize(0, 0);
std::map<int, std::vector<std::shared_ptr<IImageBuffer>>> buffers;
err =
startCamIO(halCamIOinitParam, &binInfoSize, rawSize, &pipe_tag, &buffers);
if (err != OK) {
MY_LOGE("startCamIO fail");
return err;
}
if (auto pModule = getNormalPipeModule()) {
#if 1 // query height ratio from DRV
NormalPipe_QueryInfo info;
pModule->query(PORT_RRZO.index, ENPipeQueryCmd_BS_RATIO, resizer_fmt, 0,
&info);
mResizeRatioMax = info.bs_ratio;
MY_LOGI("ResizeRatioMax = info.bs_ratio(%d)", info.bs_ratio);
#endif
}
#if SUPPORT_3A
{
P1_TIMING_CHECK("P1:3A-notifyPwrOn", 10, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-notifyPwrOn");
mLogInfo.setMemo(LogInfo::CP_OP_START_3A_PWRON_BGN);
if (mp3A->notifyP1PwrOn()) { // CCU DRV power on after ISP configPipe
setPowerNotify(MTRUE);
} else {
MY_LOGI("3A->notifyP1PwrOn() return FALSE");
}
mLogInfo.setMemo(LogInfo::CP_OP_START_3A_PWRON_END);
P1_TRACE_C_END(SLG_S); // "P1:3A-notifyPwrOn"
}
{
P1_TIMING_CHECK("P1:3A-setSensorMode", 10, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-setSensorMode");
mp3A->setSensorMode(mSensorParams.mode);
P1_TRACE_C_END(SLG_S); // "P1:3A-setSensorMode"
}
#endif
if (IS_LMV(mpConnectLMV)) {
P1_TIMING_CHECK("P1:LMV-config", 20, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LMV-config");
MY_LOGD("mpConnectLMV->config");
mpConnectLMV->config(buffers[PORT_EISO.index]);
P1_TRACE_C_END(SLG_S); // "P1:LMV-config"
}
#if SUPPORT_LCS
if (mpLCS) {
LCS_HAL_CONFIG_DATA lcsConfig;
lcsConfig.cameraVer = LCS_CAMERA_VER_3;
if (mvStreamImg[STREAM_IMG_OUT_LCS] != nullptr) {
lcsConfig.lcsOutWidth = mvStreamImg[STREAM_IMG_OUT_LCS]->getImgSize().w;
lcsConfig.lcsOutHeight = mvStreamImg[STREAM_IMG_OUT_LCS]->getImgSize().h;
lcsConfig.tgWidth = mSensorParams.size.w;
lcsConfig.tgHeight = mSensorParams.size.h;
} else {
MY_LOGI("LCS enable but no LCS stream info");
lcsConfig.lcsOutWidth = 0;
lcsConfig.lcsOutHeight = 0;
}
//
P1_TIMING_CHECK("P1:LCS-config", 20, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LCS-config");
mpLCS->ConfigLcsHal(lcsConfig);
P1_TRACE_C_END(SLG_S); // "P1:LCS-config"
}
#endif
if (mpConCtrl != nullptr && mpConCtrl->getStageCtrl() != nullptr) {
mpConCtrl->getStageCtrl()->done((MUINT32)STAGE_DONE_START, MTRUE);
}
#if SUPPORT_3A
if (mp3A) {
P1_TIMING_CHECK("P1:3A-config", 300, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-sendCtrl-attachCb");
mp3A->attachCb(IHal3ACb::eID_NOTIFY_3APROC_FINISH, this);
mp3A->attachCb(IHal3ACb::eID_NOTIFY_CURR_RESULT, this);
mp3A->attachCb(IHal3ACb::eID_NOTIFY_VSYNC_DONE, this);
P1_TRACE_C_END(SLG_S); // "P1:3A-sendCtrl-attachCb"
NS3Av3::ConfigInfo_T config;
NS3Av3::EBitMode_T b = NS3Av3::EBitMode_12Bit;
switch (mPipeBit) {
case CAM_Pipeline_10BITS:
b = NS3Av3::EBitMode_10Bit;
break;
case CAM_Pipeline_12BITS:
b = NS3Av3::EBitMode_12Bit;
break;
case CAM_Pipeline_14BITS:
b = NS3Av3::EBitMode_14Bit;
break;
case CAM_Pipeline_16BITS:
b = NS3Av3::EBitMode_16Bit;
break;
default:
MY_LOGW("CANNOT map the pipeline bit mode");
break;
}
config.i4BitMode = b;
config.i4SubsampleCount = (MINT32)(MAX(mBurstNum, 1));
config.i4HlrOption = (mDisableHLR) ? (NS3Av3::EHlrOption_ForceOff)
: (NS3Av3::EHlrOption_Auto);
config.CfgAppMeta = mCfgAppMeta;
config.CfgHalMeta = mCfgHalMeta;
//
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_START_3A_CFG_BGN,
LogInfo::CP_OP_START_3A_CFG_END);
/* getMatrix to active and from active here */
NSCamHW::HwTransHelper helper(getOpenId());
NSCamHW::HwMatrix matFromActive;
if (!helper.getMatrixFromActive(mSensorParams.mode, &matFromActive))
MY_LOGE("Get hw matFromActive failed");
NSCamHW::HwMatrix matToActive;
if (!helper.getMatrixToActive(mSensorParams.mode, &matToActive))
MY_LOGE("Get hw matToActive failed");
config.matFromAct = matFromActive;
config.matToAct = matToActive;
#if MTKCAM_HAVE_SANDBOX_SUPPORT
/* update static metadata for sandbox */
std::shared_ptr<IMetadataProvider> pMetadataProvider =
NSMetadataProviderManager::valueFor(getOpenId());
if (pMetadataProvider.get()) {
const IMetadata& metaStaticInfo =
pMetadataProvider->getMtkStaticCharacteristics();
NS3Av3::IpcMetaStaticInfo_T ipcMetaStaticInfo;
const IMetadata::IEntry& entryAvailableScene =
metaStaticInfo.entryFor(MTK_CONTROL_AVAILABLE_SCENE_MODES);
ipcMetaStaticInfo.availableSceneModesCount = entryAvailableScene.count();
for (int i = 0; i < entryAvailableScene.count(); i++)
ipcMetaStaticInfo.availableSceneModes[i] =
entryAvailableScene.itemAt(i, Type2Type<MUINT8>());
const IMetadata::IEntry& entryScnOvrd =
metaStaticInfo.entryFor(MTK_CONTROL_SCENE_MODE_OVERRIDES);
ipcMetaStaticInfo.sceneModeOverridesCount = entryScnOvrd.count();
for (int i = 0; i < entryScnOvrd.count(); i++)
ipcMetaStaticInfo.sceneModeOverrides[i] =
entryScnOvrd.itemAt(i, Type2Type<MUINT8>());
NS3Av3::QUERY_ENTRY_SINGLE(metaStaticInfo,
MTK_CONTROL_AE_COMPENSATION_STEP,
&ipcMetaStaticInfo.aeCompensationStep);
NS3Av3::GET_ENTRY_ARRAY(metaStaticInfo, MTK_CONTROL_MAX_REGIONS,
ipcMetaStaticInfo.maxRegions, 3);
NS3Av3::QUERY_ENTRY_SINGLE(metaStaticInfo,
MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION,
&ipcMetaStaticInfo.activeArrayRegion);
NS3Av3::QUERY_ENTRY_SINGLE(metaStaticInfo, MTK_LENS_INFO_SHADING_MAP_SIZE,
&ipcMetaStaticInfo.shadingMapSize);
NS3Av3::QUERY_ENTRY_SINGLE(metaStaticInfo,
MTK_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
&ipcMetaStaticInfo.availableFocalLengths);
NS3Av3::QUERY_ENTRY_SINGLE(metaStaticInfo,
MTK_LENS_INFO_AVAILABLE_APERTURES,
&ipcMetaStaticInfo.availableApertures);
mp3A->send3ACtrl(NS3Av3::E3ACtrl_IPC_Set_MetaStaticInfo,
reinterpret_cast<MINTPTR>(&ipcMetaStaticInfo), 0);
}
#endif
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-config");
MY_LOGI("mp3A->config +++");
mp3A->config(config);
MY_LOGI("mp3A->config ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-config"
}
#endif
//
if (mpHwStateCtrl != nullptr) {
MBOOL isLegacy =
(mIsLegacyStandbyMode || mForceStandbyMode > 0) ? MTRUE : MFALSE;
mpHwStateCtrl->config(getOpenId(), mLogLevel, mLogLevelI, mSysLevel,
mBurstNum, mpCamIO.get(), mp3A, isLegacy);
}
//
#ifdef P1_START_INFO_STR
#undef P1_START_INFO_STR
#endif
#define P1_START_INFO_STR \
"Cam::%d " \
"Sensor(%dx%d) Raw(%d,0x%x)-Proc(%dx%d)-Pure(%dx%d) " \
"Bin(%dx%d) BinEn=%d TG(%d:%d) DTwin(%d@%d)=%d LSM(%d) QLV(%d) " \
"Ratio(%d) SensorCfg(i:%d %dx%d s:%d b:%d c:%d, h:%d f:%d t:%d d:%d) " \
"ConfigPort[%d]:(0x%x) InitParam[R:%d B:%d D:%d Nd:%d )]"
#ifdef P1_START_INFO_VAR
#undef P1_START_INFO_VAR
#endif
#define P1_START_INFO_VAR \
getOpenId(), mSensorParams.size.w, mSensorParams.size.h, mRawDefType, \
mRawOption, pSizeProc->w, pSizeProc->h, pSizePure->w, pSizePure->h, \
binInfoSize.w, binInfoSize.h, mIsBinEn, mTgNum, mCfg.mSensorNum, \
mDisableDynamicTwin, mCfg.mSupportDynamicTwin, mIsDynamicTwinEn, \
mIsLegacyStandbyMode, mCfg.mQualityLv, mResizeRatioMax, sensorCfg.index, \
sensorCfg.crop.w, sensorCfg.crop.h, sensorCfg.scenarioId, \
sensorCfg.isBypassScenario, sensorCfg.isContinuous, sensorCfg.HDRMode, \
sensorCfg.framerate, sensorCfg.twopixelOn, sensorCfg.debugMode, \
mConfigPortNum, mConfigPort, halCamIOinitParam.mRawType, \
halCamIOinitParam.m_pipelinebitdepth, halCamIOinitParam.m_DynamicTwin, \
halCamIOinitParam.m_IQlv
//
if (EN_INIT_REQ_RUN) {
MY_LOGI("InitRqeFlow return %d %d %d - " P1_START_INFO_STR, mInitReqSet,
mInitReqNum, mInitReqCnt, P1_START_INFO_VAR);
mLogInfo.setMemo(LogInfo::CP_OP_START_REQ_WAIT_BGN,
LogInfo::START_SET_REQUEST);
return OK;
}
//
if (EN_START_CAP) {
std::lock_guard<std::mutex> _l(mStartCaptureLock);
mStartCaptureState = START_CAP_STATE_WAIT_REQ;
mStartCaptureType = NS3Av3::E_CAPTURE_NORMAL;
mStartCaptureIdx = 0;
mStartCaptureExp = 0;
MY_LOGI("EnableCaptureFlow(%d) return - " P1_START_INFO_STR,
mEnableCaptureFlow, P1_START_INFO_VAR);
mLogInfo.setMemo(LogInfo::CP_OP_START_REQ_WAIT_BGN,
LogInfo::START_SET_CAPTURE);
return OK;
}
#if MTKCAM_HAVE_SANDBOX_SUPPORT
{
MY_LOGI("V4L2TuningPipeMgr start +++");
mpV4L2TuningPipe =
std::make_shared<v4l2::V4L2TuningPipeMgr>(pipe_tag, getOpenId());
mpV4L2TuningPipe->startWorker();
MY_LOGI("V4L2TuningPipeMgr start ---");
// stt pipe should be started after normalpipe started.
MY_LOGI("V4L2SttPipeMgr start +++");
// checks if need META2 or not
const int enableMeta2 = [&]() {
if (mpV4L2LensMgr == nullptr) {
return v4l2::V4L2SttPipeMgr::DISABLE_META2;
}
return mpV4L2LensMgr->isLensDriverOpened()
? v4l2::V4L2SttPipeMgr::ENABLE_META2
: v4l2::V4L2SttPipeMgr::DISABLE_META2;
}();
mpV4L2SttPipe = std::make_shared<v4l2::V4L2SttPipeMgr>(
pipe_tag, getOpenId(), enableMeta2);
mpV4L2SttPipe->start();
MY_LOGI("V4L2SttPipeMgr start ---");
// HWEvent workers
// Notice: HwEventWorkers must be started after INormalPipe started.
MY_LOGI("V4L2HwEventWorker start +++");
auto _create_hw_event_mgrs = [this](size_t idx, EPipeSignal signal,
const char* caller) {
mpV4L2HwEventMgr[idx] = std::make_shared<v4l2::V4L2HwEventWorker>(
getOpenId(), signal, caller);
mpV4L2HwEventMgr[idx]->start();
};
MY_LOGI("V4L2HwEventWorker start ---");
_create_hw_event_mgrs(0, EPipeSignal_SOF, "evtmgr_sof");
_create_hw_event_mgrs(1, EPipeSignal_AFDONE, "evtmgr_afdone");
_create_hw_event_mgrs(2, EPipeSignal_EOF, "evtmgr_eof");
}
#endif
#if SUPPORT_3A
if (mp3A) {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_START_3A_START_BGN,
LogInfo::CP_OP_START_3A_START_END);
P1_TIMING_CHECK("P1:3A-start", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-start");
MY_LOGI("mp3A->start +++");
mp3A->start();
MY_LOGI("mp3A->start ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-start"
}
#endif
#if MTKCAM_HAVE_SANDBOX_SUPPORT
{
/* wait until a buffer enqueued, and stream on tuning pipe */
CAM_LOGD("V4L2TuningPipeMgr: wait until enqued [+]");
mpV4L2TuningPipe->waitUntilEnqued();
CAM_LOGD("V4L2TuningPipeMgr: wait until enqued [-]");
mpV4L2TuningPipe->startPipe();
}
#endif
//
{
if (mpConCtrl != nullptr && mpConCtrl->getStageCtrl() != nullptr) {
MBOOL success = MFALSE;
mpConCtrl->getStageCtrl()->wait((MUINT32)STAGE_DONE_INIT_ITEM, &success);
if (!success) {
MY_LOGE("stage - init item fail");
return BAD_VALUE;
}
}
//
MERROR status = hardwareOps_enque(
&mProcessingQueue.at(mProcessingQueue.size() - 1), ENQ_TYPE_INITIAL);
if (status != OK) {
MY_LOGE("hardware init-enque fail (%d)", status);
return status;
}
}
//
if (mpConCtrl != nullptr) {
mpConCtrl->cleanAidStage();
}
//
setStartState(NSP1Node::START_STATE_DRV_START);
if (mpCamIO != nullptr) {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_START_DRV_START_BGN,
LogInfo::CP_OP_START_DRV_START_END);
P1_TIMING_CHECK("P1:DRV-start", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-start");
MY_LOGI("mpCamIO->start +++");
if (!mpCamIO->start()) {
MY_LOGE("mpCamIO->start fail");
P1_TRACE_C_END(SLG_S); // "P1:DRV-start"
return BAD_VALUE;
}
MY_LOGI("mpCamIO->start ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-start"
}
setStartState(NSP1Node::START_STATE_LMV_SENSOR_EN);
if (IS_LMV(mpConnectLMV)) {
P1_TIMING_CHECK("P1:LMV-sensor", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LMV-sensor");
MY_LOGD("mpConnectLMV->enableSensor +++");
mpConnectLMV->enableSensor();
MY_LOGD("mpConnectLMV->enableSensor ---");
P1_TRACE_C_END(SLG_S); // "P1:LMV-sensor"
}
{
std::lock_guard<std::mutex> _l(mThreadLock);
setReady(MTRUE);
mThreadCond.notify_all();
}
{
std::lock_guard<std::mutex> _l(mStartLock);
setStartState(NSP1Node::START_STATE_READY);
mStartCond.notify_all();
}
syncHelperStart();
MY_LOGI("End - " P1_START_INFO_STR, P1_START_INFO_VAR);
#undef P1_START_INFO_STR
#undef P1_START_INFO_VAR
mLogInfo.setMemo(LogInfo::CP_OP_START_END, mBurstNum, mEnableCaptureFlow,
mInitReqSet, LogInfo::START_SET_GENERAL);
FUNCTION_OUT;
return OK;
#else
return OK;
#endif
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_request() {
#if SUPPORT_ISP
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:hardwareOps_request");
//
mLogInfo.setMemo(LogInfo::CP_OP_START_REQ_WAIT_END,
LogInfo::START_SET_REQUEST);
//
std::lock_guard<std::mutex> _l(mHardwareLock);
//
#if USING_CTRL_3A_LIST
List<NS3Av3::MetaSet_T> ctrlList;
#else
std::vector<NS3Av3::MetaSet_T*> ctrlQueue;
ctrlQueue.clear();
ctrlQueue.reserve(mInitReqNum);
#endif
//
MUINT32 total = mpTaskCollector->remainder();
MUINT32 initNum = mInitReqNum - 1;
if (CC_UNLIKELY(total < mInitReqNum)) {
MY_LOGE("init request set is not enough (%d < %d)", total, mInitReqSet);
return BAD_VALUE;
}
// Prepare for DRV
for (MUINT32 index = 0; index < initNum; index++) {
P1QueJob job(mBurstNum);
mpTaskCtrl->sessionLock();
mpTaskCollector->requireJob(&job);
mpTaskCtrl->sessionUnLock();
{
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
mProcessingQueue.push_back(job);
}
if (job.size() > 0 && job.edit(0).ptr() != nullptr) {
#if USING_CTRL_3A_LIST
ctrlList.push_back(job.edit(0).ptr()->metaSet);
#else
ctrlQueue.push_back(&(job.edit(0).ptr()->metaSet));
#endif
}
}
// Set to 3A
{
P1QueJob job(mBurstNum);
mpTaskCtrl->sessionLock();
mpTaskCollector->requireJob(&job);
mpTaskCtrl->sessionUnLock();
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
mRequestQueue.push_back(job);
}
if (job.size() > 0 && job.edit(0).ptr() != nullptr) {
#if USING_CTRL_3A_LIST
ctrlList.push_back(job.edit(0).ptr()->metaSet);
#else
ctrlQueue.push_back(&(job.edit(0).ptr()->metaSet));
#endif
}
mLastSetNum = job.getLastNum();
mTagSet.set(mLastSetNum);
//
{
std::lock_guard<std::mutex> _ll(mFrameSetLock);
#if SUPPORT_3A
if (mp3A) {
P1_TIMING_CHECK("P1:3A-startRequest", 200, TC_W);
mLogInfo.setMemo(LogInfo::CP_START_SET_BGN, LogInfo::START_SET_REQUEST,
mLastSetNum);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-startRequest");
MY_LOGI("mp3A->startRequestQ +++");
#if USING_CTRL_3A_LIST
mp3A->startRequestQ(ctrlList); // mp3A->start();
#else
mp3A->startRequestQ(ctrlQueue); // mp3A->start();
#endif
MY_LOGI("mp3A->startRequestQ ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-startRequest"
mLogInfo.setMemo(LogInfo::CP_START_SET_END, LogInfo::START_SET_REQUEST,
mLastSetNum);
}
#endif
mFrameSetAlready = MTRUE;
}
}
// EnQ to DRV
{
for (MUINT32 idx = 0; idx < initNum; idx++) {
P1QueJob job;
{
// clone the QueJob from the ProcessingQueue
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
job = mProcessingQueue.at(idx);
}
MY_LOGD("InitReqEnQ (%d/%d) +++", idx, initNum);
MERROR status = hardwareOps_enque(&job, ENQ_TYPE_INITIAL);
if (status != OK) {
MY_LOGE("hardware req-init-enque fail (%d)@(%d)", status, idx);
return status;
}
MY_LOGD("InitReqEnQ (%d/%d) ---", idx, initNum);
}
}
//
if (mpConCtrl != nullptr) {
mpConCtrl->cleanAidStage();
}
//
setStartState(NSP1Node::START_STATE_DRV_START);
#if 1
if (mpCamIO) {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_START_DRV_START_BGN,
LogInfo::CP_OP_START_DRV_START_END);
P1_TIMING_CHECK("P1:DRV-start", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-start");
MY_LOGI("mpCamIO->start +++");
if (!mpCamIO->start()) {
MY_LOGE("hardware start fail");
P1_TRACE_C_END(SLG_S); // "P1:DRV-start"
return BAD_VALUE;
}
MY_LOGI("mpCamIO->start ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-start"
}
#endif
setStartState(NSP1Node::START_STATE_LMV_SENSOR_EN);
if (IS_LMV(mpConnectLMV)) {
P1_TIMING_CHECK("P1:LMV-sensor", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LMV-sensor");
MY_LOGD("mpConnectLMV->enableSensor +++");
mpConnectLMV->enableSensor();
MY_LOGD("mpConnectLMV->enableSensor ---");
P1_TRACE_C_END(SLG_S); // "P1:LMV-sensor"
}
{
std::lock_guard<std::mutex> _l(mThreadLock);
setReady(MTRUE);
mThreadCond.notify_all();
}
{
std::lock_guard<std::mutex> _l(mStartLock);
setStartState(NSP1Node::START_STATE_READY);
mStartCond.notify_all();
}
syncHelperStart();
MY_LOGI("Cam::%d BinEn:%d ConfigPort[%d]:0x%x", getOpenId(), mIsBinEn,
mConfigPortNum, mConfigPort);
mLogInfo.setMemo(LogInfo::CP_OP_START_END, mBurstNum, mEnableCaptureFlow,
mInitReqSet, LogInfo::START_SET_REQUEST);
FUNCTION_OUT;
return OK;
#else
return OK;
#endif
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_capture() {
#if SUPPORT_ISP
FUNCTION_IN;
P1_TRACE_AUTO(SLG_B, "P1:hardwareOps_capture");
//
mLogInfo.setMemo(LogInfo::CP_OP_START_REQ_WAIT_END,
LogInfo::START_SET_CAPTURE);
//
std::lock_guard<std::mutex> _l(mHardwareLock);
//
MINT32 num = 0;
MBOOL isManualCap = MFALSE;
//
if (EN_START_CAP) {
std::lock_guard<std::mutex> _l(mStartCaptureLock);
mStartCaptureState = START_CAP_STATE_WAIT_CB;
}
//
{
MINT32 type = NS3Av3::ESTART_CAP_NORMAL;
{
#if 1
P1QueJob job(mBurstNum);
mpTaskCtrl->sessionLock();
mpTaskCollector->requireJob(&job);
mpTaskCtrl->sessionUnLock();
#endif
#if USING_CTRL_3A_LIST
List<NS3Av3::MetaSet_T> ctrlList;
generateCtrlList(&ctrlList, &job);
#else
std::vector<NS3Av3::MetaSet_T*> ctrlQueue;
ctrlQueue.clear();
ctrlQueue.reserve(job.size());
generateCtrlQueue(&ctrlQueue, &job);
#endif
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
mRequestQueue.push_back(job);
}
std::lock_guard<std::mutex> _ll(mFrameSetLock);
#if SUPPORT_3A
if (mp3A) {
P1_TIMING_CHECK("P1:3A-startCapture", 200, TC_W);
mLogInfo.setMemo(LogInfo::CP_START_SET_BGN, LogInfo::START_SET_CAPTURE,
job.getIdx());
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-startCapture");
MY_LOGI("mp3A->startCapture +++");
#if USING_CTRL_3A_LIST
type = mp3A->startCapture(ctrlList); // mp3A->start();
#else
type = mp3A->startCapture(ctrlQueue); // mp3A->start();
#endif
MY_LOGI("mp3A->startCapture ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-startCapture"
mLogInfo.setMemo(LogInfo::CP_START_SET_END, LogInfo::START_SET_CAPTURE,
job.getIdx());
}
#endif
mFrameSetAlready = MTRUE;
MY_LOGI("start-capture-type %d", type);
}
if (type != NS3Av3::ESTART_CAP_NORMAL) {
isManualCap = MTRUE;
MY_LOGI("capture in manual flow %d", type);
}
}
//
if (mpConCtrl != nullptr && mpConCtrl->getStageCtrl() != nullptr) {
MBOOL success = MFALSE;
mpConCtrl->getStageCtrl()->wait((MUINT32)STAGE_DONE_INIT_ITEM, &success);
if (!success) {
MY_LOGE("stage - cap init item fail");
return BAD_VALUE;
}
}
//
{
MERROR status = hardwareOps_enque(
&mProcessingQueue.at(mProcessingQueue.size() - 1), ENQ_TYPE_INITIAL);
if (status != OK) {
MY_LOGE("hardware cap-init-enque fail (%d)", status);
return status;
}
}
//
if (!isManualCap) {
P1_TRACE_S_BEGIN(SLG_S, "Cap Normal EnQ");
P1QueJob job(mBurstNum);
{
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
if (CC_LIKELY(mRequestQueue.size() > 0)) {
Que_T::iterator it = mRequestQueue.begin();
job = *it;
mRequestQueue.erase(it);
} else {
MY_LOGE("NormalCap RequestQueue is empty");
return BAD_VALUE;
}
}
MERROR status = onProcessEnqueFrame(&job);
if (status != OK) {
MY_LOGE("hardware cap-enque-normal fail (%d)", status);
return status;
}
num = job.edit(0).getNum();
}
P1_TRACE_C_END(SLG_S); // "Cap Normal EnQ"
//
if (num > 0) {
mLastSetNum = job.getLastNum();
mTagSet.set(mLastSetNum);
}
}
//
if (mpConCtrl != nullptr) {
mpConCtrl->cleanAidStage();
}
//
setStartState(NSP1Node::START_STATE_DRV_START);
#if 1
if (mpCamIO) {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_START_DRV_START_BGN,
LogInfo::CP_OP_START_DRV_START_END);
P1_TIMING_CHECK("P1:DRV-start", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-start");
MY_LOGI("mpCamIO->start +++");
if (!mpCamIO->start()) {
MY_LOGE("hardware start fail");
P1_TRACE_C_END(SLG_S); // "P1:DRV-start"
return BAD_VALUE;
}
MY_LOGI("mpCamIO->start ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-start"
}
#endif
//
if (isManualCap) {
setStartState(NSP1Node::START_STATE_CAP_MANUAL_ENQ);
P1_TRACE_S_BEGIN(SLG_S, "Cap Manual EnQ");
P1QueJob job(mBurstNum);
{
{
std::lock_guard<std::mutex> _l(mRequestQueueLock);
if (CC_LIKELY(mRequestQueue.size() > 0)) {
Que_T::iterator it = mRequestQueue.begin();
job = *it;
mRequestQueue.erase(it);
} else {
MY_LOGE("ManualCap RequestQueue is empty");
return BAD_VALUE;
}
}
MERROR status = onProcessEnqueFrame(&job);
if (status != OK) {
MY_LOGE("hardware cap-enque-manual fail (%d)", status);
return status;
}
num = job.edit(0).getNum();
}
P1_TRACE_C_END(SLG_S); // "Cap Manual EnQ"
//
if (num > 0) {
mLastSetNum = job.getLastNum();
mTagSet.set(mLastSetNum);
}
}
setStartState(NSP1Node::START_STATE_LMV_SENSOR_EN);
if (IS_LMV(mpConnectLMV)) {
P1_TIMING_CHECK("P1:LMV-sensor", 100, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LMV-sensor");
MY_LOGD("mpConnectLMV->enableSensor +++");
mpConnectLMV->enableSensor();
MY_LOGD("mpConnectLMV->enableSensor ---");
P1_TRACE_C_END(SLG_S); // "P1:LMV-sensor"
}
{
std::lock_guard<std::mutex> _l(mThreadLock);
setReady(MTRUE);
mThreadCond.notify_all();
}
{
std::lock_guard<std::mutex> _l(mStartLock);
setStartState(NSP1Node::START_STATE_READY);
mStartCond.notify_all();
}
syncHelperStart();
MY_LOGI("Cam::%d BinEn:%d ConfigPort[%d]:0x%x", getOpenId(), mIsBinEn,
mConfigPortNum, mConfigPort);
mLogInfo.setMemo(LogInfo::CP_OP_START_END, mBurstNum, mEnableCaptureFlow,
mInitReqSet, LogInfo::START_SET_CAPTURE);
FUNCTION_OUT;
return OK;
#else
return OK;
#endif
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::procedureAid_start() {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_S, "P1:aid_start");
MERROR status = OK;
if (mpConCtrl != nullptr && mpConCtrl->getStageCtrl() != nullptr) {
MBOOL success = MFALSE;
mpConCtrl->getStageCtrl()->wait((MUINT32)STAGE_DONE_START, &success);
if (!success) {
MY_LOGE("stage - aid start fail");
return BAD_VALUE;
}
}
//
MBOOL init_success = MTRUE;
status = buildInitItem();
if (OK != status) {
init_success = MFALSE;
MY_LOGE("CANNOT build init item");
}
if (mpConCtrl != nullptr && mpConCtrl->getStageCtrl() != nullptr) {
mpConCtrl->getStageCtrl()->done((MUINT32)STAGE_DONE_INIT_ITEM,
init_success);
}
//
FUNCTION_OUT;
return status;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::buildInitItem() {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_S, "P1:reserve_init");
if (getReady()) {
MY_LOGW("it should be executed before start ready");
return BAD_VALUE;
}
//
if (mpTaskCtrl == nullptr || mpTaskCollector == nullptr) {
return BAD_VALUE;
}
P1QueJob job(mBurstNum);
mpTaskCtrl->sessionLock();
P1TaskCollector initCollector(mpTaskCtrl);
for (int i = 0; i < mBurstNum; i++) {
P1QueAct initAct;
initCollector.enrollAct(&initAct);
createAction(&initAct, nullptr, REQ_TYPE_INITIAL);
initCollector.verifyAct(&initAct);
}
initCollector.requireJob(&job);
mpTaskCtrl->sessionUnLock();
//
if (!job.ready()) {
MY_LOGE("init-job-not-ready");
mpTaskCtrl->dumpActPool();
return BAD_VALUE;
} else {
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
mProcessingQueue.push_back(job);
}
//
P1QueJob& p_job = mProcessingQueue.at(mProcessingQueue.size() - 1);
QBufInfo* pEnBuf = nullptr;
if (mpConCtrl == nullptr || (!mpConCtrl->initBufInfo_create(&pEnBuf)) ||
pEnBuf == nullptr) {
MY_LOGE("CANNOT create the initBufInfo");
return BAD_VALUE;
}
for (size_t i = 0; i < p_job.size(); i++) {
MY_LOGD("p_job(%d)(%zu/%zu)", p_job.getIdx(), i, p_job.size());
if (OK != setupAction(&p_job.edit(i), pEnBuf)) {
MY_LOGE("setup enque act fail");
return BAD_VALUE;
}
P1Act act = GET_ACT_PTR(act, p_job.edit(i), BAD_VALUE);
act->exeState = EXE_STATE_PROCESSING;
}
//
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::generateAppMeta(P1QueAct* rAct,
NS3Av3::MetaSet_T const& result3A,
QBufInfo const& deqBuf,
IMetadata* appMetadata,
MUINT32 const index) {
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
if (act->appFrame == nullptr) {
MY_LOGW("pipeline frame is NULL (%d)", act->magicNum);
return;
}
std::shared_ptr<IPipelineFrame> request = act->appFrame;
// [3A/Flash/sensor section]
(*appMetadata) = result3A.appMeta;
MBOOL needOverrideTimestamp = MFALSE;
if (tryGetMetadata<MBOOL>(&result3A.halMeta, MTK_EIS_NEED_OVERRIDE_TIMESTAMP,
&needOverrideTimestamp) &&
needOverrideTimestamp) {
IMetadata::IEntry entry(MTK_EIS_FEATURE_ISNEED_OVERRIDE_TIMESTAMP);
entry.push_back(1, Type2Type<MUINT8>()); // Need Override timestamp
entry.push_back(0, Type2Type<MUINT8>()); // timestamp not overrided yet
(*appMetadata).update(MTK_EIS_FEATURE_ISNEED_OVERRIDE_TIMESTAMP, entry);
}
// [request section]
// android.request.frameCount
{
IMetadata::IEntry entry(MTK_REQUEST_FRAME_COUNT);
entry.push_back(request->getFrameNo(), Type2Type<MINT32>());
(*appMetadata).update(MTK_REQUEST_FRAME_COUNT, entry);
}
// android.request.metadataMode
{
IMetadata::IEntry entry(MTK_REQUEST_METADATA_MODE);
entry.push_back(MTK_REQUEST_METADATA_MODE_FULL, Type2Type<MUINT8>());
(*appMetadata).update(MTK_REQUEST_METADATA_MODE, entry);
}
// [sensor section]
// android.sensor.timestamp
{
MINT64 frame_duration = 0;
#if 1 // modify timestamp
frame_duration = act->frameExpDuration;
#endif
// ISP SOF : ISP get the first line from sensor
MINT64 Sof = (deqBuf.mvOut[index].mMetaData.mTimeStamp_B != 0)
? deqBuf.mvOut[index].mMetaData.mTimeStamp_B
: deqBuf.mvOut[index].mMetaData.mTimeStamp;
MINT64 timestamp = (Sof != 0) ? (Sof - frame_duration) : 0;
IMetadata::IEntry entry(MTK_SENSOR_TIMESTAMP);
entry.push_back(timestamp, Type2Type<MINT64>());
(*appMetadata).update(MTK_SENSOR_TIMESTAMP, entry);
}
// [sensor section]
// android.sensor.rollingshutterskew
{
MINT64 skew = 0;
queryRollingSkew(getOpenId(), &skew, mLogLevelI);
IMetadata::IEntry entry(MTK_SENSOR_ROLLING_SHUTTER_SKEW);
entry.push_back(skew, Type2Type<MINT64>());
(*appMetadata).update(MTK_SENSOR_ROLLING_SHUTTER_SKEW, entry);
}
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::generateAppTagIndex(IMetadata* appMetadata, IMetadata* appTagIndex) {
IMetadata::IEntry entryTagIndex(MTK_P1NODE_METADATA_TAG_INDEX);
for (size_t i = 0; i < (*appMetadata).count(); ++i) {
IMetadata::IEntry entry = (*appMetadata).entryAt(i);
entryTagIndex.push_back((MINT32)entry.tag(), Type2Type<MINT32>());
}
if (OK != (*appTagIndex).update(entryTagIndex.tag(), entryTagIndex)) {
MY_LOGE("fail to update index");
}
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::generateHalMeta(P1QueAct* rAct,
NS3Av3::MetaSet_T const& result3A,
QBufInfo const& deqBuf,
IMetadata const& resultAppend,
IMetadata const& inHalMetadata,
IMetadata* halMetadata,
MUINT32 const index) {
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
if (deqBuf.mvOut.size() == 0) {
MY_LOGE("deqBuf is empty");
return;
}
// 3a tuning
*halMetadata = result3A.halMeta;
// append
*halMetadata += resultAppend;
// in hal meta
*halMetadata += inHalMetadata;
{
IMetadata::IEntry entry(MTK_P1NODE_SENSOR_MODE);
entry.push_back(mSensorParams.mode, Type2Type<MINT32>());
(*halMetadata).update(MTK_P1NODE_SENSOR_MODE, entry);
}
{
IMetadata::IEntry entry(MTK_P1NODE_SENSOR_VHDR_MODE);
entry.push_back(mSensorParams.vhdrMode, Type2Type<MINT32>());
(*halMetadata).update(MTK_P1NODE_SENSOR_VHDR_MODE, entry);
}
{
IMetadata::IEntry entry(MTK_PIPELINE_FRAME_NUMBER);
entry.push_back(act->appFrame->getFrameNo(), Type2Type<MINT32>());
(*halMetadata).update(MTK_PIPELINE_FRAME_NUMBER, entry);
}
// rrzo
MUINT32 port_index = act->portBufIndex[P1_OUTPUT_PORT_RRZO];
if (port_index != P1_PORT_BUF_IDX_NONE) {
ResultMetadata const* result = &(deqBuf.mvOut[port_index].mMetaData);
if (result == nullptr) {
MY_LOGE("CANNOT get result at (%d) for (%d)", port_index, index);
return;
}
// crop region
MRect crop = result->mCrop_s;
MBOOL bIsBinEn = (act->refBinSize == mSensorParams.size) ? MFALSE : MTRUE;
{
IMetadata::IEntry entry_br(MTK_P1NODE_BIN_CROP_REGION);
entry_br.push_back(result->mCrop_s, Type2Type<MRect>());
(*halMetadata).update(MTK_P1NODE_BIN_CROP_REGION, entry_br);
IMetadata::IEntry entry_bs(MTK_P1NODE_BIN_SIZE);
entry_bs.push_back(act->refBinSize, Type2Type<MSize>());
(*halMetadata).update(MTK_P1NODE_BIN_SIZE, entry_bs);
//
if (bIsBinEn) {
BIN_REVERT(crop.p.x);
BIN_REVERT(crop.p.y);
BIN_REVERT(crop.s.w);
BIN_REVERT(crop.s.h);
}
IMetadata::IEntry entry(MTK_P1NODE_SCALAR_CROP_REGION);
entry.push_back(crop, Type2Type<MRect>());
(*halMetadata).update(MTK_P1NODE_SCALAR_CROP_REGION, entry);
}
//
{
IMetadata::IEntry entry(MTK_P1NODE_DMA_CROP_REGION);
entry.push_back(result->mCrop_d, Type2Type<MRect>());
(*halMetadata).update(MTK_P1NODE_DMA_CROP_REGION, entry);
}
//
{
IMetadata::IEntry entry(MTK_P1NODE_RESIZER_SIZE);
entry.push_back(result->mDstSize, Type2Type<MSize>());
(*halMetadata).update(MTK_P1NODE_RESIZER_SIZE, entry);
}
//
MINT32 quality = MTK_P1_RESIZE_QUALITY_LEVEL_UNKNOWN;
{
if (result->eIQlv == eCamIQ_L) {
quality = MTK_P1_RESIZE_QUALITY_LEVEL_L;
} else if (result->eIQlv == eCamIQ_H) {
quality = MTK_P1_RESIZE_QUALITY_LEVEL_H;
}
IMetadata::IEntry entry(MTK_P1NODE_RESIZE_QUALITY_LEVEL);
entry.push_back(quality, Type2Type<MINT32>());
(*halMetadata).update(MTK_P1NODE_RESIZE_QUALITY_LEVEL, entry);
}
MY_LOGI("[CropInfo] Bin(%d) Sensor" P1_SIZE_STR "ActRef" P1_SIZE_STR
"CROP_REGION" P1_RECT_STR "CropS" P1_RECT_STR "CropD" P1_RECT_STR
"DstSize" P1_SIZE_STR "- [BinQty] QUALITY_LEVEL(%d) IQlv(%d)",
bIsBinEn, P1_SIZE_VAR(mSensorParams.size),
P1_SIZE_VAR(act->refBinSize), P1_RECT_VAR(crop),
P1_RECT_VAR(result->mCrop_s), P1_RECT_VAR(result->mCrop_d),
P1_SIZE_VAR(result->mDstSize), quality, result->eIQlv);
}
//
{
MINT64 timestamp = deqBuf.mvOut[index].mMetaData.mTimeStamp;
IMetadata::IEntry entry(MTK_P1NODE_FRAME_START_TIMESTAMP);
entry.push_back(timestamp, Type2Type<MINT64>());
(*halMetadata).update(MTK_P1NODE_FRAME_START_TIMESTAMP, entry);
}
{
MINT64 timestamp_boot = deqBuf.mvOut[index].mMetaData.mTimeStamp_B;
IMetadata::IEntry entry(MTK_P1NODE_FRAME_START_TIMESTAMP_BOOT);
entry.push_back(timestamp_boot, Type2Type<MINT64>());
(*halMetadata).update(MTK_P1NODE_FRAME_START_TIMESTAMP_BOOT, entry);
}
//
if ((mIsDynamicTwinEn) && (mpCamIO != nullptr)) {
MBOOL ret = MFALSE;
MINT32 status = MTK_P1_TWIN_STATUS_NONE;
E_CamHwPathCfg curCfg = eCamHwPathCfg_Num;
ret = mpCamIO->sendCommand(ENPipeCmd_GET_HW_PATH_CFG, (MINTPTR)(&curCfg),
(MINTPTR)NULL, (MINTPTR)NULL);
if (ret) {
switch (curCfg) {
case eCamHwPathCfg_One_TG:
status = MTK_P1_TWIN_STATUS_TG_MODE_1;
break;
case eCamHwPathCfg_Two_TG:
status = MTK_P1_TWIN_STATUS_TG_MODE_2;
break;
// case eCamHwPathCfg_Num:
default:
MY_LOGI("CamHwPathCfg_Num(%d) not defined", curCfg);
break;
}
IMetadata::IEntry entry(MTK_P1NODE_TWIN_STATUS);
entry.push_back(status, Type2Type<MINT32>());
(*halMetadata).update(MTK_P1NODE_TWIN_STATUS, entry);
} else {
MY_LOGI("cannot get ENPipeCmd_GET_HW_PATH_CFG (%d)", ret);
}
MY_LOGI("(%d)=GET_HW_PATH_CFG(%d) TWIN_STATUS[%d] @ (%d)(%d:%d)", ret,
curCfg, status, act->magicNum, act->frmNum, act->reqNum);
}
//
MINT32 qtyStatus = MTK_P1_RESIZE_QUALITY_STATUS_NONE;
if (act->qualitySwitchState != QUALITY_SWITCH_STATE_NONE) {
switch (act->qualitySwitchState) {
case QUALITY_SWITCH_STATE_DONE_ACCEPT:
qtyStatus = MTK_P1_RESIZE_QUALITY_STATUS_ACCEPT;
break;
case QUALITY_SWITCH_STATE_DONE_IGNORE:
qtyStatus = MTK_P1_RESIZE_QUALITY_STATUS_IGNORE;
break;
case QUALITY_SWITCH_STATE_DONE_REJECT:
qtyStatus = MTK_P1_RESIZE_QUALITY_STATUS_REJECT;
break;
case QUALITY_SWITCH_STATE_DONE_ILLEGAL:
qtyStatus = MTK_P1_RESIZE_QUALITY_STATUS_ILLEGAL;
break;
default:
break;
}
IMetadata::IEntry entry(MTK_P1NODE_RESIZE_QUALITY_STATUS);
entry.push_back(qtyStatus, Type2Type<MINT32>());
(*halMetadata).update(MTK_P1NODE_RESIZE_QUALITY_STATUS, entry);
}
//
MBOOL qtySwitch = getQualitySwitching();
{
IMetadata::IEntry entry(MTK_P1NODE_RESIZE_QUALITY_SWITCHING);
entry.push_back(qtySwitch, Type2Type<MBOOL>());
(*halMetadata).update(MTK_P1NODE_RESIZE_QUALITY_SWITCHING, entry);
}
//
MY_LOGI("QUALITY_STATUS[%d](%d) - QUALITY_SWITCHING[%d] - " P1NUM_ACT_STR,
qtyStatus, act->qualitySwitchState, qtySwitch, P1NUM_ACT_VAR(*act));
//
if (CC_UNLIKELY(act->isRawTypeChanged)) {
MINT32 rawType = act->fullRawType;
IMetadata::IEntry entry(MTK_P1NODE_RAW_TYPE);
entry.push_back(rawType, Type2Type<MINT32>());
(*halMetadata).update(MTK_P1NODE_RAW_TYPE, entry);
MY_LOGI("MTK_P1NODE_RAW_TYPE(%d) - full raw type change - " P1NUM_ACT_STR,
rawType, P1NUM_ACT_VAR(*act));
}
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::setupAction(P1QueAct* rAct, QBufInfo* info) {
FUNCTION_IN;
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
#if SUPPORT_ISP
MUINT32 out = 0;
//
std::shared_ptr<IImageStreamInfo> pImgStreamInfo = nullptr;
std::shared_ptr<IImageBuffer> pImgBuf = nullptr;
//
NSCam::NSIoPipe::PortID portID = NSCam::NSIoPipe::PortID();
MSize dstSize = MSize(0, 0);
MRect cropRect = MRect(MPoint(0, 0), MSize(0, 0));
MUINT32 rawOutFmt = 0;
//
STREAM_IMG streamImg = STREAM_IMG_NUM;
//
if ((act->reqType == REQ_TYPE_UNKNOWN) || (act->reqType == REQ_TYPE_REDO) ||
(act->reqType == REQ_TYPE_YUV)) {
MY_LOGW("mismatch act type " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
return BAD_VALUE;
}
//
P1_TRACE_F_BEGIN(SLG_I, "P1:setup|Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum);
//
#if (IS_P1_LOGI)
std::string strInfo("");
#endif
//
for (out = 0; out < REQ_OUT_MAX; out++) {
if (!(IS_OUT(out, act->reqOutSet))) {
continue;
}
P1_TRACE_F_BEGIN(SLG_I, "REQ_OUT_%d", out);
pImgStreamInfo = nullptr;
pImgBuf = nullptr;
streamImg = STREAM_IMG_NUM;
switch (out) {
case REQ_OUT_LCSO:
case REQ_OUT_LCSO_STUFF:
streamImg = STREAM_IMG_OUT_LCS;
portID = PORT_LCSO;
dstSize = mvStreamImg[streamImg]->getImgSize();
cropRect = MRect(MPoint(0, 0), mvStreamImg[streamImg]->getImgSize());
rawOutFmt = (EPipe_PROCESSED_RAW);
if (out == REQ_OUT_LCSO_STUFF) {
// not use stuff buffer with height:1
cropRect.s = dstSize;
}
break;
case REQ_OUT_RSSO:
case REQ_OUT_RSSO_STUFF:
streamImg = STREAM_IMG_OUT_RSS;
portID = PORT_RSSO;
dstSize = mvStreamImg[streamImg]->getImgSize();
cropRect = MRect(MPoint(0, 0), mvStreamImg[streamImg]->getImgSize());
rawOutFmt = (EPipe_PROCESSED_RAW);
if (out == REQ_OUT_RSSO_STUFF) {
// not use stuff buffer with height:1
cropRect.s = dstSize;
}
break;
case REQ_OUT_RESIZER:
case REQ_OUT_RESIZER_STUFF:
streamImg = STREAM_IMG_OUT_RESIZE;
portID = PORT_RRZO;
dstSize = act->dstSize_resizer;
cropRect = act->cropRect_resizer;
rawOutFmt = (EPipe_PROCESSED_RAW);
if (out == REQ_OUT_RESIZER_STUFF) {
// use stuff buffer with height:1
cropRect.s = dstSize;
}
break;
case REQ_OUT_FULL_PROC:
case REQ_OUT_FULL_PURE:
case REQ_OUT_FULL_OPAQUE:
case REQ_OUT_FULL_STUFF:
streamImg = STREAM_IMG_OUT_FULL;
if (out == REQ_OUT_FULL_OPAQUE ||
(out == REQ_OUT_FULL_STUFF &&
act->streamBufImg[STREAM_IMG_OUT_OPAQUE].bExist)) {
streamImg = STREAM_IMG_OUT_OPAQUE;
} else if (mvStreamImg[STREAM_IMG_OUT_FULL] != nullptr) {
streamImg = STREAM_IMG_OUT_FULL;
} else if (mvStreamImg[STREAM_IMG_OUT_OPAQUE] != nullptr) {
streamImg = STREAM_IMG_OUT_OPAQUE;
}
portID = PORT_IMGO;
dstSize = act->dstSize_full;
cropRect = act->cropRect_full;
rawOutFmt = act->fullRawType;
//
if (out == REQ_OUT_FULL_STUFF) {
cropRect.s = dstSize;
}
break;
}
//
if (streamImg < STREAM_IMG_NUM) {
pImgStreamInfo = mvStreamImg[streamImg];
} else {
MY_LOGW(
"cannot find the StreamImg num:%d out:%d "
"streamImg:%d",
act->magicNum, out, streamImg);
return BAD_VALUE;
}
if (pImgStreamInfo == nullptr) {
MY_LOGW(
"cannot find the ImgStreamInfo num:%d out:%d "
"streamImg:%d",
act->magicNum, out, streamImg);
return BAD_VALUE;
}
//
MERROR err = OK;
if (out == REQ_OUT_FULL_STUFF || out == REQ_OUT_RESIZER_STUFF ||
out == REQ_OUT_LCSO_STUFF || out == REQ_OUT_RSSO_STUFF) {
err = act->stuffImageGet(streamImg, dstSize, &pImgBuf);
} else if (act->reqType == REQ_TYPE_INITIAL) {
// the initial act with the pool, it do not use the stuff buffer
err = act->poolImageGet(streamImg, &pImgBuf);
} else { // REQ_TYPE_NORMAL
if (OK != act->frameImageGet(streamImg, &pImgBuf)) {
// keep en-queue/de-queue processing
if (out == REQ_OUT_LCSO || out == REQ_OUT_RSSO ||
((mEnableDumpRaw || mCamDumpEn) &&
(out == REQ_OUT_FULL_PURE || out == REQ_OUT_FULL_PROC ||
out == REQ_OUT_FULL_OPAQUE))) {
MY_LOGI("keep the output size out:%d", out);
} else {
cropRect.s.h = dstSize.h;
}
err = act->stuffImageGet(streamImg, dstSize, &pImgBuf);
if (out == REQ_OUT_RESIZER) {
act->expRec |= EXP_REC(EXP_EVT_NOBUF_RRZO);
} else if (out == REQ_OUT_LCSO) {
act->expRec |= EXP_REC(EXP_EVT_NOBUF_LCSO);
} else if (out == REQ_OUT_RSSO) {
act->expRec |= EXP_REC(EXP_EVT_NOBUF_RSSO);
} else {
act->expRec |= EXP_REC(EXP_EVT_NOBUF_IMGO);
}
MY_LOGI(
"underway-stuff-buffer status(%d) out[%s](%d) "
"stream(%#" PRIx64 ") " P1INFO_ACT_STR,
err, P1_PORT_TO_STR(portID), out, pImgStreamInfo->getStreamId(),
P1INFO_ACT_VAR(*act));
}
}
//
if (CC_UNLIKELY((pImgBuf == nullptr) || (err != OK))) {
MY_LOGE("Cannot get ImgBuf status(%d) out[%s](%d)" P1INFO_ACT_STR, err,
P1_PORT_TO_STR(portID), out, P1INFO_ACT_VAR(*act));
mLogInfo.inspect(LogInfo::IT_BUFFER_EXCEPTION);
return BAD_VALUE;
}
//
if ((out == REQ_OUT_RESIZER || out == REQ_OUT_RESIZER_STUFF) ||
(out == REQ_OUT_FULL_PURE || out == REQ_OUT_FULL_PROC ||
out == REQ_OUT_FULL_OPAQUE || out == REQ_OUT_FULL_STUFF)) {
std::shared_ptr<IImageBufferHeap> pHeap = pImgBuf->getImageBufferHeap();
if (pHeap != nullptr) {
pHeap->setColorArrangement((MINT32)mSensorFormatOrder);
}
}
//
#if (IS_P1_LOGI)
if (1 <= mLogLevelI) {
strInfo += base::StringPrintf(
"[%s][%d](x%x)"
"(Buf)(%dx%d)(S:%d:%d P:%p V:%p F:0x%x)"
"(Crop)(%d,%d-%dx%d)(%dx%d) ",
P1_PORT_TO_STR(portID), out, rawOutFmt, pImgBuf->getImgSize().w,
pImgBuf->getImgSize().h,
static_cast<int>(pImgBuf->getBufStridesInBytes(0)),
static_cast<int>(pImgBuf->getBufSizeInBytes(0)),
reinterpret_cast<void*>(pImgBuf->getBufPA(0)),
reinterpret_cast<void*>(pImgBuf->getBufVA(0)),
pImgBuf->getImgFormat(), cropRect.p.x, cropRect.p.y, cropRect.s.w,
cropRect.s.h, dstSize.w, dstSize.h);
}
#endif
BufInfo rBufInfo(portID, pImgBuf.get(), dstSize, cropRect, act->magicNum,
act->sofIdx, rawOutFmt);
(*info).mvOut.push_back(rBufInfo);
P1_TRACE_C_END(SLG_I); // "REQ_OUT"
} // end of the loop for each out
{
if (IS_PORT(CONFIG_PORT_EISO, mConfigPort)) {
std::shared_ptr<IImageBuffer> pImgBuf = NULL;
MY_LOGD("mpConnectLMV->getBuf +++");
if (IS_LMV(mpConnectLMV)) {
mpConnectLMV->getBuf(&pImgBuf);
}
MY_LOGD("mpConnectLMV->getBuf ---");
if (pImgBuf == NULL) {
MY_LOGE("(%d) Cannot get LMV buffer", act->magicNum);
return BAD_VALUE;
}
MY_LOGD(" get LMV out[%s](%d) P(%p) V(%p)" P1INFO_ACT_STR,
P1_PORT_TO_STR(PORT_EISO), out, (void*)pImgBuf->getBufPA(0),
(void*)pImgBuf->getBufVA(0), P1INFO_ACT_VAR(*act));
act->buffer_eiso = pImgBuf;
BufInfo rBufInfo(PORT_EISO, pImgBuf.get(), pImgBuf->getImgSize(),
MRect(MPoint(0, 0), pImgBuf->getImgSize()),
act->magicNum, act->sofIdx);
(*info).mvOut.push_back(rBufInfo);
}
}
mTagEnq.set(rAct->getNum());
if (1 <= mLogLevelI) {
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::ENQ_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum,
act->flushSet);
P1_LOGI(1, "[P1::ENQ]" P1INFO_ACT_STR " %s", P1INFO_ACT_VAR(*act),
strInfo.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::ENQ_LOG"
}
//
P1_TRACE_C_END(SLG_I); // "P1:setup"
#endif
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_enque(P1QueJob* job, ENQ_TYPE type, MINT64 data) {
FUNCTION_IN;
P1_TRACE_AUTO(SLG_I, "P1:enque");
if (!getActive()) {
return BAD_VALUE;
}
if (mpCamIO == nullptr) {
MY_LOGE("NormalPipe is NULL");
return BAD_VALUE;
}
MY_LOGD("EnQ[%d](%" PRId64 ") @ (%d)", type, data, job->getIdx());
MBOOL toPush = (type == ENQ_TYPE_INITIAL) ? MFALSE : MTRUE;
MBOOL toSwitchUNI = MFALSE;
MUINT8 toSwtTgNum = 0;
MUINT32 toSwitchQuality = QUALITY_SWITCH_STATE_NONE;
#if SUPPORT_ISP
//
QBufInfo enBuf;
QBufInfo* pEnBuf = &enBuf;
if ((type == ENQ_TYPE_INITIAL) && (!EN_INIT_REQ_RUN)) {
if (mpConCtrl == nullptr || (!mpConCtrl->initBufInfo_get(&pEnBuf)) ||
pEnBuf == nullptr) {
MY_LOGE("CANNOT get the initBufInfo");
return BAD_VALUE;
}
} else {
for (size_t i = 0; i < job->size(); i++) {
MY_LOGD("job(%d)(%zu/%zu)", job->getIdx(), i, job->size());
P1QueAct& rAct = job->edit(i);
P1Act act = GET_ACT_PTR(act, rAct, BAD_VALUE);
if (OK != setupAction(&rAct, &enBuf)) {
MY_LOGE("setup enque act fail");
return BAD_VALUE;
}
if (i == 0 && act->reqType == REQ_TYPE_NORMAL) {
if (type == ENQ_TYPE_DIRECTLY) {
act->frameExpDuration = data * ONE_US_TO_NS;
}
enBuf.mShutterTimeNs = act->frameExpDuration;
}
if (act->uniSwitchState == UNI_SWITCH_STATE_REQ) {
toSwitchUNI = MTRUE;
}
if (act->tgSwitchState == TG_SWITCH_STATE_REQ) {
toSwtTgNum = act->tgSwitchNum;
}
if ((act->qualitySwitchState & QUALITY_SWITCH_STATE_REQ_NON) > 0) {
toSwitchQuality = act->qualitySwitchState;
}
act->exeState = EXE_STATE_PROCESSING;
}
}
//
if (EN_START_CAP && (!getReady()) && (type == ENQ_TYPE_NORMAL)) {
std::unique_lock<std::mutex> lck(mStartCaptureLock);
MUINT32 cnt = 0;
std::cv_status res;
MY_LOGD("StartCaptureState(%d) Cnt(%d)", mStartCaptureState, cnt);
while (mStartCaptureState == START_CAP_STATE_WAIT_CB) {
P1_TRACE_F_BEGIN(SLG_S, "StartCapture wait [%d]", cnt);
res = mStartCaptureCond.wait_for(
lck, std::chrono::nanoseconds(P1_CAPTURE_CHECK_INV_NS));
P1_TRACE_C_END(SLG_S); // "StartCapture wait"
if (res == std::cv_status::timeout) {
MY_LOGI("StartCap(%d) Cnt(%d) Res(%d)", mStartCaptureState, cnt, res);
mLogInfo.inspect(LogInfo::IT_WAIT_CATURE);
} else {
break;
}
}
P1Act act = GET_ACT_PTR(act, job->edit(0), BAD_VALUE);
act->capType = mStartCaptureType;
act->frameExpDuration = mStartCaptureExp;
act->sofIdx = mStartCaptureIdx;
for (size_t i = 0; i < pEnBuf->mvOut.size(); i++) {
pEnBuf->mvOut[i].FrameBased.mSOFidx = mStartCaptureIdx;
}
pEnBuf->mShutterTimeNs = mStartCaptureExp;
}
//
if (toSwitchUNI) {
UNI_SWITCH_STATE uniState = UNI_SWITCH_STATE_REQ;
MUINT32 switchState = 0;
MBOOL res = MFALSE;
if (mpCamIO->sendCommand(ENPipeCmd_GET_UNI_SWITCH_STATE,
(MINTPTR)(&switchState), (MINTPTR)NULL,
(MINTPTR)NULL) &&
switchState == 0) { // DRV: If switch state is NULL, then do switch.
res = mpCamIO->sendCommand(ENPipeCmd_UNI_SWITCH, (MINTPTR)NULL,
(MINTPTR)NULL, (MINTPTR)NULL);
if (res) {
uniState = UNI_SWITCH_STATE_ACT_ACCEPT;
} else {
uniState = UNI_SWITCH_STATE_ACT_IGNORE;
}
} else {
uniState = UNI_SWITCH_STATE_ACT_REJECT;
}
//
for (size_t i = 0; i < job->size(); i++) {
P1Act act = GET_ACT_PTR(act, job->edit(i), BAD_VALUE);
if (act->uniSwitchState == UNI_SWITCH_STATE_REQ) {
act->uniSwitchState = uniState;
MY_LOGD("UNI-Switch(%d)(%d,%d) drv(%d,%d):(%d)", act->magicNum,
act->frmNum, act->reqNum, switchState, res, uniState);
}
}
}
//
if (toSwtTgNum) {
TG_SWITCH_STATE tgState = TG_SWITCH_STATE_DONE_IGNORE;
MBOOL res = MFALSE;
MBOOL ret = MFALSE;
MBOOL rev = MFALSE;
MBOOL isOn = MFALSE;
E_CamHwPathCfg curCfg = eCamHwPathCfg_Num;
E_CamHwPathCfg tarCfg = eCamHwPathCfg_Num;
switch (toSwtTgNum) {
case 1:
tarCfg = eCamHwPathCfg_One_TG;
break;
case 2:
tarCfg = eCamHwPathCfg_Two_TG;
break;
default:
MY_LOGI("check act TG state num (%d)", toSwtTgNum);
break;
}
if (mpCamIO != nullptr) {
res = mpCamIO->sendCommand(ENPipeCmd_GET_DTwin_INFO, (MINTPTR)(&isOn),
(MINTPTR)NULL, (MINTPTR)NULL);
if (res && isOn) {
ret =
mpCamIO->sendCommand(ENPipeCmd_GET_HW_PATH_CFG, (MINTPTR)(&curCfg),
(MINTPTR)NULL, (MINTPTR)NULL);
}
if (!res) {
MY_LOGI("sendCmd ENPipeCmd_GET_DTwin_INFO (%d)", res);
} else if (!isOn) {
MY_LOGI("DynamicTwin not ready (%d)", isOn);
} else if (!ret) {
MY_LOGI("sendCmd ENPipeCmd_GET_HW_PATH_CFG (%d)", ret);
} else if (curCfg == eCamHwPathCfg_Num) {
MY_LOGI("check current num (%d)", curCfg);
} else if (tarCfg == eCamHwPathCfg_Num) {
MY_LOGI("check target num (%d)", tarCfg);
} else if (curCfg == tarCfg) {
MY_LOGI("CamHwPathCfg is ready (%d) == (%d)", curCfg, tarCfg);
} else {
rev = mpCamIO->sendCommand(ENPipeCmd_SET_HW_PATH_CFG, (MINTPTR)(tarCfg),
(MINTPTR)NULL, (MINTPTR)NULL);
if (!rev) {
MY_LOGI("sendCmd ENPipeCmd_SET_HW_PATH_CFG (%d)", rev);
tgState = TG_SWITCH_STATE_DONE_REJECT;
} else {
tgState = TG_SWITCH_STATE_DONE_ACCEPT;
}
}
}
//
for (size_t i = 0; i < job->size(); i++) {
P1Act act = GET_ACT_PTR(act, job->edit(i), BAD_VALUE);
if (act->tgSwitchState == TG_SWITCH_STATE_REQ) {
act->tgSwitchState = tgState;
act->tgSwitchNum = 0;
MY_LOGI("TG(%d)(%d,%d) Drv(%d) Swt(%d)(%d,%d)(%d,%d,%d):%d",
act->magicNum, act->frmNum, act->reqNum, isOn, toSwtTgNum,
curCfg, tarCfg, res, ret, rev, tgState);
}
}
}
//
if (toSwitchQuality != QUALITY_SWITCH_STATE_NONE) {
QUALITY_SWITCH_STATE switchQuality = QUALITY_SWITCH_STATE_DONE_REJECT;
MBOOL ret = MFALSE;
if (mpCamIO != nullptr && mpRegisterNotify != nullptr) {
E_CamIQLevel CamLvA = eCamIQ_L;
E_CamIQLevel CamLvB = eCamIQ_L;
if ((toSwitchQuality & QUALITY_SWITCH_STATE_REQ_H_A) > 0) {
CamLvA = eCamIQ_H;
}
if ((toSwitchQuality & QUALITY_SWITCH_STATE_REQ_H_B) > 0) {
CamLvB = eCamIQ_H;
}
ret =
mpCamIO->sendCommand(ENPipeCmd_SET_QUALITY,
(MINTPTR)(mpRegisterNotify->getNotifyQuality()),
(MINTPTR)CamLvA, (MINTPTR)CamLvB);
if (!ret) {
MY_LOGI("sendCommand ENPipeCmd_SET_QUALITY fail(%d)", ret);
switchQuality = QUALITY_SWITCH_STATE_DONE_REJECT;
setQualitySwitching(MFALSE);
} else {
switchQuality = QUALITY_SWITCH_STATE_DONE_ACCEPT;
}
}
for (size_t i = 0; i < job->size(); i++) {
P1Act act = GET_ACT_PTR(act, job->edit(i), BAD_VALUE);
if ((act->qualitySwitchState & QUALITY_SWITCH_STATE_REQ_NON) > 0) {
MY_LOGI("ResizeQ (%d)(%d,%d) Ret(%d) QualitySwt(%d => %d)",
act->magicNum, act->frmNum, act->reqNum, ret,
act->qualitySwitchState, switchQuality);
act->qualitySwitchState = switchQuality;
}
}
}
//
if (toPush) {
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
mProcessingQueue.push_back(*job);
MY_LOGD("Push(%d) to ProQ(%zu)", job->getIdx(), mProcessingQueue.size());
}
//
MBOOL isErr = MFALSE;
P1Act act = GET_ACT_PTR(act, job->edit(0), BAD_VALUE);
MINT32 numF = act->frmNum;
MINT32 numR = act->reqNum;
// check CtrlSync before EnQ
if ((IS_BURST_OFF) && // exclude burst mode
(type != ENQ_TYPE_INITIAL) && (job->size() >= 1)) {
attemptCtrlSync(&(job->edit(0)));
}
//
if ((mspSyncHelper != nullptr) && (type != ENQ_TYPE_INITIAL)) {
IMetadata ctrlMeta;
act->frameMetadataGet(STREAM_META_IN_HAL, &ctrlMeta);
mspSyncHelper->syncEnqHW(getOpenId(), &ctrlMeta);
}
//
if (type == ENQ_TYPE_DIRECTLY) {
#if (MTKCAM_HAVE_SANDBOX_SUPPORT == 0)
P1_TRACE_F_BEGIN(SLG_E,
"P1:DRV-resume|"
"Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, numF, numR);
MY_LOGI("mpCamIO->resume +++");
if (!mpCamIO->resume((QBufInfo const*)(pEnBuf))) {
MY_LOGE("[SUS-RES] DRV resume fail");
if (mpHwStateCtrl != nullptr) {
mpHwStateCtrl->dump();
}
isErr = MTRUE;
}
MY_LOGI("mpCamIO->resume ---");
P1_TRACE_C_END(SLG_E); // "P1:DRV-resume"
#endif
} else { // ENQ_TYPE_NORMAL / ENQ_TYPE_INITIAL
mLogInfo.setMemo(LogInfo::CP_ENQ_BGN, act->magicNum, numF, numR,
act->sofIdx);
P1_TRACE_F_BEGIN(SLG_I,
"P1:DRV-enque|"
"Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, numF, numR);
{
IHalSensorList* pHalSensorList = GET_HalSensorList();
IHalSensor* pHalSensor =
pHalSensorList->createSensor(LOG_TAG, getOpenId());
MUINT32 sensorDevId = pHalSensorList->querySensorDevIdx(getOpenId());
MY_LOGD("openId %d, sensorDevId %d, mMeta_PatMode %d", getOpenId(),
sensorDevId, mMeta_PatMode);
MINT ret = pHalSensor->sendCommand(
sensorDevId, SENSOR_CMD_SET_TEST_PATTERN_OUTPUT,
(MUINTPTR)&mMeta_PatMode, sizeof(MUINT32), 0, sizeof(MUINT32), 0,
sizeof(MUINT32));
if (ret != 0) {
MY_LOGE("sendCommand set pattern output fail(%d)", ret);
}
}
MY_LOGI("mpCamIO->enque +++");
if (!mpCamIO->enque(*pEnBuf)) {
MY_LOGE("DRV-enque fail");
isErr = MTRUE;
}
MY_LOGI("mpCamIO->enque ---");
P1_TRACE_C_END(SLG_I); // "P1:DRV-enque"
mLogInfo.setMemo(LogInfo::CP_ENQ_END, act->magicNum, numF, numR,
act->sofIdx);
}
//
if (isErr) {
if (toPush) {
std::lock_guard<std::mutex> _l(mProcessingQueueLock);
Que_T::iterator it = mProcessingQueue.begin();
for (; it != mProcessingQueue.end(); it++) {
if ((*it).getIdx() == job->getIdx()) {
break;
}
}
if (it != mProcessingQueue.end()) {
mProcessingQueue.erase(it);
}
MY_LOGD("Erase(%d) from ProQ(%zu)", job->getIdx(),
mProcessingQueue.size());
}
return BAD_VALUE;
}
//
if (type == ENQ_TYPE_INITIAL) {
mpConCtrl->initBufInfo_clean();
}
#endif
FUNCTION_OUT;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_deque(QBufInfo* deqBuf) {
#if SUPPORT_ISP
FUNCTION_IN;
P1_TRACE_AUTO(SLG_I, "P1:deque");
if (!getActive()) {
return BAD_VALUE;
}
std::lock_guard<std::mutex> _l(mHardwareLock);
if (!getActive()) {
return BAD_VALUE;
}
{
// deque buffer, and handle frame and metadata
MY_LOGD("%" PRId64 ", %f", mDequeThreadProfile.getAvgDuration(),
mDequeThreadProfile.getFps());
QPortID PortID;
if (IS_PORT(CONFIG_PORT_IMGO,
mConfigPort)) { // (mvOutImage_full.size() > 0) {
PortID.mvPortId.push_back(PORT_IMGO);
}
if (IS_PORT(CONFIG_PORT_RRZO,
mConfigPort)) { // (mOutImage_resizer != NULL) {
PortID.mvPortId.push_back(PORT_RRZO);
}
if (IS_PORT(CONFIG_PORT_EISO, mConfigPort)) {
PortID.mvPortId.push_back(PORT_EISO);
}
if (IS_PORT(CONFIG_PORT_LCSO, mConfigPort)) {
PortID.mvPortId.push_back(PORT_LCSO);
}
if (IS_PORT(CONFIG_PORT_RSSO, mConfigPort)) {
PortID.mvPortId.push_back(PORT_RSSO);
}
// for mBurstNum: 4 and port: I+R+E+L, the buffer is as
// [I1][I2][I3][I4][R1][R2][R3][R4][E1][E2][E3][E4][L1][L2][L3][L4]
mDequeThreadProfile.pulse_down();
//
P1_TRACE_F_BEGIN(SLG_I, "P1:DRV-deque@[0x%X]", mConfigPort);
mLogInfo.setMemo(LogInfo::CP_DEQ_BGN);
MY_LOGI("mpCamIO->deque +++");
if (!mpCamIO->deque(PortID, deqBuf)) {
if (getActive()) {
MY_LOGE("DRV-deque fail");
} else {
MY_LOGI("DRV-deque fail - after stop");
P1_TRACE_C_END(SLG_I); // "P1:DRV-deque"
return OK;
}
P1_TRACE_C_END(SLG_I); // "P1:DRV-deque"
return BAD_VALUE;
}
MY_LOGI("mpCamIO->deque ---");
mLogInfo.setMemo(LogInfo::CP_DEQ_END,
(deqBuf->mvOut.size() > 0)
? (deqBuf->mvOut[0].mMetaData.mMagicNum_hal)
: 0);
P1_TRACE_C_END(SLG_I); // "P1:DRV-deque"
//
mDequeThreadProfile.pulse_up();
}
for (size_t i = 0; i < deqBuf->mvOut.size(); i++) {
MY_LOGI(
"P1 width*height:%d*%d, mvPortId %d, mSize %d, getBufSizeInBytes(0) "
"%d, mMetaData.mDstSize.w %d, mMetaData.mDstSize.h %d",
deqBuf->mvOut[i].mBuffer->getImgSize().w,
deqBuf->mvOut[i].mBuffer->getImgSize().h,
deqBuf->mvOut[i].mPortID.index, deqBuf->mvOut[i].mSize,
deqBuf->mvOut[i].mBuffer->getBufSizeInBytes(0),
deqBuf->mvOut[i].mMetaData.mDstSize.w,
deqBuf->mvOut[i].mMetaData.mDstSize.h);
}
//
if (mDebugScanLineMask != 0 && mpDebugScanLine != nullptr) {
P1_TRACE_AUTO(SLG_E, "DrawScanLine");
for (size_t i = 0; i < deqBuf->mvOut.size(); i++) {
if ((deqBuf->mvOut[i].mPortID.index == PORT_RRZO.index &&
mDebugScanLineMask & DRAWLINE_PORT_RRZO) ||
(deqBuf->mvOut[i].mPortID.index == PORT_IMGO.index &&
mDebugScanLineMask & DRAWLINE_PORT_IMGO)) {
mpDebugScanLine->drawScanLine(
deqBuf->mvOut[i].mBuffer->getImgSize().w,
deqBuf->mvOut[i].mBuffer->getImgSize().h,
reinterpret_cast<void*>(deqBuf->mvOut[i].mBuffer->getBufVA(0)),
deqBuf->mvOut[i].mBuffer->getBufSizeInBytes(0),
deqBuf->mvOut[i].mBuffer->getBufStridesInBytes(0));
}
}
}
#if 1
if (mEnableDumpRaw && deqBuf->mvOut.size() > 0) {
MUINT32 magicNum = deqBuf->mvOut.at(0).mMetaData.mMagicNum_hal;
/* Record previous "debug.p1.pureraw_dump" prop value.
* When current prop value is not equal to previous prop value, it will
* start dump raw. When current prop value is > 0 value, it will dump
* continuous raw. For example, assume current prop value is 10 ,it will
* start continuous 10 raw dump.
*/
static MINT32 prevDumpProp = 0;
static MUINT32 continueDumpCount = 0;
/* If current "debug.p1.pureraw_dump" prop value < 0, this variable will
* save it. This variable is used to continuous magic number dump raws. For
* example, assume current prop value is -20. When pipeline starts, it will
* dump frames with magic num < 20.
*/
static MUINT32 indexRawDump = 0;
MINT32 currentDumpProp =
property_get_int32("vendor.debug.p1.pureraw_dump", 0);
if (prevDumpProp != currentDumpProp) {
if (currentDumpProp == 0) {
prevDumpProp = 0;
indexRawDump = 0;
continueDumpCount = 0;
} else if (currentDumpProp < 0) {
indexRawDump = (MUINT32)(-currentDumpProp);
} else if (currentDumpProp > 0) {
continueDumpCount = (MUINT32)currentDumpProp;
}
prevDumpProp = currentDumpProp;
}
if ((magicNum <= indexRawDump) || continueDumpCount > 0) {
if (continueDumpCount > 0) {
continueDumpCount--;
}
for (size_t i = 0; i < deqBuf->mvOut.size(); i++) {
char filename[256] = {0};
snprintf(filename, sizeof(filename),
"%s/p1_%u_%d_%04dx%04d_%04d_%d.raw", P1NODE_DUMP_PATH,
magicNum,
((deqBuf->mvOut.at(i).mPortID.index == PORT_RRZO.index) ? (0)
: (1)),
static_cast<int>(deqBuf->mvOut.at(i).mBuffer->getImgSize().w),
static_cast<int>(deqBuf->mvOut.at(i).mBuffer->getImgSize().h),
static_cast<int>(
deqBuf->mvOut.at(i).mBuffer->getBufStridesInBytes(0)),
static_cast<int>(mSensorFormatOrder));
P1_TRACE_AUTO(SLG_E, filename);
deqBuf->mvOut.at(i).mBuffer->saveToFile(filename);
MY_LOGI("save to file : %s", filename);
}
}
}
#endif
FUNCTION_OUT;
return OK;
#else
return OK;
#endif
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_stop() {
#if SUPPORT_ISP
P1_TRACE_AUTO(SLG_B, "P1:hardwareOps_stop");
// (1) handle active flag
if (!getActive()) {
MY_LOGD("active=%d - return", getActive());
return OK;
}
FUNCTION_IN;
MY_LOGI("Cam::%d Req=%d Set=%d Enq=%d Deq=%d Out=%d", getOpenId(),
mTagReq.get(), mTagSet.get(), mTagEnq.get(), mTagDeq.get(),
mTagOut.get());
MINT32 frmNum = P1_FRM_NUM_NULL;
MINT32 reqNum = P1_REQ_NUM_NULL;
MINT32 cnt = lastFrameRequestInfoNotice(&frmNum, &reqNum);
mLogInfo.setMemo(LogInfo::CP_OP_STOP_BGN, frmNum, reqNum, cnt);
setActive(MFALSE);
setReady(MFALSE);
setStartState(NSP1Node::START_STATE_NULL);
//
{
std::lock_guard<std::mutex> _ll(mFrameSetLock);
mFrameSetAlready = MFALSE;
}
//
if (getInit()) {
MY_LOGI("mHardwareLock waiting +++");
std::lock_guard<std::mutex> _l(mHardwareLock);
MY_LOGI("mHardwareLock waiting ---");
}
if (mpHwStateCtrl != nullptr) {
mpHwStateCtrl->reset();
}
// (2.2) stop 3A stt
#if SUPPORT_3A
if (mp3A) {
std::lock_guard<std::mutex> _sl(mStopSttLock);
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_STOP_3A_STOPSTT_BGN,
LogInfo::CP_OP_STOP_3A_STOPSTT_END);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-stopStt");
MY_LOGI("mp3A->stopStt +++");
mp3A->stopStt();
MY_LOGI("mp3A->stopStt ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-stopStt"
}
#endif
#if MTKCAM_HAVE_SANDBOX_SUPPORT
// stop v4l2sttpipe after 3A
MY_LOGI("stop V4L2SttPipeMgr +++");
if (CC_LIKELY(mpV4L2SttPipe.get() != nullptr)) {
mpV4L2SttPipe->stop();
mpV4L2SttPipe = nullptr;
}
MY_LOGI("stop V4L2SttPipeMgr ---");
// stop Event listener
MY_LOGI("stop V4L2HwEventWorker +++");
auto _stopHwEventMgr = [this](size_t idx) -> void {
if (mpV4L2HwEventMgr[idx].get() == nullptr) {
return;
}
mpV4L2HwEventMgr[idx]->requestExit(); // request to exit first,
mpV4L2HwEventMgr[idx]->signal(); // send a fake signal ASAP
mpV4L2HwEventMgr[idx]->stop(); // stop loop
mpV4L2HwEventMgr[idx] = nullptr; // release resource
};
_stopHwEventMgr(0);
_stopHwEventMgr(1);
_stopHwEventMgr(2);
MY_LOGI("stop V4L2HwEventWorker ---");
#endif
// (2.3) stop isp
if (CC_UNLIKELY(mpCamIO == nullptr)) {
MY_LOGE("hardware CamIO not exist");
return BAD_VALUE;
}
{
// std::lock_guard<std::mutex> _l(mHardwareLock);
if (mLongExp.get()) {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_STOP_DRV_STOP_BGN,
LogInfo::CP_OP_STOP_DRV_STOP_END,
MTRUE /* call abort */);
#if (MTKCAM_HAVE_SANDBOX_SUPPORT == 0)
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-abort");
MY_LOGI("mpCamIO->abort +++");
if (!mpCamIO->abort()) {
MY_LOGE("hardware abort fail");
// return BAD_VALUE;
}
MY_LOGI("mpCamIO->abort ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-abort"
#endif
} else {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_STOP_DRV_STOP_BGN,
LogInfo::CP_OP_STOP_DRV_STOP_END,
MFALSE /* not abort */);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-stop");
MY_LOGI("mpCamIO->stop +++");
if (!mpCamIO->stop(/*MTRUE*/)) {
MY_LOGE("hardware stop fail");
}
MY_LOGI("mpCamIO->stop ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-stop"
}
}
mLogInfo.setMemo(LogInfo::CP_OP_STOP_HW_LOCK_BGN);
MY_LOGI("HwLockStopWait +++");
std::lock_guard<std::mutex> _l(mHardwareLock);
MY_LOGI("HwLockStopWait ---");
mLogInfo.setMemo(LogInfo::CP_OP_STOP_HW_LOCK_END);
// (3.0) stop 3A
#if SUPPORT_3A
if (mp3A) {
P1_TRACE_C_END(SLG_S); // "P1:LMV-enableOIS"
#if SUPPORT_FSC
if (mpFSC != nullptr) {
mpFSC->Uninit(mp3A); // detach 3A CB before 3A->stop()
}
#endif
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-sendCtrl-detachCb");
//
mp3A->detachCb(IHal3ACb::eID_NOTIFY_3APROC_FINISH, this);
mp3A->detachCb(IHal3ACb::eID_NOTIFY_CURR_RESULT, this);
mp3A->detachCb(IHal3ACb::eID_NOTIFY_VSYNC_DONE, this);
P1_TRACE_C_END(SLG_S); // "P1:3A-sendCtrl-detachCb"
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_STOP_3A_STOP_BGN,
LogInfo::CP_OP_STOP_3A_STOP_END);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-stop");
MY_LOGI("mp3A->stop +++");
mp3A->stop();
MY_LOGI("mp3A->stop ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-stop"
}
#endif
// (3.1) destroy 3A
#if SUPPORT_3A
if (mp3A) {
if (getPowerNotify()) {
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OP_STOP_3A_PWROFF_BGN,
LogInfo::CP_OP_STOP_3A_PWROFF_END);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-notifyPwrOff");
MY_LOGI("mp3A->notifyP1PwrOff +++");
mp3A->notifyP1PwrOff(); // CCU DRV power off before ISP uninit.
MY_LOGI("mp3A->notifyP1PwrOff ---");
P1_TRACE_C_END(SLG_S); // "P1:3A-notifyPwrOff"
} else {
MY_LOGI("3A->notifyP1PwrOff() no need");
}
setPowerNotify(MFALSE);
//
mp3A = nullptr;
}
#endif
// (3.1.1) stop v4l2 pipe (IPC only)
#if MTKCAM_HAVE_SANDBOX_SUPPORT
if (mpV4L2LensMgr.get()) {
MY_LOGI("stop V4L2LensMgr +++");
mpV4L2LensMgr->stop();
mpV4L2LensMgr = nullptr;
MY_LOGI("stop V4L2LensMgr ---");
}
if (mpV4L2SensorMgr.get()) {
MY_LOGI("stop V4L2SensorWorker +++");
mpV4L2SensorMgr->stop();
mpV4L2SensorMgr = nullptr; // clear resource
MY_LOGI("stop V4L2SensorWorker ---");
}
if (mpV4L2P13ACallback.get()) {
MY_LOGI("stop V4L2P13ACallback +++");
mpV4L2P13ACallback->stop();
mpV4L2P13ACallback = nullptr;
MY_LOGI("stop V4L2P13ACallback ---");
}
if (mpV4L2TuningPipe.get()) {
MY_LOGI("stop V4L2TuningPipeMgr +++");
mpV4L2TuningPipe->stop();
mpV4L2TuningPipe = nullptr;
MY_LOGI("stop V4L2TuningPipeMgr ---");
}
#endif
if (IS_LMV(mpConnectLMV)) {
mpConnectLMV->uninit();
}
// (3.2) destroy isp
{
//
#if SUPPORT_LCS
if (mpLCS) {
mpLCS->Uninit();
mpLCS->DestroyInstance(
LOG_TAG); // instance always exist until process kill
mpLCS = nullptr;
}
#endif
#if SUPPORT_RSS
if (mpRSS != nullptr) {
mpRSS->Uninit();
mpRSS = nullptr;
}
#endif
#if SUPPORT_FSC
mpFSC = nullptr;
#endif
//
mLogInfo.setMemo(LogInfo::CP_OP_STOP_DRV_UNINIT_BGN);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-uninit");
MY_LOGI("mpCamIO->uninit +++");
if (!mpCamIO->uninit()) {
MY_LOGE("hardware uninit fail");
// return BAD_VALUE;
}
MY_LOGI("mpCamIO->uninit ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-uninit"
mLogInfo.setMemo(LogInfo::CP_OP_STOP_DRV_UNINIT_END);
//
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-destroyInstance");
MY_LOGI("mpCamIO->destroyInstance +++");
mpCamIO = nullptr;
MY_LOGI("mpCamIO->destroyInstance ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-destroyInstance"
}
//
syncHelperStop();
//
if (mspResConCtrl != nullptr) {
P1NODE_RES_CON_RELEASE(mspResConCtrl, mResConClient, mIsResConGot);
}
//
#if USING_CTRL_3A_LIST_PREVIOUS
mPreviousCtrlList.clear();
#endif
//
mLogInfo.setMemo(LogInfo::CP_OP_STOP_END, frmNum, reqNum, cnt);
//
FUNCTION_OUT;
return OK;
#else
return OK;
#endif
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::hardwareOps_streaming() {
P1_TRACE_AUTO(SLG_B, "P1:hardwareOps_streaming");
if (CC_UNLIKELY(mpHwStateCtrl == nullptr)) {
return BAD_VALUE;
}
if (!mpHwStateCtrl->checkReceiveRestreaming()) {
return BAD_VALUE;
}
//
if (mpHwStateCtrl->isLegacyStandby()) {
MINT32 nShutterTimeUs = 0;
mpHwStateCtrl->checkShutterTime(&nShutterTimeUs);
#if (MTKCAM_HAVE_SANDBOX_SUPPORT == 0)
P1_TRACE_F_BEGIN(SLG_E, "P1:DRV-Resume(%d)", nShutterTimeUs);
ret = mpCamIO->resume(nShutterTimeUs);
P1_TRACE_C_END(SLG_E); // "P1:DRV-Resume"
if (!ret) {
MY_LOGE("[SUS-RES] FAIL");
mpHwStateCtrl->dump();
mpHwStateCtrl->clean();
return BAD_VALUE;
}
#endif
//
P1_TRACE_S_BEGIN(SLG_E, "P1:3A-Resume");
mp3A->resume();
P1_TRACE_C_END(SLG_E); // "P1:3A-Resume"
//
MY_LOGI("[SUS-RES] Recover-Loop-N");
//
mpHwStateCtrl->checkThreadWeakup();
} else {
if (CC_UNLIKELY(mpTaskCtrl == nullptr || mpTaskCollector == nullptr)) {
return BAD_VALUE;
}
P1QueJob job(mBurstNum);
mpTaskCollector->requireJob(&job);
if (!job.ready()) {
MY_LOGE("job-require-fail");
mpTaskCtrl->dumpActPool();
return BAD_VALUE;
}
P1Act pAct = GET_ACT_PTR(pAct, job.edit(0), BAD_VALUE);
if (pAct->ctrlSensorStatus != SENSOR_STATUS_CTRL_STREAMING) {
MY_LOGI("status-mismatch(%d)@(%d)", pAct->ctrlSensorStatus,
pAct->getNum());
}
MINT32 nShutterTimeUs = 0;
mpHwStateCtrl->checkShutterTime(&nShutterTimeUs);
mpHwStateCtrl->checkRestreamingNum(pAct->getNum());
{
P1_TRACE_F_BEGIN(SLG_E, "P1:3A-resume(%d)", pAct->getNum());
mp3A->resume(pAct->getNum());
P1_TRACE_C_END(SLG_E); // "P1:3A-resume"
}
MERROR status =
hardwareOps_enque(&job, ENQ_TYPE_DIRECTLY, (MINT64)nShutterTimeUs);
if (OK != status) {
MY_LOGE("streaming en-queue fail (%d)@(%d)", status, job.getIdx());
return BAD_VALUE;
}
//
mpHwStateCtrl->checkThreadWeakup();
mpHwStateCtrl->checkFirstSync();
}
return OK;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::prepareCropInfo(P1QueAct* rAct,
IMetadata* pAppMetadata,
IMetadata* pHalMetadata,
PREPARE_CROP_PHASE phase,
MBOOL* pCtrlFlush) {
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
MSize refSensorSize = getCurrentBinSize(); // mSensorParams.size;
MBOOL bIsBinEn = (refSensorSize == mSensorParams.size) ? MFALSE : MTRUE;
MBOOL isFullBin = MFALSE;
if (bIsBinEn && act->reqType == REQ_TYPE_NORMAL &&
(/*IS_OUT(REQ_OUT_FULL_PROC, act->reqOutSet) ||*/
act->fullRawType == EPipe_PROCESSED_RAW)) {
isFullBin = MTRUE;
}
MY_LOGI(
"[CropInfo][%d] +++ IsBinEn:%d IsFullBin:%d "
"sensor(%dx%d) ref(%dx%d)",
phase, mIsBinEn, isFullBin, mSensorParams.size.w, mSensorParams.size.h,
refSensorSize.w, refSensorSize.h);
act->refBinSize = refSensorSize;
if (mvStreamImg[STREAM_IMG_OUT_FULL] != nullptr) {
act->dstSize_full = mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize();
act->cropRect_full =
MRect(MPoint(0, 0), (isFullBin) ? refSensorSize : mSensorParams.size);
} else if (mvStreamImg[STREAM_IMG_OUT_OPAQUE] != nullptr) {
act->dstSize_full = mSensorParams.size;
act->cropRect_full =
MRect(MPoint(0, 0), (isFullBin) ? refSensorSize : mSensorParams.size);
} else {
act->dstSize_full = MSize(0, 0);
act->cropRect_full = MRect(MPoint(0, 0), MSize(0, 0));
}
if (mvStreamImg[STREAM_IMG_OUT_RESIZE] != nullptr) {
act->dstSize_resizer = mvStreamImg[STREAM_IMG_OUT_RESIZE]->getImgSize();
act->cropRect_resizer = MRect(MPoint(0, 0), refSensorSize);
} else {
act->dstSize_resizer = MSize(0, 0);
act->cropRect_resizer = MRect(MPoint(0, 0), MSize(0, 0));
}
MY_LOGI("[CropInfo][%d] --- [F] Src" P1_RECT_STR "Dst" P1_SIZE_STR
"[R] Src" P1_RECT_STR "Dst" P1_SIZE_STR,
phase, P1_RECT_VAR(act->cropRect_full),
P1_SIZE_VAR(act->dstSize_full), P1_RECT_VAR(act->cropRect_resizer),
P1_SIZE_VAR(act->dstSize_resizer));
}
#if USING_CTRL_3A_LIST
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::generateCtrlList(List<NS3Av3::MetaSet_T>* pList, P1QueJob* rJob) {
if (CC_UNLIKELY(pList == nullptr)) {
MY_LOGE("List is nullptr");
return;
}
#define P1_3A_LIST_INDEX (2)
size_t total = (P1_3A_LIST_INDEX * mBurstNum);
#if USING_CTRL_3A_LIST_PREVIOUS // force to save and set previous metadata
// #warning "using previously padding 3A Control List"
// add dummy before first request
while (mPreviousCtrlList.size() < total) {
NS3Av3::MetaSet_T set;
set.MagicNum = 0;
set.Dummy = 1;
mPreviousCtrlList.push_back(set);
}
// add this request
for (size_t j = 0; j < (*rJob).size(); j++) {
if ((*rJob).edit(j).ptr() != nullptr) {
mPreviousCtrlList.push_back((*rJob).edit(j).ptr()->metaSet);
}
}
// keep list length in (P1_3A_LIST_INDEX + 1)
while ((mPreviousCtrlList.size() > (total + mBurstNum))) {
mPreviousCtrlList.erase(mPreviousCtrlList.begin());
}
// copy the mPreviousCtrlList to set-CtrlList
List<NS3Av3::MetaSet_T>::iterator p_it = mPreviousCtrlList.begin();
for (; p_it != mPreviousCtrlList.end(); p_it++) {
pList->push_back(*p_it);
}
#else
for (size_t i = 0; i < total; i++) {
NS3Av3::MetaSet_T set;
pList->push_back(set);
}
for (size_t j = 0; j < (*rJob).size(); j++) {
if ((*rJob).edit(j).ptr() != nullptr) {
pList->push_back((*rJob).edit(j).ptr()->metaSet);
}
}
#endif
//
if (mMetaLogOp > 0 && pList->size() > 0 &&
pList->size() == ((*rJob).size() * (P1_3A_LIST_INDEX + 1))) {
MY_LOGI("LogMeta List[%zu] Job[%zu]", pList->size(), (*rJob).size());
List<NS3Av3::MetaSet_T>::iterator it = pList->begin();
for (size_t j = 0; j < total && it != pList->end(); j++) {
it++;
} // shift to (P1_3A_LIST_INDEX * mBurstNum)
for (size_t i = 0; i < (*rJob).size() && it != pList->end(); i++, it++) {
P1Act pAct = GET_ACT_PTR(pAct, (*rJob).edit((MUINT8)i), RET_VOID);
P1_LOG_META(*pAct, &(it->appMeta), "3A.Set-APP");
P1_LOG_META(*pAct, &(it->halMeta), "3A.Set-HAL");
// P1_LOG_META(*pAct, &(pAct->metaSet.appMeta), "3A.Act-APP");
// P1_LOG_META(*pAct, &(pAct->metaSet.halMeta), "3A.Act-HAL");
}
}
return;
}
#endif
#if SUPPORT_LCS
MERROR P1NodeImp::lcsInit() {
if (mEnableLCSO) {
P1_TIMING_CHECK("P1:LCS-init", 10, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LCS-init");
MY_LOGI("MAKE_LcsHal +++");
mpLCS = MAKE_LCSHAL_IPC(LOG_TAG, getOpenId());
if (mpLCS == nullptr) {
MY_LOGE("mpLCS is NULL");
return DEAD_OBJECT;
}
if (mpLCS->Init() != LCS_RETURN_NO_ERROR) {
mpLCS->DestroyInstance(LOG_TAG);
mpLCS = nullptr;
}
MY_LOGI("MAKE_LcsHal ---");
P1_TRACE_C_END(SLG_S); // "P1:LCS-init"
}
return OK;
}
#endif
#if MTKCAM_HAVE_SANDBOX_SUPPORT
MVOID P1NodeImp::v4l2DeviceStart() {
// update dynamic info after powered on sensor
MY_LOGD("setDynamicSensorInfoToIPCHalSensor[+]");
int err = setDynamicSensorInfoToIPCHalSensor(getOpenId());
MY_LOGD("setDynamicSensorInfoToIPCHalSensor[-]");
if (CC_UNLIKELY(err != 0)) {
MY_LOGE("setDynamicSensorInfoToIPCHalSensor failed");
}
MY_LOGI("V4L2SensorWorker start +++");
mpV4L2SensorMgr = std::make_shared<v4l2::V4L2SensorWorker>(getOpenId());
mpV4L2SensorMgr->start();
MY_LOGI("V4L2SensorWorker start ---");
MY_LOGI("V4L2LensMgr start +++");
mpV4L2LensMgr = std::make_shared<v4l2::V4L2LensMgr>(getOpenId());
mpV4L2LensMgr->start();
MY_LOGI("V4L2LensMgr start ---");
MY_LOGI("V4L2P13ACallback start +++");
mpV4L2P13ACallback =
std::make_shared<v4l2::V4L2P13ACallback>(getOpenId(), this);
mpV4L2P13ACallback->start();
MY_LOGI("V4L2P13ACallback start ---");
}
#endif
MVOID P1NodeImp::addConfigPort(std::vector<PortInfo>* vPortInfo,
EImageFormat* resizer_fmt) {
if (mvStreamImg[STREAM_IMG_OUT_FULL] != nullptr) {
MINT fmt = mvStreamImg[STREAM_IMG_OUT_FULL]->getImgFormat();
IImageStreamInfo::BufPlanes_t const& planes =
mvStreamImg[STREAM_IMG_OUT_FULL]->getBufPlanes();
PortInfo OutPort(PORT_IMGO, (EImageFormat)fmt,
mvStreamImg[STREAM_IMG_OUT_FULL]->getImgSize(),
MRect(MPoint(0, 0), mSensorParams.size),
P1_STRIDE(planes, 0), P1_STRIDE(planes, 1),
P1_STRIDE(planes, 2),
0, // pureraw
MTRUE /*IS_RAW_FMT_PACK_FULL(fmt) packed*/,
10); // packed
// by driver request, the PAK should be ON even if un-packed raw
(*vPortInfo).push_back(OutPort);
mConfigPort |= CONFIG_PORT_IMGO;
mConfigPortNum++;
} else if (mvStreamImg[STREAM_IMG_OUT_OPAQUE] != nullptr) {
PortInfo OutPort(PORT_IMGO, (EImageFormat)mRawFormat, mSensorParams.size,
MRect(MPoint(0, 0), mSensorParams.size), mRawStride,
0 /*StrideInByte[1]*/, 0 /*StrideInByte[2]*/,
0, // pureraw
MTRUE /*IS_RAW_FMT_PACK_FULL(mRawFormat)*/); // packed
// by driver request, the PAK should be ON even if un-packed raw
(*vPortInfo).push_back(OutPort);
mConfigPort |= CONFIG_PORT_IMGO;
mConfigPortNum++;
}
//
if (mvStreamImg[STREAM_IMG_OUT_RESIZE] != nullptr) {
IImageStreamInfo::BufPlanes_t const& planes =
mvStreamImg[STREAM_IMG_OUT_RESIZE]->getBufPlanes();
PortInfo OutPort(
PORT_RRZO,
(EImageFormat)mvStreamImg[STREAM_IMG_OUT_RESIZE]->getImgFormat(),
mvStreamImg[STREAM_IMG_OUT_RESIZE]->getImgSize(),
MRect(MPoint(0, 0), mSensorParams.size), P1_STRIDE(planes, 0),
P1_STRIDE(planes, 1), P1_STRIDE(planes, 2),
0, // pureraw
MTRUE, // packed
10); // packed
(*vPortInfo).push_back(OutPort);
mConfigPort |= CONFIG_PORT_RRZO;
mConfigPortNum++;
//
*resizer_fmt =
(EImageFormat)mvStreamImg[STREAM_IMG_OUT_RESIZE]->getImgFormat();
}
if (mEnableLCSO && mvStreamImg[STREAM_IMG_OUT_LCS] != nullptr) {
IImageStreamInfo::BufPlanes_t const& planes =
mvStreamImg[STREAM_IMG_OUT_LCS]->getBufPlanes();
PortInfo OutPort(
PORT_LCSO,
(EImageFormat)mvStreamImg[STREAM_IMG_OUT_LCS]->getImgFormat(),
mvStreamImg[STREAM_IMG_OUT_LCS]->getImgSize(),
MRect(MPoint(0, 0), mvStreamImg[STREAM_IMG_OUT_LCS]->getImgSize()),
P1_STRIDE(planes, 0), P1_STRIDE(planes, 1), P1_STRIDE(planes, 2),
0, // pureraw
MTRUE, // packed
10);
(*vPortInfo).push_back(OutPort);
mConfigPort |= CONFIG_PORT_LCSO;
mConfigPortNum++;
}
if (mEnableRSSO && mvStreamImg[STREAM_IMG_OUT_RSS] != nullptr) {
IImageStreamInfo::BufPlanes_t const& planes =
mvStreamImg[STREAM_IMG_OUT_RSS]->getBufPlanes();
PortInfo OutPort(
PORT_RSSO,
(EImageFormat)mvStreamImg[STREAM_IMG_OUT_RSS]->getImgFormat(),
mvStreamImg[STREAM_IMG_OUT_RSS]->getImgSize(),
MRect(MPoint(0, 0), mvStreamImg[STREAM_IMG_OUT_RSS]->getImgSize()),
P1_STRIDE(planes, 0), P1_STRIDE(planes, 1), P1_STRIDE(planes, 2),
0, // pureraw
MTRUE); // packed
(*vPortInfo).push_back(OutPort);
mConfigPort |= CONFIG_PORT_RSSO;
mConfigPortNum++;
}
if (mEnableEISO) {
PortInfo OutPort(PORT_EISO, eImgFmt_BLOB, MSize(LMVO_MEMORY_SIZE, 1),
MRect(LMVO_MEMORY_SIZE, 1), LMVO_MEMORY_SIZE,
0, // pPortCfg->mStrideInByte[1],
0, // pPortCfg->mStrideInByte[2],
0, // pureraw
MTRUE,
10); // packed
(*vPortInfo).push_back(OutPort);
mConfigPort |= CONFIG_PORT_EISO;
mConfigPortNum++;
}
}
MERROR P1NodeImp::startCamIO(
QInitParam halCamIOinitParam,
MSize* binInfoSize,
MSize rawSize[2],
PipeTag* pipe_tag,
std::map<int, std::vector<std::shared_ptr<IImageBuffer>>>* buffers) {
{
MERROR err = OK;
P1_TIMING_CHECK("P1:DRV-init", 20, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-init");
MY_LOGI("mpCamIO->init +++");
if ((mConfigPort & CONFIG_PORT_RRZO) && (mConfigPort & CONFIG_PORT_IMGO)) {
*pipe_tag = kPipeTag_Out2_Tuning;
} else if ((mConfigPort & CONFIG_PORT_RRZO) ||
(mConfigPort & CONFIG_PORT_IMGO)) {
*pipe_tag = kPipeTag_Out1_Tuning;
}
if (err < 0 || !mpCamIO || !mpCamIO->init(*pipe_tag)) {
MY_LOGE("hardware init fail - err:%#x mpCamIO:%p", err, mpCamIO.get());
return DEAD_OBJECT;
}
MY_LOGI("mpCamIO->init ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-init"
}
MSize rawSize_l[2];
MSize* pSizeProc = &rawSize_l[0]; // 0 = EPipe_PROCESSED_RAW
MSize* pSizePure = &rawSize_l[1]; // 1 = EPipe_PURE_RAW
*pSizeProc = MSize(0, 0);
*pSizePure = MSize(0, 0);
if (mConfigPort & CONFIG_PORT_EISO) {
buffers->emplace(PORT_EISO.index,
std::vector<std::shared_ptr<IImageBuffer>>{});
}
#if MTKCAM_HAVE_SANDBOX_SUPPORT
IIPCHalSensor::DynamicInfo ipcDynamicInfo;
#endif
if (mpCamIO != nullptr) {
P1_TIMING_CHECK("P1:DRV-configPipe", 500, TC_W);
mLogInfo.setMemo(LogInfo::CP_OP_START_DRV_CFG_BGN);
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-configPipe");
MY_LOGI("mpCamIO->configPipe +++");
if (!mpCamIO->configPipe(halCamIOinitParam, buffers)) {
MY_LOGE("mpCamIO->configPipe fail");
P1_TRACE_C_END(SLG_S); // "P1:DRV-configPipe"
mLogInfo.setMemo(LogInfo::CP_OP_START_DRV_CFG_END);
return BAD_VALUE;
} else {
MY_LOGI("mpCamIO->configPipe ---");
P1_TRACE_C_END(SLG_S); // "P1:DRV-configPipe"
mLogInfo.setMemo(LogInfo::CP_OP_START_DRV_CFG_END);
//
{
MBOOL notSupportProc = MFALSE;
MBOOL notSupportPure = MFALSE;
MUINT32 newDefType = mRawDefType;
MUINT32 newOption = mRawOption;
P1_TRACE_S_BEGIN(SLG_S, "P1:DRV-GetImgoInfo");
if (mpCamIO->sendCommand(ENPipeCmd_GET_TG_OUT_SIZE,
(MINTPTR)(&rawSize_l), (MINTPTR)NULL,
(MINTPTR)NULL)) {
P1_TRACE_C_END(SLG_S); // "P1:DRV-GetImgoInfo"
if (pSizeProc->w == 0 || pSizeProc->h == 0) {
notSupportProc = MTRUE;
}
if (pSizePure->w == 0 || pSizePure->h == 0) {
notSupportPure = MTRUE;
}
}
if ((!notSupportProc) && (!notSupportPure)) {
// both Proc raw and Pure raw are supported
// not change the raw type setting
#if MTKCAM_HAVE_SANDBOX_SUPPORT
// update resolution from any RAW type is ok.
if (pSizePure->w != 0 && pSizePure->h != 0) {
ipcDynamicInfo.tg_size = *pSizePure;
}
#endif
} else if ((!notSupportProc) && (notSupportPure)) {
// only support Proc raw
newDefType = EPipe_PROCESSED_RAW;
newOption = (1 << EPipe_PROCESSED_RAW);
#if MTKCAM_HAVE_SANDBOX_SUPPORT
ipcDynamicInfo.tg_size = *pSizeProc;
#endif
} else if ((notSupportProc) && (!notSupportPure)) {
// only support Pure raw
newDefType = EPipe_PURE_RAW;
newOption = (1 << EPipe_PURE_RAW);
#if MTKCAM_HAVE_SANDBOX_SUPPORT
ipcDynamicInfo.tg_size = *pSizePure;
#endif
} else {
// not support Proc raw and Pure raw
MY_LOGE(
"Raw(%d,0x%x) Proc(%dx%d) Pure(%dx%d) "
"- Not Support",
mRawDefType, mRawOption, pSizeProc->w, pSizeProc->h, pSizePure->w,
pSizePure->h);
return BAD_VALUE;
}
MY_LOGI_IF((mRawDefType != newDefType) || (mRawOption != newOption),
"[RAW_TYPE] Raw(%d,0x%x) => New(%d,0x%x)"
"Proc(%dx%d) Pure(%dx%d)",
mRawDefType, mRawOption, newDefType, newOption, pSizeProc->w,
pSizeProc->h, pSizePure->w, pSizePure->h);
//
mRawDefType = newDefType;
mRawOption = newOption;
}
}
}
#if MTKCAM_HAVE_SANDBOX_SUPPORT
{
// after p1 started, update dynamic info again (for TG selection)
MY_LOGD("setDynamicSensorInfoToIPCHalSensor[+]");
int err = setDynamicSensorInfoToIPCHalSensor(getOpenId());
MY_LOGD("setDynamicSensorInfoToIPCHalSensor[-]");
if (CC_UNLIKELY(err != 0)) {
MY_LOGE("setDynamicSensorInfoToIPCHalSensor failed");
}
// Before update extended dynamic info, check bin_size and hbin_size,
// if it's 0, give it the same as tg size.
if (ipcDynamicInfo.bin_size.w == 0 || ipcDynamicInfo.bin_size.h == 0) {
ipcDynamicInfo.bin_size = ipcDynamicInfo.tg_size;
}
if (ipcDynamicInfo.hbin_size.w == 0 || ipcDynamicInfo.hbin_size.h == 0) {
ipcDynamicInfo.hbin_size = ipcDynamicInfo.tg_size;
}
// Update extended dynamic info too.
err = setDynamicInfoExToIPCHalSensor(getOpenId(), ipcDynamicInfo);
if (CC_UNLIKELY(err != 0)) {
MY_LOGE("setDynamicInfoExToIPCHalSensor failed, need check.");
}
}
#endif
rawSize[0] = rawSize_l[0];
rawSize[1] = rawSize_l[1];
return OK;
}
QInitParam P1NodeImp::prepareQInitParam(
IHalSensor::ConfigParam* sensorCfg,
NS3Av3::AEInitExpoSetting_T initExpoSetting,
std::vector<PortInfo> vPortInfo) {
sensorCfg->index = (MUINT)getOpenId();
sensorCfg->crop = mSensorParams.size;
sensorCfg->scenarioId = mSensorParams.mode;
sensorCfg->isBypassScenario = 0;
sensorCfg->isContinuous = 1;
sensorCfg->HDRMode = MFALSE;
#if (P1NODE_USING_MTK_LDVT > 0)
sensorCfg->framerate = 1;
#else
sensorCfg->framerate = mSensorParams.fps;
#endif
sensorCfg->twopixelOn = 0;
sensorCfg->debugMode = 0;
sensorCfg->exposureTime = initExpoSetting.u4Eposuretime;
sensorCfg->gain = initExpoSetting.u4AfeGain;
sensorCfg->exposureTime_se = initExpoSetting.u4Eposuretime_se;
sensorCfg->gain_se = initExpoSetting.u4AfeGain_se;
std::vector<IHalSensor::ConfigParam> vSensorCfg;
vSensorCfg.push_back(*sensorCfg); // only insert once
//
MBOOL bDynamicRawType = MTRUE; // true:[ON] ; false:[OFF]
QInitParam halCamIOinitParam(0, /*sensor test pattern */
vSensorCfg, vPortInfo, bDynamicRawType);
halCamIOinitParam.m_IQlv = mCfg.mQualityLv;
// halCamIOinitParam.m_Func.Bits.SensorNum = mCfg.mSensorNum;
halCamIOinitParam.m_pipelinebitdepth = (E_CAM_PipelineBitDepth_SEL)mPipeBit;
halCamIOinitParam.m_DynamicTwin = mIsDynamicTwinEn;
// halCamIOinitParam.m_DropCB = doNotifyDropframe;
halCamIOinitParam.mSensorFormatOrder = mSensorFormatOrder;
halCamIOinitParam.m_returnCookie = this;
// enable frame sync
if (mEnableFrameSync) {
MY_LOGI("P1 node(%d) is in synchroized mode", getOpenId());
halCamIOinitParam.m_bN3D = MTRUE;
} else {
halCamIOinitParam.m_bN3D = MFALSE;
}
return halCamIOinitParam;
}
MERROR P1NodeImp::lmvInit(MSize sensorSize, MSize rrzoSize) {
if (mEnableEISO) {
P1_TIMING_CHECK("P1:LMV-init", 20, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:LMV-init");
if (IS_LMV(mpConnectLMV)) {
MINT32 mode = EIS::EisInfo::getMode(mPackedEisInfo);
MINT32 factor = EIS::EisInfo::getFactor(mPackedEisInfo);
MY_LOGD("mpConnectLMV->init+");
if (MFALSE == mpConnectLMV->init(mode, factor, sensorSize, rrzoSize)) {
MY_LOGE("ConnectLMV create fail");
return BAD_VALUE;
}
}
P1_TRACE_C_END(SLG_S); // "P1:LMV-init"
}
return OK;
}
#if SUPPORT_3A
MERROR P1NodeImp::getAEInitExpoSetting(
NS3Av3::AEInitExpoSetting_T* initExpoSetting) {
P1_TIMING_CHECK("P1:3A-create-GetAEInitExpoSetting", 10, TC_W);
P1_TRACE_S_BEGIN(SLG_S, "P1:3A-create-GetAEInitExpoSetting");
MY_LOGI("MAKE_Hal3A +++");
MAKE_Hal3A(
mp3A, [](NS3Av3::IHal3A* p) { p->destroyInstance(LOG_TAG); }, getOpenId(),
LOG_TAG);
if (mp3A == nullptr) {
MY_LOGE("mp3A is NULL");
return DEAD_OBJECT;
}
MY_LOGI("MAKE_Hal3A ---");
mp3A->send3ACtrl(NS3Av3::E3ACtrl_GetAEInitExpoSetting,
(MINTPTR)initExpoSetting, 0);
MY_LOGI(
"GetAEInitExpoSetting: u4Eposuretime(le:%d/se:%d) "
"u4AfeGain(le:%d/se:%d)",
(*initExpoSetting).u4Eposuretime, (*initExpoSetting).u4Eposuretime_se,
(*initExpoSetting).u4AfeGain, (*initExpoSetting).u4AfeGain_se);
P1_TRACE_C_END(SLG_S); // "P1:3A-create-GetAEInitExpoSetting"
return OK;
}
#endif
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::generateCtrlQueue(std::vector<NS3Av3::MetaSet_T*>* rQue,
P1QueJob* rJob) {
for (size_t j = 0; j < (*rJob).size(); j++) {
if ((*rJob).edit(j).ptr() != nullptr) {
(*rQue).push_back(&((*rJob).edit(j).ptr()->metaSet));
}
}
//
if (mMetaLogOp > 0 && (*rQue).size() > 0 &&
(*rQue).size() == (*rJob).size()) {
MY_LOGI("LogMeta Que[%zu] Job[%zu]", (*rQue).size(), (*rJob).size());
std::vector<NS3Av3::MetaSet_T*>::iterator it = (*rQue).begin();
for (size_t i = 0; i < (*rJob).size() && it != (*rQue).end(); i++, it++) {
P1Act pAct = GET_ACT_PTR(pAct, (*rJob).edit((MUINT8)i), RET_VOID);
P1_LOG_META(*pAct, &((*it)->appMeta), "3A.Set-APP");
P1_LOG_META(*pAct, &((*it)->halMeta), "3A.Set-HAL");
}
}
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::createAction(P1QueAct* rAct,
std::shared_ptr<IPipelineFrame> appFrame,
REQ_TYPE eType) {
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
// create queue act
// MUINT32 newNum = get_and_increase_magicnum();
NS3Av3::MetaSet_T* metaInfo = &(act->metaSet);
IMetadata* pAppMeta = &(act->metaSet.appMeta);
IMetadata* pHalMeta = &(act->metaSet.halMeta);
if (pAppMeta == nullptr) {
MY_LOGE("pAppMeta == NULL");
}
act->metaSet.PreSetKey = rAct->id();
//
MINT32 meta_raw_type = (MINT32)mRawDefType;
MBOOL meta_raw_exist = MFALSE;
MBOOL meta_zsl_req = MFALSE;
//
P1_TRACE_F_BEGIN(SLG_I, "P1:create|Fnum:%d Rnum:%d", P1GET_FRM_NUM(appFrame),
P1GET_REQ_NUM(appFrame));
MINT32 meta_ZslEn = P1_META_GENERAL_EMPTY_INT;
MINT32 meta_CapIntent = P1_META_GENERAL_EMPTY_INT;
MINT32 meta_RawType = P1_META_GENERAL_EMPTY_INT;
MINT32 meta_TgNum = P1_META_GENERAL_EMPTY_INT;
MINT32 meta_QualityCtrl = P1_META_GENERAL_EMPTY_INT;
MINT32 meta_FmtImgo = P1_META_GENERAL_EMPTY_INT; // eImgFmt_UNKNOWN
MINT32 meta_FmtRrzo = P1_META_GENERAL_EMPTY_INT; // eImgFmt_UNKNOWN
//
if (appFrame != nullptr) {
if (CC_UNLIKELY(eType != REQ_TYPE_UNKNOWN)) {
MY_LOGE("Type-Mismatching (%d) on (%d, %d)", eType,
P1GET_FRM_NUM(appFrame), P1GET_REQ_NUM(appFrame));
return;
}
if (act->appFrame != appFrame) { // act->appFrame == NULL
act->appFrame = appFrame;
act->frmNum = appFrame->getFrameNo();
act->reqNum = appFrame->getRequestNo();
act->mapFrameStream();
MY_LOGI("CreateAct(%d,%d) assign frame", act->frmNum, act->reqNum);
}
//
P1_TRACE_S_BEGIN(SLG_O, "createMeta");
if (mvStreamMeta[STREAM_META_IN_APP] != nullptr) {
if (OK == act->frameMetadataGet(STREAM_META_IN_APP, pAppMeta)) {
P1_LOG_META(*act, pAppMeta, "RequestIn-APP");
} else {
MY_LOGI("can not lock the app metadata");
pAppMeta = nullptr;
}
}
if (mvStreamMeta[STREAM_META_IN_HAL] != nullptr) {
if (OK == act->frameMetadataGet(STREAM_META_IN_HAL, pHalMeta)) {
P1_LOG_META(*act, pHalMeta, "RequestIn-HAL");
} else {
MY_LOGI("can not lock the hal metadata");
pHalMeta = nullptr;
}
}
P1_TRACE_C_END(SLG_O); // "createMeta"
// check info from APP meta
if (pAppMeta != nullptr) {
MUINT8 zsl_en = MTK_CONTROL_ENABLE_ZSL_FALSE;
if (tryGetMetadata<MUINT8>(pAppMeta, MTK_CONTROL_ENABLE_ZSL, &zsl_en)) {
meta_ZslEn = zsl_en;
}
MINT32 patternMode = 0;
if (tryGetMetadata<MINT32>(pAppMeta, MTK_SENSOR_TEST_PATTERN_MODE,
&patternMode)) {
mMeta_PatMode = patternMode;
MY_LOGD("p1 createAction pattern mode %d", mMeta_PatMode);
}
MUINT8 cap_intent = MTK_CONTROL_CAPTURE_INTENT_CUSTOM;
if (tryGetMetadata<MUINT8>(pAppMeta, MTK_CONTROL_CAPTURE_INTENT,
&cap_intent)) {
meta_CapIntent = cap_intent;
}
if (zsl_en == MTK_CONTROL_ENABLE_ZSL_TRUE &&
cap_intent == MTK_CONTROL_CAPTURE_INTENT_STILL_CAPTURE
#if 1 // check-bypass-request
&& appFrame->IsReprocessFrame()
#endif
) {
meta_zsl_req = MTRUE;
}
}
// check info from HAL meta
if (pHalMeta != nullptr) {
MINT32 raw_type = meta_raw_type;
if (tryGetMetadata<MINT32>(pHalMeta, MTK_P1NODE_RAW_TYPE, &raw_type)) {
meta_RawType = raw_type;
MY_LOGD("raw type set from outside %d", raw_type);
if (meta_raw_type != raw_type) {
MY_LOGI("Metadata-Raw(%d) - Config-Raw(%d)(%d-0x%x)", raw_type,
meta_raw_type, mRawDefType, mRawOption);
}
if ((mRawOption & (MUINT32)(1 << raw_type)) > 0) {
meta_raw_type = raw_type;
meta_raw_exist = MTRUE;
} else {
MY_LOGI(
"raw type (%d) set from outside, but not accept "
"RawOption(0x%x)",
raw_type, mRawOption);
}
}
if (IS_LMV(mpConnectLMV) && mpConnectLMV->checkSwitchOut(pHalMeta)) {
act->uniSwitchState = UNI_SWITCH_STATE_REQ;
}
// for Twin Switch TG Number control
if (mIsDynamicTwinEn) {
MINT32 tg_num = MTK_P1_TWIN_SWITCH_NONE;
if (tryGetMetadata<MINT32>(pHalMeta, MTK_P1NODE_TWIN_SWITCH, &tg_num)) {
meta_TgNum = tg_num;
if (tg_num != MTK_P1_TWIN_SWITCH_NONE) {
act->tgSwitchState = TG_SWITCH_STATE_REQ;
switch (tg_num) {
case MTK_P1_TWIN_SWITCH_ONE_TG:
act->tgSwitchNum = 1;
break;
case MTK_P1_TWIN_SWITCH_TWO_TG:
act->tgSwitchNum = 2;
break;
default:
MY_LOGI("check MTK_P1NODE_TWIN_SWITCH %d", tg_num);
break;
}
}
}
}
// for Standby Mode control
if (mpHwStateCtrl != nullptr) {
act->ctrlSensorStatus = mpHwStateCtrl->checkReceiveFrame(pHalMeta);
}
// for Quality Switch control
if (mpRegisterNotify != nullptr) {
MINT32 quality_ctrl = MTK_P1_RESIZE_QUALITY_SWITCH_NONE;
act->qualitySwitchState = QUALITY_SWITCH_STATE_NONE;
if (tryGetMetadata<MINT32>(pHalMeta, MTK_P1NODE_RESIZE_QUALITY_SWITCH,
&quality_ctrl)) {
meta_QualityCtrl = quality_ctrl;
if (getQualitySwitching() &&
quality_ctrl != MTK_P1_RESIZE_QUALITY_SWITCH_NONE) {
act->qualitySwitchState = QUALITY_SWITCH_STATE_DONE_ILLEGAL;
} else {
switch (quality_ctrl) {
case MTK_P1_RESIZE_QUALITY_SWITCH_H_H:
act->qualitySwitchState = QUALITY_SWITCH_STATE_REQ_H_H;
break;
case MTK_P1_RESIZE_QUALITY_SWITCH_H_L:
act->qualitySwitchState = QUALITY_SWITCH_STATE_REQ_H_L;
break;
case MTK_P1_RESIZE_QUALITY_SWITCH_L_H:
act->qualitySwitchState = QUALITY_SWITCH_STATE_REQ_L_H;
break;
case MTK_P1_RESIZE_QUALITY_SWITCH_L_L:
act->qualitySwitchState = QUALITY_SWITCH_STATE_REQ_L_L;
break;
default:
break;
}
}
}
if (act->qualitySwitchState != QUALITY_SWITCH_STATE_NONE) {
E_CamIQLevel CamLvA = eCamIQ_MAX;
E_CamIQLevel CamLvB = eCamIQ_MAX;
if (mpCamIO != nullptr &&
mpCamIO->sendCommand(ENPipeCmd_GET_QUALITY, (MINTPTR)NULL,
(MINTPTR)&CamLvA, (MINTPTR)&CamLvB)) {
MBOOL ignore = MFALSE;
switch (quality_ctrl) {
case MTK_P1_RESIZE_QUALITY_SWITCH_H_H:
if (CamLvA == eCamIQ_H && CamLvB == eCamIQ_H) {
ignore = MTRUE;
}
break;
case MTK_P1_RESIZE_QUALITY_SWITCH_H_L:
if (CamLvA == eCamIQ_H && CamLvB == eCamIQ_L) {
ignore = MTRUE;
}
break;
case MTK_P1_RESIZE_QUALITY_SWITCH_L_H:
if (CamLvA == eCamIQ_L && CamLvB == eCamIQ_H) {
ignore = MTRUE;
}
break;
case MTK_P1_RESIZE_QUALITY_SWITCH_L_L:
if (CamLvA == eCamIQ_L && CamLvB == eCamIQ_L) {
ignore = MTRUE;
}
break;
default:
break;
}
if (ignore) {
act->qualitySwitchState = QUALITY_SWITCH_STATE_DONE_IGNORE;
}
}
}
if ((act->qualitySwitchState & QUALITY_SWITCH_STATE_REQ_NON) > 0) {
setQualitySwitching(MTRUE);
}
}
if (tryGetMetadata<MINT32>(pHalMeta, MTK_HAL_REQUEST_IMG_IMGO_FORMAT,
&(act->mReqFmt_Imgo))) {
meta_FmtImgo = act->mReqFmt_Imgo;
MY_LOGI("MTK_REQUEST_IMG_IMGO_FORMAT : 0x%x", act->mReqFmt_Imgo);
}
if (tryGetMetadata<MINT32>(pHalMeta, MTK_HAL_REQUEST_IMG_RRZO_FORMAT,
&(act->mReqFmt_Rrzo))) {
meta_FmtRrzo = act->mReqFmt_Rrzo;
MY_LOGI("MTK_REQUEST_IMG_RRZO_FORMAT : 0x%x", act->mReqFmt_Rrzo);
}
}
//
if (meta_zsl_req) {
act->reqType = REQ_TYPE_ZSL;
} else if (act->streamBufImg[STREAM_IMG_IN_YUV].bExist) {
act->reqType = REQ_TYPE_YUV;
} else if (act->streamBufImg[STREAM_IMG_IN_OPAQUE].bExist) {
act->reqType = REQ_TYPE_REDO;
} else {
act->reqType = REQ_TYPE_NORMAL;
if (IS_PORT(CONFIG_PORT_IMGO, mConfigPort) &&
act->streamBufImg[STREAM_IMG_OUT_OPAQUE].bExist) {
act->reqOutSet |= REQ_SET(REQ_OUT_FULL_OPAQUE);
}
if (IS_PORT(CONFIG_PORT_IMGO, mConfigPort) &&
act->streamBufImg[STREAM_IMG_OUT_FULL].bExist) {
if (meta_raw_type == EPipe_PROCESSED_RAW) {
act->reqOutSet |= REQ_SET(REQ_OUT_FULL_PROC);
} else {
act->reqOutSet |= REQ_SET(REQ_OUT_FULL_PURE);
}
}
if (IS_PORT(CONFIG_PORT_RRZO, mConfigPort) &&
act->streamBufImg[STREAM_IMG_OUT_RESIZE].bExist) {
act->reqOutSet |= REQ_SET(REQ_OUT_RESIZER);
}
if (IS_PORT(CONFIG_PORT_LCSO, mConfigPort) &&
act->streamBufImg[STREAM_IMG_OUT_LCS].bExist) {
act->reqOutSet |= REQ_SET(REQ_OUT_LCSO);
}
if (IS_PORT(CONFIG_PORT_RSSO, mConfigPort) &&
act->streamBufImg[STREAM_IMG_OUT_RSS].bExist) {
act->reqOutSet |= REQ_SET(REQ_OUT_RSSO);
}
}
} else {
switch (eType) {
case REQ_TYPE_INITIAL:
case REQ_TYPE_PADDING:
case REQ_TYPE_DUMMY:
act->reqType = eType;
break;
default: // REQ_TYPE_UNKNOWN/REQ_TYPE_NORMAL/REQ_TYPE_REDO/REQ_TYPE_YUV
MY_LOGE("Type-Mismatching (%d)", eType);
return;
}
pAppMeta = nullptr;
pHalMeta = nullptr;
if (act->reqType ==
REQ_TYPE_INITIAL) { // using pool buffer only in initial act
if (IS_PORT(CONFIG_PORT_IMGO, mConfigPort) &&
mpStreamPool_full != nullptr) {
if (meta_raw_type == EPipe_PROCESSED_RAW) {
act->reqOutSet |= REQ_SET(REQ_OUT_FULL_PROC);
} else {
act->reqOutSet |= REQ_SET(REQ_OUT_FULL_PURE);
}
}
if (IS_PORT(CONFIG_PORT_RRZO, mConfigPort) &&
mpStreamPool_resizer != nullptr) {
act->reqOutSet |= REQ_SET(REQ_OUT_RESIZER);
}
if (IS_PORT(CONFIG_PORT_LCSO, mConfigPort) &&
mpStreamPool_lcso != nullptr) {
act->reqOutSet |= REQ_SET(REQ_OUT_LCSO);
}
if (IS_PORT(CONFIG_PORT_RSSO, mConfigPort) &&
mpStreamPool_rsso != nullptr) {
act->reqOutSet |= REQ_SET(REQ_OUT_RSSO);
}
}
}
//
act->fullRawType = meta_raw_type;
if (act->reqType == REQ_TYPE_NORMAL) {
#if 1 // add raw type to hal meta
if (act->reqType == REQ_TYPE_NORMAL && !meta_raw_exist) {
IMetadata::IEntry entryRawType(MTK_P1NODE_RAW_TYPE);
entryRawType.push_back(meta_raw_type, Type2Type<MINT32>());
metaInfo->halMeta.update(MTK_P1NODE_RAW_TYPE, entryRawType);
}
#endif
}
//
if (act->reqType == REQ_TYPE_NORMAL || act->reqType == REQ_TYPE_INITIAL ||
act->reqType == REQ_TYPE_PADDING || act->reqType == REQ_TYPE_DUMMY) {
if (IS_PORT(CONFIG_PORT_IMGO, mConfigPort) &&
(0 == (IS_OUT(REQ_OUT_FULL_PROC, act->reqOutSet) ||
IS_OUT(REQ_OUT_FULL_PURE, act->reqOutSet) ||
IS_OUT(REQ_OUT_FULL_OPAQUE, act->reqOutSet)))) {
act->reqOutSet |= REQ_SET(REQ_OUT_FULL_STUFF);
}
if (IS_PORT(CONFIG_PORT_RRZO, mConfigPort) &&
(0 == IS_OUT(REQ_OUT_RESIZER, act->reqOutSet))) {
act->reqOutSet |= REQ_SET(REQ_OUT_RESIZER_STUFF);
}
if (IS_PORT(CONFIG_PORT_LCSO, mConfigPort) &&
(0 == IS_OUT(REQ_OUT_LCSO, act->reqOutSet))) {
act->reqOutSet |= REQ_SET(REQ_OUT_LCSO_STUFF);
}
if (IS_PORT(CONFIG_PORT_RSSO, mConfigPort) &&
(0 == IS_OUT(REQ_OUT_RSSO, act->reqOutSet))) {
act->reqOutSet |= REQ_SET(REQ_OUT_RSSO_STUFF);
}
//
prepareCropInfo(rAct, pAppMeta, pHalMeta,
PREPARE_CROP_PHASE_RECEIVE_CREATE);
act->exeState = EXE_STATE_REQUESTED;
} else if (act->reqType == REQ_TYPE_REDO || act->reqType == REQ_TYPE_YUV ||
act->reqType == REQ_TYPE_ZSL) {
act->exeState = EXE_STATE_DONE;
}
//
// mTagReq.set(rAct.id()); // set number while act register
//
if (1 <= mLogLevelI) { // P1_LOGI(1)
std::string info(act->msg);
act->msg.clear();
act->msg += base::StringPrintf(
"[P1::REQ]" P1INFO_ACT_STR
" [META ze:%d ci:%d rt:%d tn:%d qc:%d fi:%d fr:%d] [%s][%d] ",
P1INFO_ACT_VAR(*act), meta_ZslEn, meta_CapIntent, meta_RawType,
meta_TgNum, meta_QualityCtrl, meta_FmtImgo, meta_FmtRrzo,
(appFrame != nullptr) ? "New-Request" : "New-Dummy", eType);
act->msg += info;
if ((eType != REQ_TYPE_UNKNOWN) || // if the eType is assigned, it should
// be an internal act,
(EN_INIT_REQ_RUN &&
mInitReqCnt < mInitReqNum)) { // print the string since no more
// message appending
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::REQ_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum,
act->flushSet);
P1_LOGI(1, "%s", act->msg.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::REQ_LOG"
}
}
//
P1_TRACE_C_END(SLG_I); // "P1:create"
//
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::onProcessResult(P1QueAct* rAct,
QBufInfo const& deqBuf,
NS3Av3::MetaSet_T const& result3A,
IMetadata const& resultAppend,
MUINT32 const index) {
FUNCTION_IN;
//
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
//
P1_TRACE_F_BEGIN(SLG_I, "P1:result|Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum);
//
if (act->appFrame != 0) {
if ((mvStreamMeta[STREAM_META_OUT_APP] != nullptr) &&
(mvStreamMeta[STREAM_META_OUT_HAL] != nullptr)) {
// APP out Meta Stream
IMetadata outAppMetadata;
generateAppMeta(rAct, result3A, deqBuf, &outAppMetadata, index);
if ((IS_OUT(REQ_OUT_FULL_OPAQUE, act->reqOutSet)) &&
(act->streamBufImg[STREAM_IMG_OUT_OPAQUE].spImgBuf != nullptr) &&
(!IS_EXP(EXP_EVT_NOBUF_IMGO, act->expRec))) {
// app metadata index
IMetadata appTagIndex;
generateAppTagIndex(&outAppMetadata, &appTagIndex);
std::shared_ptr<IImageBufferHeap> pImageBufferHeap =
act->streamBufImg[STREAM_IMG_OUT_OPAQUE]
.spImgBuf->getImageBufferHeap();
MERROR status = OpaqueReprocUtil::setAppMetadataToHeap(pImageBufferHeap,
&appTagIndex);
MY_LOGD("setAppMetadataToHeap (%d)", status);
}
//
// HAL out Meta Stream
IMetadata inHalMetadata;
IMetadata outHalMetadata;
if (OK != act->frameMetadataGet(STREAM_META_IN_HAL, &inHalMetadata)) {
MY_LOGW("cannot get in-hal-metadata");
}
generateHalMeta(rAct, result3A, deqBuf, resultAppend, inHalMetadata,
&outHalMetadata, index);
if ((IS_OUT(REQ_OUT_FULL_OPAQUE, act->reqOutSet)) &&
(act->streamBufImg[STREAM_IMG_OUT_OPAQUE].spImgBuf != nullptr) &&
(!IS_EXP(EXP_EVT_NOBUF_IMGO, act->expRec))) {
std::shared_ptr<IImageBufferHeap> pImageBufferHeap =
act->streamBufImg[STREAM_IMG_OUT_OPAQUE]
.spImgBuf->getImageBufferHeap();
MERROR status = OpaqueReprocUtil::setHalMetadataToHeap(pImageBufferHeap,
&outHalMetadata);
MY_LOGD("setHalMetadataToHeap (%d)", status);
if ((IS_OUT(REQ_OUT_LCSO, act->reqOutSet)) &&
(act->streamBufImg[STREAM_IMG_OUT_LCS].spImgBuf != nullptr)) {
MERROR status = OpaqueReprocUtil::setLcsoImageToHeap(
pImageBufferHeap, act->streamBufImg[STREAM_IMG_OUT_LCS].spImgBuf);
MY_LOGD("setLcsoImageToHeap (%d)", status);
}
}
//
MBOOL isChange = MFALSE;
attemptCtrlReadout(rAct, &outAppMetadata, &outHalMetadata, &isChange);
//
if (mspSyncHelper != nullptr) {
IMetadata ctrlMeta;
act->frameMetadataGet(STREAM_META_IN_HAL, &ctrlMeta);
MBOOL res = mspSyncHelper->syncResultCheck(getOpenId(), &ctrlMeta,
&outHalMetadata);
if (!res) {
act->setFlush(FLUSH_MIS_SYNC);
MY_LOGI("SyncHelper flush this request (%d)" P1INFO_ACT_STR, res,
P1INFO_ACT_VAR(*act));
}
}
//
if (OK != act->frameMetadataGet(STREAM_META_OUT_APP, nullptr, MTRUE,
&outAppMetadata)) {
MY_LOGW("cannot write out-app-metadata");
} else {
P1_LOG_META(*act, &outAppMetadata, "ResultOut-APP");
}
if (OK != act->frameMetadataGet(STREAM_META_OUT_HAL, nullptr, MTRUE,
&outHalMetadata)) {
MY_LOGW("cannot write out-hal-metadata");
} else {
P1_LOG_META(*act, &outHalMetadata, "ResultOut-HAL");
}
} else {
MY_LOGW("STREAM_META_OUT not exist - APP(%d) HAL(%d)",
(mvStreamMeta[STREAM_META_OUT_APP] != nullptr) ? MTRUE : MFALSE,
(mvStreamMeta[STREAM_META_OUT_HAL] != nullptr) ? MTRUE : MFALSE);
}
//
checkBufferDumping(rAct);
}
//
#if 1 // trigger only at the end of this job
onReturnFrame(
rAct, FLUSH_NONEED,
(IS_BURST_OFF || (index == (MUINT32)(mBurstNum - 1))) ? MTRUE : MFALSE);
/* DO NOT use this P1QueAct after onReturnFrame() */
#else
onReturnFrame(rAct, FLUSH_NONEED, MTRUE);
/* DO NOT use this P1QueAct after onReturnFrame() */
#endif
//
P1_TRACE_C_END(SLG_I); // "P1:result"
//
FUNCTION_OUT;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::processRedoFrame(P1QueAct* rAct) {
FUNCTION_IN;
//
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
//
if (act->getFlush()) {
MY_LOGD("need to flush, skip frame processing");
return;
}
IMetadata appMeta;
IMetadata halMeta;
std::shared_ptr<IImageBuffer> imgBuf;
std::shared_ptr<IImageBuffer> imgBuf_lcso;
//
if (OK != act->frameImageGet(STREAM_IMG_IN_OPAQUE, &imgBuf) ||
OK != act->frameImageGet(STREAM_IMG_OUT_LCS, &imgBuf_lcso)) {
MY_LOGE("Can not get in-opaque/lcso buffer from frame");
} else {
std::shared_ptr<IImageBufferHeap> pHeap = imgBuf->getImageBufferHeap();
IMetadata appMetaTagIndex;
if (OK ==
OpaqueReprocUtil::getAppMetadataFromHeap(pHeap, &appMetaTagIndex)) {
// get the input of app metadata
IMetadata metaInApp;
if (OK != act->frameMetadataGet(STREAM_META_IN_APP, &metaInApp)) {
MY_LOGW("cannot get in-app-metadata");
}
// get p1node's tags from opaque buffer
IMetadata::IEntry entryTagIndex =
appMetaTagIndex.entryFor(MTK_P1NODE_METADATA_TAG_INDEX);
for (MUINT i = 0; i < entryTagIndex.count(); i++) {
MUINT32 tag = entryTagIndex.itemAt(
i, Type2Type<MINT32>()); // get Tag from entryTagIndex
// update entry from metaInApp to appMeta
IMetadata::IEntry entryInApp = metaInApp.entryFor(tag);
appMeta.update(tag, entryInApp);
}
// Workaround: do not return the duplicated key for YUV reprocessing
appMeta.remove(MTK_JPEG_THUMBNAIL_SIZE);
appMeta.remove(MTK_JPEG_ORIENTATION);
if (OK != act->frameMetadataGet(STREAM_META_OUT_APP, nullptr, MTRUE,
&appMeta)) {
MY_LOGW("cannot write out-app-metadata");
}
} else {
MY_LOGW("Can not get app meta from in-opaque buffer");
}
if (OK == OpaqueReprocUtil::getHalMetadataFromHeap(pHeap, &halMeta)) {
IMetadata::IEntry entry(MTK_HAL_REQUEST_REQUIRE_EXIF);
entry.push_back(1, Type2Type<MUINT8>());
halMeta.update(entry.tag(), entry);
if (OK != act->frameMetadataGet(STREAM_META_OUT_HAL, nullptr, MTRUE,
&halMeta)) {
MY_LOGW("cannot write out-hal-metadata");
}
} else {
MY_LOGW("Can not get hal meta from in-opaque buffer");
}
if (OK == OpaqueReprocUtil::getLcsoImageFromHeap(pHeap, imgBuf_lcso)) {
act->frameImagePut(STREAM_IMG_OUT_LCS);
} else {
MY_LOGW("Can not get lcso image from in-opaque buffer");
}
}
//
FUNCTION_OUT;
//
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::processYuvFrame(P1QueAct* rAct) {
FUNCTION_IN;
//
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
//
if (act->getFlush()) {
MY_LOGD("need to flush, skip frame processing");
return;
}
IMetadata inAppMetadata;
IMetadata outAppMetadata;
IMetadata inHalMetadata;
IMetadata outHalMetadata;
MINT64 timestamp = 0;
MFLOAT aperture = (0.0f);
MFLOAT focallength = (0.0f);
MINT64 exposure = 0;
MINT32 iso = 0;
MINT32 iso_boost = 0;
MINT64 duration = 0;
MUINT8 edge = MTK_EDGE_MODE_OFF;
MUINT8 noise = MTK_NOISE_REDUCTION_MODE_OFF;
MFLOAT factor = (1.0f);
// APP in Meta Stream
if (OK != act->frameMetadataGet(STREAM_META_IN_APP, &inAppMetadata)) {
MY_LOGW("cannot get in-app-metadata");
} else {
// outAppMetadata = inAppMetadata; // copy all from in-app to out-app
if (tryGetMetadata<MINT64>(&inAppMetadata, MTK_SENSOR_TIMESTAMP,
&timestamp)) {
MY_LOGD("timestamp from in-app %" PRId64, timestamp);
} else {
MY_LOGI("cannot find timestamp from in-app");
timestamp = 0;
}
//
if (tryGetMetadata<MFLOAT>(&inAppMetadata, MTK_LENS_APERTURE, &aperture)) {
MY_LOGD1("aperture from in-app %f", aperture);
if (!trySetMetadata<MFLOAT>(&outAppMetadata, MTK_LENS_APERTURE,
aperture)) {
MY_LOGW("cannot update MTK_LENS_APERTURE");
}
} else {
MY_LOGI("cannot find aperture from in-app");
aperture = (0.0f);
}
if (tryGetMetadata<MFLOAT>(&inAppMetadata, MTK_LENS_FOCAL_LENGTH,
&focallength)) {
MY_LOGD1("focallength from in-app %f", focallength);
if (!trySetMetadata<MFLOAT>(&outAppMetadata, MTK_LENS_FOCAL_LENGTH,
focallength)) {
MY_LOGW("cannot update MTK_LENS_FOCAL_LENGTH");
}
} else {
MY_LOGI("cannot find focallength from in-app");
focallength = (0.0f);
}
if (tryGetMetadata<MINT64>(&inAppMetadata, MTK_SENSOR_EXPOSURE_TIME,
&exposure)) {
MY_LOGD1("exposure from in-app %" PRId64, exposure);
if (!trySetMetadata<MINT64>(&outAppMetadata, MTK_SENSOR_EXPOSURE_TIME,
exposure)) {
MY_LOGW("cannot update MTK_SENSOR_EXPOSURE_TIME");
}
} else {
MY_LOGI("cannot find exposure from in-app");
exposure = 0;
}
if (tryGetMetadata<MINT32>(&inAppMetadata, MTK_SENSOR_SENSITIVITY, &iso)) {
MY_LOGD1("iso from in-app %" PRId32, iso);
if (!trySetMetadata<MINT32>(&outAppMetadata, MTK_SENSOR_SENSITIVITY,
iso)) {
MY_LOGW("cannot update MTK_SENSOR_SENSITIVITY");
}
} else {
MY_LOGI("cannot find iso from in-app");
iso = 0;
}
if (tryGetMetadata<MINT32>(&inAppMetadata,
MTK_CONTROL_POST_RAW_SENSITIVITY_BOOST,
&iso_boost)) {
MY_LOGD1("iso boost from in-app %" PRId32, iso_boost);
if (!trySetMetadata<MINT32>(&outAppMetadata,
MTK_CONTROL_POST_RAW_SENSITIVITY_BOOST,
iso_boost)) {
MY_LOGW("cannot update MTK_CONTROL_POST_RAW_SENSITIVITY_BOOST");
}
} else {
MY_LOGI("cannot find iso boost from in-app");
iso_boost = 0;
}
if (tryGetMetadata<MINT64>(&inAppMetadata, MTK_SENSOR_FRAME_DURATION,
&duration)) {
MY_LOGD1("duration from in-app %" PRId64, duration);
if (!trySetMetadata<MINT64>(&outAppMetadata, MTK_SENSOR_FRAME_DURATION,
duration)) {
MY_LOGW("cannot update MTK_SENSOR_FRAME_DURATION");
}
} else {
MY_LOGI("cannot find duration from in-app");
duration = 0;
}
//
if (tryGetMetadata<MUINT8>(&inAppMetadata, MTK_EDGE_MODE, &edge)) {
MY_LOGD1("MTK_EDGE_MODE from in-app %d", edge);
if (!trySetMetadata<MUINT8>(&outAppMetadata, MTK_EDGE_MODE, edge)) {
MY_LOGW("cannot update MTK_EDGE_MODE");
}
} else {
MY_LOGI("cannot find MTK_EDGE_MODE from in-app");
edge = MTK_EDGE_MODE_OFF;
}
if (tryGetMetadata<MUINT8>(&inAppMetadata, MTK_NOISE_REDUCTION_MODE,
&noise)) {
MY_LOGD1("MTK_NOISE_REDUCTION_MODE from in-app %d", noise);
if (!trySetMetadata<MUINT8>(&outAppMetadata, MTK_NOISE_REDUCTION_MODE,
noise)) {
MY_LOGW("cannot update MTK_NOISE_REDUCTION_MODE");
}
} else {
MY_LOGI("cannot find MTK_NOISE_REDUCTION_MODE from in-app");
noise = MTK_NOISE_REDUCTION_MODE_OFF;
}
if (tryGetMetadata<MFLOAT>(
&inAppMetadata, MTK_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR, &factor)) {
MY_LOGD1("MTK_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR from in-app %f",
factor);
if (!trySetMetadata<MFLOAT>(&outAppMetadata,
MTK_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR,
factor)) {
MY_LOGW("cannot update MTK_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR");
}
} else {
MY_LOGI(
"cannot find MTK_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR from in-app");
factor = (1.0f);
}
}
// APP out Meta Stream
if (!trySetMetadata<MINT64>( // always set sensor-timestamp
&outAppMetadata, MTK_SENSOR_TIMESTAMP, timestamp)) {
MY_LOGW("cannot update MTK_SENSOR_TIMESTAMP");
}
//
if (OK != act->frameMetadataGet(STREAM_META_OUT_APP, NULL, MTRUE,
&outAppMetadata)) {
MY_LOGW("cannot write out-app-metadata");
}
// HAL in/out Meta Stream
if (OK != act->frameMetadataGet(STREAM_META_IN_HAL, &inHalMetadata)) {
MY_LOGW("cannot get in-hal-metadata");
} else {
outHalMetadata = inHalMetadata;
if (!trySetMetadata<MINT32>(&outHalMetadata, MTK_P1NODE_SENSOR_MODE,
mSensorParams.mode)) {
MY_LOGW("cannot update MTK_P1NODE_SENSOR_MODE");
}
if (!trySetMetadata<MINT32>(&outHalMetadata, MTK_P1NODE_SENSOR_VHDR_MODE,
mSensorParams.vhdrMode)) {
MY_LOGW("cannot update MTK_P1NODE_SENSOR_MODE");
}
if (!trySetMetadata<MRect>(
&outHalMetadata, MTK_P1NODE_SCALAR_CROP_REGION,
MRect(mSensorParams.size.w, mSensorParams.size.h))) {
MY_LOGW("cannot update MTK_P1NODE_SCALAR_CROP_REGION");
}
if (!trySetMetadata<MRect>(
&outHalMetadata, MTK_P1NODE_DMA_CROP_REGION,
MRect(mSensorParams.size.w, mSensorParams.size.h))) {
MY_LOGW("cannot update MTK_P1NODE_DMA_CROP_REGION");
}
if (!trySetMetadata<MSize>(&outHalMetadata, MTK_P1NODE_RESIZER_SIZE,
mSensorParams.size)) {
MY_LOGW("cannot update MTK_P1NODE_RESIZER_SIZE");
}
if (OK != act->frameMetadataGet(STREAM_META_OUT_HAL, NULL, MTRUE,
&outHalMetadata)) {
MY_LOGW("cannot write out-hal-metadata");
}
}
//
FUNCTION_OUT;
//
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::releaseAction(P1QueAct* rAct) {
FUNCTION_IN;
//
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
//
P1_TRACE_F_BEGIN(SLG_I,
"P1:release|Mnum:%d SofIdx:%d Fnum:%d Rnum:%d "
"FlushSet:0x%x",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum,
act->flushSet);
//
MY_LOGD(P1INFO_ACT_STR " begin", P1INFO_ACT_VAR(*act));
//
if (!act->getFlush()) {
if (act->reqType == REQ_TYPE_REDO) {
processRedoFrame(rAct);
} else if (act->reqType == REQ_TYPE_YUV) {
processYuvFrame(rAct);
}
}
//
for (int stream = STREAM_ITEM_START; stream < STREAM_META_NUM; stream++) {
if (act->streamBufMeta[stream].bExist) {
if (OK != act->frameMetadataPut((STREAM_META)stream)) {
MY_LOGD("cannot put metadata stream(%d)", stream);
}
}
}
//
for (int stream = STREAM_ITEM_START; stream < STREAM_IMG_NUM; stream++) {
if ((!act->streamBufImg[stream].bExist) && // for INITIAL act
(act->streamBufImg[stream].eSrcType == IMG_BUF_SRC_NULL)) {
continue; // this stream is not existent and no pool/stuff buffer
}
switch (act->streamBufImg[stream].eSrcType) {
case IMG_BUF_SRC_STUFF:
if (OK != act->stuffImagePut((STREAM_IMG)stream)) {
MY_LOGD("cannot put stuff image stream(%d)", stream);
}
break;
case IMG_BUF_SRC_POOL:
if (OK != act->poolImagePut((STREAM_IMG)stream)) {
MY_LOGD("cannot put pool image stream(%d)", stream);
}
break;
case IMG_BUF_SRC_FRAME:
case IMG_BUF_SRC_NULL: // for flush act, buf src is not decided
if (OK != act->frameImagePut((STREAM_IMG)stream)) {
MY_LOGD("cannot put frame image stream(%d)", stream);
}
break;
default:
MY_LOGW("act buffer source is not defined");
MY_LOGW("check act exe " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
break;
}
}
//
if (act->getType() == ACT_TYPE_INTERNAL) {
mTagOut.set(rAct->getNum());
if (1 <= mLogLevelI) {
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::DEQ_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum,
act->flushSet);
P1_LOGI(1, "%s [InternalReturn]", act->res.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::DEQ_LOG"
}
MY_LOGD(P1INFO_ACT_STR " INTERNAL return", P1INFO_ACT_VAR(*act));
if (mpTaskCtrl != nullptr) {
mpTaskCtrl->releaseAct(rAct);
/* DO NOT use this P1QueAct after releaseAct() */
}
P1_TRACE_C_END(SLG_I); // "P1:release"
return;
}
//
MY_LOGD(P1INFO_ACT_STR " applyRelease", P1INFO_ACT_VAR(*act));
//
// Apply buffers to release
IStreamBufferSet& rStreamBufferSet = act->appFrame->getStreamBufferSet();
//
if (1 <= mLogLevelI) {
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::DEQ_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum,
act->flushSet);
std::string strInfo("");
base::StringAppendF(&strInfo, "%s [ApplyRelease]", act->res.c_str());
mNoteRelease.get(&strInfo);
P1_LOGI(1, "%s", strInfo.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::DEQ_LOG"
}
//
P1_TRACE_S_BEGIN(SLG_I, "P1:applyRelease");
rStreamBufferSet.applyRelease(getNodeId());
P1_TRACE_C_END(SLG_I); // "P1:applyRelease"
//
if (1 <= mLogLevelI) {
mNoteRelease.set(act->frmNum);
}
//
MY_LOGD(P1INFO_ACT_STR " end", P1INFO_ACT_VAR(*act));
if (mpTaskCtrl != nullptr) {
mpTaskCtrl->releaseAct(rAct);
/* DO NOT use this P1QueAct after releaseAct() */
}
P1_TRACE_C_END(SLG_I); // "P1:release"
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::releaseFrame(P1FrameAct* rFrameAct) {
FUNCTION_IN;
//
if (CC_UNLIKELY(rFrameAct->appFrame == nullptr)) {
MY_LOGE("PipelineFrame is NULL - " P1INFO_ACT_STR,
P1INFO_ACT_VAR(*rFrameAct));
return;
}
//
#if (USING_DRV_IO_PIPE_EVENT)
eventStreamingInform();
#endif
//
LogInfo::AutoMemo _m(&mLogInfo, LogInfo::CP_OUT_BGN, LogInfo::CP_OUT_END,
rFrameAct->magicNum, rFrameAct->frmNum,
rFrameAct->reqNum);
//
int32_t currReqCnt = 0;
currReqCnt = std::atomic_fetch_sub_explicit(&mInFlightRequestCnt, 1,
std::memory_order_release);
P1_TRACE_INT(SLG_B, "P1_request_cnt",
std::atomic_load_explicit(&mInFlightRequestCnt,
std::memory_order_acquire));
MY_LOGD("InFlightRequestCount-- (%d) => (%d)", currReqCnt,
std::atomic_load_explicit(&mInFlightRequestCnt,
std::memory_order_acquire));
//
#if 1
// camera display systrace - Dispatch
if (rFrameAct->reqType == REQ_TYPE_NORMAL && rFrameAct->appFrame != nullptr &&
rFrameAct->frameTimeStamp > 0) {
MINT64 const timestamp = rFrameAct->frameTimeStamp;
P1_TRACE_F_BEGIN(
SLG_B, // add information
"Cam:%d:IspP1:dispatch|timestamp(ns):%" PRId64 " duration(ns):%" PRId64
" request:%d frame:%d",
getOpenId(), timestamp, NSCam::Utils::getTimeInNs() - timestamp,
rFrameAct->appFrame->getRequestNo(), rFrameAct->appFrame->getFrameNo());
P1_TRACE_C_END(SLG_B); // "IspP1:dispatch"
}
#endif
//
if (CC_LIKELY(rFrameAct->reqType == REQ_TYPE_NORMAL)) {
mTagOut.set(rFrameAct->magicNum);
}
if (1 <= mLogLevelI) {
P1_TRACE_F_BEGIN(SLG_PFL,
"P1::OUT_LOG|Mnum:%d SofIdx:%d Fnum:%d "
"Rnum:%d FlushSet:0x%x",
rFrameAct->magicNum, rFrameAct->sofIdx, rFrameAct->frmNum,
rFrameAct->reqNum, rFrameAct->flushSet);
std::string strInfo("");
base::StringAppendF(
&strInfo, "[P1::OUT]" P1INFO_ACT_STR " [Release-%d] [DispatchFrame]",
P1INFO_ACT_VAR(*rFrameAct),
((rFrameAct->flushSet == FLUSH_NONEED) ? 0 : 1));
mNoteDispatch.get(&strInfo);
P1_LOGI(1, "%s", strInfo.c_str());
P1_TRACE_C_END(SLG_PFL); // "P1::OUT_LOG"
}
//
P1_TRACE_F_BEGIN(SLG_I,
"onDispatchFrame|Mnum:%d SofIdx:%d Fnum:%d Rnum:%d "
"FlushSet:0x%x",
rFrameAct->magicNum, rFrameAct->sofIdx, rFrameAct->frmNum,
rFrameAct->reqNum, rFrameAct->flushSet);
//
// dispatch to next node
dispatch(rFrameAct->appFrame);
//
MY_LOGI("[Dispatch-Return] " P1INFO_ACT_STR " (m_%" PRId64
") "
"(b_%" PRId64 ")",
P1INFO_ACT_VAR(*rFrameAct), rFrameAct->frameTimeStamp,
rFrameAct->frameTimeStampBoot);
//
if (1 <= mLogLevelI) {
mNoteDispatch.set(rFrameAct->frmNum);
}
//
P1_TRACE_C_END(SLG_I); // "onDispatchFrame"
//
FUNCTION_OUT;
//
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::dispatch(std::shared_ptr<IPipelineFrame> pFrame) {
FUNCTION_IN;
//
// dispatch to next node
MY_LOGI("onDispatchFrame +++ FrameNum(%d) RequestNum(%d)",
P1GET_FRM_NUM(pFrame), P1GET_REQ_NUM(pFrame));
onDispatchFrame(pFrame);
MY_LOGI("onDispatchFrame --- FrameNum(%d) RequestNum(%d)",
P1GET_FRM_NUM(pFrame), P1GET_REQ_NUM(pFrame));
//
FUNCTION_OUT;
//
return;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::requestMetadataEarlyCallback(P1QueAct* rAct,
STREAM_META const streamMeta,
IMetadata* pMetadata) {
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
//
P1_CHECK_STREAM_SET(META, streamMeta);
P1_CHECK_MAP_STREAM(Meta, (*act), streamMeta);
//
if (pMetadata == nullptr) {
MY_LOGD("Result Metadata is Null");
return BAD_VALUE;
}
if (pMetadata->count() == 0) {
MY_LOGD("Result Metadata is Empty");
return OK;
}
MY_LOGD("Meta[%d]=(%d) EarlyCB " P1INFO_ACT_STR, streamMeta,
pMetadata->count(), P1INFO_ACT_VAR(*act));
//
IMetadata outMetadata = *(pMetadata);
DurationProfile duration("EarlyCB", 5000000LL); // 5ms
duration.pulse_up();
P1_TRACE_S_BEGIN(SLG_I, "EarlyCB");
onEarlyCallback(act->appFrame, mvStreamMeta[streamMeta]->getStreamId(),
outMetadata);
P1_TRACE_C_END(SLG_I); // "EarlyCB"
duration.pulse_down();
if (duration.isWarning()) {
MY_LOGI("EarlyCB Meta[%d]=(%d) " P1INFO_ACT_STR, streamMeta,
pMetadata->count(), P1INFO_ACT_VAR(*act));
}
//
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::notifyCtrlSync(P1QueAct* rAct) {
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
//
MY_LOGI("CtrlCb_Sync[%d] sof(%d) cap(%d) exp(%" PRId64
"ns) +++ " P1INFO_ACT_STR,
IPipelineNodeCallback::eCtrl_Sync, act->sofIdx, act->capType,
act->frameExpDuration, P1INFO_ACT_VAR(*act));
DurationProfile duration("CtrlCb_Sync", 3000000LL); // 3ms
duration.pulse_up();
P1_TRACE_F_BEGIN(SLG_I, "CtrlCb_Sync[%d]", IPipelineNodeCallback::eCtrl_Sync);
onCtrlSync(act->appFrame, act->sofIdx, act->capType, act->frameExpDuration);
P1_TRACE_C_END(SLG_I); // "CtrlCb_Sync"
duration.pulse_down();
if (duration.isWarning()) {
MY_LOGI("CtrlCb_Sync[%d] sof(%d) cap(%d) exp(%" PRId64
"ns) " P1INFO_ACT_STR,
IPipelineNodeCallback::eCtrl_Sync, act->sofIdx, act->capType,
act->frameExpDuration, P1INFO_ACT_VAR(*act));
}
MY_LOGI("CtrlCb_Sync[%d] sof(%d) cap(%d) exp(%" PRId64
"ns) --- " P1INFO_ACT_STR,
IPipelineNodeCallback::eCtrl_Sync, act->sofIdx, act->capType,
act->frameExpDuration, P1INFO_ACT_VAR(*act));
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::notifyCtrlMeta(IPipelineNodeCallback::eCtrlType eType,
P1QueAct* rAct,
STREAM_META const streamAppMeta,
IMetadata* pAppMetadata,
STREAM_META const streamHalMeta,
IMetadata* pHalMetadata,
MBOOL* rIsChanged) {
*rIsChanged = MFALSE;
int64_t nsWarning = 3000000LL; // 3ms
MBOOL bChangeLog = (0 <= mLogLevelI);
switch (eType) {
case IPipelineNodeCallback::eCtrl_Resize:
nsWarning = 2000000LL;
bChangeLog = (2 <= mLogLevelI);
break;
case IPipelineNodeCallback::eCtrl_Setting:
case IPipelineNodeCallback::eCtrl_Readout:
break;
default: // IPipelineNodeCallback::eCtrl_Sync
return OK;
}
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
MUINT cntApp = 0;
MUINT cntHal = 0;
P1_CHECK_STREAM_SET(META, streamAppMeta);
P1_CHECK_STREAM_SET(META, streamHalMeta);
P1_CHECK_MAP_STREAM(Meta, (*act), streamAppMeta);
P1_CHECK_MAP_STREAM(Meta, (*act), streamHalMeta);
if (CC_UNLIKELY(pAppMetadata == nullptr)) {
MY_LOGD("AppMetadata is Null");
return BAD_VALUE;
} else {
cntApp = pAppMetadata->count();
}
if (CC_UNLIKELY(pHalMetadata == nullptr)) {
MY_LOGD("HalMetadata is Null");
return BAD_VALUE;
} else {
cntHal = pHalMetadata->count();
}
MY_LOGI("CtrlCb_Meta[%d] AppMeta[%d]=(%d) HalMeta[%d]=(%d) " P1INFO_ACT_STR,
eType, streamAppMeta, cntApp, streamHalMeta, cntHal,
P1INFO_ACT_VAR(*act));
//
IMetadata& rAppMetadata = (*(pAppMetadata));
IMetadata& rHalMetadata = (*(pHalMetadata));
MBOOL isChanged = MFALSE;
DurationProfile duration("CtrlCb_Meta", nsWarning);
duration.pulse_up();
P1_TRACE_F_BEGIN(SLG_I, "CtrlCb_Meta[%d]", eType);
if (eType == IPipelineNodeCallback::eCtrl_Setting) {
onCtrlSetting(act->appFrame, mvStreamMeta[streamAppMeta]->getStreamId(),
&rAppMetadata, mvStreamMeta[streamHalMeta]->getStreamId(),
&rHalMetadata, &isChanged);
} else if (eType == IPipelineNodeCallback::eCtrl_Readout) {
onCtrlReadout(act->appFrame, mvStreamMeta[streamAppMeta]->getStreamId(),
&rAppMetadata, mvStreamMeta[streamHalMeta]->getStreamId(),
&rHalMetadata, &isChanged);
} else { // eType == IPipelineNodeCallback::eCtrl_Resize
onCtrlResize(act->appFrame, mvStreamMeta[streamAppMeta]->getStreamId(),
&rAppMetadata, mvStreamMeta[streamHalMeta]->getStreamId(),
&rHalMetadata, &isChanged);
}
P1_TRACE_C_END(SLG_I); // "CtrlCb_Meta"
duration.pulse_down();
if (duration.isWarning() || (isChanged && bChangeLog)) { // for log only
char str[32] = {0};
switch (eType) {
case IPipelineNodeCallback::eCtrl_Setting:
snprintf(str, sizeof(str), "CtrlCb_Meta[%d]-Setting", eType);
break;
case IPipelineNodeCallback::eCtrl_Readout:
snprintf(str, sizeof(str), "CtrlCb_Meta[%d]-Readout", eType);
break;
case IPipelineNodeCallback::eCtrl_Resize:
snprintf(str, sizeof(str), "CtrlCb_Meta[%d]-Resize", eType);
break;
default: // IPipelineNodeCallback::eCtrl_Sync
return OK;
}
if (duration.isWarning()) {
MY_LOGI("%s sof(%d) cap(%d) exp(%" PRId64 "ns) " P1INFO_ACT_STR, str,
act->sofIdx, act->capType, act->frameExpDuration,
P1INFO_ACT_VAR(*act));
}
if (isChanged && bChangeLog) {
MY_LOGI(
"%s change AppMeta[%d]=(%d-%d) HalMeta[%d]=(%d-%d) " P1INFO_ACT_STR,
str, streamAppMeta, cntApp, rAppMetadata.count(), streamHalMeta,
cntHal, rHalMetadata.count(), P1INFO_ACT_VAR(*act));
}
}
*rIsChanged = isChanged;
//
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::attemptCtrlSync(P1QueAct* rAct) {
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
if ((act->appFrame != nullptr) &&
needCtrlCb(act->appFrame, IPipelineNodeCallback::eCtrl_Sync)) {
notifyCtrlSync(rAct);
}
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::attemptCtrlSetting(P1QueAct* rAct) {
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
MBOOL bIsChanged = MFALSE;
if ((act->appFrame != nullptr) &&
needCtrlCb(act->appFrame, IPipelineNodeCallback::eCtrl_Setting)) {
notifyCtrlMeta(IPipelineNodeCallback::eCtrl_Setting, rAct,
STREAM_META_IN_APP, &(act->metaSet.appMeta),
STREAM_META_IN_HAL, &(act->metaSet.halMeta), &bIsChanged);
}
if (bIsChanged) {
act->metaSet.PreSetKey = P1_PRESET_KEY_NULL;
}
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::attemptCtrlResize(P1QueAct* rAct, MBOOL* rIsChanged) {
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
MBOOL isChanged = MFALSE;
if ((act->appFrame != nullptr) &&
needCtrlCb(act->appFrame, IPipelineNodeCallback::eCtrl_Resize)) {
IMetadata revAppMeta;
IMetadata revHalMeta;
notifyCtrlMeta(IPipelineNodeCallback::eCtrl_Resize, rAct,
STREAM_META_IN_APP, &revAppMeta, STREAM_META_IN_HAL,
&revHalMeta, &isChanged);
if (isChanged) {
MBOOL ctrlFlush = MFALSE;
prepareCropInfo(rAct, &revAppMeta, &revHalMeta,
PREPARE_CROP_PHASE_CONTROL_RESIZE, &ctrlFlush);
if (ctrlFlush) {
act->setFlush(FLUSH_MIS_RESIZE);
}
}
}
*rIsChanged = isChanged;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MERROR
P1NodeImp::attemptCtrlReadout(P1QueAct* rAct,
IMetadata* pAppMetadata,
IMetadata* pHalMetadata,
MBOOL* rIsChanged) {
P1Act act = GET_ACT_PTR(act, *rAct, BAD_VALUE);
MBOOL isChanged = MFALSE;
if ((act->appFrame != nullptr) &&
needCtrlCb(act->appFrame, IPipelineNodeCallback::eCtrl_Readout)) {
notifyCtrlMeta(IPipelineNodeCallback::eCtrl_Readout, rAct,
STREAM_META_OUT_APP, pAppMetadata, STREAM_META_OUT_HAL,
pHalMetadata, &isChanged);
if (isChanged) {
MBOOL outFlush = MFALSE;
if (tryGetMetadata<MINT32>(pHalMetadata, MTK_P1NODE_CTRL_READOUT_FLUSH,
&outFlush) &&
(outFlush)) {
act->setFlush(FLUSH_MIS_READOUT);
}
}
}
*rIsChanged = isChanged;
return OK;
}
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::findPortBufIndex(QBufInfo const& deqBuf, P1QueJob* job) {
size_t job_size = (*job).size();
if ((job_size == 0) || (deqBuf.mvOut.size() % job_size > 0)) {
MY_LOGE("Output size is not match");
return MFALSE;
}
// assume the port order is the same in each de-queue set,
// it only check the first de-queue set and apply to each act
P1_OUTPUT_PORT port = P1_OUTPUT_PORT_TOTAL;
MUINT32 group = 0;
MUINT32 index = 0;
for (size_t i = 0; i < (deqBuf.mvOut.size()); i += job_size) {
index = deqBuf.mvOut[i].mPortID.index;
port = P1_OUTPUT_PORT_TOTAL;
if (index == PORT_RRZO.index) {
port = P1_OUTPUT_PORT_RRZO;
} else if (index == PORT_IMGO.index) {
port = P1_OUTPUT_PORT_IMGO;
} else if (index == PORT_EISO.index) {
port = P1_OUTPUT_PORT_EISO;
} else if (index == PORT_LCSO.index) {
port = P1_OUTPUT_PORT_LCSO;
} else if (index == PORT_RSSO.index) {
port = P1_OUTPUT_PORT_RSSO;
} else {
MY_LOGE("Output port is not match");
return MFALSE;
}
//
if (port < P1_OUTPUT_PORT_TOTAL) {
for (size_t j = 0; j < job_size; j++) {
P1Act act = GET_ACT_PTR(act, (*job).edit(j), MFALSE);
act->portBufIndex[port] = (group * job_size) + j;
}
}
group++;
}
return MTRUE;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::checkBufferDumping(P1QueAct* rAct) {
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
#if (SUPPORT_BUFFER_TUNING_DUMP)
if (mCamDumpEn == 0) {
return;
}
MINT32 nDumpIMGO = property_get_int32("vendor.debug.camera.dump.p1.imgo", 0);
if (nDumpIMGO == 0) {
return;
}
P1_TRACE_AUTO(SLG_E, "P1:BufferDumping");
MY_LOGI("[DUMP_IMGO] " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
if (act->reqType != REQ_TYPE_NORMAL) {
MY_LOGI("[DUMP_IMGO] not-apply (%d)", act->reqType);
return;
}
IMetadata outHalMetadata;
if (OK != act->frameMetadataGet(STREAM_META_OUT_HAL, &outHalMetadata)) {
MY_LOGW("[DUMP_IMGO] cannot get out-hal-metadata");
return;
}
//
std::shared_ptr<IImageBuffer> imgBuf;
if (mvStreamImg[STREAM_IMG_OUT_FULL] == nullptr) {
MY_LOGW("[DUMP_IMGO] StreamImg FULL not exist");
return;
}
MY_LOGI("[DUMP_IMGO] map(%d) type(%d) state(%d) [%p]",
act->streamBufImg[STREAM_IMG_OUT_FULL].bExist,
act->streamBufImg[STREAM_IMG_OUT_FULL].eSrcType,
act->streamBufImg[STREAM_IMG_OUT_FULL].eLockState,
act->streamBufImg[STREAM_IMG_OUT_FULL].spImgBuf.get());
imgBuf = act->streamBufImg[STREAM_IMG_OUT_FULL].spImgBuf;
if (imgBuf == NULL) {
MY_LOGW("[DUMP_IMGO] cannot get ImageBuffer");
return;
}
//
NSCam::TuningUtils::FILE_DUMP_NAMING_HINT hint;
MBOOL res = MTRUE;
res = extract(&hint, &outHalMetadata);
if (!res) {
MY_LOGW("[DUMP_IMGO] extract with metadata fail (%d)", res);
return;
}
//
res = extract(&hint, imgBuf.get());
if (!res) {
MY_LOGW("[DUMP_IMGO] extract with ImgBuf fail (%d)", res);
return;
}
//
res = extract_by_SensorOpenId(&hint, getOpenId());
if (!res) {
MY_LOGW("[DUMP_IMGO] extract with OpenId fail (%d)", res);
return;
}
//
{
char file_name[512];
::memset(file_name, 0, sizeof(file_name));
genFileName_RAW(file_name, sizeof(file_name), &hint,
NSCam::TuningUtils::RAW_PORT_IMGO);
P1_TRACE_AUTO(SLG_E, file_name);
MBOOL ret = imgBuf->saveToFile(file_name);
MY_LOGI("[DUMP_IMGO] SaveFile[%s]:(%d)", file_name, ret);
}
#endif
return;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::inflightMonitoring(INFLIGHT_MONITORING_TIMING timing) {
MINT64 currentTime = (MINT64)(NSCam::Utils::getTimeInNs());
MBOOL trigger = MFALSE;
{
std::lock_guard<std::mutex> _l(mMonitorLock);
if (currentTime > (mMonitorTime + (P1_PERIODIC_INSPECT_INV_NS))) {
mMonitorTime = currentTime;
trigger = MTRUE;
}
}
if (trigger) {
char str[128] = {0};
MINT32 cnt = (MINT32)std::atomic_load_explicit(&mInFlightRequestCnt,
std::memory_order_acquire);
switch (timing) {
case IMT_REQ:
snprintf(str, sizeof(str),
"[%d:AfterRequestReceived]"
"[Burst=%d Count=%d]",
timing, mBurstNum, cnt);
break;
case IMT_ENQ:
snprintf(str, sizeof(str),
"[%d:AfterEnQ]"
"[Burst=%d Count=%d]",
timing, mBurstNum, cnt);
break;
case IMT_DEQ:
snprintf(str, sizeof(str),
"[%d:AfterDeQ]"
"[Burst=%d Count=%d]",
timing, mBurstNum, cnt);
break;
default: // IMT_COMMON
snprintf(str, sizeof(str),
"[%d:CommonCase]"
"[Burst=%d Count=%d]",
timing, mBurstNum, cnt);
break;
}
mLogInfo.inspect(LogInfo::IT_PERIODIC_CHECK, str);
}
return;
}
MUINT32
P1NodeImp::get_and_increase_magicnum() {
std::lock_guard<std::mutex> _l(mLastNumLock);
uint32_t magicnum = 0;
if (CC_UNLIKELY(mpCamIO.get() == nullptr)) {
MY_LOGE("cannot generate magicnum since mpCamIO is nullptr");
return -1U;
}
MBOOL _result = mpCamIO->sendCommand(ENPipeCmd_GEN_MAGIC_NUM,
reinterpret_cast<MINTPTR>(&magicnum), 0,
0); // arg2, arg3 <-- dont care
if (CC_UNLIKELY(_result != MTRUE)) {
MY_LOGE("mpCamIO returns fail with cmd(ENPipeCmd_GEN_MAGIC_NUM)");
return -1U;
}
MY_LOGD("gen magicnum=%u", magicnum);
mLastNum = magicnum;
MUINT32 ret = mLastNum;
// skip num = 0 as 3A would callback 0 when request stack is empty
// skip -1U as a reserved number to indicate that which would never happen in
// 3A queue
if (ret == 0 || ret == -1U) {
ret = mLastNum = 1;
}
return ret;
}
/******************************************************************************
*
******************************************************************************/
MVOID
P1NodeImp::onReturnFrame(P1QueAct* rAct,
FLUSH_TYPE flushType,
MBOOL isTrigger) {
P1Act act = GET_ACT_PTR(act, *rAct, RET_VOID);
//
P1_TRACE_F_BEGIN(SLG_I, "P1:return|Mnum:%d SofIdx:%d Fnum:%d Rnum:%d",
act->magicNum, act->sofIdx, act->frmNum, act->reqNum);
//
if (flushType != FLUSH_NONEED) {
act->setFlush(flushType);
}
if (act->getFlush() && getActive()) {
MY_LOGI("need flush act " P1INFO_ACT_STR, P1INFO_ACT_VAR(*act));
}
act->exeState = EXE_STATE_DONE;
//
if (1 <= mLogLevelI) {
if (CC_UNLIKELY(!act->isReadoutReady)) {
std::string strInfo("");
strInfo += base::StringPrintf(
"[P1::DEL]" P1INFO_ACT_STR
" Readout(%d)"
" Bypass(%d) ",
P1INFO_ACT_VAR(*act), act->isReadoutReady,
((act->getType() == ACT_TYPE_BYPASS) ? MTRUE : MFALSE));
act->res += strInfo;
}
}
//
releaseAction(rAct);
//
if (CC_LIKELY(ACT_TYPE_INTERNAL != rAct->getType())) {
if (CC_LIKELY(act->appFrame != nullptr)) {
if (mpDeliverMgr != nullptr && mpDeliverMgr->runningGet()) {
mpDeliverMgr->sendActQueue(rAct, isTrigger);
} else {
P1FrameAct frameAct(rAct);
if (CC_LIKELY(frameAct.ready())) {
releaseFrame(&frameAct);
} else {
MY_LOGE("FrameAct not ready to release - " P1INFO_ACT_STR,
P1INFO_ACT_VAR(*act));
}
}
} else {
MY_LOGE("PipelineFrame is nullptr - " P1INFO_ACT_STR,
P1INFO_ACT_VAR(*act));
}
}
/* DO NOT use this P1QueAct after releaseAction() / sendActQueue() */
P1_TRACE_C_END(SLG_I); // "P1:return"
return;
}
#if 1
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// IndependentVerification Implementation
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/******************************************************************************
*
******************************************************************************/
MBOOL
P1NodeImp::IndependentVerification::exe(void) {
MBOOL bLoop = MTRUE;
std::shared_ptr<P1NodeImp> spP1NodeImp = mwpP1NodeImp.lock();
if (CC_UNLIKELY(spP1NodeImp == nullptr)) {
MY_LOGI("[P1_IV] exit");
bLoop = MFALSE;
return bLoop;
}
{
// for Periodic Inspection
MY_LOGI("[P1_IV] InflightMonitoring +++");
spP1NodeImp->inflightMonitoring(IMT_COMMON);
MY_LOGI("[P1_IV] InflightMonitoring ---");
}
//
return bLoop;
}
#endif
}; // namespace NSP1Node
}; // namespace v3
}; // namespace NSCam
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/******************************************************************************
*
******************************************************************************/
std::shared_ptr<NSCam::v3::P1Node> NSCam::v3::P1Node::createInstance() {
return std::make_shared<NSCam::v3::NSP1Node::P1NodeImp>();
}
#if MTKCAM_HAVE_SANDBOX_SUPPORT
int NSCam::v3::NSP1Node::P1NodeImp::setDynamicSensorInfoToIPCHalSensor(
size_t sensorIdx) {
IHalSensorList* pHalSensorList = GET_HalSensorList();
IIPCHalSensorListProv* pIPCSensorList = IIPCHalSensorListProv::getInstance();
if (CC_UNLIKELY(pHalSensorList == nullptr)) {
MY_LOGE("IHalSensorList is nullptr");
return -1;
}
if (CC_UNLIKELY(pIPCSensorList == nullptr)) {
MY_LOGE("IIPCHalSensorListProv is nullptr");
return -1;
}
IHalSensor* pHalSensor = pHalSensorList->createSensor(LOG_TAG, sensorIdx);
IIPCHalSensor* pIPCSensor = static_cast<IIPCHalSensor*>(
pIPCSensorList->createSensor(LOG_TAG, sensorIdx));
if (CC_UNLIKELY(pHalSensor == nullptr)) {
MY_LOGE("IHalSensor is nullptr");
return -1;
}
if (CC_UNLIKELY(pIPCSensor == nullptr)) {
MY_LOGE("IIPCHalSensor is nullptr");
return -1;
}
SensorDynamicInfo info;
MBOOL ok = pHalSensor->querySensorDynamicInfo(sensorIdx, &info);
if (CC_UNLIKELY(ok == MFALSE)) {
MY_LOGE("query SensorDynamicInfo returns failed");
return -1;
}
// set info to IPCHalSensor
pIPCSensor->ipcSetDynamicInfo(info);
return 0;
}
int NSCam::v3::NSP1Node::P1NodeImp::setDynamicInfoExToIPCHalSensor(
size_t sensorIdx, const IIPCHalSensor::DynamicInfo& info) {
IIPCHalSensorListProv* pIPCSensorList = IIPCHalSensorListProv::getInstance();
if (CC_UNLIKELY(pIPCSensorList == nullptr)) {
MY_LOGE("IIPCHalSensorListProv is nullptr");
return -1;
}
IIPCHalSensor* pIPCSensor = static_cast<IIPCHalSensor*>(
pIPCSensorList->createSensor(LOG_TAG, sensorIdx));
if (CC_UNLIKELY(pIPCSensor == nullptr)) {
MY_LOGE("IIPCHalSensor is nullptr");
return -1;
}
pIPCSensor->ipcSetDynamicInfoEx(info);
return 0;
}
#endif