OMX_ERRORTYPE SEC_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    SEC_OMX_BASEPORT      *pSECPort = NULL;
    OMX_U32                i = 0, elemNum = 0;
    SEC_OMX_MESSAGE       *message;

    FunctionIn();

    pSECPort = &pSECComponent->pSECPort[portIndex];

    if (!CHECK_PORT_ENABLED(pSECPort)) {
        ret = OMX_ErrorNone;
        goto EXIT;
    }

    if (pSECComponent->currentState!=OMX_StateLoaded) {
        if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
            while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) {
                message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ);
                SEC_OSAL_Free(message);
            }
            ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, portIndex);
            if (OMX_ErrorNone != ret) {
                goto EXIT;
            }
            pSECPort->portDefinition.bPopulated = OMX_FALSE;
        } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
            pSECPort->portDefinition.bPopulated = OMX_FALSE;
            SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource);
        } else {
            if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) {
                    message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ);
                    SEC_OSAL_Free(message);
                }
            }
            pSECPort->portDefinition.bPopulated = OMX_FALSE;
            SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource);
        }
    }
    pSECPort->portDefinition.bEnabled = OMX_FALSE;
    ret = OMX_ErrorNone;

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    SEC_OMX_BASEPORT      *pSECPort = NULL;
    OMX_U32                i = 0, cnt = 0;

    FunctionIn();

    pSECPort = &pSECComponent->pSECPort[portIndex];
    pSECPort->portDefinition.bEnabled = OMX_TRUE;

    if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
        ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, portIndex);
        if (OMX_ErrorNone != ret) {
            goto EXIT;
        }
        pSECPort->portDefinition.bPopulated = OMX_TRUE;
        if (pSECComponent->currentState == OMX_StateExecuting) {
            for (i=0; i<pSECPort->tunnelBufferNum; i++) {
                SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID);
            }
        }
    } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
        if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) {
            SEC_OSAL_SemaphoreWait(pSECPort->loadedResource);
            pSECPort->portDefinition.bPopulated = OMX_TRUE;
        }
    } else {
        if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) {
            SEC_OSAL_SemaphoreWait(pSECPort->loadedResource);
            pSECPort->portDefinition.bPopulated = OMX_TRUE;
        }
    }
    ret = OMX_ErrorNone;

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OMX_SetParameter(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_IN OMX_INDEXTYPE  nIndex,
    OMX_IN OMX_PTR        ComponentParameterStructure)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    SEC_OMX_BASECOMPONENT *pSECComponent = NULL;

    FunctionIn();

    if (hComponent == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if (pOMXComponent->pComponentPrivate == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;

    if (ComponentParameterStructure == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    if (pSECComponent->currentState == OMX_StateInvalid) {
        ret = OMX_ErrorInvalidState;
        goto EXIT;
    }

    switch (nIndex) {
    case OMX_IndexParamAudioInit:
    case OMX_IndexParamVideoInit:
    case OMX_IndexParamImageInit:
    case OMX_IndexParamOtherInit:
    {
        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
        ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }

        if ((pSECComponent->currentState != OMX_StateLoaded) &&
            (pSECComponent->currentState != OMX_StateWaitForResources)) {
            ret = OMX_ErrorIncorrectStateOperation;
            goto EXIT;
        }
        ret = OMX_ErrorUndefined;
        /* SEC_OSAL_Memcpy(&pSECComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */
    }
        break;
    case OMX_IndexParamPortDefinition:
    {
        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
        OMX_U32               portIndex = portDefinition->nPortIndex;
        SEC_OMX_BASEPORT         *pSECPort;

        if (portIndex >= pSECComponent->portParam.nPorts) {
            ret = OMX_ErrorBadPortIndex;
            goto EXIT;
        }
        ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }

        pSECPort = &pSECComponent->pSECPort[portIndex];

        if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) {
            if (pSECPort->portDefinition.bEnabled == OMX_TRUE) {
                ret = OMX_ErrorIncorrectStateOperation;
                goto EXIT;
            }
        }
        if (portDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) {
            ret = OMX_ErrorBadParameter;
            goto EXIT;
        }

        SEC_OSAL_Memcpy(&pSECPort->portDefinition, portDefinition, portDefinition->nSize);
    }
        break;
    case OMX_IndexParamPriorityMgmt:
    {
        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;

        if ((pSECComponent->currentState != OMX_StateLoaded) &&
            (pSECComponent->currentState != OMX_StateWaitForResources)) {
            ret = OMX_ErrorIncorrectStateOperation;
            goto EXIT;
        }

        ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }

        pSECComponent->compPriority.nGroupID = compPriority->nGroupID;
        pSECComponent->compPriority.nGroupPriority = compPriority->nGroupPriority;
    }
        break;
    case OMX_IndexParamCompBufferSupplier:
    {
        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
        OMX_U32               portIndex = bufferSupplier->nPortIndex;
        SEC_OMX_BASEPORT         *pSECPort;

        if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) {
            if (pSECPort->portDefinition.bEnabled == OMX_TRUE) {
                ret = OMX_ErrorIncorrectStateOperation;
                goto EXIT;
            }
        }

        if (portIndex >= pSECComponent->portParam.nPorts) {
            ret = OMX_ErrorBadPortIndex;
            goto EXIT;
        }
        ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }

        pSECPort = &pSECComponent->pSECPort[portIndex];
        if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) {
            ret = OMX_ErrorNone;
            goto EXIT;
        }
        if (CHECK_PORT_TUNNELED(pSECPort) == 0) {
            ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/
            goto EXIT;
        }

        if (pSECPort->portDefinition.eDir == OMX_DirInput) {
            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
                /*
                if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    ret = OMX_ErrorNone;
                }
                */
                pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER;
                bufferSupplier->nPortIndex = pSECPort->tunneledPort;
                ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
                goto EXIT;
            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
                ret = OMX_ErrorNone;
                if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER;
                    bufferSupplier->nPortIndex = pSECPort->tunneledPort;
                    ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier);
                }
                goto EXIT;
            }
        } else if (pSECPort->portDefinition.eDir == OMX_DirOutput) {
            if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) {
                ret = OMX_ErrorNone;
                if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER;
                    ret = OMX_ErrorNone;
                }
                goto EXIT;
            } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) {
                /*
                if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    ret = OMX_ErrorNone;
                }
                */
                pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER;
                ret = OMX_ErrorNone;
                goto EXIT;
            }
        }
    }
        break;
    default:
    {
        ret = OMX_ErrorUnsupportedIndex;
        goto EXIT;
    }
        break;
    }

    ret = OMX_ErrorNone;

