summaryrefslogtreecommitdiffstats
path: root/domx/omx_core/src/OMX_Core.c
diff options
context:
space:
mode:
Diffstat (limited to 'domx/omx_core/src/OMX_Core.c')
-rwxr-xr-xdomx/omx_core/src/OMX_Core.c953
1 files changed, 953 insertions, 0 deletions
diff --git a/domx/omx_core/src/OMX_Core.c b/domx/omx_core/src/OMX_Core.c
new file mode 100755
index 0000000..8d9b529
--- /dev/null
+++ b/domx/omx_core/src/OMX_Core.c
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2010, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dlfcn.h> /* For dynamic loading */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+
+/* #include "OMX_RegLib.h" */
+#include "OMX_Component.h"
+#include "OMX_Core.h"
+#include "OMX_ComponentRegistry.h"
+
+#include "timm_osal_types.h"
+#include "timm_osal_error.h"
+#include "timm_osal_trace.h"
+#include "timm_osal_mutex.h"
+
+#ifdef CHECK_SECURE_STATE
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#endif
+
+/** size for the array of allocated components. Sets the maximum
+ * number of components that can be allocated at once */
+#define MAXCOMP (50)
+#define MAXNAMESIZE (128)
+#define EMPTY_STRING "\0"
+
+/** Determine the number of elements in an array */
+#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
+
+/** Array to hold the DLL pointers for each allocated component */
+static void *pModules[MAXCOMP] = { 0 };
+
+/** Array to hold the component handles for each allocated component */
+static void *pComponents[COUNTOF(pModules)] = { 0 };
+
+/* count for call OMX_Init() */
+int count = 0;
+pthread_mutex_t mutex;
+TIMM_OSAL_PTR pCoreInitMutex = NULL;
+
+int tableCount = 0;
+ComponentTable componentTable[MAX_TABLE_SIZE];
+char *sRoleArray[60][20];
+char compName[60][200];
+
+
+char *tComponentName[MAXCOMP][MAX_ROLES] = {
+ /*video and image components */
+ {"OMX.TI.DUCATI1.VIDEO.DECODER",
+ "video_decoder.mpeg4",
+ "video_decoder.avc",
+ "video_decoder.h263",
+ "video_decoder.wmv",
+ "video_decoder.mpeg2",
+ "video_decoder.svc",
+ "video_decoder.sorspk", NULL},
+ {"OMX.TI.DUCATI1.VIDEO.DECODER.secure",
+ "video_decoder.mpeg4",
+ "video_decoder.avc",
+ "video_decoder.h263", NULL},
+ {"OMX.TI.DUCATI1.VIDEO.H264E",
+ "video_encoder.avc", NULL},
+ {"OMX.TI.DUCATI1.VIDEO.MPEG4E",
+ "video_encoder.mpeg4",
+ "video_encoder.h263",NULL},
+ {"OMX.TI.DUCATI1.VIDEO.CAMERA", "camera.omx", NULL},
+#ifdef USE_ITTIAM_AAC
+ {"OMX.ITTIAM.AAC.decode", "audio_decoder.aac", NULL},
+ {"OMX.ITTIAM.BSAC.decode", "audio_decoder.aac", NULL},
+#endif
+ {"OMX.ITTIAM.WMA.decode", "audio_decoder.wma", NULL},
+ {"OMX.ITTIAM.WMALSL.decode", "audio_decoder.wmalsl", NULL},
+ {"OMX.ITTIAM.WMAPRO.decode", "audio_decoder.wmapro", NULL},
+ /* terminate the table */
+ {NULL, NULL},
+};
+
+//AD
+extern OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComponent);
+
+#define CORE_assert CORE_paramCheck
+#define CORE_require CORE_paramCheck
+#define CORE_ensure CORE_paramCheck
+
+#define CORE_paramCheck(C, V, S) do {\
+ if (!(C)) { eError = V;\
+ TIMM_OSAL_Error("failed check: " #C);\
+ TIMM_OSAL_Error(" - returning error: " #V);\
+ if(S) TIMM_OSAL_Error(" - %s", S);\
+ goto EXIT; }\
+ } while(0)
+
+/******************************Public*Routine******************************\
+* OMX_Init()
+*
+* Description:This method will initialize the OMX Core. It is the
+* responsibility of the application to call OMX_Init to ensure the proper
+* set up of core resources.
+*
+* Returns: OMX_NOERROR Successful
+*
+* Note
+*
+\**************************************************************************/
+OMX_ERRORTYPE OMX_Init()
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE;
+
+ eOsalError = TIMM_OSAL_MutexObtain(pCoreInitMutex, TIMM_OSAL_SUSPEND);
+ CORE_assert(eOsalError == TIMM_OSAL_ERR_NONE,
+ OMX_ErrorInsufficientResources, "Mutex lock failed");
+
+ count++;
+
+ if (count == 1)
+ {
+ pthread_mutex_init(&mutex, NULL);
+ eError = OMX_BuildComponentTable();
+ }
+
+ eOsalError = TIMM_OSAL_MutexRelease(pCoreInitMutex);
+ CORE_assert(eOsalError == TIMM_OSAL_ERR_NONE,
+ OMX_ErrorInsufficientResources, "Mutex release failed");
+ EXIT:
+ return eError;
+}
+
+/******************************Public*Routine******************************\
+* OMX_GetHandle
+*
+* Description: This method will create the handle of the COMPONENTTYPE
+* If the component is currently loaded, this method will reutrn the
+* hadle of existingcomponent or create a new instance of the component.
+* It will call the OMX_ComponentInit function and then the setcallback
+* method to initialize the callback functions
+* Parameters:
+* @param[out] pHandle Handle of the loaded components
+* @param[in] cComponentName Name of the component to load
+* @param[in] pAppData Used to identify the callbacks of component
+* @param[in] pCallBacks Application callbacks
+*
+* @retval OMX_ErrorUndefined
+* @retval OMX_ErrorInvalidComponentName
+* @retval OMX_ErrorInvalidComponent
+* @retval OMX_ErrorInsufficientResources
+* @retval OMX_NOERROR Successful
+*
+* Note
+*
+\**************************************************************************/
+
+OMX_ERRORTYPE OMX_GetHandle(OMX_HANDLETYPE * pHandle,
+ OMX_STRING cComponentName, OMX_PTR pAppData,
+ OMX_CALLBACKTYPE * pCallBacks)
+{
+ static const char prefix[] = "lib";
+ static const char postfix[] = ".so";
+ OMX_ERRORTYPE(*pComponentInit) (OMX_HANDLETYPE *);
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_COMPONENTTYPE *componentType;
+ int i;
+ char buf[sizeof(prefix) + MAXNAMESIZE + sizeof(postfix)];
+ const char *pErr = dlerror();
+ char *dlError = NULL;
+#ifdef CHECK_SECURE_STATE
+ int secure_misc_drv_fd,ret;
+ OMX_U8 mode, enable=1;
+#endif
+ if (pthread_mutex_lock(&mutex) != 0)
+ {
+ TIMM_OSAL_Error("Core: Error in Mutex lock");
+ }
+
+ CORE_require(NULL != cComponentName, OMX_ErrorBadParameter, NULL);
+ CORE_require(NULL != pHandle, OMX_ErrorBadParameter, NULL);
+ CORE_require(NULL != pCallBacks, OMX_ErrorBadParameter, NULL);
+ CORE_require(count > 0, OMX_ErrorUndefined,
+ "OMX_GetHandle called without calling OMX_Init first");
+
+ /* Verify that the name is not too long and could cause a crash. Notice
+ * that the comparison is a greater than or equals. This is to make
+ * sure that there is room for the terminating NULL at the end of the
+ * name. */
+ CORE_require(strlen(cComponentName) < MAXNAMESIZE,
+ OMX_ErrorInvalidComponentName, NULL);
+
+ /* Locate the first empty slot for a component. If no slots
+ * are available, error out */
+ for (i = 0; i < (int)COUNTOF(pModules); i++)
+ {
+ if (pModules[i] == NULL)
+ break;
+ }
+ CORE_assert(i != COUNTOF(pModules), OMX_ErrorInsufficientResources,
+ NULL);
+
+ /* load the component and check for an error. If filename is not an
+ * absolute path (i.e., it does not begin with a "/"), then the
+ * file is searched for in the following locations:
+ *
+ * The LD_LIBRARY_PATH environment variable locations
+ * The library cache, /etc/ld.so.cache.
+ * /lib
+ * /usr/lib
+ *
+ * If there is an error, we can't go on, so set the error code and exit */
+ strcpy(buf, prefix); /* the lengths are defined herein or have been */
+ strcat(buf, cComponentName); /* checked already, so strcpy and strcat are */
+ strcat(buf, postfix); /* are safe to use in this context. */
+
+#ifdef CHECK_SECURE_STATE
+ //Dont return errors from misc driver to the user if any.
+ //Since this affects all usecases, secure and non-secure.
+ //Do log the errors though.
+ secure_misc_drv_fd = open("/dev/rproc_user", O_SYNC | O_RDONLY);
+ if (secure_misc_drv_fd < 0)
+ {
+ TIMM_OSAL_Error("Can't open misc driver device 0x%x\n", errno);
+ }
+ else
+ {
+ ret = read(secure_misc_drv_fd, &mode, sizeof(mode));
+ if (ret != sizeof(mode))
+ {
+ TIMM_OSAL_Error("Can't read from the misc driver");
+ }
+ else
+ {
+ if(mode == enable && strstr(cComponentName,"secure") == NULL)
+ {
+ TIMM_OSAL_Error("non-secure component not supported in secure mode");
+ eError = OMX_ErrorComponentNotFound;
+ }
+ }
+ ret = close(secure_misc_drv_fd);
+ if (ret < 0)
+ {
+ TIMM_OSAL_Error("Can't close the misc driver");
+ }
+ }
+ /* Don't allow non-secure usecases if we are in secure state.
+ * Else some of the memory regions will be unexpected firewalled.
+ * This provides a clean exit in case we are in secure mode. */
+ if (eError == OMX_ErrorComponentNotFound)
+ {
+ goto EXIT;
+ }
+#endif //CHECK_SECURE_STATE
+
+
+//#if 0
+ pModules[i] = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
+ if (pModules[i] == NULL)
+ {
+ dlError = (char *)dlerror();
+ TIMM_OSAL_Error("Failed because %s", dlError);
+ eError = OMX_ErrorComponentNotFound;
+ goto EXIT;
+ }
+
+ /* Get a function pointer to the "OMX_ComponentInit" function. If
+ * there is an error, we can't go on, so set the error code and exit */
+ pComponentInit = dlsym(pModules[i], "OMX_ComponentInit");
+ pErr = dlerror();
+ CORE_assert(((pErr == NULL) && (pComponentInit != NULL)),
+ OMX_ErrorInvalidComponent, NULL);
+//#endif
+
+ /* We now can access the dll. So, we need to call the "OMX_ComponentInit"
+ * method to load up the "handle" (which is just a list of functions to
+ * call) and we should be all set.*/
+ *pHandle = malloc(sizeof(OMX_COMPONENTTYPE));
+ CORE_assert((*pHandle != NULL), OMX_ErrorInsufficientResources,
+ "Malloc of pHandle* failed");
+
+ pComponents[i] = *pHandle;
+ componentType = (OMX_COMPONENTTYPE *) * pHandle;
+ componentType->nSize = sizeof(OMX_COMPONENTTYPE);
+
+ componentType->nVersion.s.nVersionMajor = 1;
+ componentType->nVersion.s.nVersionMinor = 1;
+ componentType->nVersion.s.nRevision = 0;
+ componentType->nVersion.s.nStep = 0;
+
+ eError = (*pComponentInit) (*pHandle);
+//eError = OMX_ComponentInit(*pHandle);
+ if (OMX_ErrorNone == eError)
+ {
+ eError =
+ (componentType->SetCallbacks) (*pHandle, pCallBacks,
+ pAppData);
+ CORE_assert(eError == OMX_ErrorNone, eError,
+ "Core: Error returned from component SetCallBack");
+ } else
+ {
+ /* when the component fails to initialize, release the
+ component handle structure */
+ free(*pHandle);
+ /* mark the component handle as NULL to prevent the caller from
+ actually trying to access the component with it, should they
+ ignore the return code */
+ *pHandle = NULL;
+ pComponents[i] = NULL;
+ dlclose(pModules[i]);
+ goto EXIT;
+ }
+ eError = OMX_ErrorNone;
+ EXIT:
+ if (pthread_mutex_unlock(&mutex) != 0)
+ {
+ TIMM_OSAL_Error("Core: Error in Mutex unlock");
+ }
+ return (eError);
+}
+
+
+/******************************Public*Routine******************************\
+* OMX_FreeHandle()
+*
+* Description:This method will unload the OMX component pointed by
+* OMX_HANDLETYPE. It is the responsibility of the calling method to ensure that
+* the Deinit method of the component has been called prior to unloading component
+*
+* Parameters:
+* @param[in] hComponent the component to unload
+*
+* Returns: OMX_NOERROR Successful
+*
+* Note
+*
+\**************************************************************************/
+OMX_ERRORTYPE OMX_FreeHandle(OMX_HANDLETYPE hComponent)
+{
+
+ OMX_ERRORTYPE eError = OMX_ErrorUndefined;
+ OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *) hComponent;
+ int i;
+
+ if (pthread_mutex_lock(&mutex) != 0)
+ {
+ TIMM_OSAL_Error("Core: Error in Mutex lock");
+ }
+
+ CORE_require(pHandle != NULL, OMX_ErrorBadParameter, NULL);
+ CORE_require(count > 0, OMX_ErrorUndefined,
+ "OMX_FreeHandle called without calling OMX_Init first");
+
+ /* Locate the component handle in the array of handles */
+ for (i = 0; i < (int)COUNTOF(pModules); i++)
+ {
+ if (pComponents[i] == hComponent)
+ break;
+ }
+
+ CORE_assert(i != COUNTOF(pModules), OMX_ErrorBadParameter, NULL);
+
+ eError = pHandle->ComponentDeInit(hComponent);
+ if (eError != OMX_ErrorNone)
+ {
+ TIMM_OSAL_Error("Error From ComponentDeInit..");
+ }
+
+ /* release the component and the component handle */
+ dlclose(pModules[i]);
+ pModules[i] = NULL;
+ free(pComponents[i]);
+
+ pComponents[i] = NULL;
+ eError = OMX_ErrorNone;
+
+ EXIT:
+ /* The unload is now complete, so set the error code to pass and exit */
+ if (pthread_mutex_unlock(&mutex) != 0)
+ {
+ TIMM_OSAL_Error("Core: Error in Mutex unlock");
+ }
+
+ return eError;
+}
+
+/******************************Public*Routine******************************\
+* OMX_DeInit()
+*
+* Description:This method will release the resources of the OMX Core. It is the
+* responsibility of the application to call OMX_DeInit to ensure the clean up of these
+* resources.
+*
+* Returns: OMX_NOERROR Successful
+*
+* Note
+*
+\**************************************************************************/
+OMX_ERRORTYPE OMX_Deinit()
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ TIMM_OSAL_ERRORTYPE eOsalError = TIMM_OSAL_ERR_NONE;
+
+ eOsalError = TIMM_OSAL_MutexObtain(pCoreInitMutex, TIMM_OSAL_SUSPEND);
+ if (eOsalError != TIMM_OSAL_ERR_NONE)
+ {
+ TIMM_OSAL_Error("Mutex lock failed");
+ }
+ /*Returning error none because of OMX spec limitation on error codes that
+ can be returned by OMX_Deinit */
+ CORE_assert(count > 0, OMX_ErrorNone,
+ "OMX_Deinit being called without a corresponding OMX_Init");
+ count--;
+
+ if (pthread_mutex_lock(&mutex) != 0)
+ TIMM_OSAL_Error("Core: Error in Mutex lock");
+
+ if (count == 0)
+ {
+ if (pthread_mutex_unlock(&mutex) != 0)
+ TIMM_OSAL_Error("Core: Error in Mutex unlock");
+ if (pthread_mutex_destroy(&mutex) != 0)
+ {
+ /*printf("%d :: Core: Error in Mutex destroy\n",__LINE__); */
+ }
+ } else
+ {
+ if (pthread_mutex_unlock(&mutex) != 0)
+ TIMM_OSAL_Error("Core: Error in Mutex unlock");
+ }
+
+ EXIT:
+ eOsalError = TIMM_OSAL_MutexRelease(pCoreInitMutex);
+ if (eOsalError != TIMM_OSAL_ERR_NONE)
+ {
+ TIMM_OSAL_Error("Mutex release failed");
+ }
+ return eError;
+}
+
+/*************************************************************************
+* OMX_SetupTunnel()
+*
+* Description: Setup the specified tunnel the two components
+*
+* Parameters:
+* @param[in] hOutput Handle of the component to be accessed
+* @param[in] nPortOutput Source port used in the tunnel
+* @param[in] hInput Component to setup the tunnel with.
+* @param[in] nPortInput Destination port used in the tunnel
+*
+* Returns: OMX_NOERROR Successful
+*
+* Note
+*
+**************************************************************************/
+/* OMX_SetupTunnel */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE
+ hOutput, OMX_IN OMX_U32 nPortOutput, OMX_IN OMX_HANDLETYPE hInput,
+ OMX_IN OMX_U32 nPortInput)
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNotImplemented;
+ OMX_COMPONENTTYPE *pCompIn, *pCompOut;
+ OMX_TUNNELSETUPTYPE oTunnelSetup;
+
+ if (hOutput == NULL && hInput == NULL)
+ return OMX_ErrorBadParameter;
+
+ oTunnelSetup.nTunnelFlags = 0;
+ oTunnelSetup.eSupplier = OMX_BufferSupplyUnspecified;
+
+ pCompOut = (OMX_COMPONENTTYPE *) hOutput;
+
+ if (hOutput)
+ {
+ eError =
+ pCompOut->ComponentTunnelRequest(hOutput, nPortOutput,
+ hInput, nPortInput, &oTunnelSetup);
+ }
+
+
+ if (eError == OMX_ErrorNone && hInput)
+ {
+ pCompIn = (OMX_COMPONENTTYPE *) hInput;
+ eError =
+ pCompIn->ComponentTunnelRequest(hInput, nPortInput,
+ hOutput, nPortOutput, &oTunnelSetup);
+ if (eError != OMX_ErrorNone && hOutput)
+ {
+ /* cancel tunnel request on output port since input port failed */
+ pCompOut->ComponentTunnelRequest(hOutput, nPortOutput,
+ NULL, 0, NULL);
+ }
+ }
+
+ return eError;
+}
+
+/*************************************************************************
+* OMX_ComponentNameEnum()
+*
+* Description: This method will provide the name of the component at the given nIndex
+*
+*Parameters:
+* @param[out] cComponentName The name of the component at nIndex
+* @param[in] nNameLength The length of the component name
+* @param[in] nIndex The index number of the component
+*
+* Returns: OMX_NOERROR Successful
+*
+* Note
+*
+**************************************************************************/
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(OMX_OUT OMX_STRING
+ cComponentName, OMX_IN OMX_U32 nNameLength, OMX_IN OMX_U32 nIndex)
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+
+ CORE_require(cComponentName != NULL, OMX_ErrorBadParameter, NULL);
+ CORE_require(count > 0, OMX_ErrorUndefined,
+ "OMX_GetHandle called without calling OMX_Init first");
+
+ if (nIndex >= (OMX_U32)tableCount)
+ {
+ eError = OMX_ErrorNoMore;
+ } else
+ {
+ strcpy(cComponentName, componentTable[nIndex].name);
+ }
+ EXIT:
+ return eError;
+}
+
+
+/*************************************************************************
+* OMX_GetRolesOfComponent()
+*
+* Description: This method will query the component for its supported roles
+*
+*Parameters:
+* @param[in] cComponentName The name of the component to query
+* @param[in] pNumRoles The number of roles supported by the component
+* @param[in] roles The roles of the component
+*
+* Returns: OMX_NOERROR Successful
+* OMX_ErrorBadParameter Faliure due to a bad input parameter
+*
+* Note
+*
+**************************************************************************/
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent(OMX_IN OMX_STRING
+ cComponentName, OMX_INOUT OMX_U32 * pNumRoles, OMX_OUT OMX_U8 ** roles)
+{
+
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_U32 i = 0;
+ OMX_U32 j = 0;
+ OMX_BOOL bFound = OMX_FALSE;
+
+ CORE_require(cComponentName != NULL, OMX_ErrorBadParameter, NULL);
+ CORE_require(pNumRoles != NULL, OMX_ErrorBadParameter, NULL);
+ CORE_require(strlen(cComponentName) < MAXNAMESIZE,
+ OMX_ErrorInvalidComponentName, NULL);
+ CORE_require(count > 0, OMX_ErrorUndefined,
+ "OMX_GetHandle called without calling OMX_Init first");
+
+ while (!bFound && i < (OMX_U32)tableCount)
+ {
+ if (strcmp(cComponentName, componentTable[i].name) == 0)
+ {
+ bFound = OMX_TRUE;
+ } else
+ {
+ i++;
+ }
+ }
+ if (roles == NULL)
+ {
+ *pNumRoles = componentTable[i].nRoles;
+ goto EXIT;
+ } else
+ {
+ if (bFound && (*pNumRoles == componentTable[i].nRoles))
+ {
+ for (j = 0; j < componentTable[i].nRoles; j++)
+ {
+ strcpy((OMX_STRING) roles[j],
+ componentTable[i].pRoleArray[j]);
+ }
+ }
+ }
+ EXIT:
+ return eError;
+}
+
+/*************************************************************************
+* OMX_GetComponentsOfRole()
+*
+* Description: This method will query the component for its supported roles
+*
+*Parameters:
+* @param[in] role The role name to query for
+* @param[in] pNumComps The number of components supporting the given role
+* @param[in] compNames The names of the components supporting the given role
+*
+* Returns: OMX_NOERROR Successful
+*
+* Note
+*
+**************************************************************************/
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole(OMX_IN OMX_STRING role,
+ OMX_INOUT OMX_U32 * pNumComps, OMX_INOUT OMX_U8 ** compNames)
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_U32 i = 0;
+ OMX_U32 j = 0;
+ OMX_U32 k = 0;
+
+ CORE_require(role != NULL, OMX_ErrorBadParameter, NULL);
+ CORE_require(pNumComps != NULL, OMX_ErrorBadParameter, NULL);
+ CORE_require(count > 0, OMX_ErrorUndefined,
+ "OMX_GetHandle called without calling OMX_Init first");
+
+ /* This implies that the componentTable is not filled */
+ CORE_assert(componentTable[i].pRoleArray[j] != NULL,
+ OMX_ErrorBadParameter, NULL);
+
+ for (i = 0; i < (OMX_U32)tableCount; i++)
+ {
+ for (j = 0; j < componentTable[i].nRoles; j++)
+ {
+ if (strcmp(componentTable[i].pRoleArray[j],
+ role) == 0)
+ {
+ /* the first call to this function should only count the number
+ of roles so that for the second call compNames can be allocated
+ with the proper size for that number of roles */
+ if (compNames != NULL)
+ {
+ strncpy((OMX_STRING) (compNames[k]),
+ (OMX_STRING) componentTable[i].
+ name, MAXNAMESIZE);
+ }
+ k++;
+ }
+ }
+ *pNumComps = k;
+ }
+
+ EXIT:
+ return eError;
+}
+
+
+/***************************************
+PRINT TABLE FOR DEBUGGING PURPOSES ONLY
+***************************************/
+
+OMX_API OMX_ERRORTYPE OMX_PrintComponentTable()
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ int i = 0;
+ int j = 0;
+
+ TIMM_OSAL_Info
+ ("--------Component Table:: %d Components found-------------",
+ tableCount);
+
+ for (i = 0; i < tableCount; i++)
+ {
+ TIMM_OSAL_Info("%i:: %s", i, componentTable[i].name);
+ for (j = 0; j < componentTable[i].nRoles; j++)
+ {
+ TIMM_OSAL_Info(" %s",
+ componentTable[i].pRoleArray[j]);
+ }
+ }
+
+ TIMM_OSAL_Info
+ ("-----------------End Component Table ------------------");
+
+ return eError;
+
+}
+
+
+OMX_ERRORTYPE OMX_BuildComponentTable()
+{
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+ OMX_CALLBACKTYPE sCallbacks;
+#ifndef STATIC_TABLE
+ OMX_HANDLETYPE hComp = 0;
+ OMX_U8 cRole[MAXNAMESIZE];
+ OMX_STRING tempName = NULL;
+ OMX_STRING temp = NULL;
+ static OMX_STRING namePrefix = "OMX";
+ static OMX_STRING filePrefix = "libOMX.";
+ static OMX_STRING suffix = ".so";
+#endif
+ int j = 0;
+ int numFiles = 0;
+ int i, k;
+ int componentfound = 0;
+
+ /* set up dummy call backs */
+ sCallbacks.EventHandler = ComponentTable_EventHandler;
+ sCallbacks.EmptyBufferDone = ComponentTable_EmptyBufferDone;
+ sCallbacks.FillBufferDone = ComponentTable_FillBufferDone;
+
+#ifndef STATIC_TABLE
+ /* allocate the name table */
+ /*
+ compName = (OMX_STRING *) malloc(MAX_TABLE_SIZE * sizeof(OMX_STRING));
+ sRoleArray = (OMX_STRING**) malloc(MAX_TABLE_SIZE * sizeof(OMX_STRING));
+ */
+
+ /* scan the target/lib directory and create a list of files in the directory */
+ numFiles = scandir(libdir, &namelist, 0, 0);
+ tableCount = 0;
+ while (numFiles--)
+ {
+ /* check if the file is an OMX component */
+ if (strncmp(namelist[numFiles]->d_name, filePrefix,
+ strlen(filePrefix)) == 0)
+ {
+
+ /* if the file is an OMX component, trim the prefix and suffix */
+ tempName = (OMX_STRING) malloc(sizeof(namelist[numFiles]->d_name) + 1); /* adding one ensures */
+ memset(tempName, 0x00, sizeof(namelist[numFiles]->d_name) + 1); /* that a null terminator will */
+ /* always be present */
+ /* copy only the name without the suffix */
+ strncpy(tempName, namelist[numFiles]->d_name,
+ strlen(namelist[numFiles]->d_name) -
+ strlen(suffix));
+ /* set a pointer to be after the lib prefix, i.e the beginning of the component name */
+ temp = strstr(tempName, namePrefix);
+
+ /* then copy the component name to the table */
+ /*
+ compName[tableCount]= (OMX_STRING) malloc(MAXNAMESIZE);
+ */
+ strncpy(compName[tableCount], temp, strlen(temp) + 1);
+ componentTable[tableCount].name =
+ compName[tableCount];
+
+ /* get the handle for the component and query for the roles of each component */
+ eError =
+ OMX_GetHandle(&hComp,
+ componentTable[tableCount].name, 0x0,
+ &sCallbacks);
+ if (eError == OMX_ErrorNone)
+ {
+ j = 0;
+ while (eError != OMX_ErrorNoMore)
+ {
+ eError =
+ ((OMX_COMPONENTTYPE *) hComp)->
+ ComponentRoleEnum(hComp, cRole,
+ j++);
+ if (eError == OMX_ErrorNotImplemented)
+ {
+ j = 1;
+ break;
+ }
+ }
+ nRoles = j - 1;
+ componentTable[tableCount].nRoles = nRoles;
+ /* sRoleArray[tableCount] = (OMX_STRING *) malloc(nRoles * sizeof(OMX_STRING)); */
+ if (nRoles > 0)
+ {
+ /* sRoleArray[tableCount] = (OMX_STRING *) malloc(nRoles * sizeof(OMX_STRING)); */
+ for (j = 0; j < nRoles; j++)
+ {
+ sRoleArray[tableCount][j] =
+ (OMX_STRING)
+ malloc(sizeof(OMX_U8) *
+ MAXNAMESIZE);
+ ((OMX_COMPONENTTYPE *)
+ hComp)->
+ ComponentRoleEnum(hComp,
+ (OMX_U8 *)
+ sRoleArray[tableCount][j],
+ j);
+ componentTable[tableCount].
+ pRoleArray[j] =
+ sRoleArray[tableCount][j];
+ }
+ } else
+ {
+ /* sRoleArray[tableCount] = (OMX_STRING *) malloc(sizeof(OMX_STRING)); */
+ sRoleArray[tableCount][j] =
+ (OMX_STRING) malloc(sizeof(OMX_U8)
+ * MAXNAMESIZE);
+ strcpy(sRoleArray[tableCount][j],
+ EMPTY_STRING);
+ componentTable[tableCount].
+ pRoleArray[j] =
+ sRoleArray[tableCount][j];
+ }
+ }
+ if (hComp)
+ {
+ /* free the component handle */
+ eError = OMX_FreeHandle(hComp);
+ if (eError != OMX_ErrorNone)
+ {
+ goto EXIT;
+ }
+ }
+ /* increment the table counter index only if above was successful */
+ tableCount++;
+ if (tempName != NULL)
+ {
+ free(tempName);
+ }
+
+ }
+ }
+
+#endif
+
+ for (i = 0, numFiles = 0; i < MAXCOMP; i++)
+ {
+ if (tComponentName[i][0] == NULL)
+ {
+ break;
+ }
+
+ for (j = 0; j < numFiles; j++)
+ {
+ if (!strcmp(componentTable[j].name,
+ tComponentName[i][0]))
+ {
+ componentfound = 1;
+ break;
+ }
+ }
+ if (componentfound == 1)
+ {
+ continue;
+ }
+
+ if (j == numFiles)
+ { /* new component */
+ k = 1;
+ while (tComponentName[i][k] != NULL)
+ {
+ componentTable[numFiles].pRoleArray[k - 1] =
+ tComponentName[i][k];
+ k++;
+ }
+ componentTable[numFiles].nRoles = k - 1;
+ strcpy(compName[numFiles], tComponentName[i][0]);
+ componentTable[numFiles].name = compName[numFiles];
+ numFiles++;
+ }
+ }
+ tableCount = numFiles;
+
+ CORE_assert(eError == OMX_ErrorNone, eError,
+ "Could not build Component Table");
+ EXIT:
+ return eError;
+}
+
+OMX_ERRORTYPE ComponentTable_EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_EVENTTYPE eEvent,
+ OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2, OMX_IN OMX_PTR pEventData)
+{
+ return OMX_ErrorNotImplemented;
+}
+
+OMX_ERRORTYPE ComponentTable_EmptyBufferDone(OMX_OUT OMX_HANDLETYPE
+ hComponent, OMX_OUT OMX_PTR pAppData,
+ OMX_OUT OMX_BUFFERHEADERTYPE * pBuffer)
+{
+ return OMX_ErrorNotImplemented;
+}
+
+OMX_ERRORTYPE ComponentTable_FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_PTR pAppData, OMX_OUT OMX_BUFFERHEADERTYPE * pBuffer)
+{
+ return OMX_ErrorNotImplemented;
+}
+
+
+
+/*===============================================================*/
+/** @fn Core_Setup : This function is called when the the OMX Core library is
+ * loaded. It creates a mutex, which is used during OMX_Init()
+ */
+/*===============================================================*/
+void __attribute__ ((constructor)) Core_Setup(void)
+{
+ TIMM_OSAL_ERRORTYPE eError = TIMM_OSAL_ERR_NONE;
+
+ eError = TIMM_OSAL_MutexCreate(&pCoreInitMutex);
+ if (eError != TIMM_OSAL_ERR_NONE)
+ {
+ TIMM_OSAL_Error("Creation of default mutex failed");
+ }
+}
+
+
+
+/*===============================================================*/
+/** @fn Core_Destroy : This function is called when the the OMX Core library is
+ * unloaded. It destroys the mutex which was created by
+ * Core_Setup().
+ *
+ */
+/*===============================================================*/
+void __attribute__ ((destructor)) Core_Destroy(void)
+{
+ TIMM_OSAL_ERRORTYPE eError = TIMM_OSAL_ERR_NONE;
+
+ eError = TIMM_OSAL_MutexDelete(pCoreInitMutex);
+ if (eError != TIMM_OSAL_ERR_NONE)
+ {
+ TIMM_OSAL_Error("Destruction of default mutex failed");
+ }
+}