/*
 * componentbase.cpp, component base class
 *
 * Copyright (c) 2009-2010 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>

#include <pthread.h>

#include <OMX_Core.h>
#include <OMX_Component.h>

#include <componentbase.h>

#include <queue.h>
#include <workqueue.h>
#include <OMX_IndexExt.h>
#include <HardwareAPI.h>

//#define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "componentbase"
#include <log.h>

static const OMX_U32 kMaxAdaptiveStreamingWidth = 1920;
static const OMX_U32 kMaxAdaptiveStreamingHeight = 1088;
/*
 * CmdProcessWork
 */
CmdProcessWork::CmdProcessWork(CmdHandlerInterface *ci)
{
    this->ci = ci;

    workq = new WorkQueue;

    __queue_init(&q);
    pthread_mutex_init(&lock, NULL);

    workq->StartWork(true);

    LOGV("command process workqueue started\n");
}

CmdProcessWork::~CmdProcessWork()
{
    struct cmd_s *temp;

    workq->StopWork();
    delete workq;

    while ((temp = PopCmdQueue()))
        free(temp);

    pthread_mutex_destroy(&lock);

    LOGV("command process workqueue stopped\n");
}

OMX_ERRORTYPE CmdProcessWork::PushCmdQueue(struct cmd_s *cmd)
{
    int ret;

    pthread_mutex_lock(&lock);
    ret = queue_push_tail(&q, cmd);
    if (ret) {
        pthread_mutex_unlock(&lock);
        return OMX_ErrorInsufficientResources;
    }

    workq->ScheduleWork(this);
    pthread_mutex_unlock(&lock);

    return OMX_ErrorNone;
}

struct cmd_s *CmdProcessWork::PopCmdQueue(void)
{
    struct cmd_s *cmd;

    pthread_mutex_lock(&lock);
    cmd = (struct cmd_s *)queue_pop_head(&q);
    pthread_mutex_unlock(&lock);

    return cmd;
}

void CmdProcessWork::Work(void)
{
    struct cmd_s *cmd;

    cmd = PopCmdQueue();
    if (cmd) {
        ci->CmdHandler(cmd);
        free(cmd);
    }
}

/* end of CmdProcessWork */

/*
 * ComponentBase
 */
/*
 * constructor & destructor
 */
void ComponentBase::__ComponentBase(void)
{
    memset(name, 0, OMX_MAX_STRINGNAME_SIZE);
    cmodule = NULL;
    handle = NULL;

    roles = NULL;
    nr_roles = 0;

    working_role = NULL;

    ports = NULL;
    nr_ports = 0;
    mEnableAdaptivePlayback = OMX_FALSE;
    memset(&portparam, 0, sizeof(portparam));

    state = OMX_StateUnloaded;

    cmdwork = NULL;

    bufferwork = NULL;

    pthread_mutex_init(&ports_block, NULL);
    pthread_mutex_init(&state_block, NULL);
}

ComponentBase::ComponentBase()
{
    __ComponentBase();
}

ComponentBase::ComponentBase(const OMX_STRING name)
{
    __ComponentBase();
    SetName(name);
}

ComponentBase::~ComponentBase()
{
    pthread_mutex_destroy(&ports_block);
    pthread_mutex_destroy(&state_block);

    if (roles) {
        if (roles[0])
            free(roles[0]);
        free(roles);
    }
}

/* end of constructor & destructor */

/*
 * accessor
 */
/* name */
void ComponentBase::SetName(const OMX_STRING name)
{
    strncpy(this->name, name, (strlen(name) < OMX_MAX_STRINGNAME_SIZE) ? strlen(name) : (OMX_MAX_STRINGNAME_SIZE-1));
   // strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE);
    this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0';
}

OMX_STRING ComponentBase::GetName(void)
{
    return name;
}

/* component module */
void ComponentBase::SetCModule(CModule *cmodule)
{
    this->cmodule = cmodule;
}

CModule *ComponentBase::GetCModule(void)
{
    return cmodule;
}

/* end of accessor */

/*
 * core methods & helpers
 */
/* roles */
OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles,
                                                 const OMX_U8 **roles)
{
    OMX_U32 i;

    if (!roles || !nr_roles)
        return OMX_ErrorBadParameter;

    if (this->roles) {
        free(this->roles[0]);
        free(this->roles);
        this->roles = NULL;
    }

    this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles);
    if (!this->roles)
        return OMX_ErrorInsufficientResources;

    this->roles[0] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE * nr_roles);
    if (!this->roles[0]) {
        free(this->roles);
        this->roles = NULL;
        return OMX_ErrorInsufficientResources;
    }

    for (i = 0; i < nr_roles; i++) {
        if (i < nr_roles-1)
            this->roles[i+1] = this->roles[i] + OMX_MAX_STRINGNAME_SIZE;

        strncpy((OMX_STRING)&this->roles[i][0],
                (const OMX_STRING)&roles[i][0], OMX_MAX_STRINGNAME_SIZE);
    }

    this->nr_roles = nr_roles;
    return OMX_ErrorNone;
}

/* GetHandle & FreeHandle */
OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle,
                                       OMX_PTR pAppData,
                                       OMX_CALLBACKTYPE *pCallBacks)
{
    OMX_U32 i;
    OMX_ERRORTYPE ret;

    if (!pHandle)
        return OMX_ErrorBadParameter;

    if (handle)
        return OMX_ErrorUndefined;

    cmdwork = new CmdProcessWork(this);
    if (!cmdwork)
        return OMX_ErrorInsufficientResources;

    bufferwork = new WorkQueue();
    if (!bufferwork) {
        ret = OMX_ErrorInsufficientResources;
        goto free_cmdwork;
    }

    handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle));
    if (!handle) {
        ret = OMX_ErrorInsufficientResources;
        goto free_bufferwork;
    }

    /* handle initialization */
    SetTypeHeader(handle, sizeof(*handle));
    handle->pComponentPrivate = static_cast<OMX_PTR>(this);
    handle->pApplicationPrivate = pAppData;

    /* connect handle's functions */
    handle->GetComponentVersion = NULL;
    handle->SendCommand = SendCommand;
    handle->GetParameter = GetParameter;
    handle->SetParameter = SetParameter;
    handle->GetConfig = GetConfig;
    handle->SetConfig = SetConfig;
    handle->GetExtensionIndex = GetExtensionIndex;
    handle->GetState = GetState;
    handle->ComponentTunnelRequest = NULL;
    handle->UseBuffer = UseBuffer;
    handle->AllocateBuffer = AllocateBuffer;
    handle->FreeBuffer = FreeBuffer;
    handle->EmptyThisBuffer = EmptyThisBuffer;
    handle->FillThisBuffer = FillThisBuffer;
    handle->SetCallbacks = SetCallbacks;
    handle->ComponentDeInit = NULL;
    handle->UseEGLImage = NULL;
    handle->ComponentRoleEnum = ComponentRoleEnum;

    appdata = pAppData;
    callbacks = pCallBacks;

    if (nr_roles == 1) {
        SetWorkingRole((OMX_STRING)&roles[0][0]);
        ret = ApplyWorkingRole();
        if (ret != OMX_ErrorNone) {
            SetWorkingRole(NULL);
            goto free_handle;
        }
    }

    *pHandle = (OMX_HANDLETYPE *)handle;
    state = OMX_StateLoaded;
    return OMX_ErrorNone;