EXIT:

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OMX_GetParameter(
    OMX_IN OMX_HANDLETYPE hComponent,
    OMX_IN OMX_INDEXTYPE  nParamIndex,
    OMX_INOUT OMX_PTR     ComponentParameterStructure)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    SEC_OMX_BASECOMPONENT *pSECComponent = NULL;

    FunctionIn();

    if (hComponent == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if (pOMXComponent->pComponentPrivate == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;

    if (ComponentParameterStructure == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    if (pSECComponent->currentState == OMX_StateInvalid) {
        ret = OMX_ErrorInvalidState;
        goto EXIT;
    }

    switch (nParamIndex) {
    case (OMX_INDEXTYPE)OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
    {
        /* For Android PV OpenCORE */
        OMXComponentCapabilityFlagsType *capabilityFlags = (OMXComponentCapabilityFlagsType *)ComponentParameterStructure;
        SEC_OSAL_Memcpy(capabilityFlags, &pSECComponent->capabilityFlags, sizeof(OMXComponentCapabilityFlagsType));
    }
        break;
    case OMX_IndexParamAudioInit:
    case OMX_IndexParamVideoInit:
    case OMX_IndexParamImageInit:
    case OMX_IndexParamOtherInit:
    {
        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
        ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }
        portParam->nPorts         = 0;
        portParam->nStartPortNumber     = 0;
    }
        break;
    case OMX_IndexParamPortDefinition:
    {
        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
        OMX_U32                       portIndex = portDefinition->nPortIndex;
        SEC_OMX_BASEPORT             *pSECPort;

        if (portIndex >= pSECComponent->portParam.nPorts) {
            ret = OMX_ErrorBadPortIndex;
            goto EXIT;
        }
        ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }

        pSECPort = &pSECComponent->pSECPort[portIndex];
        SEC_OSAL_Memcpy(portDefinition, &pSECPort->portDefinition, portDefinition->nSize);
    }
        break;
    case OMX_IndexParamPriorityMgmt:
    {
        OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure;

        ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE));
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }

        compPriority->nGroupID       = pSECComponent->compPriority.nGroupID;
        compPriority->nGroupPriority = pSECComponent->compPriority.nGroupPriority;
    }
        break;

    case OMX_IndexParamCompBufferSupplier:
    {
        OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure;
        OMX_U32                       portIndex = bufferSupplier->nPortIndex;
        SEC_OMX_BASEPORT             *pSECPort;

        if ((pSECComponent->currentState == OMX_StateLoaded) ||
            (pSECComponent->currentState == OMX_StateWaitForResources)) {
            if (portIndex >= pSECComponent->portParam.nPorts) {
                ret = OMX_ErrorBadPortIndex;
                goto EXIT;
            }
            ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
            if (ret != OMX_ErrorNone) {
                goto EXIT;
            }

            pSECPort = &pSECComponent->pSECPort[portIndex];


            if (pSECPort->portDefinition.eDir == OMX_DirInput) {
                if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
                } else if (CHECK_PORT_TUNNELED(pSECPort)) {
                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
                } else {
                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
                }
            } else {
                if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;
                } else if (CHECK_PORT_TUNNELED(pSECPort)) {
                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;
                } else {
                    bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
                }
            }
        }
        else
        {
            ret = OMX_ErrorIncorrectStateOperation;
            goto EXIT;
        }
    }
        break;
    default:
    {
        ret = OMX_ErrorUnsupportedIndex;
        goto EXIT;
    }
        break;
    }

    ret = OMX_ErrorNone;

