OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit()
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComponent;
    EXYNOS_OMX_RM_COMPONENT_LIST *pNextComponent;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    if (gpVideoDecRMComponentList) {
        pCurrComponent = gpVideoDecRMComponentList;
        while (pCurrComponent != NULL) {
            pNextComponent = pCurrComponent->pNext;
            Exynos_OSAL_Free(pCurrComponent);
            pCurrComponent = pNextComponent;
        }
        gpVideoDecRMComponentList = NULL;
    }
    if (gpVideoDecRMWaitingList) {
        pCurrComponent = gpVideoDecRMWaitingList;
        while (pCurrComponent != NULL) {
            pNextComponent = pCurrComponent->pNext;
            Exynos_OSAL_Free(pCurrComponent);
            pCurrComponent = pNextComponent;
        }
        gpVideoDecRMWaitingList = NULL;
    }

    if (gpVideoEncRMComponentList) {
        pCurrComponent = gpVideoEncRMComponentList;
        while (pCurrComponent != NULL) {
            pNextComponent = pCurrComponent->pNext;
            Exynos_OSAL_Free(pCurrComponent);
            pCurrComponent = pNextComponent;
        }
        gpVideoEncRMComponentList = NULL;
    }
    if (gpVideoEncRMWaitingList) {
        pCurrComponent = gpVideoEncRMWaitingList;
        while (pCurrComponent != NULL) {
            pNextComponent = pCurrComponent->pNext;
            Exynos_OSAL_Free(pCurrComponent);
            pCurrComponent = pNextComponent;
        }
        gpVideoEncRMWaitingList = NULL;
    }

    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    Exynos_OSAL_MutexTerminate(ghVideoRMComponentListMutex);
    ghVideoRMComponentListMutex = NULL;

    ret = OMX_ErrorNone;
EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent)
{
    OMX_ERRORTYPE             ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;

    OMX_S32 countValue = 0;
    int 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->transientState == EXYNOS_OMX_TransStateLoadedToIdle) {
        pExynosComponent->abendState = OMX_TRUE;
        for (i = 0; i < ALL_PORT_NUM; i++) {
            pExynosPort = &pExynosComponent->pExynosPort[i];
            Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
        }
        Exynos_OSAL_SignalWait(pExynosComponent->abendStateEvent, DEF_MAX_WAIT_TIME);
        Exynos_OSAL_SignalReset(pExynosComponent->abendStateEvent);
    }

    for (i = 0; i < ALL_PORT_NUM; i++) {
        pExynosPort = &pExynosComponent->pExynosPort[i];

        Exynos_OSAL_SemaphoreTerminate(pExynosPort->loadedResource);
        pExynosPort->loadedResource = NULL;
        Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource);
        pExynosPort->unloadedResource = NULL;
        Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
        pExynosPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
        pExynosPort->extendBufferHeader = NULL;

        Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ);
    }
    Exynos_OSAL_Free(pExynosComponent->pExynosPort);
    pExynosComponent->pExynosPort = NULL;
    ret = OMX_ErrorNone;
EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_ComponentLoad(EXYNOS_OMX_COMPONENT *exynos_component)
{
    OMX_ERRORTYPE      ret = OMX_ErrorNone;
    OMX_HANDLETYPE     libHandle;
    OMX_COMPONENTTYPE *pOMXComponent;

    FunctionIn();

    OMX_ERRORTYPE (*Exynos_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName);

    libHandle = Exynos_OSAL_dlopen((OMX_STRING)exynos_component->libName, RTLD_NOW);
    if (!libHandle) {
        ret = OMX_ErrorInvalidComponentName;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__);
        goto EXIT;
    }

    Exynos_OMX_ComponentInit = Exynos_OSAL_dlsym(libHandle, "Exynos_OMX_ComponentInit");
    if (!Exynos_OMX_ComponentInit) {
        Exynos_OSAL_dlclose(libHandle);
        ret = OMX_ErrorInvalidComponent;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__);
        goto EXIT;
    }

    pOMXComponent = (OMX_COMPONENTTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE));
    INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE);
    ret = (*Exynos_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, (OMX_STRING)exynos_component->componentName);
    if (ret != OMX_ErrorNone) {
        Exynos_OSAL_Free(pOMXComponent);
        Exynos_OSAL_dlclose(libHandle);
        ret = OMX_ErrorInvalidComponent;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__);
        goto EXIT;
    } else {
        if (Exynos_OMX_ComponentAPICheck(pOMXComponent) != OMX_ErrorNone) {
            if (NULL != pOMXComponent->ComponentDeInit)
                pOMXComponent->ComponentDeInit(pOMXComponent);
            Exynos_OSAL_Free(pOMXComponent);
            Exynos_OSAL_dlclose(libHandle);
            ret = OMX_ErrorInvalidComponent;
            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__);
            goto EXIT;
        }
        exynos_component->libHandle = libHandle;
        exynos_component->pOMXComponent = pOMXComponent;
        ret = OMX_ErrorNone;
    }

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    OMX_U32                i = 0, elemNum = 0;
    EXYNOS_OMX_MESSAGE       *message;

    FunctionIn();

    pExynosPort = &pExynosComponent->pExynosPort[portIndex];

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

    if (pExynosComponent->currentState != OMX_StateLoaded) {
        if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
            while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
                message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
                Exynos_OSAL_Free(message);
            }
        }
        pExynosPort->portDefinition.bPopulated = OMX_FALSE;
        Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
    }
    pExynosPort->portDefinition.bEnabled = OMX_FALSE;
    ret = OMX_ErrorNone;

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_ComponentUnload(EXYNOS_OMX_COMPONENT *exynos_component)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE *pOMXComponent = NULL;

    FunctionIn();

    if (!exynos_component) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    pOMXComponent = exynos_component->pOMXComponent;
    if (pOMXComponent != NULL) {
        pOMXComponent->ComponentDeInit(pOMXComponent);
        Exynos_OSAL_Free(pOMXComponent);
        exynos_component->pOMXComponent = NULL;
    }

    if (exynos_component->libHandle != NULL) {
        Exynos_OSAL_dlclose(exynos_component->libHandle);
        exynos_component->libHandle = NULL;
    }

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_ResourceManager_Deinit()
{
    OMX_ERRORTYPE                    ret            = OMX_ErrorNone;
    EXYNOS_OMX_RM_COMPONENT_LIST    *pCurrComponent = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST    *pNextComponent = NULL;
    int i = 0;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    for (i = 0; i < RESOURCE_MAX; i++) {
        if (gpRMList[i]) {
            pCurrComponent = gpRMList[i];
            while (pCurrComponent != NULL) {
                pNextComponent = pCurrComponent->pNext;
                Exynos_OSAL_Free(pCurrComponent);
                pCurrComponent = pNextComponent;
            }
            gpRMList[i] = NULL;
        }

        if (gpRMWaitList[i]) {
            pCurrComponent = gpRMWaitList[i];
            while (pCurrComponent != NULL) {
                pNextComponent = pCurrComponent->pNext;
                Exynos_OSAL_Free(pCurrComponent);
                pCurrComponent = pNextComponent;
            }
            gpRMWaitList[i] = NULL;
        }
    }

    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    Exynos_OSAL_MutexTerminate(ghVideoRMComponentListMutex);
    ghVideoRMComponentListMutex = NULL;

    ret = OMX_ErrorNone;

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE removeElementList(
    EXYNOS_OMX_RM_COMPONENT_LIST   **ppList,
    OMX_COMPONENTTYPE               *pOMXComponent)
{
    OMX_ERRORTYPE                 ret           = OMX_ErrorNone;
    EXYNOS_OMX_RM_COMPONENT_LIST *pCurrComp     = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pPrevComp     = NULL;
    OMX_BOOL                      bDetectComp   = OMX_FALSE;

    if (*ppList == NULL) {
        ret = OMX_ErrorUndefined;
        goto EXIT;
    }

    pCurrComp = *ppList;
    while (pCurrComp != NULL) {
        if (pCurrComp->pOMXStandComp == pOMXComponent) {
            if (*ppList == pCurrComp) {
                *ppList = pCurrComp->pNext;
                Exynos_OSAL_Free(pCurrComp);
                pCurrComp = NULL;
            } else {
                if (pPrevComp != NULL)
                    pPrevComp->pNext = pCurrComp->pNext;

                Exynos_OSAL_Free(pCurrComp);
                pCurrComp = NULL;
            }

            bDetectComp = OMX_TRUE;
            break;
        } else {
            pPrevComp = pCurrComp;
            pCurrComp = pCurrComp->pNext;
        }
    }

    if (bDetectComp == OMX_FALSE)
        ret = OMX_ErrorComponentNotFound;
    else
        ret = OMX_ErrorNone;

EXIT:
    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Component_Unregister(EXYNOS_OMX_COMPONENT_REGLIST *componentList)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    Exynos_OSAL_Free(componentList);

EXIT:
    return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)
{
    OMX_ERRORTYPE         ret = OMX_ErrorNone;
    EXYNOS_OMX_COMPONENT *currentComponent = NULL;
    EXYNOS_OMX_COMPONENT *deleteComponent  = NULL;

    FunctionIn();

    if ((gInitialized != 1) ||
        (gLoadComponentList == NULL)) {
        ret = OMX_ErrorNotReady;
        goto EXIT;
    }

    if (!hComponent) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    Exynos_OSAL_MutexLock(ghLoadComponentListMutex);
    if (gLoadComponentList->pOMXComponent == hComponent) {
        deleteComponent = gLoadComponentList;
        gLoadComponentList = gLoadComponentList->nextOMXComp;
    } else {
        currentComponent = gLoadComponentList;

        while ((currentComponent != NULL) &&
               (currentComponent->nextOMXComp != NULL)) {
            if (currentComponent->nextOMXComp->pOMXComponent == hComponent) {
                deleteComponent = currentComponent->nextOMXComp;
                currentComponent->nextOMXComp = deleteComponent->nextOMXComp;
                break;
            }
            currentComponent = currentComponent->nextOMXComp;
        }

        if (deleteComponent == NULL) {
            ret = OMX_ErrorComponentNotFound;
            Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);
            goto EXIT;
        }
    }
    Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);

    Exynos_OMX_ComponentUnload(deleteComponent);
    Exynos_OSAL_Free(deleteComponent);

