summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2009-12-03 11:39:54 -0800
committerAndreas Huber <andih@google.com>2009-12-03 12:49:09 -0800
commite3ec3cec3a2e27033249ff82964d2cbd441d9873 (patch)
tree46e3b22fc02c1f20b8a8403818395ba4ba51ddb2 /media
parentc297fccffc4ab1cb3b9f5c6a5b0802be057f3e0f (diff)
downloadframeworks_av-e3ec3cec3a2e27033249ff82964d2cbd441d9873.zip
frameworks_av-e3ec3cec3a2e27033249ff82964d2cbd441d9873.tar.gz
frameworks_av-e3ec3cec3a2e27033249ff82964d2cbd441d9873.tar.bz2
Squashed commit of the following:
commit 543e192bf2ae13f573dc4c4e53b239ed4ea00e81 Author: Andreas Huber <andih@google.com> Date: Thu Dec 3 11:33:57 2009 -0800 stagefright now acts as the OMX Master, vendors supply their own plugins through libstagefrighthw. In OpenCore-enabled builds we now sit on top of PVMaster... commit 3cbfdbd9cecadbb77b63125c62883bf1065884fe Author: Andreas Huber <andih@google.com> Date: Wed Dec 2 12:39:07 2009 -0800 More OMX infrastructure, stagefright is now taking over the OMX Master, multiplexing all contributing OMX implementations under a common interface.
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/include/OMX.h6
-rw-r--r--media/libstagefright/omx/Android.mk29
-rw-r--r--media/libstagefright/omx/OMX.cpp30
-rw-r--r--media/libstagefright/omx/OMXComponentBase.cpp201
-rw-r--r--media/libstagefright/omx/OMXComponentBase.h96
-rw-r--r--media/libstagefright/omx/OMXMaster.cpp144
-rw-r--r--media/libstagefright/omx/OMXMaster.h61
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp5
-rw-r--r--media/libstagefright/omx/OMXPVCodecsPlugin.cpp61
-rw-r--r--media/libstagefright/omx/OMXPVCodecsPlugin.h47
-rw-r--r--media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp82
-rw-r--r--media/libstagefright/omx/OMXSoftwareCodecsPlugin.h47
-rw-r--r--media/libstagefright/omx/mp3dec/Android.mk16
-rw-r--r--media/libstagefright/omx/mp3dec/MP3Decoder.cpp264
-rw-r--r--media/libstagefright/omx/mp3dec/MP3Decoder.h115
15 files changed, 1184 insertions, 20 deletions
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index a4b62b2..01b8e7a 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -23,6 +23,7 @@
namespace android {
+struct OMXMaster;
class OMXNodeInstance;
class OMX : public BnOMX,
@@ -108,9 +109,14 @@ public:
void invalidateNodeID(node_id node);
+protected:
+ virtual ~OMX();
+
private:
Mutex mLock;
+ OMXMaster *mMaster;
+
struct CallbackDispatcher;
sp<CallbackDispatcher> mDispatcher;
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 389c2c9..de2e1ac 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -8,19 +8,36 @@ LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
-LOCAL_SRC_FILES:= \
- ColorConverter.cpp \
- OMX.cpp \
- OMXNodeInstance.cpp \
+LOCAL_SRC_FILES:= \
+ ColorConverter.cpp \
+ OMX.cpp \
+ OMXComponentBase.cpp \
+ OMXNodeInstance.cpp \
+ OMXMaster.cpp \
+ OMXSoftwareCodecsPlugin.cpp \
SoftwareRenderer.cpp
+ifneq ($(BUILD_WITHOUT_PV),true)
+LOCAL_SRC_FILES += \
+ OMXPVCodecsPlugin.cpp
+else
+LOCAL_CFLAGS += -DNO_OPENCORE
+endif
+
LOCAL_SHARED_LIBRARIES := \
libbinder \
libmedia \
libutils \
libui \
- libcutils \
+ libcutils
+
+ifneq ($(BUILD_WITHOUT_PV),true)
+LOCAL_SHARED_LIBRARIES += \
libopencore_common
+endif
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_mp3
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -lpthread -ldl
@@ -35,3 +52,5 @@ LOCAL_PRELINK_MODULE:= false
LOCAL_MODULE:= libstagefright_omx
include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 5b3cc1b..9f93c31 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -18,11 +18,11 @@
#define LOG_TAG "OMX"
#include <utils/Log.h>
+#include <dlfcn.h>
+
#include "../include/OMX.h"
#include "OMXRenderer.h"
-#include "pv_omxcore.h"
-
#include "../include/OMXNodeInstance.h"
#include "../include/SoftwareRenderer.h"
@@ -30,6 +30,8 @@
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/VideoRenderer.h>
+#include "OMXMaster.h"
+
#include <OMX_Component.h>
namespace android {
@@ -178,10 +180,16 @@ private:
};
OMX::OMX()
- : mDispatcher(new CallbackDispatcher(this)),
+ : mMaster(new OMXMaster),
+ mDispatcher(new CallbackDispatcher(this)),
mNodeCounter(0) {
}
+OMX::~OMX() {
+ delete mMaster;
+ mMaster = NULL;
+}
+
void OMX::binderDied(const wp<IBinder> &the_late_who) {
OMXNodeInstance *instance;
@@ -201,14 +209,12 @@ void OMX::binderDied(const wp<IBinder> &the_late_who) {
}
status_t OMX::listNodes(List<String8> *list) {
- OMX_MasterInit(); // XXX Put this somewhere else.
-
list->clear();
OMX_U32 index = 0;
char componentName[256];
- while (OMX_MasterComponentNameEnum(componentName, sizeof(componentName), index)
- == OMX_ErrorNone) {
+ while (mMaster->enumerateComponents(
+ componentName, sizeof(componentName), index) == OMX_ErrorNone) {
list->push_back(String8(componentName));
++index;
@@ -223,14 +229,12 @@ status_t OMX::allocateNode(
*node = 0;
- OMX_MasterInit(); // XXX Put this somewhere else.
-
OMXNodeInstance *instance = new OMXNodeInstance(this, observer);
- OMX_HANDLETYPE handle;
- OMX_ERRORTYPE err = OMX_MasterGetHandle(
- &handle, const_cast<char *>(name), instance,
- &OMXNodeInstance::kCallbacks);
+ OMX_COMPONENTTYPE *handle;
+ OMX_ERRORTYPE err = mMaster->makeComponentInstance(
+ name, &OMXNodeInstance::kCallbacks,
+ instance, &handle);
if (err != OMX_ErrorNone) {
LOGV("FAILED to allocate omx component '%s'", name);
diff --git a/media/libstagefright/omx/OMXComponentBase.cpp b/media/libstagefright/omx/OMXComponentBase.cpp
new file mode 100644
index 0000000..35227a0
--- /dev/null
+++ b/media/libstagefright/omx/OMXComponentBase.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "OMXComponentBase.h"
+
+#include <stdlib.h>
+
+#include <media/stagefright/MediaDebug.h>
+
+namespace android {
+
+OMXComponentBase::OMXComponentBase(
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData)
+ : mCallbacks(callbacks),
+ mAppData(appData),
+ mComponentHandle(NULL) {
+}
+
+OMXComponentBase::~OMXComponentBase() {}
+
+void OMXComponentBase::setComponentHandle(OMX_COMPONENTTYPE *handle) {
+ CHECK_EQ(mComponentHandle, NULL);
+ mComponentHandle = handle;
+}
+
+void OMXComponentBase::postEvent(
+ OMX_EVENTTYPE event, OMX_U32 param1, OMX_U32 param2) {
+ (*mCallbacks->EventHandler)(
+ mComponentHandle, mAppData, event, param1, param2, NULL);
+}
+
+void OMXComponentBase::postFillBufferDone(OMX_BUFFERHEADERTYPE *bufHdr) {
+ (*mCallbacks->FillBufferDone)(mComponentHandle, mAppData, bufHdr);
+}
+
+void OMXComponentBase::postEmptyBufferDone(OMX_BUFFERHEADERTYPE *bufHdr) {
+ (*mCallbacks->EmptyBufferDone)(mComponentHandle, mAppData, bufHdr);
+}
+
+static OMXComponentBase *getBase(OMX_HANDLETYPE hComponent) {
+ return (OMXComponentBase *)
+ ((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate;
+}
+
+static OMX_ERRORTYPE SendCommandWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_COMMANDTYPE Cmd,
+ OMX_IN OMX_U32 nParam1,
+ OMX_IN OMX_PTR pCmdData) {
+ return getBase(hComponent)->sendCommand(Cmd, nParam1, pCmdData);
+}
+
+static OMX_ERRORTYPE GetParameterWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nParamIndex,
+ OMX_INOUT OMX_PTR pComponentParameterStructure) {
+ return getBase(hComponent)->getParameter(
+ nParamIndex, pComponentParameterStructure);
+}
+
+static OMX_ERRORTYPE SetParameterWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR pComponentParameterStructure) {
+ return getBase(hComponent)->getParameter(
+ nIndex, pComponentParameterStructure);
+}
+
+static OMX_ERRORTYPE GetConfigWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_INOUT OMX_PTR pComponentConfigStructure) {
+ return getBase(hComponent)->getConfig(nIndex, pComponentConfigStructure);
+}
+
+static OMX_ERRORTYPE SetConfigWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR pComponentConfigStructure) {
+ return getBase(hComponent)->setConfig(nIndex, pComponentConfigStructure);
+}
+
+static OMX_ERRORTYPE GetExtensionIndexWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName,
+ OMX_OUT OMX_INDEXTYPE* pIndexType) {
+ return getBase(hComponent)->getExtensionIndex(cParameterName, pIndexType);
+}
+
+static OMX_ERRORTYPE GetStateWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_STATETYPE* pState) {
+ return getBase(hComponent)->getState(pState);
+}
+
+static OMX_ERRORTYPE UseBufferWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_PTR pAppPrivate,
+ OMX_IN OMX_U32 nSizeBytes,
+ OMX_IN OMX_U8* pBuffer) {
+ return getBase(hComponent)->useBuffer(
+ ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes, pBuffer);
+}
+
+static OMX_ERRORTYPE AllocateBufferWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_PTR pAppPrivate,
+ OMX_IN OMX_U32 nSizeBytes) {
+ return getBase(hComponent)->allocateBuffer(
+ ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
+}
+
+static OMX_ERRORTYPE FreeBufferWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
+ return getBase(hComponent)->freeBuffer(nPortIndex, pBuffer);
+}
+
+static OMX_ERRORTYPE EmptyThisBufferWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
+ return getBase(hComponent)->emptyThisBuffer(pBuffer);
+}
+
+static OMX_ERRORTYPE FillThisBufferWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
+ return getBase(hComponent)->fillThisBuffer(pBuffer);
+}
+
+static OMX_ERRORTYPE ComponentDeInitWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent) {
+ delete getBase(hComponent);
+ delete (OMX_COMPONENTTYPE *)hComponent;
+
+ return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE ComponentRoleEnumWrapper(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_U8 *cRole,
+ OMX_IN OMX_U32 nIndex) {
+ return getBase(hComponent)->enumerateRoles(cRole, nIndex);
+}
+
+// static
+OMX_COMPONENTTYPE *OMXComponentBase::MakeComponent(OMXComponentBase *base) {
+ OMX_COMPONENTTYPE *result = new OMX_COMPONENTTYPE;
+
+ result->nSize = sizeof(OMX_COMPONENTTYPE);
+ result->nVersion.s.nVersionMajor = 1;
+ result->nVersion.s.nVersionMinor = 0;
+ result->nVersion.s.nRevision = 0;
+ result->nVersion.s.nStep = 0;
+ result->pComponentPrivate = base;
+ result->pApplicationPrivate = NULL;
+
+ result->GetComponentVersion = NULL;
+ result->SendCommand = SendCommandWrapper;
+ result->GetParameter = GetParameterWrapper;
+ result->SetParameter = SetParameterWrapper;
+ result->GetConfig = GetConfigWrapper;
+ result->SetConfig = SetConfigWrapper;
+ result->GetExtensionIndex = GetExtensionIndexWrapper;
+ result->GetState = GetStateWrapper;
+ result->ComponentTunnelRequest = NULL;
+ result->UseBuffer = UseBufferWrapper;
+ result->AllocateBuffer = AllocateBufferWrapper;
+ result->FreeBuffer = FreeBufferWrapper;
+ result->EmptyThisBuffer = EmptyThisBufferWrapper;
+ result->FillThisBuffer = FillThisBufferWrapper;
+ result->SetCallbacks = NULL;
+ result->ComponentDeInit = ComponentDeInitWrapper;
+ result->UseEGLImage = NULL;
+ result->ComponentRoleEnum = ComponentRoleEnumWrapper;
+
+ base->setComponentHandle(result);
+
+ return result;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/OMXComponentBase.h b/media/libstagefright/omx/OMXComponentBase.h
new file mode 100644
index 0000000..fd0df0b
--- /dev/null
+++ b/media/libstagefright/omx/OMXComponentBase.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_COMPONENT_BASE_H_
+
+#define OMX_COMPONENT_BASE_H_
+
+#include <OMX_Component.h>
+
+namespace android {
+
+struct OMXComponentBase {
+ OMXComponentBase(
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData);
+
+ virtual ~OMXComponentBase();
+
+ virtual OMX_ERRORTYPE sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR cmdData) = 0;
+
+ virtual OMX_ERRORTYPE getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) = 0;
+
+ virtual OMX_ERRORTYPE setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) = 0;
+
+ virtual OMX_ERRORTYPE getConfig(
+ OMX_INDEXTYPE index, OMX_PTR config) = 0;
+
+ virtual OMX_ERRORTYPE setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR config) = 0;
+
+ virtual OMX_ERRORTYPE getExtensionIndex(
+ const OMX_STRING name, OMX_INDEXTYPE *index) = 0;
+
+ virtual OMX_ERRORTYPE useBuffer(
+ OMX_BUFFERHEADERTYPE **bufHdr,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *buffer) = 0;
+
+ virtual OMX_ERRORTYPE allocateBuffer(
+ OMX_BUFFERHEADERTYPE **bufHdr,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) = 0;
+
+ virtual OMX_ERRORTYPE freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer) = 0;
+
+ virtual OMX_ERRORTYPE emptyThisBuffer(OMX_BUFFERHEADERTYPE *buffer) = 0;
+ virtual OMX_ERRORTYPE fillThisBuffer(OMX_BUFFERHEADERTYPE *buffer) = 0;
+
+ virtual OMX_ERRORTYPE enumerateRoles(OMX_U8 *role, OMX_U32 index) = 0;
+
+ virtual OMX_ERRORTYPE getState(OMX_STATETYPE *state) = 0;
+
+ // Wraps a given OMXComponentBase instance into an OMX_COMPONENTTYPE
+ // as required by OpenMAX APIs.
+ static OMX_COMPONENTTYPE *MakeComponent(OMXComponentBase *base);
+
+protected:
+ void postEvent(OMX_EVENTTYPE event, OMX_U32 param1, OMX_U32 param2);
+ void postFillBufferDone(OMX_BUFFERHEADERTYPE *bufHdr);
+ void postEmptyBufferDone(OMX_BUFFERHEADERTYPE *bufHdr);
+
+private:
+ void setComponentHandle(OMX_COMPONENTTYPE *handle);
+
+ const OMX_CALLBACKTYPE *mCallbacks;
+ OMX_PTR mAppData;
+ OMX_COMPONENTTYPE *mComponentHandle;
+
+ OMXComponentBase(const OMXComponentBase &);
+ OMXComponentBase &operator=(const OMXComponentBase &);
+};
+
+} // namespace android
+
+#endif // OMX_COMPONENT_BASE_H_
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
new file mode 100644
index 0000000..838a9f7
--- /dev/null
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "OMXMaster.h"
+
+#include <dlfcn.h>
+
+#include <media/stagefright/MediaDebug.h>
+
+#ifndef NO_OPENCORE
+#include "OMXPVCodecsPlugin.h"
+#endif
+
+#include "OMXSoftwareCodecsPlugin.h"
+
+namespace android {
+
+OMXMaster::OMXMaster()
+ : mVendorLibHandle(NULL) {
+ addPlugin(new OMXSoftwareCodecsPlugin);
+
+ addVendorPlugin();
+
+#ifndef NO_OPENCORE
+ addPlugin(new OMXPVCodecsPlugin);
+#endif
+}
+
+OMXMaster::~OMXMaster() {
+ clearPlugins();
+
+ if (mVendorLibHandle != NULL) {
+ dlclose(mVendorLibHandle);
+ mVendorLibHandle = NULL;
+ }
+}
+
+void OMXMaster::addVendorPlugin() {
+ mVendorLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
+
+ if (mVendorLibHandle == NULL) {
+ return;
+ }
+
+ typedef OMXPluginBase *(*CreateOMXPluginFunc)();
+ CreateOMXPluginFunc createOMXPlugin =
+ (CreateOMXPluginFunc)dlsym(
+ mVendorLibHandle, "_ZN7android15createOMXPluginEv");
+
+ addPlugin((*createOMXPlugin)());
+}
+
+void OMXMaster::addPlugin(OMXPluginBase *plugin) {
+ Mutex::Autolock autoLock(mLock);
+
+ mPlugins.push_back(plugin);
+
+ OMX_U32 index = 0;
+
+ char name[128];
+ OMX_ERRORTYPE err;
+ while ((err = plugin->enumerateComponents(
+ name, sizeof(name), index++)) == OMX_ErrorNone) {
+ String8 name8(name);
+
+ if (mPluginByComponentName.indexOfKey(name8) >= 0) {
+ LOGE("A component of name '%s' already exists, ignoring this one.",
+ name8.string());
+
+ continue;
+ }
+
+ mPluginByComponentName.add(name8, plugin);
+ }
+ CHECK_EQ(err, OMX_ErrorNoMore);
+}
+
+void OMXMaster::clearPlugins() {
+ Mutex::Autolock autoLock(mLock);
+
+ mPluginByComponentName.clear();
+
+ for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
+ it != mPlugins.end(); ++it) {
+ delete *it;
+ *it = NULL;
+ }
+
+ mPlugins.clear();
+}
+
+OMX_ERRORTYPE OMXMaster::makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ Mutex::Autolock autoLock(mLock);
+
+ *component = NULL;
+
+ ssize_t index = mPluginByComponentName.indexOfKey(String8(name));
+
+ if (index < 0) {
+ return OMX_ErrorInvalidComponentName;
+ }
+
+ OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
+ return plugin->makeComponentInstance(name, callbacks, appData, component);
+}
+
+OMX_ERRORTYPE OMXMaster::enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index) {
+ Mutex::Autolock autoLock(mLock);
+
+ size_t numComponents = mPluginByComponentName.size();
+
+ if (index >= numComponents) {
+ return OMX_ErrorNoMore;
+ }
+
+ const String8 &name8 = mPluginByComponentName.keyAt(index);
+
+ CHECK(size >= 1 + name8.size());
+ strcpy(name, name8.string());
+
+ return OMX_ErrorNone;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/OMXMaster.h b/media/libstagefright/omx/OMXMaster.h
new file mode 100644
index 0000000..63cd664
--- /dev/null
+++ b/media/libstagefright/omx/OMXMaster.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_MASTER_H_
+
+#define OMX_MASTER_H_
+
+#include <media/stagefright/OMXPluginBase.h>
+
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+#include <utils/List.h>
+#include <utils/String8.h>
+
+namespace android {
+
+struct OMXMaster : public OMXPluginBase {
+ OMXMaster();
+ virtual ~OMXMaster();
+
+ virtual OMX_ERRORTYPE makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index);
+
+private:
+ Mutex mLock;
+ List<OMXPluginBase *> mPlugins;
+ KeyedVector<String8, OMXPluginBase *> mPluginByComponentName;
+ void *mVendorLibHandle;
+
+ void addVendorPlugin();
+ void addPlugin(OMXPluginBase *plugin);
+ void clearPlugins();
+
+ OMXMaster(const OMXMaster &);
+ OMXMaster &operator=(const OMXMaster &);
+};
+
+} // namespace android
+
+#endif // OMX_MASTER_H_
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 8218918..099139a 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -20,7 +20,7 @@
#include "../include/OMXNodeInstance.h"
-#include "pv_omxcore.h"
+#include <OMX_Component.h>
#include <binder/IMemory.h>
#include <media/stagefright/MediaDebug.h>
@@ -157,7 +157,8 @@ status_t OMXNodeInstance::freeNode() {
break;
}
- OMX_ERRORTYPE err = OMX_MasterFreeHandle(mHandle);
+ OMX_ERRORTYPE err =
+ (*static_cast<OMX_COMPONENTTYPE *>(mHandle)->ComponentDeInit)(mHandle);
mHandle = NULL;
if (err != OMX_ErrorNone) {
diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp b/media/libstagefright/omx/OMXPVCodecsPlugin.cpp
new file mode 100644
index 0000000..3957901
--- /dev/null
+++ b/media/libstagefright/omx/OMXPVCodecsPlugin.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "OMXPVCodecsPlugin.h"
+
+#include "pv_omxcore.h"
+
+#include <media/stagefright/MediaDebug.h>
+
+namespace android {
+
+OMXPVCodecsPlugin::OMXPVCodecsPlugin() {
+ OMX_MasterInit();
+}
+
+OMXPVCodecsPlugin::~OMXPVCodecsPlugin() {
+ OMX_MasterDeinit();
+}
+
+OMX_ERRORTYPE OMXPVCodecsPlugin::makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ OMX_ERRORTYPE err = OMX_MasterGetHandle(
+ reinterpret_cast<OMX_HANDLETYPE *>(component),
+ const_cast<char *>(name),
+ appData,
+ const_cast<OMX_CALLBACKTYPE *>(callbacks));
+
+ if (err != OMX_ErrorNone) {
+ return err;
+ }
+
+ // PV is not even filling this in...
+ (*component)->ComponentDeInit = &OMX_MasterFreeHandle;
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE OMXPVCodecsPlugin::enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index) {
+ return OMX_MasterComponentNameEnum(name, size, index);
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.h b/media/libstagefright/omx/OMXPVCodecsPlugin.h
new file mode 100644
index 0000000..55ca87a
--- /dev/null
+++ b/media/libstagefright/omx/OMXPVCodecsPlugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_PV_CODECS_PLUGIN_H_
+
+#define OMX_PV_CODECS_PLUGIN_H_
+
+#include <media/stagefright/OMXPluginBase.h>
+
+namespace android {
+
+struct OMXPVCodecsPlugin : public OMXPluginBase {
+ OMXPVCodecsPlugin();
+ virtual ~OMXPVCodecsPlugin();
+
+ virtual OMX_ERRORTYPE makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index);
+
+private:
+ OMXPVCodecsPlugin(const OMXPVCodecsPlugin &);
+ OMXPVCodecsPlugin &operator=(const OMXPVCodecsPlugin &);
+};
+
+} // namespace android
+
+#endif // OMX_PV_CODECS_PLUGIN_H_
diff --git a/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp
new file mode 100644
index 0000000..955e509
--- /dev/null
+++ b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "OMXSoftwareCodecsPlugin.h"
+
+#include "mp3dec/MP3Decoder.h"
+
+namespace android {
+
+typedef OMX_ERRORTYPE (*ComponentFactory)(
+ const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+static OMX_ERRORTYPE MakeMP3Decoder(
+ const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ *component = OMXComponentBase::MakeComponent(
+ new MP3Decoder(callbacks, appData));
+
+ return OMX_ErrorNone;
+}
+
+static const struct ComponentInfo {
+ const char *mName;
+ ComponentFactory mFactory;
+} kComponentInfos[] = {
+ { "OMX.google.mp3dec", MakeMP3Decoder }
+};
+
+OMXSoftwareCodecsPlugin::OMXSoftwareCodecsPlugin() {
+}
+
+OMX_ERRORTYPE OMXSoftwareCodecsPlugin::makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ *component = NULL;
+
+ const size_t kNumComponentInfos =
+ sizeof(kComponentInfos) / sizeof(kComponentInfos[0]);
+
+ for (size_t i = 0; i < kNumComponentInfos; ++i) {
+ if (!strcmp(kComponentInfos[i].mName, name)) {
+ return (*kComponentInfos[i].mFactory)(
+ callbacks, appData, component);
+ }
+ }
+
+ return OMX_ErrorInvalidComponentName;
+}
+
+OMX_ERRORTYPE OMXSoftwareCodecsPlugin::enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index) {
+ const size_t kNumComponentInfos =
+ sizeof(kComponentInfos) / sizeof(kComponentInfos[0]);
+
+ if (index >= kNumComponentInfos) {
+ return OMX_ErrorNoMore;
+ }
+
+ strlcpy(name, kComponentInfos[index].mName, size);
+
+ return OMX_ErrorNone;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h
new file mode 100644
index 0000000..dcb5b19
--- /dev/null
+++ b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OMX_SOFTWARE_CODECS_PLUGIN_H_
+
+#define OMX_SOFTWARE_CODECS_PLUGIN_H_
+
+#include <media/stagefright/OMXPluginBase.h>
+
+namespace android {
+
+struct OMXSoftwareCodecsPlugin : public OMXPluginBase {
+ OMXSoftwareCodecsPlugin();
+
+ virtual OMX_ERRORTYPE makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index);
+
+private:
+ OMXSoftwareCodecsPlugin(const OMXSoftwareCodecsPlugin &);
+ OMXSoftwareCodecsPlugin &operator=(const OMXSoftwareCodecsPlugin &);
+};
+
+} // namespace android
+
+#endif // OMX_SOFTWARE_CODECS_PLUGIN_H_
+
diff --git a/media/libstagefright/omx/mp3dec/Android.mk b/media/libstagefright/omx/mp3dec/Android.mk
new file mode 100644
index 0000000..cd8b1f2
--- /dev/null
+++ b/media/libstagefright/omx/mp3dec/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ MP3Decoder.cpp
+
+LOCAL_C_INCLUDES:= \
+ $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
+
+LOCAL_SHARED_LIBRARIES:= \
+ libstagefright_omx \
+ libutils
+
+LOCAL_MODULE:= libstagefright_mp3
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/omx/mp3dec/MP3Decoder.cpp b/media/libstagefright/omx/mp3dec/MP3Decoder.cpp
new file mode 100644
index 0000000..ef085e1
--- /dev/null
+++ b/media/libstagefright/omx/mp3dec/MP3Decoder.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MP3Decoder.h"
+
+#include <media/stagefright/MediaDebug.h>
+
+namespace android {
+
+MP3Decoder::MP3Decoder(
+ const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData)
+ : OMXComponentBase(callbacks, appData),
+ mState(OMX_StateLoaded),
+ mTargetState(OMX_StateLoaded) {
+ initPort(kPortIndexInput);
+ initPort(kPortIndexOutput);
+}
+
+void MP3Decoder::initPort(OMX_U32 portIndex) {
+ mPorts[portIndex].mFlags = 0;
+
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &mPorts[portIndex].mDefinition;
+
+ def->nSize = sizeof(*def);
+ def->nVersion.s.nVersionMajor = 1;
+ def->nVersion.s.nVersionMinor = 0;
+ def->nVersion.s.nRevision = 0;
+ def->nVersion.s.nStep = 0;
+ def->nPortIndex = portIndex;
+ def->eDir = (portIndex == kPortIndexInput) ? OMX_DirInput : OMX_DirOutput;
+ def->nBufferCountActual = 1;
+ def->nBufferCountMin = 1;
+ def->bEnabled = OMX_TRUE;
+ def->bPopulated = OMX_FALSE;
+ def->eDomain = OMX_PortDomainAudio;
+
+ OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def->format.audio;
+
+ if (portIndex == kPortIndexInput) {
+ def->nBufferSize = 8192;
+ strlcpy(audioDef->cMIMEType, "audio/mpeg", 128);
+ audioDef->pNativeRender = NULL;
+ audioDef->bFlagErrorConcealment = OMX_FALSE;
+ audioDef->eEncoding = OMX_AUDIO_CodingMP3;
+ } else {
+ CHECK_EQ(portIndex, kPortIndexOutput);
+
+ def->nBufferSize = 8192;
+ strlcpy(audioDef->cMIMEType, "audio/raw", 128);
+ audioDef->pNativeRender = NULL;
+ audioDef->bFlagErrorConcealment = OMX_FALSE;
+ audioDef->eEncoding = OMX_AUDIO_CodingPCM;
+ }
+
+ def->bBuffersContiguous = OMX_TRUE; // XXX What's this?
+ def->nBufferAlignment = 1;
+}
+
+MP3Decoder::~MP3Decoder() {
+}
+
+OMX_ERRORTYPE MP3Decoder::sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR cmdData) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *def =
+ (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+
+ if (def->nSize < sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (def->nPortIndex != kPortIndexInput
+ && def->nPortIndex != kPortIndexOutput) {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (mPorts[def->nPortIndex].mDefinition.bEnabled
+ && mState != OMX_StateLoaded) {
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ memcpy(def, &mPorts[def->nPortIndex].mDefinition,
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+OMX_ERRORTYPE MP3Decoder::setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::getConfig(
+ OMX_INDEXTYPE index, OMX_PTR config) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR config) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::getExtensionIndex(
+ const OMX_STRING name, OMX_INDEXTYPE *index) {
+ return OMX_ErrorUndefined;
+}
+
+bool MP3Decoder::portIsDisabledOrPopulated(OMX_U32 portIndex) const {
+ return !mPorts[portIndex].mDefinition.bEnabled
+ || mPorts[portIndex].mDefinition.bPopulated;
+}
+
+OMX_ERRORTYPE MP3Decoder::useOrAllocateBuffer(
+ OMX_BUFFERHEADERTYPE **out,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *buffer) {
+ if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (!mPorts[portIndex].mDefinition.bEnabled) {
+ if (!(mPorts[portIndex].mFlags & kPortFlagEnabling)) {
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ } else if (mState != OMX_StateLoaded || mTargetState != OMX_StateIdle) {
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (size < mPorts[portIndex].mDefinition.nBufferSize) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (out == NULL) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer == NULL) {
+ // We need to allocate memory.
+ buffer = new OMX_U8[size];
+
+ // XXX Keep track of buffers we allocated and free them later.
+ }
+
+ OMX_BUFFERHEADERTYPE *bufHdr = new OMX_BUFFERHEADERTYPE;
+ bufHdr->nSize = sizeof(*bufHdr);
+ bufHdr->nVersion.s.nVersionMajor = 1;
+ bufHdr->nVersion.s.nVersionMinor = 0;
+ bufHdr->nVersion.s.nRevision = 0;
+ bufHdr->nVersion.s.nStep = 0;
+ bufHdr->pBuffer = buffer;
+ bufHdr->nAllocLen = size;
+ bufHdr->nFilledLen = 0;
+ bufHdr->nOffset = 0;
+ bufHdr->pAppPrivate = appPrivate;
+ bufHdr->pPlatformPrivate = NULL;
+ bufHdr->pInputPortPrivate = NULL;
+ bufHdr->pOutputPortPrivate = NULL;
+ bufHdr->hMarkTargetComponent = NULL;
+ bufHdr->pMarkData = NULL;
+ bufHdr->nTickCount = 0;
+ bufHdr->nTimeStamp = 0;
+ bufHdr->nFlags = 0;
+ bufHdr->nOutputPortIndex = 0;
+ bufHdr->nInputPortIndex = 0;
+
+ mPorts[portIndex].mBuffers.push(bufHdr);
+
+ if (mPorts[portIndex].mBuffers.size()
+ == mPorts[portIndex].mDefinition.nBufferCountActual) {
+ if (mPorts[portIndex].mDefinition.bEnabled) {
+ mPorts[portIndex].mDefinition.bPopulated = OMX_TRUE;
+ } else if (mPorts[portIndex].mFlags & kPortFlagEnabling) {
+ mPorts[portIndex].mFlags &= ~kPortFlagEnabling;
+ mPorts[portIndex].mDefinition.bEnabled = OMX_TRUE;
+ mPorts[portIndex].mDefinition.bPopulated = OMX_TRUE;
+ postEvent(OMX_EventCmdComplete, OMX_CommandPortEnable, portIndex);
+ }
+ }
+
+ if (mState == OMX_StateLoaded
+ && portIsDisabledOrPopulated(kPortIndexInput)
+ && portIsDisabledOrPopulated(kPortIndexOutput)) {
+ mState = OMX_StateIdle;
+ postEvent(OMX_EventCmdComplete, OMX_CommandStateSet, mState);
+ }
+
+ *out = bufHdr;
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE MP3Decoder::useBuffer(
+ OMX_BUFFERHEADERTYPE **out,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *buffer) {
+ if (buffer == NULL) {
+ return OMX_ErrorBadParameter;
+ }
+
+ return useOrAllocateBuffer(out, portIndex, appPrivate, size, buffer);
+}
+
+OMX_ERRORTYPE MP3Decoder::allocateBuffer(
+ OMX_BUFFERHEADERTYPE **out,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) {
+ return useOrAllocateBuffer(out, portIndex, appPrivate, size, NULL);
+}
+
+OMX_ERRORTYPE MP3Decoder::freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::emptyThisBuffer(OMX_BUFFERHEADERTYPE *buffer) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::fillThisBuffer(OMX_BUFFERHEADERTYPE *buffer) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE MP3Decoder::enumerateRoles(OMX_U8 *role, OMX_U32 index) {
+ return OMX_ErrorNoMore;
+}
+
+OMX_ERRORTYPE MP3Decoder::getState(OMX_STATETYPE *state) {
+ *state = mState;
+
+ return OMX_ErrorNone;
+}
+
+} // namespace android
diff --git a/media/libstagefright/omx/mp3dec/MP3Decoder.h b/media/libstagefright/omx/mp3dec/MP3Decoder.h
new file mode 100644
index 0000000..555acce
--- /dev/null
+++ b/media/libstagefright/omx/mp3dec/MP3Decoder.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MP3_DECODER_H_
+
+#define MP3_DECODER_H_
+
+#include "../OMXComponentBase.h"
+
+#include <OMX_Component.h>
+
+#include <utils/Vector.h>
+
+namespace android {
+
+struct MP3Decoder : public OMXComponentBase {
+ MP3Decoder(const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData);
+ virtual ~MP3Decoder();
+
+ virtual OMX_ERRORTYPE sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR cmdData);
+
+ virtual OMX_ERRORTYPE getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getConfig(
+ OMX_INDEXTYPE index, OMX_PTR config);
+
+ virtual OMX_ERRORTYPE setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR config);
+
+ virtual OMX_ERRORTYPE getExtensionIndex(
+ const OMX_STRING name, OMX_INDEXTYPE *index);
+
+ virtual OMX_ERRORTYPE useBuffer(
+ OMX_BUFFERHEADERTYPE **bufHdr,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *buffer);
+
+ virtual OMX_ERRORTYPE allocateBuffer(
+ OMX_BUFFERHEADERTYPE **bufHdr,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ virtual OMX_ERRORTYPE freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE emptyThisBuffer(OMX_BUFFERHEADERTYPE *buffer);
+ virtual OMX_ERRORTYPE fillThisBuffer(OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE enumerateRoles(OMX_U8 *role, OMX_U32 index);
+
+ virtual OMX_ERRORTYPE getState(OMX_STATETYPE *state);
+
+private:
+ enum {
+ kPortIndexInput = 0,
+ kPortIndexOutput = 1,
+
+ kNumPorts
+ };
+
+ enum {
+ kPortFlagEnabling = 1
+ };
+
+ struct Port {
+ uint32_t mFlags;
+ Vector<OMX_BUFFERHEADERTYPE *> mBuffers;
+ OMX_PARAM_PORTDEFINITIONTYPE mDefinition;
+ };
+
+ OMX_STATETYPE mState;
+ OMX_STATETYPE mTargetState;
+
+ Port mPorts[kNumPorts];
+
+ void initPort(OMX_U32 portIndex);
+
+ bool portIsDisabledOrPopulated(OMX_U32 portIndex) const;
+
+ OMX_ERRORTYPE useOrAllocateBuffer(
+ OMX_BUFFERHEADERTYPE **out,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *buffer);
+
+ MP3Decoder(const MP3Decoder &);
+ MP3Decoder &operator=(const MP3Decoder &);
+};
+
+} // namespace android
+
+#endif // MP3_DECODER_H_