free_handle:
    free(handle);

    appdata = NULL;
    callbacks = NULL;
    *pHandle = NULL;

free_bufferwork:
    delete bufferwork;

free_cmdwork:
    delete cmdwork;

    return ret;
}

OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent)
{
    OMX_ERRORTYPE ret;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    if (state != OMX_StateLoaded)
        return OMX_ErrorIncorrectStateOperation;

    FreePorts();

    free(handle);

    appdata = NULL;
    callbacks = NULL;

    delete cmdwork;
    delete bufferwork;

    state = OMX_StateUnloaded;
    return OMX_ErrorNone;
}

/* end of core methods & helpers */

/*
 * component methods & helpers
 */
OMX_ERRORTYPE ComponentBase::SendCommand(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_COMMANDTYPE Cmd,
    OMX_IN  OMX_U32 nParam1,
    OMX_IN  OMX_PTR pCmdData)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData);
}

OMX_ERRORTYPE ComponentBase::CBaseSendCommand(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_COMMANDTYPE Cmd,
    OMX_IN  OMX_U32 nParam1,
    OMX_IN  OMX_PTR pCmdData)
{
    struct cmd_s *cmd;

    if (hComponent != handle)
        return OMX_ErrorInvalidComponent;

    /* basic error check */
    switch (Cmd) {
    case OMX_CommandStateSet:
        /*
         * Todo
         */
        break;
    case OMX_CommandFlush: {
        OMX_U32 port_index = nParam1;

        if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
            return OMX_ErrorBadPortIndex;
        break;
    }
    case OMX_CommandPortDisable:
    case OMX_CommandPortEnable: {
        OMX_U32 port_index = nParam1;

        if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
            return OMX_ErrorBadPortIndex;
        break;
    }
    case OMX_CommandMarkBuffer: {
        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)pCmdData;
        OMX_MARKTYPE *copiedmark;
        OMX_U32 port_index = nParam1;

        if (port_index > nr_ports-1)
            return OMX_ErrorBadPortIndex;

        if (!mark || !mark->hMarkTargetComponent)
            return OMX_ErrorBadParameter;

        copiedmark = (OMX_MARKTYPE *)malloc(sizeof(*copiedmark));
        if (!copiedmark)
            return OMX_ErrorInsufficientResources;

        copiedmark->hMarkTargetComponent = mark->hMarkTargetComponent;
        copiedmark->pMarkData = mark->pMarkData;
        pCmdData = (OMX_PTR)copiedmark;
        break;
    }
    default:
        LOGE("command %d not supported\n", Cmd);
        return OMX_ErrorUnsupportedIndex;
    }

    cmd = (struct cmd_s *)malloc(sizeof(*cmd));
    if (!cmd)
        return OMX_ErrorInsufficientResources;

    cmd->cmd = Cmd;
    cmd->param1 = nParam1;
    cmd->cmddata = pCmdData;

    return cmdwork->PushCmdQueue(cmd);
}

OMX_ERRORTYPE ComponentBase::GetParameter(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nParamIndex,
    OMX_INOUT OMX_PTR pComponentParameterStructure)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseGetParameter(hComponent, nParamIndex,
                                    pComponentParameterStructure);
}

OMX_ERRORTYPE ComponentBase::CBaseGetParameter(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nParamIndex,
    OMX_INOUT OMX_PTR pComponentParameterStructure)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;
    switch (nParamIndex) {
    case OMX_IndexParamAudioInit:
    case OMX_IndexParamVideoInit:
    case OMX_IndexParamImageInit:
    case OMX_IndexParamOtherInit: {
        OMX_PORT_PARAM_TYPE *p =
            (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;

        ret = CheckTypeHeader(p, sizeof(*p));
        if (ret != OMX_ErrorNone)
            return ret;

        memcpy(p, &portparam, sizeof(*p));
        break;
    }
    case OMX_IndexParamPortDefinition: {
        OMX_PARAM_PORTDEFINITIONTYPE *p =
            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
        OMX_U32 index = p->nPortIndex;
        PortBase *port = NULL;

        ret = CheckTypeHeader(p, sizeof(*p));
        if (ret != OMX_ErrorNone)
            return ret;

        if (index < nr_ports)
            port = ports[index];

        if (!port)
            return OMX_ErrorBadPortIndex;

        memcpy(p, port->GetPortDefinition(), sizeof(*p));
        break;
    }
    case OMX_IndexParamCompBufferSupplier:
        /*
         * Todo
         */

        ret = OMX_ErrorUnsupportedIndex;
        break;

    default:
        ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure);
    } /* switch */

    return ret;
}

OMX_ERRORTYPE ComponentBase::SetParameter(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentParameterStructure)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseSetParameter(hComponent, nIndex,
                                    pComponentParameterStructure);
}

