• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
OSCL_DLL_ENTRY_POINT_DEFAULT()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
_Try_OMX_Init(int32 & aError,OMX_ERRORTYPE & aStatus)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
_Try_OMX_Create(int32 & aError,OMXGlobalData * & aData)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
OMX_MasterInit()365 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterInit()
366 {
367     return OMX_Init();
368 }
369 #endif
370 
OMX_Init()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*/
_OMX_Deinit(OMXGlobalData * data)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.
_Try_OMX_Deinit(int32 & aError,OMX_ERRORTYPE & aStatus,OMXGlobalData * data)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.
_Try_Data_Cleanup(int32 & aError,OMXGlobalData * aData)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
OMX_MasterDeinit()548 OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterDeinit()
549 {
550     return OMX_Deinit();
551 }
552 #endif
553 
OMX_Deinit()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
_Cleanup_Component(ProxyApplication_OMX * aProxyTerm,OMX_OUT OMX_HANDLETYPE aHandle,OMX_STRING cComponentName)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
OMX_MasterGetHandle(OMX_OUT OMX_HANDLETYPE * pHandle,OMX_IN OMX_STRING cComponentName,OMX_IN OMX_PTR pAppData,OMX_IN OMX_CALLBACKTYPE * pCallBacks)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 
OMX_GetHandle(OMX_OUT OMX_HANDLETYPE * pHandle,OMX_IN OMX_STRING cComponentName,OMX_IN OMX_PTR pAppData,OMX_IN OMX_CALLBACKTYPE * pCallBacks)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
OMX_MasterFreeHandle(OMX_IN OMX_HANDLETYPE hComponent)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 
OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent)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
OMX_MasterComponentNameEnum(OMX_OUT OMX_STRING cComponentName,OMX_IN OMX_U32 nNameLength,OMX_IN OMX_U32 nIndex)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
OMX_ComponentNameEnum(OMX_OUT OMX_STRING cComponentName,OMX_IN OMX_U32 nNameLength,OMX_IN OMX_U32 nIndex)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
OMX_MasterSetupTunnel(OMX_IN OMX_HANDLETYPE hOutput,OMX_IN OMX_U32 nPortOutput,OMX_IN OMX_HANDLETYPE hInput,OMX_IN OMX_U32 nPortInput)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 
OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE hOutput,OMX_IN OMX_U32 nPortOutput,OMX_IN OMX_HANDLETYPE hInput,OMX_IN OMX_U32 nPortInput)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
OMX_MasterGetContentPipe(OMX_OUT OMX_HANDLETYPE * hPipe,OMX_IN OMX_STRING szURI)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 
OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE * hPipe,OMX_IN OMX_STRING szURI)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
OMX_MasterGetRolesOfComponent(OMX_IN OMX_STRING compName,OMX_INOUT OMX_U32 * pNumRoles,OMX_OUT OMX_U8 ** roles)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 
OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,OMX_INOUT OMX_U32 * pNumRoles,OMX_OUT OMX_U8 ** roles)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
OMX_MasterGetComponentsOfRole(OMX_IN OMX_STRING role,OMX_INOUT OMX_U32 * pNumComps,OMX_INOUT OMX_U8 ** compNames)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 
OMX_GetComponentsOfRole(OMX_IN OMX_STRING role,OMX_INOUT OMX_U32 * pNumComps,OMX_INOUT OMX_U8 ** compNames)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