OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent)
{
    OMX_ERRORTYPE                 ret                   = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent      = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList      = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentWaitList  = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp        = NULL;
    OMX_COMPONENTTYPE            *pOMXWaitComponent     = NULL;
    int numElem = 0;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    pRMComponentList = getRMList(pExynosComponent, gpRMList, NULL);
    if (pRMComponentList == NULL) {
        ret = OMX_ErrorUndefined;
        goto EXIT;
    }

    ret = removeElementList(&pRMComponentList, pOMXComponent);
    if (ret != OMX_ErrorNone)
        goto EXIT;

    ret = setRMList(pExynosComponent, gpRMList, pRMComponentList);
    if (ret != OMX_ErrorNone)
        goto EXIT;

    pRMComponentWaitList    = getRMList(pExynosComponent, gpRMWaitList, NULL);
    pComponentTemp          = pRMComponentWaitList;

    while (pComponentTemp) {
        numElem++;
        pComponentTemp = pComponentTemp->pNext;
    }

    if (numElem > 0) {
        pOMXWaitComponent = pRMComponentWaitList->pOMXStandComp;
        ret = removeElementList(&pRMComponentWaitList, pOMXWaitComponent);
        if (ret != OMX_ErrorNone)
            goto EXIT;

        ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList);
        if (ret != OMX_ErrorNone)
            goto EXIT;

        ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
        if (ret != OMX_ErrorNone)
            goto EXIT;
    }

EXIT:
    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
{
    OMX_ERRORTYPE                    ret                    = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT        *pExynosComponent       = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST    *pRMComponentWaitList   = NULL;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    pExynosComponent        = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    pRMComponentWaitList    = getRMList(pExynosComponent, gpRMWaitList, NULL);

    ret = removeElementList(&pRMComponentWaitList, pOMXComponent);
    if (ret != OMX_ErrorNone)
        goto EXIT;

    ret = setRMList(pExynosComponent, gpRMWaitList, pRMComponentWaitList);

EXIT:
    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
{
    OMX_ERRORTYPE             ret = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC)
        ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent);
    else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC)
        ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent);

    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent)
{
    OMX_ERRORTYPE                 ret                   = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent      = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pRMComponentList      = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp        = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentCandidate   = NULL;
    int numElem       = 0;
    int lowCompDetect = 0;
    int maxResource   = 0;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    pRMComponentList = getRMList(pExynosComponent, gpRMList, &maxResource);

    pComponentTemp = pRMComponentList;
    if (pComponentTemp != NULL) {
        while (pComponentTemp) {
            numElem++;
            pComponentTemp = pComponentTemp->pNext;
        }
    } else {
        numElem = 0;
    }

    if (numElem >= maxResource) {
        lowCompDetect = searchLowPriority(pRMComponentList,
                                          pExynosComponent->compPriority.nGroupPriority,
                                          &pComponentCandidate);
        if (lowCompDetect <= 0) {
            ret = OMX_ErrorInsufficientResources;
            goto EXIT;
        } else {
            ret = removeComponent(pComponentCandidate->pOMXStandComp);
            if (ret != OMX_ErrorNone) {
                ret = OMX_ErrorInsufficientResources;
                goto EXIT;
            } else {
                ret = removeElementList(&pRMComponentList, pComponentCandidate->pOMXStandComp);
                if (ret != OMX_ErrorNone)
                    goto EXIT;

                ret = addElementList(&pRMComponentList, pOMXComponent);
                if (ret != OMX_ErrorNone)
                    goto EXIT;
            }
        }
    } else {
        ret = addElementList(&pRMComponentList, pOMXComponent);
        if (ret != OMX_ErrorNone)
            goto EXIT;
    }

    ret = setRMList(pExynosComponent, gpRMList, pRMComponentList);
    if (ret != OMX_ErrorNone)
        goto EXIT;

    ret = OMX_ErrorNone;

EXIT:
    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent)
{
    OMX_ERRORTYPE                 ret = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
    OMX_COMPONENTTYPE            *pOMXWaitComponent = NULL;
    int numElem = 0;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;

    if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) {
        pComponentTemp = gpVideoDecRMWaitingList;
        if (gpVideoDecRMComponentList == NULL) {
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }

        ret = removeElementList(&gpVideoDecRMComponentList, pOMXComponent);
        if (ret != OMX_ErrorNone) {
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }
        while (pComponentTemp) {
            numElem++;
            pComponentTemp = pComponentTemp->pNext;
        }
        if (numElem > 0) {
            pOMXWaitComponent = gpVideoDecRMWaitingList->pOMXStandComp;
            removeElementList(&gpVideoDecRMWaitingList, pOMXWaitComponent);
            ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
            if (ret != OMX_ErrorNone) {
                goto EXIT;
            }
        }
    } else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) {
        pComponentTemp = gpVideoEncRMWaitingList;
        if (gpVideoEncRMComponentList == NULL) {
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }

        ret = removeElementList(&gpVideoEncRMComponentList, pOMXComponent);
        if (ret != OMX_ErrorNone) {
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }
        while (pComponentTemp) {
            numElem++;
            pComponentTemp = pComponentTemp->pNext;
        }
        if (numElem > 0) {
            pOMXWaitComponent = gpVideoEncRMWaitingList->pOMXStandComp;
            removeElementList(&gpVideoEncRMWaitingList, pOMXWaitComponent);
            ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL);
            if (ret != OMX_ErrorNone) {
                goto EXIT;
            }
        }
    }

