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::SetCodecCreatedCallbackForTests( |
| 502 CodecCreatedCallback cb) { |
| 503 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 504 DCHECK(audio_decoder_ && video_decoder_); |
| 505 |
| 506 audio_decoder_->SetCodecCreatedCallbackForTests( |
| 507 base::Bind(cb, DemuxerStream::AUDIO)); |
| 508 video_decoder_->SetCodecCreatedCallbackForTests( |
| 509 base::Bind(cb, DemuxerStream::VIDEO)); |
| 510 } |
| 511 |
| 512 void MediaCodecPlayer::SetAlwaysReconfigureForTests(DemuxerStream::Type type) { |
| 513 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 514 DCHECK(audio_decoder_ && video_decoder_); |
| 515 |
| 516 if (type == DemuxerStream::AUDIO) |
| 517 audio_decoder_->SetAlwaysReconfigureForTests(); |
| 518 else if (type == DemuxerStream::VIDEO) |
| 519 video_decoder_->SetAlwaysReconfigureForTests(); |
| 520 } |
| 521 |
501 bool MediaCodecPlayer::IsPrerollingForTests(DemuxerStream::Type type) const { | 522 bool MediaCodecPlayer::IsPrerollingForTests(DemuxerStream::Type type) const { |
502 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 523 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
503 DCHECK(audio_decoder_ && video_decoder_); | 524 DCHECK(audio_decoder_ && video_decoder_); |
504 | 525 |
505 if (type == DemuxerStream::AUDIO) | 526 if (type == DemuxerStream::AUDIO) |
506 return audio_decoder_->IsPrerollingForTests(); | 527 return audio_decoder_->IsPrerollingForTests(); |
507 else if (type == DemuxerStream::VIDEO) | 528 else if (type == DemuxerStream::VIDEO) |
508 return video_decoder_->IsPrerollingForTests(); | 529 return video_decoder_->IsPrerollingForTests(); |
509 else | 530 else |
510 return false; | 531 return false; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 | 606 |
586 void MediaCodecPlayer::OnPrerollDone() { | 607 void MediaCodecPlayer::OnPrerollDone() { |
587 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 608 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
588 DVLOG(1) << __FUNCTION__; | 609 DVLOG(1) << __FUNCTION__; |
589 | 610 |
590 StartStatus status = StartDecoders(); | 611 StartStatus status = StartDecoders(); |
591 if (status != kStartOk) | 612 if (status != kStartOk) |
592 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); | 613 GetMediaTaskRunner()->PostTask(FROM_HERE, internal_error_cb_); |
593 } | 614 } |
594 | 615 |
595 void MediaCodecPlayer::OnStopDone() { | 616 void MediaCodecPlayer::OnDecoderDrained(DemuxerStream::Type type) { |
596 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 617 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
597 DVLOG(1) << __FUNCTION__; | 618 DVLOG(1) << __FUNCTION__ << " " << type; |
| 619 |
| 620 // We expect that OnStopDone() comes next. |
| 621 |
| 622 DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO); |
| 623 DCHECK(state_ == kStatePlaying || state_ == kStateStopping) |
| 624 << __FUNCTION__ << " illegal state: " << AsString(state_); |
| 625 |
| 626 switch (state_) { |
| 627 case kStatePlaying: |
| 628 SetState(kStateStopping); |
| 629 SetPendingStart(true); |
| 630 |
| 631 if (type == DemuxerStream::AUDIO && !VideoFinished()) { |
| 632 DVLOG(1) << __FUNCTION__ << " requesting to stop video"; |
| 633 video_decoder_->SetDecodingUntilOutputIsPresent(); |
| 634 video_decoder_->RequestToStop(); |
| 635 } else if (type == DemuxerStream::VIDEO && !AudioFinished()) { |
| 636 DVLOG(1) << __FUNCTION__ << " requesting to stop audio"; |
| 637 audio_decoder_->SetDecodingUntilOutputIsPresent(); |
| 638 audio_decoder_->RequestToStop(); |
| 639 } |
| 640 break; |
| 641 |
| 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 NOTREACHED(); |
| 651 break; |
| 652 } |
| 653 } |
| 654 |
| 655 void MediaCodecPlayer::OnStopDone(DemuxerStream::Type type) { |
| 656 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
| 657 DVLOG(1) << __FUNCTION__ << " " << type |
| 658 << " interpolated time:" << GetInterpolatedTime(); |
598 | 659 |
599 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { | 660 if (!(audio_decoder_->IsStopped() && video_decoder_->IsStopped())) { |
600 DVLOG(1) << __FUNCTION__ << " both audio and video has to be stopped" | 661 DVLOG(1) << __FUNCTION__ << " both audio and video has to be stopped" |
601 << ", ignoring"; | 662 << ", ignoring"; |
602 return; // Wait until other stream is stopped | 663 return; // Wait until other stream is stopped |
603 } | 664 } |
604 | 665 |
605 // At this point decoder threads should not be running | 666 // At this point decoder threads should not be running |
606 if (interpolator_.interpolating()) | 667 if (interpolator_.interpolating()) |
607 interpolator_.StopInterpolating(); | 668 interpolator_.StopInterpolating(); |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 bool do_audio = false; | 1055 bool do_audio = false; |
995 bool do_video = false; | 1056 bool do_video = false; |
996 | 1057 |
997 if (audio_decoder_->IsPrefetchingOrPlaying()) | 1058 if (audio_decoder_->IsPrefetchingOrPlaying()) |
998 do_audio = true; | 1059 do_audio = true; |
999 if (video_decoder_->IsPrefetchingOrPlaying()) | 1060 if (video_decoder_->IsPrefetchingOrPlaying()) |
1000 do_video = true; | 1061 do_video = true; |
1001 | 1062 |
1002 if (!do_audio && !do_video) { | 1063 if (!do_audio && !do_video) { |
1003 GetMediaTaskRunner()->PostTask( | 1064 GetMediaTaskRunner()->PostTask( |
1004 FROM_HERE, base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_)); | 1065 FROM_HERE, base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1066 DemuxerStream::UNKNOWN)); |
1005 return; | 1067 return; |
1006 } | 1068 } |
1007 | 1069 |
1008 if (do_audio) | 1070 if (do_audio) |
1009 audio_decoder_->RequestToStop(); | 1071 audio_decoder_->RequestToStop(); |
1010 if (do_video) | 1072 if (do_video) |
1011 video_decoder_->RequestToStop(); | 1073 video_decoder_->RequestToStop(); |
1012 } | 1074 } |
1013 | 1075 |
1014 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, | 1076 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); | 1109 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); |
1048 DVLOG(1) << __FUNCTION__; | 1110 DVLOG(1) << __FUNCTION__; |
1049 | 1111 |
1050 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); | 1112 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); |
1051 | 1113 |
1052 audio_decoder_.reset(new MediaCodecAudioDecoder( | 1114 audio_decoder_.reset(new MediaCodecAudioDecoder( |
1053 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1115 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
1054 media_weak_this_, DemuxerStream::AUDIO), | 1116 media_weak_this_, DemuxerStream::AUDIO), |
1055 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1117 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
1056 DemuxerStream::AUDIO), | 1118 DemuxerStream::AUDIO), |
1057 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), | 1119 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1120 DemuxerStream::AUDIO), |
| 1121 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1122 DemuxerStream::AUDIO), |
1058 internal_error_cb_, | 1123 internal_error_cb_, |
1059 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1124 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
1060 DemuxerStream::AUDIO))); | 1125 DemuxerStream::AUDIO))); |
1061 | 1126 |
1062 video_decoder_.reset(new MediaCodecVideoDecoder( | 1127 video_decoder_.reset(new MediaCodecVideoDecoder( |
1063 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, | 1128 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, |
1064 media_weak_this_, DemuxerStream::VIDEO), | 1129 media_weak_this_, DemuxerStream::VIDEO), |
1065 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, | 1130 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, |
1066 DemuxerStream::VIDEO), | 1131 DemuxerStream::VIDEO), |
1067 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), | 1132 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_, |
| 1133 DemuxerStream::VIDEO), |
| 1134 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_, |
| 1135 DemuxerStream::VIDEO), |
1068 internal_error_cb_, | 1136 internal_error_cb_, |
1069 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, | 1137 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, |
1070 DemuxerStream::VIDEO), | 1138 DemuxerStream::VIDEO), |
1071 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), | 1139 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), |
1072 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); | 1140 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); |
1073 } | 1141 } |
1074 | 1142 |
1075 bool MediaCodecPlayer::AudioFinished() const { | 1143 bool MediaCodecPlayer::AudioFinished() const { |
1076 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); | 1144 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); |
1077 } | 1145 } |
(...skipping 24 matching lines...) Expand all Loading... |
1102 RETURN_STRING(kStateWaitingForSurface); | 1170 RETURN_STRING(kStateWaitingForSurface); |
1103 RETURN_STRING(kStateWaitingForSeek); | 1171 RETURN_STRING(kStateWaitingForSeek); |
1104 RETURN_STRING(kStateError); | 1172 RETURN_STRING(kStateError); |
1105 } | 1173 } |
1106 return nullptr; // crash early | 1174 return nullptr; // crash early |
1107 } | 1175 } |
1108 | 1176 |
1109 #undef RETURN_STRING | 1177 #undef RETURN_STRING |
1110 | 1178 |
1111 } // namespace media | 1179 } // namespace media |
OLD | NEW |