/*
**
** 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;
}

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::dump(void)
{
}

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_request3AP = tap;
    m_request3AC = tac;
    m_requestISP = isp;
    m_requestSCC = scc;
    m_requestDIS = dis;
    m_requestSCP = 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_requestISPP = ispp;
    m_requestISPC = ispc;
}

void ExynosCameraFrame::setRequest(uint32_t pipeId, bool val)
{
    switch (pipeId) {
    case PIPE_3AC:
    case PIPE_3AC_FRONT:
    case PIPE_3AC_REPROCESSING:
        m_request3AC = val;
        break;
    case PIPE_3AP:
    case PIPE_3AP_FRONT:
    case PIPE_3AP_REPROCESSING:
        m_request3AP = val;
        break;
    case PIPE_ISP:
    case PIPE_ISP_FRONT:
        m_requestISP = val;
        break;
    case PIPE_ISPC:
    case PIPE_ISPC_FRONT:
    case PIPE_ISPC_REPROCESSING:
        m_requestISPC = val;
        break;
#if defined(SUPPORT_BACK_HW_VDIS) && defined(SUPPORT_FRONT_HW_VDIS)
    case PIPE_ISPP:
    case PIPE_ISPP_FRONT:
#endif
    case PIPE_ISPP_REPROCESSING:
        m_requestISPP = val;
        break;
#if defined(SUPPORT_BACK_HW_VDIS) && defined(SUPPORT_FRONT_HW_VDIS)
    case PIPE_DIS:
    case PIPE_DIS_FRONT:
        m_requestDIS = val;
        break;
#endif
    case PIPE_SCC:
    case PIPE_SCC_FRONT:
    case PIPE_SCC_REPROCESSING:
        m_requestSCC = val;
        break;
    case PIPE_SCP:
    case PIPE_SCP_FRONT:
    case PIPE_SCP_REPROCESSING:
        m_requestSCP = val;
        break;
    default:
        ALOGW("WRN(%s[%d]): unknown pipeId(%d)", __FUNCTION__, __LINE__, pipeId);
        break;
    }
}

bool ExynosCameraFrame::getRequest(uint32_t pipeId)
{
    bool request = false;

    switch (pipeId) {
    case PIPE_3AC:
    case PIPE_3AC_FRONT:
    case PIPE_3AC_REPROCESSING:
        request = m_request3AC;
        break;
    case PIPE_3AP:
    case PIPE_3AP_FRONT:
    case PIPE_3AP_REPROCESSING:
        request = m_request3AP;
        break;
    case PIPE_ISP:
    case PIPE_ISP_FRONT:
        request = m_requestISP;
        break;
    case PIPE_ISPC:
    case PIPE_ISPC_FRONT:
    case PIPE_ISPC_REPROCESSING:
        request = m_requestISPC;
        break;
#if defined(SUPPORT_BACK_HW_VDIS) && defined(SUPPORT_FRONT_HW_VDIS)
    case PIPE_ISPP:
    case PIPE_ISPP_FRONT:
#endif
    case PIPE_ISPP_REPROCESSING:
        request = m_requestISPP;
        break;
#if defined(SUPPORT_BACK_HW_VDIS) && defined(SUPPORT_FRONT_HW_VDIS)
    case PIPE_DIS:
    case PIPE_DIS_FRONT:
        request = m_requestDIS;
        break;
#endif
    case PIPE_SCC:
    case PIPE_SCC_FRONT:
    case PIPE_SCC_REPROCESSING:
        request = m_requestSCC;
        break;
    case PIPE_SCP:
    case PIPE_SCP_FRONT:
    case PIPE_SCP_REPROCESSING:
        request = m_requestSCP;
        break;
    default:
        ALOGW("WRN(%s[%d]): unknown pipeId(%d)", __FUNCTION__, __LINE__, pipeId);
        break;
    }
    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_request3AP = false;
    m_request3AC = false;
    m_requestISP = false;
    m_requestISPP = false;
    m_requestISPC = false;
    m_requestDIS = false;
    m_requestSCC = false;
    m_requestDIS = false;
    m_requestSCP = false;
    m_ispDoneFlag = false;
    m_3aaDropFlag = false;
    m_ispcDropFlag = false;
    m_disDropFlag = false;
    m_scpDropFlag = false;
    m_sccDropFlag = false;

    m_uniqueKey = 0;
    m_capture = 0;
    m_recording = false;
    m_preview = false;
    m_previewCb = false;
    m_serviceBayer = false;
    m_zsl = false;
    m_dummy = 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;
}

/*
 * 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;
}

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);

    /* HACK: Combine with old pipe */
    if (nodeIndex != DST_BUFFER_DEFAULT)
        this->m_dstBuf[DST_BUFFER_DEFAULT] = buf;

    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;

    /* HACK: Combine with old pipe */
    if (nodeIndex != DST_BUFFER_DEFAULT)
        m_dstBufState[DST_BUFFER_DEFAULT] = state;

    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;
}

}; /* namespace android */