OMX_ERRORTYPE ComponentBase::CBaseSetParameter(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentParameterStructure)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    switch (nIndex) {
    case OMX_IndexParamAudioInit:
    case OMX_IndexParamVideoInit:
    case OMX_IndexParamImageInit:
    case OMX_IndexParamOtherInit:
        /* preventing clients from setting OMX_PORT_PARAM_TYPE */
        ret = OMX_ErrorUnsupportedIndex;
        break;
    case OMX_IndexParamPortDefinition: {
        OMX_PARAM_PORTDEFINITIONTYPE *p =
            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
        OMX_U32 index = p->nPortIndex;
        PortBase *port = NULL;

        ret = CheckTypeHeader(p, sizeof(*p));
        if (ret != OMX_ErrorNone)
            return ret;

        if (index < nr_ports)
            port = ports[index];

        if (!port)
            return OMX_ErrorBadPortIndex;

        if (port->IsEnabled()) {
            if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
                return OMX_ErrorIncorrectStateOperation;
        }

        if (index == 1 && mEnableAdaptivePlayback == OMX_TRUE) {
            if (p->format.video.nFrameWidth < mMaxFrameWidth)
                p->format.video.nFrameWidth = mMaxFrameWidth;
            if (p->format.video.nFrameHeight < mMaxFrameHeight)
                p->format.video.nFrameHeight = mMaxFrameHeight;
        }

        if (working_role != NULL && !strncmp((char*)working_role, "video_encoder", 13)) {
            if (p->format.video.nFrameWidth > 2048 || p->format.video.nFrameHeight > 2048)
                return OMX_ErrorUnsupportedSetting;

            if(p->format.video.eColorFormat == OMX_COLOR_FormatUnused)
                p->nBufferSize = p->format.video.nFrameWidth * p->format.video.nFrameHeight *3/2;
        }

        ret = port->SetPortDefinition(p, false);
        if (ret != OMX_ErrorNone) {
            return ret;
        }
        break;
    }
    case OMX_IndexParamCompBufferSupplier:
        /*
         * Todo
         */

        ret = OMX_ErrorUnsupportedIndex;
        break;
    case OMX_IndexParamStandardComponentRole: {
        OMX_PARAM_COMPONENTROLETYPE *p =
            (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;

        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
            return OMX_ErrorIncorrectStateOperation;

        ret = CheckTypeHeader(p, sizeof(*p));
        if (ret != OMX_ErrorNone)
            return ret;

        ret = SetWorkingRole((OMX_STRING)p->cRole);
        if (ret != OMX_ErrorNone)
            return ret;

        if (ports)
            FreePorts();

        ret = ApplyWorkingRole();
        if (ret != OMX_ErrorNone) {
            SetWorkingRole(NULL);
            return ret;
        }
        break;
    }
    default:
        if (nIndex == (OMX_INDEXTYPE)OMX_IndexExtPrepareForAdaptivePlayback) {
            android::PrepareForAdaptivePlaybackParams* p =
                    (android::PrepareForAdaptivePlaybackParams *)pComponentParameterStructure;

            ret = CheckTypeHeader(p, sizeof(*p));
            if (ret != OMX_ErrorNone)
                return ret;

            if (p->nPortIndex != 1)
                return OMX_ErrorBadPortIndex;

            if (!(working_role != NULL && !strncmp((char*)working_role, "video_decoder", 13)))
                return  OMX_ErrorBadParameter;

            if (p->nMaxFrameWidth > kMaxAdaptiveStreamingWidth
                    || p->nMaxFrameHeight > kMaxAdaptiveStreamingHeight) {
                LOGE("resolution %d x %d exceed max driver support %d x %d\n",p->nMaxFrameWidth, p->nMaxFrameHeight,
                        kMaxAdaptiveStreamingWidth, kMaxAdaptiveStreamingHeight);
                return OMX_ErrorBadParameter;
            }

            if (GetWorkingRole() != NULL &&
                        !strcmp (GetWorkingRole(),"video_decoder.vp9")) {
                if (p->nMaxFrameWidth < 640 && p->nMaxFrameHeight < 480) {
                    p->nMaxFrameHeight = kMaxAdaptiveStreamingHeight;
                    p->nMaxFrameWidth = kMaxAdaptiveStreamingWidth;
                }
            }

            mEnableAdaptivePlayback = p->bEnable;
            if (mEnableAdaptivePlayback != OMX_TRUE)
                return OMX_ErrorBadParameter;

            mMaxFrameWidth = p->nMaxFrameWidth;
            mMaxFrameHeight = p->nMaxFrameHeight;
            /* update output port definition */
            OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput;
            if (nr_ports > p->nPortIndex && ports[p->nPortIndex]) {
                memcpy(&paramPortDefinitionOutput,ports[p->nPortIndex]->GetPortDefinition(),
                        sizeof(paramPortDefinitionOutput));
                paramPortDefinitionOutput.format.video.nFrameWidth = mMaxFrameWidth;
                paramPortDefinitionOutput.format.video.nFrameHeight = mMaxFrameHeight;
                ports[p->nPortIndex]->SetPortDefinition(&paramPortDefinitionOutput, true);
            }
        } else {
            ret = ComponentSetParameter(nIndex, pComponentParameterStructure);
        }
        break;
    } /* switch */

    return ret;
}

OMX_ERRORTYPE ComponentBase::GetConfig(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_INOUT OMX_PTR pComponentConfigStructure)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseGetConfig(hComponent, nIndex,
                                 pComponentConfigStructure);
}

OMX_ERRORTYPE ComponentBase::CBaseGetConfig(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_INOUT OMX_PTR pComponentConfigStructure)
{
    OMX_ERRORTYPE ret;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    switch (nIndex) {
    default:
        ret = ComponentGetConfig(nIndex, pComponentConfigStructure);
    }

    return ret;
}

OMX_ERRORTYPE ComponentBase::SetConfig(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentConfigStructure)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseSetConfig(hComponent, nIndex,
                                 pComponentConfigStructure);
}

OMX_ERRORTYPE ComponentBase::CBaseSetConfig(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_INDEXTYPE nIndex,
    OMX_IN  OMX_PTR pComponentConfigStructure)
{
    OMX_ERRORTYPE ret;
 
    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    switch (nIndex) {
    default:
        ret = ComponentSetConfig(nIndex, pComponentConfigStructure);
    }

    return ret;
}

OMX_ERRORTYPE ComponentBase::GetExtensionIndex(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_STRING cParameterName,
    OMX_OUT OMX_INDEXTYPE* pIndexType)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseGetExtensionIndex(hComponent, cParameterName,
                                         pIndexType);
}

OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_STRING cParameterName,
    OMX_OUT OMX_INDEXTYPE* pIndexType)
{
    /*
     * Todo
     */
    if (hComponent != handle) {

        return OMX_ErrorBadParameter;
    }

    if (!strcmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexStoreMetaDataInBuffers);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.rotation")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.enableSyncEncoding")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSyncEncoding);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtPrependSPSPPS);
        return OMX_ErrorNone;
    }

#ifdef TARGET_HAS_VPP
    if (!strcmp(cParameterName, "OMX.Intel.index.vppBufferNum")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum);
        return OMX_ErrorNone;
    }
#endif
    
    if (!strcmp(cParameterName, "OMX.Intel.index.enableErrorReport")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtPrepareForAdaptivePlayback);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.requestBlackFramePointer")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtRequestBlackFramePointer);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.vp8MaxFrameRatio")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtVP8MaxFrameSizeRatio);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.temporalLayer")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtTemporalLayer);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.vuiEnable")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexParamIntelAVCVUI);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.sliceNumber")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexConfigIntelSliceNumbers);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.intelBitrateConfig")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexConfigIntelBitrate);
        return OMX_ErrorNone;
    }

    if (!strcmp(cParameterName, "OMX.Intel.index.autoIntraRefresh")) {
        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexConfigIntelAIR);
        return OMX_ErrorNone;
    }

    return OMX_ErrorUnsupportedIndex;
}

OMX_ERRORTYPE ComponentBase::GetState(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_OUT OMX_STATETYPE* pState)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseGetState(hComponent, pState);
}

OMX_ERRORTYPE ComponentBase::CBaseGetState(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_OUT OMX_STATETYPE* pState)
{
    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    pthread_mutex_lock(&state_block);
    *pState = state;
    pthread_mutex_unlock(&state_block);
    return OMX_ErrorNone;
}
OMX_ERRORTYPE ComponentBase::UseBuffer(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes,
    OMX_IN OMX_U8 *pBuffer)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex,
                                 pAppPrivate, nSizeBytes, pBuffer);
}

