OMXMaster.cpp revision c7e91eee2e79e3e4c8f84fd6b8a753215955d4e8
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
27namespace android {
28
29OMXMaster::OMXMaster()
30    : mVendorLibHandle(NULL) {
31    addVendorPlugin();
32
33#ifndef NO_OPENCORE
34    addPlugin(new OMXPVCodecsPlugin);
35#endif
36}
37
38OMXMaster::~OMXMaster() {
39    clearPlugins();
40
41    if (mVendorLibHandle != NULL) {
42        dlclose(mVendorLibHandle);
43        mVendorLibHandle = NULL;
44    }
45}
46
47void 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
64void 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
89void 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
103OMX_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
131OMX_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
147OMX_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
167OMX_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