1b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber/* 2b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * Copyright (C) 2009 The Android Open Source Project 3b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * 4b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * you may not use this file except in compliance with the License. 6b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * You may obtain a copy of the License at 7b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * 8b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * 10b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * Unless required by applicable law or agreed to in writing, software 11b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * See the License for the specific language governing permissions and 14b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber * limitations under the License. 15b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber */ 16b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 17fb41d59595a09f60fd2fa3618e9d5a4937c4555bAndreas Huber//#define LOG_NDEBUG 0 18fb41d59595a09f60fd2fa3618e9d5a4937c4555bAndreas Huber#define LOG_TAG "OMXMaster" 19fb41d59595a09f60fd2fa3618e9d5a4937c4555bAndreas Huber#include <utils/Log.h> 20fb41d59595a09f60fd2fa3618e9d5a4937c4555bAndreas Huber 21b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber#include "OMXMaster.h" 22b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include "SoftOMXPlugin.h" 244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber 25b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber#include <dlfcn.h> 26b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 27b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber#include <media/stagefright/MediaDebug.h> 28b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 29b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Hubernamespace android { 30b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 31b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas HuberOMXMaster::OMXMaster() 32b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber : mVendorLibHandle(NULL) { 33b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber addVendorPlugin(); 344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber addPlugin(new SoftOMXPlugin); 35b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 36b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 37b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas HuberOMXMaster::~OMXMaster() { 38b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber clearPlugins(); 39b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 40b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber if (mVendorLibHandle != NULL) { 41b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber dlclose(mVendorLibHandle); 42b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber mVendorLibHandle = NULL; 43b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 44b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 45b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 46b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Hubervoid OMXMaster::addVendorPlugin() { 474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber addPlugin("libstagefrighthw.so"); 484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber} 494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber 504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid OMXMaster::addPlugin(const char *libname) { 514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber mVendorLibHandle = dlopen(libname, RTLD_NOW); 52b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 53b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber if (mVendorLibHandle == NULL) { 54b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber return; 55b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 56b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 57b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber typedef OMXPluginBase *(*CreateOMXPluginFunc)(); 58b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber CreateOMXPluginFunc createOMXPlugin = 59b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber (CreateOMXPluginFunc)dlsym( 60bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev mVendorLibHandle, "createOMXPlugin"); 61bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev if (!createOMXPlugin) 62bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev createOMXPlugin = (CreateOMXPluginFunc)dlsym( 63b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber mVendorLibHandle, "_ZN7android15createOMXPluginEv"); 64b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 65fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber if (createOMXPlugin) { 66fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber addPlugin((*createOMXPlugin)()); 67fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber } 68b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 69b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 70b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Hubervoid OMXMaster::addPlugin(OMXPluginBase *plugin) { 71b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber Mutex::Autolock autoLock(mLock); 72b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 73b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber mPlugins.push_back(plugin); 74b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 75b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMX_U32 index = 0; 76b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 77b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber char name[128]; 78b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMX_ERRORTYPE err; 79b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber while ((err = plugin->enumerateComponents( 80b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber name, sizeof(name), index++)) == OMX_ErrorNone) { 81b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber String8 name8(name); 82b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 83b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber if (mPluginByComponentName.indexOfKey(name8) >= 0) { 84b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber LOGE("A component of name '%s' already exists, ignoring this one.", 85b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber name8.string()); 86b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 87b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber continue; 88b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 89b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 90b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber mPluginByComponentName.add(name8, plugin); 91b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 92274626469b716560d7539d0d830c41b83f3665a1Andreas Huber 93274626469b716560d7539d0d830c41b83f3665a1Andreas Huber if (err != OMX_ErrorNoMore) { 94274626469b716560d7539d0d830c41b83f3665a1Andreas Huber LOGE("OMX plugin failed w/ error 0x%08x after registering %d " 95274626469b716560d7539d0d830c41b83f3665a1Andreas Huber "components", err, mPluginByComponentName.size()); 96274626469b716560d7539d0d830c41b83f3665a1Andreas Huber } 97b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 98b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 99b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Hubervoid OMXMaster::clearPlugins() { 100b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber Mutex::Autolock autoLock(mLock); 101b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 102bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*); 103bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev DestroyOMXPluginFunc destroyOMXPlugin = 104bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev (DestroyOMXPluginFunc)dlsym( 105bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev mVendorLibHandle, "destroyOMXPlugin"); 106bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev 107b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber mPluginByComponentName.clear(); 108b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 109b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber for (List<OMXPluginBase *>::iterator it = mPlugins.begin(); 110bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev it != mPlugins.end(); ++it) { 111bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev if (destroyOMXPlugin) 112bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev destroyOMXPlugin(*it); 113bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev else 114bbe9cb4f5f87e36b886ea3ba72dc514a081f3fe3Iliyan Malchev delete *it; 115b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber *it = NULL; 116b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 117b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 118b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber mPlugins.clear(); 119b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 120b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 121b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas HuberOMX_ERRORTYPE OMXMaster::makeComponentInstance( 122b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber const char *name, 123b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber const OMX_CALLBACKTYPE *callbacks, 124b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMX_PTR appData, 125b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMX_COMPONENTTYPE **component) { 126b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber Mutex::Autolock autoLock(mLock); 127b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 128b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber *component = NULL; 129b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 130b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber ssize_t index = mPluginByComponentName.indexOfKey(String8(name)); 131b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 132b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber if (index < 0) { 133b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber return OMX_ErrorInvalidComponentName; 134b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 135b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 136b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMXPluginBase *plugin = mPluginByComponentName.valueAt(index); 137fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber OMX_ERRORTYPE err = 138fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber plugin->makeComponentInstance(name, callbacks, appData, component); 139fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 140fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber if (err != OMX_ErrorNone) { 141fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber return err; 142fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber } 143fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 144fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber mPluginByInstance.add(*component, plugin); 145fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 146fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber return err; 147fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber} 148fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 149fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas HuberOMX_ERRORTYPE OMXMaster::destroyComponentInstance( 150fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber OMX_COMPONENTTYPE *component) { 151fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber Mutex::Autolock autoLock(mLock); 152fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 153fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber ssize_t index = mPluginByInstance.indexOfKey(component); 154fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 155fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber if (index < 0) { 156fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber return OMX_ErrorBadParameter; 157fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber } 158fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 159fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber OMXPluginBase *plugin = mPluginByInstance.valueAt(index); 160fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber mPluginByInstance.removeItemsAt(index); 161fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber 162fef6435a0692f3c9b6055903dfb7699e90e19d46Andreas Huber return plugin->destroyComponentInstance(component); 163b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 164b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 165b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas HuberOMX_ERRORTYPE OMXMaster::enumerateComponents( 166b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMX_STRING name, 167b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber size_t size, 168b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber OMX_U32 index) { 169b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber Mutex::Autolock autoLock(mLock); 170b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 171b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber size_t numComponents = mPluginByComponentName.size(); 172b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 173b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber if (index >= numComponents) { 174b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber return OMX_ErrorNoMore; 175b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber } 176b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 177b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber const String8 &name8 = mPluginByComponentName.keyAt(index); 178b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 179b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber CHECK(size >= 1 + name8.size()); 180b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber strcpy(name, name8.string()); 181b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 182b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber return OMX_ErrorNone; 183b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} 184b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber 185c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas HuberOMX_ERRORTYPE OMXMaster::getRolesOfComponent( 186c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber const char *name, 187c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber Vector<String8> *roles) { 188c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber Mutex::Autolock autoLock(mLock); 189c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber 190c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber roles->clear(); 191c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber 192c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber ssize_t index = mPluginByComponentName.indexOfKey(String8(name)); 193c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber 194c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber if (index < 0) { 195c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber return OMX_ErrorInvalidComponentName; 196c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber } 197c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber 198c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber OMXPluginBase *plugin = mPluginByComponentName.valueAt(index); 199c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber return plugin->getRolesOfComponent(name, roles); 200c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber} 201c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8Andreas Huber 202b0caf946b7ae9be519c0cede935ea2ecb44f9bd0Andreas Huber} // namespace android 203