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