1 /*
2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
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 express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 /*
18  * Copyright (C) 2009 The Android Open Source Project
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *      http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32 
33 #include "WrsOMXPlugin.h"
34 
35 #include <dlfcn.h>
36 
37 #include <HardwareAPI.h>
38 #include <media/stagefright/foundation/ADebug.h>
39 
40 namespace android {
41 
createOMXPlugin()42 OMXPluginBase *createOMXPlugin() {
43     return new WrsOMXPlugin;
44 }
45 
WrsOMXPlugin()46 WrsOMXPlugin::WrsOMXPlugin()
47 {
48 #ifdef TARGET_HAS_ISV
49    AddCore("libisv_omx_core.so");
50 #else
51    AddCore("libwrs_omxil_core_pvwrapped.so");
52 #if defined(USE_MEDIASDK)
53    AddCore("libmfx_omx_core.so");
54 #endif
55 #endif
56 }
57 
AddCore(const char * coreName)58 OMX_ERRORTYPE WrsOMXPlugin::AddCore(const char* coreName)
59 {
60    void* libHandle = dlopen(coreName, RTLD_NOW);
61 
62    if (libHandle != NULL) {
63         WrsOMXCore* core = (WrsOMXCore*)calloc(1,sizeof(WrsOMXCore));
64 
65         if (!core) {
66             dlclose(libHandle);
67             return OMX_ErrorUndefined;
68         }
69         // set plugin lib handle and methods
70         core->mLibHandle = libHandle;
71         core->mInit = (WrsOMXCore::InitFunc)dlsym(libHandle, "OMX_Init");
72         core->mDeinit = (WrsOMXCore::DeinitFunc)dlsym(libHandle, "OMX_Deinit");
73 
74         core->mComponentNameEnum =
75             (WrsOMXCore::ComponentNameEnumFunc)dlsym(libHandle, "OMX_ComponentNameEnum");
76 
77         core->mGetHandle = (WrsOMXCore::GetHandleFunc)dlsym(libHandle, "OMX_GetHandle");
78         core->mFreeHandle = (WrsOMXCore::FreeHandleFunc)dlsym(libHandle, "OMX_FreeHandle");
79 
80         core->mGetRolesOfComponentHandle =
81             (WrsOMXCore::GetRolesOfComponentFunc)dlsym(
82                     libHandle, "OMX_GetRolesOfComponent");
83         if (core->mInit != NULL) {
84             (*(core->mInit))();
85         }
86         if (core->mComponentNameEnum != NULL) {
87             // calculating number of components registered inside given OMX core
88             char tmpComponentName[OMX_MAX_STRINGNAME_SIZE] = { 0 };
89             OMX_U32 tmpIndex = 0;
90             while (OMX_ErrorNone == ((*(core->mComponentNameEnum))(tmpComponentName, OMX_MAX_STRINGNAME_SIZE, tmpIndex))) {
91                 tmpIndex++;
92             ALOGI("OMX IL core %s: declares component %s", coreName, tmpComponentName);
93             }
94             core->mNumComponents = tmpIndex;
95             ALOGI("OMX IL core %s: contains %u components", coreName, core->mNumComponents);
96         }
97         // add plugin to the vector
98         mCores.push_back(core);
99     }
100     else {
101         ALOGW("OMX IL core %s not found", coreName);
102         return OMX_ErrorUndefined; // Do we need to return error message
103     }
104     return OMX_ErrorNone;
105 }
106 
~WrsOMXPlugin()107 WrsOMXPlugin::~WrsOMXPlugin() {
108     for (OMX_U32 i = 0; i < mCores.size(); i++) {
109        if (mCores[i] != NULL && mCores[i]->mLibHandle != NULL) {
110           (*(mCores[i]->mDeinit))();
111 
112           dlclose(mCores[i]->mLibHandle);
113           free(mCores[i]);
114        }
115     }
116 }
117 
makeComponentInstance(const char * name,const OMX_CALLBACKTYPE * callbacks,OMX_PTR appData,OMX_COMPONENTTYPE ** component)118 OMX_ERRORTYPE WrsOMXPlugin::makeComponentInstance(
119         const char *name,
120         const OMX_CALLBACKTYPE *callbacks,
121         OMX_PTR appData,
122         OMX_COMPONENTTYPE **component) {
123     for (OMX_U32 i = 0; i < mCores.size(); i++) {
124         if (mCores[i] != NULL) {
125             if (mCores[i]->mLibHandle == NULL) {
126                 continue;
127             }
128 
129             OMX_ERRORTYPE omx_res = (*(mCores[i]->mGetHandle))(
130                 reinterpret_cast<OMX_HANDLETYPE *>(component),
131                 const_cast<char *>(name),
132                 appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
133             if(omx_res == OMX_ErrorNone) {
134                 Mutex::Autolock autoLock(mMutex);
135                 WrsOMXComponent comp;
136 
137                 comp.mComponent = *component;
138                 comp.mCore = mCores[i];
139 
140                 mComponents.push_back(comp);
141                 return OMX_ErrorNone;
142             } else if(omx_res == OMX_ErrorInsufficientResources) {
143                 return OMX_ErrorInsufficientResources;
144             }
145         }
146     }
147     return OMX_ErrorInvalidComponentName;
148 }
149 
destroyComponentInstance(OMX_COMPONENTTYPE * component)150 OMX_ERRORTYPE WrsOMXPlugin::destroyComponentInstance(
151         OMX_COMPONENTTYPE *component) {
152     Mutex::Autolock autoLock(mMutex);
153     for (OMX_U32 i = 0; i < mComponents.size(); i++) {
154         if (mComponents[i].mComponent == component) {
155             if (mComponents[i].mCore == NULL || mComponents[i].mCore->mLibHandle == NULL) {
156                 return OMX_ErrorUndefined;
157             }
158             OMX_ERRORTYPE omx_res = (*(mComponents[i].mCore->mFreeHandle))(reinterpret_cast<OMX_HANDLETYPE *>(component));
159             mComponents.erase(mComponents.begin() + i);
160             return omx_res;
161         }
162     }
163     return OMX_ErrorInvalidComponent;
164 }
165 
enumerateComponents(OMX_STRING name,size_t size,OMX_U32 index)166 OMX_ERRORTYPE WrsOMXPlugin::enumerateComponents(
167         OMX_STRING name,
168         size_t size,
169         OMX_U32 index) {
170     // returning components
171     OMX_U32 relativeIndex = index;
172     for (OMX_U32 i = 0; i < mCores.size(); i++) {
173         if (mCores[i]->mLibHandle == NULL) {
174            continue;
175         }
176         if (relativeIndex < mCores[i]->mNumComponents) return ((*(mCores[i]->mComponentNameEnum))(name, size, relativeIndex));
177         else relativeIndex -= mCores[i]->mNumComponents;
178     }
179     return OMX_ErrorNoMore;
180 }
181 
getRolesOfComponent(const char * name,Vector<String8> * roles)182 OMX_ERRORTYPE WrsOMXPlugin::getRolesOfComponent(
183         const char *name,
184         Vector<String8> *roles) {
185     roles->clear();
186     for (OMX_U32 j = 0; j < mCores.size(); j++) {
187         if (mCores[j]->mLibHandle == NULL) {
188            continue;
189         }
190 
191         OMX_U32 numRoles;
192         OMX_ERRORTYPE err = (*(mCores[j]->mGetRolesOfComponentHandle))(
193                 const_cast<OMX_STRING>(name), &numRoles, NULL);
194 
195         if (err != OMX_ErrorNone) {
196             continue;
197         }
198 
199         if (numRoles > 0) {
200             OMX_U8 **array = new OMX_U8 *[numRoles];
201             for (OMX_U32 i = 0; i < numRoles; ++i) {
202                 array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
203             }
204 
205             OMX_U32 numRoles2 = numRoles;
206             err = (*(mCores[j]->mGetRolesOfComponentHandle))(
207                     const_cast<OMX_STRING>(name), &numRoles2, array);
208 
209             CHECK_EQ(err, OMX_ErrorNone);
210             CHECK_EQ(numRoles, numRoles2);
211 
212             for (OMX_U32 i = 0; i < numRoles; ++i) {
213                 String8 s((const char *)array[i]);
214                 roles->push(s);
215 
216                 delete[] array[i];
217                 array[i] = NULL;
218             }
219 
220             delete[] array;
221             array = NULL;
222         }
223         return OMX_ErrorNone;
224     }
225     return OMX_ErrorInvalidComponent;
226 }
227 
228 }  // namespace android
229