Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1078)

Unified Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1560983002: Fix MP4 mid-stream resolution changes for MSE on android spitzer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase + TODO comment in ResetCodecState Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | media/filters/gpu_video_decoder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/media/android_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc
index 1ce513f86689b23ad1bd117b273ddbb4f7a7fd4a..57310cef73e71ce64172d0c6ca2fc5b9dca75f49 100644
--- a/content/common/gpu/media/android_video_decode_accelerator.cc
+++ b/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/android/build_info.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
@@ -353,15 +354,15 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
size_t offset = 0;
size_t size = 0;
- TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutputBuffer");
+ TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput");
media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
&eos, NULL);
- TRACE_EVENT_END2("media", "AVDA::DequeueOutputBuffer", "status", status,
+ TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status,
"presentation_timestamp (ms)",
presentation_timestamp.InMilliseconds());
- DVLOG(3) << "AVDA::DequeueOutputBuffer: pts:" << presentation_timestamp
+ DVLOG(3) << "AVDA::DequeueOutput: pts:" << presentation_timestamp
<< " buf_index:" << buf_index << " offset:" << offset
<< " size:" << size << " eos:" << eos;
@@ -385,8 +386,8 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
// Dynamic resolution change support is not specified by the Android
// platform at and before JB-MR1, so it's not possible to smoothly
// continue playback at this point. Instead, error out immediately,
- // expecting clients to Reset() as appropriate to avoid this.
- // b/7093648
+ // expecting clients to Flush() or Reset() as appropriate to avoid
+ // this. b/7093648
RETURN_ON_FAILURE(this, size_ == gfx::Size(width, height),
"Dynamic resolution change is not supported.",
PLATFORM_FAILURE, false);
@@ -420,13 +421,15 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
auto it = eos ? bitstream_buffers_in_decoder_.end()
: bitstream_buffers_in_decoder_.find(presentation_timestamp);
- if (it == bitstream_buffers_in_decoder_.end()) {
- media_codec_->ReleaseOutputBuffer(buf_index, false);
+ if (eos) {
+ DVLOG(3) << "AVDA::DequeueOutput: Resetting output state after EOS";
+ ResetCodecState();
+
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
weak_this_factory_.GetWeakPtr()));
- } else {
+ } else if (it != bitstream_buffers_in_decoder_.end()) {
const int32_t bitstream_buffer_id = it->second;
bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(),
++it);
@@ -448,6 +451,11 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() {
break;
}
}
+ } else {
+ DVLOG(3) << "AVDA::DequeueOutput: Releasing buffer with unexpected PTS: "
+ << presentation_timestamp;
+ media_codec_->ReleaseOutputBuffer(buf_index, false);
+ should_try_again = true;
}
return should_try_again;
@@ -590,6 +598,42 @@ bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
return true;
}
+void AndroidVideoDecodeAccelerator::ResetCodecState() {
+ // TODO(chcunningham): This will likely dismiss a handful of decoded frames
+ // that have not yet been drawn and returned to us for re-use. Consider
+ // a more complicated design that would wait for these to be drawn before
+ // dismissing.
+ for (const auto& it : output_picture_buffers_) {
+ strategy_->DismissOnePictureBuffer(it.second);
+ client_->DismissPictureBuffer(it.first);
+ dismissed_picture_ids_.insert(it.first);
+ }
+ output_picture_buffers_.clear();
+ std::queue<int32_t> empty;
+ std::swap(free_picture_ids_, empty);
+ CHECK(free_picture_ids_.empty());
+ picturebuffers_requested_ = false;
+ bitstream_buffers_in_decoder_.clear();
+
+ // When codec is not in error state we can quickly reset (internally calls
+ // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
+ // (b/8125974, b/8347958) so we must stop() and reconfigure MediaCodec. The
+ // full reconfigure is much slower and may cause visible freezing if done
+ // mid-stream.
+ if (state_ == NO_ERROR &&
+ base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
+ DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
+ media_codec_->Reset();
+ } else {
+ DVLOG(3) << __FUNCTION__
+ << " Doing slow MediaCodec reset (stop/re-configure).";
+ io_timer_.Stop();
+ media_codec_->Stop();
+ ConfigureMediaCodec();
+ state_ = NO_ERROR;
+ }
+}
+
void AndroidVideoDecodeAccelerator::Reset() {
DCHECK(thread_checker_.CalledOnValidThread());
TRACE_EVENT0("media", "AVDA::Reset");
@@ -608,28 +652,7 @@ void AndroidVideoDecodeAccelerator::Reset() {
TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
bitstreams_notified_in_advance_.clear();
- for (OutputBufferMap::iterator it = output_picture_buffers_.begin();
- it != output_picture_buffers_.end();
- ++it) {
- strategy_->DismissOnePictureBuffer(it->second);
- client_->DismissPictureBuffer(it->first);
- dismissed_picture_ids_.insert(it->first);
- }
- output_picture_buffers_.clear();
- std::queue<int32_t> empty;
- std::swap(free_picture_ids_, empty);
- CHECK(free_picture_ids_.empty());
- picturebuffers_requested_ = false;
- bitstream_buffers_in_decoder_.clear();
-
- // On some devices, and up to at least JB-MR1,
- // - flush() can fail after EOS (b/8125974); and
- // - mid-stream resolution change is unsupported (b/7093648).
- // To cope with these facts, we always stop & restart the codec on Reset().
- io_timer_.Stop();
- media_codec_->Stop();
- ConfigureMediaCodec();
- state_ = NO_ERROR;
+ ResetCodecState();
base::MessageLoop::current()->PostTask(
FROM_HERE,
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | media/filters/gpu_video_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698