summaryrefslogtreecommitdiffstats
path: root/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c
diff options
context:
space:
mode:
Diffstat (limited to 'exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c')
-rw-r--r--exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c478
1 files changed, 478 insertions, 0 deletions
diff --git a/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c b/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c
new file mode 100644
index 0000000..6a2c979
--- /dev/null
+++ b/exynos/multimedia/openmax/component/common/SEC_OMX_Resourcemanager.c
@@ -0,0 +1,478 @@
+/*
+ *
+ * Copyright 2010 Samsung Electronics S.LSI Co. LTD
+ *
+ * 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.
+ */
+
+/*
+ * @file SEC_OMX_Resourcemanager.c
+ * @brief
+ * @author SeungBeom Kim (sbcrux.kim@samsung.com)
+ * @version 1.1.0
+ * @history
+ * 2010.7.15 : Create
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "SEC_OMX_Resourcemanager.h"
+#include "SEC_OMX_Basecomponent.h"
+#include "SEC_OSAL_Memory.h"
+#include "SEC_OSAL_Mutex.h"
+
+#undef SEC_LOG_TAG
+#define SEC_LOG_TAG "SEC_RM"
+#define SEC_LOG_OFF
+#include "SEC_OSAL_Log.h"
+
+
+#define MAX_RESOURCE_VIDEO_DEC 3 /* for Android */
+#define MAX_RESOURCE_VIDEO_ENC 1 /* for Android */
+
+/* Max allowable video scheduler component instance */
+static SEC_OMX_RM_COMPONENT_LIST *gpVideoDecRMComponentList = NULL;
+static SEC_OMX_RM_COMPONENT_LIST *gpVideoDecRMWaitingList = NULL;
+static SEC_OMX_RM_COMPONENT_LIST *gpVideoEncRMComponentList = NULL;
+static SEC_OMX_RM_COMPONENT_LIST *gpVideoEncRMWaitingList = NULL;
+static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL;
+
+
+OMX_ERRORTYPE addElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL;
+ SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
+
+ pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ if (*ppList != NULL) {
+ pTempComp = *ppList;
+ while (pTempComp->pNext != NULL) {
+ pTempComp = pTempComp->pNext;
+ }
+ pTempComp->pNext = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST));
+ if (pTempComp->pNext == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL;
+ ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent;
+ ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pSECComponent->compPriority.nGroupPriority;
+ goto EXIT;
+ } else {
+ *ppList = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST));
+ if (*ppList == NULL) {
+ ret = OMX_ErrorInsufficientResources;
+ goto EXIT;
+ }
+ pTempComp = *ppList;
+ pTempComp->pNext = NULL;
+ pTempComp->pOMXStandComp = pOMXComponent;
+ pTempComp->groupPriority = pSECComponent->compPriority.nGroupPriority;
+ }
+
+EXIT:
+ return ret;
+}
+
+OMX_ERRORTYPE removeElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_RM_COMPONENT_LIST *pCurrComp = NULL;
+ SEC_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;
+ SEC_OSAL_Free(pCurrComp);
+ } else {
+ if (pPrevComp != NULL)
+ pPrevComp->pNext = pCurrComp->pNext;
+
+ SEC_OSAL_Free(pCurrComp);
+ }
+ bDetectComp = OMX_TRUE;
+ break;
+ } else {
+ pPrevComp = pCurrComp;
+ pCurrComp = pCurrComp->pNext;
+ }
+ }
+
+ if (bDetectComp == OMX_FALSE)
+ ret = OMX_ErrorComponentNotFound;
+ else
+ ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+
+int searchLowPriority(SEC_OMX_RM_COMPONENT_LIST *RMComp_list, OMX_U32 inComp_priority, SEC_OMX_RM_COMPONENT_LIST **outLowComp)
+{
+ int ret = 0;
+ SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL;
+ SEC_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL;
+
+ if (RMComp_list == NULL)
+ ret = -1;
+
+ pTempComp = RMComp_list;
+ *outLowComp = 0;
+
+ while (pTempComp != NULL) {
+ if (pTempComp->groupPriority > inComp_priority) {
+ if (pCandidateComp != NULL) {
+ if (pCandidateComp->groupPriority < pTempComp->groupPriority)
+ pCandidateComp = pTempComp;
+ } else {
+ pCandidateComp = pTempComp;
+ }
+ }
+
+ pTempComp = pTempComp->pNext;
+ }
+
+ *outLowComp = pCandidateComp;
+ if (pCandidateComp == NULL)
+ ret = 0;
+ else
+ ret = 1;
+
+EXIT:
+ return ret;
+}
+
+OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
+
+ pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ if (pSECComponent->currentState == OMX_StateIdle) {
+ (*(pSECComponent->pCallbacks->EventHandler))
+ (pOMXComponent, pSECComponent->callbackData,
+ OMX_EventError, OMX_ErrorResourcesLost, 0, NULL);
+ ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL);
+ if (ret != OMX_ErrorNone) {
+ ret = OMX_ErrorUndefined;
+ goto EXIT;
+ }
+ } else if ((pSECComponent->currentState == OMX_StateExecuting) || (pSECComponent->currentState == OMX_StatePause)) {
+ /* Todo */
+ }
+
+ ret = OMX_ErrorNone;
+
+EXIT:
+ return ret;
+}
+
+
+OMX_ERRORTYPE SEC_OMX_ResourceManager_Init()
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ FunctionIn();
+ ret = SEC_OSAL_MutexCreate(&ghVideoRMComponentListMutex);
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit()
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_RM_COMPONENT_LIST *pCurrComponent;
+ SEC_OMX_RM_COMPONENT_LIST *pNextComponent;
+
+ FunctionIn();
+
+ SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+ if (gpVideoDecRMComponentList) {
+ pCurrComponent = gpVideoDecRMComponentList;
+ while (pCurrComponent != NULL) {
+ pNextComponent = pCurrComponent->pNext;
+ SEC_OSAL_Free(pCurrComponent);
+ pCurrComponent = pNextComponent;
+ }
+ gpVideoDecRMComponentList = NULL;
+ }
+ if (gpVideoDecRMWaitingList) {
+ pCurrComponent = gpVideoDecRMWaitingList;
+ while (pCurrComponent != NULL) {
+ pNextComponent = pCurrComponent->pNext;
+ SEC_OSAL_Free(pCurrComponent);
+ pCurrComponent = pNextComponent;
+ }
+ gpVideoDecRMWaitingList = NULL;
+ }
+
+ if (gpVideoEncRMComponentList) {
+ pCurrComponent = gpVideoEncRMComponentList;
+ while (pCurrComponent != NULL) {
+ pNextComponent = pCurrComponent->pNext;
+ SEC_OSAL_Free(pCurrComponent);
+ pCurrComponent = pNextComponent;
+ }
+ gpVideoEncRMComponentList = NULL;
+ }
+ if (gpVideoEncRMWaitingList) {
+ pCurrComponent = gpVideoEncRMWaitingList;
+ while (pCurrComponent != NULL) {
+ pNextComponent = pCurrComponent->pNext;
+ SEC_OSAL_Free(pCurrComponent);
+ pCurrComponent = pNextComponent;
+ }
+ gpVideoEncRMWaitingList = NULL;
+ }
+
+ SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+ SEC_OSAL_MutexTerminate(ghVideoRMComponentListMutex);
+ ghVideoRMComponentListMutex = NULL;
+
+ ret = OMX_ErrorNone;
+EXIT:
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
+ SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
+ SEC_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL;
+ int numElem = 0;
+ int lowCompDetect = 0;
+
+ FunctionIn();
+
+ SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+ pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ if (pSECComponent->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, pSECComponent->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 (pSECComponent->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, pSECComponent->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:
+
+ SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
+ SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL;
+ OMX_COMPONENTTYPE *pOMXWaitComponent = NULL;
+ int numElem = 0;
+
+ FunctionIn();
+
+ SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+ pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+
+ if (pSECComponent->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 (pSECComponent->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:
+
+ SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
+
+ FunctionIn();
+
+ SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+ pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC)
+ ret = addElementList(&gpVideoDecRMWaitingList, pOMXComponent);
+ else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC)
+ ret = addElementList(&gpVideoEncRMWaitingList, pOMXComponent);
+
+ SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+ FunctionOut();
+
+ return ret;
+}
+
+OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
+
+ FunctionIn();
+
+ SEC_OSAL_MutexLock(ghVideoRMComponentListMutex);
+
+ pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
+ if (pSECComponent->codecType == HW_VIDEO_DEC_CODEC)
+ ret = removeElementList(&gpVideoDecRMWaitingList, pOMXComponent);
+ else if (pSECComponent->codecType == HW_VIDEO_ENC_CODEC)
+ ret = removeElementList(&gpVideoEncRMWaitingList, pOMXComponent);
+
+ SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex);
+
+ FunctionOut();
+
+ return ret;
+}
+