EXIT:
    FunctionOut();

    return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY Exynos_OMX_GetHandle(
    OMX_OUT OMX_HANDLETYPE *pHandle,
    OMX_IN  OMX_STRING cComponentName,
    OMX_IN  OMX_PTR pAppData,
    OMX_IN  OMX_CALLBACKTYPE *pCallBacks)
{
    OMX_ERRORTYPE         ret = OMX_ErrorNone;
    EXYNOS_OMX_COMPONENT *loadComponent;
    EXYNOS_OMX_COMPONENT *currentComponent;
    unsigned int i = 0;

    FunctionIn();

    if (gInitialized != 1) {
        ret = OMX_ErrorNotReady;
        goto EXIT;
    }

    if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ComponentName : %s", cComponentName);

    for (i = 0; i < gComponentNum; i++) {
        if (Exynos_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) {
            loadComponent = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT));
            Exynos_OSAL_Memset(loadComponent, 0, sizeof(EXYNOS_OMX_COMPONENT));

            Exynos_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName);
            Exynos_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName);
            ret = Exynos_OMX_ComponentLoad(loadComponent);
            if (ret != OMX_ErrorNone) {
                Exynos_OSAL_Free(loadComponent);
                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
                goto EXIT;
            }

            ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData);
            if (ret != OMX_ErrorNone) {
                Exynos_OMX_ComponentUnload(loadComponent);
                Exynos_OSAL_Free(loadComponent);
                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
                goto EXIT;
            }

            Exynos_OSAL_MutexLock(ghLoadComponentListMutex);
            if (gLoadComponentList == NULL) {
                gLoadComponentList = loadComponent;
            } else {
                currentComponent = gLoadComponentList;
                while (currentComponent->nextOMXComp != NULL) {
                    currentComponent = currentComponent->nextOMXComp;
                }
                currentComponent->nextOMXComp = loadComponent;
            }
            Exynos_OSAL_MutexUnlock(ghLoadComponentListMutex);

            *pHandle = loadComponent->pOMXComponent;
            ret = OMX_ErrorNone;
            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_OMX_GetHandle : %s", "OMX_ErrorNone");
            goto EXIT;
        }
    }

    ret = OMX_ErrorComponentNotFound;

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    EXYNOS_OMX_BASEPORT      *pExynosInputPort = NULL;
    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = NULL;
    int i = 0;

    FunctionIn();

    if (hComponent == NULL) {
        ret = OMX_ErrorBadParameter;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
        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;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
        goto EXIT;
    }
    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;

    INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE);
    pExynosComponent->portParam.nPorts = ALL_PORT_NUM;
    pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX;

    pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
    if (pExynosPort == NULL) {
        ret = OMX_ErrorInsufficientResources;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
        goto EXIT;
    }
    Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
    pExynosComponent->pExynosPort = pExynosPort;

    /* Input Port */
    pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX];

    Exynos_OSAL_QueueCreate(&pExynosInputPort->bufferQ, MAX_QUEUE_ELEMENTS);

    pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
    if (pExynosInputPort->extendBufferHeader == NULL) {
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        ret = OMX_ErrorInsufficientResources;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
        goto EXIT;
    }
    Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);

    pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
    if (pExynosInputPort->bufferStateAllocate == NULL) {
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        ret = OMX_ErrorInsufficientResources;
        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
        goto EXIT;
    }
    Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);

    pExynosInputPort->bufferSemID = NULL;
    pExynosInputPort->assignedBufferNum = 0;
    pExynosInputPort->portState = OMX_StateMax;
    pExynosInputPort->bIsPortFlushed = OMX_FALSE;
    pExynosInputPort->bIsPortDisabled = OMX_FALSE;
    pExynosInputPort->tunneledComponent = NULL;
    pExynosInputPort->tunneledPort = 0;
    pExynosInputPort->tunnelBufferNum = 0;
    pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
    pExynosInputPort->tunnelFlags = 0;
    ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->loadedResource);
    if (ret != OMX_ErrorNone) {
        Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
        pExynosInputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        goto EXIT;
    }
    ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->unloadedResource);
    if (ret != OMX_ErrorNone) {
        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
        pExynosInputPort->loadedResource = NULL;
        Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
        pExynosInputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        goto EXIT;
    }

    INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
    pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX;
    pExynosInputPort->portDefinition.eDir = OMX_DirInput;
    pExynosInputPort->portDefinition.nBufferCountActual = 0;
    pExynosInputPort->portDefinition.nBufferCountMin = 0;
    pExynosInputPort->portDefinition.nBufferSize = 0;
    pExynosInputPort->portDefinition.bEnabled = OMX_FALSE;
    pExynosInputPort->portDefinition.bPopulated = OMX_FALSE;
    pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax;
    pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
    pExynosInputPort->portDefinition.nBufferAlignment = 0;
    pExynosInputPort->markType.hMarkTargetComponent = NULL;
    pExynosInputPort->markType.pMarkData = NULL;
    pExynosInputPort->exceptionFlag = GENERAL_STATE;

    /* Output Port */
    pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX];

    Exynos_OSAL_QueueCreate(&pExynosOutputPort->bufferQ, MAX_QUEUE_ELEMENTS); /* For in case of "Output Buffer Share", MAX ELEMENTS(DPB + EDPB) */ 

    pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
    if (pExynosOutputPort->extendBufferHeader == NULL) {
        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
        pExynosInputPort->unloadedResource = NULL;
        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
        pExynosInputPort->loadedResource = NULL;
        Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
        pExynosInputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        ret = OMX_ErrorInsufficientResources;
        goto EXIT;
    }
    Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);

    pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
    if (pExynosOutputPort->bufferStateAllocate == NULL) {
        Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
        pExynosOutputPort->extendBufferHeader = NULL;

        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
        pExynosInputPort->unloadedResource = NULL;
        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
        pExynosInputPort->loadedResource = NULL;
        Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
        pExynosInputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        ret = OMX_ErrorInsufficientResources;
        goto EXIT;
    }
    Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);

    pExynosOutputPort->bufferSemID = NULL;
    pExynosOutputPort->assignedBufferNum = 0;
    pExynosOutputPort->portState = OMX_StateMax;
    pExynosOutputPort->bIsPortFlushed = OMX_FALSE;
    pExynosOutputPort->bIsPortDisabled = OMX_FALSE;
    pExynosOutputPort->tunneledComponent = NULL;
    pExynosOutputPort->tunneledPort = 0;
    pExynosOutputPort->tunnelBufferNum = 0;
    pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
    pExynosOutputPort->tunnelFlags = 0;
    ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->loadedResource);
    if (ret != OMX_ErrorNone) {
        Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate);
        pExynosOutputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
        pExynosOutputPort->extendBufferHeader = NULL;

        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
        pExynosInputPort->unloadedResource = NULL;
        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
        pExynosInputPort->loadedResource = NULL;
        Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
        pExynosInputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        goto EXIT;
    }
    ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->unloadedResource);
    if (ret != OMX_ErrorNone) {
        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->loadedResource);
        pExynosOutputPort->loadedResource = NULL;
        Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate);
        pExynosOutputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
        pExynosOutputPort->extendBufferHeader = NULL;

        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
        pExynosInputPort->unloadedResource = NULL;
        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
        pExynosInputPort->loadedResource = NULL;
        Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
        pExynosInputPort->bufferStateAllocate = NULL;
        Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
        pExynosInputPort->extendBufferHeader = NULL;
        Exynos_OSAL_Free(pExynosPort);
        pExynosPort = NULL;
        goto EXIT;
    }

    INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
    pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX;
    pExynosOutputPort->portDefinition.eDir = OMX_DirOutput;
    pExynosOutputPort->portDefinition.nBufferCountActual = 0;
    pExynosOutputPort->portDefinition.nBufferCountMin = 0;
    pExynosOutputPort->portDefinition.nBufferSize = 0;
    pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE;
    pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE;
    pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax;
    pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
    pExynosOutputPort->portDefinition.nBufferAlignment = 0;
    pExynosOutputPort->markType.hMarkTargetComponent = NULL;
    pExynosOutputPort->markType.pMarkData = NULL;
    pExynosOutputPort->exceptionFlag = GENERAL_STATE;

    pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
    pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
    pExynosComponent->checkTimeStamp.startTimeStamp = 0;
    pExynosComponent->checkTimeStamp.nStartFlags = 0x0;

    pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer;
    pOMXComponent->FillThisBuffer  = &Exynos_OMX_FillThisBuffer;

    ret = OMX_ErrorNone;
EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Component_Register(EXYNOS_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum)
{
    OMX_ERRORTYPE  ret = OMX_ErrorNone;
    int            componentNum = 0, roleNum = 0, totalCompNum = 0;
    int            read;
    char          *libName;
    size_t         len;
    const char    *errorMsg;
    DIR           *dir;
    struct dirent *d;

    int (*Exynos_OMX_COMPONENT_Library_Register)(ExynosRegisterComponentType **exynosComponents);
    ExynosRegisterComponentType **exynosComponentsTemp;
    EXYNOS_OMX_COMPONENT_REGLIST *componentList;

    FunctionIn();

    dir = opendir(EXYNOS_OMX_INSTALL_PATH);
    if (dir == NULL) {
        ret = OMX_ErrorUndefined;
        goto EXIT;
    }

    componentList = (EXYNOS_OMX_COMPONENT_REGLIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM);
    Exynos_OSAL_Memset(componentList, 0, sizeof(EXYNOS_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM);
    libName = Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE);

    while ((d = readdir(dir)) != NULL) {
        OMX_HANDLETYPE soHandle;

        if (Exynos_OSAL_Strncmp(d->d_name, "libOMX.Exynos.", Exynos_OSAL_Strlen("libOMX.Exynos.")) == 0) {
            Exynos_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE);
            Exynos_OSAL_Strcpy(libName, EXYNOS_OMX_INSTALL_PATH);
            Exynos_OSAL_Strcat(libName, d->d_name);
            Exynos_OSAL_Log(EXYNOS_LOG_INFO, "Loading the library: %s", d->d_name);
            if ((soHandle = Exynos_OSAL_dlopen(libName, RTLD_NOW)) != NULL) {
                Exynos_OSAL_dlerror();    /* clear error*/
                if ((Exynos_OMX_COMPONENT_Library_Register = Exynos_OSAL_dlsym(soHandle, "Exynos_OMX_COMPONENT_Library_Register")) != NULL) {
                    int i = 0;
                    unsigned int j = 0;

                    componentNum = (*Exynos_OMX_COMPONENT_Library_Register)(NULL);
                    exynosComponentsTemp = (ExynosRegisterComponentType **)Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType*) * componentNum);
                    for (i = 0; i < componentNum; i++) {
                        exynosComponentsTemp[i] = Exynos_OSAL_Malloc(sizeof(ExynosRegisterComponentType));
                        Exynos_OSAL_Memset(exynosComponentsTemp[i], 0, sizeof(ExynosRegisterComponentType));
                    }
                    (*Exynos_OMX_COMPONENT_Library_Register)(exynosComponentsTemp);

                    for (i = 0; i < componentNum; i++) {
                        Exynos_OSAL_Strcpy(componentList[totalCompNum].component.componentName, exynosComponentsTemp[i]->componentName);
                        for (j = 0; j < exynosComponentsTemp[i]->totalRoleNum; j++)
                            Exynos_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], exynosComponentsTemp[i]->roles[j]);
                        componentList[totalCompNum].component.totalRoleNum = exynosComponentsTemp[i]->totalRoleNum;

                        Exynos_OSAL_Strcpy(componentList[totalCompNum].libName, libName);

                        totalCompNum++;
                    }
                    for (i = 0; i < componentNum; i++) {
                        Exynos_OSAL_Free(exynosComponentsTemp[i]);
                    }

                    Exynos_OSAL_Free(exynosComponentsTemp);
                } else {
                    if ((errorMsg = Exynos_OSAL_dlerror()) != NULL)
                        Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlsym failed: %s", errorMsg);
                }
                Exynos_OSAL_dlclose(soHandle);
            } else {
                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "dlopen failed: %s", Exynos_OSAL_dlerror());
            }
        } else {
            /* not a component name line. skip */
            continue;
        }
    }

    Exynos_OSAL_Free(libName);

    closedir(dir);

    *compList = componentList;
    *compNum = totalCompNum;

EXIT:
    FunctionOut();

    return ret;
}