| 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 1606e28b10538a9e28032e4806d289f6dc448b42..355059f1cc14ba89edfd27f82108a8aeaeae7cbd 100644
|
| --- a/content/common/gpu/media/android_video_decode_accelerator.cc
|
| +++ b/content/common/gpu/media/android_video_decode_accelerator.cc
|
| @@ -409,9 +409,9 @@ void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) {
|
| void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| TRACE_EVENT0("media", "AVDA::DoIOTask");
|
| - if (state_ == ERROR) {
|
| +
|
| + if (state_ == ERROR || state_ == PENDING_CODEC_REINITIALIZATION)
|
| return;
|
| - }
|
|
|
| bool did_work = QueueInput();
|
| while (DequeueOutput())
|
| @@ -782,6 +782,15 @@ void AndroidVideoDecodeAccelerator::DecodeBuffer(
|
| TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
|
| pending_bitstream_buffers_.size());
|
|
|
| + if (state_ == PENDING_CODEC_REINITIALIZATION) {
|
| + base::AutoReset<bool> auto_reset(&defer_errors_, true);
|
| + if (!ConfigureMediaCodec()) {
|
| + POST_ERROR(PLATFORM_FAILURE, "Failed to configure MediaCodec.");
|
| + return;
|
| + }
|
| + state_ = NO_ERROR;
|
| + }
|
| +
|
| DoIOTask(true);
|
| }
|
|
|
| @@ -890,14 +899,11 @@ bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
|
|
|
| void AndroidVideoDecodeAccelerator::ResetCodecState() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (state_ == PENDING_CODEC_REINITIALIZATION)
|
| + return
|
| +
|
| bitstream_buffers_in_decoder_.clear();
|
| -
|
| - // We don't dismiss picture buffers here since we might not get a format
|
| - // changed message to re-request them, such as during a seek. In that case,
|
| - // we want to reuse the existing buffers. However, we're about to invalidate
|
| - // all the output buffers, so we must be sure that the strategy no longer
|
| - // refers to them.
|
| -
|
| if (pending_input_buf_index_ != -1) {
|
| // The data for that index exists in the input buffer, but corresponding
|
| // shm block been deleted. Check that it is safe to flush the coec, i.e.
|
| @@ -907,8 +913,11 @@ void AndroidVideoDecodeAccelerator::ResetCodecState() {
|
| pending_input_buf_index_ = -1;
|
| }
|
|
|
| - if (state_ == WAITING_FOR_KEY)
|
| - state_ = NO_ERROR;
|
| + // We don't dismiss picture buffers here since we might not get a format
|
| + // changed message to re-request them, such as during a seek. In that case,
|
| + // we want to reuse the existing buffers. However, we're about to invalidate
|
| + // all the output buffers, so we must be sure that the strategy no longer
|
| + // refers to them.
|
|
|
| // We might increment error_sequence_token here to cancel any delayed errors,
|
| // but right now it's unclear that it's safe to do so. If we are in an error
|
| @@ -923,24 +932,25 @@ void AndroidVideoDecodeAccelerator::ResetCodecState() {
|
| // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
|
| // one. The full reconfigure is much slower and may cause visible freezing if
|
| // done mid-stream.
|
| - if (state_ == NO_ERROR &&
|
| + if (state_ != ERROR &&
|
| base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
|
| - DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
|
| + DVLOG(3) << __FUNCTION__ << ": flushing the MediaCodec.";
|
| media_codec_->Reset();
|
| - // Since we just flushed all the output buffers, make sure that nothing is
|
| - // using them.
|
| - strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
|
| + state_ = NO_ERROR;
|
| } else {
|
| - DVLOG(3) << __FUNCTION__
|
| - << " Deleting the MediaCodec and creating a new one.";
|
| - g_avda_timer.Pointer()->StopTimer(this);
|
| + DVLOG(3) << __FUNCTION__ << ": deleting the MediaCodec.";
|
| media_codec_.reset();
|
| - // Changing the codec will also notify the strategy to forget about any
|
| - // output buffers it has currently.
|
| - state_ = NO_ERROR;
|
| - if (!ConfigureMediaCodec())
|
| - POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
|
| + // The MediaCodec will be initialized lazily on the next Decode().
|
| + // TODO(liberato): After asynchronous MediaCodec initialization is
|
| + // implemented, we should choose to eagerly reinitialize the MediaCodec when
|
| + // we know a Decode() call is coming soon anyway.
|
| + state_ = PENDING_CODEC_REINITIALIZATION;
|
| }
|
| +
|
| + // Notify the strategy that the MediaCodec changed because any output buffers
|
| + // it owns are now invalid.
|
| + strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
|
| + g_avda_timer.Pointer()->StopTimer(this);
|
| }
|
|
|
| void AndroidVideoDecodeAccelerator::DismissPictureBuffers() {
|
|
|