summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/omx
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r--media/libstagefright/omx/Android.mk6
-rw-r--r--media/libstagefright/omx/OMX.cpp18
-rw-r--r--media/libstagefright/omx/OMXMaster.cpp67
-rw-r--r--media/libstagefright/omx/OMXMaster.h7
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp97
-rw-r--r--media/libstagefright/omx/SimpleSoftOMXComponent.cpp44
-rwxr-xr-xmedia/libstagefright/omx/SoftOMXPlugin.cpp9
-rw-r--r--media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp3
8 files changed, 188 insertions, 63 deletions
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 5f0f567..d16d5df 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -30,6 +30,12 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright_foundation \
libdl
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
+ LOCAL_CFLAGS += -DQTI_FLAC_DECODER
+endif
+endif
+
LOCAL_MODULE:= libstagefright_omx
LOCAL_CFLAGS += -Werror -Wall
LOCAL_CLANG := true
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 56b6055..68ff9b0 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -473,6 +473,10 @@ OMX_ERRORTYPE OMX::OnEvent(
findInstance(node)->onEvent(eEvent, nData1, nData2);
sp<OMX::CallbackDispatcher> dispatcher = findDispatcher(node);
+ if (dispatcher == NULL) {
+ ALOGW("OnEvent Callback dispatcher NULL, skip post");
+ return OMX_ErrorNone;
+ }
// output rendered events are not processed as regular events until they hit the observer
if (eEvent == OMX_EventOutputRendered) {
@@ -518,7 +522,12 @@ OMX_ERRORTYPE OMX::OnEmptyBufferDone(
msg.fenceFd = fenceFd;
msg.u.buffer_data.buffer = buffer;
- findDispatcher(node)->post(msg);
+ sp<OMX::CallbackDispatcher> callbackDispatcher = findDispatcher(node);
+ if (callbackDispatcher != NULL) {
+ callbackDispatcher->post(msg);
+ } else {
+ ALOGW("OnEmptyBufferDone Callback dispatcher NULL, skip post");
+ }
return OMX_ErrorNone;
}
@@ -537,7 +546,12 @@ OMX_ERRORTYPE OMX::OnFillBufferDone(
msg.u.extended_buffer_data.flags = pBuffer->nFlags;
msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
- findDispatcher(node)->post(msg);
+ sp<OMX::CallbackDispatcher> callbackDispatcher = findDispatcher(node);
+ if (callbackDispatcher != NULL) {
+ callbackDispatcher->post(msg);
+ } else {
+ ALOGW("OnFillBufferDone Callback dispatcher NULL, skip post");
+ }
return OMX_ErrorNone;
}
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index ae3cb33..f7bb733 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -25,52 +25,58 @@
#include <dlfcn.h>
#include <media/stagefright/foundation/ADebug.h>
+#include <cutils/properties.h>
namespace android {
-OMXMaster::OMXMaster()
- : mVendorLibHandle(NULL) {
+OMXMaster::OMXMaster() {
addVendorPlugin();
addPlugin(new SoftOMXPlugin);
+ addUserPlugin();
}
OMXMaster::~OMXMaster() {
clearPlugins();
-
- if (mVendorLibHandle != NULL) {
- dlclose(mVendorLibHandle);
- mVendorLibHandle = NULL;
- }
}
void OMXMaster::addVendorPlugin() {
addPlugin("libstagefrighthw.so");
}
+void OMXMaster::addUserPlugin() {
+ char plugin[PROPERTY_VALUE_MAX];
+ if (property_get("media.sf.omx-plugin", plugin, NULL)) {
+ addPlugin(plugin);
+ }
+}
+
void OMXMaster::addPlugin(const char *libname) {
- mVendorLibHandle = dlopen(libname, RTLD_NOW);
+ void* handle = dlopen(libname, RTLD_NOW);
- if (mVendorLibHandle == NULL) {
+ if (handle == NULL) {
return;
}
typedef OMXPluginBase *(*CreateOMXPluginFunc)();
CreateOMXPluginFunc createOMXPlugin =
(CreateOMXPluginFunc)dlsym(
- mVendorLibHandle, "createOMXPlugin");
+ handle, "createOMXPlugin");
if (!createOMXPlugin)
createOMXPlugin = (CreateOMXPluginFunc)dlsym(
- mVendorLibHandle, "_ZN7android15createOMXPluginEv");
+ handle, "_ZN7android15createOMXPluginEv");
if (createOMXPlugin) {
- addPlugin((*createOMXPlugin)());
+ addPlugin((*createOMXPlugin)(), handle);
}
}
-void OMXMaster::addPlugin(OMXPluginBase *plugin) {
+void OMXMaster::addPlugin(OMXPluginBase *plugin, void *handle) {
+ if (plugin == 0) {
+ return;
+ }
Mutex::Autolock autoLock(mLock);
- mPlugins.push_back(plugin);
+ mPlugins.add(plugin, handle);
OMX_U32 index = 0;
@@ -100,21 +106,32 @@ void OMXMaster::clearPlugins() {
Mutex::Autolock autoLock(mLock);
typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
- DestroyOMXPluginFunc destroyOMXPlugin =
- (DestroyOMXPluginFunc)dlsym(
- mVendorLibHandle, "destroyOMXPlugin");
- mPluginByComponentName.clear();
+ for (unsigned int i = 0; i < mPlugins.size(); i++) {
+ OMXPluginBase *plugin = mPlugins.keyAt(i);
+ if (plugin != NULL) {
+ void *handle = mPlugins.valueAt(i);
+
+ if (handle != NULL) {
+ DestroyOMXPluginFunc destroyOMXPlugin =
+ (DestroyOMXPluginFunc)dlsym(
+ handle, "destroyOMXPlugin");
+
+ if (destroyOMXPlugin)
+ destroyOMXPlugin(plugin);
+ else
+ delete plugin;
- for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
- it != mPlugins.end(); ++it) {
- if (destroyOMXPlugin)
- destroyOMXPlugin(*it);
- else
- delete *it;
- *it = NULL;
+ dlclose(handle);
+ } else {
+ delete plugin;
+ }
+
+ plugin = NULL;
+ }
}
+ mPluginByComponentName.clear();
mPlugins.clear();
}
diff --git a/media/libstagefright/omx/OMXMaster.h b/media/libstagefright/omx/OMXMaster.h
index 6069741..c07fed3 100644
--- a/media/libstagefright/omx/OMXMaster.h
+++ b/media/libstagefright/omx/OMXMaster.h
@@ -51,15 +51,14 @@ struct OMXMaster : public OMXPluginBase {
private:
Mutex mLock;
- List<OMXPluginBase *> mPlugins;
+ KeyedVector<OMXPluginBase *, void *> mPlugins;
KeyedVector<String8, OMXPluginBase *> mPluginByComponentName;
KeyedVector<OMX_COMPONENTTYPE *, OMXPluginBase *> mPluginByInstance;
- void *mVendorLibHandle;
-
void addVendorPlugin();
+ void addUserPlugin();
void addPlugin(const char *libname);
- void addPlugin(OMXPluginBase *plugin);
+ void addPlugin(OMXPluginBase *plugin, void *handle = NULL);
void clearPlugins();
OMXMaster(const OMXMaster &);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 8735eff..f9c3cfb 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -101,19 +101,22 @@ static void InitOMXParams(T *params) {
namespace android {
struct BufferMeta {
- BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
+ BufferMeta(const sp<IMemory> &mem, OMX_U32 portIndex, bool is_backup = false)
: mMem(mem),
- mIsBackup(is_backup) {
+ mIsBackup(is_backup),
+ mPortIndex(portIndex) {
}
- BufferMeta(size_t size)
+ BufferMeta(size_t size, OMX_U32 portIndex)
: mSize(size),
- mIsBackup(false) {
+ mIsBackup(false),
+ mPortIndex(portIndex) {
}
- BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
+ BufferMeta(const sp<GraphicBuffer> &graphicBuffer, OMX_U32 portIndex)
: mGraphicBuffer(graphicBuffer),
- mIsBackup(false) {
+ mIsBackup(false),
+ mPortIndex(portIndex) {
}
void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
@@ -122,7 +125,8 @@ struct BufferMeta {
}
// check component returns proper range
- sp<ABuffer> codec = getBuffer(header, false /* backup */, true /* limit */);
+ sp<ABuffer> codec = getBuffer(header, false /* backup */,
+ !(header->nFlags & OMX_BUFFERFLAG_EXTRADATA));
memcpy((OMX_U8 *)mMem->pointer() + header->nOffset, codec->data(), codec->size());
}
@@ -132,9 +136,11 @@ struct BufferMeta {
return;
}
+ size_t bytesToCopy = header->nFlags & OMX_BUFFERFLAG_EXTRADATA ?
+ header->nAllocLen - header->nOffset : header->nFilledLen;
memcpy(header->pBuffer + header->nOffset,
(const OMX_U8 *)mMem->pointer() + header->nOffset,
- header->nFilledLen);
+ bytesToCopy);
}
// return either the codec or the backup buffer
@@ -160,11 +166,16 @@ struct BufferMeta {
mGraphicBuffer = graphicBuffer;
}
+ OMX_U32 getPortIndex() {
+ return mPortIndex;
+ }
+
private:
sp<GraphicBuffer> mGraphicBuffer;
sp<IMemory> mMem;
size_t mSize;
bool mIsBackup;
+ OMX_U32 mPortIndex;
BufferMeta(const BufferMeta &);
BufferMeta &operator=(const BufferMeta &);
@@ -190,7 +201,6 @@ OMXNodeInstance::OMXNodeInstance(
mNodeID(0),
mHandle(NULL),
mObserver(observer),
- mDying(false),
mBufferIDCount(0)
{
mName = ADebug::GetDebugName(name);
@@ -204,6 +214,7 @@ OMXNodeInstance::OMXNodeInstance(
mMetadataType[0] = kMetadataBufferTypeInvalid;
mMetadataType[1] = kMetadataBufferTypeInvalid;
mIsSecure = AString(name).endsWith(".secure");
+ atomic_store(&mDying, false);
}
OMXNodeInstance::~OMXNodeInstance() {
@@ -274,11 +285,12 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {
// The code below may trigger some more events to be dispatched
// by the OMX component - we want to ignore them as our client
// does not expect them.
- mDying = true;
+ atomic_store(&mDying, true);
OMX_STATETYPE state;
CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
switch (state) {
+ case OMX_StatePause:
case OMX_StateExecuting:
{
ALOGV("forcing Executing->Idle");
@@ -661,7 +673,7 @@ status_t OMXNodeInstance::useBuffer(
return BAD_VALUE;
}
- BufferMeta *buffer_meta = new BufferMeta(params);
+ BufferMeta *buffer_meta = new BufferMeta(params, portIndex);
OMX_BUFFERHEADERTYPE *header;
@@ -713,7 +725,7 @@ status_t OMXNodeInstance::useGraphicBuffer2_l(
return UNKNOWN_ERROR;
}
- BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
+ BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex);
OMX_BUFFERHEADERTYPE *header = NULL;
OMX_U8* bufferHandle = const_cast<OMX_U8*>(
@@ -771,7 +783,7 @@ status_t OMXNodeInstance::useGraphicBuffer(
return StatusFromOMXError(err);
}
- BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
+ BufferMeta *bufferMeta = new BufferMeta(graphicBuffer, portIndex);
OMX_BUFFERHEADERTYPE *header;
@@ -812,6 +824,9 @@ status_t OMXNodeInstance::useGraphicBuffer(
status_t OMXNodeInstance::updateGraphicBufferInMeta_l(
OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) {
+ if (header == NULL) {
+ return BAD_VALUE;
+ }
if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
return BAD_VALUE;
}
@@ -845,7 +860,7 @@ status_t OMXNodeInstance::updateGraphicBufferInMeta(
OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id buffer) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex);
return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, buffer, header);
}
@@ -974,7 +989,7 @@ status_t OMXNodeInstance::allocateBuffer(
void **buffer_data) {
Mutex::Autolock autoLock(mLock);
- BufferMeta *buffer_meta = new BufferMeta(size);
+ BufferMeta *buffer_meta = new BufferMeta(size, portIndex);
OMX_BUFFERHEADERTYPE *header;
@@ -1015,7 +1030,7 @@ status_t OMXNodeInstance::allocateBufferWithBackup(
return BAD_VALUE;
}
- BufferMeta *buffer_meta = new BufferMeta(params, true);
+ BufferMeta *buffer_meta = new BufferMeta(params, portIndex, true);
OMX_BUFFERHEADERTYPE *header;
@@ -1056,7 +1071,10 @@ status_t OMXNodeInstance::freeBuffer(
removeActiveBuffer(portIndex, buffer);
- OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex);
+ if (header == NULL) {
+ return BAD_VALUE;
+ }
BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
@@ -1072,7 +1090,10 @@ status_t OMXNodeInstance::freeBuffer(
status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer, int fenceFd) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput);
+ if (header == NULL) {
+ return BAD_VALUE;
+ }
header->nFilledLen = 0;
header->nOffset = 0;
header->nFlags = 0;
@@ -1105,7 +1126,10 @@ status_t OMXNodeInstance::emptyBuffer(
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
+ if (header == NULL) {
+ return BAD_VALUE;
+ }
BufferMeta *buffer_meta =
static_cast<BufferMeta *>(header->pAppPrivate);
sp<ABuffer> backup = buffer_meta->getBuffer(header, true /* backup */, false /* limit */);
@@ -1385,7 +1409,10 @@ bool OMXNodeInstance::handleMessage(omx_message &msg) {
if (msg.type == omx_message::FILL_BUFFER_DONE) {
OMX_BUFFERHEADERTYPE *buffer =
- findBufferHeader(msg.u.extended_buffer_data.buffer);
+ findBufferHeader(msg.u.extended_buffer_data.buffer, kPortIndexOutput);
+ if (buffer == NULL) {
+ return false;
+ }
{
Mutex::Autolock _l(mDebugLock);
@@ -1416,7 +1443,10 @@ bool OMXNodeInstance::handleMessage(omx_message &msg) {
}
} else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
OMX_BUFFERHEADERTYPE *buffer =
- findBufferHeader(msg.u.buffer_data.buffer);
+ findBufferHeader(msg.u.buffer_data.buffer, kPortIndexInput);
+ if (buffer == NULL) {
+ return false;
+ }
{
Mutex::Autolock _l(mDebugLock);
@@ -1458,6 +1488,9 @@ void OMXNodeInstance::onObserverDied(OMXMaster *master) {
ALOGE("!!! Observer died. Quickly, do something, ... anything...");
// Try to force shutdown of the node and hope for the best.
+ // But allow the component to observe mDying = true first
+ atomic_store(&mDying, true);
+ sleep(2);
freeNode(master);
}
@@ -1525,7 +1558,7 @@ OMX_ERRORTYPE OMXNodeInstance::OnEvent(
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
- if (instance->mDying) {
+ if (atomic_load(&instance->mDying)) {
return OMX_ErrorNone;
}
return instance->owner()->OnEvent(
@@ -1538,7 +1571,7 @@ OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
- if (instance->mDying) {
+ if (atomic_load(&instance->mDying)) {
return OMX_ErrorNone;
}
int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
@@ -1552,7 +1585,7 @@ OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
- if (instance->mDying) {
+ if (atomic_load(&instance->mDying)) {
return OMX_ErrorNone;
}
int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
@@ -1591,7 +1624,8 @@ void OMXNodeInstance::removeActiveBuffer(
void OMXNodeInstance::freeActiveBuffers() {
// Make sure to count down here, as freeBuffer will in turn remove
// the active buffer from the vector...
- for (size_t i = mActiveBuffers.size(); i--;) {
+ for (size_t i = mActiveBuffers.size(); i;) {
+ i--;
freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
}
}
@@ -1613,7 +1647,8 @@ OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader)
return buffer;
}
-OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
+OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(
+ OMX::buffer_id buffer, OMX_U32 portIndex) {
if (buffer == 0) {
return NULL;
}
@@ -1623,7 +1658,15 @@ OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
CLOGW("findBufferHeader: buffer %u not found", buffer);
return NULL;
}
- return mBufferIDToBufferHeader.valueAt(index);
+ OMX_BUFFERHEADERTYPE *header = mBufferIDToBufferHeader.valueAt(index);
+ BufferMeta *buffer_meta =
+ static_cast<BufferMeta *>(header->pAppPrivate);
+ if (buffer_meta->getPortIndex() != portIndex) {
+ CLOGW("findBufferHeader: buffer %u found but with incorrect port index.", buffer);
+ android_errorWriteLog(0x534e4554, "28816827");
+ return NULL;
+ }
+ return header;
}
OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index 13afd45..2ae807e 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -425,16 +425,43 @@ void SimpleSoftOMXComponent::onSendCommand(
}
}
+void SimpleSoftOMXComponent::onTransitionError() {
+ mState = OMX_StateInvalid;
+ mTargetState = OMX_StateInvalid;
+ notify(OMX_EventError, OMX_CommandStateSet, OMX_StateInvalid, 0);
+}
+
void SimpleSoftOMXComponent::onChangeState(OMX_STATETYPE state) {
+ bool skipTransitions = false;
+
// We shouldn't be in a state transition already.
- CHECK_EQ((int)mState, (int)mTargetState);
+ if (mState != mTargetState) {
+ // Workaround to prevent assertion
+ // XXX CHECK_EQ((int)mState, (int)mTargetState);
+ ALOGW("mState %d != mTargetState %d", mState, mTargetState);
+ skipTransitions = true;
+ onTransitionError();
+ }
switch (mState) {
case OMX_StateLoaded:
- CHECK_EQ((int)state, (int)OMX_StateIdle);
+ if (state != OMX_StateIdle) {
+ // Workaround to prevent assertion
+ // XXX CHECK_EQ((int)state, (int)OMX_StateIdle);
+ ALOGW("In OMX_StateLoaded, state %d != OMX_StateIdle", state);
+ skipTransitions = true;
+ onTransitionError();
+ }
break;
case OMX_StateIdle:
- CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
+ if (!(state == OMX_StateLoaded || state == OMX_StateExecuting)) {
+ // Workaround to prevent assertion
+ // XXX CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
+ ALOGW("In OMX_StateIdle, state %d != OMX_StateLoaded||OMX_StateExecuting",
+ state);
+ skipTransitions = true;
+ onTransitionError();
+ }
break;
case OMX_StateExecuting:
{
@@ -448,11 +475,20 @@ void SimpleSoftOMXComponent::onChangeState(OMX_STATETYPE state) {
notify(OMX_EventCmdComplete, OMX_CommandStateSet, state, NULL);
break;
}
-
+ case OMX_StateInvalid: {
+ ALOGW("In OMX_StateInvalid, ignore state transition to %d", state);
+ skipTransitions = true;
+ onTransitionError();
+ break;
+ }
default:
TRESPASS();
}
+ if (skipTransitions) {
+ return;
+ }
+
mTargetState = state;
checkTransitions();
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index 0f9c00c..4afd5d5 100755
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -59,6 +59,9 @@ static const struct {
{ "OMX.google.raw.decoder", "rawdec", "audio_decoder.raw" },
{ "OMX.google.flac.encoder", "flacenc", "audio_encoder.flac" },
{ "OMX.google.gsm.decoder", "gsmdec", "audio_decoder.gsm" },
+#ifdef QTI_FLAC_DECODER
+ { "OMX.qti.audio.decoder.flac", "flacdec", "audio_decoder.flac" },
+#endif
};
static const size_t kNumComponents =
@@ -74,6 +77,7 @@ OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
OMX_COMPONENTTYPE **component) {
ALOGV("makeComponentInstance '%s'", name);
+ dlerror(); // clear any existing error
for (size_t i = 0; i < kNumComponents; ++i) {
if (strcmp(name, kComponents[i].mName)) {
continue;
@@ -91,6 +95,8 @@ OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
return OMX_ErrorComponentNotFound;
}
+ ALOGV("load component %s for %s", libName.c_str(), name);
+
typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)(
const char *, const OMX_CALLBACKTYPE *,
OMX_PTR, OMX_COMPONENTTYPE **);
@@ -101,7 +107,8 @@ OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
"_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"
"PvPP17OMX_COMPONENTTYPE");
- if (createSoftOMXComponent == NULL) {
+ if (const char *error = dlerror()) {
+ ALOGE("unable to dlsym %s: %s", libName.c_str(), error);
dlclose(libHandle);
libHandle = NULL;
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 8ea7a6e..dc3ed39 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -606,6 +606,9 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer(
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+#ifdef MTK_HARDWARE
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+#endif
ConvertRGB32ToPlanar(
dst, dstStride, dstVStride,
(const uint8_t *)bits, width, height, srcStride,