1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "QComOMXPlugin.h"
19
20#include <dlfcn.h>
21
22#include <media/hardware/HardwareAPI.h>
23
24namespace android {
25
26OMXPluginBase *createOMXPlugin() {
27    return new QComOMXPlugin;
28}
29
30QComOMXPlugin::QComOMXPlugin()
31    : mLibHandle(dlopen("libOmxCore.so", RTLD_NOW)),
32      mInit(NULL),
33      mDeinit(NULL),
34      mComponentNameEnum(NULL),
35      mGetHandle(NULL),
36      mFreeHandle(NULL),
37      mGetRolesOfComponentHandle(NULL) {
38    if (mLibHandle != NULL) {
39        mInit = (InitFunc)dlsym(mLibHandle, "OMX_Init");
40        mDeinit = (DeinitFunc)dlsym(mLibHandle, "OMX_Deinit");
41
42        mComponentNameEnum =
43            (ComponentNameEnumFunc)dlsym(mLibHandle, "OMX_ComponentNameEnum");
44
45        mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "OMX_GetHandle");
46        mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "OMX_FreeHandle");
47
48        mGetRolesOfComponentHandle =
49            (GetRolesOfComponentFunc)dlsym(
50                    mLibHandle, "OMX_GetRolesOfComponent");
51
52        if (!mInit || !mDeinit || !mComponentNameEnum || !mGetHandle ||
53            !mFreeHandle || !mGetRolesOfComponentHandle) {
54            dlclose(mLibHandle);
55            mLibHandle = NULL;
56        } else
57        (*mInit)();
58    }
59}
60
61QComOMXPlugin::~QComOMXPlugin() {
62    if (mLibHandle != NULL) {
63        (*mDeinit)();
64
65        dlclose(mLibHandle);
66        mLibHandle = NULL;
67    }
68}
69
70OMX_ERRORTYPE QComOMXPlugin::makeComponentInstance(
71        const char *name,
72        const OMX_CALLBACKTYPE *callbacks,
73        OMX_PTR appData,
74        OMX_COMPONENTTYPE **component) {
75    if (mLibHandle == NULL) {
76        return OMX_ErrorUndefined;
77    }
78
79    return (*mGetHandle)(
80            reinterpret_cast<OMX_HANDLETYPE *>(component),
81            const_cast<char *>(name),
82            appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
83}
84
85OMX_ERRORTYPE QComOMXPlugin::destroyComponentInstance(
86        OMX_COMPONENTTYPE *component) {
87    if (mLibHandle == NULL) {
88        return OMX_ErrorUndefined;
89    }
90
91    return (*mFreeHandle)(reinterpret_cast<OMX_HANDLETYPE *>(component));
92}
93
94OMX_ERRORTYPE QComOMXPlugin::enumerateComponents(
95        OMX_STRING name,
96        size_t size,
97        OMX_U32 index) {
98    if (mLibHandle == NULL) {
99        return OMX_ErrorUndefined;
100    }
101
102    return (*mComponentNameEnum)(name, size, index);
103}
104
105OMX_ERRORTYPE QComOMXPlugin::getRolesOfComponent(
106        const char *name,
107        Vector<String8> *roles) {
108    roles->clear();
109
110    if (mLibHandle == NULL) {
111        return OMX_ErrorUndefined;
112    }
113
114    OMX_U32 numRoles;
115    OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)(
116            const_cast<OMX_STRING>(name), &numRoles, NULL);
117
118    if (err != OMX_ErrorNone) {
119        return err;
120    }
121
122    if (numRoles > 0) {
123        OMX_U8 **array = new OMX_U8 *[numRoles];
124        for (OMX_U32 i = 0; i < numRoles; ++i) {
125            array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
126        }
127
128        OMX_U32 numRoles2;
129        err = (*mGetRolesOfComponentHandle)(
130                const_cast<OMX_STRING>(name), &numRoles2, array);
131
132	if (err != OMX_ErrorNone) {
133	  return err;
134	}
135
136	if (numRoles2 != numRoles) {
137	  return err;
138	}
139
140        for (OMX_U32 i = 0; i < numRoles; ++i) {
141            String8 s((const char *)array[i]);
142            roles->push(s);
143
144            delete[] array[i];
145            array[i] = NULL;
146        }
147
148        delete[] array;
149        array = NULL;
150    }
151
152    return OMX_ErrorNone;
153}
154
155}  // namespace android
156