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

Unified Diff: media/base/android/media_source_player.cc

Issue 79283006: Let only seeks reset Android MSE stream playback completion (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased, addressed ps6 comments. includes some test cleanup Created 7 years 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
Index: media/base/android/media_source_player.cc
diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc
index 4c6cb9c1215602e934600f547b83d2470eb53928..e5b518e22c0e64930311496a95c4e3c72ce219f0 100644
--- a/media/base/android/media_source_player.cc
+++ b/media/base/android/media_source_player.cc
@@ -73,8 +73,8 @@ MediaSourcePlayer::MediaSourcePlayer(
video_codec_(kUnknownVideoCodec),
num_channels_(0),
sampling_rate_(0),
- audio_finished_(true),
- video_finished_(true),
+ reached_audio_eos_(false),
+ reached_video_eos_(false),
playing_(false),
is_audio_encrypted_(false),
is_video_encrypted_(false),
@@ -318,8 +318,6 @@ void MediaSourcePlayer::StartInternal() {
return;
}
- audio_finished_ = false;
- video_finished_ = false;
SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
ProcessPendingEvents();
}
@@ -451,6 +449,9 @@ void MediaSourcePlayer::OnDemuxerSeekDone(
audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time);
}
+ reached_audio_eos_ = false;
+ reached_video_eos_ = false;
+
base::TimeDelta current_time = GetCurrentTime();
// TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
// to preroll media decoder jobs. Currently |start_presentation_timestamp_|
@@ -530,19 +531,28 @@ void MediaSourcePlayer::ProcessPendingEvents() {
if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
- int count = (audio_decoder_job_ ? 1 : 0) + (video_decoder_job_ ? 1 : 0);
+ DCHECK(audio_decoder_job_ || AudioFinished());
+ DCHECK(video_decoder_job_ || VideoFinished());
+
+ int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
+
+ // It is possible that all streams have finished decode, yet starvation
+ // occurred during the last stream's EOS decode. In this case, prefetch is a
+ // no-op.
+ ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
+ if (count == 0)
+ return;
+ SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
base::Closure barrier = BarrierClosure(count, base::Bind(
&MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr()));
- if (audio_decoder_job_)
+ if (!AudioFinished())
audio_decoder_job_->Prefetch(barrier);
- if (video_decoder_job_)
+ if (!VideoFinished())
video_decoder_job_->Prefetch(barrier);
- SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
- ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
return;
}
@@ -590,16 +600,27 @@ void MediaSourcePlayer::MediaDecoderCallback(
return;
}
- if (pending_event_ != NO_EVENT_PENDING) {
+ DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
+
+ // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
+ // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
+ // any other pending events only after handling EOS detection.
+ if (IsEventPending(SEEK_EVENT_PENDING)) {
ProcessPendingEvents();
return;
}
- if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
+ if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
PlaybackCompleted(is_audio);
+
+ if (pending_event_ != NO_EVENT_PENDING) {
+ ProcessPendingEvents();
return;
}
+ if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
+ return;
+
if (status == MEDIA_CODEC_OK && is_clock_manager &&
presentation_timestamp != kNoTimestamp()) {
UpdateTimestamps(presentation_timestamp, audio_output_bytes);
@@ -643,6 +664,7 @@ void MediaSourcePlayer::MediaDecoderCallback(
void MediaSourcePlayer::DecodeMoreAudio() {
DVLOG(1) << __FUNCTION__;
DCHECK(!audio_decoder_job_->is_decoding());
+ DCHECK(!AudioFinished());
if (audio_decoder_job_->Decode(
start_time_ticks_, start_presentation_timestamp_, base::Bind(
@@ -672,6 +694,7 @@ void MediaSourcePlayer::DecodeMoreAudio() {
void MediaSourcePlayer::DecodeMoreVideo() {
DVLOG(1) << __FUNCTION__;
DCHECK(!video_decoder_job_->is_decoding());
+ DCHECK(!VideoFinished());
if (video_decoder_job_->Decode(
start_time_ticks_, start_presentation_timestamp_, base::Bind(
@@ -706,11 +729,11 @@ void MediaSourcePlayer::DecodeMoreVideo() {
void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
if (is_audio)
- audio_finished_ = true;
+ reached_audio_eos_ = true;
else
- video_finished_ = true;
+ reached_video_eos_ = true;
- if ((!HasAudio() || audio_finished_) && (!HasVideo() || video_finished_)) {
+ if (AudioFinished() && VideoFinished()) {
playing_ = false;
clock_.Pause();
start_time_ticks_ = base::TimeTicks();
@@ -735,6 +758,14 @@ bool MediaSourcePlayer::HasAudio() {
return kUnknownAudioCodec != audio_codec_;
}
+bool MediaSourcePlayer::AudioFinished() {
+ return reached_audio_eos_ || !HasAudio();
+}
+
+bool MediaSourcePlayer::VideoFinished() {
+ return reached_video_eos_ || !HasVideo();
+}
+
void MediaSourcePlayer::ConfigureAudioDecoderJob() {
if (!HasAudio()) {
audio_decoder_job_.reset();
@@ -916,9 +947,10 @@ void MediaSourcePlayer::OnPrefetchDone() {
if (!clock_.IsPlaying())
clock_.Play();
- if (audio_decoder_job_)
+ if (!AudioFinished())
DecodeMoreAudio();
- if (video_decoder_job_)
+
+ if (!VideoFinished())
DecodeMoreVideo();
}

Powered by Google App Engine
This is Rietveld 408576698