1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #ifndef OSCL_BASE_H_INCLUDED 19 #include "oscl_base.h" 20 #endif 21 22 #ifndef PV_OMXDEFS_H_INCLUDED 23 #include "pv_omxdefs.h" 24 #endif 25 26 #ifndef OMX_Component_h 27 #include "OMX_Component.h" 28 #endif 29 30 #ifndef PV_OMXCORE_H_INCLUDED 31 #include "pv_omxcore.h" 32 #endif 33 34 #ifndef OSCL_MEM_BASIC_FUNCTIONS_H 35 #include "oscl_mem_basic_functions.h" 36 #endif 37 38 #ifndef OSCL_STDSTRING_H_INCLUDED 39 #include "oscl_stdstring.h" 40 #endif 41 42 #ifndef OSCL_ERROR_H_INCLUDED 43 #include "oscl_error.h" 44 #endif 45 46 #ifndef OSCL_INIT_H_INCLUDED 47 #include "oscl_init.h" 48 #endif 49 50 #ifndef PV_OMX_CONFIG_PARSER_H 51 #include "pv_omx_config_parser.h" 52 #endif 53 54 // pv_omxregistry.h is only needed if NOT using CML2 55 #ifndef USE_CML2_CONFIG 56 #include "pv_omxregistry.h" 57 #endif 58 59 #include "oscl_init.h" 60 61 // Use default DLL entry point 62 #ifndef OSCL_DLL_H_INCLUDED 63 #include "oscl_dll.h" 64 #endif 65 66 #if USE_DYNAMIC_LOAD_OMX_COMPONENTS 67 // until dynamic registry - register all components 68 // unconditionally - may error out at load time 69 70 OMX_ERRORTYPE Mpeg4Register(); 71 OMX_ERRORTYPE H263Register(); 72 OMX_ERRORTYPE AvcRegister(); 73 OMX_ERRORTYPE WmvRegister(); 74 OMX_ERRORTYPE AacRegister(); 75 OMX_ERRORTYPE AmrRegister(); 76 OMX_ERRORTYPE Mp3Register(); 77 OMX_ERRORTYPE WmaRegister(); 78 79 OMX_ERRORTYPE AmrEncRegister(); 80 OMX_ERRORTYPE Mpeg4EncRegister(); 81 OMX_ERRORTYPE H263EncRegister(); 82 OMX_ERRORTYPE AvcEncRegister(); 83 OMX_ERRORTYPE AacEncRegister(); 84 85 86 #else 87 88 #if REGISTER_OMX_M4V_COMPONENT 89 OMX_ERRORTYPE Mpeg4Register(); 90 #endif 91 92 #if REGISTER_OMX_H263_COMPONENT 93 OMX_ERRORTYPE H263Register(); 94 #endif 95 96 #if REGISTER_OMX_AVC_COMPONENT 97 OMX_ERRORTYPE AvcRegister(); 98 #endif 99 100 #if REGISTER_OMX_WMV_COMPONENT 101 OMX_ERRORTYPE WmvRegister(); 102 #endif 103 104 #if REGISTER_OMX_AAC_COMPONENT 105 OMX_ERRORTYPE AacRegister(); 106 #endif 107 108 #if REGISTER_OMX_AMR_COMPONENT 109 OMX_ERRORTYPE AmrRegister(); 110 #endif 111 112 #if REGISTER_OMX_MP3_COMPONENT 113 OMX_ERRORTYPE Mp3Register(); 114 #endif 115 116 #if REGISTER_OMX_WMA_COMPONENT 117 OMX_ERRORTYPE WmaRegister(); 118 #endif 119 120 #if REGISTER_OMX_AMRENC_COMPONENT 121 OMX_ERRORTYPE AmrEncRegister(); 122 #endif 123 124 #if REGISTER_OMX_M4VENC_COMPONENT 125 OMX_ERRORTYPE Mpeg4EncRegister(); 126 #endif 127 128 #if REGISTER_OMX_H263ENC_COMPONENT 129 OMX_ERRORTYPE H263EncRegister(); 130 #endif 131 132 #if REGISTER_OMX_AVCENC_COMPONENT 133 OMX_ERRORTYPE AvcEncRegister(); 134 #endif 135 136 #if REGISTER_OMX_AACENC_COMPONENT 137 OMX_ERRORTYPE AacEncRegister(); 138 #endif 139 #endif 140 OSCL_DLL_ENTRY_POINT_DEFAULT() 141 142 /* Initializes the component */ 143 static OMX_ERRORTYPE _OMX_Init() 144 { 145 OMX_ERRORTYPE Status = OMX_ErrorNone; 146 int32 error; 147 //get global data structure 148 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 149 if (error) // can't access registry 150 { 151 return OMX_ErrorInsufficientResources; 152 } 153 else if (!data) // singleton object has been destroyed 154 { 155 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 156 return OMX_ErrorInsufficientResources; 157 } 158 159 #if PROXY_INTERFACE 160 ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; 161 #endif 162 OMX_U32 ii; 163 164 /* Initialize template list to NULL at the beginning */ 165 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii++) 166 { 167 data->ipRegTemplateList[ii] = NULL; 168 } 169 170 for (ii = 0; ii < MAX_INSTANTIATED_COMPONENTS; ii++) 171 { 172 data->iComponentHandle[ii] = NULL; 173 data->ipInstantiatedComponentReg[ii] = NULL; 174 #if PROXY_INTERFACE 175 pProxyTerm[ii] = NULL; 176 #endif 177 } 178 179 //Release the singleton. 180 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 181 if (error) 182 { 183 //registry error 184 Status = OMX_ErrorUndefined; 185 return Status; 186 } 187 188 #if USE_DYNAMIC_LOAD_OMX_COMPONENTS 189 //unconditional registration 190 // MPEG4 191 Status = Mpeg4Register(); 192 if (Status != OMX_ErrorNone) 193 return Status; 194 195 196 //H263 197 Status = H263Register(); 198 if (Status != OMX_ErrorNone) 199 return Status; 200 201 // AVC 202 Status = AvcRegister(); 203 if (Status != OMX_ErrorNone) 204 return Status; 205 206 // WMV 207 Status = WmvRegister(); 208 if (Status != OMX_ErrorNone) 209 return Status; 210 211 // AAC 212 Status = AacRegister(); 213 if (Status != OMX_ErrorNone) 214 return Status; 215 216 // AMR 217 Status = AmrRegister(); 218 if (Status != OMX_ErrorNone) 219 return Status; 220 221 // MP3 222 Status = Mp3Register(); 223 if (Status != OMX_ErrorNone) 224 return Status; 225 226 // WMA 227 Status = WmaRegister(); 228 if (Status != OMX_ErrorNone) 229 return Status; 230 231 //AMR ENCODER 232 Status = AmrEncRegister(); 233 if (Status != OMX_ErrorNone) 234 return Status; 235 236 //MPEG4 Encoder 237 Status = Mpeg4EncRegister(); 238 if (Status != OMX_ErrorNone) 239 return Status; 240 241 //H263 Encoder 242 Status = H263EncRegister(); 243 if (Status != OMX_ErrorNone) 244 return Status; 245 246 //H264/AVC Encoder 247 Status = AvcEncRegister(); 248 if (Status != OMX_ErrorNone) 249 return Status; 250 251 //AAC Encoder 252 Status = AacEncRegister(); 253 if (Status != OMX_ErrorNone) 254 return Status; 255 256 257 #else 258 // REGISTER COMPONENT TYPES (ONE BY ONE) 259 #if REGISTER_OMX_M4V_COMPONENT 260 // MPEG4 261 Status = Mpeg4Register(); 262 if (Status != OMX_ErrorNone) 263 return Status; 264 #endif 265 266 #if REGISTER_OMX_H263_COMPONENT 267 //H263 268 Status = H263Register(); 269 if (Status != OMX_ErrorNone) 270 return Status; 271 #endif 272 273 #if REGISTER_OMX_AVC_COMPONENT 274 // AVC 275 Status = AvcRegister(); 276 if (Status != OMX_ErrorNone) 277 return Status; 278 #endif 279 280 #if REGISTER_OMX_WMV_COMPONENT 281 // WMV 282 Status = WmvRegister(); 283 if (Status != OMX_ErrorNone) 284 return Status; 285 #endif 286 287 #if REGISTER_OMX_AAC_COMPONENT 288 // AAC 289 Status = AacRegister(); 290 if (Status != OMX_ErrorNone) 291 return Status; 292 #endif 293 294 #if REGISTER_OMX_AMR_COMPONENT 295 // AMR 296 Status = AmrRegister(); 297 if (Status != OMX_ErrorNone) 298 return Status; 299 #endif 300 301 #if REGISTER_OMX_MP3_COMPONENT 302 // MP3 303 Status = Mp3Register(); 304 if (Status != OMX_ErrorNone) 305 return Status; 306 #endif 307 308 #if REGISTER_OMX_WMA_COMPONENT 309 // WMA 310 Status = WmaRegister(); 311 if (Status != OMX_ErrorNone) 312 return Status; 313 #endif 314 315 #if REGISTER_OMX_AMRENC_COMPONENT 316 //AMR ENCODER 317 Status = AmrEncRegister(); 318 if (Status != OMX_ErrorNone) 319 return Status; 320 #endif 321 322 #if REGISTER_OMX_M4VENC_COMPONENT 323 //MPEG4 Encoder 324 Status = Mpeg4EncRegister(); 325 if (Status != OMX_ErrorNone) 326 return Status; 327 #endif 328 329 #if REGISTER_OMX_H263ENC_COMPONENT 330 //H263 Encoder 331 Status = H263EncRegister(); 332 if (Status != OMX_ErrorNone) 333 return Status; 334 #endif 335 #if REGISTER_OMX_AVCENC_COMPONENT 336 //H264/AVC Encoder 337 Status = AvcEncRegister(); 338 if (Status != OMX_ErrorNone) 339 return Status; 340 #endif 341 342 #if REGISTER_OMX_AACENC_COMPONENT 343 //AAC Encoder 344 Status = AacEncRegister(); 345 if (Status != OMX_ErrorNone) 346 return Status; 347 #endif 348 #endif 349 return OMX_ErrorNone; 350 } 351 352 //this routine is needed to avoid a longjmp clobber warning 353 static void _Try_OMX_Init(int32& aError, OMX_ERRORTYPE& aStatus) 354 { 355 OSCL_TRY(aError, aStatus = _OMX_Init();); 356 } 357 //this routine is needed to avoid a longjmp clobber warning 358 static void _Try_OMX_Create(int32& aError, OMXGlobalData*& aData) 359 { 360 OSCL_TRY(aError, aData = OSCL_NEW(OMXGlobalData, ());); 361 } 362 363 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 364 // in case of static build - just redirect master omx core call to local pv core call 365 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterInit() 366 { 367 return OMX_Init(); 368 } 369 #endif 370 371 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_Init() 372 { 373 OMX_ERRORTYPE status = OMX_ErrorNone; 374 375 //Check the global instance counter and only init OMX on the first call. 376 bool osclInit = false; 377 int32 error; 378 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 379 380 //Check for whether Oscl is initialized in this thread. If not, we will 381 //initialize it here. 382 if (error == EPVErrorBaseNotInstalled) 383 { 384 //init all Oscl layers except Oscl scheduler. 385 OsclSelect select; 386 select.iOsclScheduler = false; 387 OsclInit::Init(error, &select); 388 if (error) 389 { 390 status = OMX_ErrorUndefined;//can't init Oscl 391 return status; 392 } 393 else 394 { 395 osclInit = true; 396 } 397 } 398 399 if (data) 400 { 401 //Just update the instance counter. 402 data->iInstanceCount++; 403 404 //Release the singleton. 405 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 406 if (error) 407 { 408 status = OMX_ErrorUndefined; 409 return status; 410 } 411 } 412 else 413 { 414 //First call-- 415 //create the OMX singleton 416 _Try_OMX_Create(error, data); 417 if (error != OsclErrNone) 418 { 419 status = OMX_ErrorInsufficientResources;//some leave happened. 420 } 421 422 //Release the singleton. 423 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 424 if (error) 425 { 426 //registry error 427 status = OMX_ErrorUndefined; 428 return status; 429 } 430 431 //If create succeeded, then init the OMX globals. 432 if (status == OMX_ErrorNone) 433 { 434 _Try_OMX_Init(error, status); 435 if (error != OsclErrNone) 436 { 437 status = OMX_ErrorUndefined;//probably no memory. 438 } 439 else 440 { 441 //keep track of whether we did Oscl init internally, 442 //so we can cleanup later. 443 data->iOsclInit = osclInit; 444 } 445 } 446 } 447 448 if (error && status == OMX_ErrorNone) 449 status = OMX_ErrorUndefined;//registry error 450 451 return status; 452 } 453 454 455 456 /* De-initializes the component*/ 457 static OMX_ERRORTYPE _OMX_Deinit(OMXGlobalData* data) 458 { 459 OMX_S32 ii; 460 #if PROXY_INTERFACE 461 ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; 462 #endif 463 OMX_HANDLETYPE* componentHandle = data->iComponentHandle; 464 465 466 // go through all component instnaces and delete leftovers if necessary 467 for (ii = 0; ii < MAX_INSTANTIATED_COMPONENTS; ii++) 468 { 469 470 #if PROXY_INTERFACE 471 if (pProxyTerm[ii]) 472 { 473 // delete leftover components 474 // call the OMX_FreeHandle through the proxy 475 if ((componentHandle[ii] != NULL) && (data->ipInstantiatedComponentReg[ii] != NULL)) 476 pProxyTerm[ii]->ProxyFreeHandle(componentHandle[ii]); 477 478 // exit thread 479 pProxyTerm[ii]->Exit(); 480 delete pProxyTerm[ii]; 481 // delete array entries associated with pProxyTerm and Component handle 482 pProxyTerm[ii] = NULL; 483 componentHandle[ii] = NULL; 484 data->ipInstantiatedComponentReg[ii] = NULL; 485 } 486 #else 487 if ((componentHandle[ii] != NULL) && (data->ipInstantiatedComponentReg[ii] != NULL)) 488 { 489 490 // call destructor with the corresponding handle as argument 491 OMX_PTR &aOmxLib = data->ipInstantiatedComponentReg[ii]->SharedLibraryPtr; 492 OMX_PTR aOsclUuid = data->ipInstantiatedComponentReg[ii]->SharedLibraryOsclUuid; 493 OMX_U32 &aRefCount = data->ipInstantiatedComponentReg[ii]->SharedLibraryRefCounter; 494 (data->ipInstantiatedComponentReg[ii]->FunctionPtrDestroyComponent)(componentHandle[ii], aOmxLib, aOsclUuid, aRefCount); 495 } 496 497 componentHandle[ii] = NULL; 498 data->ipInstantiatedComponentReg[ii] = NULL; 499 #endif 500 } 501 502 //Finally de-register all the components 503 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii++) 504 { 505 506 if (data->ipRegTemplateList[ii]) 507 { 508 if (data->ipRegTemplateList[ii]->SharedLibraryOsclUuid) 509 { 510 oscl_free(data->ipRegTemplateList[ii]->SharedLibraryOsclUuid); 511 data->ipRegTemplateList[ii]->SharedLibraryOsclUuid = NULL; 512 } 513 #if USE_DYNAMIC_LOAD_OMX_COMPONENTS 514 if (data->ipRegTemplateList[ii]->SharedLibraryPtr) 515 { 516 OsclSharedLibrary *lib = (OsclSharedLibrary *)(data->ipRegTemplateList[ii]->SharedLibraryPtr); 517 lib->Close(); 518 OSCL_DELETE(lib); 519 data->ipRegTemplateList[ii]->SharedLibraryPtr = NULL; 520 } 521 #endif 522 oscl_free(data->ipRegTemplateList[ii]); 523 data->ipRegTemplateList[ii] = NULL; 524 } 525 else 526 { 527 break; 528 } 529 } 530 531 return OMX_ErrorNone; 532 } 533 534 //this routine is needed to avoid a longjmp clobber warning. 535 static void _Try_OMX_Deinit(int32 &aError, OMX_ERRORTYPE& aStatus, OMXGlobalData* data) 536 { 537 OSCL_TRY(aError, aStatus = _OMX_Deinit(data);); 538 } 539 540 //this routine is needed to avoid a longjmp clobber warning. 541 static void _Try_Data_Cleanup(int32 &aError, OMXGlobalData* aData) 542 { 543 OSCL_TRY(aError, OSCL_DELETE(aData);); 544 } 545 546 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 547 // in case of static build - just redirect master omx core call to local pv core call 548 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterDeinit() 549 { 550 return OMX_Deinit(); 551 } 552 #endif 553 554 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_Deinit() 555 { 556 OMX_ERRORTYPE status = OMX_ErrorNone; 557 558 //Check the global instance counter and only cleanup OMX on the last call. 559 bool osclInit = false; 560 int32 error; 561 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 562 if (data) 563 { 564 data->iInstanceCount--; 565 if (data->iInstanceCount == 0) 566 { 567 //save the "OsclInit" flag to decide whether to cleanup Oscl later. 568 osclInit = data->iOsclInit; 569 570 //Cleanup the OMX globals. 571 _Try_OMX_Deinit(error, status, data); 572 if (error != OsclErrNone) 573 status = OMX_ErrorUndefined;//some leave happened. 574 575 //Regardless of the cleanup result, cleanup the OMX singleton. 576 _Try_Data_Cleanup(error, data); 577 data = NULL; 578 if (error != OsclErrNone) 579 status = OMX_ErrorUndefined;//some leave happened. 580 581 } 582 } 583 584 //Release the singleton. 585 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 586 587 //If this is the last call and we initialized Oscl in OMX_Init, 588 //then clean it up here. 589 if (osclInit) 590 { 591 //cleanup all layers except Oscl scheduler. 592 OsclSelect select; 593 select.iOsclScheduler = false; 594 OsclInit::Cleanup(error, &select); 595 //ignore errors here. 596 } 597 598 return status; 599 } 600 601 #if PROXY_INTERFACE 602 static void _Cleanup_Component(ProxyApplication_OMX* aProxyTerm, OMX_OUT OMX_HANDLETYPE aHandle, 603 OMX_STRING cComponentName) 604 { 605 if (aProxyTerm) 606 { 607 aProxyTerm->Exit(); 608 delete aProxyTerm; 609 } 610 611 if (!aHandle) 612 { 613 return; 614 } 615 616 //find the component destructor and call it 617 OMX_S32 ii; 618 int32 error; 619 620 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 621 622 if (error || !data) 623 { 624 return; 625 } 626 627 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) 628 { 629 // go through the list of supported components and find the component based on its name (identifier) 630 if (data->ipRegTemplateList[ii] != NULL) 631 { 632 if (!oscl_strcmp((data->ipRegTemplateList[ii])->ComponentName, cComponentName)) 633 { 634 // found a matching name. Use this destructor 635 OMX_PTR &aOmxLib = data->ipRegTemplateList[ii]->SharedLibraryPtr; 636 OMX_PTR aOsclUuid = data->ipRegTemplateList[ii]->SharedLibraryOsclUuid; 637 OMX_U32 &aRefCount = data->ipRegTemplateList[ii]->SharedLibraryRefCounter; 638 (data->ipRegTemplateList[ii]->FunctionPtrDestroyComponent)(aHandle, aOmxLib, aOsclUuid, aRefCount); 639 break; 640 } 641 } 642 else 643 { 644 break; 645 } 646 } 647 648 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 649 } 650 #endif 651 652 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 653 // in case of static build - just redirect master omx core call to local pv core call 654 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_MasterGetHandle(OMX_OUT OMX_HANDLETYPE* pHandle, 655 OMX_IN OMX_STRING cComponentName, 656 OMX_IN OMX_PTR pAppData, 657 OMX_IN OMX_CALLBACKTYPE* pCallBacks) 658 { 659 660 return OMX_GetHandle(pHandle,cComponentName,pAppData,pCallBacks); 661 } 662 #endif 663 664 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(OMX_OUT OMX_HANDLETYPE* pHandle, 665 OMX_IN OMX_STRING cComponentName, 666 OMX_IN OMX_PTR pAppData, 667 OMX_IN OMX_CALLBACKTYPE* pCallBacks) 668 { 669 OMX_ERRORTYPE ErrorType = OMX_ErrorNone; 670 int32 error; 671 672 #if PROXY_INTERFACE 673 ProxyApplication_OMX* pTempProxyTerm = new ProxyApplication_OMX; 674 675 if (pTempProxyTerm->GetMemPoolPtr() == NULL) 676 { 677 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 678 ErrorType = OMX_ErrorInsufficientResources; 679 return ErrorType; 680 } 681 pTempProxyTerm->Start(); 682 683 *pHandle = NULL; 684 685 ErrorType = pTempProxyTerm->ProxyGetHandle(pHandle, cComponentName, pAppData, pCallBacks); 686 687 //Get registry to store values 688 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 689 if (error) // can't access registry 690 { 691 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 692 return OMX_ErrorInvalidState; 693 } 694 else if (!data) // singleton object has been destroyed 695 { 696 // Unlock registry before calling cleanup otherwise it'll lead to deadlock. 697 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 698 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 699 return OMX_ErrorInvalidState; 700 } 701 702 if ((NULL != *pHandle) && (OMX_ErrorNone == ErrorType)) 703 { 704 OMX_U32* componentIndex = &(data->iComponentIndex); 705 OMX_HANDLETYPE* componentHandle = data->iComponentHandle; 706 707 // First, find an empty slot in the proxy/component handle array to store the component/proxy handle 708 OMX_U32 jj; 709 for (jj = 0; jj < MAX_INSTANTIATED_COMPONENTS; jj++) 710 { 711 if (componentHandle[jj] == NULL) 712 break; 713 } 714 // can't find a free slot 715 if (jj == MAX_INSTANTIATED_COMPONENTS) 716 { 717 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 718 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 719 ErrorType = OMX_ErrorInsufficientResources; 720 return ErrorType; 721 } 722 else 723 { 724 *componentIndex = jj; 725 } 726 727 ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; 728 729 pProxyTerm[*componentIndex] = pTempProxyTerm; 730 731 // now that we got the component handle, store the handle in the componentHandle array 732 componentHandle[*componentIndex] = *pHandle; 733 734 // record the component destructor function ptr; 735 OMX_S32 ii; 736 OMX_U8 componentFoundflag = false; 737 738 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) 739 { 740 // go through the list of supported components and find the component based on its name (identifier) 741 if (data->ipRegTemplateList[ii] != NULL) 742 { 743 if (!oscl_strcmp((data->ipRegTemplateList[ii])->ComponentName, cComponentName)) 744 { 745 // found a matching name 746 componentFoundflag = true; 747 // save the Registry Ptr into the array of instantiated components 748 data->ipInstantiatedComponentReg[*componentIndex] = data->ipRegTemplateList[ii]; 749 break; 750 } 751 } 752 else 753 { 754 break; 755 } 756 } 757 758 if (!componentFoundflag) 759 { 760 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 761 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 762 763 pProxyTerm[*componentIndex] = NULL; 764 componentHandle[*componentIndex] = NULL; 765 766 ErrorType = OMX_ErrorComponentNotFound; 767 return ErrorType; 768 } 769 770 data->iNumBaseInstance++; 771 if (data->iNumBaseInstance > MAX_INSTANTIATED_COMPONENTS) 772 { 773 //Cleanup and unlock registry 774 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 775 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 776 777 pProxyTerm[*componentIndex] = NULL; 778 componentHandle[*componentIndex] = NULL; 779 data->ipInstantiatedComponentReg[*componentIndex] = NULL; 780 781 ErrorType = OMX_ErrorInsufficientResources; 782 return ErrorType; 783 } 784 } 785 else 786 { 787 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 788 _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); 789 790 ErrorType = OMX_ErrorUndefined; 791 return ErrorType; 792 } 793 794 #else 795 //Get registry to store values 796 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 797 if (error) // can't access registry 798 { 799 return OMX_ErrorInvalidState; 800 } 801 else if (!data) // singleton object has been destroyed 802 { 803 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 804 return OMX_ErrorInvalidState; 805 } 806 807 OMX_U32* componentIndex = &(data->iComponentIndex); 808 OMX_HANDLETYPE* componentHandle = data->iComponentHandle; 809 810 // First, find an empty slot in the proxy/component handle array to store the component/proxy handle 811 OMX_U32 jj; 812 for (jj = 0; jj < MAX_INSTANTIATED_COMPONENTS; jj++) 813 { 814 if (componentHandle[jj] == NULL) 815 break; 816 } 817 // can't find a free slot 818 if (jj == MAX_INSTANTIATED_COMPONENTS) 819 { 820 //Release the singleton. 821 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 822 ErrorType = OMX_ErrorInsufficientResources; 823 return ErrorType; 824 } 825 else 826 { 827 *componentIndex = jj; 828 } 829 830 OMX_S32 ii; 831 832 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) 833 { 834 // go through the list of supported components and find the component based on its name (identifier) 835 if (data->ipRegTemplateList[ii] != NULL) 836 { 837 if (!oscl_strcmp((data->ipRegTemplateList[ii])->ComponentName, cComponentName)) 838 { 839 // found a matching name 840 // call the factory for the component 841 OMX_STRING aOmxLibName = data->ipRegTemplateList[ii]->SharedLibraryName; 842 OMX_PTR &aOmxLib = data->ipRegTemplateList[ii]->SharedLibraryPtr; 843 OMX_PTR aOsclUuid = data->ipRegTemplateList[ii]->SharedLibraryOsclUuid; 844 OMX_U32 &aRefCount = data->ipRegTemplateList[ii]->SharedLibraryRefCounter; 845 if ((data->ipRegTemplateList[ii]->FunctionPtrCreateComponent)(pHandle, pAppData, NULL, aOmxLibName, aOmxLib, aOsclUuid, aRefCount) == OMX_ErrorNone) 846 { 847 // now that we got the component handle, store the handle in the componentHandle array 848 componentHandle[*componentIndex] = *pHandle; 849 850 // also, record the component registration info to be able to destroy it 851 data->ipInstantiatedComponentReg[*componentIndex] = (data->ipRegTemplateList[ii]); 852 853 data->iNumBaseInstance++; 854 855 if (data->iNumBaseInstance > MAX_INSTANTIATED_COMPONENTS) 856 { 857 //cleanup 858 ((data->ipRegTemplateList[ii])->FunctionPtrDestroyComponent)(componentHandle[*componentIndex], aOmxLib, aOsclUuid, aRefCount); 859 componentHandle[*componentIndex] = NULL; 860 data->ipInstantiatedComponentReg[*componentIndex] = NULL; 861 862 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 863 ErrorType = OMX_ErrorInsufficientResources; 864 return ErrorType; 865 } 866 867 ((OMX_COMPONENTTYPE*)*pHandle)->SetCallbacks(*pHandle, pCallBacks, pAppData); 868 } 869 else 870 { 871 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 872 ErrorType = OMX_ErrorInsufficientResources; 873 return ErrorType; 874 } 875 } 876 877 } 878 else 879 { 880 break; 881 } 882 883 } 884 // can't find the component after going through all of them 885 if (componentHandle[*componentIndex] == NULL) 886 { 887 ErrorType = OMX_ErrorComponentNotFound; 888 } 889 890 #endif 891 892 //Release the singleton 893 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 894 if (error) 895 { 896 //registry error 897 return OMX_ErrorInvalidState; 898 } 899 900 return ErrorType; 901 } 902 903 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 904 // in case of static build - just redirect master omx core call to local pv core call 905 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_MasterFreeHandle(OMX_IN OMX_HANDLETYPE hComponent) 906 { 907 return OMX_FreeHandle(hComponent); 908 } 909 #endif 910 911 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) 912 { 913 OMX_ERRORTYPE ErrorType = OMX_ErrorNone; 914 int32 error; 915 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 916 if (error) // can't access registry 917 { 918 return OMX_ErrorInvalidState; 919 } 920 else if (!data) // singleton object has been destroyed 921 { 922 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 923 return OMX_ErrorInvalidState; 924 } 925 926 OMX_S32 ii, ComponentNumber = 0; 927 928 // Find the component index in the array of handles 929 for (ii = 0; ii < MAX_INSTANTIATED_COMPONENTS ; ii++) 930 { 931 if (hComponent == data->iComponentHandle[ii]) 932 { 933 ComponentNumber = ii; 934 break; 935 } 936 } 937 938 // cannot find the component handle 939 if (ii == MAX_INSTANTIATED_COMPONENTS) 940 { 941 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 942 ErrorType = OMX_ErrorInvalidComponent; 943 return ErrorType; 944 } 945 946 #if PROXY_INTERFACE 947 ProxyApplication_OMX* pTempProxyTerm = data->ipProxyTerm[ComponentNumber]; 948 949 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 950 if (error) 951 { 952 ErrorType = OMX_ErrorUndefined; 953 return ErrorType; 954 } 955 // call the OMX_FreeHandle through the proxy 956 ErrorType = pTempProxyTerm->ProxyFreeHandle(hComponent); 957 958 // exit thread 959 pTempProxyTerm->Exit(); 960 961 data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); 962 if (error) // can't access registry 963 { 964 return OMX_ErrorInvalidState; 965 } 966 else if (!data) // singleton object has been destroyed 967 { 968 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 969 return OMX_ErrorInvalidState; 970 } 971 972 ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; 973 974 delete pProxyTerm[ComponentNumber]; 975 // delete array entries associated with pProxyTerm and Component handle 976 pProxyTerm[ComponentNumber] = NULL; 977 data->iComponentHandle[ComponentNumber] = NULL; 978 data->ipInstantiatedComponentReg[ComponentNumber] = NULL; 979 980 #else 981 982 // call the component AO destructor through the function pointer 983 OMX_PTR &aOmxLib = data->ipInstantiatedComponentReg[ii]->SharedLibraryPtr; 984 OMX_PTR aOsclUuid = data->ipInstantiatedComponentReg[ii]->SharedLibraryOsclUuid; 985 OMX_U32 &aRefCount = data->ipInstantiatedComponentReg[ii]->SharedLibraryRefCounter; 986 ErrorType = (data->ipInstantiatedComponentReg[ComponentNumber]->FunctionPtrDestroyComponent)(hComponent, aOmxLib, aOsclUuid, aRefCount); 987 988 data->iComponentHandle[ComponentNumber] = NULL; 989 data->ipInstantiatedComponentReg[ComponentNumber] = NULL; 990 991 data->iNumBaseInstance--; 992 993 #endif 994 995 //Release the singleton. 996 OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); 997 if (error) 998 { 999 ErrorType = OMX_ErrorUndefined; 1000 return ErrorType; 1001 } 1002 return ErrorType; 1003 1004 } 1005 1006 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 1007 // in case of static build - just redirect master omx core call to local pv core call 1008 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_MasterComponentNameEnum( 1009 OMX_OUT OMX_STRING cComponentName, 1010 OMX_IN OMX_U32 nNameLength, 1011 OMX_IN OMX_U32 nIndex) 1012 { 1013 return OMX_ComponentNameEnum(cComponentName,nNameLength,nIndex); 1014 } 1015 #endif 1016 1017 //This is a method to be called directly under testapp thread 1018 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( 1019 OMX_OUT OMX_STRING cComponentName, 1020 OMX_IN OMX_U32 nNameLength, 1021 OMX_IN OMX_U32 nIndex) 1022 { 1023 int32 error; 1024 1025 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::getInstance(OSCL_SINGLETON_ID_OMX, error); 1026 if (!data) 1027 { 1028 return OMX_ErrorUndefined; 1029 } 1030 OMX_U32 Index = 0; 1031 1032 while (data->ipRegTemplateList[Index] != NULL) 1033 { 1034 if (Index == nIndex) 1035 { 1036 break; 1037 } 1038 Index++; 1039 } 1040 1041 if (data->ipRegTemplateList[Index] != NULL) 1042 { 1043 oscl_strncpy(cComponentName, (data->ipRegTemplateList[Index])->ComponentName, nNameLength); 1044 } 1045 else 1046 { 1047 return OMX_ErrorNoMore; 1048 } 1049 1050 return OMX_ErrorNone; 1051 1052 } 1053 1054 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 1055 // in case of static build - just redirect master omx core call to local pv core call 1056 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterSetupTunnel( 1057 OMX_IN OMX_HANDLETYPE hOutput, 1058 OMX_IN OMX_U32 nPortOutput, 1059 OMX_IN OMX_HANDLETYPE hInput, 1060 OMX_IN OMX_U32 nPortInput) 1061 { 1062 return OMX_SetupTunnel(hOutput,nPortOutput,hInput,nPortInput); 1063 } 1064 #endif 1065 1066 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_SetupTunnel( 1067 OMX_IN OMX_HANDLETYPE hOutput, 1068 OMX_IN OMX_U32 nPortOutput, 1069 OMX_IN OMX_HANDLETYPE hInput, 1070 OMX_IN OMX_U32 nPortInput) 1071 { 1072 OSCL_UNUSED_ARG(hOutput); 1073 OSCL_UNUSED_ARG(nPortOutput); 1074 OSCL_UNUSED_ARG(hInput); 1075 OSCL_UNUSED_ARG(nPortInput); 1076 return OMX_ErrorNotImplemented; 1077 } 1078 1079 1080 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 1081 // in case of static build - just redirect master omx core call to local pv core call 1082 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterGetContentPipe( 1083 OMX_OUT OMX_HANDLETYPE *hPipe, 1084 OMX_IN OMX_STRING szURI) 1085 { 1086 return OMX_GetContentPipe(hPipe,szURI); 1087 } 1088 #endif 1089 1090 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetContentPipe( 1091 OMX_OUT OMX_HANDLETYPE *hPipe, 1092 OMX_IN OMX_STRING szURI) 1093 { 1094 OSCL_UNUSED_ARG(hPipe); 1095 OSCL_UNUSED_ARG(szURI); 1096 return OMX_ErrorNotImplemented; 1097 } 1098 1099 1100 ///////////////////////////////////////////////////// 1101 /////////////// Given a compName, find the component and then return its role(s) 1102 ///////////////// It's the caller's responsibility to provide enough space for the role(s) 1103 //////////////////////////////////////////////////////////////////////////// 1104 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 1105 // in case of static build - just redirect master omx core call to local pv core call 1106 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterGetRolesOfComponent( 1107 OMX_IN OMX_STRING compName, 1108 OMX_INOUT OMX_U32* pNumRoles, 1109 OMX_OUT OMX_U8** roles) 1110 { 1111 return OMX_GetRolesOfComponent(compName, pNumRoles, roles); 1112 } 1113 #endif 1114 1115 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetRolesOfComponent( 1116 OMX_IN OMX_STRING compName, 1117 OMX_INOUT OMX_U32* pNumRoles, 1118 OMX_OUT OMX_U8** roles) 1119 { 1120 int32 error; 1121 1122 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::getInstance(OSCL_SINGLETON_ID_OMX, error); 1123 if (!data) 1124 { 1125 return OMX_ErrorUndefined; 1126 } 1127 1128 OMX_STRING RoleString[MAX_ROLES_SUPPORTED]; 1129 OMX_U32 ii; 1130 1131 // first check if there is a component with the correct name 1132 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) 1133 { 1134 if (data->ipRegTemplateList[ii]) 1135 { 1136 if (!oscl_strcmp(data->ipRegTemplateList[ii]->ComponentName, compName)) 1137 { 1138 (data->ipRegTemplateList[ii])->GetRolesOfComponent(RoleString); 1139 break; 1140 } 1141 } 1142 } 1143 1144 if (ii == MAX_SUPPORTED_COMPONENTS) 1145 { 1146 // component not found 1147 *pNumRoles = 0; 1148 return OMX_ErrorInvalidComponent; 1149 } 1150 1151 1152 // Return the number of roles supported by the component. 1153 *pNumRoles = (data->ipRegTemplateList[ii])->NumberOfRolesSupported; 1154 if (roles != NULL) 1155 { 1156 for (ii = 0; ii < *pNumRoles; ii++) 1157 { 1158 oscl_strncpy((OMX_STRING) roles[ii], (OMX_STRING)RoleString[ii], oscl_strlen((OMX_STRING)RoleString[ii]) + 1); 1159 } 1160 } 1161 1162 return OMX_ErrorNone; 1163 } 1164 1165 ///////////////////////////////////////////////////////////////////////// 1166 ////////// Given a role (say "video_decoder.avc") give the number (and a list) of 1167 ///////////components that support the role 1168 /////////// It is the callers responsibility to provide enough space for component names, 1169 //////////// so it may need to make the call twice. Once to find number of components, and 2nd time 1170 //////////// to find their actual names 1171 ////////////////////////////////////////////////////////////////////////////////// 1172 #if (USE_DYNAMIC_LOAD_OMX_COMPONENTS == 0) 1173 // in case of static build - just redirect master omx core call to local pv core call 1174 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterGetComponentsOfRole( 1175 OMX_IN OMX_STRING role, 1176 OMX_INOUT OMX_U32 *pNumComps, 1177 OMX_INOUT OMX_U8 **compNames) 1178 { 1179 return OMX_GetComponentsOfRole(role, pNumComps, compNames); 1180 } 1181 #endif 1182 1183 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetComponentsOfRole( 1184 OMX_IN OMX_STRING role, 1185 OMX_INOUT OMX_U32 *pNumComps, 1186 OMX_INOUT OMX_U8 **compNames) 1187 { 1188 int32 error; 1189 1190 OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::getInstance(OSCL_SINGLETON_ID_OMX, error); 1191 if (!data) 1192 { 1193 return OMX_ErrorUndefined; 1194 } 1195 1196 OMX_U32 ii, jj; 1197 OMX_STRING RoleString[MAX_ROLES_SUPPORTED]; 1198 // initialize 1199 *pNumComps = 0; 1200 1201 // go through all components and check if they support the given role 1202 for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) 1203 { 1204 if (data->ipRegTemplateList[ii]) 1205 { 1206 // get the component role 1207 (data->ipRegTemplateList[ii])->GetRolesOfComponent(RoleString); 1208 1209 for (jj = 0; jj < (data->ipRegTemplateList[ii])->NumberOfRolesSupported; jj++) 1210 { 1211 // if the role matches, increment the counter and record the comp. name 1212 if (!oscl_strcmp(RoleString[jj], role)) 1213 { 1214 // if a placeholder for compNames is provided, copy the component name into it 1215 if (compNames != NULL) 1216 { 1217 oscl_strncpy((OMX_STRING) compNames[*pNumComps], (data->ipRegTemplateList[ii])->ComponentName, 1218 oscl_strlen((data->ipRegTemplateList[ii])->ComponentName) + 1); 1219 } 1220 // increment the counter 1221 *pNumComps = (*pNumComps + 1); 1222 } 1223 1224 } 1225 } 1226 } 1227 1228 return OMX_ErrorNone; 1229 1230 } 1231 1232