Chromium Code Reviews| Index: media/base/android/media_codec_decoder.cc |
| diff --git a/media/base/android/media_codec_decoder.cc b/media/base/android/media_codec_decoder.cc |
| index 6d7119f408590b5372261766708adb741119b779..026df89dd3642a394c9ff9b8b84b9aa5755153e6 100644 |
| --- a/media/base/android/media_codec_decoder.cc |
| +++ b/media/base/android/media_codec_decoder.cc |
| @@ -50,7 +50,7 @@ MediaCodecDecoder::MediaCodecDecoder( |
| stop_done_cb_(stop_done_cb), |
| error_cb_(error_cb), |
| state_(kStopped), |
| - preroll_mode_(kPrerollTillPTS), |
| + is_prepared_(false), |
| eos_enqueued_(false), |
| completed_(false), |
| last_frame_posted_(false), |
| @@ -104,7 +104,7 @@ void MediaCodecDecoder::Flush() { |
| verify_next_frame_is_key_ = true; |
| #endif |
| - preroll_mode_ = kPrerollTillPTS; |
| + is_prepared_ = false; |
| if (media_codec_bridge_) { |
| // MediaCodecBridge::Reset() performs MediaCodecBridge.flush() |
| @@ -123,7 +123,7 @@ void MediaCodecDecoder::ReleaseMediaCodec() { |
| DVLOG(1) << class_name() << "::" << __FUNCTION__; |
| media_codec_bridge_.reset(); |
| - preroll_mode_ = kPrerollTillPTS; |
| + is_prepared_ = false; |
|
qinmin
2015/09/03 05:30:04
this variable is updated on both decoder thread an
Tima Vaisburd
2015/09/03 19:55:27
During Flush() and ReleaseMediaCodec() the decoder
|
| } |
| bool MediaCodecDecoder::IsPrefetchingOrPlaying() const { |
| @@ -163,14 +163,15 @@ bool MediaCodecDecoder::IsCompleted() const { |
| bool MediaCodecDecoder::NotCompletedAndNeedsPreroll() const { |
| DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| - return HasStream() && preroll_mode_ != kNoPreroll && !completed_; |
| + return HasStream() && !completed_ && |
| + (!is_prepared_ || preroll_timestamp_ != base::TimeDelta()); |
| } |
| -void MediaCodecDecoder::SetDecodingUntilOutputIsPresent() { |
| +void MediaCodecDecoder::SetPrerollTimestamp(base::TimeDelta preroll_timestamp) { |
| DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| - DVLOG(1) << class_name() << "::" << __FUNCTION__; |
| + DVLOG(1) << class_name() << "::" << __FUNCTION__ << ": " << preroll_timestamp; |
| - preroll_mode_ = kPrerollTillOutputIsPresent; |
| + preroll_timestamp_ = preroll_timestamp; |
| } |
| base::android::ScopedJavaLocalRef<jobject> MediaCodecDecoder::GetMediaCrypto() { |
| @@ -242,12 +243,11 @@ MediaCodecDecoder::ConfigStatus MediaCodecDecoder::Configure() { |
| return result; |
| } |
| -bool MediaCodecDecoder::Preroll(base::TimeDelta preroll_timestamp, |
| - const base::Closure& preroll_done_cb) { |
| +bool MediaCodecDecoder::Preroll(const base::Closure& preroll_done_cb) { |
| DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| DVLOG(1) << class_name() << "::" << __FUNCTION__ |
| - << " preroll_timestamp:" << preroll_timestamp; |
| + << " preroll_timestamp:" << preroll_timestamp_; |
| DecoderState state = GetState(); |
| if (state != kPrefetched) { |
| @@ -263,16 +263,12 @@ bool MediaCodecDecoder::Preroll(base::TimeDelta preroll_timestamp, |
| } |
| DCHECK(!decoder_thread_.IsRunning()); |
| - DCHECK(preroll_mode_ != kNoPreroll); |
| preroll_done_cb_ = preroll_done_cb; |
| // We only synchronize video stream. |
| DissociatePTSFromTime(); // associaton will happen after preroll is done. |
| - preroll_timestamp_ = (preroll_mode_ == kPrerollTillPTS) ? preroll_timestamp |
| - : base::TimeDelta(); |
| - |
| last_frame_posted_ = false; |
| // Start the decoder thread |
| @@ -313,7 +309,7 @@ bool MediaCodecDecoder::Start(base::TimeDelta start_timestamp) { |
| // We only synchronize video stream. |
| AssociateCurrentTimeWithPTS(start_timestamp); |
| - preroll_timestamp_ = base::TimeDelta(); |
| + // preroll_timestamp_ = base::TimeDelta(); |
|
qinmin
2015/09/03 05:30:04
remove this if unused
Tima Vaisburd
2015/09/03 19:55:26
Replaced with
DCHECK(preroll_timestamp_ == base:
|
| // Start the decoder thread |
| if (!decoder_thread_.IsRunning()) { |
| @@ -399,16 +395,18 @@ void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) { |
| SetState(kStopped); |
| completed_ = (eos_encountered && !drain_decoder_); |
| + // If the stream is completed during preroll we need to report it since |
| + // another stream might be running and the player waits for two callbacks. |
| if (completed_ && !preroll_done_cb_.is_null()) { |
| + preroll_timestamp_ = base::TimeDelta(); |
| media_task_runner_->PostTask(FROM_HERE, |
| base::ResetAndReturn(&preroll_done_cb_)); |
| } |
| if (eos_encountered && drain_decoder_) { |
| - ReleaseMediaCodec(); |
| drain_decoder_ = false; |
| eos_enqueued_ = false; |
| - preroll_mode_ = kPrerollTillOutputIsPresent; |
| + ReleaseMediaCodec(); |
| media_task_runner_->PostTask(FROM_HERE, decoder_drained_cb_); |
| } |
| @@ -420,14 +418,14 @@ void MediaCodecDecoder::OnPrerollDone() { |
| DVLOG(1) << class_name() << "::" << __FUNCTION__; |
| - preroll_mode_ = kNoPreroll; |
| + preroll_timestamp_ = base::TimeDelta(); |
| - // The state might be kStopping. |
| - if (GetState() == kPrerolling) { |
| + // The state might be kStopping (?) |
| + if (GetState() == kPrerolling) |
| SetState(kPrerolled); |
| - media_task_runner_->PostTask(FROM_HERE, |
| - base::ResetAndReturn(&preroll_done_cb_)); |
| - } |
| + |
| + if (!preroll_done_cb_.is_null()) |
| + base::ResetAndReturn(&preroll_done_cb_).Run(); |
| } |
| void MediaCodecDecoder::OnDemuxerDataAvailable(const DemuxerData& data) { |
| @@ -578,6 +576,7 @@ void MediaCodecDecoder::ProcessNextFrame() { |
| // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. |
| // We only need to let finish the delayed rendering tasks. |
| + DVLOG(1) << class_name() << "::" << __FUNCTION__ << " kStopping, returning"; |
| return; |
| } |
| @@ -797,6 +796,8 @@ bool MediaCodecDecoder::DepleteOutputBufferQueue() { |
| case MEDIA_CODEC_OK: |
| // We got the decoded frame. |
| + is_prepared_ = true; |
| + |
| if (pts < preroll_timestamp_) |
| render_mode = kRenderSkip; |
| else if (GetState() == kPrerolling) |