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

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 and addresses PS3 comments 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 audio_finished_(false),
77 video_finished_(true), 77 video_finished_(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 audio_finished_ = false;
453 video_finished_ = 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_ || AudioFinishedOrNoAudio());
535 DCHECK(video_decoder_job_ || VideoFinishedOrNoVideo());
536
537 int count = ((AudioFinishedOrNoAudio()) ? 0 : 1) +
538 ((VideoFinishedOrNoVideo()) ? 0 : 1);
534 539
535 base::Closure barrier = BarrierClosure(count, base::Bind( 540 base::Closure barrier = BarrierClosure(count, base::Bind(
536 &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr())); 541 &MediaSourcePlayer::OnPrefetchDone, weak_this_.GetWeakPtr()));
537 542
538 if (audio_decoder_job_) 543 if (!AudioFinishedOrNoAudio())
539 audio_decoder_job_->Prefetch(barrier); 544 audio_decoder_job_->Prefetch(barrier);
540 545
541 if (video_decoder_job_) 546 if (!VideoFinishedOrNoVideo())
542 video_decoder_job_->Prefetch(barrier); 547 video_decoder_job_->Prefetch(barrier);
543 548
544 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING); 549 SetPendingEvent(PREFETCH_DONE_EVENT_PENDING);
545 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING); 550 ClearPendingEvent(PREFETCH_REQUEST_EVENT_PENDING);
546 return; 551 return;
547 } 552 }
548 553
549 DCHECK_EQ(pending_event_, NO_EVENT_PENDING); 554 DCHECK_EQ(pending_event_, NO_EVENT_PENDING);
550 555
551 // Now that all pending events have been handled, resume decoding if we are 556 // Now that all pending events have been handled, resume decoding if we are
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 if (is_clock_manager) 588 if (is_clock_manager)
584 decoder_starvation_callback_.Cancel(); 589 decoder_starvation_callback_.Cancel();
585 590
586 if (status == MEDIA_CODEC_ERROR) { 591 if (status == MEDIA_CODEC_ERROR) {
587 DVLOG(1) << __FUNCTION__ << " : decode error"; 592 DVLOG(1) << __FUNCTION__ << " : decode error";
588 Release(); 593 Release();
589 manager()->OnError(player_id(), MEDIA_ERROR_DECODE); 594 manager()->OnError(player_id(), MEDIA_ERROR_DECODE);
590 return; 595 return;
591 } 596 }
592 597
598 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
599 PlaybackCompleted(is_audio);
600 return;
601 }
602
593 if (pending_event_ != NO_EVENT_PENDING) { 603 if (pending_event_ != NO_EVENT_PENDING) {
594 ProcessPendingEvents(); 604 ProcessPendingEvents();
595 return; 605 return;
596 } 606 }
597 607
598 if (status == MEDIA_CODEC_OUTPUT_END_OF_STREAM) {
599 PlaybackCompleted(is_audio);
600 return;
601 }
602
603 if (status == MEDIA_CODEC_OK && is_clock_manager && 608 if (status == MEDIA_CODEC_OK && is_clock_manager &&
604 presentation_timestamp != kNoTimestamp()) { 609 presentation_timestamp != kNoTimestamp()) {
605 UpdateTimestamps(presentation_timestamp, audio_output_bytes); 610 UpdateTimestamps(presentation_timestamp, audio_output_bytes);
606 } 611 }
607 612
608 if (!playing_) { 613 if (!playing_) {
609 if (is_clock_manager) 614 if (is_clock_manager)
610 clock_.Pause(); 615 clock_.Pause();
611 return; 616 return;
612 } 617 }
(...skipping 23 matching lines...) Expand all
636 DecodeMoreAudio(); 641 DecodeMoreAudio();
637 return; 642 return;
638 } 643 }
639 644
640 DecodeMoreVideo(); 645 DecodeMoreVideo();
641 } 646 }
642 647
643 void MediaSourcePlayer::DecodeMoreAudio() { 648 void MediaSourcePlayer::DecodeMoreAudio() {
644 DVLOG(1) << __FUNCTION__; 649 DVLOG(1) << __FUNCTION__;
645 DCHECK(!audio_decoder_job_->is_decoding()); 650 DCHECK(!audio_decoder_job_->is_decoding());
651 DCHECK(!AudioFinishedOrNoAudio());
646 652
647 if (audio_decoder_job_->Decode( 653 if (audio_decoder_job_->Decode(
648 start_time_ticks_, start_presentation_timestamp_, base::Bind( 654 start_time_ticks_, start_presentation_timestamp_, base::Bind(
649 &MediaSourcePlayer::MediaDecoderCallback, 655 &MediaSourcePlayer::MediaDecoderCallback,
650 weak_this_.GetWeakPtr(), true))) { 656 weak_this_.GetWeakPtr(), true))) {
651 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio", 657 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreAudio",
652 audio_decoder_job_.get()); 658 audio_decoder_job_.get());
653 return; 659 return;
654 } 660 }
655 661
656 // Failed to start the next decode. 662 // Failed to start the next decode.
657 // Wait for demuxer ready message. 663 // Wait for demuxer ready message.
658 DCHECK(!reconfig_audio_decoder_); 664 DCHECK(!reconfig_audio_decoder_);
659 reconfig_audio_decoder_ = true; 665 reconfig_audio_decoder_ = true;
660 666
661 // Config change may have just been detected on the other stream. If so, 667 // Config change may have just been detected on the other stream. If so,
662 // don't send a duplicate demuxer config request. 668 // don't send a duplicate demuxer config request.
663 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) { 669 if (IsEventPending(CONFIG_CHANGE_EVENT_PENDING)) {
664 DCHECK(reconfig_video_decoder_); 670 DCHECK(reconfig_video_decoder_);
665 return; 671 return;
666 } 672 }
667 673
668 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING); 674 SetPendingEvent(CONFIG_CHANGE_EVENT_PENDING);
669 ProcessPendingEvents(); 675 ProcessPendingEvents();
670 } 676 }
671 677
672 void MediaSourcePlayer::DecodeMoreVideo() { 678 void MediaSourcePlayer::DecodeMoreVideo() {
673 DVLOG(1) << __FUNCTION__; 679 DVLOG(1) << __FUNCTION__;
674 DCHECK(!video_decoder_job_->is_decoding()); 680 DCHECK(!video_decoder_job_->is_decoding());
681 DCHECK(!VideoFinishedOrNoVideo());
675 682
676 if (video_decoder_job_->Decode( 683 if (video_decoder_job_->Decode(
677 start_time_ticks_, start_presentation_timestamp_, base::Bind( 684 start_time_ticks_, start_presentation_timestamp_, base::Bind(
678 &MediaSourcePlayer::MediaDecoderCallback, 685 &MediaSourcePlayer::MediaDecoderCallback,
679 weak_this_.GetWeakPtr(), false))) { 686 weak_this_.GetWeakPtr(), false))) {
680 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo", 687 TRACE_EVENT_ASYNC_BEGIN0("media", "MediaSourcePlayer::DecodeMoreVideo",
681 video_decoder_job_.get()); 688 video_decoder_job_.get());
682 return; 689 return;
683 } 690 }
684 691
(...skipping 18 matching lines...) Expand all
703 ProcessPendingEvents(); 710 ProcessPendingEvents();
704 } 711 }
705 712
706 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) { 713 void MediaSourcePlayer::PlaybackCompleted(bool is_audio) {
707 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")"; 714 DVLOG(1) << __FUNCTION__ << "(" << is_audio << ")";
708 if (is_audio) 715 if (is_audio)
709 audio_finished_ = true; 716 audio_finished_ = true;
710 else 717 else
711 video_finished_ = true; 718 video_finished_ = true;
712 719
713 if ((!HasAudio() || audio_finished_) && (!HasVideo() || video_finished_)) { 720 if (AudioFinishedOrNoAudio() && VideoFinishedOrNoVideo()) {
714 playing_ = false; 721 playing_ = false;
715 clock_.Pause(); 722 clock_.Pause();
716 start_time_ticks_ = base::TimeTicks(); 723 start_time_ticks_ = base::TimeTicks();
717 manager()->OnPlaybackComplete(player_id()); 724 manager()->OnPlaybackComplete(player_id());
718 } 725 }
726
727 if (pending_event_ != NO_EVENT_PENDING)
qinmin 2013/12/04 00:20:16 i think you should process the pending events firs
wolenetz 2013/12/05 01:03:28 From our chats/analyses, MediaDecoderCallback() ca
728 ProcessPendingEvents();
719 } 729 }
720 730
721 void MediaSourcePlayer::ClearDecodingData() { 731 void MediaSourcePlayer::ClearDecodingData() {
722 DVLOG(1) << __FUNCTION__; 732 DVLOG(1) << __FUNCTION__;
723 if (audio_decoder_job_) 733 if (audio_decoder_job_)
724 audio_decoder_job_->Flush(); 734 audio_decoder_job_->Flush();
725 if (video_decoder_job_) 735 if (video_decoder_job_)
726 video_decoder_job_->Flush(); 736 video_decoder_job_->Flush();
727 start_time_ticks_ = base::TimeTicks(); 737 start_time_ticks_ = base::TimeTicks();
728 } 738 }
729 739
730 bool MediaSourcePlayer::HasVideo() { 740 bool MediaSourcePlayer::HasVideo() {
731 return kUnknownVideoCodec != video_codec_; 741 return kUnknownVideoCodec != video_codec_;
732 } 742 }
733 743
734 bool MediaSourcePlayer::HasAudio() { 744 bool MediaSourcePlayer::HasAudio() {
735 return kUnknownAudioCodec != audio_codec_; 745 return kUnknownAudioCodec != audio_codec_;
736 } 746 }
737 747
748 bool MediaSourcePlayer::AudioFinishedOrNoAudio() {
749 return audio_finished_ || !HasAudio();
750 }
751
752 bool MediaSourcePlayer::VideoFinishedOrNoVideo() {
753 return video_finished_ || !HasVideo();
754 }
755
738 void MediaSourcePlayer::ConfigureAudioDecoderJob() { 756 void MediaSourcePlayer::ConfigureAudioDecoderJob() {
739 if (!HasAudio()) { 757 if (!HasAudio()) {
740 audio_decoder_job_.reset(); 758 audio_decoder_job_.reset();
741 return; 759 return;
742 } 760 }
743 761
744 // Create audio decoder job only if config changes. 762 // Create audio decoder job only if config changes.
745 if (audio_decoder_job_ && !reconfig_audio_decoder_) 763 if (audio_decoder_job_ && !reconfig_audio_decoder_)
746 return; 764 return;
747 765
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 if (pending_event_ != NO_EVENT_PENDING) { 927 if (pending_event_ != NO_EVENT_PENDING) {
910 ProcessPendingEvents(); 928 ProcessPendingEvents();
911 return; 929 return;
912 } 930 }
913 931
914 start_time_ticks_ = base::TimeTicks::Now(); 932 start_time_ticks_ = base::TimeTicks::Now();
915 start_presentation_timestamp_ = GetCurrentTime(); 933 start_presentation_timestamp_ = GetCurrentTime();
916 if (!clock_.IsPlaying()) 934 if (!clock_.IsPlaying())
917 clock_.Play(); 935 clock_.Play();
918 936
919 if (audio_decoder_job_) 937 if (!AudioFinishedOrNoAudio()) {
938 DCHECK(audio_decoder_job_);
920 DecodeMoreAudio(); 939 DecodeMoreAudio();
921 if (video_decoder_job_) 940 }
941
942 if (!VideoFinishedOrNoVideo()) {
943 DCHECK(video_decoder_job_);
922 DecodeMoreVideo(); 944 DecodeMoreVideo();
945 }
923 } 946 }
924 947
925 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) { 948 const char* MediaSourcePlayer::GetEventName(PendingEventFlags event) {
926 static const char* kPendingEventNames[] = { 949 static const char* kPendingEventNames[] = {
927 "SEEK", 950 "SEEK",
928 "SURFACE_CHANGE", 951 "SURFACE_CHANGE",
929 "CONFIG_CHANGE", 952 "CONFIG_CHANGE",
930 "PREFETCH_REQUEST", 953 "PREFETCH_REQUEST",
931 "PREFETCH_DONE", 954 "PREFETCH_DONE",
932 }; 955 };
(...skipping 21 matching lines...) Expand all
954 977
955 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) { 978 void MediaSourcePlayer::ClearPendingEvent(PendingEventFlags event) {
956 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")"; 979 DVLOG(1) << __FUNCTION__ << "(" << GetEventName(event) << ")";
957 DCHECK_NE(event, NO_EVENT_PENDING); 980 DCHECK_NE(event, NO_EVENT_PENDING);
958 DCHECK(IsEventPending(event)) << GetEventName(event); 981 DCHECK(IsEventPending(event)) << GetEventName(event);
959 982
960 pending_event_ &= ~event; 983 pending_event_ &= ~event;
961 } 984 }
962 985
963 } // namespace media 986 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_source_player.h ('k') | media/base/android/media_source_player_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698