1 /* 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 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "OMXMaster" 19 #include <utils/Log.h> 20 21 #include "OMXMaster.h" 22 23 #include "SoftOMXPlugin.h" 24 25 #include <dlfcn.h> 26 27 #include <media/stagefright/foundation/ADebug.h> 28 29 namespace android { 30 31 OMXMaster::OMXMaster() 32 : mVendorLibHandle(NULL) { 33 addVendorPlugin(); 34 addPlugin(new SoftOMXPlugin); 35 } 36 37 OMXMaster::~OMXMaster() { 38 clearPlugins(); 39 40 if (mVendorLibHandle != NULL) { 41 dlclose(mVendorLibHandle); 42 mVendorLibHandle = NULL; 43 } 44 } 45 46 void OMXMaster::addVendorPlugin() { 47 addPlugin("libstagefrighthw.so"); 48 } 49 50 void OMXMaster::addPlugin(const char *libname) { 51 mVendorLibHandle = dlopen(libname, RTLD_NOW); 52 53 if (mVendorLibHandle == NULL) { 54 return; 55 } 56 57 typedef OMXPluginBase *(*CreateOMXPluginFunc)(); 58 CreateOMXPluginFunc createOMXPlugin = 59 (CreateOMXPluginFunc)dlsym( 60 mVendorLibHandle, "createOMXPlugin"); 61 if (!createOMXPlugin) 62 createOMXPlugin = (CreateOMXPluginFunc)dlsym( 63 mVendorLibHandle, "_ZN7android15createOMXPluginEv"); 64 65 if (createOMXPlugin) { 66 addPlugin((*createOMXPlugin)()); 67 } 68 } 69 70 void OMXMaster::addPlugin(OMXPluginBase *plugin) { 71 Mutex::Autolock autoLock(mLock); 72 73 mPlugins.push_back(plugin); 74 75 OMX_U32 index = 0; 76 77 char name[128]; 78 OMX_ERRORTYPE err; 79 while ((err = plugin->enumerateComponents( 80 name, sizeof(name), index++)) == OMX_ErrorNone) { 81 String8 name8(name); 82 83 if (mPluginByComponentName.indexOfKey(name8) >= 0) { 84 ALOGE("A component of name '%s' already exists, ignoring this one.", 85 name8.string()); 86 87 continue; 88 } 89 90 mPluginByComponentName.add(name8, plugin); 91 } 92 93 if (err != OMX_ErrorNoMore) { 94 ALOGE("OMX plugin failed w/ error 0x%08x after registering %d " 95 "components", err, mPluginByComponentName.size()); 96 } 97 } 98 99 void OMXMaster::clearPlugins() { 100 Mutex::Autolock autoLock(mLock); 101 102 typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*); 103 DestroyOMXPluginFunc destroyOMXPlugin = 104 (DestroyOMXPluginFunc)dlsym( 105 mVendorLibHandle, "destroyOMXPlugin"); 106 107 mPluginByComponentName.clear(); 108 109 for (List<OMXPluginBase *>::iterator it = mPlugins.begin(); 110 it != mPlugins.end(); ++it) { 111 if (destroyOMXPlugin) 112 destroyOMXPlugin(*it); 113 else 114 delete *it; 115 *it = NULL; 116 } 117 118 mPlugins.clear(); 119 } 120 121 OMX_ERRORTYPE OMXMaster::makeComponentInstance( 122 const char *name, 123 const OMX_CALLBACKTYPE *callbacks, 124 OMX_PTR appData, 125 OMX_COMPONENTTYPE **component) { 126 Mutex::Autolock autoLock(mLock); 127 128 *component = NULL; 129 130 ssize_t index = mPluginByComponentName.indexOfKey(String8(name)); 131 132 if (index < 0) { 133 return OMX_ErrorInvalidComponentName; 134 } 135 136 OMXPluginBase *plugin = mPluginByComponentName.valueAt(index); 137 OMX_ERRORTYPE err = 138 plugin->makeComponentInstance(name, callbacks, appData, component); 139 140 if (err != OMX_ErrorNone) { 141 return err; 142 } 143 144 mPluginByInstance.add(*component, plugin); 145 146 return err; 147 } 148 149 OMX_ERRORTYPE OMXMaster::destroyComponentInstance( 150 OMX_COMPONENTTYPE *component) { 151 Mutex::Autolock autoLock(mLock); 152 153 ssize_t index = mPluginByInstance.indexOfKey(component); 154 155 if (index < 0) { 156 return OMX_ErrorBadParameter; 157 } 158 159 OMXPluginBase *plugin = mPluginByInstance.valueAt(index); 160 mPluginByInstance.removeItemsAt(index); 161 162 return plugin->destroyComponentInstance(component); 163 } 164 165 OMX_ERRORTYPE OMXMaster::enumerateComponents( 166 OMX_STRING name, 167 size_t size, 168 OMX_U32 index) { 169 Mutex::Autolock autoLock(mLock); 170 171 size_t numComponents = mPluginByComponentName.size(); 172 173 if (index >= numComponents) { 174 return OMX_ErrorNoMore; 175 } 176 177 const String8 &name8 = mPluginByComponentName.keyAt(index); 178 179 CHECK(size >= 1 + name8.size()); 180 strcpy(name, name8.string()); 181 182 return OMX_ErrorNone; 183 } 184 185 OMX_ERRORTYPE OMXMaster::getRolesOfComponent( 186 const char *name, 187 Vector<String8> *roles) { 188 Mutex::Autolock autoLock(mLock); 189 190 roles->clear(); 191 192 ssize_t index = mPluginByComponentName.indexOfKey(String8(name)); 193 194 if (index < 0) { 195 return OMX_ErrorInvalidComponentName; 196 } 197 198 OMXPluginBase *plugin = mPluginByComponentName.valueAt(index); 199 return plugin->getRolesOfComponent(name, roles); 200 } 201 202 } // namespace android 203