blob: 545e6d4705fa6a0c46f4d93ed3cee7b42317a1e7 [file] [log] [blame]
Andreas Huberb0caf942009-12-03 11:39:54 -08001/*
2 * Copyright (C) 2009 The Android Open Source Project
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
Andreas Huberfb41d592010-06-23 11:31:17 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "OMXMaster"
19#include <utils/Log.h>
20
Andreas Huberb0caf942009-12-03 11:39:54 -080021#include "OMXMaster.h"
22
Andreas Huber4b3913a2011-05-11 14:13:42 -070023#include "SoftOMXPlugin.h"
24
Andreas Huberb0caf942009-12-03 11:39:54 -080025#include <dlfcn.h>
26
27#include <media/stagefright/MediaDebug.h>
28
Andreas Huberb0caf942009-12-03 11:39:54 -080029namespace android {
30
31OMXMaster::OMXMaster()
32 : mVendorLibHandle(NULL) {
Andreas Huberb0caf942009-12-03 11:39:54 -080033 addVendorPlugin();
Andreas Huber4b3913a2011-05-11 14:13:42 -070034 addPlugin(new SoftOMXPlugin);
Andreas Huberb0caf942009-12-03 11:39:54 -080035}
36
37OMXMaster::~OMXMaster() {
38 clearPlugins();
39
40 if (mVendorLibHandle != NULL) {
41 dlclose(mVendorLibHandle);
42 mVendorLibHandle = NULL;
43 }
44}
45
46void OMXMaster::addVendorPlugin() {
Andreas Huber4b3913a2011-05-11 14:13:42 -070047 addPlugin("libstagefrighthw.so");
48}
49
50void OMXMaster::addPlugin(const char *libname) {
51 mVendorLibHandle = dlopen(libname, RTLD_NOW);
Andreas Huberb0caf942009-12-03 11:39:54 -080052
53 if (mVendorLibHandle == NULL) {
54 return;
55 }
56
57 typedef OMXPluginBase *(*CreateOMXPluginFunc)();
58 CreateOMXPluginFunc createOMXPlugin =
59 (CreateOMXPluginFunc)dlsym(
60 mVendorLibHandle, "_ZN7android15createOMXPluginEv");
61
Andreas Huberfef64352009-12-04 12:52:40 -080062 if (createOMXPlugin) {
63 addPlugin((*createOMXPlugin)());
64 }
Andreas Huberb0caf942009-12-03 11:39:54 -080065}
66
67void OMXMaster::addPlugin(OMXPluginBase *plugin) {
68 Mutex::Autolock autoLock(mLock);
69
70 mPlugins.push_back(plugin);
71
72 OMX_U32 index = 0;
73
74 char name[128];
75 OMX_ERRORTYPE err;
76 while ((err = plugin->enumerateComponents(
77 name, sizeof(name), index++)) == OMX_ErrorNone) {
78 String8 name8(name);
79
80 if (mPluginByComponentName.indexOfKey(name8) >= 0) {
81 LOGE("A component of name '%s' already exists, ignoring this one.",
82 name8.string());
83
84 continue;
85 }
86
87 mPluginByComponentName.add(name8, plugin);
88 }
89 CHECK_EQ(err, OMX_ErrorNoMore);
90}
91
92void OMXMaster::clearPlugins() {
93 Mutex::Autolock autoLock(mLock);
94
95 mPluginByComponentName.clear();
96
97 for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
98 it != mPlugins.end(); ++it) {
99 delete *it;
100 *it = NULL;
101 }
102
103 mPlugins.clear();
104}
105
106OMX_ERRORTYPE OMXMaster::makeComponentInstance(
107 const char *name,
108 const OMX_CALLBACKTYPE *callbacks,
109 OMX_PTR appData,
110 OMX_COMPONENTTYPE **component) {
111 Mutex::Autolock autoLock(mLock);
112
113 *component = NULL;
114
115 ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
116
117 if (index < 0) {
118 return OMX_ErrorInvalidComponentName;
119 }
120
121 OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
Andreas Huberfef64352009-12-04 12:52:40 -0800122 OMX_ERRORTYPE err =
123 plugin->makeComponentInstance(name, callbacks, appData, component);
124
125 if (err != OMX_ErrorNone) {
126 return err;
127 }
128
129 mPluginByInstance.add(*component, plugin);
130
131 return err;
132}
133
134OMX_ERRORTYPE OMXMaster::destroyComponentInstance(
135 OMX_COMPONENTTYPE *component) {
136 Mutex::Autolock autoLock(mLock);
137
138 ssize_t index = mPluginByInstance.indexOfKey(component);
139
140 if (index < 0) {
141 return OMX_ErrorBadParameter;
142 }
143
144 OMXPluginBase *plugin = mPluginByInstance.valueAt(index);
145 mPluginByInstance.removeItemsAt(index);
146
147 return plugin->destroyComponentInstance(component);
Andreas Huberb0caf942009-12-03 11:39:54 -0800148}
149
150OMX_ERRORTYPE OMXMaster::enumerateComponents(
151 OMX_STRING name,
152 size_t size,
153 OMX_U32 index) {
154 Mutex::Autolock autoLock(mLock);
155
156 size_t numComponents = mPluginByComponentName.size();
157
158 if (index >= numComponents) {
159 return OMX_ErrorNoMore;
160 }
161
162 const String8 &name8 = mPluginByComponentName.keyAt(index);
163
164 CHECK(size >= 1 + name8.size());
165 strcpy(name, name8.string());
166
167 return OMX_ErrorNone;
168}
169
Andreas Huberc7e91ee2009-12-15 15:22:08 -0800170OMX_ERRORTYPE OMXMaster::getRolesOfComponent(
171 const char *name,
172 Vector<String8> *roles) {
173 Mutex::Autolock autoLock(mLock);
174
175 roles->clear();
176
177 ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
178
179 if (index < 0) {
180 return OMX_ErrorInvalidComponentName;
181 }
182
183 OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
184 return plugin->getRolesOfComponent(name, roles);
185}
186
Andreas Huberb0caf942009-12-03 11:39:54 -0800187} // namespace android