diff options
Diffstat (limited to 'media/libstagefright/omx/OMXNodeInstance.cpp')
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 97 |
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) { |