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