OMX_ERRORTYPE ComponentBase::CBaseUseBuffer(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes,
    OMX_IN OMX_U8 *pBuffer)
{
    PortBase *port = NULL;
    OMX_ERRORTYPE ret;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    if (!ppBufferHdr)
        return OMX_ErrorBadParameter;
    *ppBufferHdr = NULL;

    if (!pBuffer)
        return OMX_ErrorBadParameter;

    if (ports)
        if (nPortIndex < nr_ports)
            port = ports[nPortIndex];

    if (!port)
        return OMX_ErrorBadParameter;

    if (port->IsEnabled()) {
        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
            return OMX_ErrorIncorrectStateOperation;
    }

    return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes,
                           pBuffer);
}

OMX_ERRORTYPE ComponentBase::AllocateBuffer(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex,
                                      pAppPrivate, nSizeBytes);
}

OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
    OMX_IN OMX_U32 nPortIndex,
    OMX_IN OMX_PTR pAppPrivate,
    OMX_IN OMX_U32 nSizeBytes)
{
    PortBase *port = NULL;
    OMX_ERRORTYPE ret;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    if (!ppBuffer)
        return OMX_ErrorBadParameter;
    *ppBuffer = NULL;

    if (ports)
        if (nPortIndex < nr_ports)
            port = ports[nPortIndex];

    if (!port)
        return OMX_ErrorBadParameter;

    if (port->IsEnabled()) {
        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
            return OMX_ErrorIncorrectStateOperation;
    }

    return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
}

OMX_ERRORTYPE ComponentBase::FreeBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_U32 nPortIndex,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer);
}

OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_U32 nPortIndex,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    PortBase *port = NULL;
    OMX_ERRORTYPE ret;

    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    if (!pBuffer)
        return OMX_ErrorBadParameter;

    if (ports)
        if (nPortIndex < nr_ports)
            port = ports[nPortIndex];

    if (!port)
        return OMX_ErrorBadParameter;

    ProcessorPreFreeBuffer(nPortIndex, pBuffer);

    return port->FreeBuffer(nPortIndex, pBuffer);
}

OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
}

OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    PortBase *port = NULL;
    OMX_U32 port_index;
    OMX_ERRORTYPE ret;

    if ((hComponent != handle) || !pBuffer)
        return OMX_ErrorBadParameter;

    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
    if (ret != OMX_ErrorNone)
        return ret;

    port_index = pBuffer->nInputPortIndex;
    if (port_index == (OMX_U32)-1)
        return OMX_ErrorBadParameter;

    if (ports)
        if (port_index < nr_ports)
            port = ports[port_index];

    if (!port)
        return OMX_ErrorBadParameter;

    if (port->IsEnabled()) {
        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
            state != OMX_StatePause)
            return OMX_ErrorIncorrectStateOperation;
    }

    if (!pBuffer->hMarkTargetComponent) {
        OMX_MARKTYPE *mark;

        mark = port->PopMark();
        if (mark) {
            pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent;
            pBuffer->pMarkData = mark->pMarkData;
            free(mark);
        }
    }

    ProcessorPreEmptyBuffer(pBuffer);

    ret = port->PushThisBuffer(pBuffer);
    if (ret == OMX_ErrorNone)
        bufferwork->ScheduleWork(this);

    return ret;
}

OMX_ERRORTYPE ComponentBase::FillThisBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
}

OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
{
    PortBase *port = NULL;
    OMX_U32 port_index;
    OMX_ERRORTYPE ret;

    if ((hComponent != handle) || !pBuffer)
        return OMX_ErrorBadParameter;

    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
    if (ret != OMX_ErrorNone)
        return ret;

    port_index = pBuffer->nOutputPortIndex;
    if (port_index == (OMX_U32)-1)
        return OMX_ErrorBadParameter;

    if (ports)
        if (port_index < nr_ports)
            port = ports[port_index];

    if (!port)
        return OMX_ErrorBadParameter;

    if (port->IsEnabled()) {
        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
            state != OMX_StatePause)
            return OMX_ErrorIncorrectStateOperation;
    }

    ProcessorPreFillBuffer(pBuffer);

    ret = port->PushThisBuffer(pBuffer);
    if (ret == OMX_ErrorNone)
        bufferwork->ScheduleWork(this);

    return ret;
}

OMX_ERRORTYPE ComponentBase::SetCallbacks(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
    OMX_IN  OMX_PTR pAppData)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
}

OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
    OMX_IN  OMX_HANDLETYPE hComponent,
    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
    OMX_IN  OMX_PTR pAppData)
{
    if (hComponent != handle)
        return OMX_ErrorBadParameter;

    appdata = pAppData;
    callbacks = pCallbacks;

    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_OUT OMX_U8 *cRole,
    OMX_IN OMX_U32 nIndex)
{
    ComponentBase *cbase;

    if (!hComponent)
        return OMX_ErrorBadParameter;

    cbase = static_cast<ComponentBase *>
        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
    if (!cbase)
        return OMX_ErrorBadParameter;

    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
}

OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_OUT OMX_U8 *cRole,
    OMX_IN OMX_U32 nIndex)
{
    if (hComponent != (OMX_HANDLETYPE *)this->handle)
        return OMX_ErrorBadParameter;

    if (nIndex >= nr_roles)
        return OMX_ErrorBadParameter;

    strncpy((char *)cRole, (const char *)roles[nIndex],
            OMX_MAX_STRINGNAME_SIZE);
    return OMX_ErrorNone;
}

/* implement CmdHandlerInterface */
static const char *cmd_name[OMX_CommandMarkBuffer+2] = {
    "OMX_CommandStateSet",
    "OMX_CommandFlush",
    "OMX_CommandPortDisable",
    "OMX_CommandPortEnable",
    "OMX_CommandMarkBuffer",
    "Unknown Command",
};

static inline const char *GetCmdName(OMX_COMMANDTYPE cmd)
{
    if (cmd > OMX_CommandMarkBuffer)
        cmd = (OMX_COMMANDTYPE)(OMX_CommandMarkBuffer+1);

    return cmd_name[cmd];
}

