Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0d4e25c authored by Steve Kondik's avatar Steve Kondik
Browse files

stagefright: Add support for loading a custom OMXPlugin

 * To facilitate moving the stagefright-plugins glue out of the
   framework, support is added to OMXMaster to load multiple
   external plugins besides internal/vendor versions.
 * This is currently limited to one plugin, defined by the
   "mm.sf.omx-plugin" system property. The code will allow any
   number of libraries to be loaded, though.
 * Should also be useful for nonstandard vendor implementations too.

Change-Id: I27d7e16ad56baa17754d8ea47a8c608a0d73d6f1
parent f18e008f
Loading
Loading
Loading
Loading
+42 −25
Original line number Diff line number Diff line
@@ -26,11 +26,11 @@
#include <fcntl.h>

#include <media/stagefright/foundation/ADebug.h>
#include <cutils/properties.h>

namespace android {

OMXMaster::OMXMaster()
    : mVendorLibHandle(NULL) {
OMXMaster::OMXMaster() {

    mProcessName[0] = 0;
    if (mProcessName[0] == 0) {
@@ -56,45 +56,51 @@ OMXMaster::OMXMaster()

    addVendorPlugin();
    addPlugin(new SoftOMXPlugin);
    addUserPlugin();
}

OMXMaster::~OMXMaster() {
    clearPlugins();

    if (mVendorLibHandle != NULL) {
        dlclose(mVendorLibHandle);
        mVendorLibHandle = NULL;
    }
}

void OMXMaster::addVendorPlugin() {
    addPlugin("libstagefrighthw.so");
}

void OMXMaster::addUserPlugin() {
    char plugin[PROPERTY_VALUE_MAX];
    if (property_get("media.sf.omx-plugin", plugin, NULL)) {
        addPlugin(plugin);
    }
}

void OMXMaster::addPlugin(const char *libname) {
    mVendorLibHandle = dlopen(libname, RTLD_NOW);
    void* handle = dlopen(libname, RTLD_NOW);

    if (mVendorLibHandle == NULL) {
    if (handle == NULL) {
        return;
    }

    typedef OMXPluginBase *(*CreateOMXPluginFunc)();
    CreateOMXPluginFunc createOMXPlugin =
        (CreateOMXPluginFunc)dlsym(
                mVendorLibHandle, "createOMXPlugin");
                handle, "createOMXPlugin");
    if (!createOMXPlugin)
        createOMXPlugin = (CreateOMXPluginFunc)dlsym(
                mVendorLibHandle, "_ZN7android15createOMXPluginEv");
                handle, "_ZN7android15createOMXPluginEv");

    if (createOMXPlugin) {
        addPlugin((*createOMXPlugin)());
        addPlugin((*createOMXPlugin)(), handle);
    }
}

void OMXMaster::addPlugin(OMXPluginBase *plugin) {
void OMXMaster::addPlugin(OMXPluginBase *plugin, void *handle) {
    if (plugin == 0) {
       return;
    }
    Mutex::Autolock autoLock(mLock);

    mPlugins.push_back(plugin);
    mPlugins.add(plugin, handle);

    OMX_U32 index = 0;

@@ -124,21 +130,32 @@ void OMXMaster::clearPlugins() {
    Mutex::Autolock autoLock(mLock);

    typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);

    for (unsigned int i = 0; i < mPlugins.size(); i++) {
        OMXPluginBase *plugin = mPlugins.keyAt(i);
        if (plugin != NULL) {
            void *handle = mPlugins.valueAt(i);

            if (handle != NULL) {
                DestroyOMXPluginFunc destroyOMXPlugin =
                    (DestroyOMXPluginFunc)dlsym(
                mVendorLibHandle, "destroyOMXPlugin");
                            handle, "destroyOMXPlugin");

    mPluginByComponentName.clear();

    for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
            it != mPlugins.end(); ++it) {
                if (destroyOMXPlugin)
            destroyOMXPlugin(*it);
                    destroyOMXPlugin(plugin);
                else
            delete *it;
        *it = NULL;
                    delete plugin;

                dlclose(handle);
            } else {
                delete plugin;
            }

            plugin = NULL;
        }
    }

    mPluginByComponentName.clear();
    mPlugins.clear();
}

+3 −4
Original line number Diff line number Diff line
@@ -52,15 +52,14 @@ struct OMXMaster : public OMXPluginBase {
private:
    char mProcessName[16];
    Mutex mLock;
    List<OMXPluginBase *> mPlugins;
    KeyedVector<OMXPluginBase *, void *> mPlugins;
    KeyedVector<String8, OMXPluginBase *> mPluginByComponentName;
    KeyedVector<OMX_COMPONENTTYPE *, OMXPluginBase *> mPluginByInstance;

    void *mVendorLibHandle;

    void addVendorPlugin();
    void addUserPlugin();
    void addPlugin(const char *libname);
    void addPlugin(OMXPluginBase *plugin);
    void addPlugin(OMXPluginBase *plugin, void *handle = NULL);
    void clearPlugins();

    OMXMaster(const OMXMaster &);
+5 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
        OMX_COMPONENTTYPE **component) {
    ALOGV("makeComponentInstance '%s'", name);

    dlerror(); // clear any existing error
    for (size_t i = 0; i < kNumComponents; ++i) {
        if (strcmp(name, kComponents[i].mName)) {
            continue;
@@ -94,6 +95,8 @@ OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
            return OMX_ErrorComponentNotFound;
        }

        ALOGV("load component %s for %s", libName.c_str(), name);

        typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)(
                const char *, const OMX_CALLBACKTYPE *,
                OMX_PTR, OMX_COMPONENTTYPE **);
@@ -104,7 +107,8 @@ OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
                    "_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"
                    "PvPP17OMX_COMPONENTTYPE");

        if (createSoftOMXComponent == NULL) {
        if (const char *error = dlerror()) {
            ALOGE("unable to dlsym %s: %s", libName.c_str(), error);
            dlclose(libHandle);
            libHandle = NULL;