diff options
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r-- | media/libstagefright/omx/Android.mk | 29 | ||||
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 30 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXComponentBase.cpp | 201 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXComponentBase.h | 96 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXMaster.cpp | 144 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXMaster.h | 61 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXPVCodecsPlugin.cpp | 61 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXPVCodecsPlugin.h | 47 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp | 82 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXSoftwareCodecsPlugin.h | 47 | ||||
-rw-r--r-- | media/libstagefright/omx/mp3dec/Android.mk | 16 | ||||
-rw-r--r-- | media/libstagefright/omx/mp3dec/MP3Decoder.cpp | 264 | ||||
-rw-r--r-- | media/libstagefright/omx/mp3dec/MP3Decoder.h | 115 |
14 files changed, 1178 insertions, 20 deletions
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_ |