EXIT:

    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    FunctionOut();

    return ret;
}
OMX_ERRORTYPE Exynos_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent)
{
    OMX_ERRORTYPE                 ret = OMX_ErrorNone;
    EXYNOS_OMX_BASECOMPONENT     *pExynosComponent = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
    EXYNOS_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL;
    int numElem = 0;
    int lowCompDetect = 0;

    FunctionIn();

    Exynos_OSAL_MutexLock(ghVideoRMComponentListMutex);

    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;

    if (pExynosComponent->codecType == HW_VIDEO_DEC_CODEC) {
        pComponentTemp = gpVideoDecRMComponentList;
        if (pComponentTemp != NULL) {
            while (pComponentTemp) {
                numElem++;
                pComponentTemp = pComponentTemp->pNext;
            }
        } else {
            numElem = 0;
        }
        if (numElem >= MAX_RESOURCE_VIDEO_DEC) {
            lowCompDetect = searchLowPriority(gpVideoDecRMComponentList, pExynosComponent->compPriority.nGroupPriority, &pComponentCandidate);
            if (lowCompDetect <= 0) {
                ret = OMX_ErrorInsufficientResources;
                goto EXIT;
            } else {
                ret = removeComponent(pComponentCandidate->pOMXStandComp);
                if (ret != OMX_ErrorNone) {
                    ret = OMX_ErrorInsufficientResources;
                    goto EXIT;
                } else {
                    ret = removeElementList(&gpVideoDecRMComponentList, pComponentCandidate->pOMXStandComp);
                    ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent);
                    if (ret != OMX_ErrorNone) {
                        ret = OMX_ErrorInsufficientResources;
                        goto EXIT;
                    }
                }
            }
        } else {
            ret = addElementList(&gpVideoDecRMComponentList, pOMXComponent);
            if (ret != OMX_ErrorNone) {
                ret = OMX_ErrorInsufficientResources;
                goto EXIT;
            }
        }
    } else if (pExynosComponent->codecType == HW_VIDEO_ENC_CODEC) {
        pComponentTemp = gpVideoEncRMComponentList;
        if (pComponentTemp != NULL) {
            while (pComponentTemp) {
                numElem++;
                pComponentTemp = pComponentTemp->pNext;
            }
        } else {
            numElem = 0;
        }
        if (numElem >= MAX_RESOURCE_VIDEO_ENC) {
            lowCompDetect = searchLowPriority(gpVideoEncRMComponentList, pExynosComponent->compPriority.nGroupPriority, &pComponentCandidate);
            if (lowCompDetect <= 0) {
                ret = OMX_ErrorInsufficientResources;
                goto EXIT;
            } else {
                ret = removeComponent(pComponentCandidate->pOMXStandComp);
                if (ret != OMX_ErrorNone) {
                    ret = OMX_ErrorInsufficientResources;
                    goto EXIT;
                } else {
                    ret = removeElementList(&gpVideoEncRMComponentList, pComponentCandidate->pOMXStandComp);
                    ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent);
                    if (ret != OMX_ErrorNone) {
                        ret = OMX_ErrorInsufficientResources;
                        goto EXIT;
                    }
                }
            }
        } else {
            ret = addElementList(&gpVideoEncRMComponentList, pOMXComponent);
            if (ret != OMX_ErrorNone) {
                ret = OMX_ErrorInsufficientResources;
                goto EXIT;
            }
        }
    }
    ret = OMX_ErrorNone;

EXIT:

    Exynos_OSAL_MutexUnlock(ghVideoRMComponentListMutex);

    FunctionOut();

    return ret;
}