OMXMaster.cpp revision 8ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cd
1e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber/*
2e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *
4e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * you may not use this file except in compliance with the License.
6e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * You may obtain a copy of the License at
7e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *
8e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber *
10e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * See the License for the specific language governing permissions and
14e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber * limitations under the License.
15e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber */
16e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
17e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "OMXMaster.h"
18e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
19e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <dlfcn.h>
20e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
21e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <media/stagefright/MediaDebug.h>
22e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
23e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#ifndef NO_OPENCORE
24e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "OMXPVCodecsPlugin.h"
25e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#endif
26e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
27e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubernamespace android {
28e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
29e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMXMaster::OMXMaster()
30e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    : mVendorLibHandle(NULL) {
31e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    addVendorPlugin();
32e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
33e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#ifndef NO_OPENCORE
34e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    addPlugin(new OMXPVCodecsPlugin);
35e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#endif
36e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
37e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
38e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMXMaster::~OMXMaster() {
39e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    clearPlugins();
40e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
41e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (mVendorLibHandle != NULL) {
42e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        dlclose(mVendorLibHandle);
43e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        mVendorLibHandle = NULL;
44e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
45e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
46e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
47e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubervoid OMXMaster::addVendorPlugin() {
48e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mVendorLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
49e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
50e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (mVendorLibHandle == NULL) {
51e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        return;
52e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
53e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
54e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    typedef OMXPluginBase *(*CreateOMXPluginFunc)();
55e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    CreateOMXPluginFunc createOMXPlugin =
56e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        (CreateOMXPluginFunc)dlsym(
57e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber                mVendorLibHandle, "_ZN7android15createOMXPluginEv");
58e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
59f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    if (createOMXPlugin) {
60f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        addPlugin((*createOMXPlugin)());
61f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    }
62e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
63e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
64e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubervoid OMXMaster::addPlugin(OMXPluginBase *plugin) {
65e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
66e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
67e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mPlugins.push_back(plugin);
68e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
69e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    OMX_U32 index = 0;
70e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
71e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    char name[128];
72e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    OMX_ERRORTYPE err;
73e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    while ((err = plugin->enumerateComponents(
74e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber                    name, sizeof(name), index++)) == OMX_ErrorNone) {
75e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        String8 name8(name);
76e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
77e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        if (mPluginByComponentName.indexOfKey(name8) >= 0) {
78e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber            LOGE("A component of name '%s' already exists, ignoring this one.",
79e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber                 name8.string());
80e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
81e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber            continue;
82e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        }
83e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
84e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        mPluginByComponentName.add(name8, plugin);
85e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
86e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    CHECK_EQ(err, OMX_ErrorNoMore);
87e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
88e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
89e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubervoid OMXMaster::clearPlugins() {
90e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
91e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
92e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mPluginByComponentName.clear();
93e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
94e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
95e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber         it != mPlugins.end(); ++it) {
96e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        delete *it;
97e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        *it = NULL;
98e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
99e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
100e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    mPlugins.clear();
101e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
102e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
103e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMX_ERRORTYPE OMXMaster::makeComponentInstance(
104e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        const char *name,
105e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        const OMX_CALLBACKTYPE *callbacks,
106e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_PTR appData,
107e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_COMPONENTTYPE **component) {
108e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
109e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
110e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    *component = NULL;
111e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
112e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
113e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
114e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (index < 0) {
115e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        return OMX_ErrorInvalidComponentName;
116e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
117e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
118e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
119f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMX_ERRORTYPE err =
120f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        plugin->makeComponentInstance(name, callbacks, appData, component);
121f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
122f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    if (err != OMX_ErrorNone) {
123f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        return err;
124f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    }
125f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
126f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    mPluginByInstance.add(*component, plugin);
127f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
128f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    return err;
129f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber}
130f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
131f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas HuberOMX_ERRORTYPE OMXMaster::destroyComponentInstance(
132f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        OMX_COMPONENTTYPE *component) {
133f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    Mutex::Autolock autoLock(mLock);
134f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
135f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    ssize_t index = mPluginByInstance.indexOfKey(component);
136f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
137f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    if (index < 0) {
138f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber        return OMX_ErrorBadParameter;
139f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    }
140f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
141f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMXPluginBase *plugin = mPluginByInstance.valueAt(index);
142f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    mPluginByInstance.removeItemsAt(index);
143f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
144f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    return plugin->destroyComponentInstance(component);
145e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
146e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
147e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas HuberOMX_ERRORTYPE OMXMaster::enumerateComponents(
148e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_STRING name,
149e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        size_t size,
150e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        OMX_U32 index) {
151e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    Mutex::Autolock autoLock(mLock);
152e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
153e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    size_t numComponents = mPluginByComponentName.size();
154e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
155e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    if (index >= numComponents) {
156e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber        return OMX_ErrorNoMore;
157e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    }
158e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
159e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    const String8 &name8 = mPluginByComponentName.keyAt(index);
160e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
161e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    CHECK(size >= 1 + name8.size());
162e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    strcpy(name, name8.string());
163e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
164e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber    return OMX_ErrorNone;
165e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}
166e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
1678ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas HuberOMX_ERRORTYPE OMXMaster::getRolesOfComponent(
1688ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber        const char *name,
1698ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber        Vector<String8> *roles) {
1708ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    Mutex::Autolock autoLock(mLock);
1718ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
1728ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    roles->clear();
1738ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
1748ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
1758ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
1768ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    if (index < 0) {
1778ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber        return OMX_ErrorInvalidComponentName;
1788ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    }
1798ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
1808ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
1818ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber    return plugin->getRolesOfComponent(name, roles);
1828ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber}
1838ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber
184e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber}  // namespace android
185