am 2d6d609c: Merge change I74bf38a0 into eclair-mr2

Merge commit '2d6d609c9ede7ed8924001df00af9c13effab8ad' into eclair-mr2-plus-aosp

* commit '2d6d609c9ede7ed8924001df00af9c13effab8ad':
  Squashed commit of the following:
This commit is contained in:
Andreas Huber
2009-12-03 16:40:04 -08:00
committed by Android Git Automerger
17 changed files with 1238 additions and 20 deletions

View File

@ -18,6 +18,7 @@
#define HARDWARE_API_H_
#include <media/stagefright/OMXPluginBase.h>
#include <media/stagefright/VideoRenderer.h>
#include <ui/ISurface.h>
#include <utils/RefBase.h>
@ -31,5 +32,7 @@ extern android::VideoRenderer *createRenderer(
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight);
extern android::OMXPluginBase *createOMXPlugin();
#endif // HARDWARE_API_H_

View File

@ -0,0 +1,51 @@
/*
* 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_PLUGIN_BASE_H_
#define OMX_PLUGIN_BASE_H_
#include <sys/types.h>
#include <OMX_Component.h>
namespace android {
struct OMXComponentBase;
struct OMXPluginBase {
OMXPluginBase() {}
virtual ~OMXPluginBase() {}
virtual OMX_ERRORTYPE makeComponentInstance(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component) = 0;
virtual OMX_ERRORTYPE enumerateComponents(
OMX_STRING name,
size_t size,
OMX_U32 index) = 0;
private:
OMXPluginBase(const OMXPluginBase &);
OMXPluginBase &operator=(const OMXPluginBase &);
};
} // namespace android
#endif // OMX_PLUGIN_BASE_H_

View File

@ -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;

View File

@ -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))

View File

@ -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);

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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) {

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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)

View File

@ -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

View File

@ -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_