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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/android/media_source_player.h" 5 #include "media/base/android/media_source_player.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/android/jni_android.h" 9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 scoped_ptr<DemuxerAndroid> demuxer) 66 scoped_ptr<DemuxerAndroid> demuxer)
67 : MediaPlayerAndroid(player_id, manager), 67 : MediaPlayerAndroid(player_id, manager),
68 demuxer_(demuxer.Pass()), 68 demuxer_(demuxer.Pass()),
69 pending_event_(NO_EVENT_PENDING), 69 pending_event_(NO_EVENT_PENDING),
70 width_(0), 70 width_(0),
71 height_(0), 71 height_(0),
72 audio_codec_(kUnknownAudioCodec), 72 audio_codec_(kUnknownAudioCodec),
73 video_codec_(kUnknownVideoCodec), 73 video_codec_(kUnknownVideoCodec),
74 num_channels_(0), 74 num_channels_(0),
75 sampling_rate_(0), 75 sampling_rate_(0),
76 audio_finished_(true), 76 reached_audio_eos_(false),
77 video_finished_(true), 77 reached_video_eos_(false),
78 playing_(false), 78 playing_(false),
79 is_audio_encrypted_(false), 79 is_audio_encrypted_(false),
80 is_video_encrypted_(false), 80 is_video_encrypted_(false),
81 volume_(-1.0), 81 volume_(-1.0),
82 clock_(&default_tick_clock_), 82 clock_(&default_tick_clock_),
83 next_video_data_is_iframe_(true), 83 next_video_data_is_iframe_(true),
84 doing_browser_seek_(false), 84 doing_browser_seek_(false),
85 pending_seek_(false), 85 pending_seek_(false),
86 reconfig_audio_decoder_(false), 86 reconfig_audio_decoder_(false),
87 reconfig_video_decoder_(false), 87 reconfig_video_decoder_(false),
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 // Create decoder jobs if they are not created 311 // Create decoder jobs if they are not created
312 ConfigureAudioDecoderJob(); 312 ConfigureAudioDecoderJob();
313 ConfigureVideoDecoderJob(); 313 ConfigureVideoDecoderJob();
314 314
315 // If one of the decoder job is not ready, do nothing. 315 // If one of the decoder job is not ready, do nothing.
316 if ((HasAudio() && !audio_decoder_job_) || 316 if ((HasAudio() && !audio_decoder_job_) ||
317 (HasVideo() && !video_decoder_job_)) { 317 (HasVideo() && !video_decoder_job_)) {
318 return; 318 return;
319 } 319 }
320 320
321 audio_finished_ = false;
322 video_finished_ = false;
323 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 321 SetPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
324 ProcessPendingEvents(); 322 ProcessPendingEvents();
325 } 323 }
326 324
327 void MediaSourcePlayer::OnDemuxerConfigsAvailable( 325 void MediaSourcePlayer::OnDemuxerConfigsAvailable(
328 const DemuxerConfigs& configs) { 326 const DemuxerConfigs& configs) {
329 DVLOG(1) << __FUNCTION__; 327 DVLOG(1) << __FUNCTION__;
330 duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms); 328 duration_ = base::TimeDelta::FromMilliseconds(configs.duration_ms);
331 clock_.SetDuration(duration_); 329 clock_.SetDuration(duration_);
332 330
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 // A browser seek must not jump into the past. Ideally, it seeks to the 442 // A browser seek must not jump into the past. Ideally, it seeks to the
445 // requested time, but it might jump into the future. 443 // requested time, but it might jump into the future.
446 DCHECK(actual_browser_seek_time >= GetCurrentTime()); 444 DCHECK(actual_browser_seek_time >= GetCurrentTime());
447 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: " 445 DVLOG(1) << __FUNCTION__ << " : setting clock to actual browser seek time: "
448 << actual_browser_seek_time.InSecondsF(); 446 << actual_browser_seek_time.InSecondsF();
449 clock_.SetTime(actual_browser_seek_time, actual_browser_seek_time); 447 clock_.SetTime(actual_browser_seek_time, actual_browser_seek_time);
450 if (audio_timestamp_helper_) 448 if (audio_timestamp_helper_)
451 audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time); 449 audio_timestamp_helper_->SetBaseTimestamp(actual_browser_seek_time);
452 } 450 }
453 451
452 reached_audio_eos_ = false;
453 reached_video_eos_ = false;
454
454 base::TimeDelta current_time = GetCurrentTime(); 455 base::TimeDelta current_time = GetCurrentTime();
455 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_| 456 // TODO(qinmin): Simplify the logic by using |start_presentation_timestamp_|
456 // to preroll media decoder jobs. Currently |start_presentation_timestamp_| 457 // to preroll media decoder jobs. Currently |start_presentation_timestamp_|
457 // is calculated from decoder output, while preroll relies on the access 458 // is calculated from decoder output, while preroll relies on the access
458 // unit's timestamp. There are some differences between the two. 459 // unit's timestamp. There are some differences between the two.
459 preroll_timestamp_ = current_time; 460 preroll_timestamp_ = current_time;
460 if (audio_decoder_job_) 461 if (audio_decoder_job_)
461 audio_decoder_job_->BeginPrerolling(preroll_timestamp_); 462 audio_decoder_job_->BeginPrerolling(preroll_timestamp_);
462 if (video_decoder_job_) 463 if (video_decoder_job_)
463 video_decoder_job_->BeginPrerolling(preroll_timestamp_); 464 video_decoder_job_->BeginPrerolling(preroll_timestamp_);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 524
524 // Return early if we can't successfully configure a new video decoder job 525 // Return early if we can't successfully configure a new video decoder job
525 // yet, except continue processing other pending events if |surface_| is 526 // yet, except continue processing other pending events if |surface_| is
526 // empty. 527 // empty.
527 if (HasVideo() && !video_decoder_job_ && !surface_.IsEmpty()) 528 if (HasVideo() && !video_decoder_job_ && !surface_.IsEmpty())
528 return; 529 return;
529 } 530 }
530 531
531 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) { 532 if (IsEventPending(PREFETCH_REQUEST_EVENT_PENDING)) {
532 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT."; 533 DVLOG(1) << __FUNCTION__ << " : Handling PREFETCH_REQUEST_EVENT.";
533 int count = (audio_decoder_job_ ? 1 : 0) + (video_decoder_job_ ? 1 : 0); 534 DCHECK(audio_decoder_job_ || AudioFinished());
535 DCHECK(video_decoder_job_ || VideoFinished());
534 536
537 int count = (AudioFinished() ? 0 : 1) + (VideoFinished() ? 0 : 1);
538
539 // It is possible that all streams have finished decode, yet starvation
540 // occurred during the last stream's EOS decode. In this case, prefetch is a
541 // no-op.
542 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
543 if (count == 0)
544 return;
545
546 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
535 base::Closure barrier = BarrierClosure(count, base::Bind( 547 base::Closure barrier = BarrierClosure(count, base::Bind(
536 &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr())); 548 &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr()));
537 549
538 if (audio_decoder_job_) 550 if (!AudioFinished())
539 audio_decoder_job_->Prefetch(barrier); 551 audio_decoder_job_->Prefetch(barrier);
540 552
541 if (video_decoder_job_) 553 if (!VideoFinished())
542 video_decoder_job_->Prefetch(barrier); 554 video_decoder_job_->Prefetch(barrier);
543 555
544 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
545 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
546 return; 556 return;
547 } 557 }
548 558
549 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); 559 DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
550 560
551 // Now that all pending events have been handled, resume decoding if we are 561 // Now that all pending events have been handled, resume decoding if we are
552 // still playing. 562 // still playing.
553 if (playing_) 563 if (playing_)
554 StartInternal(); 564 StartInternal();
555 } 565 }
(...skipping 27 matching lines...) Expand all
583 if (is_clock_manager) 593 if (is_clock_manager)
584 decoder_starvation_callback_.Cancel(); 594 decoder_starvation_callback_.Cancel();
585 595
586 if (status == MEDIA_CODEC_ERROR) { 596 if (status == MEDIA_CODEC_ERROR) {
587 DVLOG(1) << __FUNCTION__ << " : decode error"; 597 DVLOG(1) << __FUNCTION__ << " : decode error";
588 Release(); 598 Release();
589 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); 599 manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
590 return; 600 return;
591 } 601 }
592 602
603 DCHECK(!IsEventPending(PREFETCH_DONE_EVENT_PENDING));
604
605 // Let |SEEK_EVENT_PENDING| (the highest priority event outside of
606 // |PREFETCH_DONE_EVENT_PENDING|) preempt output EOS detection here. Process
607 // any other pending events only after handling EOS detection.
608 if (IsEventPending(SEEK_EVENT_PENDING)) {
609 ProcessPendingEvents();
610 return;
611 }
612
613 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
614 PlaybackCompleted(is_audio);
615
593 if (pending_event_ != NO_EVENT_PENDING) { 616 if (pending_event_ != NO_EVENT_PENDING) {
594 ProcessPendingEvents(); 617 ProcessPendingEvents();
595 return; 618 return;
596 } 619 }
597 620
598 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) { 621 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM)
599 PlaybackCompleted(is_audio);
600 return; 622 return;
601 }
602 623
603 if (status == MEDIA_CODEC_OK && is_clock_manager && 624 if (status == MEDIA_CODEC_OK && is_clock_manager &&
604 presentation_timestamp != kNoTimestamp()) { 625 presentation_timestamp != kNoTimestamp()) {
605 UpdateTimestamps(presentation_timestamp, audio_output_bytes); 626 UpdateTimestamps(presentation_timestamp, audio_output_bytes);
606 } 627 }
607 628
608 if (!playing_) { 629 if (!playing_) {
609 if (is_clock_manager) 630 if (is_clock_manager)
610 clock_.Pause(); 631 clock_.Pause();
611 return; 632 return;
(...skipping 24 matching lines...) Expand all
636 DecodeMoreAudio(); 657 DecodeMoreAudio();
637 return; 658 return;
638 } 659 }
639 660
640 DecodeMoreVideo(); 661 DecodeMoreVideo();
641 } 662 }
642 663
643 void MediaSourcePlayer::DecodeMoreAudio() { 664 void MediaSourcePlayer::DecodeMoreAudio() {
644 DVLOG(1) << __FUNCTION__; 665 DVLOG(1) << __FUNCTION__;
645 DCHECK(!audio_decoder_job_->is_decoding()); 666 DCHECK(!audio_decoder_job_->is_decoding());
667 DCHECK(!AudioFinished());
646 668
647 if (audio_decoder_job_->Decode( 669 if (audio_decoder_job_->Decode(
648 start_time_ticks_, start_presentation_timestamp_, base::Bind( 670 start_time_ticks_, start_presentation_timestamp_, base::Bind(
649 &MediaSourcePlayer::MediaDecoderCallback, 671 &MediaSourcePlayer::MediaDecoderCallback,
650 weak_this_.GetWeakPtr(), true))) { 672 weak_this_.GetWeakPtr(), true))) {
651 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", 673 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
652 audio_decoder_job_.get()); 674 audio_decoder_job_.get());
653 return; 675 return;
654 } 676 }
655 677
656 // Failed to start the next decode. 678 // Failed to start the next decode.
657 // Wait for demuxer ready message. 679 // Wait for demuxer ready message.
658 DCHECK(!reconfig_audio_decoder_); 680 DCHECK(!reconfig_audio_decoder_);
659 reconfig_audio_decoder_ = true; 681 reconfig_audio_decoder_ = true;
660 682
661 // Config change may have just been detected on the other stream. If so, 683 // Config change may have just been detected on the other stream. If so,
662 // don't send a duplicate demuxer config request. 684 // don't send a duplicate demuxer config request.
663 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 685 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
664 DCHECK(reconfig_video_decoder_); 686 DCHECK(reconfig_video_decoder_);
665 return; 687 return;
666 } 688 }
667 689
668 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 690 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
669 ProcessPendingEvents(); 691 ProcessPendingEvents();
670 } 692 }
671 693
672 void MediaSourcePlayer::DecodeMoreVideo() { 694 void MediaSourcePlayer::DecodeMoreVideo() {
673 DVLOG(1) << __FUNCTION__; 695 DVLOG(1) << __FUNCTION__;
674 DCHECK(!video_decoder_job_->is_decoding()); 696 DCHECK(!video_decoder_job_->is_decoding());
697 DCHECK(!VideoFinished());
675 698
676 if (video_decoder_job_->Decode( 699 if (video_decoder_job_->Decode(
677 start_time_ticks_, start_presentation_timestamp_, base::Bind( 700 start_time_ticks_, start_presentation_timestamp_, base::Bind(
678 &MediaSourcePlayer::MediaDecoderCallback, 701 &MediaSourcePlayer::MediaDecoderCallback,
679 weak_this_.GetWeakPtr(), false))) { 702 weak_this_.GetWeakPtr(), false))) {
680 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", 703 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
681 video_decoder_job_.get()); 704 video_decoder_job_.get());
682 return; 705 return;
683 } 706 }
684 707
(...skipping 14 matching lines...) Expand all
699 return; 722 return;
700 } 723 }
701 724
702 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 725 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
703 ProcessPendingEvents(); 726 ProcessPendingEvents();
704 } 727 }
705 728
706 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { 729 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
707 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")"; 730 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
708 if (is_audio) 731 if (is_audio)
709 audio_finished_ = true; 732 reached_audio_eos_ = true;
710 else 733 else
711 video_finished_ = true; 734 reached_video_eos_ = true;
712 735
713 if ((!HasAudio() || audio_finished_) && (!HasVideo() || video_finished_)) { 736 if (AudioFinished() && VideoFinished()) {
714 playing_ = false; 737 playing_ = false;
715 clock_.Pause(); 738 clock_.Pause();
716 start_time_ticks_ = base::TimeTicks(); 739 start_time_ticks_ = base::TimeTicks();
717 manager()->OnPlaybackComplete(player_id()); 740 manager()->OnPlaybackComplete(player_id());
718 } 741 }
719 } 742 }
720 743
721 void MediaSourcePlayer::ClearDecodingData() { 744 void MediaSourcePlayer::ClearDecodingData() {
722 DVLOG(1) << __FUNCTION__; 745 DVLOG(1) << __FUNCTION__;
723 if (audio_decoder_job_) 746 if (audio_decoder_job_)
724 audio_decoder_job_->Flush(); 747 audio_decoder_job_->Flush();
725 if (video_decoder_job_) 748 if (video_decoder_job_)
726 video_decoder_job_->Flush(); 749 video_decoder_job_->Flush();
727 start_time_ticks_ = base::TimeTicks(); 750 start_time_ticks_ = base::TimeTicks();
728 } 751 }
729 752
730 bool MediaSourcePlayer::HasVideo() { 753 bool MediaSourcePlayer::HasVideo() {
731 return kUnknownVideoCodec != video_codec_; 754 return kUnknownVideoCodec != video_codec_;
732 } 755 }
733 756
734 bool MediaSourcePlayer::HasAudio() { 757 bool MediaSourcePlayer::HasAudio() {
735 return kUnknownAudioCodec != audio_codec_; 758 return kUnknownAudioCodec != audio_codec_;
736 } 759 }
737 760
761 bool MediaSourcePlayer::AudioFinished() {
762 return reached_audio_eos_ || !HasAudio();
763 }
764
765 bool MediaSourcePlayer::VideoFinished() {
766 return reached_video_eos_ || !HasVideo();
767 }
768
738 void MediaSourcePlayer::ConfigureAudioDecoderJob() { 769 void MediaSourcePlayer::ConfigureAudioDecoderJob() {
739 if (!HasAudio()) { 770 if (!HasAudio()) {
740 audio_decoder_job_.reset(); 771 audio_decoder_job_.reset();
741 return; 772 return;
742 } 773 }
743 774
744 // Create audio decoder job only if config changes. 775 // Create audio decoder job only if config changes.
745 if (audio_decoder_job_ && !reconfig_audio_decoder_) 776 if (audio_decoder_job_ && !reconfig_audio_decoder_)
746 return; 777 return;
747 778
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 if (pending_event_ != NO_EVENT_PENDING) { 940 if (pending_event_ != NO_EVENT_PENDING) {
910 ProcessPendingEvents(); 941 ProcessPendingEvents();
911 return; 942 return;
912 } 943 }
913 944
914 start_time_ticks_ = base::TimeTicks::Now(); 945 start_time_ticks_ = base::TimeTicks::Now();
915 start_presentation_timestamp_ = GetCurrentTime(); 946 start_presentation_timestamp_ = GetCurrentTime();
916 if (!clock_.IsPlaying()) 947 if (!clock_.IsPlaying())
917 clock_.Play(); 948 clock_.Play();
918 949
919 if (audio_decoder_job_) 950 if (!AudioFinished())
920 DecodeMoreAudio(); 951 DecodeMoreAudio();
921 if (video_decoder_job_) 952
953 if (!VideoFinished())
922 DecodeMoreVideo(); 954 DecodeMoreVideo();
923 } 955 }
924 956
925 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) { 957 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
926 static const char* kPendingEventNames[] = { 958 static const char* kPendingEventNames[] = {
927 "SEEK", 959 "SEEK",
928 "SURFACE_CHANGE", 960 "SURFACE_CHANGE",
929 "CONFIG_CHANGE", 961 "CONFIG_CHANGE",
930 "PREFETCH_REQUEST", 962 "PREFETCH_REQUEST",
931 "PREFETCH_DONE", 963 "PREFETCH_DONE",
(...skipping 22 matching lines...) Expand all
954 986
955 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 987 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
956 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 988 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
957 DCHECK_NE(event, NO_EVENT_PENDING); 989 DCHECK_NE(event, NO_EVENT_PENDING);
958 DCHECK(IsEventPending(event)) << GetEventName(event); 990 DCHECK(IsEventPending(event)) << GetEventName(event);
959 991
960 pending_event_ &= ~event; 992 pending_event_ &= ~event;
961 } 993 }
962 994
963 } // namespace media 995 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698