blob: fb2875db0ceb3fd86ad9dcf43772da642b93f612 [file] [log] [blame]
/*
*
* 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_Core.c
* @brief SEC OpenMAX IL Core
* @author SeungBeom Kim (sbcrux.kim@samsung.com)
* HyeYeon Chung (hyeon.chung@samsung.com)
* Yunji Kim (yunji.kim@samsung.com)
* @version 1.0
* @history
* 2010.7.15 : Create
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h> // for pthread related functions
#include "SEC_OMX_Core.h"
#include "SEC_OSAL_Mutex.h" // for mutext related functions
#include "SEC_OSAL_ETC.h" // for SEC_OSAL_Strcmp, etc
#include "SEC_OMX_Component_Register.h"
#include "SEC_OSAL_Memory.h"
#include "SEC_OMX_Resourcemanager.h"
#undef SEC_LOG_TAG
#define SEC_LOG_TAG "SEC_OMX_CORE"
#define SEC_LOG_OFF
#include "SEC_OSAL_Log.h"
static int gInitialized = 0;
static OMX_U32 gComponentNum = 0;
static SEC_OMX_COMPONENT_REGLIST *gComponentList = NULL;
static SEC_OMX_COMPONENT *gLoadComponentList = NULL;
static pthread_mutex_t ghLoadComponentListMutex = PTHREAD_MUTEX_INITIALIZER;
OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
FunctionIn();
SEC_OSAL_MutexLock(&ghLoadComponentListMutex);
if (gInitialized == 0) {
if (SEC_OMX_Component_Register(&gComponentList, &gComponentNum)) {
ret = OMX_ErrorInsufficientResources;
SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : %s", "OMX_ErrorInsufficientResources");
goto EXIT;
}
SEC_OMX_ResourceManager_Init();
SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_Init : %s", "OMX_ErrorNone");
}
++gInitialized;
EXIT:
SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex);
FunctionOut();
return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
FunctionIn();
SEC_OSAL_MutexLock(&ghLoadComponentListMutex);
if (gInitialized > 0) {
--gInitialized;
}
if (gInitialized != 0) {
// Some component still uses the core.
// Nothing needs to be done
goto EXIT;
}
SEC_OMX_ResourceManager_Deinit();
if (OMX_ErrorNone != SEC_OMX_Component_Unregister(gComponentList)) {
ret = OMX_ErrorUndefined;
goto EXIT;
}
gComponentList = NULL;
gComponentNum = 0;
EXIT:
SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex);
FunctionOut();
return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum(
OMX_OUT OMX_STRING cComponentName,
OMX_IN OMX_U32 nNameLength,
OMX_IN OMX_U32 nIndex)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
FunctionIn();
if (nIndex >= gComponentNum) {
ret = OMX_ErrorNoMore;
goto EXIT;
}
sprintf(cComponentName, "%s", gComponentList[nIndex].component.componentName);
ret = OMX_ErrorNone;
EXIT:
FunctionOut();
return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_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;
SEC_OMX_COMPONENT *loadComponent;
SEC_OMX_COMPONENT *currentComponent;
FunctionIn();
if (gInitialized != 1) {
ret = OMX_ErrorNotReady;
goto EXIT;
}
if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
SEC_OSAL_Log(SEC_LOG_TRACE, "ComponentName : %s", cComponentName);
OMX_U32 i = 0;
for (i = 0; i < gComponentNum; i++) {
if (SEC_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) {
loadComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT));
SEC_OSAL_Memset(loadComponent, 0, sizeof(SEC_OMX_COMPONENT));
SEC_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName);
SEC_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName);
ret = SEC_OMX_ComponentLoad(loadComponent);
if (ret != OMX_ErrorNone) {
SEC_OSAL_Free(loadComponent);
SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
goto EXIT;
}
ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData);
if (ret != OMX_ErrorNone) {
SEC_OMX_ComponentUnload(loadComponent);
SEC_OSAL_Free(loadComponent);
SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
goto EXIT;
}
SEC_OSAL_MutexLock(&ghLoadComponentListMutex);
if (gLoadComponentList == NULL) {
gLoadComponentList = loadComponent;
} else {
currentComponent = gLoadComponentList;
while (currentComponent->nextOMXComp != NULL) {
currentComponent = currentComponent->nextOMXComp;
}
currentComponent->nextOMXComp = loadComponent;
}
SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex);
*pHandle = loadComponent->pOMXComponent;
ret = OMX_ErrorNone;
SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_GetHandle : %s", "OMX_ErrorNone");
goto EXIT;
}
}
ret = OMX_ErrorComponentNotFound;
EXIT:
FunctionOut();
return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)
{
OMX_ERRORTYPE ret = OMX_ErrorNone;
SEC_OMX_COMPONENT *currentComponent;
SEC_OMX_COMPONENT *deleteComponent;
FunctionIn();
if (gInitialized != 1) {
ret = OMX_ErrorNotReady;
goto EXIT;
}
if (!hComponent) {
ret = OMX_ErrorBadParameter;
goto EXIT;
}
SEC_OSAL_MutexLock(&ghLoadComponentListMutex);
currentComponent = gLoadComponentList;
if (gLoadComponentList->pOMXComponent == hComponent) {
deleteComponent = gLoadComponentList;
gLoadComponentList = gLoadComponentList->nextOMXComp;
} else {
while ((currentComponent != NULL) && (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent))
currentComponent = currentComponent->nextOMXComp;
if (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) {
deleteComponent = currentComponent->nextOMXComp;
currentComponent->nextOMXComp = deleteComponent->nextOMXComp;
} else if (currentComponent == NULL) {
ret = OMX_ErrorComponentNotFound;
goto EXIT;
}
}
SEC_OMX_ComponentUnload(deleteComponent);
SEC_OSAL_Free(deleteComponent);
EXIT:
SEC_OSAL_MutexUnlock(&ghLoadComponentListMutex);
FunctionOut();
return ret;
}
OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel(
OMX_IN OMX_HANDLETYPE hOutput,
OMX_IN OMX_U32 nPortOutput,
OMX_IN OMX_HANDLETYPE hInput,
OMX_IN OMX_U32 nPortInput)
{
OMX_ERRORTYPE ret = OMX_ErrorNotImplemented;
EXIT:
return ret;
}
OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe(
OMX_OUT OMX_HANDLETYPE *hPipe,
OMX_IN OMX_STRING szURI)
{
OMX_ERRORTYPE ret = OMX_ErrorNotImplemented;
EXIT:
return ret;
}
OMX_API OMX_ERRORTYPE SEC_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 (SEC_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) {
if (compNames != NULL) {
SEC_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName);
}
*pNumComps = (*pNumComps + 1);
}
}
}
EXIT:
FunctionOut();
return ret;
}
OMX_API OMX_ERRORTYPE SEC_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 (SEC_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++) {
SEC_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]);
}
}
EXIT:
FunctionOut();
return ret;
}