EXIT:

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    SEC_OMX_MESSAGE       *message;
    OMX_STATETYPE          destState = messageParam;
    OMX_STATETYPE          currentState = pSECComponent->currentState;
    SEC_OMX_BASEPORT      *pSECPort = NULL;
    OMX_S32                countValue = 0;
    int                   i = 0, j = 0;

    FunctionIn();

    /* check parameters */
    if (currentState == destState) {
         ret = OMX_ErrorSameState;
            goto EXIT;
    }
    if (currentState == OMX_StateInvalid) {
        ret = OMX_ErrorInvalidState;
        goto EXIT;
    }

    if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) {
        ret = SEC_OMX_Get_Resource(pOMXComponent);
        if (ret != OMX_ErrorNone) {
            goto EXIT;
        }
    }
    if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded))       ||
        ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid))      ||
        ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) ||
        ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) {
        SEC_OMX_Release_Resource(pOMXComponent);
    }

    SEC_OSAL_Log(SEC_LOG_TRACE, "destState: %d", destState);

    switch (destState) {
    case OMX_StateInvalid:
        switch (currentState) {
        case OMX_StateIdle:
        case OMX_StateExecuting:
        case OMX_StatePause:
        case OMX_StateLoaded:
        case OMX_StateWaitForResources:
            pSECComponent->currentState = OMX_StateInvalid;
            if (pSECComponent->hBufferProcess) {
                pSECComponent->bExitBufferProcessThread = OMX_TRUE;

                for (i = 0; i < ALL_PORT_NUM; i++) {
                    SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue);
                    if (countValue == 0)
                        SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID);
                }

                SEC_OSAL_SignalSet(pSECComponent->pauseEvent);
                SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess);
                pSECComponent->hBufferProcess = NULL;

                for (i = 0; i < ALL_PORT_NUM; i++) {
                    SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex);
                    pSECComponent->secDataBuffer[i].bufferMutex = NULL;
                }

                SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent);
                for (i = 0; i < ALL_PORT_NUM; i++) {
                    SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID);
                    pSECComponent->pSECPort[i].bufferSemID = NULL;
                }
            }
            if (pSECComponent->sec_mfc_componentTerminate != NULL)
                pSECComponent->sec_mfc_componentTerminate(pOMXComponent);
            break;
        }
        ret = OMX_ErrorInvalidState;
        break;
    case OMX_StateLoaded:
        switch (currentState) {
        case OMX_StateIdle:
            pSECComponent->bExitBufferProcessThread = OMX_TRUE;

            for (i = 0; i < ALL_PORT_NUM; i++) {
                SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue);
                if (countValue == 0)
                    SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID);
            }

            SEC_OSAL_SignalSet(pSECComponent->pauseEvent);
            SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess);
            pSECComponent->hBufferProcess = NULL;

            for (i = 0; i < ALL_PORT_NUM; i++) {
                SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex);
                pSECComponent->secDataBuffer[i].bufferMutex = NULL;
            }

            SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent);
            for (i = 0; i < ALL_PORT_NUM; i++) {
                SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID);
                pSECComponent->pSECPort[i].bufferSemID = NULL;
            }

            pSECComponent->sec_mfc_componentTerminate(pOMXComponent);

            for (i = 0; i < (pSECComponent->portParam.nPorts); i++) {
                pSECPort = (pSECComponent->pSECPort + i);
                if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) {
                        message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ);
                        if (message != NULL)
                            SEC_OSAL_Free(message);
                    }
                    ret = pSECComponent->sec_FreeTunnelBuffer(pSECComponent, i);
                    if (OMX_ErrorNone != ret) {
                        goto EXIT;
                    }
                } else {
                    if (CHECK_PORT_ENABLED(pSECPort)) {
                        SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource);
                        pSECPort->portDefinition.bPopulated = OMX_FALSE;
                    }
                }
            }
            pSECComponent->currentState = OMX_StateLoaded;
            break;
        case OMX_StateWaitForResources:
            ret = SEC_OMX_Out_WaitForResource(pOMXComponent);
            pSECComponent->currentState = OMX_StateLoaded;
            break;
        case OMX_StateExecuting:
        case OMX_StatePause:
        default:
            ret = OMX_ErrorIncorrectStateTransition;
            break;
        }
        break;
    case OMX_StateIdle:
        switch (currentState) {
        case OMX_StateLoaded:
            for (i = 0; i < pSECComponent->portParam.nPorts; i++) {
                pSECPort = (pSECComponent->pSECPort + i);
                if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                    if (CHECK_PORT_ENABLED(pSECPort)) {
                        ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, i);
                        if (ret!=OMX_ErrorNone)
                            goto EXIT;
                    }
                } else {
                    if (CHECK_PORT_ENABLED(pSECPort)) {
                        SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[i].loadedResource);
                        pSECPort->portDefinition.bPopulated = OMX_TRUE;
                    }
                }
            }
            ret = pSECComponent->sec_mfc_componentInit(pOMXComponent);
            if (ret != OMX_ErrorNone) {
                /*
                 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
                 */
                goto EXIT;
            }
            pSECComponent->bExitBufferProcessThread = OMX_FALSE;
            SEC_OSAL_SignalCreate(&pSECComponent->pauseEvent);
            for (i = 0; i < ALL_PORT_NUM; i++) {
                SEC_OSAL_SemaphoreCreate(&pSECComponent->pSECPort[i].bufferSemID);
            }
            for (i = 0; i < ALL_PORT_NUM; i++) {
                SEC_OSAL_MutexCreate(&pSECComponent->secDataBuffer[i].bufferMutex);
            }
            ret = SEC_OSAL_ThreadCreate(&pSECComponent->hBufferProcess,
                             SEC_OMX_BufferProcessThread,
                             pOMXComponent);
            if (ret != OMX_ErrorNone) {
                /*
                 * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free
                 */

                SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent);
                for (i = 0; i < ALL_PORT_NUM; i++) {
                    SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex);
                    pSECComponent->secDataBuffer[i].bufferMutex = NULL;
                }
                for (i = 0; i < ALL_PORT_NUM; i++) {
                    SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID);
                    pSECComponent->pSECPort[i].bufferSemID = NULL;
                }

                ret = OMX_ErrorInsufficientResources;
                goto EXIT;
            }
            pSECComponent->currentState = OMX_StateIdle;
            break;
        case OMX_StateExecuting:
        case OMX_StatePause:
            SEC_OMX_BufferFlushProcessNoEvent(pOMXComponent, ALL_PORT_INDEX);
            pSECComponent->currentState = OMX_StateIdle;
            break;
        case OMX_StateWaitForResources:
            pSECComponent->currentState = OMX_StateIdle;
            break;
        }
        break;
    case OMX_StateExecuting:
        switch (currentState) {
        case OMX_StateLoaded:
            ret = OMX_ErrorIncorrectStateTransition;
            break;
        case OMX_StateIdle:
            for (i = 0; i < pSECComponent->portParam.nPorts; i++) {
                pSECPort = &pSECComponent->pSECPort[i];
                if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) {
                    for (j = 0; j < pSECPort->tunnelBufferNum; j++) {
                        SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID);
                    }
                }
            }

            pSECComponent->transientState = SEC_OMX_TransStateMax;
            pSECComponent->currentState = OMX_StateExecuting;
            SEC_OSAL_SignalSet(pSECComponent->pauseEvent);
            break;
        case OMX_StatePause:
            for (i = 0; i < pSECComponent->portParam.nPorts; i++) {
                pSECPort = &pSECComponent->pSECPort[i];
                if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) {
                    OMX_U32 semaValue = 0, cnt = 0;
                    SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &semaValue);
                    if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > semaValue) {
                        cnt = SEC_OSAL_GetElemNum(&pSECPort->bufferQ) - semaValue;
                        for (j = 0; j < cnt; j++) {
                            SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID);
                        }
                    }
                }
            }

            pSECComponent->currentState = OMX_StateExecuting;
            SEC_OSAL_SignalSet(pSECComponent->pauseEvent);
            break;
        case OMX_StateWaitForResources:
            ret = OMX_ErrorIncorrectStateTransition;
            break;
        }
        break;
    case OMX_StatePause:
        switch (currentState) {
        case OMX_StateLoaded:
            ret = OMX_ErrorIncorrectStateTransition;
            break;
        case OMX_StateIdle:
            pSECComponent->currentState = OMX_StatePause;
            break;
        case OMX_StateExecuting:
            pSECComponent->currentState = OMX_StatePause;
            break;
        case OMX_StateWaitForResources:
            ret = OMX_ErrorIncorrectStateTransition;
            break;
        }
        break;
    case OMX_StateWaitForResources:
        switch (currentState) {
        case OMX_StateLoaded:
            ret = SEC_OMX_In_WaitForResource(pOMXComponent);
            pSECComponent->currentState = OMX_StateWaitForResources;
            break;
        case OMX_StateIdle:
        case OMX_StateExecuting:
        case OMX_StatePause:
            ret = OMX_ErrorIncorrectStateTransition;
            break;
        }
        break;
    }

