OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / hardware / ti / omap3 / omx / system / src / openmax_il / omx_core / src / OMX_Core.c
1 /* ====================================================================
2 *             Texas Instruments OMAP(TM) Platform Software
3 * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved.
4 *
5 * Use of this software is controlled by the terms and conditions found
6 * in the license agreement under which this software has been supplied.
7 * ==================================================================== */
8
9 #include <dlfcn.h>   /* For dynamic loading */
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <pthread.h>
14 #include <utils/Log.h>
15
16 #undef LOG_TAG
17 #define LOG_TAG "TIOMX_CORE"
18
19 #include "OMX_Component.h"
20 #include "OMX_Core.h"
21 #include "OMX_ComponentRegistry.h"
22
23 #ifndef NO_OPENCORE
24 /** determine capabilities of a component before acually using it */
25 #include "ti_omx_config_parser.h"
26 #endif
27
28 /** size for the array of allocated components.  Sets the maximum 
29  * number of components that can be allocated at once */
30 #define MAXCOMP (50)
31 #define MAXNAMESIZE (130)
32 #define EMPTY_STRING "\0"
33
34 /** Determine the number of elements in an array */
35 #define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
36
37 /** Array to hold the DLL pointers for each allocated component */
38 static void* pModules[MAXCOMP] = {0};
39
40 /** Array to hold the component handles for each allocated component */
41 static void* pComponents[COUNTOF(pModules)] = {0};
42
43 /** count will be used as a reference counter for OMX_Init()
44     so all changes to count should be mutex protected */
45 int count = 0;
46 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
47
48 int tableCount = 0;
49 ComponentTable componentTable[MAX_TABLE_SIZE];
50 char * sRoleArray[60][20];
51 char compName[60][200];
52
53 char *tComponentName[MAXCOMP][2] = {
54     /*video and image components */
55     //{"OMX.TI.JPEG.decoder", "image_decoder.jpeg" },
56     {"OMX.TI.JPEG.Encoder", "image_encoder.jpeg"},
57     //{"OMX.TI.Video.Decoder", "video_decoder.h263"},
58     {"OMX.TI.Video.Decoder", "video_decoder.avc"},
59     //{"OMX.TI.Video.Decoder", "video_decoder.mpeg2"},
60     {"OMX.TI.Video.Decoder", "video_decoder.mpeg4"},
61     {"OMX.TI.Video.Decoder", "video_decoder.wmv"},
62     {"OMX.TI.Video.encoder", "video_encoder.mpeg4"},
63     {"OMX.TI.Video.encoder", "video_encoder.h263"},
64     {"OMX.TI.Video.encoder", "video_encoder.avc"},
65     //{"OMX.TI.VPP", "iv_renderer.yuv.overlay"},
66     //{"OMX.TI.Camera", "camera.yuv"},
67
68     /* Speech components */
69 /*  {"OMX.TI.G729.encode", NULL},
70     {"OMX.TI.G729.decode", NULL},       
71     {"OMX.TI.G722.encode", NULL},
72     {"OMX.TI.G722.decode", NULL},
73     {"OMX.TI.G711.encode", NULL},
74     {"OMX.TI.G711.decode", NULL},
75     {"OMX.TI.G723.encode", NULL},
76     {"OMX.TI.G723.decode", NULL},
77     {"OMX.TI.G726.encode", NULL},
78     {"OMX.TI.G726.decode", NULL},
79     {"OMX.TI.GSMFR.encode", NULL},
80     {"OMX.TI.GSMFR.decode", NULL},
81 */
82
83     /* Audio components */
84 #ifdef BUILD_WITH_TI_AUDIO
85     {"OMX.TI.MP3.decode", "audio_decoder.mp3"},
86     {"OMX.TI.AAC.encode", "audio_encoder.aac"},
87     {"OMX.TI.AAC.decode", "audio_decoder.aac"},
88     {"OMX.TI.WMA.decode", "audio_decoder.wma"},
89     {"OMX.TI.WBAMR.decode", "audio_decoder.amrwb"},
90     {"OMX.TI.AMR.decode", "audio_decoder.amrnb"},
91     {"OMX.TI.AMR.encode", "audio_encoder.amrnb"},
92     {"OMX.TI.WBAMR.encode", "audio_encoder.amrwb"},
93 #endif
94 /*  {"OMX.TI.PCM.encode", NULL},
95     {"OMX.TI.PCM.decode", NULL},     
96     {"OMX.TI.RAG.decode", "audio_decoder.ra"},
97     {"OMX.TI.IMAADPCM.decode", NULL},
98     {"OMX.TI.IMAADPCM.encode", NULL},
99 */
100
101     /* terminate the table */
102     {NULL, NULL},
103 };
104
105
106 /******************************Public*Routine******************************\
107 * OMX_Init()
108 *
109 * Description:This method will initialize the OMX Core.  It is the 
110 * responsibility of the application to call OMX_Init to ensure the proper
111 * set up of core resources.
112 *
113 * Returns:    OMX_NOERROR          Successful
114 *
115 * Note
116 *
117 \**************************************************************************/
118 OMX_ERRORTYPE TIOMX_Init()
119 {
120     OMX_ERRORTYPE eError = OMX_ErrorNone;
121
122     if(pthread_mutex_lock(&mutex) != 0)
123     {
124         LOGE("%d :: Core: Error in Mutex lock\n",__LINE__);
125         return OMX_ErrorUndefined;
126     }
127
128     count++;
129     LOGD("init count = %d\n", count);
130
131     if (count == 1)
132     {
133         eError = TIOMX_BuildComponentTable();
134     }
135
136     if(pthread_mutex_unlock(&mutex) != 0)
137     {
138         LOGE("%d :: Core: Error in Mutex unlock\n",__LINE__);
139         return OMX_ErrorUndefined;
140     }
141     return eError;
142 }
143 /******************************Public*Routine******************************\
144 * OMX_GetHandle
145 *
146 * Description: This method will create the handle of the COMPONENTTYPE
147 * If the component is currently loaded, this method will reutrn the 
148 * hadle of existingcomponent or create a new instance of the component.
149 * It will call the OMX_ComponentInit function and then the setcallback
150 * method to initialize the callback functions
151 * Parameters:
152 * @param[out] pHandle            Handle of the loaded components 
153 * @param[in] cComponentName     Name of the component to load
154 * @param[in] pAppData           Used to identify the callbacks of component 
155 * @param[in] pCallBacks         Application callbacks
156 *
157 * @retval OMX_ErrorUndefined         
158 * @retval OMX_ErrorInvalidComponentName
159 * @retval OMX_ErrorInvalidComponent
160 * @retval OMX_ErrorInsufficientResources 
161 * @retval OMX_NOERROR                      Successful
162 *
163 * Note
164 *
165 \**************************************************************************/
166
167 OMX_ERRORTYPE TIOMX_GetHandle( OMX_HANDLETYPE* pHandle, OMX_STRING cComponentName,
168     OMX_PTR pAppData, OMX_CALLBACKTYPE* pCallBacks)
169 {
170     static const char prefix[] = "lib";
171     static const char postfix[] = ".so";
172     OMX_ERRORTYPE (*pComponentInit)(OMX_HANDLETYPE*);
173     OMX_ERRORTYPE err = OMX_ErrorNone;
174     OMX_COMPONENTTYPE *componentType;
175     const char* pErr = dlerror();
176
177     if(pthread_mutex_lock(&mutex) != 0)
178     {
179         LOGE("%d :: Core: Error in Mutex lock\n",__LINE__);
180         return OMX_ErrorUndefined;
181     }
182
183     if ((NULL == cComponentName) || (NULL == pHandle) || (NULL == pCallBacks)) {
184         err = OMX_ErrorBadParameter;
185         goto UNLOCK_MUTEX;
186     }
187
188     /* Verify that the name is not too long and could cause a crash.  Notice
189      * that the comparison is a greater than or equals.  This is to make
190      * sure that there is room for the terminating NULL at the end of the
191      * name. */
192     if(strlen(cComponentName) >= MAXNAMESIZE) {
193         err = OMX_ErrorInvalidComponentName;
194         goto UNLOCK_MUTEX;
195     }
196     /* Locate the first empty slot for a component.  If no slots
197      * are available, error out */
198     int i = 0;
199     for(i=0; i< COUNTOF(pModules); i++) {
200         if(pModules[i] == NULL) break;
201     }
202     if(i == COUNTOF(pModules)) {
203         err = OMX_ErrorInsufficientResources;
204         goto UNLOCK_MUTEX;
205     }
206
207     int refIndex = 0;
208     for (refIndex=0; refIndex < MAX_TABLE_SIZE; refIndex++) {
209         //get the index for the component in the table
210         if (strcmp(componentTable[refIndex].name, cComponentName) == 0) {
211             LOGD("Found component %s with refCount %d\n",
212                   cComponentName, componentTable[refIndex].refCount);
213
214             /* check if the component is already loaded */
215             if (componentTable[refIndex].refCount >= MAX_CONCURRENT_INSTANCES) {
216                 err = OMX_ErrorInsufficientResources;
217                 LOGE("Max instances of component %s already created.\n", cComponentName);
218                 goto UNLOCK_MUTEX;
219             } else {  // we have not reached the limit yet
220                 /* do what was done before need to limit concurrent instances of each component */
221
222                 /* load the component and check for an error.  If filename is not an
223                  * absolute path (i.e., it does not  begin with a "/"), then the
224                  * file is searched for in the following locations:
225                  *
226                  *     The LD_LIBRARY_PATH environment variable locations
227                  *     The library cache, /etc/ld.so.cache.
228                  *     /lib
229                  *     /usr/lib
230                  *
231                  * If there is an error, we can't go on, so set the error code and exit */
232
233                 /* the lengths are defined herein or have been
234                  * checked already, so strcpy and strcat are
235                  * are safe to use in this context. */
236                 char buf[sizeof(prefix) + MAXNAMESIZE + sizeof(postfix)];
237                 strcpy(buf, prefix);
238                 strcat(buf, cComponentName);
239                 strcat(buf, postfix);
240
241                 pModules[i] = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
242                 if( pModules[i] == NULL ) {
243                     LOGE("dlopen %s failed because %s\n", buf, dlerror());
244                     err = OMX_ErrorComponentNotFound;
245                     goto UNLOCK_MUTEX;
246                 }
247
248                 /* Get a function pointer to the "OMX_ComponentInit" function.  If
249                  * there is an error, we can't go on, so set the error code and exit */
250                 pComponentInit = dlsym(pModules[i], "OMX_ComponentInit");
251                 pErr = dlerror();
252                 if( (pErr != NULL) || (pComponentInit == NULL) ) {
253                     LOGE("%d:: dlsym failed for module %p\n", __LINE__, pModules[i]);
254                     err = OMX_ErrorInvalidComponent;
255                     goto CLEAN_UP;
256                 }
257
258                /* We now can access the dll.  So, we need to call the "OMX_ComponentInit"
259                 * method to load up the "handle" (which is just a list of functions to
260                 * call) and we should be all set.*/
261                 *pHandle = malloc(sizeof(OMX_COMPONENTTYPE));
262                 if(*pHandle == NULL) {
263                     err = OMX_ErrorInsufficientResources;
264                     LOGE("%d:: malloc of pHandle* failed\n", __LINE__);
265                     goto CLEAN_UP;
266                 }
267
268                 pComponents[i] = *pHandle;
269                 componentType = (OMX_COMPONENTTYPE*) *pHandle;
270                 componentType->nSize = sizeof(OMX_COMPONENTTYPE);
271                 err = (*pComponentInit)(*pHandle);
272                 if (OMX_ErrorNone == err) {
273                     err = (componentType->SetCallbacks)(*pHandle, pCallBacks, pAppData);
274                     if (err != OMX_ErrorNone) {
275                         LOGE("%d :: Core: SetCallBack failed %d\n",__LINE__, err);
276                         goto CLEAN_UP;
277                     }
278                     /* finally, OMX_ComponentInit() was successful and
279                        SetCallbacks was successful, we have a valid instance,
280                        so no we increment refCount */
281                     componentTable[refIndex].pHandle[componentTable[refIndex].refCount] = *pHandle;
282                     componentTable[refIndex].refCount += 1;
283                     goto UNLOCK_MUTEX;  // Component is found, and thus we are done
284                 }
285                 else if (err == OMX_ErrorInsufficientResources) {
286                         LOGE("%d :: Core: Insufficient Resources for Component %d\n",__LINE__, err);
287                         goto CLEAN_UP;
288                 }
289             }
290         }
291     }
292
293     // If we are here, we have not found the component
294     err = OMX_ErrorComponentNotFound;
295     goto UNLOCK_MUTEX;
296 CLEAN_UP:
297     if(*pHandle != NULL)
298     /* cover the case where we error out before malloc'd */
299     {
300         free(*pHandle);
301         *pHandle = NULL;
302     }
303     pComponents[i] = NULL;
304     dlclose(pModules[i]);
305     pModules[i] = NULL;
306
307 UNLOCK_MUTEX:
308     if(pthread_mutex_unlock(&mutex) != 0)
309     {
310         LOGE("%d :: Core: Error in Mutex unlock\n",__LINE__);
311         err = OMX_ErrorUndefined;
312     }
313     return (err);
314 }
315
316
317 /******************************Public*Routine******************************\
318 * OMX_FreeHandle()
319 *
320 * Description:This method will unload the OMX component pointed by 
321 * OMX_HANDLETYPE. It is the responsibility of the calling method to ensure that
322 * the Deinit method of the component has been called prior to unloading component
323 *
324 * Parameters:
325 * @param[in] hComponent the component to unload
326 *
327 * Returns:    OMX_NOERROR          Successful
328 *
329 * Note
330 *
331 \**************************************************************************/
332 OMX_ERRORTYPE TIOMX_FreeHandle (OMX_HANDLETYPE hComponent)
333 {
334
335     OMX_ERRORTYPE retVal = OMX_ErrorUndefined;
336     OMX_COMPONENTTYPE *pHandle = (OMX_COMPONENTTYPE *)hComponent;
337
338     if(pthread_mutex_lock(&mutex) != 0)
339     {
340         LOGE("%d :: Core: Error in Mutex lock\n",__LINE__);
341         return OMX_ErrorUndefined;
342     }
343
344     /* Locate the component handle in the array of handles */
345     int i = 0;
346     for(i=0; i< COUNTOF(pModules); i++) {
347         if(pComponents[i] == hComponent) break;
348     }
349
350     if(i == COUNTOF(pModules)) {
351         LOGE("%d :: Core: component %p is not found\n", __LINE__, hComponent);
352         retVal = OMX_ErrorBadParameter;
353         goto EXIT;
354     }
355
356     retVal = pHandle->ComponentDeInit(hComponent);
357     if (retVal != OMX_ErrorNone) {
358         LOGE("%d :: ComponentDeInit failed %d\n",__LINE__, retVal);
359         goto EXIT;
360     }
361
362     int refIndex = 0, handleIndex = 0;
363     for (refIndex=0; refIndex < MAX_TABLE_SIZE; refIndex++) {
364         for (handleIndex=0; handleIndex < componentTable[refIndex].refCount; handleIndex++){
365             /* get the position for the component in the table */
366             if (componentTable[refIndex].pHandle[handleIndex] == hComponent){
367                 LOGD("Found matching pHandle(%p) at index %d with refCount %d",
368                       hComponent, refIndex, componentTable[refIndex].refCount);
369                 if (componentTable[refIndex].refCount) {
370                     componentTable[refIndex].refCount -= 1;
371                 }
372                 componentTable[refIndex].pHandle[handleIndex] = NULL;
373                 dlclose(pModules[i]);
374                 pModules[i] = NULL;
375                 free(pComponents[i]);
376                 pComponents[i] = NULL;
377                 retVal = OMX_ErrorNone;
378                 goto EXIT;
379             }
380         }
381     }
382
383     // If we are here, we have not found the matching component
384     retVal = OMX_ErrorComponentNotFound;
385
386 EXIT:
387     /* The unload is now complete, so set the error code to pass and exit */
388     if(pthread_mutex_unlock(&mutex) != 0)
389     {
390         LOGE("%d :: Core: Error in Mutex unlock\n",__LINE__);
391         return OMX_ErrorUndefined;
392     }
393
394     return retVal;
395 }
396
397 /******************************Public*Routine******************************\
398 * OMX_DeInit()
399 *
400 * Description:This method will release the resources of the OMX Core.  It is the 
401 * responsibility of the application to call OMX_DeInit to ensure the clean up of these
402 * resources.
403 *
404 * Returns:    OMX_NOERROR          Successful
405 *
406 * Note
407 *
408 \**************************************************************************/
409 OMX_ERRORTYPE TIOMX_Deinit()
410 {
411     if(pthread_mutex_lock(&mutex) != 0) {
412         LOGE("%d :: Core: Error in Mutex lock\n",__LINE__);
413         return OMX_ErrorUndefined;
414     }
415
416     if (count) {
417         count--;
418     }
419
420     LOGD("deinit count = %d\n", count);
421
422     if(pthread_mutex_unlock(&mutex) != 0) {
423         LOGE("%d :: Core: Error in Mutex unlock\n",__LINE__);
424         return OMX_ErrorUndefined;
425     }
426
427     return OMX_ErrorNone;
428 }
429
430 /*************************************************************************
431 * OMX_SetupTunnel()
432 *
433 * Description: Setup the specified tunnel the two components
434 *
435 * Parameters:
436 * @param[in] hOutput     Handle of the component to be accessed
437 * @param[in] nPortOutput Source port used in the tunnel
438 * @param[in] hInput      Component to setup the tunnel with.
439 * @param[in] nPortInput  Destination port used in the tunnel
440 *
441 * Returns:    OMX_NOERROR          Successful
442 *
443 * Note
444 *
445 **************************************************************************/
446 /* OMX_SetupTunnel */
447 OMX_API OMX_ERRORTYPE OMX_APIENTRY TIOMX_SetupTunnel(
448     OMX_IN  OMX_HANDLETYPE hOutput,
449     OMX_IN  OMX_U32 nPortOutput,
450     OMX_IN  OMX_HANDLETYPE hInput,
451     OMX_IN  OMX_U32 nPortInput)
452 {
453     OMX_ERRORTYPE eError = OMX_ErrorNotImplemented;
454     OMX_COMPONENTTYPE *pCompIn, *pCompOut;
455     OMX_TUNNELSETUPTYPE oTunnelSetup;
456
457     if (hOutput == NULL && hInput == NULL)
458         return OMX_ErrorBadParameter;
459
460     oTunnelSetup.nTunnelFlags = 0;
461     oTunnelSetup.eSupplier = OMX_BufferSupplyUnspecified;
462
463     pCompOut = (OMX_COMPONENTTYPE*)hOutput;
464
465     if (hOutput)
466     {
467         eError = pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, hInput, nPortInput, &oTunnelSetup);
468     }
469
470
471     if (eError == OMX_ErrorNone && hInput) 
472     {  
473         pCompIn = (OMX_COMPONENTTYPE*)hInput;
474         eError = pCompIn->ComponentTunnelRequest(hInput, nPortInput, hOutput, nPortOutput, &oTunnelSetup);
475         if (eError != OMX_ErrorNone && hOutput) 
476         {
477             /* cancel tunnel request on output port since input port failed */
478             pCompOut->ComponentTunnelRequest(hOutput, nPortOutput, NULL, 0, NULL);
479         }
480     }
481   
482     return eError;
483 }
484
485 /*************************************************************************
486 * OMX_ComponentNameEnum()
487 *
488 * Description: This method will provide the name of the component at the given nIndex
489 *
490 *Parameters:
491 * @param[out] cComponentName       The name of the component at nIndex
492 * @param[in] nNameLength                The length of the component name
493 * @param[in] nIndex                         The index number of the component 
494 *
495 * Returns:    OMX_NOERROR          Successful
496 *
497 * Note
498 *
499 **************************************************************************/
500 OMX_API OMX_ERRORTYPE OMX_APIENTRY TIOMX_ComponentNameEnum(
501     OMX_OUT OMX_STRING cComponentName,
502     OMX_IN  OMX_U32 nNameLength,
503     OMX_IN  OMX_U32 nIndex)
504 {
505     OMX_ERRORTYPE eError = OMX_ErrorNone;
506
507     if (nIndex >=  tableCount)
508     {
509         eError = OMX_ErrorNoMore;
510      }
511     else
512     {
513         strcpy(cComponentName, componentTable[nIndex].name);
514     }
515     
516     return eError;
517 }
518
519
520 /*************************************************************************
521 * OMX_GetRolesOfComponent()
522 *
523 * Description: This method will query the component for its supported roles
524 *
525 *Parameters:
526 * @param[in] cComponentName     The name of the component to query
527 * @param[in] pNumRoles     The number of roles supported by the component
528 * @param[in] roles              The roles of the component
529 *
530 * Returns:    OMX_NOERROR          Successful
531 *                 OMX_ErrorBadParameter         Faliure due to a bad input parameter
532 *
533 * Note
534 *
535 **************************************************************************/
536 OMX_API OMX_ERRORTYPE TIOMX_GetRolesOfComponent (
537     OMX_IN      OMX_STRING cComponentName,
538     OMX_INOUT   OMX_U32 *pNumRoles,
539     OMX_OUT     OMX_U8 **roles)
540 {
541
542     OMX_ERRORTYPE eError = OMX_ErrorNone;
543     OMX_U32 i = 0;
544     OMX_U32 j = 0;
545     OMX_BOOL bFound = OMX_FALSE;
546
547     if (cComponentName == NULL || pNumRoles == NULL)
548     {
549         if (cComponentName == NULL)
550         {
551             LOGE("cComponentName is NULL\n");
552         }
553         if (pNumRoles == NULL)
554         {
555             LOGE("pNumRoles is NULL\n");
556         }
557         eError = OMX_ErrorBadParameter;
558         goto EXIT;       
559     }
560     while (i < tableCount)
561     {\r
562         if (strcmp(cComponentName, componentTable[i].name) == 0)\r
563         {\r
564             bFound = OMX_TRUE;\r
565             break;\r
566         }
567         i++;\r
568     }
569     if (!bFound)
570     {
571         eError = OMX_ErrorComponentNotFound;
572         LOGE("component %s not found\n", cComponentName);
573         goto EXIT;
574     } 
575     if (roles == NULL)
576     { 
577         *pNumRoles = componentTable[i].nRoles;
578     }
579     else
580     {
581         /* must be second of two calls,
582            pNumRoles is input in this context.
583            If pNumRoles is < actual number of roles
584            than we return an error */
585         if (*pNumRoles >= componentTable[i].nRoles)
586         {
587             for (j = 0; j<componentTable[i].nRoles; j++) 
588             {
589                 strcpy((OMX_STRING)roles[j], componentTable[i].pRoleArray[j]);
590             }
591             *pNumRoles = componentTable[i].nRoles;
592         }
593         else
594         {
595             eError = OMX_ErrorBadParameter;
596             LOGE("pNumRoles (%d) is less than actual number (%d) of roles \
597                    for this component %s\n", *pNumRoles, componentTable[i].nRoles, cComponentName);
598         }
599     }
600     EXIT:
601     return eError;
602 }
603
604 /*************************************************************************
605 * OMX_GetComponentsOfRole()
606 *
607 * Description: This method will query the component for its supported roles
608 *
609 *Parameters:
610 * @param[in] role     The role name to query for
611 * @param[in] pNumComps     The number of components supporting the given role
612 * @param[in] compNames      The names of the components supporting the given role
613 *
614 * Returns:    OMX_NOERROR          Successful
615 *
616 * Note
617 *
618 **************************************************************************/
619 OMX_API OMX_ERRORTYPE TIOMX_GetComponentsOfRole ( 
620     OMX_IN      OMX_STRING role,
621     OMX_INOUT   OMX_U32 *pNumComps,
622     OMX_INOUT   OMX_U8  **compNames)
623 {
624     OMX_ERRORTYPE eError = OMX_ErrorNone;
625     OMX_U32 i = 0;
626     OMX_U32 j = 0;
627     OMX_U32 k = 0;
628     OMX_U32 compOfRoleCount = 0;
629
630     if (role == NULL || pNumComps == NULL)
631     {
632        if (role == NULL)
633        {
634            LOGE("role is NULL");
635        }
636        if (pNumComps == NULL)
637        {
638            LOGE("pNumComps is NULL\n");
639        }
640        eError = OMX_ErrorBadParameter;
641        goto EXIT;
642     }
643
644    /* This implies that the componentTable is not filled */
645     if (!tableCount)
646     {
647         eError = OMX_ErrorUndefined;
648         LOGE("Component table is empty. Please reload OMX Core\n");
649         goto EXIT;
650     }
651
652     /* no matter, we always want to know number of matching components
653        so this will always run */ 
654     for (i = 0; i < tableCount; i++)
655     {
656         for (j = 0; j < componentTable[i].nRoles; j++) 
657         { 
658             if (strcmp(componentTable[i].pRoleArray[j], role) == 0)
659             {
660                 /* the first call to this function should only count the number
661                    of roles 
662                 */
663                 compOfRoleCount++;
664             }
665         }
666     }
667     if (compOfRoleCount == 0)
668     {
669         eError = OMX_ErrorComponentNotFound;
670         LOGE("Component supporting role %s was not found\n", role);
671     }
672     if (compNames == NULL)
673     {
674         /* must be the first of two calls */
675         *pNumComps = compOfRoleCount;
676     }
677     else
678     {
679         /* must be the second of two calls */
680         if (*pNumComps < compOfRoleCount)
681         {
682             /* pNumComps is input in this context,
683                it can not be less, this would indicate
684                the array is not large enough
685             */
686             eError = OMX_ErrorBadParameter;
687             LOGE("pNumComps (%d) is less than the actual number (%d) of components \
688                   supporting role %s\n", *pNumComps, compOfRoleCount, role);
689         }
690         else
691         {
692             k = 0;
693             for (i = 0; i < tableCount; i++)
694             {
695                 for (j = 0; j < componentTable[i].nRoles; j++) 
696                 { 
697                     if (strcmp(componentTable[i].pRoleArray[j], role) == 0)
698                     {
699                         /*  the second call compNames can be allocated
700                             with the proper size for that number of roles.
701                         */
702                         compNames[k] = (OMX_U8*)componentTable[i].name;
703                         k++;
704                         if (k == compOfRoleCount)
705                         {
706                             /* there are no more components of this role
707                                so we can exit here */
708                             *pNumComps = k;
709                             goto EXIT;
710                         } 
711                     }
712                 }
713             }
714         }        
715     }
716
717     EXIT:
718     return eError;
719 }
720
721
722 OMX_ERRORTYPE TIOMX_BuildComponentTable()
723 {
724     OMX_ERRORTYPE eError = OMX_ErrorNone;
725     OMX_CALLBACKTYPE sCallbacks;
726     int j = 0;
727     int numFiles = 0;
728     int i;
729
730     for (i = 0, numFiles = 0; i < MAXCOMP; i ++) {
731         if (tComponentName[i][0] == NULL) {
732             break;
733         }
734         if (numFiles <= MAX_TABLE_SIZE){
735             for (j = 0; j < numFiles; j ++) {
736                 if (!strcmp(componentTable[j].name, tComponentName[i][0])) {
737                     /* insert the role */
738                     if (tComponentName[i][1] != NULL)
739                     {
740                         componentTable[j].pRoleArray[componentTable[j].nRoles] = tComponentName[i][1];
741                         componentTable[j].pHandle[componentTable[j].nRoles] = NULL; //initilize the pHandle element
742                         componentTable[j].nRoles ++;
743                     }
744                     break;
745                 }
746             }
747             if (j == numFiles) { /* new component */
748                 if (tComponentName[i][1] != NULL){
749                     componentTable[numFiles].pRoleArray[0] = tComponentName[i][1];
750                     componentTable[numFiles].nRoles = 1;
751                 }
752                 strcpy(compName[numFiles], tComponentName[i][0]);
753                 componentTable[numFiles].name = compName[numFiles];
754                 componentTable[numFiles].refCount = 0; //initialize reference counter.
755                 numFiles ++;
756             }
757         }
758     }
759     tableCount = numFiles;
760     if (eError != OMX_ErrorNone){
761         LOGE("Could not build Component Table\n");
762     }
763
764     return eError;
765 }
766
767 OMX_BOOL TIOMXConfigParserRedirect(
768     OMX_PTR aInputParameters,
769     OMX_PTR aOutputParameters)
770
771 {
772     OMX_BOOL Status = OMX_FALSE;
773 #ifndef NO_OPENCORE
774     Status = TIOMXConfigParser(aInputParameters, aOutputParameters);
775 #endif
776     return Status;
777 }