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