blob: 7a1a93ae131716f969b2386c782db14ea19cd665 [file] [log] [blame]
/*
**
** Copyright 2013, Samsung Electronics Co. LTD
**
** 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_NDEBUG 0 */
#define LOG_TAG "ExynosCameraPipeISPC"
#include <cutils/log.h>
#include "ExynosCameraPipeISPC.h"
namespace android {
ExynosCameraPipeISPC::~ExynosCameraPipeISPC()
{
this->destroy();
}
status_t ExynosCameraPipeISPC::create(int32_t *sensorIds)
{
CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
int ret = 0;
for (int i = 0; i < MAX_NODE; i++) {
if (sensorIds) {
CLOGD("DEBUG(%s[%d]):set new sensorIds[%d] : %d", __FUNCTION__, __LINE__, i, sensorIds[i]);
m_sensorIds[i] = sensorIds[i];
} else {
m_sensorIds[i] = -1;
}
}
m_node[CAPTURE_NODE] = new ExynosCameraNode();
ret = m_node[CAPTURE_NODE]->create("ISPC", m_cameraId);
if (ret < 0) {
CLOGE("ERR(%s[%d]): CAPTURE_NODE create fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
ret = m_node[CAPTURE_NODE]->open(m_nodeNum[CAPTURE_NODE]);
if (ret < 0) {
CLOGE("ERR(%s[%d]): CAPTURE_NODE open fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
CLOGD("DEBUG(%s):Node(%d) opened", __FUNCTION__, m_nodeNum[CAPTURE_NODE]);
/* mainNode is CAPTURE_NODE */
m_mainNodeNum = CAPTURE_NODE;
m_mainNode = m_node[m_mainNodeNum];
/* setInput for 54xx */
ret = m_setInput(m_node, m_nodeNum, m_sensorIds);
if (ret < 0) {
CLOGE("ERR(%s[%d]): m_setInput fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
m_mainThread = ExynosCameraThreadFactory::createThread(this, &ExynosCameraPipeISPC::m_mainThreadFunc, "ISPCThread");
if (m_parameters->getUseDynamicScc()) {
m_inputFrameQ = new frame_queue_t(m_mainThread);
m_inputFrameQ->setWaitTime(200000000); /* .5 sec */
} else {
m_inputFrameQ = new frame_queue_t;
m_inputFrameQ->setWaitTime(500000000); /* .5 sec */
}
m_prepareBufferCount = m_exynosconfig->current->pipeInfo.prepare[getPipeId()];
CLOGI("INFO(%s[%d]):create() is succeed (%d) prepare (%d)", __FUNCTION__, __LINE__, getPipeId(), m_prepareBufferCount);
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::destroy(void)
{
CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
if (m_node[CAPTURE_NODE] != NULL) {
if (m_node[CAPTURE_NODE]->close() != NO_ERROR) {
CLOGE("ERR(%s):close fail", __FUNCTION__);
return INVALID_OPERATION;
}
delete m_node[CAPTURE_NODE];
m_node[CAPTURE_NODE] = NULL;
CLOGD("DEBUG(%s):Node(CAPTURE_NODE, m_nodeNum : %d, m_sensorIds : %d) closed",
__FUNCTION__, m_nodeNum[CAPTURE_NODE], m_sensorIds[CAPTURE_NODE]);
}
m_mainNode = NULL;
m_mainNodeNum = -1;
if (m_inputFrameQ != NULL) {
m_inputFrameQ->release();
delete m_inputFrameQ;
m_inputFrameQ = NULL;
}
CLOGI("INFO(%s[%d]):destroy() is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::clearInputFrameQ(void)
{
CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
if (m_inputFrameQ != NULL)
m_inputFrameQ->release();
//if (&m_requestFrameQ != NULL)
m_requestFrameQ.release();
CLOGI("INFO(%s[%d]):clearInputFrameQ() is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::setBoosting(bool isBoosting)
{
CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
m_isBoosting = isBoosting;
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::m_setPipeInfo(camera_pipe_info_t *pipeInfos)
{
CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
status_t ret = NO_ERROR;
if (pipeInfos == NULL) {
CLOGE("ERR(%s[%d]): pipeInfos == NULL. so, fail", __FUNCTION__, __LINE__);
return INVALID_OPERATION;
}
/* initialize node */
ret = m_setNodeInfo(m_node[CAPTURE_NODE], &pipeInfos[0],
2, YUV_FULL_RANGE,
true);
if (ret != NO_ERROR) {
CLOGE("ERR(%s[%d]): m_setNodeInfo(%d, %d, %d) fail",
__FUNCTION__, __LINE__, pipeInfos[0].rectInfo.fullW, pipeInfos[0].rectInfo.fullH, pipeInfos[0].bufInfo.count);
return INVALID_OPERATION;
}
m_numBuffers = pipeInfos[0].bufInfo.count;
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::setupPipe(camera_pipe_info_t *pipeInfos, int32_t *sensorIds)
{
CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
status_t ret = NO_ERROR;
/* TODO: check node state */
/* stream on? */
/* set new sensorId to m_sensorIds */
if (sensorIds) {
CLOGD("DEBUG(%s[%d]):set new sensorIds", __FUNCTION__, __LINE__);
for (int i = 0; i < MAX_NODE; i++)
m_sensorIds[i] = sensorIds[i];
}
ret = m_setInput(m_node, m_nodeNum, m_sensorIds);
if (ret < 0) {
CLOGE("ERR(%s[%d]): m_setInput fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
if (pipeInfos) {
ret = m_setPipeInfo(pipeInfos);
if (ret < 0) {
CLOGE("ERR(%s[%d]): m_setPipeInfo fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
}
for (uint32_t i = 0; i < m_numBuffers; i++) {
m_runningFrameList[i] = NULL;
}
m_numOfRunningFrame = 0;
m_requestFrameQ.release();
m_prepareBufferCount = m_exynosconfig->current->pipeInfo.prepare[getPipeId()];
CLOGI("INFO(%s[%d]):setupPipe() is succeed (%d) prepare (%d)", __FUNCTION__, __LINE__, getPipeId(), m_prepareBufferCount);
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::prepare(void)
{
CLOGV("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
return NO_ERROR;
}
bool ExynosCameraPipeISPC::m_checkThreadLoop(void)
{
Mutex::Autolock lock(m_pipeframeLock);
bool loop = false;
if (m_inputFrameQ->getSizeOfProcessQ() > 0)
loop = true;
if (m_inputFrameQ->getSizeOfProcessQ() == 0 &&
m_numOfRunningFrame == 0)
loop = false;
if (m_isReprocessing() == false)
loop = true;
#if 0
if (m_parameters->getUseDynamicScc() == false)
loop = true;
#endif
return loop;
}
bool ExynosCameraPipeISPC::m_mainThreadFunc(void)
{
int ret = 0;
if (m_flagStartPipe == false) {
/* waiting for pipe started */
usleep(5000);
return m_checkThreadLoop();
}
if (m_flagTryStop == true) {
usleep(5000);
return true;
}
ret = m_putBuffer();
if (ret < 0) {
if (ret != TIMED_OUT) {
CLOGE("ERR(%s):m_putBuffer fail", __FUNCTION__);
/* TODO: doing exception handling */
return m_checkThreadLoop();
} else if(m_isBoosting == true) {
CLOGW("WARN(%s):ISPC is boosting. m_putBuffer() again", __FUNCTION__);
/* On boosting, ISPC must wait the request frame before buffer DQ */
return m_checkThreadLoop();
}
}
ret = m_getBuffer();
if (ret < 0) {
CLOGE("ERR(%s):m_getBuffer fail", __FUNCTION__);
/* TODO: doing exception handling */
return m_checkThreadLoop();
}
return m_checkThreadLoop();
}
status_t ExynosCameraPipeISPC::m_putBuffer(void)
{
ExynosCameraFrame *newFrame = NULL;
ExynosCameraBuffer newBuffer;
int ret = 0;
entity_buffer_type_t entityBufType = ENTITY_BUFFER_INVALID;
camera2_node_group node_group_info_isp;
camera2_node_group node_group_info_dis;
ret = m_inputFrameQ->waitAndPopProcessQ(&newFrame);
if (ret < 0) {
/* TODO: We need to make timeout duration depends on FPS */
if (ret == TIMED_OUT) {
CLOGW("WARN(%s):wait timeout", __FUNCTION__);
m_node[CAPTURE_NODE]->dumpState();
} else {
CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret);
/* TODO: doing exception handling */
}
return ret;
}
if (newFrame == NULL) {
CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__);
return INVALID_OPERATION;
}
ret = newFrame->getDstBuffer(getPipeId(), &newBuffer);
if (ret < 0) {
CLOGE("ERR(%s[%d]):frame get buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: doing exception handling */
return OK;
}
ret = newFrame->getEntityBufferType(getPipeId(), &entityBufType);
if (ret < 0) {
CLOGE("ERR(%s[%d]):frame get buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return INVALID_OPERATION;
}
/* check buffer index */
if (newBuffer.index < 0) {
if (entityBufType != ENTITY_BUFFER_DELIVERY) {
CLOGE("ERR(%s[%d]): Entity buffer type is ENTITY_BUFFER_FIXED, but index (%d)", __FUNCTION__, __LINE__, newBuffer.index);
return BAD_VALUE;
}
CLOGV("DEBUG(%s[%d]): no buffer to QBUF", __FUNCTION__, __LINE__);
ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_REQUESTED);
if (ret < 0) {
CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
return ret;
}
/* When current frame has no buffer to queue and there is no buffer in ISPC,
the frame should not be requested to ISPC by ISP */
if (newFrame->getRequest(getPipeId()) == true && m_numOfRunningFrame < 2) {
CLOGD("DEBUG(%s[%d]): requestISPC for frame(%d) is canceled. ISPC Q num(%d)",
__FUNCTION__, __LINE__, newFrame->getFrameCount(), m_numOfRunningFrame);
newFrame->setRequest(getPipeId(), false);
/* isp */
newFrame->getNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP);
node_group_info_isp.capture[PERFRAME_BACK_SCC_POS].request = false;
newFrame->storeNodeGroupInfo(&node_group_info_isp, PERFRAME_INFO_ISP);
/* dis */
newFrame->getNodeGroupInfo(&node_group_info_dis, PERFRAME_INFO_DIS);
node_group_info_dis.capture[PERFRAME_BACK_SCC_POS].request = false;
newFrame->storeNodeGroupInfo(&node_group_info_dis, PERFRAME_INFO_DIS);
}
} else {
camera2_shot_ext *shot_ext = (struct camera2_shot_ext *)(newBuffer.addr[1]);
if (shot_ext != NULL) {
newFrame->getMetaData(shot_ext);
m_parameters->duplicateCtrlMetadata((void *)shot_ext);
m_activityControl->activityBeforeExecFunc(getPipeId(), (void *)&newBuffer);
if (m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perFrameNodeType == PERFRAME_NODE_TYPE_LEADER) {
camera2_node_group node_group_info;
memset(&shot_ext->node_group, 0x0, sizeof(camera2_node_group));
newFrame->getNodeGroupInfo(&node_group_info, m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perframeInfoIndex);
/* Per - Leader */
if (node_group_info.leader.request == 1) {
if (m_checkNodeGroupInfo(-1, &m_curNodeGroupInfo.leader, &node_group_info.leader) != NO_ERROR)
CLOGW("WARN(%s[%d]): m_checkNodeGroupInfo(leader) fail", __FUNCTION__, __LINE__);
setMetaNodeLeaderInputSize(shot_ext,
node_group_info.leader.input.cropRegion[0],
node_group_info.leader.input.cropRegion[1],
node_group_info.leader.input.cropRegion[2],
node_group_info.leader.input.cropRegion[3]);
setMetaNodeLeaderOutputSize(shot_ext,
node_group_info.leader.output.cropRegion[0],
node_group_info.leader.output.cropRegion[1],
node_group_info.leader.output.cropRegion[2],
node_group_info.leader.output.cropRegion[3]);
setMetaNodeLeaderRequest(shot_ext,
node_group_info.leader.request);
setMetaNodeLeaderVideoID(shot_ext,
m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perFrameVideoID);
}
/* Per - Captures */
for (int i = 0; i < m_perframeMainNodeGroupInfo.perframeSupportNodeNum - 1; i ++) {
if (node_group_info.capture[i].request == 1) {
if (m_checkNodeGroupInfo(i, &m_curNodeGroupInfo.capture[i], &node_group_info.capture[i]) != NO_ERROR)
CLOGW("WARN(%s[%d]): m_checkNodeGroupInfo(%d) fail", __FUNCTION__, __LINE__, i);
setMetaNodeCaptureInputSize(shot_ext, i,
node_group_info.capture[i].input.cropRegion[0],
node_group_info.capture[i].input.cropRegion[1],
node_group_info.capture[i].input.cropRegion[2],
node_group_info.capture[i].input.cropRegion[3]);
setMetaNodeCaptureOutputSize(shot_ext, i,
node_group_info.capture[i].output.cropRegion[0],
node_group_info.capture[i].output.cropRegion[1],
node_group_info.capture[i].output.cropRegion[2],
node_group_info.capture[i].output.cropRegion[3]);
setMetaNodeCaptureRequest(shot_ext, i, node_group_info.capture[i].request);
setMetaNodeCaptureVideoID(shot_ext, i, m_perframeMainNodeGroupInfo.perFrameCaptureInfo[i].perFrameVideoID);
}
}
}
}
m_nodeStateQAndDQ = m_nodeStateQAndDQ | (1 << newBuffer.index);
CLOGV("DEBUG(%s[%d]):index(%d) m_nodeStateQAndDQ(%d)", __FUNCTION__, __LINE__, newBuffer.index, m_nodeStateQAndDQ);
ret = m_node[CAPTURE_NODE]->putBuffer(&newBuffer);
if (ret < 0) {
CLOGE("ERR(%s):putBuffer fail", __FUNCTION__);
ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE);
if (ret < 0) {
CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_ERROR);
if (ret < 0) {
CLOGE("ERR(%s[%d]):set entity buffer state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
m_outputFrameQ->pushProcessQ(&newFrame);
return ret;
}
if (entityBufType == ENTITY_BUFFER_FIXED || m_reprocessing == true) {
ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_PROCESSING);
if (ret < 0) {
CLOGE("ERR(%s[%d]): setDstBuffer state fail", __FUNCTION__, __LINE__);
return ret;
}
} else {
newBuffer.index = -1;
ret = newFrame->setDstBuffer(getPipeId(), newBuffer);
if (ret < 0) {
CLOGE("ERR(%s[%d]): setDstBuffer state fail", __FUNCTION__, __LINE__);
return ret;
}
ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_REQUESTED);
if (ret < 0) {
CLOGE("ERR(%s[%d]): setDstBuffer state fail", __FUNCTION__, __LINE__);
return ret;
}
}
m_numOfRunningFrame++;
}
/* check request */
if (entityBufType == ENTITY_BUFFER_FIXED || newFrame->getRequest(getPipeId()) == true) {
m_requestFrameQ.pushProcessQ(&newFrame);
CLOGV("DEBUG(%s[%d]): push reqeust Frame (frame cnt:%d, request cnt: %d)", __FUNCTION__, __LINE__, newFrame->getFrameCount(), m_requestFrameQ.getSizeOfProcessQ());
} else {
ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE);
if (ret < 0) {
CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
/* TODO: doing exception handling */
return OK;
}
CLOGV("DEBUG(%s):entity pipeId(%d), frameCount(%d), numOfRunningFrame(%d), requestCount(%d)",
__FUNCTION__, getPipeId(), newFrame->getFrameCount(), m_numOfRunningFrame, m_requestFrameQ.getSizeOfProcessQ());
m_outputFrameQ->pushProcessQ(&newFrame);
}
if (m_numOfRunningFrame < 1 && getPipeId() < MAX_PIPE_NUM && m_parameters->getUseDynamicScc() == true) {
CLOGW("DEBUG(%s):entity pipeId(%d), frameCount(%d),requestISPC(%d), numOfRunningFrame(%d), requestCount(%d)",
__FUNCTION__, getPipeId(), newFrame->getFrameCount(), newFrame->getRequest(getPipeId()), m_numOfRunningFrame, m_requestFrameQ.getSizeOfProcessQ());
}
return NO_ERROR;
}
status_t ExynosCameraPipeISPC::m_getBuffer(void)
{
ExynosCameraFrame *curFrame = NULL;
ExynosCameraBuffer curBuffer;
int index = -1;
int ret = 0;
bool foundMatchedFrame = false;
entity_buffer_type_t entityBufType = ENTITY_BUFFER_INVALID;
struct camera2_stream *shot_stream = NULL;
CLOGV("DEBUG(%s[%d]: request frame size(%d), numOfRunningFrame(%d)", __FUNCTION__, __LINE__, m_requestFrameQ.getSizeOfProcessQ(), m_numOfRunningFrame);
if (m_requestFrameQ.getSizeOfProcessQ() == 0) {
CLOGV("DEBUG(%s[%d]): no request", __FUNCTION__, __LINE__);
return NO_ERROR;
}
if (m_numOfRunningFrame <= 0 || m_flagStartPipe == false) {
CLOGD("DEBUG(%s[%d]): skip getBuffer, flagStartPipe(%d), numOfRunningFrame = %d", __FUNCTION__, __LINE__, m_flagStartPipe, m_numOfRunningFrame);
return NO_ERROR;
}
ret = m_node[CAPTURE_NODE]->getBuffer(&curBuffer, &index);
if (ret < 0) {
CLOGE("ERR(%s[%d]):getBuffer fail", __FUNCTION__, __LINE__);
/* TODO: doing exception handling */
return ret;
}
m_nodeStateQAndDQ = m_nodeStateQAndDQ & ~(1 << curBuffer.index);
CLOGV("DEBUG(%s[%d]):index(%d) m_nodeStateQAndDQ(%d)", __FUNCTION__, __LINE__, curBuffer.index, m_nodeStateQAndDQ);
if (index < 0) {
CLOGE("ERR(%s[%d]):Invalid index(%d) fail", __FUNCTION__, __LINE__, index);
return INVALID_OPERATION;
}
m_activityControl->activityAfterExecFunc(getPipeId(), (void *)&curBuffer);
/* set runningFrameList for completeFrame */
do {
m_requestFrameQ.popProcessQ(&curFrame);
m_retry = false;
if (curFrame == NULL) {
CLOGE("ERR(%s[%d]): curFrame is NULL, size of requestFrameQ(%d)", __FUNCTION__, __LINE__, m_requestFrameQ.getSizeOfProcessQ());
if (m_requestFrameQ.getSizeOfProcessQ() == 0) {
m_putBuffer();
CLOGW("WARN(%s[%d]):m_putBuffer() again, size(%d)", __FUNCTION__, __LINE__, m_requestFrameQ.getSizeOfProcessQ());
m_retry = true;
}
continue;
}
ret = curFrame->getEntityBufferType(getPipeId(), &entityBufType);
if (ret < 0) {
CLOGE("ERR(%s[%d]):frame get buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
entityBufType = ENTITY_BUFFER_INVALID;
continue;
}
if (curFrame->getRequest(getPipeId()) == false) {
ret = curFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_SKIP);
if (ret < 0) {
CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
}
CLOGE("ERR(%s[%d]):frame drop pipeId(%d), frameCount(%d), numOfRunningFrame(%d), requestCount(%d)",
__FUNCTION__, __LINE__, getPipeId(), curFrame->getFrameCount(), m_numOfRunningFrame, m_requestFrameQ.getSizeOfProcessQ());
curFrame->setRequest(getPipeId(), true);
if (entityBufType == ENTITY_BUFFER_DELIVERY) {
m_outputFrameQ->pushProcessQ(&curFrame);
if (m_requestFrameQ.getSizeOfProcessQ() == 0) {
m_putBuffer();
CLOGW("WARN:m_putBuffer() again, size(%d)", m_requestFrameQ.getSizeOfProcessQ());
m_retry = true;
}
continue;
}
}
if (m_runningFrameList[curBuffer.index] != NULL) {
CLOGE("ERR(%s):new buffer is invalid, we already get buffer index(%d), curFrame->frameCount(%d)",
__FUNCTION__, index, curFrame->getFrameCount());
m_dumpRunningFrameList();
ret = BAD_VALUE;
goto lost_buffer;
}
m_runningFrameList[curBuffer.index] = curFrame;
/* If we found match frame, quit loop */
foundMatchedFrame = true;
break;
} while (m_retry == true || (0 < m_requestFrameQ.getSizeOfProcessQ() && entityBufType == ENTITY_BUFFER_DELIVERY));
if (foundMatchedFrame == false || m_runningFrameList[curBuffer.index] == NULL) {
CLOGE("ERR(%s):buffer is invalid, ",
__FUNCTION__);
m_dumpRunningFrameList();
ret = BAD_VALUE;
goto lost_buffer;
}
if (entityBufType == ENTITY_BUFFER_DELIVERY) {
/* set frame for dynamic capture */
ret = curFrame->setDstBuffer(getPipeId(), curBuffer);
if (ret < 0) {
CLOGE("ERR(%s): setDstBuffer fail", __FUNCTION__);
goto lost_buffer;
}
}
ret = curFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_COMPLETE);
if (ret < 0) {
CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
goto lost_buffer;
}
/* complete frame */
ret = m_completeFrame(&curFrame, curBuffer);
if (ret < 0) {
CLOGE("ERR(%s):m_comleteFrame fail", __FUNCTION__);
/* TODO: doing exception handling */
}
if (curFrame == NULL) {
CLOGE("ERR(%s):curFrame is fail", __FUNCTION__);
ret = BAD_VALUE;
goto lost_buffer;
}
entity_buffer_state_t tempState;
curFrame->getDstBufferState(getPipeId(), &tempState);
if (getPipeId() < MAX_PIPE_NUM && m_parameters->getUseDynamicScc() == true) {
CLOGD("DEBUG(%s[%d]): ISPC pipe output done, curFrameCount(%d) - index(%d), bufState(%d)",
__FUNCTION__, __LINE__, curFrame->getFrameCount(), curBuffer.index, tempState);
}
m_outputFrameQ->pushProcessQ(&curFrame);
return NO_ERROR;
lost_buffer:
CLOGE("ERR{%s[%d]): FATAL : buffer(%d) will be lost!!!!", __FUNCTION__, __LINE__, curBuffer.index);
return ret;
}
void ExynosCameraPipeISPC::m_init(void)
{
m_metadataTypeShot = false;
m_dqFailCount = false;
m_retry = false;
m_nodeStateQAndDQ = 0;
}
}; /* namespace android */