blob: 64614e778a5bd354536f44f314f38dab6397f0d8 [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 "ExynosCameraFrame"
#include <cutils/log.h>
#include "ExynosCameraFrame.h"
namespace android {
#ifdef DEBUG_FRAME_MEMORY_LEAK
unsigned long long ExynosCameraFrame::m_checkLeakCount;
Mutex ExynosCameraFrame::m_countLock;
#endif
ExynosCameraFrame::ExynosCameraFrame(
ExynosCameraParameters *obj_param,
uint32_t frameCount,
uint32_t frameType)
{
ALOGV("DEBUG(%s[%d]): create frame type(%d), frameCount(%d)", __FUNCTION__, __LINE__, frameType, frameCount);
m_parameters = obj_param;
m_frameCount = frameCount;
m_frameType = frameType;
m_init();
}
ExynosCameraFrame::ExynosCameraFrame()
{
m_parameters = NULL;
m_frameCount = 0;
m_frameType = FRAME_TYPE_OTHERS;
m_init();
}
ExynosCameraFrame::~ExynosCameraFrame()
{
m_deinit();
}
#ifdef DEBUG_FRAME_MEMORY_LEAK
long long int ExynosCameraFrame::getCheckLeakCount()
{
return m_privateCheckLeakCount;
}
#endif
status_t ExynosCameraFrame::addSiblingEntity(
__unused ExynosCameraFrameEntity *curEntity,
ExynosCameraFrameEntity *newEntity)
{
Mutex::Autolock l(m_linkageLock);
m_linkageList.push_back(newEntity);
return NO_ERROR;
}
status_t ExynosCameraFrame::addChildEntity(
ExynosCameraFrameEntity *parentEntity,
ExynosCameraFrameEntity *newEntity)
{
status_t ret = NO_ERROR;
if (parentEntity == NULL) {
ALOGE("ERR(%s):parentEntity is NULL", __FUNCTION__);
return BAD_VALUE;
}
/* TODO: This is not suit in case of newEntity->next != NULL */
ExynosCameraFrameEntity *tmpEntity;
tmpEntity = parentEntity->getNextEntity();
ret = parentEntity->setNextEntity(newEntity);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):setNextEntity fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
newEntity->setNextEntity(tmpEntity);
return ret;
}
status_t ExynosCameraFrame::addChildEntity(
ExynosCameraFrameEntity *parentEntity,
ExynosCameraFrameEntity *newEntity,
int parentPipeId)
{
status_t ret = NO_ERROR;
if (parentEntity == NULL) {
ALOGE("ERR(%s):parentEntity is NULL", __FUNCTION__);
return BAD_VALUE;
}
/* TODO: This is not suit in case of newEntity->next != NULL */
ExynosCameraFrameEntity *tmpEntity;
tmpEntity = parentEntity->getNextEntity();
ret = parentEntity->setNextEntity(newEntity);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):setNextEntity fail, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
if (0 <= parentPipeId) {
ret = newEntity->setParentPipeId((enum pipeline)parentPipeId);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):setParentPipeId(%d) fail, ret(%d)", __FUNCTION__, __LINE__, parentPipeId, ret);
return ret;
}
} else {
ALOGW("WARN(%s[%d]):parentPipeId(%d) < 0. you may set parentPipeId which connect between parent(%d) and child(%d)",
__FUNCTION__, __LINE__, parentPipeId, parentEntity->getPipeId(), newEntity->getPipeId());
}
newEntity->setNextEntity(tmpEntity);
return ret;
}
ExynosCameraFrameEntity *ExynosCameraFrame::getFirstEntity(void)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *firstEntity = NULL;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
firstEntity = NULL;
return firstEntity;
}
r = m_linkageList.begin()++;
m_currentEntity = r;
firstEntity = *r;
return firstEntity;
}
ExynosCameraFrameEntity *ExynosCameraFrame::getNextEntity(void)
{
ExynosCameraFrameEntity *nextEntity = NULL;
Mutex::Autolock l(m_linkageLock);
m_currentEntity++;
if (m_currentEntity == m_linkageList.end()) {
return nextEntity;
}
nextEntity = *m_currentEntity;
return nextEntity;
}
/* Unused, but useful */
/*
ExynosCameraFrameEntity *ExynosCameraFrame::getChildEntity(ExynosCameraFrameEntity *parentEntity)
{
ExynosCameraFrameEntity *childEntity = NULL;
if (parentEntity == NULL) {
ALOGE("ERR(%s):parentEntity is NULL", __FUNCTION__);
return childEntity;
}
childEntity = parentEntity->getNextEntity();
return childEntity;
}
*/
ExynosCameraFrameEntity *ExynosCameraFrame::searchEntityByPipeId(uint32_t pipeId)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
int listSize = 0;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return NULL;
}
listSize = m_linkageList.size();
r = m_linkageList.begin();
for (int i = 0; i < listSize; i++) {
curEntity = *r;
if (curEntity == NULL) {
ALOGE("ERR(%s):curEntity is NULL, index(%d), linkageList size(%d)",
__FUNCTION__, i, listSize);
return NULL;
}
while (curEntity != NULL) {
if (curEntity->getPipeId() == pipeId)
return curEntity;
curEntity = curEntity->getNextEntity();
}
r++;
}
ALOGD("DEBUG(%s):Cannot find matched entity, frameCount(%d), pipeId(%d)", __FUNCTION__, getFrameCount(), pipeId);
return NULL;
}
status_t ExynosCameraFrame::setSrcBuffer(uint32_t pipeId,
ExynosCameraBuffer srcBuf)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setSrcBuf(srcBuf);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set src buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::setDstBuffer(uint32_t pipeId,
ExynosCameraBuffer dstBuf,
uint32_t nodeIndex)
{
status_t ret = NO_ERROR;
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setDstBuf(dstBuf, nodeIndex);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
/* TODO: set buffer to child node's source */
entity = entity->getNextEntity();
if (entity != NULL) {
ret = entity->setSrcBuf(dstBuf);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
}
return ret;
}
status_t ExynosCameraFrame::setDstBuffer(uint32_t pipeId,
ExynosCameraBuffer dstBuf,
uint32_t nodeIndex,
int parentPipeId)
{
status_t ret = NO_ERROR;
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setDstBuf(dstBuf, nodeIndex);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
/* TODO: set buffer to child node's source */
entity = entity->getNextEntity();
if (entity != NULL) {
bool flagSetChildEntity = false;
/*
* it will set child's source buffer
* when no specific parent set. (for backward compatibility)
* when specific parent only. (for MCPipe)
*/
if (entity->flagSpecficParent() == true) {
if (parentPipeId == entity->getParentPipeId()) {
flagSetChildEntity = true;
} else {
ALOGV("DEBUG(%s[%d]):parentPipeId(%d) != entity->getParentPipeId()(%d). so skip setting child src Buf",
__FUNCTION__, __LINE__, parentPipeId, entity->getParentPipeId());
}
} else {
/* this is for backward compatiblity */
flagSetChildEntity = true;
}
/* child mode need to setting next */
if (flagSetChildEntity == true) {
ret = entity->setSrcBuf(dstBuf);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
}
}
return ret;
}
status_t ExynosCameraFrame::getSrcBuffer(uint32_t pipeId,
ExynosCameraBuffer *srcBuf)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->getSrcBuf(srcBuf);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not get src buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::getDstBuffer(uint32_t pipeId,
ExynosCameraBuffer *dstBuf,
uint32_t nodeIndex)
{
status_t ret = NO_ERROR;
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->getDstBuf(dstBuf, nodeIndex);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not get dst buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::setSrcRect(uint32_t pipeId, ExynosRect srcRect)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setSrcRect(srcRect);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set src rect, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::setDstRect(uint32_t pipeId, ExynosRect dstRect)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setDstRect(dstRect);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst rect, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
/* TODO: set buffer to child node's source */
entity = entity->getNextEntity();
if (entity != NULL) {
ret = entity->setSrcRect(dstRect);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst rect, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
}
return ret;
}
status_t ExynosCameraFrame::getSrcRect(uint32_t pipeId, ExynosRect *srcRect)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->getSrcRect(srcRect);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not get src rect, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::getDstRect(uint32_t pipeId, ExynosRect *dstRect)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->getDstRect(dstRect);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not get dst rect, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::getSrcBufferState(uint32_t pipeId,
entity_buffer_state_t *state)
{
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
*state = entity->getSrcBufState();
return NO_ERROR;
}
status_t ExynosCameraFrame::getDstBufferState(uint32_t pipeId,
entity_buffer_state_t *state,
uint32_t nodeIndex)
{
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
*state = entity->getDstBufState(nodeIndex);
return NO_ERROR;
}
status_t ExynosCameraFrame::setSrcBufferState(uint32_t pipeId,
entity_buffer_state_t state)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setSrcBufState(state);
return ret;
}
status_t ExynosCameraFrame::setDstBufferState(uint32_t pipeId,
entity_buffer_state_t state,
uint32_t nodeIndex)
{
status_t ret = NO_ERROR;
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setDstBufState(state, nodeIndex);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set dst buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
/* Set buffer to child node's source */
entity = entity->getNextEntity();
if (entity != NULL) {
ret = entity->setSrcBufState(state);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):Could not set src buffer, ret(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
}
return ret;
}
status_t ExynosCameraFrame::ensureSrcBufferState(uint32_t pipeId,
entity_buffer_state_t state)
{
status_t ret = NO_ERROR;
int retry = 0;
entity_buffer_state_t curState;
do {
ret = getSrcBufferState(pipeId, &curState);
if (ret != NO_ERROR)
continue;
if (state == curState) {
ret = OK;
break;
} else {
ret = BAD_VALUE;
usleep(100);
}
retry++;
if (retry == 10)
ret = TIMED_OUT;
} while (ret != OK && retry < 100);
ALOGV("DEBUG(%s[%d]): retry count %d", __FUNCTION__, __LINE__, retry);
return ret;
}
status_t ExynosCameraFrame::ensureDstBufferState(uint32_t pipeId,
entity_buffer_state_t state)
{
status_t ret = NO_ERROR;
int retry = 0;
entity_buffer_state_t curState;
do {
ret = getDstBufferState(pipeId, &curState);
if (ret != NO_ERROR)
continue;
if (state == curState) {
ret = OK;
break;
} else {
ret = BAD_VALUE;
usleep(100);
}
retry++;
if (retry == 10)
ret = TIMED_OUT;
} while (ret != OK && retry < 100);
ALOGV("DEBUG(%s[%d]): retry count %d", __FUNCTION__, __LINE__, retry);
return ret;
}
status_t ExynosCameraFrame::setEntityState(uint32_t pipeId,
entity_state_t state)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_entityLock);
#endif
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
if (entity->getEntityState() == ENTITY_STATE_COMPLETE &&
state != ENTITY_STATE_REWORK) {
return NO_ERROR;
}
if (state == ENTITY_STATE_COMPLETE) {
m_numCompletePipe++;
if (m_numCompletePipe >= m_numRequestPipe)
setFrameState(FRAME_STATE_COMPLETE);
}
entity->setEntityState(state);
return NO_ERROR;
}
status_t ExynosCameraFrame::getEntityState(uint32_t pipeId,
entity_state_t *state)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_entityLock);
#endif
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
*state = entity->getEntityState();
return NO_ERROR;
}
status_t ExynosCameraFrame::getEntityBufferType(uint32_t pipeId,
entity_buffer_type_t *type)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_entityLock);
#endif
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
*type = entity->getBufType();
return NO_ERROR;
}
uint32_t ExynosCameraFrame::getFrameCount(void)
{
return m_frameCount;
}
status_t ExynosCameraFrame::setNumRequestPipe(uint32_t num)
{
m_numRequestPipe = num;
return NO_ERROR;
}
uint32_t ExynosCameraFrame::getNumRequestPipe(void)
{
return m_numRequestPipe;
}
bool ExynosCameraFrame::isComplete(void)
{
return checkFrameState(FRAME_STATE_COMPLETE);
}
ExynosCameraFrameEntity *ExynosCameraFrame::getFrameDoneEntity(void)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return NULL;
}
r = m_linkageList.begin()++;
curEntity = *r;
while (r != m_linkageList.end()) {
if (curEntity != NULL) {
switch (curEntity->getEntityState()) {
case ENTITY_STATE_FRAME_SKIP:
case ENTITY_STATE_REWORK:
case ENTITY_STATE_FRAME_DONE:
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
return curEntity;
break;
default:
break;
}
}
r++;
curEntity = *r;
}
return NULL;
}
ExynosCameraFrameEntity *ExynosCameraFrame::getFrameDoneEntity(uint32_t pipeID)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return NULL;
}
r = m_linkageList.begin()++;
curEntity = *r;
while (r != m_linkageList.end()) {
if (curEntity != NULL && pipeID == curEntity->getPipeId()) {
switch (curEntity->getEntityState()) {
case ENTITY_STATE_FRAME_SKIP:
case ENTITY_STATE_REWORK:
case ENTITY_STATE_FRAME_DONE:
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
return curEntity;
break;
default:
break;
}
}
r++;
curEntity = *r;
}
return NULL;
}
ExynosCameraFrameEntity *ExynosCameraFrame::getFrameDoneFirstEntity(void)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return NULL;
}
r = m_linkageList.begin()++;
curEntity = *r;
while (r != m_linkageList.end()) {
if (curEntity != NULL) {
switch (curEntity->getEntityState()) {
case ENTITY_STATE_REWORK:
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
return curEntity;
break;
case ENTITY_STATE_FRAME_DONE:
return curEntity;
break;
case ENTITY_STATE_FRAME_SKIP:
case ENTITY_STATE_COMPLETE:
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
break;
default:
break;
}
}
r++;
curEntity = *r;
}
return NULL;
}
ExynosCameraFrameEntity *ExynosCameraFrame::getFrameDoneFirstEntity(uint32_t pipeID)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return NULL;
}
r = m_linkageList.begin()++;
curEntity = *r;
while (r != m_linkageList.end()) {
if (curEntity != NULL) {
switch (curEntity->getEntityState()) {
case ENTITY_STATE_REWORK:
if (curEntity->getPipeId() == pipeID)
return curEntity;
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
break;
case ENTITY_STATE_FRAME_DONE:
if (curEntity->getPipeId() == pipeID)
return curEntity;
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
break;
case ENTITY_STATE_FRAME_SKIP:
case ENTITY_STATE_COMPLETE:
if (curEntity->getNextEntity() != NULL) {
curEntity = curEntity->getNextEntity();
continue;
}
break;
default:
break;
}
}
r++;
curEntity = *r;
}
return NULL;
}
status_t ExynosCameraFrame::skipFrame(void)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameStateLock);
#endif
m_frameState = FRAME_STATE_SKIPPED;
return NO_ERROR;
}
void ExynosCameraFrame::setFrameState(frame_status_t state)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameStateLock);
#endif
/* TODO: We need state machine */
if (state > FRAME_STATE_INVALID)
m_frameState = FRAME_STATE_INVALID;
else
m_frameState = state;
}
frame_status_t ExynosCameraFrame::getFrameState(void)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameStateLock);
#endif
return m_frameState;
}
bool ExynosCameraFrame::checkFrameState(frame_status_t state)
{
#ifdef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameStateLock);
#endif
return (m_frameState == state) ? true : false;
}
void ExynosCameraFrame::printEntity(void)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
int listSize = 0;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return;
}
listSize = m_linkageList.size();
r = m_linkageList.begin();
ALOGD("DEBUG(%s): FrameCount(%d), request(%d), complete(%d)", __FUNCTION__, getFrameCount(), m_numRequestPipe, m_numCompletePipe);
for (int i = 0; i < listSize; i++) {
curEntity = *r;
if (curEntity == NULL) {
ALOGE("ERR(%s):curEntity is NULL, index(%d)", __FUNCTION__, i);
return;
}
ALOGD("DEBUG(%s):sibling id(%d), state(%d)",
__FUNCTION__, curEntity->getPipeId(), curEntity->getEntityState());
while (curEntity != NULL) {
ALOGD("DEBUG(%s):----- Child id(%d), state(%d)",
__FUNCTION__, curEntity->getPipeId(), curEntity->getEntityState());
curEntity = curEntity->getNextEntity();
}
r++;
}
return;
}
void ExynosCameraFrame::printNotDoneEntity(void)
{
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
int listSize = 0;
Mutex::Autolock l(m_linkageLock);
if (m_linkageList.empty()) {
ALOGE("ERR(%s):m_linkageList is empty", __FUNCTION__);
return;
}
listSize = m_linkageList.size();
r = m_linkageList.begin();
ALOGD("DEBUG(%s): FrameCount(%d), request(%d), complete(%d)",
__FUNCTION__, getFrameCount(), m_numRequestPipe, m_numCompletePipe);
for (int i = 0; i < listSize; i++) {
curEntity = *r;
if (curEntity == NULL) {
ALOGE("ERR(%s):curEntity is NULL, index(%d)", __FUNCTION__, i);
return;
}
if (curEntity->getEntityState() != ENTITY_STATE_COMPLETE) {
ALOGD("DEBUG(%s):sibling id(%d), state(%d)",
__FUNCTION__, curEntity->getPipeId(), curEntity->getEntityState());
}
while (curEntity != NULL) {
if (curEntity->getEntityState() != ENTITY_STATE_COMPLETE) {
ALOGD("DEBUG(%s):----- Child id(%d), state(%d)",
__FUNCTION__, curEntity->getPipeId(), curEntity->getEntityState());
}
curEntity = curEntity->getNextEntity();
}
r++;
}
return;
}
void ExynosCameraFrame::dump(void)
{
printEntity();
for (int i = 0; i < MAX_NUM_PIPES; i ++) {
if (m_request[INDEX(i)] == true)
ALOGI("INFO(%s[%d]):pipeId(%d)'s request is ture", __FUNCTION__, __LINE__, i);
}
}
void ExynosCameraFrame::frameLock(void)
{
#ifndef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameLock);
#endif
m_frameLocked = true;
}
void ExynosCameraFrame::frameUnlock(void)
{
#ifndef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameLock);
#endif
m_frameLocked = false;
}
bool ExynosCameraFrame::getFrameLockState(void)
{
#ifndef USE_FRAME_REFERENCE_COUNT
Mutex::Autolock lock(m_frameLock);
#endif
return m_frameLocked;
}
status_t ExynosCameraFrame::initMetaData(struct camera2_shot_ext *shot)
{
status_t ret = NO_ERROR;
if (shot != NULL) {
ALOGV("DEBUG(%s[%d]): initialize shot_ext", __FUNCTION__, __LINE__);
memcpy(&m_metaData, shot, sizeof(struct camera2_shot_ext));
}
ret = m_parameters->duplicateCtrlMetadata(&m_metaData);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):duplicate Ctrl metadata fail", __FUNCTION__, __LINE__);
return INVALID_OPERATION;
}
return ret;
}
status_t ExynosCameraFrame::getMetaData(struct camera2_shot_ext *shot)
{
if (shot == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(shot, &m_metaData, sizeof(struct camera2_shot_ext));
return NO_ERROR;
}
status_t ExynosCameraFrame::setMetaData(struct camera2_shot_ext *shot)
{
if (shot == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(&m_metaData, shot, sizeof(struct camera2_shot_ext));
return NO_ERROR;
}
status_t ExynosCameraFrame::storeDynamicMeta(struct camera2_shot_ext *shot)
{
if (shot == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (getMetaDmRequestFrameCount(shot) == 0)
ALOGW("WRN(%s[%d]): DM Frame count is ZERO", __FUNCTION__, __LINE__);
memcpy(&m_metaData.shot.dm, &shot->shot.dm, sizeof(struct camera2_dm));
return NO_ERROR;
}
status_t ExynosCameraFrame::storeDynamicMeta(struct camera2_dm *dm)
{
if (dm == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (getMetaDmRequestFrameCount(dm) == 0)
ALOGW("WRN(%s[%d]): DM Frame count is ZERO", __FUNCTION__, __LINE__);
memcpy(&m_metaData.shot.dm, dm, sizeof(struct camera2_dm));
return NO_ERROR;
}
status_t ExynosCameraFrame::storeUserDynamicMeta(struct camera2_shot_ext *shot)
{
if (shot == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(&m_metaData.shot.udm, &shot->shot.udm, sizeof(struct camera2_udm));
return NO_ERROR;
}
status_t ExynosCameraFrame::storeUserDynamicMeta(struct camera2_udm *udm)
{
if (udm == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(&m_metaData.shot.udm, udm, sizeof(struct camera2_udm));
return NO_ERROR;
}
status_t ExynosCameraFrame::getDynamicMeta(struct camera2_shot_ext *shot)
{
if (shot == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(&shot->shot.dm, &m_metaData.shot.dm, sizeof(struct camera2_dm));
return NO_ERROR;
}
status_t ExynosCameraFrame::getDynamicMeta(struct camera2_dm *dm)
{
if (dm == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(dm, &m_metaData.shot.dm, sizeof(struct camera2_dm));
return NO_ERROR;
}
status_t ExynosCameraFrame::getUserDynamicMeta(struct camera2_shot_ext *shot)
{
if (shot == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(&shot->shot.udm, &m_metaData.shot.udm, sizeof(struct camera2_udm));
return NO_ERROR;
}
status_t ExynosCameraFrame::getUserDynamicMeta(struct camera2_udm *udm)
{
if (udm == NULL) {
ALOGE("ERR(%s[%d]): buffer is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(udm, &m_metaData.shot.udm, sizeof(struct camera2_udm));
return NO_ERROR;
}
status_t ExynosCameraFrame::setMetaDataEnable(bool flag)
{
m_metaDataEnable = flag;
return NO_ERROR;
}
bool ExynosCameraFrame::getMetaDataEnable()
{
long count = 0;
while (count < DM_WAITING_COUNT) {
if (m_metaDataEnable == true) {
if (0 < count)
ALOGD("DEBUG(%s[%d]): metadata enable count(%ld) ", __FUNCTION__, __LINE__, count);
break;
}
count++;
usleep(WAITING_TIME);
}
return m_metaDataEnable;
}
status_t ExynosCameraFrame::getNodeGroupInfo(struct camera2_node_group *node_group, int index)
{
if (node_group == NULL) {
ALOGE("ERR(%s[%d]): node_group is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (index >= PERFRAME_NODE_GROUP_MAX) {
ALOGE("ERR(%s[%d]): index is bigger than PERFRAME_NODE_GROUP_MAX", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(node_group, &m_node_gorup[index], sizeof(struct camera2_node_group));
return NO_ERROR;
}
status_t ExynosCameraFrame::storeNodeGroupInfo(struct camera2_node_group *node_group, int index)
{
if (node_group == NULL) {
ALOGE("ERR(%s[%d]): node_group is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (index >= PERFRAME_NODE_GROUP_MAX) {
ALOGE("ERR(%s[%d]): index is bigger than PERFRAME_NODE_GROUP_MAX", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
memcpy(&m_node_gorup[index], node_group, sizeof(struct camera2_node_group));
return NO_ERROR;
}
status_t ExynosCameraFrame::getNodeGroupInfo(struct camera2_node_group *node_group, int index, int *zoom)
{
getNodeGroupInfo(node_group, index);
*zoom = m_zoom;
return NO_ERROR;
}
status_t ExynosCameraFrame::storeNodeGroupInfo(struct camera2_node_group *node_group, int index, int zoom)
{
storeNodeGroupInfo(node_group, index);
m_zoom = zoom;
return NO_ERROR;
}
void ExynosCameraFrame::dumpNodeGroupInfo(const char *name)
{
if (name != NULL)
ALOGD("INFO(%s[%d]):(%s)++++++++++++++++++++ frameCount(%d)", __FUNCTION__, __LINE__, name, m_frameCount);
else
ALOGD("INFO(%s[%d]):()++++++++++++++++++++ frameCount(%d)", __FUNCTION__, __LINE__, m_frameCount);
for (int i = 0; i < PERFRAME_NODE_GROUP_MAX; i ++) {
ALOGI("INFO(%s[%d]):Leader[%d] (%d, %d, %d, %d)(%d, %d, %d, %d)(%d %d)",
__FUNCTION__, __LINE__,
i,
m_node_gorup[i].leader.input.cropRegion[0],
m_node_gorup[i].leader.input.cropRegion[1],
m_node_gorup[i].leader.input.cropRegion[2],
m_node_gorup[i].leader.input.cropRegion[3],
m_node_gorup[i].leader.output.cropRegion[0],
m_node_gorup[i].leader.output.cropRegion[1],
m_node_gorup[i].leader.output.cropRegion[2],
m_node_gorup[i].leader.output.cropRegion[3],
m_node_gorup[i].leader.request,
m_node_gorup[i].leader.vid);
for (int j = 0; j < CAPTURE_NODE_MAX; j ++) {
ALOGI("INFO(%s[%d]):Capture[%d][%d] (%d, %d, %d, %d)(%d, %d, %d, %d)(%d, %d)",
__FUNCTION__, __LINE__,
i,
j,
m_node_gorup[i].capture[j].input.cropRegion[0],
m_node_gorup[i].capture[j].input.cropRegion[1],
m_node_gorup[i].capture[j].input.cropRegion[2],
m_node_gorup[i].capture[j].input.cropRegion[3],
m_node_gorup[i].capture[j].output.cropRegion[0],
m_node_gorup[i].capture[j].output.cropRegion[1],
m_node_gorup[i].capture[j].output.cropRegion[2],
m_node_gorup[i].capture[j].output.cropRegion[3],
m_node_gorup[i].capture[j].request,
m_node_gorup[i].capture[j].vid);
}
if (name != NULL)
ALOGD("INFO(%s[%d]):(%s)------------------------ ", __FUNCTION__, __LINE__, name);
else
ALOGD("INFO(%s[%d]):()------------------------ ", __FUNCTION__, __LINE__);
}
if (name != NULL)
ALOGD("INFO(%s[%d]):(%s)++++++++++++++++++++", __FUNCTION__, __LINE__, name);
else
ALOGD("INFO(%s[%d]):()++++++++++++++++++++", __FUNCTION__, __LINE__);
return;
}
void ExynosCameraFrame::setJpegSize(int size)
{
m_jpegSize = size;
}
int ExynosCameraFrame::getJpegSize(void)
{
return m_jpegSize;
}
int64_t ExynosCameraFrame::getTimeStamp(void)
{
return (int64_t)getMetaDmSensorTimeStamp(&m_metaData);
}
#ifdef SAMSUNG_TIMESTAMP_BOOT
int64_t ExynosCameraFrame::getTimeStampBoot(void)
{
return (int64_t)getMetaUdmSensorTimeStampBoot(&m_metaData);
}
#endif
void ExynosCameraFrame::getFpsRange(uint32_t *min, uint32_t *max)
{
getMetaCtlAeTargetFpsRange(&m_metaData, min, max);
}
void ExynosCameraFrame::setRequest(bool tap,
bool tac,
bool isp,
bool scc,
bool dis,
bool scp)
{
m_request[PIPE_3AP] = tap;
m_request[PIPE_3AC] = tac;
m_request[PIPE_ISP] = isp;
m_request[PIPE_SCC] = scc;
m_request[PIPE_DIS] = dis;
m_request[PIPE_SCP] = scp;
}
void ExynosCameraFrame::setRequest(bool tap,
bool tac,
bool isp,
bool ispp,
bool ispc,
bool scc,
bool dis,
bool scp)
{
setRequest(tap,
tac,
isp,
scc,
dis,
scp);
m_request[PIPE_ISPP] = ispp;
m_request[PIPE_ISPC] = ispc;
}
void ExynosCameraFrame::setRequest(uint32_t pipeId, bool val)
{
switch (pipeId) {
case PIPE_3AC_FRONT:
case PIPE_3AC_REPROCESSING:
pipeId = PIPE_3AC;
break;
case PIPE_3AP_FRONT:
case PIPE_3AP_REPROCESSING:
pipeId = PIPE_3AP;
break;
case PIPE_ISP_FRONT:
pipeId = PIPE_ISP;
break;
case PIPE_ISPC_FRONT:
case PIPE_ISPC_REPROCESSING:
pipeId = PIPE_ISPC;
break;
case PIPE_SCC_FRONT:
case PIPE_SCC_REPROCESSING:
pipeId = PIPE_SCC;
break;
case PIPE_SCP_FRONT:
case PIPE_SCP_REPROCESSING:
pipeId = PIPE_SCP;
break;
default:
break;
}
if ((pipeId % 100) >= MAX_NUM_PIPES)
ALOGW("WRN(%s[%d]):Invalid pipeId(%d)", __FUNCTION__, __LINE__, pipeId);
else
m_request[INDEX(pipeId)] = val;
}
bool ExynosCameraFrame::getRequest(uint32_t pipeId)
{
bool request = false;
switch (pipeId) {
case PIPE_3AC_FRONT:
case PIPE_3AC_REPROCESSING:
pipeId = PIPE_3AC;
break;
case PIPE_3AP_FRONT:
case PIPE_3AP_REPROCESSING:
pipeId = PIPE_3AP;
break;
case PIPE_ISP_FRONT:
pipeId = PIPE_ISP;
break;
case PIPE_ISPC_FRONT:
case PIPE_ISPC_REPROCESSING:
pipeId = PIPE_ISPC;
break;
case PIPE_SCC_FRONT:
case PIPE_SCC_REPROCESSING:
pipeId = PIPE_SCC;
break;
case PIPE_SCP_FRONT:
case PIPE_SCP_REPROCESSING:
pipeId = PIPE_SCP;
break;
default:
break;
}
if ((pipeId % 100) >= MAX_NUM_PIPES)
ALOGW("WRN(%s[%d]):Invalid pipeId(%d)", __FUNCTION__, __LINE__, pipeId);
else
request = m_request[INDEX(pipeId)];
return request;
}
bool ExynosCameraFrame::getIspDone(void)
{
return m_ispDoneFlag;
}
void ExynosCameraFrame::setIspDone(bool done)
{
m_ispDoneFlag = done;
}
bool ExynosCameraFrame::get3aaDrop()
{
return m_3aaDropFlag;
}
void ExynosCameraFrame::set3aaDrop(bool flag)
{
m_3aaDropFlag = flag;
}
void ExynosCameraFrame::setIspcDrop(bool flag)
{
m_ispcDropFlag = flag;
}
bool ExynosCameraFrame::getIspcDrop(void)
{
return m_ispcDropFlag;
}
void ExynosCameraFrame::setDisDrop(bool flag)
{
m_disDropFlag = flag;
}
bool ExynosCameraFrame::getDisDrop(void)
{
return m_disDropFlag;
}
bool ExynosCameraFrame::getScpDrop()
{
return m_scpDropFlag;
}
void ExynosCameraFrame::setScpDrop(bool flag)
{
m_scpDropFlag = flag;
}
bool ExynosCameraFrame::getSccDrop()
{
return m_sccDropFlag;
}
void ExynosCameraFrame::setSccDrop(bool flag)
{
m_sccDropFlag = flag;
}
uint32_t ExynosCameraFrame::getUniqueKey(void)
{
return m_uniqueKey;
}
status_t ExynosCameraFrame::setUniqueKey(uint32_t uniqueKey)
{
m_uniqueKey = uniqueKey;
return NO_ERROR;
}
#ifdef USE_FRAME_REFERENCE_COUNT
int32_t ExynosCameraFrame::incRef()
{
Mutex::Autolock lock(m_refCountLock);
m_refCount++;
return m_refCount;
}
int32_t ExynosCameraFrame::decRef()
{
Mutex::Autolock lock(m_refCountLock);
m_refCount--;
if (m_refCount < 0)
ALOGE("ERR(%s[%d]):reference count do not have negatve value, m_refCount(%d)", __FUNCTION__, __LINE__, m_refCount);
return m_refCount;
}
int32_t ExynosCameraFrame::getRef()
{
Mutex::Autolock lock(m_refCountLock);
return m_refCount;
}
#endif
status_t ExynosCameraFrame::setFrameInfo(ExynosCameraParameters *obj_param, uint32_t frameCount, uint32_t frameType)
{
status_t ret = NO_ERROR;
m_parameters = obj_param;
m_frameCount = frameCount;
m_frameType = frameType;
return ret;
}
uint32_t ExynosCameraFrame::getFrameType()
{
return m_frameType;
}
status_t ExynosCameraFrame::m_init()
{
m_numRequestPipe = 0;
m_numCompletePipe = 0;
m_frameState = FRAME_STATE_READY;
m_frameLocked = false;
m_metaDataEnable = false;
m_zoom = 0;
memset(&m_metaData, 0x0, sizeof(struct camera2_shot_ext));
m_jpegSize = 0;
m_ispDoneFlag = false;
m_3aaDropFlag = false;
m_ispcDropFlag = false;
m_disDropFlag = false;
m_scpDropFlag = false;
m_sccDropFlag = false;
for (int i = 0; i < MAX_NUM_PIPES; i++)
m_request[i] = false;
m_uniqueKey = 0;
m_capture = 0;
m_recording = false;
m_preview = false;
m_previewCb = false;
m_serviceBayer = false;
m_zsl = false;
#ifdef USE_FRAME_REFERENCE_COUNT
m_refCount = 1;
#endif
for (int i = 0; i < PERFRAME_NODE_GROUP_MAX; i++)
memset(&m_node_gorup[i], 0x0, sizeof(struct camera2_node_group));
ALOGV("DEBUG(%s[%d]): Generate frame type(%d), frameCount(%d)", __FUNCTION__, __LINE__, m_frameType, m_frameCount);
#ifdef DEBUG_FRAME_MEMORY_LEAK
m_privateCheckLeakCount = 0;
m_countLock.lock();
m_checkLeakCount ++;
m_privateCheckLeakCount = m_checkLeakCount;
ALOGE("CONSTRUCTOR (%lld)", m_privateCheckLeakCount);
m_countLock.unlock();
#endif
m_dupBufferInfo.streamID = 0;
m_dupBufferInfo.extScalerPipeID = 0;
return NO_ERROR;
}
status_t ExynosCameraFrame::m_deinit()
{
ALOGV("DEBUG(%s[%d]): Delete frame type(%d), frameCount(%d)", __FUNCTION__, __LINE__, m_frameType, m_frameCount);
#ifdef DEBUG_FRAME_MEMORY_LEAK
ALOGI("DESTRUCTOR (%lld)", m_privateCheckLeakCount);
#endif
List<ExynosCameraFrameEntity *>::iterator r;
ExynosCameraFrameEntity *curEntity = NULL;
ExynosCameraFrameEntity *tmpEntity = NULL;
Mutex::Autolock l(m_linkageLock);
while (!m_linkageList.empty()) {
r = m_linkageList.begin()++;
if (*r) {
curEntity = *r;
while (curEntity != NULL) {
tmpEntity = curEntity->getNextEntity();
ALOGV("DEBUG(%s[%d])", __FUNCTION__, curEntity->getPipeId());
delete curEntity;
curEntity = tmpEntity;
}
}
m_linkageList.erase(r);
}
return NO_ERROR;
}
status_t ExynosCameraFrame::setRotation(uint32_t pipeId, int rotation)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setRotation(rotation);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):pipeId(%d)->setRotation(%d) fail", __FUNCTION__, __LINE__, pipeId, rotation);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::getRotation(uint32_t pipeId)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
return entity->getRotation();
}
#ifdef PERFRAME_CONTROL_FOR_FLIP
status_t ExynosCameraFrame::setFlipHorizontal(uint32_t pipeId, int flipHorizontal)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setFlipHorizontal(flipHorizontal);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):pipeId(%d)->setRotation(%d) fail", __FUNCTION__, __LINE__, pipeId, flipHorizontal);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::getFlipHorizontal(uint32_t pipeId)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
return entity->getFlipHorizontal();
}
status_t ExynosCameraFrame::setFlipVertical(uint32_t pipeId, int flipVertical)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
ret = entity->setFlipVertical(flipVertical);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):pipeId(%d)->setRotation(%d) fail", __FUNCTION__, __LINE__, pipeId, flipVertical);
return ret;
}
return ret;
}
status_t ExynosCameraFrame::getFlipVertical(uint32_t pipeId)
{
status_t ret = NO_ERROR;
ExynosCameraFrameEntity *entity = searchEntityByPipeId(pipeId);
if (entity == NULL) {
ALOGE("ERR(%s[%d]):Could not find entity, pipeID(%d)", __FUNCTION__, __LINE__, pipeId);
return BAD_VALUE;
}
return entity->getFlipVertical();
}
#endif
/*
* ExynosCameraFrameEntity class
*/
ExynosCameraFrameEntity::ExynosCameraFrameEntity(
uint32_t pipeId,
entity_type_t type,
entity_buffer_type_t bufType)
{
m_pipeId = pipeId;
if (m_setEntityType(type) != NO_ERROR)
ALOGE("ERR(%s[%d]):setEntityType fail, pipeId(%d), type(%d)", __FUNCTION__, __LINE__, pipeId, type);
m_bufferType = bufType;
m_entityState = ENTITY_STATE_READY;
m_prevEntity = NULL;
m_nextEntity = NULL;
m_flagSpecificParent = false;
m_parentPipeId = -1;
m_rotation = 0;
#ifdef PERFRAME_CONTROL_FOR_FLIP
m_flipHorizontal = 0;
m_flipVertical = 0;
#endif
}
status_t ExynosCameraFrameEntity::m_setEntityType(entity_type_t type)
{
status_t ret = NO_ERROR;
m_EntityType = type;
switch (type) {
case ENTITY_TYPE_INPUT_ONLY:
m_srcBufState = ENTITY_BUFFER_STATE_REQUESTED;
m_dstBufState[DST_BUFFER_DEFAULT] = ENTITY_BUFFER_STATE_NOREQ;
break;
case ENTITY_TYPE_OUTPUT_ONLY:
m_srcBufState = ENTITY_BUFFER_STATE_NOREQ;
m_dstBufState[DST_BUFFER_DEFAULT] = ENTITY_BUFFER_STATE_REQUESTED;
break;
case ENTITY_TYPE_INPUT_OUTPUT:
m_srcBufState = ENTITY_BUFFER_STATE_REQUESTED;
m_dstBufState[DST_BUFFER_DEFAULT] = ENTITY_BUFFER_STATE_REQUESTED;
break;
default:
m_srcBufState = ENTITY_BUFFER_STATE_NOREQ;
m_dstBufState[DST_BUFFER_DEFAULT] = ENTITY_BUFFER_STATE_NOREQ;
m_EntityType = ENTITY_TYPE_INVALID;
ret = BAD_VALUE;
break;
}
return ret;
}
uint32_t ExynosCameraFrameEntity::getPipeId(void)
{
return m_pipeId;
}
status_t ExynosCameraFrameEntity::setSrcBuf(ExynosCameraBuffer buf)
{
status_t ret = NO_ERROR;
if (m_srcBufState == ENTITY_BUFFER_STATE_COMPLETE) {
ALOGV("WRN(%s[%d]):Buffer completed, state(%d)", __FUNCTION__, __LINE__, m_srcBufState);
return NO_ERROR;
}
if (m_bufferType != ENTITY_BUFFER_DELIVERY &&
m_srcBufState != ENTITY_BUFFER_STATE_REQUESTED) {
ALOGE("ERR(%s[%d]):Invalid buffer state(%d)", __FUNCTION__, __LINE__, m_srcBufState);
return INVALID_OPERATION;
}
this->m_srcBuf = buf;
ret = setSrcBufState(ENTITY_BUFFER_STATE_READY);
return ret;
}
status_t ExynosCameraFrameEntity::setDstBuf(ExynosCameraBuffer buf, uint32_t nodeIndex)
{
status_t ret = NO_ERROR;
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
if (m_bufferType != ENTITY_BUFFER_DELIVERY &&
m_dstBufState[nodeIndex] != ENTITY_BUFFER_STATE_REQUESTED) {
ALOGE("ERR(%s[%d]):Invalid buffer state(%d)", __FUNCTION__, __LINE__, m_dstBufState[nodeIndex]);
return INVALID_OPERATION;
}
this->m_dstBuf[nodeIndex] = buf;
ret = setDstBufState(ENTITY_BUFFER_STATE_READY, nodeIndex);
#ifndef SUPPORT_DEPTH_MAP
/* HACK: Combine with old pipe */
if (nodeIndex != DST_BUFFER_DEFAULT)
this->m_dstBuf[DST_BUFFER_DEFAULT] = buf;
#endif
return ret;
}
status_t ExynosCameraFrameEntity::getSrcBuf(ExynosCameraBuffer *buf)
{
*buf = this->m_srcBuf;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::getDstBuf(ExynosCameraBuffer *buf, uint32_t nodeIndex)
{
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
/* Comment out: It was collide with ExynosCamera's dirty dynamic bayer handling routine.
* (make error log, but no side effect)
* This code added for block human error.
* I will add this code after check the side effect closely.
*/
/*
if (this->m_dstBuf[nodeIndex].index == -1) {
ALOGE("ERR(%s[%d]):Invalid buffer index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
*/
*buf = this->m_dstBuf[nodeIndex];
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::setSrcRect(ExynosRect rect)
{
this->m_srcRect = rect;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::setDstRect(ExynosRect rect)
{
this->m_dstRect = rect;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::getSrcRect(ExynosRect *rect)
{
*rect = this->m_srcRect;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::getDstRect(ExynosRect *rect)
{
*rect = this->m_dstRect;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::setSrcBufState(entity_buffer_state_t state)
{
if (m_srcBufState == ENTITY_BUFFER_STATE_COMPLETE) {
ALOGV("WRN(%s[%d]):Buffer completed, state(%d)", __FUNCTION__, __LINE__, m_srcBufState);
return NO_ERROR;
}
m_srcBufState = state;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::setDstBufState(entity_buffer_state_t state, uint32_t nodeIndex)
{
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return BAD_VALUE;
}
m_dstBufState[nodeIndex] = state;
#ifndef SUPPORT_DEPTH_MAP
/* HACK: Combine with old pipe */
if (nodeIndex != DST_BUFFER_DEFAULT)
m_dstBufState[DST_BUFFER_DEFAULT] = state;
#endif
return NO_ERROR;
}
entity_buffer_state_t ExynosCameraFrameEntity::getSrcBufState(void)
{
return m_srcBufState;
}
entity_buffer_state_t ExynosCameraFrameEntity::getDstBufState(uint32_t nodeIndex)
{
if (nodeIndex >= DST_BUFFER_COUNT_MAX) {
ALOGE("ERR(%s[%d]):Invalid buffer index, index(%d)", __FUNCTION__, __LINE__, nodeIndex);
return ENTITY_BUFFER_STATE_INVALID;
}
return m_dstBufState[nodeIndex];
}
entity_buffer_type_t ExynosCameraFrameEntity::getBufType(void)
{
return m_bufferType;
}
status_t ExynosCameraFrameEntity::setEntityState(entity_state_t state)
{
this->m_entityState = state;
return NO_ERROR;
}
entity_state_t ExynosCameraFrameEntity::getEntityState(void)
{
return this->m_entityState;
}
ExynosCameraFrameEntity *ExynosCameraFrameEntity::getPrevEntity(void)
{
return this->m_prevEntity;
}
ExynosCameraFrameEntity *ExynosCameraFrameEntity::getNextEntity(void)
{
return this->m_nextEntity;
}
status_t ExynosCameraFrameEntity::setPrevEntity(ExynosCameraFrameEntity *entity)
{
this->m_prevEntity = entity;
return NO_ERROR;
}
status_t ExynosCameraFrameEntity::setNextEntity(ExynosCameraFrameEntity *entity)
{
this->m_nextEntity = entity;
return NO_ERROR;
}
bool ExynosCameraFrameEntity::flagSpecficParent(void)
{
return m_flagSpecificParent;
}
status_t ExynosCameraFrameEntity::setParentPipeId(enum pipeline parentPipeId)
{
if (0 <= m_parentPipeId) {
ALOGE("ERR(%s[%d]):m_parentPipeId(%d) is already set. parentPipeId(%d)",
__FUNCTION__, __LINE__, m_parentPipeId, parentPipeId);
return BAD_VALUE;
}
m_flagSpecificParent = true;
m_parentPipeId = parentPipeId;
return NO_ERROR;
}
int ExynosCameraFrameEntity::getParentPipeId(void)
{
return m_parentPipeId;
}
status_t ExynosCameraFrameEntity::setRotation(int rotation)
{
m_rotation = rotation;
return NO_ERROR;
}
int ExynosCameraFrameEntity::getRotation(void)
{
return m_rotation;
}
#ifdef PERFRAME_CONTROL_FOR_FLIP
status_t ExynosCameraFrameEntity::setFlipHorizontal(int flipHorizontal)
{
m_flipHorizontal = flipHorizontal;
return NO_ERROR;
}
int ExynosCameraFrameEntity::getFlipHorizontal(void)
{
return m_flipHorizontal;
}
status_t ExynosCameraFrameEntity::setFlipVertical(int flipVertical)
{
m_flipVertical = flipVertical;
return NO_ERROR;
}
int ExynosCameraFrameEntity::getFlipVertical(void)
{
return m_flipVertical;
}
#endif
}; /* namespace android */