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