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
40namespace android {
41
42OMXPluginBase *createOMXPlugin() {
43    return new WrsOMXPlugin;
44}
45
46WrsOMXPlugin::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
58OMX_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 %ld 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
107WrsOMXPlugin::~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
118OMX_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            }
143        }
144    }
145    return OMX_ErrorInvalidComponentName;
146}
147
148OMX_ERRORTYPE WrsOMXPlugin::destroyComponentInstance(
149        OMX_COMPONENTTYPE *component) {
150    Mutex::Autolock autoLock(mMutex);
151    for (OMX_U32 i = 0; i < mComponents.size(); i++) {
152        if (mComponents[i].mComponent == component) {
153            if (mComponents[i].mCore == NULL || mComponents[i].mCore->mLibHandle == NULL) {
154                return OMX_ErrorUndefined;
155            }
156            OMX_ERRORTYPE omx_res = (*(mComponents[i].mCore->mFreeHandle))(reinterpret_cast<OMX_HANDLETYPE *>(component));
157            mComponents.erase(mComponents.begin() + i);
158            return omx_res;
159        }
160    }
161    return OMX_ErrorInvalidComponent;
162}
163
164OMX_ERRORTYPE WrsOMXPlugin::enumerateComponents(
165        OMX_STRING name,
166        size_t size,
167        OMX_U32 index) {
168    // returning components
169    OMX_U32 relativeIndex = index;
170    for (OMX_U32 i = 0; i < mCores.size(); i++) {
171        if (mCores[i]->mLibHandle == NULL) {
172           continue;
173        }
174        if (relativeIndex < mCores[i]->mNumComponents) return ((*(mCores[i]->mComponentNameEnum))(name, size, relativeIndex));
175        else relativeIndex -= mCores[i]->mNumComponents;
176    }
177    return OMX_ErrorNoMore;
178}
179
180OMX_ERRORTYPE WrsOMXPlugin::getRolesOfComponent(
181        const char *name,
182        Vector<String8> *roles) {
183    roles->clear();
184    for (OMX_U32 j = 0; j < mCores.size(); j++) {
185        if (mCores[j]->mLibHandle == NULL) {
186           continue;
187        }
188
189        OMX_U32 numRoles;
190        OMX_ERRORTYPE err = (*(mCores[j]->mGetRolesOfComponentHandle))(
191                const_cast<OMX_STRING>(name), &numRoles, NULL);
192
193        if (err != OMX_ErrorNone) {
194            continue;
195        }
196
197        if (numRoles > 0) {
198            OMX_U8 **array = new OMX_U8 *[numRoles];
199            for (OMX_U32 i = 0; i < numRoles; ++i) {
200                array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
201            }
202
203            OMX_U32 numRoles2 = numRoles;
204            err = (*(mCores[j]->mGetRolesOfComponentHandle))(
205                    const_cast<OMX_STRING>(name), &numRoles2, array);
206
207            CHECK_EQ(err, OMX_ErrorNone);
208            CHECK_EQ(numRoles, numRoles2);
209
210            for (OMX_U32 i = 0; i < numRoles; ++i) {
211                String8 s((const char *)array[i]);
212                roles->push(s);
213
214                delete[] array[i];
215                array[i] = NULL;
216            }
217
218            delete[] array;
219            array = NULL;
220        }
221        return OMX_ErrorNone;
222    }
223    return OMX_ErrorInvalidComponent;
224}
225
226}  // namespace android
227