blob: 473e3e05ef7ddef68787475d6a413bbd1c4e77f6 [file] [log] [blame]
/*
* Copyright (C) 2014-2018 Intel Corporation
*
* 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 "InputSystem"
#include <string>
#include "InputSystem.h"
#include "MediaController.h"
#include "PlatformData.h"
#include "MediaEntity.h"
#include "LogHelper.h"
#include "PerformanceTraces.h"
#include "IPU3CameraCapInfo.h"
#include "GraphConfigManager.h"
#include "GraphConfig.h"
#include "CameraStream.h"
namespace cros {
namespace intel {
InputSystem::InputSystem(IISysObserver *observer, std::shared_ptr<MediaController> mediaCtl):
mObserver(observer),
mMediaCtl(mediaCtl),
mMediaCtlHelper(mediaCtl, this),
mStarted(false),
mIsysRequestPool("IsysRequestPool"),
mBuffersReceived(0),
mBufferSeqNbr(0),
mCameraThread("InputSystem"),
mPollerThread(new PollerThread("IsysPollerThread")),
mRequestDone(true),
mPollErrorTimes(0),
mErrCb(nullptr)
{
LOG1("@%s", __FUNCTION__);
mIsysRequestPool.init(MAX_REQUEST_IN_PROCESS_NUM);
mPendingIsysRequests.clear();
if (!mCameraThread.Start()) {
LOGE("Camera thread failed to start");
}
}
InputSystem::~InputSystem()
{
LOG1("@%s", __FUNCTION__);
requestExitAndWait();
mConfiguredNodesPerName.clear();
// Clear here, since mediaRequestId does not
// make sense after nodes have been closed
mPendingIsysRequests.clear();
}
status_t InputSystem::requestExitAndWait()
{
LOG1("@%s", __FUNCTION__);
status_t status = OK;
if (mStarted) {
status_t ret = NO_ERROR;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleExit, base::Unretained(this));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &ret);
status |= ret;
}
if (mPollerThread) {
status |= mPollerThread->requestExitAndWait();
mPollerThread.reset();
}
mCameraThread.Stop();
return status;
}
void InputSystem::registerErrorCallback(IErrorCallback *errCb)
{
LOG1("@%s, errCb:%p", __FUNCTION__, errCb);
mErrCb = errCb;
}
status_t InputSystem::configure(IStreamConfigProvider &streamConfigMgr,
MediaCtlHelper::ConfigurationResults &outData)
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
CLEAR(outData);
MessageConfigure msg;
msg.streamConfigProv = &streamConfigMgr;
msg.result = &outData;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleConfigure, base::Unretained(this),
base::Passed(std::move(msg)));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
status_t InputSystem::handleConfigure(MessageConfigure msg)
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
FrameInfo videoNodeInfo;
IStreamConfigProvider &graphConfigMgr = *msg.streamConfigProv;
std::shared_ptr<GraphConfig> gc = graphConfigMgr.getBaseGraphConfig(IStreamConfigProvider::CIO2);
if (CC_UNLIKELY(gc.get() == nullptr)) {
LOGE("ERROR: Graph config is nullptr");
return status;
}
mConfiguredNodesPerName.clear(); // in the mMediaCtlHelper.configure, the mConfiguredNodesPerName will be triggered to be regenerated.
mConfiguredNodes.clear();
mStarted = false;
mMediaCtlHelper.closeVideoNodes();
mMediaCtlHelper.resetLinks();
status = mMediaCtlHelper.configure(graphConfigMgr, IStreamConfigProvider::CIO2);
if (status != OK) {
LOGE("Failed to configure input system.");
return status;
}
status = gc->getSensorFrameParams(mMediaCtlHelper.getConfigResults().sensorFrameParams);
if (status != NO_ERROR) {
LOGE("Failed to calculate Frame Params, status:%d", status);
return status;
}
status = mPollerThread->init((std::vector<std::shared_ptr<cros::V4L2Device>>&) mConfiguredNodes,
this, POLLPRI | POLLIN | POLLOUT | POLLERR, false);
if (status != NO_ERROR) {
LOGE("PollerThread init failed (ret = %d)", status);
return status;
}
if (msg.result)
*msg.result = mMediaCtlHelper.getConfigResults();
return status;
}
status_t InputSystem::opened(IPU3NodeNames isysNodeName,
std::shared_ptr<cros::V4L2VideoNode> videoNode)
{
LOG1("@%s: isysNodeName:%d", __FUNCTION__, isysNodeName);
mConfiguredNodes.push_back(videoNode);
mConfiguredNodesPerName.insert(std::make_pair(isysNodeName,
videoNode));
return OK;
}
status_t InputSystem::start()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleStart, base::Unretained(this));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
status_t InputSystem::handleStart()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
int ret = 0;
for (size_t i = 0; i < mConfiguredNodes.size(); i++) {
ret = mConfiguredNodes[i]->Start();
if (ret < 0) {
LOGE("STREAMON failed (%s)", mConfiguredNodes[i]->Name().c_str());
status = UNKNOWN_ERROR;
MessageStop msg;
msg.stop = false;
handleStop(msg);
break;
}
}
mPollErrorTimes = 0;
if (status == NO_ERROR)
mStarted = true;
CheckAndCallbackError(status != NO_ERROR, mErrCb, UNKNOWN_ERROR,
"@%s: STREAMON failed", __FUNCTION__);
return status;
}
status_t InputSystem::stop()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
MessageStop msg;
msg.stop = true;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleStop, base::Unretained(this),
base::Passed(std::move(msg)));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
status_t InputSystem::handleStop(MessageStop msg)
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
int ret = 0;
mBufferSeqNbr = 0;
mPollerThread->flush(true);
for (size_t i = 0; i < mConfiguredNodes.size(); i++) {
ret = mConfiguredNodes[i]->Stop();
if (ret < 0) {
LOGE("STREAMOFF failed (%s)", mConfiguredNodes[i]->Name().c_str());
status = UNKNOWN_ERROR;
}
}
// Video nodes will really stop after the buffer pools released
mStarted = false;
return status;
}
status_t InputSystem::releaseBufferPools()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleReleaseBufferPools,
base::Unretained(this));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
status_t InputSystem::handleReleaseBufferPools()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
int ret = 0;
// destroyBufferPool() is a private method in V4L2 class and
// it is combined into stop() method. For example, mmap'ed
// buffers require unmapping between STREAMOFF and releasing
// buffer pool. This method allows doing these steps separately.
for (size_t i = 0; i < mConfiguredNodes.size(); i++) {
ret = mConfiguredNodes[i]->Stop();
if (ret < 0) {
LOGE("Failed (%zu)", i);
status = UNKNOWN_ERROR;
}
}
mStarted = false;
/*
* Now that we are stopped we flush the poller thread to remove
* any messages there and any references to the old nodes.
*/
status = mPollerThread->flush(/* sync */ true, /* clear */ true);
if (CC_UNLIKELY(status != OK)) {
LOGW("Input system poller thread flush failed!!");
}
return status;
}
bool InputSystem::isStarted()
{
LOG1("@%s", __FUNCTION__);
bool value = false;
MessageBoolQuery msg;
msg.value = &value;
status_t status = NO_ERROR;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleIsStarted, base::Unretained(this),
base::Passed(std::move(msg)));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return value;
}
status_t InputSystem::handleIsStarted(MessageBoolQuery msg)
{
LOG1("@%s", __FUNCTION__);
if(msg.value)
*msg.value = mStarted;
return NO_ERROR;
}
status_t InputSystem::putFrame(IPU3NodeNames isysNodeName,
cros::V4L2Buffer *buf, int32_t reqId)
{
LOG2("@%s", __FUNCTION__);
MessageFrame msg;
msg.reqId = reqId;
msg.isysNodeName = isysNodeName;
msg.buf = buf;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handlePutFrame, base::Unretained(this),
base::Passed(std::move(msg)));
mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
return NO_ERROR;
}
status_t InputSystem::handlePutFrame(MessageFrame msg)
{
LOG2("@%s", __FUNCTION__);
std::shared_ptr<IsysRequest> isysReq;
status_t status = NO_ERROR;
bool newReq = false;
IPU3NodeNames isysNodeName = msg.isysNodeName;
cros::V4L2Buffer *buf = msg.buf;
const int32_t reqId = msg.reqId;
/* first checking if existing mediaRequest created */
auto itRequest = mPendingIsysRequests.find(reqId);
if (itRequest == mPendingIsysRequests.end()) {
// create
LOG2("%s: create new pending Isys Request for reqId %d", __FUNCTION__,
reqId);
status = mIsysRequestPool.acquireItem(isysReq);
CheckAndCallbackError(status != NO_ERROR, mErrCb, UNKNOWN_ERROR,
"@%s: failed to acquire Isys Request", __FUNCTION__);
// clear potential reused Nodes
isysReq->configuredNodesForRequest.clear();
newReq = true;
} else {
// edit
LOG2("%s: Found Pending Request for ReqId %d", __FUNCTION__, reqId);
isysReq = mPendingIsysRequests.at(reqId);
}
ConfiguredNodesPerName::iterator it =
mConfiguredNodesPerName.find(isysNodeName);
CheckAndCallbackError(it == mConfiguredNodesPerName.end(), mErrCb, BAD_VALUE,
"@%s: ISYS putframe - node (%d) not found!", __FUNCTION__,isysNodeName);
std::shared_ptr<cros::V4L2VideoNode> videoNode = it->second;
int ret = videoNode->PutFrame(buf);
CheckAndCallbackError(ret < 0, mErrCb,UNKNOWN_ERROR,
"@%s: isys putframe failed for dev: %s", __FUNCTION__,videoNode->Name().c_str());
CheckAndCallbackError(isysReq == nullptr, mErrCb, UNKNOWN_ERROR,
"@%s: isysReq is nullptr", __FUNCTION__);
isysReq->configuredNodesForRequest.push_back(videoNode);
isysReq->numNodesForRequest = isysReq->configuredNodesForRequest.size();
if (newReq) {
isysReq->requestId = msg.reqId;
mPendingIsysRequests.emplace(isysReq->requestId, isysReq);
}
return NO_ERROR;
}
status_t InputSystem::grabFrame(IPU3NodeNames isysNodeName, cros::V4L2Buffer *buf)
{
LOG2("@%s", __FUNCTION__);
ConfiguredNodesPerName::iterator it =
mConfiguredNodesPerName.find(isysNodeName);
if (it == mConfiguredNodesPerName.end()) {
LOGE("ISYS node (%d) not found!", isysNodeName);
return BAD_VALUE;
}
std::shared_ptr<cros::V4L2VideoNode> videoNode = it->second;
int ret = videoNode->GrabFrame(buf);
if (ret < 0) {
LOGE("@%s failed", __FUNCTION__);
return UNKNOWN_ERROR;
}
return NO_ERROR;
}
status_t InputSystem::setBufferPool(IPU3NodeNames isysNodeName,
std::vector<cros::V4L2Buffer> &pool,
bool cached)
{
LOG2("@%s", __FUNCTION__);
status_t status = NO_ERROR;
MessageBufferPool msg;
msg.isysNodeName = isysNodeName;
msg.pool = &pool;
msg.cached = cached;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleSetBufferPool,
base::Unretained(this), base::Passed(std::move(msg)));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
status_t InputSystem::handleSetBufferPool(MessageBufferPool msg)
{
LOG2("@%s", __FUNCTION__);
status_t status = NO_ERROR;
IPU3NodeNames isysNodeName = msg.isysNodeName;
std::vector<cros::V4L2Buffer> *pool = msg.pool;
size_t num_buffers = pool->size();
bool cached = msg.cached;
std::shared_ptr<cros::V4L2VideoNode> videoNode = nullptr;
enum v4l2_memory memType = getDefaultMemoryType(ISYS_NODE_RAW);
ConfiguredNodesPerName::iterator it =
mConfiguredNodesPerName.find(isysNodeName);
if (it == mConfiguredNodesPerName.end()) {
LOGE("@%s: ISYS node (%d) not found!", __FUNCTION__, isysNodeName);
return BAD_VALUE;
}
videoNode = it->second;
pool->clear();
status = videoNode->SetupBuffers(num_buffers, cached, memType, pool);
if (status != NO_ERROR) {
LOGE("Failed setting buffer poll into the device.");
return status;
}
return status;
}
status_t InputSystem::getOutputNodes(ConfiguredNodesPerName **nodes,
int &nodeCount)
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
MessageNodes msg;
msg.nodes = nodes;
msg.nodeCount = &nodeCount;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleGetOutputNodes,
base::Unretained(this), base::Passed(std::move(msg)));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
std::shared_ptr<cros::V4L2VideoNode> InputSystem::findOutputNode(IPU3NodeNames isysNodeName)
{
auto it = mConfiguredNodesPerName.find(isysNodeName);
if (it == mConfiguredNodesPerName.end()) {
LOGE("@%s ISYS node (%d) not found!", __FUNCTION__, isysNodeName);
return nullptr;
}
return it->second;
}
status_t InputSystem::handleGetOutputNodes(MessageNodes msg)
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
ConfiguredNodesPerName **nodes = msg.nodes;
int *nodeCount = msg.nodeCount;
if (nodes)
*nodes = &mConfiguredNodesPerName;
if (nodeCount)
*nodeCount = mConfiguredNodes.size();
return status;
}
status_t InputSystem::capture(int requestId)
{
LOG2("@%s: request ID: %d", __FUNCTION__, requestId);
MessageCapture msg;
msg.requestId = requestId;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleCapture,
base::Unretained(this), base::Passed(std::move(msg)));
mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
return NO_ERROR;
}
status_t InputSystem::handleCapture(MessageCapture msg)
{
LOG2("@%s", __FUNCTION__);
mCaptureQueue.push_back(msg.requestId);
// Start polling if all buffers for the previous request have
// been received
if (mRequestDone) {
pollNextRequest();
mRequestDone = false;
}
return NO_ERROR;
}
status_t InputSystem::flush()
{
LOG1("@%s", __FUNCTION__);
status_t status = NO_ERROR;
// flush the poll messages
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handleFlush, base::Unretained(this));
mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
return status;
}
status_t InputSystem::handleFlush()
{
LOG1("@%s:", __FUNCTION__);
mPollerThread->flush(true);
return NO_ERROR;
}
status_t InputSystem::handleExit()
{
LOG1("@%s", __FUNCTION__);
// stop streaming before closing devices
if (mStarted) {
MessageStop msg;
msg.stop = false;
handleStop(msg);
}
mStarted = false;
return NO_ERROR;
}
status_t InputSystem::notifyPollEvent(PollEventMessage *pollMsg)
{
LOG2("@%s", __FUNCTION__);
if (pollMsg == nullptr || pollMsg->data.activeDevices == nullptr)
return BAD_VALUE;
// Common thread message fields for any case
MessagePollEvent msg;
msg.pollMsgId = pollMsg->id;
msg.requestId = pollMsg->data.reqId;
if (pollMsg->id == POLL_EVENT_ID_EVENT) {
int numDevices = pollMsg->data.activeDevices->size();
if (numDevices == 0) {
LOG1("@%s: devices flushed", __FUNCTION__);
return OK;
}
int numPolledDevices = pollMsg->data.polledDevices->size();
if (CC_UNLIKELY(numPolledDevices == 0)) {
LOGW("No devices Polled?");
return OK;
}
msg.activeDevices = new std::shared_ptr<cros::V4L2VideoNode>[numDevices];
for (int i = 0; i < numDevices; i++) {
msg.activeDevices[i] = (std::shared_ptr<cros::V4L2VideoNode>&) pollMsg->data.activeDevices->at(i);
}
msg.numDevices = numDevices;
msg.polledDevices = numPolledDevices;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handlePollEvent,
base::Unretained(this), base::Passed(std::move(msg)));
mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
if (pollMsg->data.activeDevices->size() != pollMsg->data.polledDevices->size()) {
LOG2("@%s: %zu inactive nodes for request %d, retry poll", __FUNCTION__,
pollMsg->data.inactiveDevices->size(),
pollMsg->data.reqId);
pollMsg->data.polledDevices->clear();
*pollMsg->data.polledDevices = *pollMsg->data.inactiveDevices; // retry with inactive devices
return -EAGAIN;
}
} else if (pollMsg->id == POLL_EVENT_ID_ERROR) {
LOGE("device poll failed");
// For now, set number of device to zero in error case
msg.numDevices = 0;
msg.polledDevices = 0;
base::Callback<status_t()> closure =
base::Bind(&InputSystem::handlePollEvent,
base::Unretained(this), base::Passed(std::move(msg)));
mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
}
return OK;
}
status_t InputSystem::getIsysNodeName(std::shared_ptr<cros::V4L2VideoNode> node, IPU3NodeNames &isysNodeName)
{
LOG2("@%s", __FUNCTION__);
for (const auto &configNode : mConfiguredNodesPerName) {
if (configNode.second.get() == node.get()) {
isysNodeName = configNode.first;
return NO_ERROR;
}
}
return BAD_VALUE;
}
status_t InputSystem::handlePollEvent(MessagePollEvent msg)
{
LOG2("@%s", __FUNCTION__);
status_t status = NO_ERROR;
cros::V4L2Buffer outBuf;
std::shared_ptr<cros::V4L2VideoNode> *activeNodes;
IPU3NodeNames isysNodeName = IMGU_NODE_NULL;
uint8_t nodeCount = mCaptureInProgress->numNodesForRequest;
int activeNodecount = 0;
int requestId = -999;
activeNodes = msg.activeDevices;
activeNodecount = msg.numDevices;
requestId = msg.requestId;
LOG2("@%s: received %d / %d buffers for request Id %d", __FUNCTION__,
activeNodecount,
nodeCount,
requestId);
if (msg.pollMsgId == POLL_EVENT_ID_ERROR) {
// Notify observer
IISysObserver::IsysMessage isysMsg;
isysMsg.id = IISysObserver::ISYS_MESSAGE_ID_ERROR;
isysMsg.data.error.status = status;
mObserver->notifyIsysEvent(isysMsg);
// Poll again if poll error times is less than the threshold.
if (mPollErrorTimes++ < POLL_REQUEST_TRY_TIMES) {
status = mPollerThread->pollRequest(mCaptureInProgress->requestId,
IPU3_EVENT_POLL_TIMEOUT,
(std::vector<std::shared_ptr<cros::V4L2Device>>*) &mCaptureInProgress->configuredNodesForRequest);
return status;
} else if (mErrCb) {
// return a error message if poll failed happens 5 times in succession
mErrCb->deviceError();
return UNKNOWN_ERROR;
}
}
mPollErrorTimes = 0;
for (int i = 0; i < activeNodecount; i++) {
status = getIsysNodeName(activeNodes[i], isysNodeName);
if (status != NO_ERROR) {
LOGE("Error getting ISYS node, err %d", status);
// Notify observer
IISysObserver::IsysMessage isysMsg;
isysMsg.id = IISysObserver::ISYS_MESSAGE_ID_ERROR;
isysMsg.data.error.status = status;
mObserver->notifyIsysEvent(isysMsg);
// Poll again
status = mPollerThread->pollRequest(mCaptureInProgress->requestId,
IPU3_EVENT_POLL_TIMEOUT,
(std::vector<std::shared_ptr<cros::V4L2Device>>*) &mCaptureInProgress->configuredNodesForRequest);
return status;
}
status = grabFrame(isysNodeName, &outBuf);
if (status != NO_ERROR) {
LOGE("Error getting data from ISYS node %d", isysNodeName);
// Notify observer
IISysObserver::IsysMessage isysMsg;
isysMsg.id = IISysObserver::ISYS_MESSAGE_ID_ERROR;
isysMsg.data.error.status = status;
mObserver->notifyIsysEvent(isysMsg);
// Poll again
status = mPollerThread->pollRequest(mCaptureInProgress->requestId,
IPU3_EVENT_POLL_TIMEOUT,
(std::vector<std::shared_ptr<cros::V4L2Device>>*) &mCaptureInProgress->configuredNodesForRequest);
return status;
}
// When receiving the first buffer for a request,
// store the sequence number. All buffers should
// have the same sequence number.
if (mBufferSeqNbr == 0) {
mBufferSeqNbr = outBuf.Sequence();
} else if (mBufferSeqNbr != outBuf.Sequence()) {
LOG2("@%s: sequence number mismatch, expecting %d but received %d",
__FUNCTION__, mBufferSeqNbr, outBuf.Sequence());
mBufferSeqNbr = outBuf.Sequence();
}
LOG2("input system outBuf.sequence %u", outBuf.Sequence());
mBuffersReceived++;
// Notify observer
IISysObserver::IsysMessage isysMsg;
isysMsg.id = IISysObserver::ISYS_MESSAGE_ID_EVENT;
isysMsg.data.event.requestId = requestId;
isysMsg.data.event.isysNodeName = isysNodeName;
isysMsg.data.event.buffer = &outBuf;
mObserver->notifyIsysEvent(isysMsg);
}
delete[] activeNodes;
if (mBuffersReceived == nodeCount) {
LOG2("@%s: all buffers received (%d/%d) for request Id %d",
__FUNCTION__, mBuffersReceived, nodeCount, requestId);
mBuffersReceived = 0;
mBufferSeqNbr++;
mRequestDone = true;
if (!mStarted)
return status;
// Start polling if there is a new request in the queue
if (mPendingIsysRequests.size() > 0 && mCaptureQueue.size() > 0) {
pollNextRequest();
mRequestDone = false;
}
}
return status;
}
status_t InputSystem::pollNextRequest()
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);
status_t status = NO_ERROR;
int reqId = mCaptureQueue[0];
mCaptureInProgress.reset();
/* first checking if existing mediaRequest created */
auto itRequest = mPendingIsysRequests.find(reqId);
if (itRequest == mPendingIsysRequests.end()) {
LOGE("No Request pending for reqId %d, BUG!", reqId);
return UNKNOWN_ERROR;
}
mCaptureInProgress = mPendingIsysRequests.at(reqId);
// clean queue of request.
mPendingIsysRequests.erase(reqId);
mCaptureQueue.erase(mCaptureQueue.begin());
status = mPollerThread->pollRequest(mCaptureInProgress->requestId,
IPU3_EVENT_POLL_TIMEOUT,
(std::vector<std::shared_ptr<cros::V4L2Device>>*) &mCaptureInProgress->configuredNodesForRequest);
return status;
}
}
}