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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 | 425 |
426 // Restrict the current time to be equal to seek_time | 426 // Restrict the current time to be equal to seek_time |
427 // for the next StartPlaybackDecoders() call. | 427 // for the next StartPlaybackDecoders() call. |
428 | 428 |
429 base::TimeDelta seek_time = seek_info_->is_browser_seek | 429 base::TimeDelta seek_time = seek_info_->is_browser_seek |
430 ? actual_browser_seek_time | 430 ? actual_browser_seek_time |
431 : seek_info_->seek_time; | 431 : seek_info_->seek_time; |
432 | 432 |
433 interpolator_.SetBounds(seek_time, seek_time); | 433 interpolator_.SetBounds(seek_time, seek_time); |
434 audio_decoder_->SetBaseTimestamp(seek_time); | 434 audio_decoder_->SetBaseTimestamp(seek_time); |
| 435 audio_decoder_->SetNeedsPreroll(true); |
| 436 video_decoder_->SetNeedsPreroll(true); |
435 | 437 |
436 // The Flush() might set the state to kStateError. | 438 // The Flush() might set the state to kStateError. |
437 if (state_ == kStateError) { | 439 if (state_ == kStateError) { |
438 // Notify the Renderer. | 440 // Notify the Renderer. |
439 if (!seek_info_->is_browser_seek) | 441 if (!seek_info_->is_browser_seek) |
440 ui_task_runner_->PostTask(FROM_HERE, | 442 ui_task_runner_->PostTask(FROM_HERE, |
441 base::Bind(seek_done_cb_, seek_time)); | 443 base::Bind(seek_done_cb_, seek_time)); |
442 | 444 |
443 seek_info_.reset(); | 445 seek_info_.reset(); |
444 return; | 446 return; |
(...skipping 30 matching lines...) Expand all Loading... |
475 } | 477 } |
476 | 478 |
477 void MediaCodecPlayer::OnDemuxerDurationChanged( | 479 void MediaCodecPlayer::OnDemuxerDurationChanged( |
478 base::TimeDelta duration) { | 480 base::TimeDelta duration) { |
479 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 481 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
480 DVLOG(1) << __FUNCTION__ << " duration:" << duration; | 482 DVLOG(1) << __FUNCTION__ << " duration:" << duration; |
481 | 483 |
482 duration_ = duration; | 484 duration_ = duration; |
483 } | 485 } |
484 | 486 |
| 487 void MediaCodecPlayer::SetDecodersTimeCallbackForTests( |
| 488 DecodersTimeCallback cb) { |
| 489 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 490 decoders_time_cb_ = cb; |
| 491 } |
| 492 |
| 493 bool MediaCodecPlayer::IsPrerollingForTests(DemuxerStream::Type type) const { |
| 494 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 495 DCHECK(audio_decoder_ && video_decoder_); |
| 496 |
| 497 if (type == DemuxerStream::AUDIO) |
| 498 return audio_decoder_->IsPrerollingForTests(); |
| 499 else if (type == DemuxerStream::VIDEO) |
| 500 return video_decoder_->IsPrerollingForTests(); |
| 501 else |
| 502 return false; |
| 503 } |
| 504 |
485 // Events from Player, called on UI thread | 505 // Events from Player, called on UI thread |
486 | 506 |
487 void MediaCodecPlayer::OnMediaMetadataChanged(base::TimeDelta duration, | 507 void MediaCodecPlayer::OnMediaMetadataChanged(base::TimeDelta duration, |
488 const gfx::Size& video_size) { | 508 const gfx::Size& video_size) { |
489 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 509 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
490 | 510 |
491 if (duration != kNoTimestamp()) | 511 if (duration != kNoTimestamp()) |
492 metadata_cache_.duration = duration; | 512 metadata_cache_.duration = duration; |
493 | 513 |
494 if (!video_size.IsEmpty()) | 514 if (!video_size.IsEmpty()) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 | 568 |
549 if (HasVideo() && !video_decoder_->HasVideoSurface()) { | 569 if (HasVideo() && !video_decoder_->HasVideoSurface()) { |
550 SetState(kStateWaitingForSurface); | 570 SetState(kStateWaitingForSurface); |
551 return; | 571 return; |
552 } | 572 } |
553 | 573 |
554 SetState(kStatePlaying); | 574 SetState(kStatePlaying); |
555 StartPlaybackOrBrowserSeek(); | 575 StartPlaybackOrBrowserSeek(); |
556 } | 576 } |
557 | 577 |
| 578 void MediaCodecPlayer::OnPrerollDone() { |
| 579 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 580 DVLOG(1) << __FUNCTION__; |
| 581 |
| 582 if (!(audio_decoder_->IsPrerollDone() && video_decoder_->IsPrerollDone())) { |
| 583 DVLOG(1) << __FUNCTION__ << " both audio and video needs to be done" |
| 584 << " prerolling, ignoring"; |
| 585 return; // Wait until both streams are done prerolling. |
| 586 } |
| 587 |
| 588 if (!AudioFinished()) |
| 589 audio_decoder_->ResumeAfterPreroll(); |
| 590 if (!VideoFinished()) |
| 591 video_decoder_->ResumeAfterPreroll(); |
| 592 } |
| 593 |
558 void MediaCodecPlayer::OnStopDone() { | 594 void MediaCodecPlayer::OnStopDone() { |
559 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 595 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
560 DVLOG(1) << __FUNCTION__; | 596 DVLOG(1) << __FUNCTION__; |
561 | 597 |
562 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) | 598 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { |
| 599 DVLOG(1) << __FUNCTION__ << " both audio and video has to be stopped" |
| 600 << ", ignoring"; |
563 return; // Wait until other stream is stopped | 601 return; // Wait until other stream is stopped |
| 602 } |
564 | 603 |
565 // At this point decoder threads should not be running | 604 // At this point decoder threads should not be running |
566 if (interpolator_.interpolating()) | 605 if (interpolator_.interpolating()) |
567 interpolator_.StopInterpolating(); | 606 interpolator_.StopInterpolating(); |
568 | 607 |
569 base::TimeDelta seek_time; | 608 base::TimeDelta seek_time; |
570 switch (state_) { | 609 switch (state_) { |
571 case kStateStopping: { | 610 case kStateStopping: { |
572 base::TimeDelta seek_time = GetPendingSeek(); | 611 base::TimeDelta seek_time = GetPendingSeek(); |
573 if (seek_time != kNoTimestamp()) { | 612 if (seek_time != kNoTimestamp()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 } | 668 } |
630 | 669 |
631 void MediaCodecPlayer::OnTimeIntervalUpdate(DemuxerStream::Type type, | 670 void MediaCodecPlayer::OnTimeIntervalUpdate(DemuxerStream::Type type, |
632 base::TimeDelta now_playing, | 671 base::TimeDelta now_playing, |
633 base::TimeDelta last_buffered) { | 672 base::TimeDelta last_buffered) { |
634 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 673 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
635 | 674 |
636 DVLOG(2) << __FUNCTION__ << ": stream type:" << type << " [" << now_playing | 675 DVLOG(2) << __FUNCTION__ << ": stream type:" << type << " [" << now_playing |
637 << "," << last_buffered << "]"; | 676 << "," << last_buffered << "]"; |
638 | 677 |
| 678 // For testing only: report time interval as we receive it from decoders |
| 679 // as an indication of what is being rendered. |
| 680 if (!decoders_time_cb_.is_null()) { |
| 681 ui_task_runner_->PostTask( |
| 682 FROM_HERE, |
| 683 base::Bind(decoders_time_cb_, type, now_playing, last_buffered)); |
| 684 } |
| 685 |
639 // I assume that audio stream cannot be added after we get configs by | 686 // I assume that audio stream cannot be added after we get configs by |
640 // OnDemuxerConfigsAvailable(), but that audio can finish early. | 687 // OnDemuxerConfigsAvailable(), but that audio can finish early. |
641 | 688 |
642 if (type == DemuxerStream::VIDEO) { | 689 if (type == DemuxerStream::VIDEO) { |
643 // Ignore video PTS if there is audio stream or if it's behind current | 690 // Ignore video PTS if there is audio stream or if it's behind current |
644 // time as set by audio stream. | 691 // time as set by audio stream. |
645 if (!AudioFinished() || now_playing < interpolator_.GetInterpolatedTime()) | 692 if (!AudioFinished() || |
| 693 (HasAudio() && now_playing < interpolator_.GetInterpolatedTime())) |
646 return; | 694 return; |
647 } | 695 } |
648 | 696 |
649 interpolator_.SetBounds(now_playing, last_buffered); | 697 interpolator_.SetBounds(now_playing, last_buffered); |
650 | 698 |
651 // Post to UI thread | 699 // Post to UI thread |
652 ui_task_runner_->PostTask(FROM_HERE, | 700 ui_task_runner_->PostTask(FROM_HERE, |
653 base::Bind(time_update_cb_, GetInterpolatedTime(), | 701 base::Bind(time_update_cb_, GetInterpolatedTime(), |
654 base::TimeTicks::Now())); | 702 base::TimeTicks::Now())); |
655 } | 703 } |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 963 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
916 DVLOG(1) << __FUNCTION__; | 964 DVLOG(1) << __FUNCTION__; |
917 | 965 |
918 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); | 966 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); |
919 | 967 |
920 audio_decoder_.reset(new MediaCodecAudioDecoder( | 968 audio_decoder_.reset(new MediaCodecAudioDecoder( |
921 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 969 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
922 media_weak_this_, DemuxerStream::AUDIO), | 970 media_weak_this_, DemuxerStream::AUDIO), |
923 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 971 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
924 DemuxerStream::AUDIO), | 972 DemuxerStream::AUDIO), |
| 973 base::Bind(&MediaCodecPlayer::OnPrerollDone, media_weak_this_), |
925 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), | 974 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), |
926 internal_error_cb_, | 975 internal_error_cb_, |
927 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 976 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
928 DemuxerStream::AUDIO))); | 977 DemuxerStream::AUDIO))); |
929 | 978 |
930 video_decoder_.reset(new MediaCodecVideoDecoder( | 979 video_decoder_.reset(new MediaCodecVideoDecoder( |
931 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 980 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
932 media_weak_this_, DemuxerStream::VIDEO), | 981 media_weak_this_, DemuxerStream::VIDEO), |
933 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 982 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
934 DemuxerStream::VIDEO), | 983 DemuxerStream::VIDEO), |
| 984 base::Bind(&MediaCodecPlayer::OnPrerollDone, media_weak_this_), |
935 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), | 985 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), |
936 internal_error_cb_, | 986 internal_error_cb_, |
937 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 987 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
938 DemuxerStream::VIDEO), | 988 DemuxerStream::VIDEO), |
939 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 989 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
940 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 990 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); |
941 } | 991 } |
942 | 992 |
943 bool MediaCodecPlayer::AudioFinished() const { | 993 bool MediaCodecPlayer::AudioFinished() const { |
944 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 994 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
(...skipping 25 matching lines...) Expand all Loading... |
970 RETURN_STRING(kStateWaitingForSurface); | 1020 RETURN_STRING(kStateWaitingForSurface); |
971 RETURN_STRING(kStateWaitingForSeek); | 1021 RETURN_STRING(kStateWaitingForSeek); |
972 RETURN_STRING(kStateError); | 1022 RETURN_STRING(kStateError); |
973 } | 1023 } |
974 return nullptr; // crash early | 1024 return nullptr; // crash early |
975 } | 1025 } |
976 | 1026 |
977 #undef RETURN_STRING | 1027 #undef RETURN_STRING |
978 | 1028 |
979 } // namespace media | 1029 } // namespace media |
OLD | NEW |