void ComponentBase::CmdHandler(struct cmd_s *cmd)
{
    LOGV("%s:%s: handling %s command\n",
         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));

    switch (cmd->cmd) {
    case OMX_CommandStateSet: {
        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;

        pthread_mutex_lock(&state_block);
        TransState(transition);
        pthread_mutex_unlock(&state_block);
        break;
    }
    case OMX_CommandFlush: {
        OMX_U32 port_index = cmd->param1;
        pthread_mutex_lock(&ports_block);
        ProcessorFlush(port_index);
        FlushPort(port_index, 1);
        pthread_mutex_unlock(&ports_block);
        break;
    }
    case OMX_CommandPortDisable: {
        OMX_U32 port_index = cmd->param1;

        TransStatePort(port_index, PortBase::OMX_PortDisabled);
        break;
    }
    case OMX_CommandPortEnable: {
        OMX_U32 port_index = cmd->param1;

        TransStatePort(port_index, PortBase::OMX_PortEnabled);
        break;
    }
    case OMX_CommandMarkBuffer: {
        OMX_U32 port_index = (OMX_U32)cmd->param1;
        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata;

        PushThisMark(port_index, mark);
        break;
    }
    default:
        LOGE("%s:%s:%s: exit failure, command %d cannot be handled\n",
             GetName(), GetWorkingRole(), GetCmdName(cmd->cmd), cmd->cmd);
        break;
    } /* switch */

    LOGV("%s:%s: command %s handling done\n",
         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
}

/*
 * SendCommand:OMX_CommandStateSet
 * called in CmdHandler or called in other parts of component for reporting
 * internal error (OMX_StateInvalid).
 */
/*
 * Todo
 *   Resource Management (OMX_StateWaitForResources)
 *   for now, we never notify OMX_ErrorInsufficientResources,
 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
 */
static const char *state_name[OMX_StateWaitForResources+2] = {
    "OMX_StateInvalid",
    "OMX_StateLoaded",
    "OMX_StateIdle",
    "OMX_StateExecuting",
    "OMX_StatePause",
    "OMX_StateWaitForResources",
    "Unknown State",
};

static inline const char *GetStateName(OMX_STATETYPE state)
{
    if (state > OMX_StateWaitForResources)
        state = (OMX_STATETYPE)(OMX_StateWaitForResources+1);

    return state_name[state];
}

void ComponentBase::TransState(OMX_STATETYPE transition)
{
    OMX_STATETYPE current = this->state;
    OMX_EVENTTYPE event;
    OMX_U32 data1, data2;
    OMX_ERRORTYPE ret;

    LOGV("%s:%s: try to transit state from %s to %s\n",
         GetName(), GetWorkingRole(), GetStateName(current),
         GetStateName(transition));

    /* same state */
    if (current == transition) {
        ret = OMX_ErrorSameState;
        LOGE("%s:%s: exit failure, same state (%s)\n",
             GetName(), GetWorkingRole(), GetStateName(current));
        goto notify_event;
    }

    /* invalid state */
    if (current == OMX_StateInvalid) {
        ret = OMX_ErrorInvalidState;
        LOGE("%s:%s: exit failure, current state is OMX_StateInvalid\n",
             GetName(), GetWorkingRole());
        goto notify_event;
    }

    if (transition == OMX_StateLoaded)
        ret = TransStateToLoaded(current);
    else if (transition == OMX_StateIdle)
        ret = TransStateToIdle(current);
    else if (transition == OMX_StateExecuting)
        ret = TransStateToExecuting(current);
    else if (transition == OMX_StatePause)
        ret = TransStateToPause(current);
    else if (transition == OMX_StateInvalid)
        ret = TransStateToInvalid(current);
    else if (transition == OMX_StateWaitForResources)
        ret = TransStateToWaitForResources(current);
    else
        ret = OMX_ErrorIncorrectStateTransition;

notify_event:
    if (ret == OMX_ErrorNone) {
        event = OMX_EventCmdComplete;
        data1 = OMX_CommandStateSet;
        data2 = transition;

        state = transition;
        LOGD("%s:%s: transition from %s to %s completed",
             GetName(), GetWorkingRole(),
             GetStateName(current), GetStateName(transition));
    }
    else {
        event = OMX_EventError;
        data1 = ret;
        data2 = 0;

        if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) {
            state = OMX_StateInvalid;
            LOGE("%s:%s: exit failure, transition from %s to %s, "
                 "current state is %s\n",
                 GetName(), GetWorkingRole(), GetStateName(current),
                 GetStateName(transition), GetStateName(state));
        }
    }

    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);

    /* WaitForResources workaround */
    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
        callbacks->EventHandler(handle, appdata,
                                OMX_EventResourcesAcquired, 0, 0, NULL);
}

inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
{
    OMX_ERRORTYPE ret;

    if (current == OMX_StateIdle) {
        OMX_U32 i;

        for (i = 0; i < nr_ports; i++)
	{
            if (ports[i]->GetPortBufferCount() > 0) {
                ports[i]->WaitPortBufferCompletion();
	    };
	};

        ret = ProcessorDeinit();
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorDeinit() failed "
                 "(ret : 0x%08x)\n", GetName(), GetWorkingRole(),
                 ret);
            goto out;
        }
    }
    else if (current == OMX_StateWaitForResources) {
        LOGV("%s:%s: "
             "state transition's requested from WaitForResources to Loaded\n",
             GetName(), GetWorkingRole());

        /*
         * from WaitForResources to Loaded considered from Loaded to Loaded.
         * do nothing
         */

        ret = OMX_ErrorNone;
    }
    else
        ret = OMX_ErrorIncorrectStateTransition;

out:
    return ret;
}

inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    if (current == OMX_StateLoaded) {
        OMX_U32 i;
        for (i = 0; i < nr_ports; i++) {
            if (ports[i]->IsEnabled()) {
                if (GetWorkingRole() != NULL &&
                        !strncmp (GetWorkingRole(),"video_decoder", 13 )) {
                    ret = ports[i]->WaitPortBufferCompletionTimeout(800);
                } else {
                    ports[i]->WaitPortBufferCompletion();
                }
            }
        }

        if (ret == OMX_ErrorNone) {
            ret = ProcessorInit();
        }
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorInit() failed (ret : 0x%08x)\n",
                 GetName(), GetWorkingRole(), ret);
            goto out;
        }
    }
    else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) {
        pthread_mutex_lock(&ports_block);
        FlushPort(OMX_ALL, 0);
        pthread_mutex_unlock(&ports_block);
        LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole());

        bufferwork->CancelScheduledWork(this);
        LOGV("%s:%s: discarded all scheduled buffer process work\n",
             GetName(), GetWorkingRole());

        if (current == OMX_StatePause) {
            bufferwork->ResumeWork();
            LOGV("%s:%s: buffer process work resumed\n",
                 GetName(), GetWorkingRole());
        }

        bufferwork->StopWork();
        LOGV("%s:%s: buffer process work stopped\n",
             GetName(), GetWorkingRole());

        ret = ProcessorStop();
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorStop() failed (ret : 0x%08x)\n",
                 GetName(), GetWorkingRole(), ret);
            goto out;
        }
    }
    else if (current == OMX_StateWaitForResources) {
        LOGV("%s:%s: "
             "state transition's requested from WaitForResources to Idle\n",
             GetName(), GetWorkingRole());

        /* same as Loaded to Idle BUT DO NOTHING for now */

        ret = OMX_ErrorNone;
    }
    else
        ret = OMX_ErrorIncorrectStateTransition;

