summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/ACodec.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2013-04-19 11:55:18 -0700
committerAndreas Huber <andih@google.com>2013-04-19 11:55:18 -0700
commit0ae2001f40587556e2f5ed56f791292fb5e9a329 (patch)
tree8b4980c76a87eb6826399dc11d8d771ee9628fcb /media/libstagefright/ACodec.cpp
parent005bb86bd99077283df1968958d5c514a3bfa16a (diff)
downloadframeworks_av-0ae2001f40587556e2f5ed56f791292fb5e9a329.zip
frameworks_av-0ae2001f40587556e2f5ed56f791292fb5e9a329.tar.gz
frameworks_av-0ae2001f40587556e2f5ed56f791292fb5e9a329.tar.bz2
A flush of a video decoder connected to a native window must reclaim
output buffers already queued for rendering before considering a flush completed. Otherwise the decoder may not have enough output buffers to continue decoding after the discontinuity and we'll never dequeue more from the native window. Change-Id: I42e275dc336568e180081c6d7c0dc05fc9637c79 related-to-bug: 8578467
Diffstat (limited to 'media/libstagefright/ACodec.cpp')
-rw-r--r--media/libstagefright/ACodec.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index b3bc6d8..6d952c3 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -2135,6 +2135,42 @@ size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
return n;
}
+size_t ACodec::countBuffersOwnedByNativeWindow() const {
+ size_t n = 0;
+
+ for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
+ const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
+
+ if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
+ ++n;
+ }
+ }
+
+ return n;
+}
+
+void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
+ if (mNativeWindow == NULL) {
+ return;
+ }
+
+ int minUndequeuedBufs = 0;
+ status_t err = mNativeWindow->query(
+ mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+ &minUndequeuedBufs);
+
+ if (err != OK) {
+ ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
+ mComponentName.c_str(), strerror(-err), -err);
+
+ minUndequeuedBufs = 0;
+ }
+
+ while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
+ && dequeueBufferFromNativeWindow() != NULL) {
+ }
+}
+
bool ACodec::allYourBuffersAreBelongToUs(
OMX_U32 portIndex) {
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
@@ -4177,6 +4213,10 @@ void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
if (mFlushComplete[kPortIndexInput]
&& mFlushComplete[kPortIndexOutput]
&& mCodec->allYourBuffersAreBelongToUs()) {
+ // We now own all buffers except possibly those still queued with
+ // the native window for rendering. Let's get those back as well.
+ mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
+
sp<AMessage> notify = mCodec->mNotify->dup();
notify->setInt32("what", ACodec::kWhatFlushCompleted);
notify->post();