blob: 3643de42d2e2afe38f370101df1ff14e2260872f [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-RequestSettingPolicyMediator"
#include <memory>
#include <mtkcam/pipeline/policy/InterfaceTableDef.h>
#include <mtkcam/pipeline/policy/IRequestSettingPolicyMediator.h>
#include "MyUtils.h"
#include <vector>
/******************************************************************************
*
******************************************************************************/
/******************************************************************************
*
******************************************************************************/
class RequestSettingPolicyMediator_Default
: public NSCam::v3::pipeline::policy::pipelinesetting::
IRequestSettingPolicyMediator {
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Data Members.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
protected: //// Static data (unchangable)
std::shared_ptr<NSCam::v3::pipeline::policy::PipelineStaticInfo const>
mPipelineStaticInfo;
std::shared_ptr<NSCam::v3::pipeline::policy::PipelineUserConfiguration const>
mPipelineUserConfiguration;
std::shared_ptr<
NSCam::v3::pipeline::policy::pipelinesetting::PolicyTable const>
mPolicyTable;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Operations.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public: //// Instantiation.
explicit RequestSettingPolicyMediator_Default(
NSCam::v3::pipeline::policy::pipelinesetting::
MediatorCreationParams const& params);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// IRequestSettingPolicyMediator Interfaces.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public: //// Interfaces.
auto evaluateRequest(
NSCam::v3::pipeline::policy::pipelinesetting::RequestOutputParams* out,
NSCam::v3::pipeline::policy::pipelinesetting::RequestInputParams const&
in) -> int override;
private:
bool misFdEnabled = false;
};
/******************************************************************************
*
******************************************************************************/
std::shared_ptr<
NSCam::v3::pipeline::policy::pipelinesetting::IRequestSettingPolicyMediator>
makeRequestSettingPolicyMediator_Default(
NSCam::v3::pipeline::policy::pipelinesetting::MediatorCreationParams const&
params) {
return std::make_shared<RequestSettingPolicyMediator_Default>(params);
}
/******************************************************************************
*
******************************************************************************/
RequestSettingPolicyMediator_Default::RequestSettingPolicyMediator_Default(
NSCam::v3::pipeline::policy::pipelinesetting::MediatorCreationParams const&
params)
: IRequestSettingPolicyMediator(),
mPipelineStaticInfo(params.pPipelineStaticInfo),
mPipelineUserConfiguration(params.pPipelineUserConfiguration),
mPolicyTable(params.pPolicyTable) {}
/******************************************************************************
*
******************************************************************************/
auto RequestSettingPolicyMediator_Default::evaluateRequest(
NSCam::v3::pipeline::policy::pipelinesetting::RequestOutputParams* out,
NSCam::v3::pipeline::policy::pipelinesetting::RequestInputParams const& in)
-> int {
NSCam::v3::pipeline::policy::fdintent::RequestOutputParams fdOut;
NSCam::v3::pipeline::policy::fdintent::RequestInputParams fdIn;
NSCam::v3::pipeline::policy::p2nodedecision::RequestOutputParams
p2DecisionOut;
NSCam::v3::pipeline::policy::p2nodedecision::RequestInputParams p2DecisionIn;
NSCam::v3::pipeline::policy::featuresetting::RequestOutputParams featureOut;
NSCam::v3::pipeline::policy::featuresetting::RequestInputParams featureIn;
NSCam::v3::pipeline::policy::capturestreamupdater::RequestOutputParams
capUpdaterOut;
NSCam::v3::pipeline::policy::capturestreamupdater::RequestInputParams
capUpdaterIn;
std::shared_ptr<NSCam::v3::IImageStreamInfo> pJpeg_YUV = nullptr;
std::shared_ptr<NSCam::v3::IImageStreamInfo> pThumbnail_YUV = nullptr;
bool noP2Node = !in.pConfiguration_PipelineNodesNeed->needP2CaptureNode &&
!in.pConfiguration_PipelineNodesNeed->needP2StreamNode;
// (1) is face detection intent?
if (CC_LIKELY(mPolicyTable->fFaceDetectionIntent != nullptr)) {
fdIn.hasFDNodeConfigured = in.pConfiguration_PipelineNodesNeed->needFDNode;
fdIn.isFdEnabled_LastFrame = misFdEnabled;
fdIn.pRequest_AppControl = in.pRequest_AppControl;
fdIn.pRequest_ParsedAppMetaControl = in.pRequest_ParsedAppMetaControl;
mPolicyTable->fFaceDetectionIntent(fdOut, fdIn);
misFdEnabled = fdOut.hasFDMeta;
}
// (2.1) are any capture streams updated?
if (in.pRequest_AppImageStreamInfo->pAppImage_Jpeg != nullptr &&
CC_LIKELY(mPolicyTable->fCaptureStreamUpdater != nullptr)) {
capUpdaterIn.sensorID = mPipelineStaticInfo->sensorIds[0];
capUpdaterIn.pRequest_AppControl = in.pRequest_AppControl;
capUpdaterIn.pRequest_ParsedAppMetaControl =
in.pRequest_ParsedAppMetaControl;
capUpdaterIn.isJpegRotationSupported =
true; // use property to control is support or not?
capUpdaterIn.pConfiguration_HalImage_Jpeg_YUV =
&(in.pConfiguration_StreamInfo_NonP1->pHalImage_Jpeg_YUV);
capUpdaterIn.pConfiguration_HalImage_Thumbnail_YUV =
&(in.pConfiguration_StreamInfo_NonP1->pHalImage_Thumbnail_YUV);
// prepare out buffer
capUpdaterOut.pHalImage_Jpeg_YUV = &pJpeg_YUV;
capUpdaterOut.pHalImage_Thumbnail_YUV = &pThumbnail_YUV;
mPolicyTable->fCaptureStreamUpdater(capUpdaterOut, capUpdaterIn);
}
// (2.2) P2Node decision: the responsibility of P2StreamNode and P2CaptureNode
if (CC_LIKELY(mPolicyTable->fP2NodeDecision != nullptr)) {
p2DecisionIn.requestNo = in.requestNo;
p2DecisionIn.hasP2CaptureNode =
in.pConfiguration_PipelineNodesNeed->needP2CaptureNode;
p2DecisionIn.hasP2StreamNode =
in.pConfiguration_PipelineNodesNeed->needP2StreamNode;
p2DecisionIn.isFdEnabled = fdOut.isFDMetaEn;
p2DecisionIn.pConfiguration_StreamInfo_NonP1 =
in.pConfiguration_StreamInfo_NonP1;
p2DecisionIn.pConfiguration_StreamInfo_P1 =
&((*(in.pConfiguration_StreamInfo_P1))[0]); // use main1 info
p2DecisionIn.pRequest_AppControl = in.pRequest_AppControl;
p2DecisionIn.pRequest_AppImageStreamInfo = in.pRequest_AppImageStreamInfo;
p2DecisionIn.pRequest_ParsedAppMetaControl =
in.pRequest_ParsedAppMetaControl;
p2DecisionIn.needThumbnail = (pThumbnail_YUV != nullptr);
mPolicyTable->fP2NodeDecision(&p2DecisionOut, p2DecisionIn);
}
// (2.3) feature setting
if (CC_LIKELY(mPolicyTable->mFeaturePolicy != nullptr) && (!noP2Node)) {
featureIn.requestNo = in.requestNo;
featureIn.Configuration_HasRecording =
mPipelineUserConfiguration->pParsedAppImageStreamInfo->hasVideoConsumer;
featureIn.maxP2CaptureSize = p2DecisionOut.maxP2CaptureSize;
featureIn.maxP2StreamSize = p2DecisionOut.maxP2StreamSize;
featureIn.needP2CaptureNode = p2DecisionOut.needP2CaptureNode;
featureIn.needP2StreamNode = p2DecisionOut.needP2StreamNode;
featureIn.pConfiguration_StreamInfo_P1 = in.pConfiguration_StreamInfo_P1;
featureIn.pRequest_AppControl = in.pRequest_AppControl;
featureIn.pRequest_AppImageStreamInfo = in.pRequest_AppImageStreamInfo;
featureIn.pRequest_ParsedAppMetaControl = in.pRequest_ParsedAppMetaControl;
for (size_t i = 0; i < mPipelineStaticInfo->sensorIds.size(); i++) {
featureIn.sensorModes.push_back((*in.pSensorMode)[i]);
}
mPolicyTable->mFeaturePolicy->evaluateRequest(&featureOut, &featureIn);
(*out).needZslFlow = featureOut.needZslFlow;
(*out).zslPolicyParams = featureOut.zslPolicyParams;
(*out).needReconfiguration = featureOut.needReconfiguration;
(*out).sensorModes = featureOut.sensorModes;
(*out).reconfigCategory = featureOut.reconfigCategory;
(*out).boostScenario = featureOut.boostScenario;
(*out).featureFlag = featureOut.featureFlag;
}
// (3) build every frames out param
#define NOT_DUMMY (0)
#define POST_DUMMY (1)
#define PRE_DUMMY (2)
auto buildOutParam =
[&](std::shared_ptr<NSCam::v3::pipeline::policy::featuresetting ::
RequestResultParams> const setting,
int dummy, bool isMain) -> int {
MY_LOGD("build out frame param +");
std::shared_ptr<
NSCam::v3::pipeline::policy::pipelinesetting::RequestResultParams>
result = std::make_shared<NSCam::v3::pipeline::policy::pipelinesetting::
RequestResultParams>();
// build topology
NSCam::v3::pipeline::policy::topology::RequestOutputParams topologyOut;
NSCam::v3::pipeline::policy::topology::RequestInputParams topologyIn;
if (CC_LIKELY(mPolicyTable->fTopology != nullptr)) {
topologyIn.isDummyFrame = dummy != 0;
topologyIn.isFdEnabled = (isMain) ? fdOut.isFdEnabled : false;
topologyIn.needP2CaptureNode = p2DecisionOut.needP2CaptureNode;
topologyIn.needP2StreamNode =
(isMain) ? p2DecisionOut.needP2StreamNode
: false; // p2 stream node don't need process sub frame
topologyIn.pConfiguration_PipelineNodesNeed =
in.pConfiguration_PipelineNodesNeed; // topology no need to ref?
topologyIn.pConfiguration_StreamInfo_NonP1 =
in.pConfiguration_StreamInfo_NonP1;
topologyIn.pPipelineStaticInfo = mPipelineStaticInfo.get();
topologyIn.pRequest_AppImageStreamInfo =
(isMain) ? in.pRequest_AppImageStreamInfo : nullptr;
topologyIn.pvImageStreamId_from_CaptureNode =
&(p2DecisionOut.vImageStreamId_from_CaptureNode);
topologyIn.pvImageStreamId_from_StreamNode =
&(p2DecisionOut.vImageStreamId_from_StreamNode);
topologyIn.pvMetaStreamId_from_CaptureNode =
&(p2DecisionOut.vMetaStreamId_from_CaptureNode);
topologyIn.pvMetaStreamId_from_StreamNode =
&(p2DecisionOut.vMetaStreamId_from_StreamNode);
// prepare output buffer
topologyOut.pNodesNeed = &(result->nodesNeed);
topologyOut.pNodeSet = &(result->nodeSet);
topologyOut.pRootNodes = &(result->roots);
topologyOut.pEdges = &(result->edges);
mPolicyTable->fTopology(topologyOut, topologyIn);
}
// build P2 IO map
NSCam::v3::pipeline::policy::iomap::RequestOutputParams iomapOut;
NSCam::v3::pipeline::policy::iomap::RequestInputParams iomapIn;
if (CC_LIKELY(mPolicyTable->fIOMap_P2Node != nullptr) &&
CC_LIKELY(mPolicyTable->fIOMap_NonP2Node != nullptr)) {
std::vector<uint32_t> needP1Dma;
iomapIn.pConfiguration_StreamInfo_NonP1 =
in.pConfiguration_StreamInfo_NonP1;
iomapIn.pConfiguration_StreamInfo_P1 = in.pConfiguration_StreamInfo_P1;
iomapIn.pRequest_HalImage_Thumbnail_YUV = pThumbnail_YUV.get();
iomapIn.pRequest_AppImageStreamInfo = in.pRequest_AppImageStreamInfo;
if (setting != nullptr) {
iomapIn.pRequest_NeedP1Dma = &(setting->needP1Dma);
} else {
for (int i = 0; i < topologyOut.pNodesNeed->needP1Node.size(); i++) {
uint32_t P1Dma = 0;
if (topologyOut.pNodesNeed->needP1Node[i] == true) {
P1Dma = NSCam::v3::pipeline::policy::P1_IMGO |
NSCam::v3::pipeline::policy::P1_LCSO;
}
needP1Dma.push_back(P1Dma);
}
iomapIn.pRequest_NeedP1Dma = &(needP1Dma);
}
iomapIn.pRequest_PipelineNodesNeed = topologyOut.pNodesNeed;
iomapIn.pvImageStreamId_from_CaptureNode =
&(p2DecisionOut.vImageStreamId_from_CaptureNode);
iomapIn.pvImageStreamId_from_StreamNode =
&(p2DecisionOut.vImageStreamId_from_StreamNode);
iomapIn.pvMetaStreamId_from_CaptureNode =
&(p2DecisionOut.vMetaStreamId_from_CaptureNode);
iomapIn.pvMetaStreamId_from_StreamNode =
&(p2DecisionOut.vMetaStreamId_from_StreamNode);
iomapIn.isMainFrame = isMain;
iomapIn.isDummyFrame = dummy != 0;
// prepare output buffer
iomapOut.pNodeIOMapImage = &(result->nodeIOMapImage);
iomapOut.pNodeIOMapMeta = &(result->nodeIOMapMeta);
if (dummy == NOT_DUMMY) {
mPolicyTable->fIOMap_P2Node(iomapOut, iomapIn);
}
mPolicyTable->fIOMap_NonP2Node(iomapOut, iomapIn);
}
//
if (isMain) {
if (pJpeg_YUV != nullptr) {
result->vUpdatedImageStreamInfo[pJpeg_YUV->getStreamId()] = pJpeg_YUV;
}
if (pThumbnail_YUV != nullptr) {
result->vUpdatedImageStreamInfo[pThumbnail_YUV->getStreamId()] =
pThumbnail_YUV;
}
}
if (setting != nullptr) {
result->additionalApp = setting->additionalApp;
result->additionalHal = setting->vAdditionalHal;
} else {
result->additionalApp = std::make_shared<NSCam::IMetadata>();
for (int i = 0; i < topologyOut.pNodesNeed->needP1Node.size(); i++) {
result->additionalHal.push_back(std::make_shared<NSCam::IMetadata>());
}
}
// update Metdata
if (CC_LIKELY(mPolicyTable->pRequestMetadataPolicy != nullptr)) {
NSCam::v3::pipeline::policy::requestmetadata::EvaluateRequestParams
metdataParams;
metdataParams.requestNo = in.requestNo;
metdataParams.isZSLMode = in.isZSLMode;
metdataParams.pRequest_AppImageStreamInfo =
in.pRequest_AppImageStreamInfo;
metdataParams.pRequest_ParsedAppMetaControl =
in.pRequest_ParsedAppMetaControl;
metdataParams.pSensorSize = in.pSensorSize;
metdataParams.pAdditionalApp = result->additionalApp;
metdataParams.pvAdditionalHal = &result->additionalHal;
metdataParams.pRequest_AppControl = in.pRequest_AppControl;
for (size_t i = 0; i < in.pConfiguration_StreamInfo_P1->size(); i++) {
if ((*(in.pConfiguration_StreamInfo_P1))[i].pHalImage_P1_Rrzo !=
nullptr) {
metdataParams.RrzoSize.push_back(
(*(in.pConfiguration_StreamInfo_P1))[i]
.pHalImage_P1_Rrzo->getImgSize());
}
}
mPolicyTable->pRequestMetadataPolicy->evaluateRequest(metdataParams);
}
if (isMain) {
(*out).mainFrame = result;
MY_LOGD("build mainFrame -");
} else {
switch (dummy) {
case NOT_DUMMY:
(*out).subFrames.push_back(result);
break;
case POST_DUMMY:
(*out).postDummyFrames.push_back(result);
break;
case PRE_DUMMY:
(*out).preDummyFrames.push_back(result);
break;
default:
MY_LOGW("Cannot be here");
break;
}
}
MY_LOGD("build out frame param -");
return NSCam::OK;
};
if (noP2Node) {
buildOutParam(nullptr, NOT_DUMMY, true);
MY_LOGD("no p2 node process done");
return NSCam::OK;
}
buildOutParam(featureOut.mainFrame, NOT_DUMMY, true);
for (auto const& it : featureOut.subFrames) {
buildOutParam(it, NOT_DUMMY, false);
}
for (auto const& it : featureOut.postDummyFrames) {
buildOutParam(it, POST_DUMMY, false);
}
for (auto const& it : featureOut.preDummyFrames) {
buildOutParam(it, PRE_DUMMY, false);
}
return NSCam::OK;
}