out:
    return ret;
}

inline OMX_ERRORTYPE
ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
{
    OMX_ERRORTYPE ret;

    if (current == OMX_StateIdle) {
        bufferwork->StartWork(true);
        LOGV("%s:%s: buffer process work started with executing state\n",
             GetName(), GetWorkingRole());

        ret = ProcessorStart();
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorStart() failed (ret : 0x%08x)\n",
                 GetName(), GetWorkingRole(), ret);
            goto out;
        }
    }
    else if (current == OMX_StatePause) {
        bufferwork->ResumeWork();
        LOGV("%s:%s: buffer process work resumed\n",
             GetName(), GetWorkingRole());

        ret = ProcessorResume();
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorResume() failed (ret : 0x%08x)\n",
                 GetName(), GetWorkingRole(), ret);
            goto out;
        }
    }
    else
        ret = OMX_ErrorIncorrectStateTransition;

out:
    return ret;
}

inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
{
    OMX_ERRORTYPE ret;

    if (current == OMX_StateIdle) {
        bufferwork->StartWork(false);
        LOGV("%s:%s: buffer process work started with paused state\n",
             GetName(), GetWorkingRole());

        ret = ProcessorStart();
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorSart() failed (ret : 0x%08x)\n",
                 GetName(), GetWorkingRole(), ret);
            goto out;
        }
    }
    else if (current == OMX_StateExecuting) {
        bufferwork->PauseWork();
        LOGV("%s:%s: buffer process work paused\n",
             GetName(), GetWorkingRole());

        ret = ProcessorPause();
        if (ret != OMX_ErrorNone) {
            LOGE("%s:%s: ProcessorPause() failed (ret : 0x%08x)\n",
                 GetName(), GetWorkingRole(), ret);
            goto out;
        }
    }
    else
        ret = OMX_ErrorIncorrectStateTransition;

out:
    return ret;
}

inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
{
    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
    LOGV("transit to invalid state from %d state",current);
    /*
     * Todo
     *   graceful escape
     */
    return ret;
}

inline OMX_ERRORTYPE
ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
{
    OMX_ERRORTYPE ret;

    if (current == OMX_StateLoaded) {
        LOGV("%s:%s: "
             "state transition's requested from Loaded to WaitForResources\n",
             GetName(), GetWorkingRole());
        ret = OMX_ErrorNone;
    }
    else
        ret = OMX_ErrorIncorrectStateTransition;

    return ret;
}

/* mark buffer */
void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark)
{
    PortBase *port = NULL;
    OMX_EVENTTYPE event;
    OMX_U32 data1, data2;
    OMX_ERRORTYPE ret;

    if (ports)
        if (port_index < nr_ports)
            port = ports[port_index];

    if (!port) {
        ret = OMX_ErrorBadPortIndex;
        goto notify_event;
    }

    ret = port->PushMark(mark);
    if (ret != OMX_ErrorNone) {
        /* don't report OMX_ErrorInsufficientResources */
        ret = OMX_ErrorUndefined;
        goto notify_event;
    }

notify_event:
    if (ret == OMX_ErrorNone) {
        event = OMX_EventCmdComplete;
        data1 = OMX_CommandMarkBuffer;
        data2 = port_index;
    }
    else {
        event = OMX_EventError;
        data1 = ret;
        data2 = 0;
    }

    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
}

void ComponentBase::FlushPort(OMX_U32 port_index, bool notify)
{
    OMX_U32 i, from_index, to_index;

    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
        return;

    if (port_index == OMX_ALL) {
        from_index = 0;
        to_index = nr_ports - 1;
    }
    else {
        from_index = port_index;
        to_index = port_index;
    }

    LOGV("%s:%s: flush ports (from index %u to %u)\n",
         GetName(), GetWorkingRole(), from_index, to_index);

    for (i = from_index; i <= to_index; i++) {
        ports[i]->FlushPort();
        if (notify)
            callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
                                    OMX_CommandFlush, i, NULL);
    }

    LOGV("%s:%s: flush ports done\n", GetName(), GetWorkingRole());
}

extern const char *GetPortStateName(OMX_U8 state); //portbase.cpp

void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state)
{
    OMX_EVENTTYPE event;
    OMX_U32 data1, data2;
    OMX_U32 i, from_index, to_index;
    OMX_ERRORTYPE ret;

    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
        return;

    if (port_index == OMX_ALL) {
        from_index = 0;
        to_index = nr_ports - 1;
    }
    else {
        from_index = port_index;
        to_index = port_index;
    }

    LOGV("%s:%s: transit ports state to %s (from index %u to %u)\n",
         GetName(), GetWorkingRole(), GetPortStateName(state),
         from_index, to_index);

    pthread_mutex_lock(&ports_block);
    for (i = from_index; i <= to_index; i++) {
        ret = ports[i]->TransState(state);
        if (ret == OMX_ErrorNone) {
            event = OMX_EventCmdComplete;
            if (state == PortBase::OMX_PortEnabled) {
                data1 = OMX_CommandPortEnable;
                ProcessorReset();
            } else {
                data1 = OMX_CommandPortDisable;
            }
            data2 = i;
        } else {
            event = OMX_EventError;
            data1 = ret;
            data2 = 0;
        }
        callbacks->EventHandler(handle, appdata, event,
                                data1, data2, NULL);
    }
    pthread_mutex_unlock(&ports_block);

    LOGV("%s:%s: transit ports state to %s completed\n",
         GetName(), GetWorkingRole(), GetPortStateName(state));
}

/* set working role */
OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role)
{
    OMX_U32 i;

    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
        return OMX_ErrorIncorrectStateOperation;

    if (!role) {
        working_role = NULL;
        return OMX_ErrorNone;
    }

    for (i = 0; i < nr_roles; i++) {
        if (!strcmp((char *)&roles[i][0], role)) {
            working_role = (OMX_STRING)&roles[i][0];
            return OMX_ErrorNone;
        }
    }

    LOGE("%s: cannot find %s role\n", GetName(), role);
    return OMX_ErrorBadParameter;
}

