Chromium Code Reviews| 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 2cc7c32c14d5d21f49b46ab24e38942bb15db94a..b67410a2c69836eb40e8498a702f43e570b268a6 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" |
| @@ -332,8 +333,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); |
| @@ -368,7 +369,9 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() { |
| : bitstream_buffers_in_decoder_.find(presentation_timestamp); |
| if (it == bitstream_buffers_in_decoder_.end()) { |
| - media_codec_->ReleaseOutputBuffer(buf_index, false); |
| + DVLOG(3) << "AVDA::DequeueOutputBuffer: Resetting output state after EOS"; |
| + ResetOutputState(); |
|
liberato (no reviews please)
2016/01/06 18:06:32
we don't know that this is eos. we might not have
chcunningham
2016/01/07 02:14:48
Done. Added a log and made sure to ReleaseOutputBu
|
| + |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |
| base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, |
| @@ -537,6 +540,39 @@ bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { |
| return true; |
| } |
| +void AndroidVideoDecodeAccelerator::ResetOutputState() { |
|
liberato (no reviews please)
2016/01/06 18:06:32
maybe ResetCodecState, or maybe ResetOrReplaceCode
chcunningham
2016/01/07 02:14:48
Made this ResetCodecState
|
| + for (OutputBufferMap::iterator it = output_picture_buffers_.begin(); |
|
watk
2016/01/06 20:05:51
Range based for-loop opportunity!
chcunningham
2016/01/07 02:14:48
Done.
|
| + it != output_picture_buffers_.end(); ++it) { |
| + strategy_->DismissOnePictureBuffer(it->second); |
|
liberato (no reviews please)
2016/01/06 18:06:32
this will immediately make the images undrawable,
chcunningham
2016/01/07 02:14:48
SetImageForPicture appears to be a no-op whenever
liberato (no reviews please)
2016/01/07 14:48:55
doesn't do anything for null: wow! well then, i'd
chcunningham
2016/01/08 22:49:36
SGTM. I added a temporary count of dismissed-frame
|
| + 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()); |
|
watk
2016/01/06 20:05:51
Heh, this is a paranoid check.
chcunningham
2016/01/07 02:14:48
Are you suggesting a downgrade to DCHECK?
|
| + 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 && |
|
liberato (no reviews please)
2016/01/06 18:06:32
not sure that it matters if |state_| is NO_ERROR o
chcunningham
2016/01/07 02:14:48
My thinking here comes from the state diagram in t
|
| + 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(); |
|
liberato (no reviews please)
2016/01/06 18:06:32
is this going to be deferred as part of sandersd@
chcunningham
2016/01/07 02:14:48
sanders@, comment on your plans?
Agree, lazy woul
|
| + state_ = NO_ERROR; |
| + } |
| +} |
| + |
| void AndroidVideoDecodeAccelerator::Reset() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| TRACE_EVENT0("media", "AVDA::Reset"); |
| @@ -555,28 +591,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; |
| + ResetOutputState(); |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |