blob: 819324d7db73fe66cc8f10e280cdba14074d4642 [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.
*/
#include "camera/hal/mediatek/mtkcam/pipeline/hwnode/p2/P2_StreamingNode.h"
#include <mtkcam/utils/debug/P2_DebugControl.h>
#define P2_CLASS_TAG StreamingNode
#define P2_TRACE TRACE_P2_NODE
#include "P2_LogHeader.h"
#include <memory>
std::shared_ptr<P2StreamingNode> P2StreamingNode::createInstance(
P2StreamingNode::ePass2Type const type,
NSCam::v3::P2Common::UsageHint usage) {
if (type < 0 || type >= PASS2_TYPE_TOTAL) {
MY_LOGE("not supported p2 type %d", type);
return nullptr;
}
return std::make_shared<P2::P2StreamingNodeImp>(type, usage);
}
namespace P2 {
P2StreamingNodeImp::P2StreamingNodeImp(
const P2StreamingNode::ePass2Type pass2Type,
const NSCam::v3::P2Common::UsageHint& usageHint)
: BaseNode(), P2StreamingNode() {
MY_LOG_FUNC_ENTER("StreamingNode");
MUINT32 logLevel = property_get_int32(KEY_P2_LOG, VAL_P2_LOG);
mLog = NSCam::Utils::makeLogger("", "P2S", logLevel);
mDispatcher = std::make_shared<DispatchProcessor>();
mP2Info = std::make_shared<P2InfoObj>(mLog);
mP2Info->mConfigInfo.mP2Type = toP2Type(pass2Type, usageHint);
mP2Info->mConfigInfo.mUsageHint = toP2UsageHint(usageHint);
mP2Info->mConfigInfo.mLogLevel = logLevel;
MY_LOG_FUNC_EXIT();
}
P2StreamingNodeImp::~P2StreamingNodeImp() {
MY_LOG_S_FUNC_ENTER(mLog);
if (mStatus != STATUS_IDLE) {
this->uninit();
}
MY_LOG_S_FUNC_EXIT(mLog);
}
NSCam::MERROR P2StreamingNodeImp::init(
const IPipelineNode::InitParams& initParam) {
ILog sensorLog = NSCam::Utils::makeSensorLogger(mLog, initParam.openId);
MY_LOG_S_FUNC_ENTER(sensorLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "StreamingNode::init");
MBOOL ret = MFALSE;
if (mStatus != STATUS_IDLE) {
MY_S_LOGW(sensorLog, "cannot init: status[%d] != IDLE", mStatus);
} else {
mDispatcher->setNeedThread(MFALSE);
ret = parseInitParam(sensorLog, initParam) &&
mDispatcher->init(P2InitParam(
P2Info(mP2Info, sensorLog, mP2Info->mConfigInfo.mMainSensorID)));
if (ret) {
mLog = sensorLog;
mStatus = STATUS_READY;
}
}
MY_LOG_S_FUNC_EXIT(sensorLog);
return ret ? OK : UNKNOWN_ERROR;
}
NSCam::MERROR P2StreamingNodeImp::uninit() {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "StreamingNode::uninit");
MBOOL ret = MFALSE;
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot uninit: status[%d] != READY", mStatus);
} else {
mDispatcher->uninit();
mStatus = STATUS_IDLE;
ret = MTRUE;
}
MY_LOG_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
NSCam::MERROR P2StreamingNodeImp::config(
const P2StreamingNode::ConfigParams& configParam) {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "StreamingNode::config");
MBOOL ret = MFALSE;
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot config: status[%d] != READY", mStatus);
} else {
ret = parseConfigParam(configParam) &&
mDispatcher->config(P2ConfigParam(P2Info(
mP2Info, mP2Info->mLog, mP2Info->mConfigInfo.mMainSensorID)));
}
MY_LOG_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
NSCam::MERROR P2StreamingNodeImp::queue(std::shared_ptr<IPipelineFrame> frame) {
TRACE_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
MBOOL ret = MFALSE;
if (mStatus != STATUS_READY) {
MY_LOGE("cannot queue: status[%d] != READY", mStatus);
} else if (frame == nullptr) {
MY_LOGE("cannot queue: pipeline frame = NULL");
} else {
std::shared_ptr<MWFrame> frameHolder;
P2_CAM_TRACE_BEGIN(TRACE_ADVANCED, "StreamingNode:queue->newMWFrame");
MUINT32 frameID = generateFrameID();
ILog frameLog = NSCam::Utils::makeFrameLogger(
mLog, frame->getFrameNo(), frame->getRequestNo(), frameID);
frameHolder =
std::make_shared<MWFrame>(frameLog, mNodeID, mNodeName, frame);
P2_CAM_TRACE_END(TRACE_ADVANCED);
if (frameHolder == nullptr) {
MY_LOGE("@@ OOM: allocate MWFrame failed");
} else {
// MWFrame will handle callback even if enque failed
ret = MTRUE;
std::shared_ptr<P2FrameRequest> request;
if (prepareFrameRequest(frameLog, &request, frameHolder)) {
mDispatcher->enque(request);
}
}
}
TRACE_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
NSCam::MERROR P2StreamingNodeImp::kick() {
return OK;
}
NSCam::MERROR P2StreamingNodeImp::flush() {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "StreamingNode::flush");
MBOOL ret = MTRUE;
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot flush: status[%d] != READY", mStatus);
ret = MFALSE;
} else {
mDispatcher->flush();
}
MY_LOG_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
NSCam::MERROR P2StreamingNodeImp::flush(
const std::shared_ptr<IPipelineFrame>& frame) {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "StreamingNode::flush");
if (frame != nullptr) {
ILog log = NSCam::Utils::makeFrameLogger(mLog, frame->getFrameNo(),
frame->getRequestNo(), 0);
MWFrame::flushFrame(log, frame, mNodeID);
}
MY_LOG_S_FUNC_EXIT(mLog);
return OK;
}
MINT32 P2StreamingNodeImp::getOpenId() const {
TRACE_S_FUNC_ENTER(mLog);
TRACE_S_FUNC_EXIT(mLog);
return mP2Info->mConfigInfo.mMainSensorID;
}
P2StreamingNodeImp::NodeId_T P2StreamingNodeImp::getNodeId() const {
TRACE_S_FUNC_ENTER(mLog);
TRACE_S_FUNC_EXIT(mLog);
return mNodeID;
}
char const* P2StreamingNodeImp::getNodeName() const {
TRACE_S_FUNC_ENTER(mLog);
TRACE_S_FUNC_EXIT(mLog);
return mNodeName.c_str();
}
P2Type P2StreamingNodeImp::toP2Type(
P2StreamingNode::ePass2Type /*pass2type*/,
const NSCam::v3::P2Common::UsageHint& hint) const {
TRACE_S_FUNC_ENTER(mLog);
P2Type type = P2_UNKNOWN;
if (hint.mAppMode == NSCam::v3::P2Common::APP_MODE_VIDEO) {
type = P2_VIDEO;
} else if (hint.mAppMode == NSCam::v3::P2Common::APP_MODE_HIGH_SPEED_VIDEO) {
type = P2_HS_VIDEO;
} else {
type = P2_PHOTO;
}
TRACE_S_FUNC_EXIT(mLog);
return type;
}
P2UsageHint P2StreamingNodeImp::toP2UsageHint(
const NSCam::v3::P2Common::UsageHint& hint) const {
TRACE_S_FUNC_ENTER(mLog);
P2UsageHint usage;
usage.mStreamingSize = hint.mStreamingSize;
usage.m3DNRMode = hint.m3DNRMode;
usage.mUseTSQ = hint.mUseTSQ;
usage.mDynamicTuning = property_get_int32("vendor.debug.p2.dynamicTuning", 1);
usage.mOutCfg.mMaxOutNum = hint.mOutCfg.mMaxOutNum;
usage.mOutCfg.mHasPhysical = hint.mOutCfg.mHasPhysical;
usage.mOutCfg.mHasLarge = hint.mOutCfg.mHasLarge;
TRACE_S_FUNC_EXIT(mLog);
return usage;
}
MUINT32 P2StreamingNodeImp::generateFrameID() {
TRACE_S_FUNC_ENTER(mLog);
TRACE_S_FUNC_EXIT(mLog);
return ++mFrameCount;
}
MBOOL P2StreamingNodeImp::parseInitParam(
const ILog& log, const IPipelineNode::InitParams& initParam) {
TRACE_S_FUNC_ENTER(log);
MBOOL ret = MTRUE;
this->mNodeID = initParam.nodeId;
this->mNodeName = initParam.nodeName;
mP2Info->mConfigInfo.mMainSensorID = initParam.openId;
mP2Info->mConfigInfo.mLog = log;
mP2Info->mLog = log;
mP2Info->addSensorInfo(log, initParam.openId);
for (MUINT32 id : initParam.subOpenIdList) {
if (id != (MUINT32)initParam.openId) {
ILog sensorLog = makeSensorLogger(log, id);
mP2Info->addSensorInfo(sensorLog, id);
}
}
mInIDMap = std::make_shared<P2InIDMap>(mP2Info->mConfigInfo.mAllSensorID,
initParam.openId);
TRACE_S_FUNC_EXIT(log);
return ret;
}
MBOOL P2StreamingNodeImp::parseConfigParam(
const P2StreamingNode::ConfigParams& configParam) {
TRACE_S_FUNC_ENTER(mLog);
MBOOL ret = MFALSE;
std::shared_ptr<MWInfo> info = std::make_shared<MWInfo>(configParam);
if (info == nullptr) {
MY_LOGE("OOM: allocate MWInfo failed");
} else if (!info->isValid(mP2Info->mConfigInfo.mLog)) {
MY_LOGE("invalid config param");
} else {
mMWInfo = info;
mP2Info = mP2Info->clone();
mP2Info->mConfigInfo.mUsageHint = toP2UsageHint(configParam.mUsageHint);
mP2Info->mConfigInfo.mStreamConfigure = configParam.vStreamConfigure;
updateConfigInfo(mP2Info, mMWInfo);
ret = MTRUE;
}
TRACE_S_FUNC_EXIT(mLog);
return ret;
}
MVOID P2StreamingNodeImp::updateConfigInfo(
const std::shared_ptr<P2InfoObj>& p2Info,
const std::shared_ptr<MWInfo>& mwInfo) {
TRACE_S_FUNC_ENTER(mLog);
p2Info->mConfigInfo.mBurstNum = mwInfo->getBurstNum();
p2Info->mConfigInfo.mCustomOption = mwInfo->getCustomOption();
TRACE_S_FUNC_EXIT(mLog);
}
MBOOL P2StreamingNodeImp::prepareFrameRequest(
const ILog& log,
std::shared_ptr<P2FrameRequest>* request,
const std::shared_ptr<MWFrame>& frameHolder) {
TRACE_S_FUNC_ENTER(log);
MBOOL ret = MTRUE;
std::shared_ptr<P2DataObj> p2Data = std::make_shared<P2DataObj>(log);
p2Data->mFrameData.mP2FrameNo = log.getLogFrameID();
P2Pack p2Pack(log, mP2Info, p2Data);
P2_CAM_TRACE_BEGIN(TRACE_ADVANCED, "new MWFrameRequest");
*request = std::make_shared<MWFrameRequest>(log, p2Pack, p2Data, mMWInfo,
frameHolder, mInIDMap);
P2_CAM_TRACE_END(TRACE_ADVANCED);
if (*request == nullptr) {
MY_LOGE("prepareFrameRequest OOM: allocate MWFrameRequest failed");
ret = MFALSE;
}
TRACE_S_FUNC_EXIT(log);
return ret;
}
} // namespace P2