/* apply a working role for a component having multiple roles */
OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void)
{
    OMX_U32 i;
    OMX_ERRORTYPE ret;

    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
        return OMX_ErrorIncorrectStateOperation;

    if (!working_role)
        return OMX_ErrorBadParameter;

    if (!callbacks || !appdata)
        return OMX_ErrorBadParameter;

    ret = AllocatePorts();
    if (ret != OMX_ErrorNone) {
        LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret);
        return ret;
    }

    /* now we can access ports */
    for (i = 0; i < nr_ports; i++) {
        ports[i]->SetOwner(handle);
        ports[i]->SetCallbacks(handle, callbacks, appdata);
    }

    LOGI("%s: set working role %s:", GetName(), GetWorkingRole());
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::AllocatePorts(void)
{
    OMX_DIRTYPE dir;
    bool has_input, has_output;
    OMX_U32 i;
    OMX_ERRORTYPE ret;

    if (ports)
        return OMX_ErrorBadParameter;

    ret = ComponentAllocatePorts();
    if (ret != OMX_ErrorNone) {
        LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n",
             name, ret);
        return ret;
    }

    has_input = false;
    has_output = false;
    ret = OMX_ErrorNone;
    for (i = 0; i < nr_ports; i++) {
        dir = ports[i]->GetPortDirection();
        if (dir == OMX_DirInput)
            has_input = true;
        else if (dir == OMX_DirOutput)
            has_output = true;
        else {
            ret = OMX_ErrorUndefined;
            break;
        }
    }
    if (ret != OMX_ErrorNone)
        goto free_ports;

    if ((has_input == false) && (has_output == true))
        cvariant = CVARIANT_SOURCE;
    else if ((has_input == true) && (has_output == true))
        cvariant = CVARIANT_FILTER;
    else if ((has_input == true) && (has_output == false))
        cvariant = CVARIANT_SINK;
    else
        goto free_ports;

    return OMX_ErrorNone;

free_ports:
    LOGE("%s(): exit, unknown component variant\n", __func__);
    FreePorts();
    return OMX_ErrorUndefined;
}

/* called int FreeHandle() */
OMX_ERRORTYPE ComponentBase::FreePorts(void)
{
    if (ports) {
        OMX_U32 i, this_nr_ports = this->nr_ports;

        for (i = 0; i < this_nr_ports; i++) {
            if (ports[i]) {
                OMX_MARKTYPE *mark;
                /* it should be empty before this */
                while ((mark = ports[i]->PopMark()))
                    free(mark);

                delete ports[i];
                ports[i] = NULL;
            }
        }
        delete []ports;
        ports = NULL;
    }

    return OMX_ErrorNone;
}

/* buffer processing */
/* implement WorkableInterface */
void ComponentBase::Work(void)
{
    OMX_BUFFERHEADERTYPE **buffers[nr_ports];
    OMX_BUFFERHEADERTYPE *buffers_hdr[nr_ports];
    OMX_BUFFERHEADERTYPE *buffers_org[nr_ports];
    buffer_retain_t retain[nr_ports];
    OMX_U32 i;
    OMX_ERRORTYPE ret;

    if (nr_ports == 0) {
        return;
    }

    memset(buffers, 0, sizeof(OMX_BUFFERHEADERTYPE *) * nr_ports);
    memset(buffers_hdr, 0, sizeof(OMX_BUFFERHEADERTYPE *) * nr_ports);
    memset(buffers_org, 0, sizeof(OMX_BUFFERHEADERTYPE *) * nr_ports);

    pthread_mutex_lock(&ports_block);

    while(IsAllBufferAvailable())
    {
        for (i = 0; i < nr_ports; i++) {
            buffers_hdr[i] = ports[i]->PopBuffer();
            buffers[i] = &buffers_hdr[i];
            buffers_org[i] = buffers_hdr[i];
            retain[i] = BUFFER_RETAIN_NOT_RETAIN;
        }

        if (working_role != NULL && !strncmp((char*)working_role, "video_decoder", 13)){
            ret = ProcessorProcess(buffers, &retain[0], nr_ports);
        }else{
            ret = ProcessorProcess(buffers_hdr, &retain[0], nr_ports);
        }

        if (ret == OMX_ErrorNone) {
            if (!working_role || (strncmp((char*)working_role, "video_encoder", 13) != 0))
                PostProcessBuffers(buffers, &retain[0]);

            for (i = 0; i < nr_ports; i++) {
                if (buffers_hdr[i] == NULL)
                    continue;

                if(retain[i] == BUFFER_RETAIN_GETAGAIN) {
                    ports[i]->RetainThisBuffer(*buffers[i], false);
                }
                else if (retain[i] == BUFFER_RETAIN_ACCUMULATE) {
                    ports[i]->RetainThisBuffer(*buffers[i], true);
                }
                else if (retain[i] == BUFFER_RETAIN_OVERRIDDEN) {
                    ports[i]->RetainAndReturnBuffer(buffers_org[i], *buffers[i]);
                }
                else if (retain[i] == BUFFER_RETAIN_CACHE) {
                    //nothing to do
                } else {
                    ports[i]->ReturnThisBuffer(*buffers[i]);
                }
            }
        }
        else {

            for (i = 0; i < nr_ports; i++) {
                if (buffers_hdr[i] == NULL)
                    continue;

                /* return buffers by hands, these buffers're not in queue */
                ports[i]->ReturnThisBuffer(*buffers[i]);
                /* flush ports */
                ports[i]->FlushPort();
            }

            callbacks->EventHandler(handle, appdata, OMX_EventError, ret,
                                    0, NULL);
        }
    }

    pthread_mutex_unlock(&ports_block);
}

bool ComponentBase::IsAllBufferAvailable(void)
{
    OMX_U32 i;
    OMX_U32 nr_avail = 0;

    for (i = 0; i < nr_ports; i++) {
        OMX_U32 length = 0;

        if (ports[i]->IsEnabled()) {
            length += ports[i]->BufferQueueLength();
            length += ports[i]->RetainedBufferQueueLength();
        }

        if (length)
            nr_avail++;
    }

    if (nr_avail == nr_ports)
        return true;
    else
        return false;
}

inline void ComponentBase::SourcePostProcessBuffers(
    OMX_BUFFERHEADERTYPE ***buffers)
{
    OMX_U32 i;

    for (i = 0; i < nr_ports; i++) {
        /*
         * in case of source component, buffers're marked when they come
         * from the ouput ports
         */
        if (!(*buffers[i])->hMarkTargetComponent) {
            OMX_MARKTYPE *mark;

            mark = ports[i]->PopMark();
            if (mark) {
                (*buffers[i])->hMarkTargetComponent = mark->hMarkTargetComponent;
                (*buffers[i])->pMarkData = mark->pMarkData;
                free(mark);
            }
        }
    }
}

