diff options
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r-- | media/libstagefright/omx/Android.mk | 50 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXMaster.cpp | 17 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXMaster.h | 1 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 1 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXPVCodecsPlugin.cpp | 101 | ||||
-rw-r--r-- | media/libstagefright/omx/SimpleSoftOMXComponent.cpp | 640 | ||||
-rw-r--r-- | media/libstagefright/omx/SoftOMXComponent.cpp | 326 | ||||
-rw-r--r-- | media/libstagefright/omx/SoftOMXPlugin.cpp | 170 | ||||
-rw-r--r-- | media/libstagefright/omx/SoftOMXPlugin.h (renamed from media/libstagefright/omx/OMXPVCodecsPlugin.h) | 17 | ||||
-rw-r--r-- | media/libstagefright/omx/tests/OMXHarness.cpp | 21 |
10 files changed, 1192 insertions, 152 deletions
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk index 6e069c8..08ad6f3 100644 --- a/media/libstagefright/omx/Android.mk +++ b/media/libstagefright/omx/Android.mk @@ -1,41 +1,28 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -ifneq ($(BUILD_WITHOUT_PV),true) -# Set up the OpenCore variables. -include external/opencore/Config.mk -LOCAL_C_INCLUDES := $(PV_INCLUDES) -LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY) -endif - LOCAL_C_INCLUDES += $(JNI_H_INCLUDE) LOCAL_SRC_FILES:= \ - OMX.cpp \ + OMX.cpp \ OMXComponentBase.cpp \ + OMXMaster.cpp \ OMXNodeInstance.cpp \ - OMXMaster.cpp - -ifneq ($(BUILD_WITHOUT_PV),true) -LOCAL_SRC_FILES += \ - OMXPVCodecsPlugin.cpp -else -LOCAL_CFLAGS += -DNO_OPENCORE -endif - -LOCAL_C_INCLUDES += $(TOP)/frameworks/base/include/media/stagefright/openmax - -LOCAL_SHARED_LIBRARIES := \ - libbinder \ - libmedia \ - libutils \ - libui \ - libcutils \ - -ifneq ($(BUILD_WITHOUT_PV),true) -LOCAL_SHARED_LIBRARIES += \ - libopencore_common -endif + SimpleSoftOMXComponent.cpp \ + SoftOMXComponent.cpp \ + SoftOMXPlugin.cpp \ + +LOCAL_C_INCLUDES += \ + frameworks/base/media/libstagefright \ + $(TOP)/frameworks/base/include/media/stagefright/openmax + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libmedia \ + libutils \ + libui \ + libcutils \ + libstagefright_foundation \ ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) LOCAL_LDLIBS += -lpthread -ldl @@ -49,5 +36,6 @@ LOCAL_MODULE:= libstagefright_omx include $(BUILD_SHARED_LIBRARY) -include $(call all-makefiles-under,$(LOCAL_PATH)) +################################################################################ +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp index 56b169a..545e6d4 100644 --- a/media/libstagefright/omx/OMXMaster.cpp +++ b/media/libstagefright/omx/OMXMaster.cpp @@ -20,23 +20,18 @@ #include "OMXMaster.h" +#include "SoftOMXPlugin.h" + #include <dlfcn.h> #include <media/stagefright/MediaDebug.h> -#ifndef NO_OPENCORE -#include "OMXPVCodecsPlugin.h" -#endif - namespace android { OMXMaster::OMXMaster() : mVendorLibHandle(NULL) { addVendorPlugin(); - -#ifndef NO_OPENCORE - addPlugin(new OMXPVCodecsPlugin); -#endif + addPlugin(new SoftOMXPlugin); } OMXMaster::~OMXMaster() { @@ -49,7 +44,11 @@ OMXMaster::~OMXMaster() { } void OMXMaster::addVendorPlugin() { - mVendorLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW); + addPlugin("libstagefrighthw.so"); +} + +void OMXMaster::addPlugin(const char *libname) { + mVendorLibHandle = dlopen(libname, RTLD_NOW); if (mVendorLibHandle == NULL) { return; diff --git a/media/libstagefright/omx/OMXMaster.h b/media/libstagefright/omx/OMXMaster.h index 7ba8d18..feee1f9 100644 --- a/media/libstagefright/omx/OMXMaster.h +++ b/media/libstagefright/omx/OMXMaster.h @@ -58,6 +58,7 @@ private: void *mVendorLibHandle; void addVendorPlugin(); + void addPlugin(const char *libname); void addPlugin(OMXPluginBase *plugin); void clearPlugins(); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index cdce772..8462988 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -234,6 +234,7 @@ status_t OMXNodeInstance::getParameter( Mutex::Autolock autoLock(mLock); OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params); + return StatusFromOMXError(err); } diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp b/media/libstagefright/omx/OMXPVCodecsPlugin.cpp deleted file mode 100644 index d1f5be3..0000000 --- a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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) { - return OMX_MasterGetHandle( - reinterpret_cast<OMX_HANDLETYPE *>(component), - const_cast<char *>(name), - appData, - const_cast<OMX_CALLBACKTYPE *>(callbacks)); -} - -OMX_ERRORTYPE OMXPVCodecsPlugin::destroyComponentInstance( - OMX_COMPONENTTYPE *component) { - return OMX_MasterFreeHandle(component); -} - -OMX_ERRORTYPE OMXPVCodecsPlugin::enumerateComponents( - OMX_STRING name, - size_t size, - OMX_U32 index) { - return OMX_MasterComponentNameEnum(name, size, index); -} - -OMX_ERRORTYPE OMXPVCodecsPlugin::getRolesOfComponent( - const char *name, - Vector<String8> *roles) { - roles->clear(); - - OMX_U32 numRoles; - OMX_ERRORTYPE err = - OMX_MasterGetRolesOfComponent( - const_cast<char *>(name), - &numRoles, - NULL); - - if (err != OMX_ErrorNone) { - return err; - } - - if (numRoles > 0) { - OMX_U8 **array = new OMX_U8 *[numRoles]; - for (OMX_U32 i = 0; i < numRoles; ++i) { - array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE]; - } - - OMX_U32 numRoles2; - err = OMX_MasterGetRolesOfComponent( - const_cast<char *>(name), &numRoles2, array); - - CHECK_EQ(err, OMX_ErrorNone); - CHECK_EQ(numRoles, numRoles2); - - for (OMX_U32 i = 0; i < numRoles; ++i) { - String8 s((const char *)array[i]); - roles->push(s); - - delete[] array[i]; - array[i] = NULL; - } - - delete[] array; - array = NULL; - } - - return OMX_ErrorNone; -} - -} // namespace android diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp new file mode 100644 index 0000000..179b2a0 --- /dev/null +++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp @@ -0,0 +1,640 @@ +/* + * Copyright (C) 2011 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. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SimpleSoftOMXComponent" +#include <utils/Log.h> + +#include "include/SimpleSoftOMXComponent.h" + +#include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/ALooper.h> +#include <media/stagefright/foundation/AMessage.h> + +namespace android { + +SimpleSoftOMXComponent::SimpleSoftOMXComponent( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) + : SoftOMXComponent(name, callbacks, appData, component), + mLooper(new ALooper), + mHandler(new AHandlerReflector<SimpleSoftOMXComponent>(this)), + mState(OMX_StateLoaded), + mTargetState(OMX_StateLoaded) { + mLooper->setName(name); + mLooper->registerHandler(mHandler); + + mLooper->start( + false, // runOnCallingThread + false, // canCallJava + PRIORITY_AUDIO); +} + +SimpleSoftOMXComponent::~SimpleSoftOMXComponent() { + mLooper->unregisterHandler(mHandler->id()); + mLooper->stop(); +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::sendCommand( + OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) { + CHECK(data == NULL); + + sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler->id()); + msg->setInt32("cmd", cmd); + msg->setInt32("param", param); + msg->post(); + + return OMX_ErrorNone; +} + +bool SimpleSoftOMXComponent::isSetParameterAllowed( + OMX_INDEXTYPE index, const OMX_PTR params) const { + if (mState == OMX_StateLoaded) { + return true; + } + + OMX_U32 portIndex; + + switch (index) { + case OMX_IndexParamPortDefinition: + { + portIndex = ((OMX_PARAM_PORTDEFINITIONTYPE *)params)->nPortIndex; + break; + } + + case OMX_IndexParamAudioPcm: + { + portIndex = ((OMX_AUDIO_PARAM_PCMMODETYPE *)params)->nPortIndex; + break; + } + + case OMX_IndexParamAudioAac: + { + portIndex = ((OMX_AUDIO_PARAM_AACPROFILETYPE *)params)->nPortIndex; + break; + } + + default: + return false; + } + + CHECK(portIndex < mPorts.size()); + + return !mPorts.itemAt(portIndex).mDef.bEnabled; +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::getParameter( + OMX_INDEXTYPE index, OMX_PTR params) { + Mutex::Autolock autoLock(mLock); + return internalGetParameter(index, params); +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::setParameter( + OMX_INDEXTYPE index, const OMX_PTR params) { + Mutex::Autolock autoLock(mLock); + + CHECK(isSetParameterAllowed(index, params)); + + return internalSetParameter(index, params); +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::internalGetParameter( + OMX_INDEXTYPE index, OMX_PTR params) { + switch (index) { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *defParams = + (OMX_PARAM_PORTDEFINITIONTYPE *)params; + + if (defParams->nPortIndex >= mPorts.size() + || defParams->nSize + != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) { + return OMX_ErrorUndefined; + } + + const PortInfo *port = + &mPorts.itemAt(defParams->nPortIndex); + + memcpy(defParams, &port->mDef, sizeof(port->mDef)); + + return OMX_ErrorNone; + } + + default: + return OMX_ErrorUnsupportedIndex; + } +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::internalSetParameter( + OMX_INDEXTYPE index, const OMX_PTR params) { + switch (index) { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *defParams = + (OMX_PARAM_PORTDEFINITIONTYPE *)params; + + if (defParams->nPortIndex >= mPorts.size() + || defParams->nSize + != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) { + return OMX_ErrorUndefined; + } + + PortInfo *port = + &mPorts.editItemAt(defParams->nPortIndex); + + if (defParams->nBufferSize != port->mDef.nBufferSize) { + CHECK_GE(defParams->nBufferSize, port->mDef.nBufferSize); + port->mDef.nBufferSize = defParams->nBufferSize; + } + + if (defParams->nBufferCountActual + != port->mDef.nBufferCountActual) { + CHECK_GE(defParams->nBufferCountActual, + port->mDef.nBufferCountMin); + + port->mDef.nBufferCountActual = defParams->nBufferCountActual; + } + + return OMX_ErrorNone; + } + + default: + return OMX_ErrorUnsupportedIndex; + } +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::useBuffer( + OMX_BUFFERHEADERTYPE **header, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size, + OMX_U8 *ptr) { + Mutex::Autolock autoLock(mLock); + CHECK_LT(portIndex, mPorts.size()); + + *header = new OMX_BUFFERHEADERTYPE; + (*header)->nSize = sizeof(OMX_BUFFERHEADERTYPE); + (*header)->nVersion.s.nVersionMajor = 1; + (*header)->nVersion.s.nVersionMinor = 0; + (*header)->nVersion.s.nRevision = 0; + (*header)->nVersion.s.nStep = 0; + (*header)->pBuffer = ptr; + (*header)->nAllocLen = size; + (*header)->nFilledLen = 0; + (*header)->nOffset = 0; + (*header)->pAppPrivate = appPrivate; + (*header)->pPlatformPrivate = NULL; + (*header)->pInputPortPrivate = NULL; + (*header)->pOutputPortPrivate = NULL; + (*header)->hMarkTargetComponent = NULL; + (*header)->pMarkData = NULL; + (*header)->nTickCount = 0; + (*header)->nTimeStamp = 0; + (*header)->nFlags = 0; + (*header)->nOutputPortIndex = portIndex; + (*header)->nInputPortIndex = portIndex; + + PortInfo *port = &mPorts.editItemAt(portIndex); + + CHECK(mState == OMX_StateLoaded || port->mDef.bEnabled == OMX_FALSE); + + CHECK_LT(port->mBuffers.size(), port->mDef.nBufferCountActual); + + port->mBuffers.push(); + + BufferInfo *buffer = + &port->mBuffers.editItemAt(port->mBuffers.size() - 1); + + buffer->mHeader = *header; + buffer->mOwnedByUs = false; + + if (port->mBuffers.size() == port->mDef.nBufferCountActual) { + port->mDef.bPopulated = OMX_TRUE; + checkTransitions(); + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::allocateBuffer( + OMX_BUFFERHEADERTYPE **header, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size) { + OMX_U8 *ptr = new OMX_U8[size]; + + OMX_ERRORTYPE err = + useBuffer(header, portIndex, appPrivate, size, ptr); + + if (err != OMX_ErrorNone) { + delete[] ptr; + ptr = NULL; + + return err; + } + + CHECK((*header)->pPlatformPrivate == NULL); + (*header)->pPlatformPrivate = ptr; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::freeBuffer( + OMX_U32 portIndex, + OMX_BUFFERHEADERTYPE *header) { + Mutex::Autolock autoLock(mLock); + + CHECK_LT(portIndex, mPorts.size()); + + PortInfo *port = &mPorts.editItemAt(portIndex); + +#if 0 // XXX + CHECK((mState == OMX_StateIdle && mTargetState == OMX_StateLoaded) + || port->mDef.bEnabled == OMX_FALSE); +#endif + + bool found = false; + for (size_t i = 0; i < port->mBuffers.size(); ++i) { + BufferInfo *buffer = &port->mBuffers.editItemAt(i); + + if (buffer->mHeader == header) { + CHECK(!buffer->mOwnedByUs); + + if (header->pPlatformPrivate != NULL) { + // This buffer's data was allocated by us. + CHECK(header->pPlatformPrivate == header->pBuffer); + + delete[] header->pBuffer; + header->pBuffer = NULL; + } + + delete header; + header = NULL; + + port->mBuffers.removeAt(i); + port->mDef.bPopulated = OMX_FALSE; + + checkTransitions(); + + found = true; + break; + } + } + + CHECK(found); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::emptyThisBuffer( + OMX_BUFFERHEADERTYPE *buffer) { + sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler->id()); + msg->setPointer("header", buffer); + msg->post(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::fillThisBuffer( + OMX_BUFFERHEADERTYPE *buffer) { + sp<AMessage> msg = new AMessage(kWhatFillThisBuffer, mHandler->id()); + msg->setPointer("header", buffer); + msg->post(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SimpleSoftOMXComponent::getState(OMX_STATETYPE *state) { + Mutex::Autolock autoLock(mLock); + + *state = mState; + + return OMX_ErrorNone; +} + +void SimpleSoftOMXComponent::onMessageReceived(const sp<AMessage> &msg) { + Mutex::Autolock autoLock(mLock); + + switch (msg->what()) { + case kWhatSendCommand: + { + int32_t cmd, param; + CHECK(msg->findInt32("cmd", &cmd)); + CHECK(msg->findInt32("param", ¶m)); + + onSendCommand((OMX_COMMANDTYPE)cmd, (OMX_U32)param); + break; + } + + case kWhatEmptyThisBuffer: + case kWhatFillThisBuffer: + { + OMX_BUFFERHEADERTYPE *header; + CHECK(msg->findPointer("header", (void **)&header)); + + CHECK(mState == OMX_StateExecuting && mTargetState == mState); + + bool found = false; + for (size_t i = 0; i < mPorts.size(); ++i) { + PortInfo *port = &mPorts.editItemAt(i); + + for (size_t j = 0; j < port->mBuffers.size(); ++j) { + BufferInfo *buffer = &port->mBuffers.editItemAt(j); + + if (buffer->mHeader == header) { + CHECK(!buffer->mOwnedByUs); + + buffer->mOwnedByUs = true; + + CHECK((msg->what() == kWhatEmptyThisBuffer + && port->mDef.eDir == OMX_DirInput) + || (port->mDef.eDir == OMX_DirOutput)); + + port->mQueue.push_back(buffer); + onQueueFilled(i); + + found = true; + break; + } + } + } + + CHECK(found); + break; + } + + default: + TRESPASS(); + break; + } +} + +void SimpleSoftOMXComponent::onSendCommand( + OMX_COMMANDTYPE cmd, OMX_U32 param) { + switch (cmd) { + case OMX_CommandStateSet: + { + onChangeState((OMX_STATETYPE)param); + break; + } + + case OMX_CommandPortEnable: + case OMX_CommandPortDisable: + { + onPortEnable(param, cmd == OMX_CommandPortEnable); + break; + } + + case OMX_CommandFlush: + { + onPortFlush(param, true /* sendFlushComplete */); + break; + } + + default: + TRESPASS(); + break; + } +} + +void SimpleSoftOMXComponent::onChangeState(OMX_STATETYPE state) { + // We shouldn't be in a state transition already. + CHECK_EQ((int)mState, (int)mTargetState); + + switch (mState) { + case OMX_StateLoaded: + CHECK_EQ((int)state, (int)OMX_StateIdle); + break; + case OMX_StateIdle: + CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting); + break; + case OMX_StateExecuting: + { + CHECK_EQ((int)state, (int)OMX_StateIdle); + + for (size_t i = 0; i < mPorts.size(); ++i) { + onPortFlush(i, false /* sendFlushComplete */); + } + + mState = OMX_StateIdle; + notify(OMX_EventCmdComplete, OMX_CommandStateSet, state, NULL); + break; + } + + default: + TRESPASS(); + } + + mTargetState = state; + + checkTransitions(); +} + +void SimpleSoftOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) { + CHECK_LT(portIndex, mPorts.size()); + + PortInfo *port = &mPorts.editItemAt(portIndex); + CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE); + CHECK(port->mDef.bEnabled == !enable); + + if (!enable) { + port->mDef.bEnabled = OMX_FALSE; + port->mTransition = PortInfo::DISABLING; + + for (size_t i = 0; i < port->mBuffers.size(); ++i) { + BufferInfo *buffer = &port->mBuffers.editItemAt(i); + + if (buffer->mOwnedByUs) { + buffer->mOwnedByUs = false; + + if (port->mDef.eDir == OMX_DirInput) { + notifyEmptyBufferDone(buffer->mHeader); + } else { + CHECK_EQ(port->mDef.eDir, OMX_DirOutput); + notifyFillBufferDone(buffer->mHeader); + } + } + } + + port->mQueue.clear(); + } else { + port->mTransition = PortInfo::ENABLING; + } + + checkTransitions(); +} + +void SimpleSoftOMXComponent::onPortFlush( + OMX_U32 portIndex, bool sendFlushComplete) { + if (portIndex == OMX_ALL) { + for (size_t i = 0; i < mPorts.size(); ++i) { + onPortFlush(i, sendFlushComplete); + } + + if (sendFlushComplete) { + notify(OMX_EventCmdComplete, OMX_CommandFlush, OMX_ALL, NULL); + } + + return; + } + + CHECK_LT(portIndex, mPorts.size()); + + PortInfo *port = &mPorts.editItemAt(portIndex); + CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE); + + for (size_t i = 0; i < port->mBuffers.size(); ++i) { + BufferInfo *buffer = &port->mBuffers.editItemAt(i); + + if (!buffer->mOwnedByUs) { + continue; + } + + buffer->mHeader->nFilledLen = 0; + buffer->mHeader->nOffset = 0; + buffer->mHeader->nFlags = 0; + + buffer->mOwnedByUs = false; + + if (port->mDef.eDir == OMX_DirInput) { + notifyEmptyBufferDone(buffer->mHeader); + } else { + CHECK_EQ(port->mDef.eDir, OMX_DirOutput); + + notifyFillBufferDone(buffer->mHeader); + } + } + + port->mQueue.clear(); + + if (sendFlushComplete) { + notify(OMX_EventCmdComplete, OMX_CommandFlush, portIndex, NULL); + + onPortFlushCompleted(portIndex); + } +} + +void SimpleSoftOMXComponent::checkTransitions() { + if (mState != mTargetState) { + bool transitionComplete = true; + + if (mState == OMX_StateLoaded) { + CHECK_EQ((int)mTargetState, (int)OMX_StateIdle); + + for (size_t i = 0; i < mPorts.size(); ++i) { + const PortInfo &port = mPorts.itemAt(i); + if (port.mDef.bEnabled == OMX_FALSE) { + continue; + } + + if (port.mDef.bPopulated == OMX_FALSE) { + transitionComplete = false; + break; + } + } + } else if (mTargetState == OMX_StateLoaded) { + CHECK_EQ((int)mState, (int)OMX_StateIdle); + + for (size_t i = 0; i < mPorts.size(); ++i) { + const PortInfo &port = mPorts.itemAt(i); + if (port.mDef.bEnabled == OMX_FALSE) { + continue; + } + + size_t n = port.mBuffers.size(); + + if (n > 0) { + CHECK_LE(n, port.mDef.nBufferCountActual); + + if (n == port.mDef.nBufferCountActual) { + CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_TRUE); + } else { + CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_FALSE); + } + + transitionComplete = false; + break; + } + } + } + + if (transitionComplete) { + mState = mTargetState; + + notify(OMX_EventCmdComplete, OMX_CommandStateSet, mState, NULL); + } + } + + for (size_t i = 0; i < mPorts.size(); ++i) { + PortInfo *port = &mPorts.editItemAt(i); + + if (port->mTransition == PortInfo::DISABLING) { + if (port->mBuffers.empty()) { + LOGV("Port %d now disabled.", i); + + port->mTransition = PortInfo::NONE; + notify(OMX_EventCmdComplete, OMX_CommandPortDisable, i, NULL); + + onPortEnableCompleted(i, false /* enabled */); + } + } else if (port->mTransition == PortInfo::ENABLING) { + if (port->mDef.bPopulated == OMX_TRUE) { + LOGV("Port %d now enabled.", i); + + port->mTransition = PortInfo::NONE; + port->mDef.bEnabled = OMX_TRUE; + notify(OMX_EventCmdComplete, OMX_CommandPortEnable, i, NULL); + + onPortEnableCompleted(i, true /* enabled */); + } + } + } +} + +void SimpleSoftOMXComponent::addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def) { + CHECK_EQ(def.nPortIndex, mPorts.size()); + + mPorts.push(); + PortInfo *info = &mPorts.editItemAt(mPorts.size() - 1); + info->mDef = def; + info->mTransition = PortInfo::NONE; +} + +void SimpleSoftOMXComponent::onQueueFilled(OMX_U32 portIndex) { +} + +void SimpleSoftOMXComponent::onPortFlushCompleted(OMX_U32 portIndex) { +} + +void SimpleSoftOMXComponent::onPortEnableCompleted( + OMX_U32 portIndex, bool enabled) { +} + +List<SimpleSoftOMXComponent::BufferInfo *> & +SimpleSoftOMXComponent::getPortQueue(OMX_U32 portIndex) { + CHECK_LT(portIndex, mPorts.size()); + return mPorts.editItemAt(portIndex).mQueue; +} + +SimpleSoftOMXComponent::PortInfo *SimpleSoftOMXComponent::editPortInfo( + OMX_U32 portIndex) { + CHECK_LT(portIndex, mPorts.size()); + return &mPorts.editItemAt(portIndex); +} + +} // namespace android diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp new file mode 100644 index 0000000..b1c34dc --- /dev/null +++ b/media/libstagefright/omx/SoftOMXComponent.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2011 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. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SoftOMXComponent" +#include <utils/Log.h> + +#include "include/SoftOMXComponent.h" + +#include <media/stagefright/foundation/ADebug.h> + +namespace android { + +SoftOMXComponent::SoftOMXComponent( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) + : mName(name), + mCallbacks(callbacks), + mComponent(new OMX_COMPONENTTYPE), + mLibHandle(NULL) { + mComponent->nSize = sizeof(*mComponent); + mComponent->nVersion.s.nVersionMajor = 1; + mComponent->nVersion.s.nVersionMinor = 0; + mComponent->nVersion.s.nRevision = 0; + mComponent->nVersion.s.nStep = 0; + mComponent->pComponentPrivate = this; + mComponent->pApplicationPrivate = appData; + + mComponent->GetComponentVersion = NULL; + mComponent->SendCommand = SendCommandWrapper; + mComponent->GetParameter = GetParameterWrapper; + mComponent->SetParameter = SetParameterWrapper; + mComponent->GetConfig = GetConfigWrapper; + mComponent->SetConfig = SetConfigWrapper; + mComponent->GetExtensionIndex = GetExtensionIndexWrapper; + mComponent->GetState = GetStateWrapper; + mComponent->ComponentTunnelRequest = NULL; + mComponent->UseBuffer = UseBufferWrapper; + mComponent->AllocateBuffer = AllocateBufferWrapper; + mComponent->FreeBuffer = FreeBufferWrapper; + mComponent->EmptyThisBuffer = EmptyThisBufferWrapper; + mComponent->FillThisBuffer = FillThisBufferWrapper; + mComponent->SetCallbacks = NULL; + mComponent->ComponentDeInit = NULL; + mComponent->UseEGLImage = NULL; + mComponent->ComponentRoleEnum = NULL; + + *component = mComponent; +} + +SoftOMXComponent::~SoftOMXComponent() { + delete mComponent; + mComponent = NULL; +} + +void SoftOMXComponent::setLibHandle(void *libHandle) { + CHECK(libHandle != NULL); + mLibHandle = libHandle; +} + +void *SoftOMXComponent::libHandle() const { + return mLibHandle; +} + +OMX_ERRORTYPE SoftOMXComponent::initCheck() const { + return OMX_ErrorNone; +} + +const char *SoftOMXComponent::name() const { + return mName.c_str(); +} + +void SoftOMXComponent::notify( + OMX_EVENTTYPE event, + OMX_U32 data1, OMX_U32 data2, OMX_PTR data) { + (*mCallbacks->EventHandler)( + mComponent, + mComponent->pApplicationPrivate, + event, + data1, + data2, + data); +} + +void SoftOMXComponent::notifyEmptyBufferDone(OMX_BUFFERHEADERTYPE *header) { + (*mCallbacks->EmptyBufferDone)( + mComponent, mComponent->pApplicationPrivate, header); +} + +void SoftOMXComponent::notifyFillBufferDone(OMX_BUFFERHEADERTYPE *header) { + (*mCallbacks->FillBufferDone)( + mComponent, mComponent->pApplicationPrivate, header); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::SendCommandWrapper( + OMX_HANDLETYPE component, + OMX_COMMANDTYPE cmd, + OMX_U32 param, + OMX_PTR data) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->sendCommand(cmd, param, data); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::GetParameterWrapper( + OMX_HANDLETYPE component, + OMX_INDEXTYPE index, + OMX_PTR params) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->getParameter(index, params); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::SetParameterWrapper( + OMX_HANDLETYPE component, + OMX_INDEXTYPE index, + OMX_PTR params) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->setParameter(index, params); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::GetConfigWrapper( + OMX_HANDLETYPE component, + OMX_INDEXTYPE index, + OMX_PTR params) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->getConfig(index, params); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::SetConfigWrapper( + OMX_HANDLETYPE component, + OMX_INDEXTYPE index, + OMX_PTR params) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->setConfig(index, params); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::GetExtensionIndexWrapper( + OMX_HANDLETYPE component, + OMX_STRING name, + OMX_INDEXTYPE *index) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->getExtensionIndex(name, index); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::UseBufferWrapper( + OMX_HANDLETYPE component, + OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size, + OMX_U8 *ptr) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->useBuffer(buffer, portIndex, appPrivate, size, ptr); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::AllocateBufferWrapper( + OMX_HANDLETYPE component, + OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->allocateBuffer(buffer, portIndex, appPrivate, size); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::FreeBufferWrapper( + OMX_HANDLETYPE component, + OMX_U32 portIndex, + OMX_BUFFERHEADERTYPE *buffer) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->freeBuffer(portIndex, buffer); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::EmptyThisBufferWrapper( + OMX_HANDLETYPE component, + OMX_BUFFERHEADERTYPE *buffer) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->emptyThisBuffer(buffer); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::FillThisBufferWrapper( + OMX_HANDLETYPE component, + OMX_BUFFERHEADERTYPE *buffer) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->fillThisBuffer(buffer); +} + +// static +OMX_ERRORTYPE SoftOMXComponent::GetStateWrapper( + OMX_HANDLETYPE component, + OMX_STATETYPE *state) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + return me->getState(state); +} + +//////////////////////////////////////////////////////////////////////////////// + +OMX_ERRORTYPE SoftOMXComponent::sendCommand( + OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::getParameter( + OMX_INDEXTYPE index, OMX_PTR params) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::setParameter( + OMX_INDEXTYPE index, const OMX_PTR params) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::getConfig( + OMX_INDEXTYPE index, OMX_PTR params) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::setConfig( + OMX_INDEXTYPE index, const OMX_PTR params) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::getExtensionIndex( + const char *name, OMX_INDEXTYPE *index) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::useBuffer( + OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size, + OMX_U8 *ptr) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::allocateBuffer( + OMX_BUFFERHEADERTYPE **buffer, + OMX_U32 portIndex, + OMX_PTR appPrivate, + OMX_U32 size) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::freeBuffer( + OMX_U32 portIndex, + OMX_BUFFERHEADERTYPE *buffer) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::emptyThisBuffer( + OMX_BUFFERHEADERTYPE *buffer) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::fillThisBuffer( + OMX_BUFFERHEADERTYPE *buffer) { + return OMX_ErrorUndefined; +} + +OMX_ERRORTYPE SoftOMXComponent::getState(OMX_STATETYPE *state) { + return OMX_ErrorUndefined; +} + +} // namespace android diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp new file mode 100644 index 0000000..6bd6624 --- /dev/null +++ b/media/libstagefright/omx/SoftOMXPlugin.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2011 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. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SoftOMXPlugin" +#include <utils/Log.h> + +#include "SoftOMXPlugin.h" +#include "include/SoftOMXComponent.h" + +#include <media/stagefright/foundation/AString.h> + +#include <dlfcn.h> + +namespace android { + +static const struct { + const char *mName; + const char *mLibNameSuffix; + const char *mRole; + +} kComponents[] = { + { "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" }, + { "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" }, + { "OMX.google.amrwb.decoder", "amrdec", "audio_decoder.amrwb" }, + { "OMX.google.avc.decoder", "avcdec", "video_decoder.avc" }, + { "OMX.google.g711.alaw.decoder", "g711dec", "audio_decoder.g711alaw" }, + { "OMX.google.g711.mlaw.decoder", "g711dec", "audio_decoder.g711mlaw" }, + { "OMX.google.h263.decoder", "mpeg4dec", "video_decoder.h263" }, + { "OMX.google.mpeg4.decoder", "mpeg4dec", "video_decoder.mpeg4" }, + { "OMX.google.mp3.decoder", "mp3dec", "audio_decoder.mp3" }, + { "OMX.google.vorbis.decoder", "vorbisdec", "audio_decoder.vorbis" }, + { "OMX.google.vpx.decoder", "vpxdec", "video_decoder.vpx" }, +}; + +static const size_t kNumComponents = + sizeof(kComponents) / sizeof(kComponents[0]); + +SoftOMXPlugin::SoftOMXPlugin() { +} + +OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) { + LOGV("makeComponentInstance '%s'", name); + + for (size_t i = 0; i < kNumComponents; ++i) { + if (strcmp(name, kComponents[i].mName)) { + continue; + } + + AString libName = "libstagefright_soft_"; + libName.append(kComponents[i].mLibNameSuffix); + libName.append(".so"); + + void *libHandle = dlopen(libName.c_str(), RTLD_NOW); + + if (libHandle == NULL) { + LOGE("unable to dlopen %s", libName.c_str()); + + return OMX_ErrorComponentNotFound; + } + + typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)( + const char *, const OMX_CALLBACKTYPE *, + OMX_PTR, OMX_COMPONENTTYPE **); + + CreateSoftOMXComponentFunc createSoftOMXComponent = + (CreateSoftOMXComponentFunc)dlsym( + libHandle, + "_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE" + "PvPP17OMX_COMPONENTTYPE"); + + if (createSoftOMXComponent == NULL) { + dlclose(libHandle); + libHandle = NULL; + + return OMX_ErrorComponentNotFound; + } + + sp<SoftOMXComponent> codec = + (*createSoftOMXComponent)(name, callbacks, appData, component); + + if (codec == NULL) { + dlclose(libHandle); + libHandle = NULL; + + return OMX_ErrorInsufficientResources; + } + + OMX_ERRORTYPE err = codec->initCheck(); + if (err != OMX_ErrorNone) { + dlclose(libHandle); + libHandle = NULL; + + return err; + } + + codec->incStrong(this); + codec->setLibHandle(libHandle); + + return OMX_ErrorNone; + } + + return OMX_ErrorInvalidComponentName; +} + +OMX_ERRORTYPE SoftOMXPlugin::destroyComponentInstance( + OMX_COMPONENTTYPE *component) { + SoftOMXComponent *me = + (SoftOMXComponent *) + ((OMX_COMPONENTTYPE *)component)->pComponentPrivate; + + void *libHandle = me->libHandle(); + + me->decStrong(this); + me = NULL; + + dlclose(libHandle); + libHandle = NULL; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SoftOMXPlugin::enumerateComponents( + OMX_STRING name, + size_t size, + OMX_U32 index) { + if (index >= kNumComponents) { + return OMX_ErrorNoMore; + } + + strcpy(name, kComponents[index].mName); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SoftOMXPlugin::getRolesOfComponent( + const char *name, + Vector<String8> *roles) { + for (size_t i = 0; i < kNumComponents; ++i) { + if (strcmp(name, kComponents[i].mName)) { + continue; + } + + roles->clear(); + roles->push(String8(kComponents[i].mRole)); + + return OMX_ErrorNone; + } + + return OMX_ErrorInvalidComponentName; +} + +} // namespace android diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.h b/media/libstagefright/omx/SoftOMXPlugin.h index c133232..f93c323 100644 --- a/media/libstagefright/omx/OMXPVCodecsPlugin.h +++ b/media/libstagefright/omx/SoftOMXPlugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2011 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. @@ -14,17 +14,17 @@ * limitations under the License. */ -#ifndef OMX_PV_CODECS_PLUGIN_H_ +#ifndef SOFT_OMX_PLUGIN_H_ -#define OMX_PV_CODECS_PLUGIN_H_ +#define SOFT_OMX_PLUGIN_H_ +#include <media/stagefright/foundation/ABase.h> #include <media/stagefright/OMXPluginBase.h> namespace android { -struct OMXPVCodecsPlugin : public OMXPluginBase { - OMXPVCodecsPlugin(); - virtual ~OMXPVCodecsPlugin(); +struct SoftOMXPlugin : public OMXPluginBase { + SoftOMXPlugin(); virtual OMX_ERRORTYPE makeComponentInstance( const char *name, @@ -45,10 +45,9 @@ struct OMXPVCodecsPlugin : public OMXPluginBase { Vector<String8> *roles); private: - OMXPVCodecsPlugin(const OMXPVCodecsPlugin &); - OMXPVCodecsPlugin &operator=(const OMXPVCodecsPlugin &); + DISALLOW_EVIL_CONSTRUCTORS(SoftOMXPlugin); }; } // namespace android -#endif // OMX_PV_CODECS_PLUGIN_H_ +#endif // SOFT_OMX_PLUGIN_H_ diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp index 54c0d77..a404f1f 100644 --- a/media/libstagefright/omx/tests/OMXHarness.cpp +++ b/media/libstagefright/omx/tests/OMXHarness.cpp @@ -29,6 +29,7 @@ #include <media/stagefright/DataSource.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaDebug.h> +#include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MediaExtractor.h> #include <media/stagefright/MediaSource.h> @@ -454,6 +455,7 @@ static const char *GetMimeFromComponentRole(const char *componentRole) { { "video_decoder.avc", "video/avc" }, { "video_decoder.mpeg4", "video/mp4v-es" }, { "video_decoder.h263", "video/3gpp" }, + { "video_decoder.vpx", "video/x-vnd.on2.vp8" }, // we appear to use this as a synonym to amrnb. { "audio_decoder.amr", "audio/3gpp" }, @@ -461,7 +463,10 @@ static const char *GetMimeFromComponentRole(const char *componentRole) { { "audio_decoder.amrnb", "audio/3gpp" }, { "audio_decoder.amrwb", "audio/amr-wb" }, { "audio_decoder.aac", "audio/mp4a-latm" }, - { "audio_decoder.mp3", "audio/mpeg" } + { "audio_decoder.mp3", "audio/mpeg" }, + { "audio_decoder.vorbis", "audio/vorbis" }, + { "audio_decoder.g711alaw", MEDIA_MIMETYPE_AUDIO_G711_ALAW }, + { "audio_decoder.g711mlaw", MEDIA_MIMETYPE_AUDIO_G711_MLAW }, }; for (size_t i = 0; i < sizeof(kRoleToMime) / sizeof(kRoleToMime[0]); ++i) { @@ -492,7 +497,15 @@ static const char *GetURLForMime(const char *mime) { { "audio/mp4a-latm", "file:///sdcard/media_api/video/H264_AAC.3gp" }, { "audio/mpeg", - "file:///sdcard/media_api/music/MP3CBR.mp3" } + "file:///sdcard/media_api/music/MP3CBR.mp3" }, + { "audio/vorbis", + "file:///sdcard/media_api/metaDataTestMedias/OGG/" + "When You Say Nothing At All.ogg" }, + { "video/x-vnd.on2.vp8", + "file:///sdcard/media_api/webm/big-buck-bunny_trailer.webm" }, + { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "file:///sdcard/M1F1-Alaw-AFsp.wav" }, + { MEDIA_MIMETYPE_AUDIO_G711_MLAW, + "file:///sdcard/M1F1-mulaw-AFsp.wav" }, }; for (size_t i = 0; i < sizeof(kMimeToURL) / sizeof(kMimeToURL[0]); ++i) { @@ -746,6 +759,10 @@ status_t Harness::testAll() { const IOMX::ComponentInfo &info = *it; const char *componentName = info.mName.string(); + if (strncmp(componentName, "OMX.google.", 11)) { + continue; + } + for (List<String8>::const_iterator role_it = info.mRoles.begin(); role_it != info.mRoles.end(); ++role_it) { const char *componentRole = (*role_it).string(); |