Home | History | Annotate | Download | only in omx
      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