diff options
author | Wei Jia <wjia@google.com> | 2015-04-28 18:22:36 -0700 |
---|---|---|
committer | Wei Jia <wjia@google.com> | 2015-04-30 09:53:14 -0700 |
commit | bac588208fadec78e3fa205c238089df277d3817 (patch) | |
tree | 3feebbd56bf126f282d96583f2a60f17fdfabdfe | |
parent | c0239eca6d022b498d21cc467f83f715f7e7ed89 (diff) | |
download | frameworks_av-bac588208fadec78e3fa205c238089df277d3817.zip frameworks_av-bac588208fadec78e3fa205c238089df277d3817.tar.gz frameworks_av-bac588208fadec78e3fa205c238089df277d3817.tar.bz2 |
MediaSync: map returned output buffers to previously received input buffers.
Bug: 19666434
Change-Id: I81e9cb8e73d950b3be5d29cf010c6793894ad802
-rw-r--r-- | include/media/stagefright/MediaSync.h | 8 | ||||
-rw-r--r-- | media/libstagefright/MediaSync.cpp | 23 |
2 files changed, 29 insertions, 2 deletions
diff --git a/include/media/stagefright/MediaSync.h b/include/media/stagefright/MediaSync.h index 8ad74a4..e071b65 100644 --- a/include/media/stagefright/MediaSync.h +++ b/include/media/stagefright/MediaSync.h @@ -23,6 +23,7 @@ #include <media/stagefright/foundation/AHandler.h> #include <utils/Condition.h> +#include <utils/KeyedVector.h> #include <utils/Mutex.h> namespace android { @@ -190,6 +191,13 @@ private: int64_t mNextBufferItemMediaUs; List<BufferItem> mBufferItems; + + // Keep track of buffers received from |mInput|. This is needed because + // it's possible the consumer of |mOutput| could return a different + // GraphicBuffer::handle (e.g., due to passing buffers through IPC), + // and that could cause problem if the producer of |mInput| only + // supports pre-registered buffers. + KeyedVector<uint64_t, sp<GraphicBuffer> > mBuffersFromInput; sp<ALooper> mLooper; float mPlaybackRate; diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp index 8030a36..4350b59 100644 --- a/media/libstagefright/MediaSync.cpp +++ b/media/libstagefright/MediaSync.cpp @@ -430,7 +430,16 @@ void MediaSync::onFrameAvailableFromInput() { return; } + if (mBuffersFromInput.indexOfKey(bufferItem.mGraphicBuffer->getId()) >= 0) { + // Something is wrong since this buffer should be at our hands, bail. + mInput->consumerDisconnect(); + onAbandoned_l(true /* isInput */); + return; + } + mBuffersFromInput.add(bufferItem.mGraphicBuffer->getId(), bufferItem.mGraphicBuffer); + mBufferItems.push_back(bufferItem); + if (mBufferItems.size() == 1) { onDrainVideo_l(); } @@ -497,9 +506,19 @@ void MediaSync::onBufferReleasedByOutput() { void MediaSync::returnBufferToInput_l( const sp<GraphicBuffer> &buffer, const sp<Fence> &fence) { + ssize_t ix = mBuffersFromInput.indexOfKey(buffer->getId()); + if (ix < 0) { + // The buffer is unknown, something is wrong, bail. + mOutput->disconnect(NATIVE_WINDOW_API_MEDIA); + onAbandoned_l(false /* isInput */); + return; + } + sp<GraphicBuffer> oldBuffer = mBuffersFromInput.valueAt(ix); + mBuffersFromInput.removeItemsAt(ix); + // Attach and release the buffer back to the input. int consumerSlot; - status_t status = mInput->attachBuffer(&consumerSlot, buffer); + status_t status = mInput->attachBuffer(&consumerSlot, oldBuffer); ALOGE_IF(status != NO_ERROR, "attaching buffer to input failed (%d)", status); if (status == NO_ERROR) { status = mInput->releaseBuffer(consumerSlot, 0 /* frameNumber */, @@ -512,7 +531,7 @@ void MediaSync::returnBufferToInput_l( return; } - ALOGV("released buffer %#llx to input", (long long)buffer->getId()); + ALOGV("released buffer %#llx to input", (long long)oldBuffer->getId()); // Notify any waiting onFrameAvailable calls. --mNumOutstandingBuffers; |