OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_codec_player.h" | 5 #include "media/base/android/media_codec_player.h" |
6 | 6 |
7 #include "base/barrier_closure.h" | 7 #include "base/barrier_closure.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 seek_info_->seek_time <= actual_browser_seek_time); | 434 seek_info_->seek_time <= actual_browser_seek_time); |
435 | 435 |
436 // Restrict the current time to be equal to seek_time | 436 // Restrict the current time to be equal to seek_time |
437 // for the next StartPlaybackDecoders() call. | 437 // for the next StartPlaybackDecoders() call. |
438 | 438 |
439 base::TimeDelta seek_time = seek_info_->is_browser_seek | 439 base::TimeDelta seek_time = seek_info_->is_browser_seek |
440 ? actual_browser_seek_time | 440 ? actual_browser_seek_time |
441 : seek_info_->seek_time; | 441 : seek_info_->seek_time; |
442 | 442 |
443 interpolator_.SetBounds(seek_time, seek_time); | 443 interpolator_.SetBounds(seek_time, seek_time); |
444 | |
444 audio_decoder_->SetBaseTimestamp(seek_time); | 445 audio_decoder_->SetBaseTimestamp(seek_time); |
445 | 446 |
447 audio_decoder_->SetPrerollTimestamp(seek_time); | |
448 video_decoder_->SetPrerollTimestamp(seek_time); | |
449 | |
446 // The Flush() might set the state to kStateError. | 450 // The Flush() might set the state to kStateError. |
447 if (state_ == kStateError) { | 451 if (state_ == kStateError) { |
448 // Notify the Renderer. | 452 // Notify the Renderer. |
449 if (!seek_info_->is_browser_seek) | 453 if (!seek_info_->is_browser_seek) |
450 ui_task_runner_->PostTask(FROM_HERE, | 454 ui_task_runner_->PostTask(FROM_HERE, |
451 base::Bind(seek_done_cb_, seek_time)); | 455 base::Bind(seek_done_cb_, seek_time)); |
452 | 456 |
453 seek_info_.reset(); | 457 seek_info_.reset(); |
454 return; | 458 return; |
455 } | 459 } |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
601 } | 605 } |
602 | 606 |
603 SetState(kStatePlaying); | 607 SetState(kStatePlaying); |
604 StartPlaybackOrBrowserSeek(); | 608 StartPlaybackOrBrowserSeek(); |
605 } | 609 } |
606 | 610 |
607 void MediaCodecPlayer::OnPrerollDone() { | 611 void MediaCodecPlayer::OnPrerollDone() { |
608 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 612 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
609 DVLOG(1) << __FUNCTION__; | 613 DVLOG(1) << __FUNCTION__; |
610 | 614 |
615 if (state_ != kStatePlaying) { | |
616 DVLOG(1) << __FUNCTION__ << ": in state " << AsString(state_) | |
617 << ", ignoring"; | |
618 return; | |
619 } | |
620 | |
611 StartStatus status = StartDecoders(); | 621 StartStatus status = StartDecoders(); |
612 if (status != kStartOk) | 622 if (status != kStartOk) |
613 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | 623 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
614 } | 624 } |
615 | 625 |
616 void MediaCodecPlayer::OnDecoderDrained(DemuxerStream::Type type) { | 626 void MediaCodecPlayer::OnDecoderDrained(DemuxerStream::Type type) { |
617 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 627 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
618 DVLOG(1) << __FUNCTION__ << " " << type; | 628 DVLOG(1) << __FUNCTION__ << " " << type; |
619 | 629 |
620 // We expect that OnStopDone() comes next. | 630 // We expect that OnStopDone() comes next. |
621 | 631 |
622 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); | 632 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); |
623 DCHECK(state_ == kStatePlaying || state_ == kStateStopping) | 633 DCHECK(state_ == kStatePlaying || state_ == kStateStopping) |
624 << __FUNCTION__ << " illegal state: " << AsString(state_); | 634 << __FUNCTION__ << " illegal state: " << AsString(state_); |
625 | 635 |
626 switch (state_) { | 636 switch (state_) { |
627 case kStatePlaying: | 637 case kStatePlaying: |
628 SetState(kStateStopping); | 638 SetState(kStateStopping); |
629 SetPendingStart(true); | 639 SetPendingStart(true); |
630 | 640 |
631 if (type == DemuxerStream::AUDIO && !VideoFinished()) { | 641 if (type == DemuxerStream::AUDIO && !VideoFinished()) { |
632 DVLOG(1) << __FUNCTION__ << " requesting to stop video"; | 642 DVLOG(1) << __FUNCTION__ << " requesting to stop video"; |
633 video_decoder_->SetDecodingUntilOutputIsPresent(); | |
634 video_decoder_->RequestToStop(); | 643 video_decoder_->RequestToStop(); |
635 } else if (type == DemuxerStream::VIDEO && !AudioFinished()) { | 644 } else if (type == DemuxerStream::VIDEO && !AudioFinished()) { |
636 DVLOG(1) << __FUNCTION__ << " requesting to stop audio"; | 645 DVLOG(1) << __FUNCTION__ << " requesting to stop audio"; |
637 audio_decoder_->SetDecodingUntilOutputIsPresent(); | |
638 audio_decoder_->RequestToStop(); | 646 audio_decoder_->RequestToStop(); |
639 } | 647 } |
640 break; | 648 break; |
641 | 649 |
642 case kStateStopping: | |
643 if (type == DemuxerStream::AUDIO && !VideoFinished()) | |
644 video_decoder_->SetDecodingUntilOutputIsPresent(); | |
645 else if (type == DemuxerStream::VIDEO && !AudioFinished()) | |
646 audio_decoder_->SetDecodingUntilOutputIsPresent(); | |
647 break; | |
648 | |
649 default: | 650 default: |
650 NOTREACHED(); | |
651 break; | 651 break; |
652 } | 652 } |
653 } | 653 } |
654 | 654 |
655 void MediaCodecPlayer::OnStopDone(DemuxerStream::Type type) { | 655 void MediaCodecPlayer::OnStopDone(DemuxerStream::Type type) { |
656 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 656 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
657 DVLOG(1) << __FUNCTION__ << " " << type | 657 DVLOG(1) << __FUNCTION__ << " " << type |
658 << " interpolated time:" << GetInterpolatedTime(); | 658 << " interpolated time:" << GetInterpolatedTime(); |
659 | 659 |
660 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { | 660 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
956 } | 956 } |
957 } | 957 } |
958 | 958 |
959 return kStartOk; | 959 return kStartOk; |
960 } | 960 } |
961 | 961 |
962 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( | 962 MediaCodecPlayer::StartStatus MediaCodecPlayer::MaybePrerollDecoders( |
963 bool* preroll_required) { | 963 bool* preroll_required) { |
964 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 964 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
965 | 965 |
966 base::TimeDelta current_time = GetInterpolatedTime(); | 966 DVLOG(1) << __FUNCTION__ << " current_time:" << GetInterpolatedTime(); |
967 | |
968 DVLOG(1) << __FUNCTION__ << " current_time:" << current_time; | |
969 | 967 |
970 // If requested, preroll is always done in the beginning of the playback, | 968 // If requested, preroll is always done in the beginning of the playback, |
971 // after prefetch. The request might not happen at all though, in which case | 969 // after prefetch. The request might not happen at all though, in which case |
972 // we won't have prerolling phase. We need the prerolling when we (re)create | 970 // we won't have prerolling phase. We need the prerolling when we (re)create |
973 // the decoder, because its configuration and initialization (getting input, | 971 // the decoder, because its configuration and initialization (getting input, |
974 // but not making output) can take time, and after the seek because there | 972 // but not making output) can take time, and after the seek because there |
975 // could be some data to be skipped and there is again initialization after | 973 // could be some data to be skipped and there is again initialization after |
976 // the flush. | 974 // the flush. |
977 | 975 |
978 *preroll_required = false; | 976 *preroll_required = false; |
979 | 977 |
980 int count = 0; | 978 int count = 0; |
981 const bool do_audio_preroll = audio_decoder_->NotCompletedAndNeedsPreroll(); | 979 const bool do_audio = audio_decoder_->NotCompletedAndNeedsPreroll(); |
982 if (do_audio_preroll) | 980 if (do_audio) |
983 ++count; | 981 ++count; |
984 | 982 |
985 const bool do_video_preroll = video_decoder_->NotCompletedAndNeedsPreroll(); | 983 const bool do_video = video_decoder_->NotCompletedAndNeedsPreroll(); |
986 if (do_video_preroll) | 984 if (do_video) |
987 ++count; | 985 ++count; |
988 | 986 |
989 if (count == 0) { | 987 if (count == 0) { |
990 DVLOG(1) << __FUNCTION__ << ": preroll is not required, skipping"; | 988 DVLOG(1) << __FUNCTION__ << ": preroll is not required, skipping"; |
991 return kStartOk; | 989 return kStartOk; |
992 } | 990 } |
993 | 991 |
994 *preroll_required = true; | 992 *preroll_required = true; |
995 | 993 |
996 DCHECK(count > 0); | 994 DCHECK(count > 0); |
997 DCHECK(do_audio_preroll || do_video_preroll); | 995 DCHECK(do_audio || do_video); |
998 | 996 |
999 DVLOG(1) << __FUNCTION__ << ": preroll for " << count << " stream(s)"; | 997 DVLOG(1) << __FUNCTION__ << ": preroll for " << count << " stream(s)"; |
1000 | 998 |
1001 base::Closure preroll_cb = base::BarrierClosure( | 999 base::Closure preroll_cb = base::BarrierClosure( |
1002 count, base::Bind(&MediaCodecPlayer::OnPrerollDone, media_weak_this_)); | 1000 count, base::Bind(&MediaCodecPlayer::OnPrerollDone, media_weak_this_)); |
1003 | 1001 |
1004 if (do_audio_preroll) { | 1002 if (do_audio) { |
qinmin
2015/09/03 05:30:04
simply if (do_audio && !audio_decoder_->Preroll(p
Tima Vaisburd
2015/09/03 19:55:27
Done.
| |
1005 if (!audio_decoder_->Preroll(current_time, preroll_cb)) | 1003 if (!audio_decoder_->Preroll(preroll_cb)) |
1006 return kStartFailed; | 1004 return kStartFailed; |
1007 } | 1005 } |
1008 | 1006 |
1009 if (do_video_preroll) { | 1007 if (do_video) { |
qinmin
2015/09/03 05:30:04
ditto
Tima Vaisburd
2015/09/03 19:55:27
Done.
| |
1010 if (!video_decoder_->Preroll(current_time, preroll_cb)) | 1008 if (!video_decoder_->Preroll(preroll_cb)) |
1011 return kStartFailed; | 1009 return kStartFailed; |
1012 } | 1010 } |
1013 | 1011 |
1014 return kStartOk; | 1012 return kStartOk; |
1015 } | 1013 } |
1016 | 1014 |
1017 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartDecoders() { | 1015 MediaCodecPlayer::StartStatus MediaCodecPlayer::StartDecoders() { |
1018 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1016 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1019 | 1017 |
1020 if (!interpolator_.interpolating()) | 1018 if (!interpolator_.interpolating()) |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1170 RETURN_STRING(kStateWaitingForSurface); | 1168 RETURN_STRING(kStateWaitingForSurface); |
1171 RETURN_STRING(kStateWaitingForSeek); | 1169 RETURN_STRING(kStateWaitingForSeek); |
1172 RETURN_STRING(kStateError); | 1170 RETURN_STRING(kStateError); |
1173 } | 1171 } |
1174 return nullptr; // crash early | 1172 return nullptr; // crash early |
1175 } | 1173 } |
1176 | 1174 |
1177 #undef RETURN_STRING | 1175 #undef RETURN_STRING |
1178 | 1176 |
1179 } // namespace media | 1177 } // namespace media |
OLD | NEW |