| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #ifndef OSCL_BASE_H_INCLUDED |
| #include "oscl_base.h" |
| #endif |
| |
| #ifndef PV_OMXDEFS_H_INCLUDED |
| #include "pv_omxdefs.h" |
| #endif |
| |
| #ifndef OMX_Component_h |
| #include "omx_component.h" |
| #endif |
| |
| #ifndef PV_OMXCORE_H_INCLUDED |
| #include "pv_omxcore.h" |
| #endif |
| |
| #ifndef OSCL_MEM_BASIC_FUNCTIONS_H |
| #include "oscl_mem_basic_functions.h" |
| #endif |
| |
| #ifndef OSCL_STDSTRING_H_INCLUDED |
| #include "oscl_stdstring.h" |
| #endif |
| |
| #ifndef OSCL_ERROR_H_INCLUDED |
| #include "oscl_error.h" |
| #endif |
| |
| #ifndef OSCL_INIT_H_INCLUDED |
| #include "oscl_init.h" |
| #endif |
| |
| // pv_omxregistry.h is only needed if NOT using CML2 |
| #ifndef USE_CML2_CONFIG |
| #include "pv_omxregistry.h" |
| #endif |
| |
| #include "oscl_init.h" |
| |
| // Use default DLL entry point |
| #ifndef OSCL_DLL_H_INCLUDED |
| #include "oscl_dll.h" |
| #endif |
| |
| #if REGISTER_OMX_M4V_COMPONENT |
| OMX_ERRORTYPE Mpeg4Register(); |
| #endif |
| |
| #if REGISTER_OMX_H263_COMPONENT |
| OMX_ERRORTYPE H263Register(); |
| #endif |
| |
| #if REGISTER_OMX_AVC_COMPONENT |
| OMX_ERRORTYPE AvcRegister(); |
| #endif |
| |
| #if REGISTER_OMX_WMV_COMPONENT |
| OMX_ERRORTYPE WmvRegister(); |
| #endif |
| |
| #if REGISTER_OMX_AAC_COMPONENT |
| OMX_ERRORTYPE AacRegister(); |
| #endif |
| |
| #if REGISTER_OMX_AMR_COMPONENT |
| OMX_ERRORTYPE AmrRegister(); |
| #endif |
| |
| #if REGISTER_OMX_MP3_COMPONENT |
| OMX_ERRORTYPE Mp3Register(); |
| #endif |
| |
| #if REGISTER_OMX_WMA_COMPONENT |
| OMX_ERRORTYPE WmaRegister(); |
| #endif |
| |
| #if REGISTER_OMX_AMRENC_COMPONENT |
| OMX_ERRORTYPE AmrEncRegister(); |
| #endif |
| |
| #if REGISTER_OMX_M4VENC_COMPONENT |
| OMX_ERRORTYPE Mpeg4EncRegister(); |
| #endif |
| |
| #if REGISTER_OMX_H263ENC_COMPONENT |
| OMX_ERRORTYPE H263EncRegister(); |
| #endif |
| |
| #if REGISTER_OMX_AVCENC_COMPONENT |
| OMX_ERRORTYPE AvcEncRegister(); |
| #endif |
| |
| #if REGISTER_OMX_AACENC_COMPONENT |
| OMX_ERRORTYPE AacEncRegister(); |
| #endif |
| |
| OSCL_DLL_ENTRY_POINT_DEFAULT() |
| |
| /* Initializes the component */ |
| static OMX_ERRORTYPE _OMX_Init() |
| { |
| OMX_ERRORTYPE Status = OMX_ErrorNone; |
| int32 error; |
| //get global data structure |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (error) // can't access registry |
| { |
| return OMX_ErrorInsufficientResources; |
| } |
| else if (!data) // singleton object has been destroyed |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| #if PROXY_INTERFACE |
| ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; |
| #endif |
| OMX_U32 ii; |
| |
| /* Initialize template list to NULL at the beginning */ |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii++) |
| { |
| data->ipRegTemplateList[ii] = NULL; |
| } |
| |
| for (ii = 0; ii < MAX_INSTANTIATED_COMPONENTS; ii++) |
| { |
| data->iComponentHandle[ii] = NULL; |
| data->ipInstantiatedComponentReg[ii] = NULL; |
| #if PROXY_INTERFACE |
| pProxyTerm[ii] = NULL; |
| #endif |
| } |
| |
| //Release the singleton. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| if (error) |
| { |
| //registry error |
| Status = OMX_ErrorUndefined; |
| return Status; |
| } |
| |
| // REGISTER COMPONENT TYPES (ONE BY ONE) |
| #if REGISTER_OMX_M4V_COMPONENT |
| // MPEG4 |
| Status = Mpeg4Register(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_H263_COMPONENT |
| //H263 |
| Status = H263Register(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_AVC_COMPONENT |
| // AVC |
| Status = AvcRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_WMV_COMPONENT |
| // WMV |
| Status = WmvRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_AAC_COMPONENT |
| // AAC |
| Status = AacRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_AMR_COMPONENT |
| // AMR |
| Status = AmrRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_MP3_COMPONENT |
| // MP3 |
| Status = Mp3Register(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_WMA_COMPONENT |
| // WMA |
| Status = WmaRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_AMRENC_COMPONENT |
| //AMR ENCODER |
| Status = AmrEncRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_M4VENC_COMPONENT |
| //MPEG4 Encoder |
| Status = Mpeg4EncRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_H263ENC_COMPONENT |
| //H263 Encoder |
| Status = H263EncRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| #if REGISTER_OMX_AVCENC_COMPONENT |
| //H264/AVC Encoder |
| Status = AvcEncRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| #if REGISTER_OMX_AACENC_COMPONENT |
| //AAC Encoder |
| Status = AacEncRegister(); |
| if (Status != OMX_ErrorNone) |
| return Status; |
| #endif |
| |
| return OMX_ErrorNone; |
| } |
| |
| //this routine is needed to avoid a longjmp clobber warning |
| static void _Try_OMX_Init(int32& aError, OMX_ERRORTYPE& aStatus) |
| { |
| OSCL_TRY(aError, aStatus = _OMX_Init();); |
| } |
| //this routine is needed to avoid a longjmp clobber warning |
| static void _Try_OMX_Create(int32& aError, OMXGlobalData*& aData) |
| { |
| OSCL_TRY(aError, aData = OSCL_NEW(OMXGlobalData, ());); |
| } |
| |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_Init() |
| { |
| OMX_ERRORTYPE status = OMX_ErrorNone; |
| |
| //Check the global instance counter and only init OMX on the first call. |
| bool osclInit = false; |
| int32 error; |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| |
| //Check for whether Oscl is initialized in this thread. If not, we will |
| //initialize it here. |
| if (error == EPVErrorBaseNotInstalled) |
| { |
| //init all Oscl layers except Oscl scheduler. |
| OsclSelect select; |
| select.iOsclScheduler = false; |
| OsclInit::Init(error, &select); |
| if (error) |
| { |
| status = OMX_ErrorUndefined;//can't init Oscl |
| return status; |
| } |
| else |
| { |
| osclInit = true; |
| } |
| } |
| |
| if (data) |
| { |
| //Just update the instance counter. |
| data->iInstanceCount++; |
| |
| //Release the singleton. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| if (error) |
| { |
| status = OMX_ErrorUndefined; |
| return status; |
| } |
| } |
| else |
| { |
| //First call-- |
| //create the OMX singleton |
| _Try_OMX_Create(error, data); |
| if (error != OsclErrNone) |
| { |
| status = OMX_ErrorInsufficientResources;//some leave happened. |
| } |
| |
| //Release the singleton. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| if (error) |
| { |
| //registry error |
| status = OMX_ErrorUndefined; |
| return status; |
| } |
| |
| //If create succeeded, then init the OMX globals. |
| if (status == OMX_ErrorNone) |
| { |
| _Try_OMX_Init(error, status); |
| if (error != OsclErrNone) |
| { |
| status = OMX_ErrorUndefined;//probably no memory. |
| } |
| else |
| { |
| //keep track of whether we did Oscl init internally, |
| //so we can cleanup later. |
| data->iOsclInit = osclInit; |
| } |
| } |
| } |
| |
| if (error && status == OMX_ErrorNone) |
| status = OMX_ErrorUndefined;//registry error |
| |
| return status; |
| } |
| |
| |
| |
| /* De-initializes the component*/ |
| static OMX_ERRORTYPE _OMX_Deinit(OMXGlobalData* data) |
| { |
| OMX_S32 ii; |
| #if PROXY_INTERFACE |
| ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; |
| #endif |
| OMX_HANDLETYPE* componentHandle = data->iComponentHandle; |
| |
| |
| // go through all component instnaces and delete leftovers if necessary |
| for (ii = 0; ii < MAX_INSTANTIATED_COMPONENTS; ii++) |
| { |
| |
| #if PROXY_INTERFACE |
| if (pProxyTerm[ii]) |
| { |
| // delete leftover components |
| // call the OMX_FreeHandle through the proxy |
| if ((componentHandle[ii] != NULL) && (data->ipInstantiatedComponentReg[ii] != NULL)) |
| pProxyTerm[ii]->ProxyFreeHandle(componentHandle[ii]); |
| |
| // exit thread |
| pProxyTerm[ii]->Exit(); |
| delete pProxyTerm[ii]; |
| // delete array entries associated with pProxyTerm and Component handle |
| pProxyTerm[ii] = NULL; |
| componentHandle[ii] = NULL; |
| data->ipInstantiatedComponentReg[ii] = NULL; |
| } |
| #else |
| if ((componentHandle[ii] != NULL) && (data->ipInstantiatedComponentReg[ii] != NULL)) |
| { |
| |
| // call destructor with the corresponding handle as argument |
| OMX_PTR &aOmxLib = data->ipInstantiatedComponentReg[ii]->SharedLibraryPtr; |
| OMX_PTR aOsclUuid = data->ipInstantiatedComponentReg[ii]->SharedLibraryOsclUuid; |
| OMX_U32 &aRefCount = data->ipInstantiatedComponentReg[ii]->SharedLibraryRefCounter; |
| (data->ipInstantiatedComponentReg[ii]->FunctionPtrDestroyComponent)(componentHandle[ii], aOmxLib, aOsclUuid, aRefCount); |
| } |
| |
| componentHandle[ii] = NULL; |
| data->ipInstantiatedComponentReg[ii] = NULL; |
| #endif |
| } |
| |
| //Finally de-register all the components |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii++) |
| { |
| |
| if (data->ipRegTemplateList[ii]) |
| { |
| if (data->ipRegTemplateList[ii]->SharedLibraryOsclUuid) |
| { |
| oscl_free(data->ipRegTemplateList[ii]->SharedLibraryOsclUuid); |
| data->ipRegTemplateList[ii]->SharedLibraryOsclUuid = NULL; |
| } |
| #if USE_DYNAMIC_LOAD_OMX_COMPONENTS |
| if (data->ipRegTemplateList[ii]->SharedLibraryPtr) |
| { |
| OsclSharedLibrary *lib = (OsclSharedLibrary *)(data->ipRegTemplateList[ii]->SharedLibraryPtr); |
| lib->Close(); |
| OSCL_DELETE(lib); |
| data->ipRegTemplateList[ii]->SharedLibraryPtr = NULL; |
| } |
| #endif |
| oscl_free(data->ipRegTemplateList[ii]); |
| data->ipRegTemplateList[ii] = NULL; |
| } |
| else |
| { |
| break; |
| } |
| } |
| |
| return OMX_ErrorNone; |
| } |
| |
| //this routine is needed to avoid a longjmp clobber warning. |
| static void _Try_OMX_Deinit(int32 &aError, OMX_ERRORTYPE& aStatus, OMXGlobalData* data) |
| { |
| OSCL_TRY(aError, aStatus = _OMX_Deinit(data);); |
| } |
| |
| //this routine is needed to avoid a longjmp clobber warning. |
| static void _Try_Data_Cleanup(int32 &aError, OMXGlobalData* aData) |
| { |
| OSCL_TRY(aError, OSCL_DELETE(aData);); |
| } |
| |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_Deinit() |
| { |
| OMX_ERRORTYPE status = OMX_ErrorNone; |
| |
| //Check the global instance counter and only cleanup OMX on the last call. |
| bool osclInit = false; |
| int32 error; |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (data) |
| { |
| data->iInstanceCount--; |
| if (data->iInstanceCount == 0) |
| { |
| //save the "OsclInit" flag to decide whether to cleanup Oscl later. |
| osclInit = data->iOsclInit; |
| |
| //Cleanup the OMX globals. |
| _Try_OMX_Deinit(error, status, data); |
| if (error != OsclErrNone) |
| status = OMX_ErrorUndefined;//some leave happened. |
| |
| //Regardless of the cleanup result, cleanup the OMX singleton. |
| _Try_Data_Cleanup(error, data); |
| data = NULL; |
| if (error != OsclErrNone) |
| status = OMX_ErrorUndefined;//some leave happened. |
| |
| } |
| } |
| |
| //Release the singleton. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| |
| //If this is the last call and we initialized Oscl in OMX_Init, |
| //then clean it up here. |
| if (osclInit) |
| { |
| //cleanup all layers except Oscl scheduler. |
| OsclSelect select; |
| select.iOsclScheduler = false; |
| OsclInit::Cleanup(error, &select); |
| //ignore errors here. |
| } |
| |
| return status; |
| } |
| |
| #if PROXY_INTERFACE |
| static void _Cleanup_Component(ProxyApplication_OMX* aProxyTerm, OMX_OUT OMX_HANDLETYPE aHandle, |
| OMX_STRING cComponentName) |
| { |
| if (aProxyTerm) |
| { |
| aProxyTerm->Exit(); |
| delete aProxyTerm; |
| } |
| |
| if (!aHandle) |
| { |
| return; |
| } |
| |
| //find the component destructor and call it |
| OMX_S32 ii; |
| int32 error; |
| |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| |
| if (error || !data) |
| { |
| return; |
| } |
| |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) |
| { |
| // go through the list of supported components and find the component based on its name (identifier) |
| if (data->ipRegTemplateList[ii] != NULL) |
| { |
| if (!oscl_strcmp((data->ipRegTemplateList[ii])->ComponentName, cComponentName)) |
| { |
| // found a matching name. Use this destructor |
| OMX_PTR &aOmxLib = data->ipRegTemplateList[ii]->SharedLibraryPtr; |
| OMX_PTR aOsclUuid = data->ipRegTemplateList[ii]->SharedLibraryOsclUuid; |
| OMX_U32 &aRefCount = data->ipRegTemplateList[ii]->SharedLibraryRefCounter; |
| (data->ipRegTemplateList[ii]->FunctionPtrDestroyComponent)(aHandle, aOmxLib, aOsclUuid, aRefCount); |
| break; |
| } |
| } |
| else |
| { |
| break; |
| } |
| } |
| |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| } |
| #endif |
| |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(OMX_OUT OMX_HANDLETYPE* pHandle, |
| OMX_IN OMX_STRING cComponentName, |
| OMX_IN OMX_PTR pAppData, |
| OMX_IN OMX_CALLBACKTYPE* pCallBacks) |
| { |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| int32 error; |
| |
| #if PROXY_INTERFACE |
| ProxyApplication_OMX* pTempProxyTerm = new ProxyApplication_OMX; |
| |
| if (pTempProxyTerm->GetMemPoolPtr() == NULL) |
| { |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| ErrorType = OMX_ErrorInsufficientResources; |
| return ErrorType; |
| } |
| pTempProxyTerm->Start(); |
| |
| ErrorType = pTempProxyTerm->ProxyGetHandle(pHandle, cComponentName, pAppData, pCallBacks); |
| |
| //Get registry to store values |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (error) // can't access registry |
| { |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| return OMX_ErrorInvalidState; |
| } |
| else if (!data) // singleton object has been destroyed |
| { |
| // Unlock registry before calling cleanup otherwise it'll lead to deadlock. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| return OMX_ErrorInvalidState; |
| } |
| |
| OMX_U32* componentIndex = &(data->iComponentIndex); |
| OMX_HANDLETYPE* componentHandle = data->iComponentHandle; |
| |
| // First, find an empty slot in the proxy/component handle array to store the component/proxy handle |
| OMX_U32 jj; |
| for (jj = 0; jj < MAX_INSTANTIATED_COMPONENTS; jj++) |
| { |
| if (componentHandle[jj] == NULL) |
| break; |
| } |
| // can't find a free slot |
| if (jj == MAX_INSTANTIATED_COMPONENTS) |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| ErrorType = OMX_ErrorInsufficientResources; |
| return ErrorType; |
| } |
| else |
| { |
| *componentIndex = jj; |
| } |
| |
| ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; |
| |
| pProxyTerm[*componentIndex] = pTempProxyTerm; |
| |
| if (*pHandle) |
| { |
| // now that we got the component handle, store the handle in the componentHandle array |
| componentHandle[*componentIndex] = *pHandle; |
| |
| // record the component destructor function ptr; |
| OMX_S32 ii; |
| OMX_U8 componentFoundflag = false; |
| |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) |
| { |
| // go through the list of supported components and find the component based on its name (identifier) |
| if (data->ipRegTemplateList[ii] != NULL) |
| { |
| if (!oscl_strcmp((data->ipRegTemplateList[ii])->ComponentName, cComponentName)) |
| { |
| // found a matching name |
| componentFoundflag = true; |
| // save the Registry Ptr into the array of instantiated components |
| data->ipInstantiatedComponentReg[*componentIndex] = data->ipRegTemplateList[ii]; |
| break; |
| } |
| } |
| else |
| { |
| break; |
| } |
| } |
| |
| if (!componentFoundflag) |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| |
| pProxyTerm[*componentIndex] = NULL; |
| componentHandle[*componentIndex] = NULL; |
| |
| ErrorType = OMX_ErrorComponentNotFound; |
| return ErrorType; |
| } |
| |
| data->iNumBaseInstance++; |
| if (data->iNumBaseInstance > MAX_INSTANTIATED_COMPONENTS) |
| { |
| //Cleanup and unlock registry |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| |
| pProxyTerm[*componentIndex] = NULL; |
| componentHandle[*componentIndex] = NULL; |
| data->ipInstantiatedComponentReg[*componentIndex] = NULL; |
| |
| ErrorType = OMX_ErrorInsufficientResources; |
| return ErrorType; |
| } |
| } |
| else |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| _Cleanup_Component(pTempProxyTerm, *pHandle, cComponentName); |
| |
| ErrorType = OMX_ErrorUndefined; |
| return ErrorType; |
| } |
| |
| #else |
| //Get registry to store values |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (error) // can't access registry |
| { |
| return OMX_ErrorInvalidState; |
| } |
| else if (!data) // singleton object has been destroyed |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| return OMX_ErrorInvalidState; |
| } |
| |
| OMX_U32* componentIndex = &(data->iComponentIndex); |
| OMX_HANDLETYPE* componentHandle = data->iComponentHandle; |
| |
| // First, find an empty slot in the proxy/component handle array to store the component/proxy handle |
| OMX_U32 jj; |
| for (jj = 0; jj < MAX_INSTANTIATED_COMPONENTS; jj++) |
| { |
| if (componentHandle[jj] == NULL) |
| break; |
| } |
| // can't find a free slot |
| if (jj == MAX_INSTANTIATED_COMPONENTS) |
| { |
| //Release the singleton. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| ErrorType = OMX_ErrorInsufficientResources; |
| return ErrorType; |
| } |
| else |
| { |
| *componentIndex = jj; |
| } |
| |
| OMX_S32 ii; |
| |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) |
| { |
| // go through the list of supported components and find the component based on its name (identifier) |
| if (data->ipRegTemplateList[ii] != NULL) |
| { |
| if (!oscl_strcmp((data->ipRegTemplateList[ii])->ComponentName, cComponentName)) |
| { |
| // found a matching name |
| // call the factory for the component |
| OMX_STRING aOmxLibName = data->ipRegTemplateList[ii]->SharedLibraryName; |
| OMX_PTR &aOmxLib = data->ipRegTemplateList[ii]->SharedLibraryPtr; |
| OMX_PTR aOsclUuid = data->ipRegTemplateList[ii]->SharedLibraryOsclUuid; |
| OMX_U32 &aRefCount = data->ipRegTemplateList[ii]->SharedLibraryRefCounter; |
| if ((data->ipRegTemplateList[ii]->FunctionPtrCreateComponent)(pHandle, pAppData, NULL, aOmxLibName, aOmxLib, aOsclUuid, aRefCount) == OMX_ErrorNone) |
| { |
| // now that we got the component handle, store the handle in the componentHandle array |
| componentHandle[*componentIndex] = *pHandle; |
| |
| // also, record the component registration info to be able to destroy it |
| data->ipInstantiatedComponentReg[*componentIndex] = (data->ipRegTemplateList[ii]); |
| |
| data->iNumBaseInstance++; |
| |
| if (data->iNumBaseInstance > MAX_INSTANTIATED_COMPONENTS) |
| { |
| //cleanup |
| ((data->ipRegTemplateList[ii])->FunctionPtrDestroyComponent)(componentHandle[*componentIndex], aOmxLib, aOsclUuid, aRefCount); |
| componentHandle[*componentIndex] = NULL; |
| data->ipInstantiatedComponentReg[*componentIndex] = NULL; |
| |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| ErrorType = OMX_ErrorInsufficientResources; |
| return ErrorType; |
| } |
| |
| ((OMX_COMPONENTTYPE*)*pHandle)->SetCallbacks(*pHandle, pCallBacks, pAppData); |
| } |
| else |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| ErrorType = OMX_ErrorInsufficientResources; |
| return ErrorType; |
| } |
| } |
| |
| } |
| else |
| { |
| break; |
| } |
| |
| } |
| // can't find the component after going through all of them |
| if (componentHandle[*componentIndex] == NULL) |
| { |
| ErrorType = OMX_ErrorComponentNotFound; |
| } |
| |
| #endif |
| |
| //Release the singleton |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| if (error) |
| { |
| //registry error |
| return OMX_ErrorInvalidState; |
| } |
| |
| return ErrorType; |
| } |
| |
| |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) |
| { |
| OMX_ERRORTYPE ErrorType = OMX_ErrorNone; |
| int32 error; |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (error) // can't access registry |
| { |
| return OMX_ErrorInvalidState; |
| } |
| else if (!data) // singleton object has been destroyed |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| return OMX_ErrorInvalidState; |
| } |
| |
| OMX_S32 ii, ComponentNumber = 0; |
| |
| // Find the component index in the array of handles |
| for (ii = 0; ii < MAX_INSTANTIATED_COMPONENTS ; ii++) |
| { |
| if (hComponent == data->iComponentHandle[ii]) |
| { |
| ComponentNumber = ii; |
| break; |
| } |
| } |
| |
| // cannot find the component handle |
| if (ii == MAX_INSTANTIATED_COMPONENTS) |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| ErrorType = OMX_ErrorInvalidComponent; |
| return ErrorType; |
| } |
| |
| #if PROXY_INTERFACE |
| ProxyApplication_OMX* pTempProxyTerm = data->ipProxyTerm[ComponentNumber]; |
| |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| if (error) |
| { |
| ErrorType = OMX_ErrorUndefined; |
| return ErrorType; |
| } |
| // call the OMX_FreeHandle through the proxy |
| ErrorType = pTempProxyTerm->ProxyFreeHandle(hComponent); |
| |
| // exit thread |
| pTempProxyTerm->Exit(); |
| |
| data = (OMXGlobalData*)OsclSingletonRegistry::lockAndGetInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (error) // can't access registry |
| { |
| return OMX_ErrorInvalidState; |
| } |
| else if (!data) // singleton object has been destroyed |
| { |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| return OMX_ErrorInvalidState; |
| } |
| |
| ProxyApplication_OMX** pProxyTerm = data->ipProxyTerm; |
| |
| delete pProxyTerm[ComponentNumber]; |
| // delete array entries associated with pProxyTerm and Component handle |
| pProxyTerm[ComponentNumber] = NULL; |
| data->iComponentHandle[ComponentNumber] = NULL; |
| data->ipInstantiatedComponentReg[ComponentNumber] = NULL; |
| |
| #else |
| |
| // call the component AO destructor through the function pointer |
| OMX_PTR &aOmxLib = data->ipInstantiatedComponentReg[ii]->SharedLibraryPtr; |
| OMX_PTR aOsclUuid = data->ipInstantiatedComponentReg[ii]->SharedLibraryOsclUuid; |
| OMX_U32 &aRefCount = data->ipInstantiatedComponentReg[ii]->SharedLibraryRefCounter; |
| ErrorType = (data->ipInstantiatedComponentReg[ComponentNumber]->FunctionPtrDestroyComponent)(hComponent, aOmxLib, aOsclUuid, aRefCount); |
| |
| data->iComponentHandle[ComponentNumber] = NULL; |
| data->ipInstantiatedComponentReg[ComponentNumber] = NULL; |
| |
| data->iNumBaseInstance--; |
| |
| #endif |
| |
| //Release the singleton. |
| OsclSingletonRegistry::registerInstanceAndUnlock(data, OSCL_SINGLETON_ID_OMX, error); |
| if (error) |
| { |
| ErrorType = OMX_ErrorUndefined; |
| return ErrorType; |
| } |
| return ErrorType; |
| |
| } |
| |
| //This is a method to be called directly under testapp thread |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( |
| OMX_OUT OMX_STRING cComponentName, |
| OMX_IN OMX_U32 nNameLength, |
| OMX_IN OMX_U32 nIndex) |
| { |
| int32 error; |
| |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::getInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (!data) |
| { |
| return OMX_ErrorUndefined; |
| } |
| OMX_U32 Index = 0; |
| |
| while (data->ipRegTemplateList[Index] != NULL) |
| { |
| if (Index == nIndex) |
| { |
| break; |
| } |
| Index++; |
| } |
| |
| if (data->ipRegTemplateList[Index] != NULL) |
| { |
| oscl_strncpy(cComponentName, (data->ipRegTemplateList[Index])->ComponentName, nNameLength); |
| } |
| else |
| { |
| return OMX_ErrorNoMore; |
| } |
| |
| return OMX_ErrorNone; |
| |
| } |
| |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_SetupTunnel( |
| OMX_IN OMX_HANDLETYPE hOutput, |
| OMX_IN OMX_U32 nPortOutput, |
| OMX_IN OMX_HANDLETYPE hInput, |
| OMX_IN OMX_U32 nPortInput) |
| { |
| OSCL_UNUSED_ARG(hOutput); |
| OSCL_UNUSED_ARG(nPortOutput); |
| OSCL_UNUSED_ARG(hInput); |
| OSCL_UNUSED_ARG(nPortInput); |
| return OMX_ErrorNotImplemented; |
| } |
| |
| |
| |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetContentPipe( |
| OMX_OUT OMX_HANDLETYPE *hPipe, |
| OMX_IN OMX_STRING szURI) |
| { |
| OSCL_UNUSED_ARG(hPipe); |
| OSCL_UNUSED_ARG(szURI); |
| return OMX_ErrorNotImplemented; |
| } |
| |
| |
| ///////////////////////////////////////////////////// |
| /////////////// Given a compName, find the component and then return its role(s) |
| ///////////////// It's the caller's responsibility to provide enough space for the role(s) |
| //////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetRolesOfComponent( |
| OMX_IN OMX_STRING compName, |
| OMX_INOUT OMX_U32* pNumRoles, |
| OMX_OUT OMX_U8** roles) |
| { |
| int32 error; |
| |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::getInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (!data) |
| { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_STRING RoleString = NULL; |
| OMX_S32 ii; |
| |
| // first check if there is a component with the correct name |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) |
| { |
| if (data->ipRegTemplateList[ii]) |
| { |
| if (!oscl_strcmp(data->ipRegTemplateList[ii]->ComponentName, compName)) |
| { |
| (data->ipRegTemplateList[ii])->GetRolesOfComponent(&RoleString); |
| break; |
| } |
| } |
| } |
| |
| if (ii == MAX_SUPPORTED_COMPONENTS) |
| { |
| // component not found |
| *pNumRoles = 0; |
| return OMX_ErrorInvalidComponent; |
| } |
| |
| |
| // for simplicity all our components have 1 role only |
| // if a component has more than 1 role, still register it for each role separately, and use |
| // factory/destructor separately |
| *pNumRoles = 1; |
| if (roles != NULL) |
| { |
| oscl_strncpy((OMX_STRING) roles[0], (OMX_STRING)RoleString, oscl_strlen((OMX_STRING)RoleString) + 1); |
| } |
| |
| return OMX_ErrorNone; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////// |
| ////////// Given a role (say "video_decoder.avc") give the number (and a list) of |
| ///////////components that support the role |
| /////////// It is the callers responsibility to provide enough space for component names, |
| //////////// so it may need to make the call twice. Once to find number of components, and 2nd time |
| //////////// to find their actual names |
| ////////////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF OMX_ERRORTYPE OMX_GetComponentsOfRole( |
| OMX_IN OMX_STRING role, |
| OMX_INOUT OMX_U32 *pNumComps, |
| OMX_INOUT OMX_U8 **compNames) |
| { |
| int32 error; |
| |
| OMXGlobalData* data = (OMXGlobalData*)OsclSingletonRegistry::getInstance(OSCL_SINGLETON_ID_OMX, error); |
| if (!data) |
| { |
| return OMX_ErrorUndefined; |
| } |
| |
| OMX_U32 ii; |
| OMX_STRING RoleString; |
| // initialize |
| *pNumComps = 0; |
| |
| // go through all components and check if they support the given role |
| for (ii = 0; ii < MAX_SUPPORTED_COMPONENTS; ii ++) |
| { |
| if (data->ipRegTemplateList[ii]) |
| { |
| // get the component role |
| (data->ipRegTemplateList[ii])->GetRolesOfComponent(&RoleString); |
| |
| // if the role matches, increment the counter and record the comp. name |
| if (!oscl_strcmp(RoleString, role)) |
| { |
| // if a placeholder for compNames is provided, copy the component name into it |
| if (compNames != NULL) |
| { |
| oscl_strncpy((OMX_STRING) compNames[*pNumComps], (data->ipRegTemplateList[ii])->ComponentName, |
| oscl_strlen((data->ipRegTemplateList[ii])->ComponentName) + 1); |
| } |
| // increment the counter |
| *pNumComps = (*pNumComps + 1); |
| |
| } |
| } |
| } |
| |
| return OMX_ErrorNone; |
| |
| } |