OMX_API OMX_ERRORTYPE Exynos_OMX_GetRolesOfComponent (
    OMX_IN    OMX_STRING compName,
    OMX_INOUT OMX_U32 *pNumRoles,
    OMX_OUT   OMX_U8 **roles)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    OMX_BOOL      detectComp = OMX_FALSE;
    int           compNum = 0, totalRoleNum = 0;
    int i = 0;

    FunctionIn();

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

    for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) {
        if (gComponentList != NULL) {
            if (Exynos_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) {
                *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum;
                compNum = i;
                detectComp = OMX_TRUE;
                break;
            }
        } else {
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }
    }

    if (detectComp == OMX_FALSE) {
        *pNumRoles = 0;
        ret = OMX_ErrorComponentNotFound;
        goto EXIT;
    }

    if (roles != NULL) {
        for (i = 0; i < totalRoleNum; i++) {
            Exynos_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]);
        }
    }

EXIT:
    FunctionOut();

    return ret;
}
OMX_API OMX_ERRORTYPE Exynos_OMX_GetComponentsOfRole (
    OMX_IN    OMX_STRING role,
    OMX_INOUT OMX_U32 *pNumComps,
    OMX_INOUT OMX_U8  **compNames)
{
    OMX_ERRORTYPE ret = OMX_ErrorNone;
    int           max_role_num = 0;
    OMX_STRING    RoleString[MAX_OMX_COMPONENT_ROLE_SIZE];
    int i = 0, j = 0;

    FunctionIn();

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

    *pNumComps = 0;

    for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) {
        max_role_num = gComponentList[i].component.totalRoleNum;

        for (j = 0; j < max_role_num; j++) {
            if (Exynos_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) {
                if (compNames != NULL) {
                    Exynos_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName);
                }
                *pNumComps = (*pNumComps + 1);
            }
        }
    }

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