inline void ComponentBase::FilterPostProcessBuffers(
    OMX_BUFFERHEADERTYPE ***buffers,
    const buffer_retain_t *retain)
{
    OMX_MARKTYPE *mark;
    OMX_U32 i, j;

    for (i = 0; i < nr_ports; i++) {
        if (ports[i]->GetPortDirection() == OMX_DirInput) {
            for (j = 0; j < nr_ports; j++) {
                if (ports[j]->GetPortDirection() != OMX_DirOutput)
                    continue;

                /* propagates EOS flag */
                /* clear input EOS at the end of this loop */
                if (retain[i] != BUFFER_RETAIN_GETAGAIN) {
                    if ((*buffers[i])->nFlags & OMX_BUFFERFLAG_EOS)
                        (*buffers[j])->nFlags |= OMX_BUFFERFLAG_EOS;
                }

                /* propagates marks */
                /*
                 * if hMarkTargetComponent == handle then the mark's not
                 * propagated
                 */
                if ((*buffers[i])->hMarkTargetComponent &&
                    ((*buffers[i])->hMarkTargetComponent != handle)) {
                    if ((*buffers[j])->hMarkTargetComponent) {
                        mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
                        if (mark) {
                            mark->hMarkTargetComponent =
                                (*buffers[i])->hMarkTargetComponent;
                            mark->pMarkData = (*buffers[i])->pMarkData;
                            ports[j]->PushMark(mark);
                            mark = NULL;
                            (*buffers[i])->hMarkTargetComponent = NULL;
                            (*buffers[i])->pMarkData = NULL;
                        }
                    }
                    else {
                        mark = ports[j]->PopMark();
                        if (mark) {
                            (*buffers[j])->hMarkTargetComponent =
                                mark->hMarkTargetComponent;
                            (*buffers[j])->pMarkData = mark->pMarkData;
                            free(mark);

                            mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
                            if (mark) {
                                mark->hMarkTargetComponent =
                                    (*buffers[i])->hMarkTargetComponent;
                                mark->pMarkData = (*buffers[i])->pMarkData;
                                ports[j]->PushMark(mark);
                                mark = NULL;
                                (*buffers[i])->hMarkTargetComponent = NULL;
                                (*buffers[i])->pMarkData = NULL;
                            }
                        }
                        else {
                            (*buffers[j])->hMarkTargetComponent =
                                (*buffers[i])->hMarkTargetComponent;
                            (*buffers[j])->pMarkData = (*buffers[i])->pMarkData;
                            (*buffers[i])->hMarkTargetComponent = NULL;
                            (*buffers[i])->pMarkData = NULL;
                        }
                    }
                }
            }
            /* clear input buffer's EOS */
            if (retain[i] != BUFFER_RETAIN_GETAGAIN)
                (*buffers[i])->nFlags &= ~OMX_BUFFERFLAG_EOS;
        }
    }
}

inline void ComponentBase::SinkPostProcessBuffers()
{
    return;
}

void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
                                       const buffer_retain_t *retain)
{

    if (cvariant == CVARIANT_SOURCE)
        SourcePostProcessBuffers(buffers);
    else if (cvariant == CVARIANT_FILTER)
        FilterPostProcessBuffers(buffers, retain);
    else if (cvariant == CVARIANT_SINK) {
        SinkPostProcessBuffers();
    }
    else {
        LOGE("%s(): fatal error unknown component variant (%d)\n",
             __func__, cvariant);
    }
}

/* processor default callbacks */
OMX_ERRORTYPE ComponentBase::ProcessorInit(void)
{
    return OMX_ErrorNone;
}
OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void)
{
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ProcessorStart(void)
{
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ProcessorReset(void)
{
    return OMX_ErrorNone;
}


OMX_ERRORTYPE ComponentBase::ProcessorStop(void)
{
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ProcessorPause(void)
{
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ProcessorResume(void)
{
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ProcessorFlush(OMX_U32)
{
    return OMX_ErrorNone;
}
OMX_ERRORTYPE ComponentBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE*)
{
    return OMX_ErrorNone;
}

OMX_ERRORTYPE ComponentBase::ProcessorPreEmptyBuffer(OMX_BUFFERHEADERTYPE*)
{
    return OMX_ErrorNone;
}
OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE **,
                                           buffer_retain_t *,
                                           OMX_U32)
{
    LOGE("ProcessorProcess not be implemented");
    return OMX_ErrorNotImplemented;
}
OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE ***,
                                           buffer_retain_t *,
                                           OMX_U32)
{
    LOGE("ProcessorProcess not be implemented");
    return OMX_ErrorNotImplemented;
}

OMX_ERRORTYPE ComponentBase::ProcessorPreFreeBuffer(OMX_U32, OMX_BUFFERHEADERTYPE*)
{
    return OMX_ErrorNone;

}
/* end of processor callbacks */

/* helper for derived class */
OMX_STRING ComponentBase::GetWorkingRole(void)
{
    return &working_role[0];
}

const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void)
{
    return handle;
}
#if 0
void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader,
                               bool dumpdata)
{
    OMX_U8 *pbuffer = bufferheader->pBuffer, *p;
    OMX_U32 offset = bufferheader->nOffset;
    OMX_U32 alloc_len = bufferheader->nAllocLen;
    OMX_U32 filled_len =  bufferheader->nFilledLen;
    OMX_U32 left = filled_len, oneline;
    OMX_U32 index = 0, i;
    /* 0x%04lx:  %02x %02x .. (n = 16)\n\0 */
    char prbuffer[8 + 3 * 0x10 + 2], *pp;
    OMX_U32 prbuffer_len;

    LOGD("Component %s DumpBuffer\n", name);
    LOGD("%s port index = %lu",
         (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output",
         (bufferheader->nInputPortIndex != 0x7fffffff) ?
         bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex);
    LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n",
         alloc_len, offset, filled_len);
    LOGD("nTimeStamp = %lld, nTickCount = %lu",
         bufferheader->nTimeStamp,
         bufferheader->nTickCount);
    LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags);
    LOGD("hMarkTargetComponent = %p, pMarkData = %p\n",
         bufferheader->hMarkTargetComponent, bufferheader->pMarkData);

    if (!pbuffer || !alloc_len || !filled_len)
        return;

    if (offset + filled_len > alloc_len)
        return;

    if (!dumpdata)
        return;

    p = pbuffer + offset;
    while (left) {
        oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */
        pp += sprintf(pp, "0x%04lx: ", index);
        for (i = 0; i < oneline; i++)
            pp += sprintf(pp, " %02x", *(p + i));
        pp += sprintf(pp, "\n");
        *pp = '\0';

        index += 0x10;
        p += oneline;
        left -= oneline;

        pp = &prbuffer[0];
        LOGD("%s", pp);
    }
}
#endif
/* end of component methods & helpers */

/*
 * omx header manipuation
 */
void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
{
    OMX_U32 *nsize;
    OMX_VERSIONTYPE *nversion;

    if (!type)
        return;

    nsize = (OMX_U32 *)type;
    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));

    *nsize = size;
    nversion->nVersion = OMX_SPEC_VERSION;
}

OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size)
{
    OMX_U32 *nsize;
    OMX_VERSIONTYPE *nversion;

    if (!type)
        return OMX_ErrorBadParameter;

    nsize = (OMX_U32 *)type;
    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));

    if (*nsize != size)
        return OMX_ErrorBadParameter;

    if (nversion->nVersion != OMX_SPEC_VERSION)
        return OMX_ErrorVersionMismatch;

    return OMX_ErrorNone;
}

/* end of ComponentBase */
