Index: media/base/android/media_decoder_job.cc |
diff --git a/media/base/android/media_decoder_job.cc b/media/base/android/media_decoder_job.cc |
index 74aeecdc54520b016b01251be1c742f48be5205c..85708813e40fe4a7006e7a9a487176e9a9aed85b 100644 |
--- a/media/base/android/media_decoder_job.cc |
+++ b/media/base/android/media_decoder_job.cc |
@@ -28,6 +28,7 @@ MediaDecoderJob::MediaDecoderJob( |
media_codec_bridge_(media_codec_bridge), |
needs_flush_(false), |
input_eos_encountered_(false), |
+ output_eos_encountered_(false), |
skip_eos_enqueue_(true), |
prerolling_(true), |
weak_this_(this), |
@@ -275,6 +276,7 @@ void MediaDecoderJob::DecodeInternal( |
if (needs_flush) { |
DVLOG(1) << "DecodeInternal needs flush."; |
input_eos_encountered_ = false; |
+ output_eos_encountered_ = false; |
MediaCodecStatus reset_status = media_codec_bridge_->Reset(); |
if (MEDIA_CODEC_OK != reset_status) { |
callback.Run(reset_status, kNoTimestamp(), 0); |
@@ -282,6 +284,11 @@ void MediaDecoderJob::DecodeInternal( |
} |
} |
+ // Once output EOS has occurred, we should not be asked to decode again. |
+ // MediaCodec has undefined behavior if similarly asked to decode after output |
+ // EOS. |
+ DCHECK(!output_eos_encountered_); |
+ |
// For aborted access unit, just skip it and inform the player. |
if (unit.status == DemuxerStream::kAborted) { |
// TODO(qinmin): use a new enum instead of MEDIA_CODEC_STOPPED. |
@@ -292,6 +299,7 @@ void MediaDecoderJob::DecodeInternal( |
if (skip_eos_enqueue_) { |
if (unit.end_of_stream || unit.data.empty()) { |
input_eos_encountered_ = true; |
+ output_eos_encountered_ = true; |
callback.Run(MEDIA_CODEC_OUTPUT_END_OF_STREAM, kNoTimestamp(), 0); |
return; |
} |
@@ -299,7 +307,6 @@ void MediaDecoderJob::DecodeInternal( |
skip_eos_enqueue_ = false; |
} |
- |
MediaCodecStatus input_status = MEDIA_CODEC_INPUT_END_OF_STREAM; |
if (!input_eos_encountered_) { |
input_status = QueueInputBuffer(unit); |
@@ -315,14 +322,13 @@ void MediaDecoderJob::DecodeInternal( |
size_t offset = 0; |
size_t size = 0; |
base::TimeDelta presentation_timestamp; |
- bool output_eos_encountered = false; |
base::TimeDelta timeout = base::TimeDelta::FromMilliseconds( |
kMediaCodecTimeoutInMilliseconds); |
MediaCodecStatus status = media_codec_bridge_->DequeueOutputBuffer( |
timeout, &buffer_index, &offset, &size, &presentation_timestamp, |
- &output_eos_encountered); |
+ &output_eos_encountered_); |
if (status != MEDIA_CODEC_OK) { |
if (status == MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED && |
@@ -334,7 +340,7 @@ void MediaDecoderJob::DecodeInternal( |
} |
// TODO(xhwang/qinmin): This logic is correct but strange. Clean it up. |
- if (output_eos_encountered) |
+ if (output_eos_encountered_) |
status = MEDIA_CODEC_OUTPUT_END_OF_STREAM; |
else if (input_status == MEDIA_CODEC_INPUT_END_OF_STREAM) |
status = MEDIA_CODEC_INPUT_END_OF_STREAM; |