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,"libOmxAlacDec.so") || 492 !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) && 493 (number_of_adec_nt_session+1 > MAX_AUDIO_NT_SESSION)) { 494 DEBUG_PRINT_ERROR("Rejecting new session..Reached max limit for DSP audio decoder session"); 495 pthread_mutex_unlock(&lock_core); 496 return OMX_ErrorInsufficientResources; 497 } 498 // Construct the component requested 499 // Function returns the opaque handle 500 void* pThis = (*(core[cmp_index].fn_ptr))(); 501 if(pThis) 502 { 503 void *hComp = NULL; 504 hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis); 505 if((eRet = qc_omx_component_init(hComp, optComponentName)) != 506 OMX_ErrorNone) 507 { 508 DEBUG_PRINT("Component not created succesfully\n"); 509 pthread_mutex_unlock(&lock_core); 510 return eRet; 511 512 } 513 qc_omx_component_set_callbacks(hComp,callBacks,appData); 514 515 if (vpp_cmp_index >= 0) 516 { 517 hnd_index = get_comp_handle_index("OMX.qti.vdec.vpp"); 518 } 519 else 520 { 521 hnd_index = get_comp_handle_index(optComponentName); 522 } 523 524 if(hnd_index >= 0) 525 { 526 core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp; 527 } 528 else 529 { 530 DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n"); 531 pthread_mutex_unlock(&lock_core); 532 return OMX_ErrorInsufficientResources; 533 } 534 DEBUG_PRINT("Component %p Successfully created\n",*handle); 535 if(!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so") || 536 !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so") || 537 !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") || 538 !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) { 539 540 number_of_adec_nt_session++; 541 DEBUG_PRINT("OMX_GetHandle: number_of_adec_nt_session : %d\n", 542 number_of_adec_nt_session); 543 } 544 } 545 else 546 { 547 eRet = OMX_ErrorInsufficientResources; 548 DEBUG_PRINT("Component Creation failed\n"); 549 } 550 } 551 else 552 { 553 eRet = OMX_ErrorNotImplemented; 554 DEBUG_PRINT("library couldnt return create instance fn\n"); 555 } 556 557 } 558 else 559 { 560 eRet = OMX_ErrorNotImplemented; 561 DEBUG_PRINT("ERROR: Already another instance active ;rejecting \n"); 562 } 563 } 564 else 565 { 566 eRet = OMX_ErrorBadParameter; 567 DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n"); 568 } 569 pthread_mutex_unlock(&lock_core); 570 return eRet; 571 } 572 /* ====================================================================== 573 FUNCTION 574 OMX_FreeHandle 575 576 DESCRIPTION 577 Destructs the component handles. 578 579 PARAMETERS 580 None 581 582 RETURN VALUE 583 Error None. 584 ========================================================================== */ 585 OMX_API OMX_ERRORTYPE OMX_APIENTRY 586 OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp) 587 { 588 OMX_ERRORTYPE eRet = OMX_ErrorNone; 589 int err = 0, i = 0; 590 DEBUG_PRINT("OMXCORE API : FreeHandle %p\n", hComp); 591 592 // 0. Check that we have an active instance 593 if((i=is_cmp_handle_exists(hComp)) >=0) 594 { 595 // 1. Delete the component 596 if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone) 597 { 598 pthread_mutex_lock(&lock_core); 599 clear_cmp_handle(hComp); 600 /* Unload component library */ 601 if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle) 602 { 603 if(check_lib_unload(i)) 604 { 605 DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n", 606 core[i].name); 607 err = dlclose(core[i].so_lib_handle); 608 if(err) 609 { 610 DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n", 611 err,core[i].name); 612 } 613 core[i].so_lib_handle = NULL; 614 } 615 if(!strcmp(core[i].so_lib_name,"libOmxWmaDec.so") || 616 !strcmp(core[i].so_lib_name,"libOmxAacDec.so") || 617 !strcmp(core[i].so_lib_name,"libOmxAlacDec.so") || 618 !strcmp(core[i].so_lib_name,"libOmxApeDec.so")) { 619 if(number_of_adec_nt_session>0) 620 number_of_adec_nt_session--; 621 DEBUG_PRINT_ERROR("OMX_FreeHandle: reduced number_of_adec_nt_session %d\n", 622 number_of_adec_nt_session); 623 } 624 } 625 pthread_mutex_unlock(&lock_core); 626 } 627 else 628 { 629 DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp); 630 return eRet; 631 } 632 } 633 else 634 { 635 DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n"); 636 } 637 return OMX_ErrorNone; 638 } 639 /* ====================================================================== 640 FUNCTION 641 OMX_SetupTunnel 642 643 DESCRIPTION 644 Not Implemented. 645 646 PARAMETERS 647 None 648 649 RETURN VALUE 650 None. 651 ========================================================================== */ 652 OMX_API OMX_ERRORTYPE OMX_APIENTRY 653 OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent, 654 OMX_IN OMX_U32 outputPort, 655 OMX_IN OMX_HANDLETYPE inputComponent, 656 OMX_IN OMX_U32 inputPort) 657 { 658 (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort; 659 /* Not supported right now */ 660 DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n"); 661 return OMX_ErrorNotImplemented; 662 } 663 /* ====================================================================== 664 FUNCTION 665 OMX_GetContentPipe 666 667 DESCRIPTION 668 Not Implemented. 669 670 PARAMETERS 671 None 672 673 RETURN VALUE 674 None. 675 ========================================================================== */ 676 OMX_API OMX_ERRORTYPE 677 OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe, 678 OMX_IN OMX_STRING uri) 679 { 680 (void) pipe, (void) uri; 681 /* Not supported right now */ 682 DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n"); 683 return OMX_ErrorNotImplemented; 684 } 685 686 /* ====================================================================== 687 FUNCTION 688 OMX_GetComponentNameEnum 689 690 DESCRIPTION 691 Returns the component name associated with the index. 692 693 PARAMETERS 694 None 695 696 RETURN VALUE 697 None. 698 ========================================================================== */ 699 OMX_API OMX_ERRORTYPE OMX_APIENTRY 700 OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName, 701 OMX_IN OMX_U32 nameLen, 702 OMX_IN OMX_U32 index) 703 { 704 OMX_ERRORTYPE eRet = OMX_ErrorNone; 705 DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName 706 ,(unsigned)nameLen 707 ,(unsigned)index); 708 if(index < SIZE_OF_CORE) 709 { 710 #ifdef _ANDROID_ 711 strlcpy(componentName, core[index].name,nameLen); 712 #else 713 strncpy(componentName, core[index].name,nameLen); 714 #endif 715 } 716 else 717 { 718 eRet = OMX_ErrorNoMore; 719 } 720 return eRet; 721 } 722 723 /* ====================================================================== 724 FUNCTION 725 OMX_GetComponentsOfRole 726 727 DESCRIPTION 728 Returns the component name which can fulfill the roles passed in the 729 argument. 730 731 PARAMETERS 732 None 733 734 RETURN VALUE 735 None. 736 ========================================================================== */ 737 OMX_API OMX_ERRORTYPE 738 OMX_GetComponentsOfRole(OMX_IN OMX_STRING role, 739 OMX_INOUT OMX_U32* numComps, 740 OMX_INOUT OMX_U8** compNames) 741 { 742 OMX_ERRORTYPE eRet = OMX_ErrorNone; 743 unsigned i,j,namecount=0; 744 745 printf(" Inside OMX_GetComponentsOfRole \n"); 746 747 /*If CompNames is NULL then return*/ 748 if (compNames == NULL) 749 { 750 if (numComps == NULL) 751 { 752 eRet = OMX_ErrorBadParameter; 753 } 754 else 755 { 756 *numComps = 0; 757 for (i=0; i<SIZE_OF_CORE;i++) 758 { 759 for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++) 760 { 761 if(!strcmp(role,core[i].roles[j])) 762 { 763 (*numComps)++; 764 } 765 } 766 } 767 } 768 return eRet; 769 } 770 771 if(numComps) 772 { 773 namecount = *numComps; 774 775 if (namecount == 0) 776 { 777 return OMX_ErrorBadParameter; 778 } 779 780 *numComps = 0; 781 782 for (i=0; i<SIZE_OF_CORE;i++) 783 { 784 for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++) 785 { 786 if(!strcmp(role,core[i].roles[j])) 787 { 788 #ifdef _ANDROID_ 789 strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE); 790 #else 791 strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE); 792 #endif 793 (*numComps)++; 794 break; 795 } 796 } 797 if (*numComps == namecount) 798 { 799 break; 800 } 801 } 802 } 803 else 804 { 805 eRet = OMX_ErrorBadParameter; 806 } 807 808 printf(" Leaving OMX_GetComponentsOfRole \n"); 809 return eRet; 810 } 811 /* ====================================================================== 812 FUNCTION 813 OMX_GetRolesOfComponent 814 815 DESCRIPTION 816 Returns the primary role of the components supported. 817 818 PARAMETERS 819 None 820 821 RETURN VALUE 822 None. 823 ========================================================================== */ 824 OMX_API OMX_ERRORTYPE 825 OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName, 826 OMX_INOUT OMX_U32* numRoles, 827 OMX_OUT OMX_U8** roles) 828 { 829 /* Not supported right now */ 830 OMX_ERRORTYPE eRet = OMX_ErrorNone; 831 unsigned i,j,numofroles = 0;; 832 DEBUG_PRINT("GetRolesOfComponent %s\n",compName); 833 834 if (roles == NULL) 835 { 836 if (numRoles == NULL) 837 { 838 eRet = OMX_ErrorBadParameter; 839 } 840 else 841 { 842 *numRoles = 0; 843 for(i=0; i< SIZE_OF_CORE; i++) 844 { 845 if(!strcmp(compName,core[i].name)) 846 { 847 for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++) 848 { 849 (*numRoles)++; 850 } 851 break; 852 } 853 } 854 855 } 856 return eRet; 857 } 858 859 if(numRoles) 860 { 861 if (*numRoles == 0) 862 { 863 return OMX_ErrorBadParameter; 864 } 865 866 numofroles = *numRoles; 867 *numRoles = 0; 868 for(i=0; i< SIZE_OF_CORE; i++) 869 { 870 if(!strcmp(compName,core[i].name)) 871 { 872 for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++) 873 { 874 if(roles && roles[*numRoles]) 875 { 876 #ifdef _ANDROID_ 877 strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE); 878 #else 879 strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE); 880 #endif 881 } 882 (*numRoles)++; 883 if (numofroles == *numRoles) 884 { 885 break; 886 } 887 } 888 break; 889 } 890 } 891 } 892 else 893 { 894 DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n"); 895 eRet = OMX_ErrorBadParameter; 896 } 897 return eRet; 898 } 899 900 OMX_API OMX_BOOL 901 OMXConfigParser( 902 OMX_PTR aInputParameters, 903 OMX_PTR aOutputParameters) 904 { 905 OMX_BOOL Status = OMX_TRUE; 906 VideoOMXConfigParserOutputs *aOmxOutputParameters; 907 OMXConfigParserInputs *aOmxInputParameters; 908 aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters; 909 aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters; 910 911 aOmxOutputParameters->width = 176; //setting width to QCIF 912 aOmxOutputParameters->height = 144; //setting height to QCIF 913 914 //TODO 915 //Qcom component do not use the level/profile from IL client .They are parsing the first buffer 916 //sent in ETB so for now setting the defalut values . Going farward we can call 917 //QC parser here. 918 if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc")) 919 { 920 aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile 921 aOmxOutputParameters->level = 0; // minimum supported h264 level 922 } 923 else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263"))) 924 { 925 aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile 926 aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level 927 } 928 929 return Status; 930 } 931