blob: 209de1be60ca90a796e8ad329f4e6289d3849935 [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/inFlightRequest"
//
#include "MyUtils.h"
#include <mtkcam/utils/std/Trace.h>
#include <memory>
#include <mtkcam/pipeline/pipeline/InFlightRequest.h>
#include <property_lib.h>
#include <string>
#include <utility>
#include <vector>
//
using NSCam::v3::InFlightRequest;
/******************************************************************************
*
******************************************************************************/
InFlightRequest::InFlightRequest() : IPipelineFrameListener() {}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::dumpState(const std::vector<std::string>& options) const {
{
mLock.lock();
for (auto const& v : mRequest) {
auto pFrame = v.second.lock();
if (pFrame != nullptr) {
pFrame->dumpState(options);
}
}
mLock.unlock();
}
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::registerRequest(
std::shared_ptr<IPipelineFrame> const& pFrame) {
MY_LOGD("+");
std::lock_guard<std::mutex> _l(mLock);
// add request
mRequest.push_back(std::make_pair(pFrame->getFrameNo(), pFrame));
// add node
std::vector<IPipelineDAG::NodeObj_T> const& vNode =
pFrame->getPipelineDAG().getToposort();
for (size_t s = 0; s < vNode.size(); s++) {
NodeId_T node = vNode[s].id;
std::shared_ptr<IStreamInfoSet const> in, out;
if (CC_UNLIKELY(OK != pFrame->queryIOStreamInfoSet(node, &in, &out))) {
MY_LOGE("queryIOStreamInfoSet failed");
break;
}
//
if (out->getImageInfoNum() > 0 || out->getMetaInfoNum() > 0) {
auto it = mRequestMap_image.find(node);
if (it == mRequestMap_image.end()) {
RequestList frameL;
frameL.push_back(pFrame->getFrameNo());
mRequestMap_image.emplace(node, frameL);
} else {
it->second.push_back(pFrame->getFrameNo());
}
auto it2 = mRequestMap_meta.find(node);
if (it2 == mRequestMap_meta.end()) {
RequestList frameL;
frameL.push_back(pFrame->getFrameNo());
mRequestMap_meta.emplace(node, frameL);
} else {
it2->second.push_back(pFrame->getFrameNo());
}
}
}
// register
pFrame->attachListener(shared_from_this(), nullptr);
MY_LOGD("-");
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::waitUntilDrained() {
CAM_TRACE_CALL();
MY_LOGD("+");
std::unique_lock<std::mutex> _l(mLock);
while (!mRequest.empty()) {
MY_LOGD_IF(1, "frameNo:%u in the front", (*(mRequest.begin())).first);
mRequestCond.wait(_l);
}
MY_LOGD("-");
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::waitUntilNodeDrained(NodeId_T id) {
CAM_TRACE_CALL();
waitUntilNodeMetaDrained(id);
waitUntilNodeImageDrained(id);
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::waitUntilNodeMetaDrained(NodeId_T id) {
std::unique_lock<std::mutex> _l(mLock);
do {
auto it = mRequestMap_meta.find(id);
if (it == mRequestMap_meta.end() || it->second.empty()) {
break;
}
MY_LOGD("Node: %" PRIdPTR " has frameNo: %d in the front of meta list", id,
*(it->second.begin()));
mRequestCond.wait(_l);
} while (1);
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::waitUntilNodeImageDrained(NodeId_T id) {
std::unique_lock<std::mutex> _l(mLock);
do {
auto it = mRequestMap_image.find(id);
if (it == mRequestMap_image.end() || it->second.empty()) {
break;
}
MY_LOGD("Node: %" PRIdPTR " has frameNo: %d in the front of image list", id,
*(it->second.begin()));
mRequestCond.wait(_l);
} while (1);
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::onPipelineFrame(MUINT32 const frameNo,
MUINT32 const message,
MVOID* const /*pCookie*/
) {
MY_LOGD("frame: %d message: %#x", frameNo, message);
std::lock_guard<std::mutex> _l(mLock);
if (message == eMSG_FRAME_RELEASED) {
for (FrameListT::iterator it = mRequest.begin(); it != mRequest.end();
it++) {
if ((*it).first == frameNo) {
mRequest.erase(it);
mRequestCond.notify_all();
break;
}
}
}
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::onPipelineFrame(MUINT32 const frameNo,
NodeId_T const nodeId,
MUINT32 const message,
MVOID* const /*pCookie*/
) {
MY_LOGD("frame: %d, nodeId: %" PRIdPTR ", msg: %d", frameNo, nodeId, message);
std::lock_guard<std::mutex> _l(mLock);
auto it_meta = mRequestMap_meta.find(nodeId);
auto it_image = mRequestMap_image.find(nodeId);
if (CC_UNLIKELY(it_meta == mRequestMap_meta.end() &&
it_image == mRequestMap_image.end())) {
MY_LOGE("no node in meta/image mapper: %" PRIdPTR "", nodeId);
return;
}
switch (message) {
case eMSG_ALL_OUT_META_BUFFERS_RELEASED: {
RequestList& list = it_meta->second;
for (RequestList::iterator it = list.begin(); it != list.end(); it++) {
if (*it == frameNo) {
list.erase(it);
break;
}
}
mRequestCond.notify_all();
} break;
case eMSG_ALL_OUT_IMAGE_BUFFERS_RELEASED: {
RequestList& list = it_image->second;
for (RequestList::iterator it = list.begin(); it != list.end(); it++) {
if (*it == frameNo) {
list.erase(it);
break;
}
}
mRequestCond.notify_all();
} break;
default:
break;
}
}
/******************************************************************************
*
******************************************************************************/
MVOID
InFlightRequest::clear() {
std::lock_guard<std::mutex> _l(mLock);
mRequestMap_meta.clear();
mRequestMap_image.clear();
mRequest.clear();
}