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 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 491 |
492 duration_ = duration; | 492 duration_ = duration; |
493 } | 493 } |
494 | 494 |
495 void MediaCodecPlayer::SetDecodersTimeCallbackForTests( | 495 void MediaCodecPlayer::SetDecodersTimeCallbackForTests( |
496 DecodersTimeCallback cb) { | 496 DecodersTimeCallback cb) { |
497 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 497 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
498 decoders_time_cb_ = cb; | 498 decoders_time_cb_ = cb; |
499 } | 499 } |
500 | 500 |
| 501 void MediaCodecPlayer::SetAlwaysReconfigureForTests(DemuxerStream::Type type) { |
| 502 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 503 DCHECK(audio_decoder_ && video_decoder_); |
| 504 |
| 505 if (type == DemuxerStream::AUDIO) |
| 506 audio_decoder_->SetAlwaysReconfigureForTests(); |
| 507 else if (type == DemuxerStream::VIDEO) |
| 508 video_decoder_->SetAlwaysReconfigureForTests(); |
| 509 } |
| 510 |
501 bool MediaCodecPlayer::IsPrerollingForTests(DemuxerStream::Type type) const { | 511 bool MediaCodecPlayer::IsPrerollingForTests(DemuxerStream::Type type) const { |
502 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 512 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
503 DCHECK(audio_decoder_ && video_decoder_); | 513 DCHECK(audio_decoder_ && video_decoder_); |
504 | 514 |
505 if (type == DemuxerStream::AUDIO) | 515 if (type == DemuxerStream::AUDIO) |
506 return audio_decoder_->IsPrerollingForTests(); | 516 return audio_decoder_->IsPrerollingForTests(); |
507 else if (type == DemuxerStream::VIDEO) | 517 else if (type == DemuxerStream::VIDEO) |
508 return video_decoder_->IsPrerollingForTests(); | 518 return video_decoder_->IsPrerollingForTests(); |
509 else | 519 else |
510 return false; | 520 return false; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 597 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
588 DVLOG(1) << __FUNCTION__; | 598 DVLOG(1) << __FUNCTION__; |
589 | 599 |
590 DCHECK(interpolator_.interpolating()); | 600 DCHECK(interpolator_.interpolating()); |
591 | 601 |
592 StartStatus status = StartDecoders(interpolator_.GetInterpolatedTime()); | 602 StartStatus status = StartDecoders(interpolator_.GetInterpolatedTime()); |
593 if (status != kStartOk) | 603 if (status != kStartOk) |
594 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | 604 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
595 } | 605 } |
596 | 606 |
597 void MediaCodecPlayer::OnStopDone() { | 607 void MediaCodecPlayer::OnDecoderDrained(DemuxerStream::Type type) { |
598 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 608 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
599 DVLOG(1) << __FUNCTION__; | 609 DVLOG(1) << __FUNCTION__ << " " << type; |
| 610 |
| 611 // We expect that OnStopDone() comes next. |
| 612 |
| 613 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); |
| 614 DCHECK(state_ == kStatePlaying || state_ == kStateStopping) |
| 615 << __FUNCTION__ << " illegal state: " << AsString(state_); |
| 616 |
| 617 switch (state_) { |
| 618 case kStatePlaying: |
| 619 SetState(kStateStopping); |
| 620 SetPendingStart(true); |
| 621 |
| 622 if (type == DemuxerStream::AUDIO && !VideoFinished()) { |
| 623 DVLOG(1) << __FUNCTION__ << " requesting to stop video"; |
| 624 video_decoder_->SetNeedsPreroll(); |
| 625 video_decoder_->RequestToStop(); |
| 626 } else if (type == DemuxerStream::VIDEO && !AudioFinished()) { |
| 627 DVLOG(1) << __FUNCTION__ << " requesting to stop audio"; |
| 628 audio_decoder_->SetNeedsPreroll(); |
| 629 audio_decoder_->RequestToStop(); |
| 630 } |
| 631 break; |
| 632 |
| 633 case kStateStopping: |
| 634 if (type == DemuxerStream::AUDIO && !VideoFinished()) |
| 635 video_decoder_->SetNeedsPreroll(); |
| 636 else if (type == DemuxerStream::VIDEO && !AudioFinished()) |
| 637 audio_decoder_->SetNeedsPreroll(); |
| 638 break; |
| 639 |
| 640 default: |
| 641 NOTREACHED(); |
| 642 break; |
| 643 } |
| 644 } |
| 645 |
| 646 void MediaCodecPlayer::OnStopDone(DemuxerStream::Type type) { |
| 647 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 648 DVLOG(1) << __FUNCTION__ << " " << type |
| 649 << " interpolated time:" << GetInterpolatedTime(); |
600 | 650 |
601 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { | 651 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { |
602 DVLOG(1) << __FUNCTION__ << " both audio and video has to be stopped" | 652 DVLOG(1) << __FUNCTION__ << " both audio and video has to be stopped" |
603 << ", ignoring"; | 653 << ", ignoring"; |
604 return; // Wait until other stream is stopped | 654 return; // Wait until other stream is stopped |
605 } | 655 } |
606 | 656 |
607 // At this point decoder threads should not be running | 657 // At this point decoder threads should not be running |
608 if (interpolator_.interpolating()) | 658 if (interpolator_.interpolating()) |
609 interpolator_.StopInterpolating(); | 659 interpolator_.StopInterpolating(); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 bool do_audio = false; | 1030 bool do_audio = false; |
981 bool do_video = false; | 1031 bool do_video = false; |
982 | 1032 |
983 if (audio_decoder_->IsPrefetchingOrPlaying()) | 1033 if (audio_decoder_->IsPrefetchingOrPlaying()) |
984 do_audio = true; | 1034 do_audio = true; |
985 if (video_decoder_->IsPrefetchingOrPlaying()) | 1035 if (video_decoder_->IsPrefetchingOrPlaying()) |
986 do_video = true; | 1036 do_video = true; |
987 | 1037 |
988 if (!do_audio && !do_video) { | 1038 if (!do_audio && !do_video) { |
989 GetMediaTaskRunner()->PostTask( | 1039 GetMediaTaskRunner()->PostTask( |
990 FROM_HERE, base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_)); | 1040 FROM_HERE, base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1041 DemuxerStream::UNKNOWN)); |
991 return; | 1042 return; |
992 } | 1043 } |
993 | 1044 |
994 if (do_audio) | 1045 if (do_audio) |
995 audio_decoder_->RequestToStop(); | 1046 audio_decoder_->RequestToStop(); |
996 if (do_video) | 1047 if (do_video) |
997 video_decoder_->RequestToStop(); | 1048 video_decoder_->RequestToStop(); |
998 } | 1049 } |
999 | 1050 |
1000 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, | 1051 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1084 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1034 DVLOG(1) << __FUNCTION__; | 1085 DVLOG(1) << __FUNCTION__; |
1035 | 1086 |
1036 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); | 1087 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); |
1037 | 1088 |
1038 audio_decoder_.reset(new MediaCodecAudioDecoder( | 1089 audio_decoder_.reset(new MediaCodecAudioDecoder( |
1039 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1090 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
1040 media_weak_this_, DemuxerStream::AUDIO), | 1091 media_weak_this_, DemuxerStream::AUDIO), |
1041 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1092 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
1042 DemuxerStream::AUDIO), | 1093 DemuxerStream::AUDIO), |
1043 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), | 1094 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1095 DemuxerStream::AUDIO), |
| 1096 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1097 DemuxerStream::AUDIO), |
1044 internal_error_cb_, | 1098 internal_error_cb_, |
1045 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1099 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
1046 DemuxerStream::AUDIO))); | 1100 DemuxerStream::AUDIO))); |
1047 | 1101 |
1048 video_decoder_.reset(new MediaCodecVideoDecoder( | 1102 video_decoder_.reset(new MediaCodecVideoDecoder( |
1049 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1103 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
1050 media_weak_this_, DemuxerStream::VIDEO), | 1104 media_weak_this_, DemuxerStream::VIDEO), |
1051 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1105 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
1052 DemuxerStream::VIDEO), | 1106 DemuxerStream::VIDEO), |
1053 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), | 1107 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1108 DemuxerStream::VIDEO), |
| 1109 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1110 DemuxerStream::VIDEO), |
1054 internal_error_cb_, | 1111 internal_error_cb_, |
1055 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1112 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
1056 DemuxerStream::VIDEO), | 1113 DemuxerStream::VIDEO), |
1057 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 1114 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
1058 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 1115 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); |
1059 } | 1116 } |
1060 | 1117 |
1061 bool MediaCodecPlayer::AudioFinished() const { | 1118 bool MediaCodecPlayer::AudioFinished() const { |
1062 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 1119 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
1063 } | 1120 } |
(...skipping 24 matching lines...) Expand all Loading... |
1088 RETURN_STRING(kStateWaitingForSurface); | 1145 RETURN_STRING(kStateWaitingForSurface); |
1089 RETURN_STRING(kStateWaitingForSeek); | 1146 RETURN_STRING(kStateWaitingForSeek); |
1090 RETURN_STRING(kStateError); | 1147 RETURN_STRING(kStateError); |
1091 } | 1148 } |
1092 return nullptr; // crash early | 1149 return nullptr; // crash early |
1093 } | 1150 } |
1094 | 1151 |
1095 #undef RETURN_STRING | 1152 #undef RETURN_STRING |
1096 | 1153 |
1097 } // namespace media | 1154 } // namespace media |
OLD | NEW |