1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2009, 2015, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of The Linux Foundation nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 --------------------------------------------------------------------------*/ 28 /*============================================================================ 29 O p e n M A X w r a p p e r s 30 O p e n M A X C o r e 31 32 This module contains the implementation of the OpenMAX core. 33 34 *//*========================================================================*/ 35 36 ////////////////////////////////////////////////////////////////////////////// 37 // Include Files 38 ////////////////////////////////////////////////////////////////////////////// 39 40 #include <dlfcn.h> // dynamic library 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include <unistd.h> 44 #include <string.h> 45 #include <stdio.h> 46 #include <pthread.h> 47 48 #include "qc_omx_core.h" 49 #include "omx_core_cmp.h" 50 #include <cutils/properties.h> 51 52 extern omx_core_cb_type core[]; 53 extern const unsigned int SIZE_OF_CORE; 54 static pthread_mutex_t lock_core = PTHREAD_MUTEX_INITIALIZER; 55 static int number_of_adec_nt_session; 56 57 #define MAX_AUDIO_NT_SESSION 2 58 59 /* ====================================================================== 60 FUNCTION 61 omx_core_load_cmp_library 62 63 DESCRIPTION 64 Loads up the libary name mentioned in the argument 65 66 PARAMETERS 67 None 68 69 RETURN VALUE 70 Constructor for creating component instances. 71 ========================================================================== */ 72 static create_qc_omx_component 73 omx_core_load_cmp_library(char *libname, void **handle_ptr) 74 { 75 create_qc_omx_component fn_ptr = NULL; 76 if(handle_ptr) 77 { 78 DEBUG_PRINT("Dynamically Loading the library : %s\n",libname); 79 *handle_ptr = dlopen(libname,RTLD_NOW); 80 if(*handle_ptr) 81 { 82 fn_ptr = dlsym(*handle_ptr, "get_omx_component_factory_fn"); 83 84 if(fn_ptr == NULL) 85 { 86 DEBUG_PRINT("Error: Library %s incompatible as QCOM OMX component loader - %s\n", 87 libname, dlerror()); 88 *handle_ptr = NULL; 89 } 90 } 91 else 92 { 93 DEBUG_PRINT("Error: Couldn't load %s: %s\n",libname,dlerror()); 94 } 95 } 96 return fn_ptr; 97 } 98 99 /* ====================================================================== 100 FUNCTION 101 OMX_Init 102 103 DESCRIPTION 104 This is the first function called by the application. 105 There is nothing to do here since components shall be loaded 106 whenever the get handle method is called. 107 108 PARAMETERS 109 None 110 111 RETURN VALUE 112 None. 113 ========================================================================== */ 114 OMX_API OMX_ERRORTYPE OMX_APIENTRY 115 OMX_Init() 116 { 117 DEBUG_PRINT("OMXCORE API - OMX_Init \n"); 118 /* Nothing to do here ; shared objects shall be loaded at the get handle method */ 119 return OMX_ErrorNone; 120 } 121 122 /* ====================================================================== 123 FUNCTION 124 get_cmp_index 125 126 DESCRIPTION 127 Obtains the index associated with the name. 128 129 PARAMETERS 130 None 131 132 RETURN VALUE 133 Error None. 134 ========================================================================== */ 135 static int get_cmp_index(char *cmp_name) 136 { 137 int rc = -1,i=0; 138 DEBUG_PRINT("before get_cmp_index **********%d\n", rc); 139 140 for(i=0; i< (int)SIZE_OF_CORE; i++) 141 { 142 DEBUG_PRINT("get_cmp_index: cmp_name = %s , core[i].name = %s ,count = %d \n",cmp_name,core[i].name,i); 143 144 if(!strcmp(cmp_name, core[i].name)) 145 { 146 rc = i; 147 break; 148 } 149 } 150 DEBUG_PRINT("returning index %d\n", rc); 151 return rc; 152 } 153 154 /* ====================================================================== 155 FUNCTION 156 clear_cmp_handle 157 158 DESCRIPTION 159 Clears the component handle from the component table. 160 161 PARAMETERS 162 None 163 164 RETURN VALUE 165 None. 166 ========================================================================== */ 167 static void clear_cmp_handle(OMX_HANDLETYPE inst) 168 { 169 unsigned i = 0,j=0; 170 171 if(NULL == inst) 172 return; 173 174 for(i=0; i< SIZE_OF_CORE; i++) 175 { 176 for(j=0; j< OMX_COMP_MAX_INST; j++) 177 { 178 if(inst == core[i].inst[j]) 179 { 180 core[i].inst[j] = NULL; 181 return; 182 } 183 } 184 } 185 return; 186 } 187 /* ====================================================================== 188 FUNCTION 189 is_cmp_handle_exists 190 191 DESCRIPTION 192 Check if the component handle already exists or not. 193 194 PARAMETERS 195 None 196 197 RETURN VALUE 198 index pointer if the handle exists 199 negative value otherwise 200 ========================================================================== */ 201 static int is_cmp_handle_exists(OMX_HANDLETYPE inst) 202 { 203 unsigned i=0,j=0; 204 int rc = -1; 205 206 if(NULL == inst) 207 return rc; 208 209 pthread_mutex_lock(&lock_core); 210 for(i=0; i< SIZE_OF_CORE; i++) 211 { 212 for(j=0; j< OMX_COMP_MAX_INST; j++) 213 { 214 if(inst == core[i].inst[j]) 215 { 216 rc = i; 217 goto finish; 218 } 219 } 220 } 221 finish: 222 pthread_mutex_unlock(&lock_core); 223 return rc; 224 } 225 226 /* ====================================================================== 227 FUNCTION 228 get_comp_handle_index 229 230 DESCRIPTION 231 Gets the index to store the next handle for specified component name. 232 233 PARAMETERS 234 cmp_name : Component Name 235 236 RETURN VALUE 237 Index of next handle to be stored 238 ========================================================================== */ 239 static int get_comp_handle_index(char *cmp_name) 240 { 241 unsigned i=0,j=0; 242 int rc = -1; 243 for(i=0; i< SIZE_OF_CORE; i++) 244 { 245 if(!strcmp(cmp_name, core[i].name)) 246 { 247 for(j=0; j< OMX_COMP_MAX_INST; j++) 248 { 249 if(NULL == core[i].inst[j]) 250 { 251 rc = j; 252 DEBUG_PRINT("free handle slot exists %d\n", rc); 253 return rc; 254 } 255 } 256 break; 257 } 258 } 259 return rc; 260 } 261 262 /* ====================================================================== 263 FUNCTION 264 check_lib_unload 265 266 DESCRIPTION 267 Check if any component instance is using the library 268 269 PARAMETERS 270 index: Component Index in core array. 271 272 RETURN VALUE 273 1: Library Unused and can be unloaded. 274 0: Library used and shouldnt be unloaded. 275 ========================================================================== */ 276 static int check_lib_unload(int index) 277 { 278 unsigned i=0; 279 int rc = 1; 280 281 for(i=0; i< OMX_COMP_MAX_INST; i++) 282 { 283 if(core[index].inst[i]) 284 { 285 rc = 0; 286 DEBUG_PRINT("Library Used \n"); 287 break; 288 } 289 } 290 return rc; 291 } 292 /* ====================================================================== 293 FUNCTION 294 is_cmp_already_exists 295 296 DESCRIPTION 297 Check if the component already exists or not. Used in the 298 management of component handles. 299 300 PARAMETERS 301 None 302 303 RETURN VALUE 304 Error None. 305 ========================================================================== */ 306 static int is_cmp_already_exists(char *cmp_name) 307 { 308 unsigned i =0,j=0; 309 int rc = -1; 310 for(i=0; i< SIZE_OF_CORE; i++) 311 { 312 if(!strcmp(cmp_name, core[i].name)) 313 { 314 for(j=0; j< OMX_COMP_MAX_INST; j++) 315 { 316 if(core[i].inst[j]) 317 { 318 rc = i; 319 DEBUG_PRINT("Component exists %d\n", rc); 320 return rc; 321 } 322 } 323 break; 324 } 325 } 326 return rc; 327 } 328 329 /* ====================================================================== 330 FUNCTION 331 get_cmp_handle 332 333 DESCRIPTION 334 Get component handle. 335 336 PARAMETERS 337 None 338 339 RETURN VALUE 340 Error None. 341 ========================================================================== */ 342 void* get_cmp_handle(char *cmp_name) 343 { 344 unsigned i =0,j=0; 345 346 DEBUG_PRINT("get_cmp_handle \n"); 347 for(i=0; i< SIZE_OF_CORE; i++) 348 { 349 if(!strcmp(cmp_name, core[i].name)) 350 { 351 for(j=0; j< OMX_COMP_MAX_INST; j++) 352 { 353 if(core[i].inst[j]) 354 { 355 DEBUG_PRINT("get_cmp_handle match\n"); 356 return core[i].inst[j]; 357 } 358 } 359 } 360 } 361 DEBUG_PRINT("get_cmp_handle returning NULL \n"); 362 return NULL; 363 } 364 365 /* ====================================================================== 366 FUNCTION 367 OMX_DeInit 368 369 DESCRIPTION 370 DeInitialize all the the relevant OMX components. 371 372 PARAMETERS 373 None 374 375 RETURN VALUE 376 Error None. 377 ========================================================================== */ 378 OMX_API OMX_ERRORTYPE OMX_APIENTRY 379 OMX_Deinit() 380 { 381 return OMX_ErrorNone; 382 } 383 384 /* ====================================================================== 385 FUNCTION 386 OMX_GetHandle 387 388 DESCRIPTION 389 Constructs requested component. Relevant library is loaded if needed. 390 391 PARAMETERS 392 None 393 394 RETURN VALUE 395 Error None if everything goes fine. 396 ========================================================================== */ 397 398 OMX_API OMX_ERRORTYPE OMX_APIENTRY 399 OMX_GetHandle(OMX_OUT OMX_HANDLETYPE* handle, 400 OMX_IN OMX_STRING componentName, 401 OMX_IN OMX_PTR appData, 402 OMX_IN OMX_CALLBACKTYPE* callBacks) 403 { 404 OMX_ERRORTYPE eRet = OMX_ErrorNone; 405 int cmp_index = -1; 406 int hnd_index = -1; 407 int vpp_cmp_index = -1; 408 409 DEBUG_PRINT("OMXCORE API : GetHandle %p %s %p\n", handle, 410 componentName, 411 appData); 412 pthread_mutex_lock(&lock_core); 413 if(handle) 414 { 415 struct stat sd; 416 *handle = NULL; 417 char optComponentName[OMX_MAX_STRINGNAME_SIZE]; 418 strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE); 419 420 if(strstr(componentName, "avc") && strstr(componentName, "decoder")) 421 { 422 void *libhandle = dlopen("libOmxVideoDSMode.so", RTLD_NOW); 423 if(libhandle) 424 { 425 int (*fn_ptr)() = dlsym(libhandle, "isDSModeActive"); 426 427 if(fn_ptr == NULL) 428 { 429 DEBUG_PRINT_ERROR("Error: isDSModeActive Not Found %s\n", 430 dlerror()); 431 } 432 else 433 { 434 int isActive = fn_ptr(); 435 char *pSubString = strstr(componentName, ".dsmode"); 436 if(pSubString) 437 { 438 optComponentName[pSubString - componentName] = 0; 439 } 440 else if(isActive) 441 { 442 strlcat(optComponentName, ".dsmode", OMX_MAX_STRINGNAME_SIZE); 443 } 444 cmp_index = get_cmp_index(optComponentName); 445 } 446 dlclose(libhandle); 447 } 448 else 449 { 450 DEBUG_PRINT_ERROR("Failed to load dsmode library"); 451 } 452 } 453 454 if(cmp_index < 0) 455 { 456 cmp_index = get_cmp_index(componentName); 457 strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE); 458 } 459 if(cmp_index >= 0) 460 { 461 char value[PROPERTY_VALUE_MAX]; 462 DEBUG_PRINT("getting fn pointer\n"); 463 464 // Load VPP omx component for decoder if vpp 465 // property is enabled 466 if ((property_get("media.vpp.enable", value, NULL)) 467 && (!strcmp("1", value) || !strcmp("true", value))) { 468 DEBUG_PRINT("VPP property is enabled"); 469 if (!strcmp(core[cmp_index].so_lib_name, "libOmxVdec.so")) { 470 vpp_cmp_index = get_cmp_index("OMX.qti.vdec.vpp"); 471 if (vpp_cmp_index < 0) { 472 DEBUG_PRINT_ERROR("Unable to find VPP OMX lib in registry "); 473 } else { 474 DEBUG_PRINT("Loading vpp for vdec"); 475 cmp_index = vpp_cmp_index; 476 } 477 } 478 } 479 480 // dynamically load the so 481 core[cmp_index].fn_ptr = 482 omx_core_load_cmp_library(core[cmp_index].so_lib_name, 483 &core[cmp_index].so_lib_handle); 484 485 486 if(core[cmp_index].fn_ptr) 487 { 488 //Do not allow more than MAX limit for DSP audio decoders 489 if((!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so") || 490 !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so") || 491 !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so") || 492 !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") || 493 !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) && 494 (number_of_adec_nt_session+1 > MAX_AUDIO_NT_SESSION)) { 495 DEBUG_PRINT_ERROR("Rejecting new session..Reached max limit for DSP audio decoder session"); 496 pthread_mutex_unlock(&lock_core); 497 return OMX_ErrorInsufficientResources; 498 } 499 // Construct the component requested 500 // Function returns the opaque handle 501 void* pThis = (*(core[cmp_index].fn_ptr))(); 502 if(pThis) 503 { 504 void *hComp = NULL; 505 hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis); 506 if((eRet = qc_omx_component_init(hComp, optComponentName)) != 507 OMX_ErrorNone) 508 { 509 DEBUG_PRINT("Component not created succesfully\n"); 510 pthread_mutex_unlock(&lock_core); 511 return eRet; 512 513 } 514 qc_omx_component_set_callbacks(hComp,callBacks,appData); 515 516 if (vpp_cmp_index >= 0) 517 { 518 hnd_index = get_comp_handle_index("OMX.qti.vdec.vpp"); 519 } 520 else 521 { 522 hnd_index = get_comp_handle_index(optComponentName); 523 } 524 525 if(hnd_index >= 0) 526 { 527 core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp; 528 } 529 else 530 { 531 DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n"); 532 pthread_mutex_unlock(&lock_core); 533 return OMX_ErrorInsufficientResources; 534 } 535 DEBUG_PRINT("Component %p Successfully created\n",*handle); 536 if(!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so") || 537 !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so") || 538 !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so") || 539 !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") || 540 !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) { 541 542 number_of_adec_nt_session++; 543 DEBUG_PRINT("OMX_GetHandle: number_of_adec_nt_session : %d\n", 544 number_of_adec_nt_session); 545 } 546 } 547 else 548 { 549 eRet = OMX_ErrorInsufficientResources; 550 DEBUG_PRINT("Component Creation failed\n"); 551 } 552 } 553 else 554 { 555 eRet = OMX_ErrorNotImplemented; 556 DEBUG_PRINT("library couldnt return create instance fn\n"); 557 } 558 559 } 560 else 561 { 562 eRet = OMX_ErrorNotImplemented; 563 DEBUG_PRINT("ERROR: Already another instance active ;rejecting \n"); 564 } 565 } 566 else 567 { 568 eRet = OMX_ErrorBadParameter; 569 DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n"); 570 } 571 pthread_mutex_unlock(&lock_core); 572 return eRet; 573 } 574 /* ====================================================================== 575 FUNCTION 576 OMX_FreeHandle 577 578 DESCRIPTION 579 Destructs the component handles. 580 581 PARAMETERS 582 None 583 584 RETURN VALUE 585 Error None. 586 ========================================================================== */ 587 OMX_API OMX_ERRORTYPE OMX_APIENTRY 588 OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp) 589 { 590 OMX_ERRORTYPE eRet = OMX_ErrorNone; 591 int err = 0, i = 0; 592 DEBUG_PRINT("OMXCORE API : FreeHandle %p\n", hComp); 593 594 // 0. Check that we have an active instance 595 if((i=is_cmp_handle_exists(hComp)) >=0) 596 { 597 // 1. Delete the component 598 if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone) 599 { 600 pthread_mutex_lock(&lock_core); 601 clear_cmp_handle(hComp); 602 /* Unload component library */ 603 if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle) 604 { 605 if(check_lib_unload(i)) 606 { 607 DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n", 608 core[i].name); 609 err = dlclose(core[i].so_lib_handle); 610 if(err) 611 { 612 DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n", 613 err,core[i].name); 614 } 615 core[i].so_lib_handle = NULL; 616 } 617 if(!strcmp(core[i].so_lib_name,"libOmxWmaDec.so") || 618 !strcmp(core[i].so_lib_name,"libOmxAacDec.so") || 619 !strcmp(core[i].so_lib_name,"libOmxAlacDec.so") || 620 !strcmp(core[i].so_lib_name,"libOmxApeDec.so")) { 621 if(number_of_adec_nt_session>0) 622 number_of_adec_nt_session--; 623 DEBUG_PRINT_ERROR("OMX_FreeHandle: reduced number_of_adec_nt_session %d\n", 624 number_of_adec_nt_session); 625 } 626 } 627 pthread_mutex_unlock(&lock_core); 628 } 629 else 630 { 631 DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp); 632 return eRet; 633 } 634 } 635 else 636 { 637 DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n"); 638 } 639 return OMX_ErrorNone; 640 } 641 /* ====================================================================== 642 FUNCTION 643 OMX_SetupTunnel 644 645 DESCRIPTION 646 Not Implemented. 647 648 PARAMETERS 649 None 650 651 RETURN VALUE 652 None. 653 ========================================================================== */ 654 OMX_API OMX_ERRORTYPE OMX_APIENTRY 655 OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent, 656 OMX_IN OMX_U32 outputPort, 657 OMX_IN OMX_HANDLETYPE inputComponent, 658 OMX_IN OMX_U32 inputPort) 659 { 660 (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort; 661 /* Not supported right now */ 662 DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n"); 663 return OMX_ErrorNotImplemented; 664 } 665 /* ====================================================================== 666 FUNCTION 667 OMX_GetContentPipe 668 669 DESCRIPTION 670 Not Implemented. 671 672 PARAMETERS 673 None 674 675 RETURN VALUE 676 None. 677 ========================================================================== */ 678 OMX_API OMX_ERRORTYPE 679 OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe, 680 OMX_IN OMX_STRING uri) 681 { 682 (void) pipe, (void) uri; 683 /* Not supported right now */ 684 DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n"); 685 return OMX_ErrorNotImplemented; 686 } 687 688 /* ====================================================================== 689 FUNCTION 690 OMX_GetComponentNameEnum 691 692 DESCRIPTION 693 Returns the component name associated with the index. 694 695 PARAMETERS 696 None 697 698 RETURN VALUE 699 None. 700 ========================================================================== */ 701 OMX_API OMX_ERRORTYPE OMX_APIENTRY 702 OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName, 703 OMX_IN OMX_U32 nameLen, 704 OMX_IN OMX_U32 index) 705 { 706 OMX_ERRORTYPE eRet = OMX_ErrorNone; 707 DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName 708 ,(unsigned)nameLen 709 ,(unsigned)index); 710 if(index < SIZE_OF_CORE) 711 { 712 #ifdef _ANDROID_ 713 strlcpy(componentName, core[index].name,nameLen); 714 #else 715 strncpy(componentName, core[index].name,nameLen); 716 #endif 717 } 718 else 719 { 720 eRet = OMX_ErrorNoMore; 721 } 722 return eRet; 723 } 724 725 /* ====================================================================== 726 FUNCTION 727 OMX_GetComponentsOfRole 728 729 DESCRIPTION 730 Returns the component name which can fulfill the roles passed in the 731 argument. 732 733 PARAMETERS 734 None 735 736 RETURN VALUE 737 None. 738 ========================================================================== */ 739 OMX_API OMX_ERRORTYPE 740 OMX_GetComponentsOfRole(OMX_IN OMX_STRING role, 741 OMX_INOUT OMX_U32* numComps, 742 OMX_INOUT OMX_U8** compNames) 743 { 744 OMX_ERRORTYPE eRet = OMX_ErrorNone; 745 unsigned i,j,namecount=0; 746 747 printf(" Inside OMX_GetComponentsOfRole \n"); 748 749 /*If CompNames is NULL then return*/ 750 if (compNames == NULL) 751 { 752 if (numComps == NULL) 753 { 754 eRet = OMX_ErrorBadParameter; 755 } 756 else 757 { 758 *numComps = 0; 759 for (i=0; i<SIZE_OF_CORE;i++) 760 { 761 for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++) 762 { 763 if(!strcmp(role,core[i].roles[j])) 764 { 765 (*numComps)++; 766 } 767 } 768 } 769 } 770 return eRet; 771 } 772 773 if(numComps) 774 { 775 namecount = *numComps; 776 777 if (namecount == 0) 778 { 779 return OMX_ErrorBadParameter; 780 } 781 782 *numComps = 0; 783 784 for (i=0; i<SIZE_OF_CORE;i++) 785 { 786 for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++) 787 { 788 if(!strcmp(role,core[i].roles[j])) 789 { 790 #ifdef _ANDROID_ 791 strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE); 792 #else 793 strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE); 794 #endif 795 (*numComps)++; 796 break; 797 } 798 } 799 if (*numComps == namecount) 800 { 801 break; 802 } 803 } 804 } 805 else 806 { 807 eRet = OMX_ErrorBadParameter; 808 } 809 810 printf(" Leaving OMX_GetComponentsOfRole \n"); 811 return eRet; 812 } 813 /* ====================================================================== 814 FUNCTION 815 OMX_GetRolesOfComponent 816 817 DESCRIPTION 818 Returns the primary role of the components supported. 819 820 PARAMETERS 821 None 822 823 RETURN VALUE 824 None. 825 ========================================================================== */ 826 OMX_API OMX_ERRORTYPE 827 OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName, 828 OMX_INOUT OMX_U32* numRoles, 829 OMX_OUT OMX_U8** roles) 830 { 831 /* Not supported right now */ 832 OMX_ERRORTYPE eRet = OMX_ErrorNone; 833 unsigned i,j,numofroles = 0;; 834 DEBUG_PRINT("GetRolesOfComponent %s\n",compName); 835 836 if (roles == NULL) 837 { 838 if (numRoles == NULL) 839 { 840 eRet = OMX_ErrorBadParameter; 841 } 842 else 843 { 844 *numRoles = 0; 845 for(i=0; i< SIZE_OF_CORE; i++) 846 { 847 if(!strcmp(compName,core[i].name)) 848 { 849 for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++) 850 { 851 (*numRoles)++; 852 } 853 break; 854 } 855 } 856 857 } 858 return eRet; 859 } 860 861 if(numRoles) 862 { 863 if (*numRoles == 0) 864 { 865 return OMX_ErrorBadParameter; 866 } 867 868 numofroles = *numRoles; 869 *numRoles = 0; 870 for(i=0; i< SIZE_OF_CORE; i++) 871 { 872 if(!strcmp(compName,core[i].name)) 873 { 874 for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++) 875 { 876 if(roles && roles[*numRoles]) 877 { 878 #ifdef _ANDROID_ 879 strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE); 880 #else 881 strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE); 882 #endif 883 } 884 (*numRoles)++; 885 if (numofroles == *numRoles) 886 { 887 break; 888 } 889 } 890 break; 891 } 892 } 893 } 894 else 895 { 896 DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n"); 897 eRet = OMX_ErrorBadParameter; 898 } 899 return eRet; 900 } 901 902 OMX_API OMX_BOOL 903 OMXConfigParser( 904 OMX_PTR aInputParameters, 905 OMX_PTR aOutputParameters) 906 { 907 OMX_BOOL Status = OMX_TRUE; 908 VideoOMXConfigParserOutputs *aOmxOutputParameters; 909 OMXConfigParserInputs *aOmxInputParameters; 910 aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters; 911 aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters; 912 913 aOmxOutputParameters->width = 176; //setting width to QCIF 914 aOmxOutputParameters->height = 144; //setting height to QCIF 915 916 //TODO 917 //Qcom component do not use the level/profile from IL client .They are parsing the first buffer 918 //sent in ETB so for now setting the defalut values . Going farward we can call 919 //QC parser here. 920 if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc")) 921 { 922 aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile 923 aOmxOutputParameters->level = 0; // minimum supported h264 level 924 } 925 else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263"))) 926 { 927 aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile 928 aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level 929 } 930 931 return Status; 932 } 933