summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/omx/OMXNodeInstance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/omx/OMXNodeInstance.cpp')
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp97
1 files changed, 70 insertions, 27 deletions
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) {