EXIT:
    if (ret == OMX_ErrorNone) {
        if (pSECComponent->pCallbacks != NULL) {
            pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
            pSECComponent->callbackData,
            OMX_EventCmdComplete, OMX_CommandStateSet,
            destState, NULL);
        }
    } else {
        if (pSECComponent->pCallbacks != NULL) {
            pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
            pSECComponent->callbackData,
            OMX_EventError, ret, 0, NULL);
        }
    }
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(
    OMX_IN OMX_HANDLETYPE        hComponent,
    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
{
    OMX_ERRORTYPE           ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    OMX_BOOL               findBuffer = OMX_FALSE;
    EXYNOS_OMX_MESSAGE       *message;
    OMX_U32                i = 0;

    FunctionIn();

    if (hComponent == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if (pOMXComponent->pComponentPrivate == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    if (pExynosComponent->currentState == OMX_StateInvalid) {
        ret = OMX_ErrorInvalidState;
        goto EXIT;
    }

    if (pBuffer == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) {
        ret = OMX_ErrorBadPortIndex;
        goto EXIT;
    }

    ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if ((pExynosComponent->currentState != OMX_StateIdle) &&
        (pExynosComponent->currentState != OMX_StateExecuting) &&
        (pExynosComponent->currentState != OMX_StatePause)) {
        ret = OMX_ErrorIncorrectStateOperation;
        goto EXIT;
    }

    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
    if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
        ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) &&
        (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
        ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
        (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
        ret = OMX_ErrorIncorrectStateOperation;
        goto EXIT;
    }

    Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
        if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
            pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
            findBuffer = OMX_TRUE;
            break;
        }
    }

    if (findBuffer == OMX_FALSE) {
        ret = OMX_ErrorBadParameter;
        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
        goto EXIT;
    }

    message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
    if (message == NULL) {
        ret = OMX_ErrorInsufficientResources;
        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
        goto EXIT;
    }
    message->messageType = EXYNOS_OMX_CommandFillBuffer;
    message->messageParam = (OMX_U32) i;
    message->pCmdData = (OMX_PTR)pBuffer;

    ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
    if (ret != 0) {
        ret = OMX_ErrorUndefined;
        Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
        goto EXIT;
    }

    ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
    Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OMX_EmptyThisBuffer(
    OMX_IN OMX_HANDLETYPE        hComponent,
    OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
{
    OMX_ERRORTYPE           ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    SEC_OMX_BASEPORT      *pSECPort = NULL;
    OMX_BOOL               findBuffer = OMX_FALSE;
    SEC_OMX_MESSAGE       *message;
    OMX_U32                i = 0;

    FunctionIn();

    if (hComponent == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if (pOMXComponent->pComponentPrivate == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    if (pSECComponent->currentState == OMX_StateInvalid) {
        ret = OMX_ErrorInvalidState;
        goto EXIT;
    }

    if (pBuffer == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) {
        ret = OMX_ErrorBadPortIndex;
        goto EXIT;
    }

    ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if ((pSECComponent->currentState != OMX_StateIdle) &&
        (pSECComponent->currentState != OMX_StateExecuting) &&
        (pSECComponent->currentState != OMX_StatePause)) {
        ret = OMX_ErrorIncorrectStateOperation;
        goto EXIT;
    }

    pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX];
    if ((!CHECK_PORT_ENABLED(pSECPort)) ||
        ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) &&
        (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) ||
        ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) &&
        (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) {
        ret = OMX_ErrorIncorrectStateOperation;
        goto EXIT;
    }

    for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) {
        if (pBuffer == pSECPort->bufferHeader[i]) {
            findBuffer = OMX_TRUE;
            break;
        }
    }

    if (findBuffer == OMX_FALSE) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    } else {
        ret = OMX_ErrorNone;
    }

    message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE));
    if (message == NULL) {
        ret = OMX_ErrorInsufficientResources;
        goto EXIT;
    }
    message->messageType = SEC_OMX_CommandEmptyBuffer;
    message->messageParam = (OMX_U32) i;
    message->pCmdData = (OMX_PTR)pBuffer;

    SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message);
    SEC_OSAL_SemaphorePost(pSECPort->bufferSemID);

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    SEC_OMX_BASEPORT      *pSECPort = NULL;
    OMX_BUFFERHEADERTYPE  *bufferHeader = NULL;
    SEC_OMX_MESSAGE       *message = NULL;
    OMX_U32                flushNum = 0;
    OMX_S32                semValue = 0;

    FunctionIn();

    pSECPort = &pSECComponent->pSECPort[portIndex];
    while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) {
        SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &semValue);
        if (semValue == 0)
            SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID);
        SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID);

        message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ);
        if (message != NULL) {
            bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData;
            bufferHeader->nFilledLen = 0;

            if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                if (portIndex) {
                    OMX_EmptyThisBuffer(pSECPort->tunneledComponent, bufferHeader);
                } else {
                    OMX_FillThisBuffer(pSECPort->tunneledComponent, bufferHeader);
                }
                SEC_OSAL_Free(message);
                message = NULL;
            } else if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
                SEC_OSAL_Log(SEC_LOG_ERROR, "Tunneled mode is not working, Line:%d", __LINE__);
                ret = OMX_ErrorNotImplemented;
                SEC_OSAL_Queue(&pSECPort->bufferQ, pSECPort);
                goto EXIT;
            } else {
                if (portIndex == OUTPUT_PORT_INDEX) {
                    pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader);
                } else {
                    pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader);
                }

                SEC_OSAL_Free(message);
                message = NULL;
            }
        }
    }

    if (pSECComponent->secDataBuffer[portIndex].dataValid == OMX_TRUE) {
        if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
            message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE));
            message->pCmdData = pSECComponent->secDataBuffer[portIndex].bufferHeader;
            message->messageType = 0;
            message->messageParam = -1;
            SEC_OSAL_Queue(&pSECPort->bufferQ, message);
            pSECComponent->sec_BufferReset(pOMXComponent, portIndex);
        } else {
            if (portIndex == INPUT_PORT_INDEX)
                pSECComponent->sec_InputBufferReturn(pOMXComponent);
            else if (portIndex == OUTPUT_PORT_INDEX)
                pSECComponent->sec_OutputBufferReturn(pOMXComponent);
        }
    }

    if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) {
        while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) < pSECPort->assignedBufferNum) {
            SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID);
        }
        if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) != pSECPort->assignedBufferNum)
            SEC_OSAL_SetElemNum(&pSECPort->bufferQ, pSECPort->assignedBufferNum);
    } else {
        while(1) {
            int cnt;
            SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &cnt);
            if (cnt == 0)
                break;
            SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID);
        }
        SEC_OSAL_SetElemNum(&pSECPort->bufferQ, 0);
    }

    pSECComponent->processData[portIndex].dataLen       = 0;
    pSECComponent->processData[portIndex].nFlags        = 0;
    pSECComponent->processData[portIndex].remainDataLen = 0;
    pSECComponent->processData[portIndex].timeStamp     = 0;
    pSECComponent->processData[portIndex].usedDataLen   = 0;

EXIT:
    FunctionOut();

    return ret;
}