blob: a567b8d960ba061a0e5b3b29234bc44837e56c3a [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_CaptureNode.h"
#include <mtkcam/utils/debug/P2_DebugControl.h>
#define P2_CLASS_TAG CaptureNode
#define P2_TRACE TRACE_P2_NODE
#include "P2_LogHeader.h"
#include <memory>
std::shared_ptr<P2CaptureNode> P2CaptureNode::createInstance(ePass2Type type) {
if (type < 0 || type >= PASS2_TYPE_TOTAL) {
MY_LOGE("not supported p2 type %d", type);
return nullptr;
}
return std::make_shared<P2::P2CaptureNodeImp>(type);
}
P2::P2CaptureNodeImp::P2CaptureNodeImp(const ePass2Type pass2Type)
: BaseNode() {
MY_LOG_FUNC_ENTER("CaptureNode");
mNodeName = "P2CaptureNode"; // default name
MUINT32 logLevel = property_get_int32(KEY_P2_LOG, VAL_P2_LOG);
mLog = NSCam::Utils::makeLogger("", "P2C", logLevel);
mCaptureProcessor = std::make_shared<CaptureProcessor>();
mP2Info = std::make_shared<P2InfoObj>(mLog);
mP2Info->mConfigInfo.mP2Type = toP2Type(pass2Type);
mP2Info->mConfigInfo.mLogLevel = logLevel;
MY_LOG_FUNC_EXIT();
}
P2::P2CaptureNodeImp::~P2CaptureNodeImp() {
MY_LOG_S_FUNC_ENTER(mLog);
if (mStatus != STATUS_IDLE) {
this->uninit();
}
MY_LOG_S_FUNC_EXIT(mLog);
}
MERROR P2::P2CaptureNodeImp::init(const InitParams& rParams) {
ILog sensorLog = makeSensorLogger(mLog, rParams.openId);
MY_LOG_S_FUNC_ENTER(sensorLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "CaptureNode::init");
if (mStatus != STATUS_IDLE) {
MY_S_LOGW(sensorLog, "cannot init: status[%d] != IDLE", mStatus);
return INVALID_OPERATION;
}
MBOOL ret = MFALSE;
mCaptureProcessor->setEnable(MTRUE);
mP2Info->mConfigInfo.mMainSensorID = rParams.openId;
mP2Info->mConfigInfo.mLog = sensorLog;
mP2Info->mLog = sensorLog;
mP2Info->addSensorInfo(sensorLog, rParams.openId);
for (MUINT32 id : rParams.subOpenIdList) {
if (id != rParams.openId) {
ILog log = makeSensorLogger(mLog, id);
mP2Info->addSensorInfo(log, id);
}
}
mInIDMap = std::make_shared<P2InIDMap>(mP2Info->mConfigInfo.mAllSensorID,
rParams.openId);
ret = mCaptureProcessor->init(P2InitParam(
P2Info(mP2Info, sensorLog, mP2Info->mConfigInfo.mMainSensorID)));
if (ret) {
mLog = sensorLog;
mStatus = STATUS_READY;
mOpenId = rParams.openId;
mNodeId = rParams.nodeId;
mNodeName = rParams.nodeName;
MY_LOGD("OpenId %d, nodeId %#" PRIxPTR ", name %s", getOpenId(),
getNodeId(), getNodeName());
}
MY_LOG_S_FUNC_EXIT(sensorLog);
return ret ? OK : UNKNOWN_ERROR;
}
MERROR P2::P2CaptureNodeImp::uninit() {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "CaptureNode::uninit");
MBOOL ret = MFALSE;
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot uninit: status[%d] != READY", mStatus);
} else {
mCaptureProcessor->uninit();
mStatus = STATUS_IDLE;
ret = MTRUE;
}
MY_LOG_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
MERROR P2::P2CaptureNodeImp::config(const ConfigParams& configParam) {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "CaptureNode::config");
MBOOL ret = MFALSE;
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot config: status[%d] != READY", mStatus);
} else {
ret = parseConfigParam(configParam) &&
mCaptureProcessor->config(P2ConfigParam(P2Info(
mP2Info, mP2Info->mLog, mP2Info->mConfigInfo.mMainSensorID)));
}
MY_LOG_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
MERROR P2::P2CaptureNodeImp::queue(std::shared_ptr<IPipelineFrame> frame) {
TRACE_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "CaptureNode::queue");
MBOOL ret = MFALSE;
MY_LOGD("req#:%d, frame#:%d", frame->getRequestNo(), frame->getFrameNo());
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot queue: status[%d] != READY", mStatus);
} else if (frame == nullptr) {
MY_S_LOGW(mLog, "cannot queue: pipeline frame = NULL");
} else {
mRequestNo = frame->getRequestNo();
MUINT32 uFrameNo = frame->getFrameNo();
ILog frameLog =
NSCam::Utils::makeFrameLogger(mLog, uFrameNo, mRequestNo, uFrameNo);
std::shared_ptr<MWFrame> frameHolder =
std::make_shared<MWFrame>(frameLog, mNodeId, mNodeName, frame);
// MWFrame will handle callback even if enque failed
std::shared_ptr<P2FrameRequest> pFrameRequest =
createFrameRequest(frameLog, frameHolder);
if (pFrameRequest != nullptr) {
mCaptureProcessor->enque(pFrameRequest);
ret = MTRUE;
}
}
TRACE_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
MERROR P2::P2CaptureNodeImp::flush() {
MY_LOG_S_FUNC_ENTER(mLog);
std::lock_guard<std::mutex> _lock(mMutex);
P2_CAM_TRACE_NAME(TRACE_DEFAULT, "CaptureNode::flush");
MBOOL ret = MTRUE;
if (mStatus != STATUS_READY) {
MY_S_LOGW(mLog, "cannot flush: status[%d] != READY", mStatus);
ret = MFALSE;
} else {
mCaptureProcessor->flush();
}
MY_LOG_S_FUNC_EXIT(mLog);
return ret ? OK : UNKNOWN_ERROR;
}
MERROR P2::P2CaptureNodeImp::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, "CaptureNode::flush");
if (frame != nullptr) {
if (frame->getRequestNo() == mRequestNo) {
// Ensure that multi-frame request doesn't drop a frame
queue(frame);
} else {
ILog log = NSCam::Utils::makeFrameLogger(mLog, frame->getFrameNo(),
frame->getRequestNo(), 0);
MWFrame::flushFrame(log, frame, mNodeId);
}
}
MY_LOG_S_FUNC_EXIT(mLog);
return OK;
}
P2Type P2::P2CaptureNodeImp::toP2Type(ePass2Type pass2type) const {
P2Type type = P2_UNKNOWN;
if (pass2type == PASS2_TIMESHARING) {
type = P2_TIMESHARE_CAPTURE;
} else {
type = P2_CAPTURE;
}
return type;
}
MBOOL P2::P2CaptureNodeImp::parseConfigParam(const ConfigParams& configParam) {
TRACE_S_FUNC_ENTER(mLog);
MBOOL ret = MFALSE;
std::shared_ptr<MWInfo> info = std::make_shared<MWInfo>(configParam);
if (!info->isValid(mP2Info->mConfigInfo.mLog)) {
MY_S_LOGW(mLog, "invalid config param");
} else {
mMWInfo = info;
mP2Info = mP2Info->clone();
mP2Info->mConfigInfo.mStreamConfigure = configParam.vStreamConfigure;
updateConfigInfo(mP2Info, mMWInfo);
ret = MTRUE;
}
TRACE_S_FUNC_EXIT(mLog);
return ret;
}
MVOID P2::P2CaptureNodeImp::updateConfigInfo(
const std::shared_ptr<P2InfoObj>& p2Info,
const std::shared_ptr<MWInfo>& mwInfo) {
TRACE_S_FUNC_ENTER(mLog);
p2Info->mConfigInfo.mCustomOption = mwInfo->getCustomOption();
TRACE_S_FUNC_EXIT(mLog);
}
std::shared_ptr<P2::P2FrameRequest> P2::P2CaptureNodeImp::createFrameRequest(
const ILog& log, const std::shared_ptr<MWFrame>& frameHolder) {
TRACE_S_FUNC_ENTER(log);
std::shared_ptr<P2DataObj> p2Data = std::make_shared<P2DataObj>(log);
p2Data->mFrameData.mP2FrameNo = log.getLogFrameID();
P2Pack p2Pack(log, mP2Info, p2Data);
std::shared_ptr<P2FrameRequest> request = std::make_shared<MWFrameRequest>(
log, p2Pack, p2Data, mMWInfo, frameHolder, mInIDMap);
TRACE_S_FUNC_EXIT(log);
return request;
}