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

Side by Side Diff: media/base/android/media_codec_player.cc

Issue 1287423004: MediaCodecPlayer implementation (stage 5 - reconfiguration) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-cleanuptest
Patch Set: Avoid potential frame skipping after decoder drain with a new prerolling mode Created 5 years, 3 months 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
OLDNEW
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
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
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_->SetPrerollTillNextFrame();
634 video_decoder_->RequestToStop();
635 } else if (type == DemuxerStream::VIDEO && !AudioFinished()) {
636 DVLOG(1) << __FUNCTION__ << " requesting to stop audio";
637 audio_decoder_->SetPrerollTillNextFrame();
638 audio_decoder_->RequestToStop();
639 }
640 break;
641
642 case kStateStopping:
643 if (type == DemuxerStream::AUDIO && !VideoFinished())
644 video_decoder_->SetPrerollTillNextFrame();
645 else if (type == DemuxerStream::VIDEO && !AudioFinished())
646 audio_decoder_->SetPrerollTillNextFrame();
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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 bool do_audio = false; 1054 bool do_audio = false;
994 bool do_video = false; 1055 bool do_video = false;
995 1056
996 if (audio_decoder_->IsPrefetchingOrPlaying()) 1057 if (audio_decoder_->IsPrefetchingOrPlaying())
997 do_audio = true; 1058 do_audio = true;
998 if (video_decoder_->IsPrefetchingOrPlaying()) 1059 if (video_decoder_->IsPrefetchingOrPlaying())
999 do_video = true; 1060 do_video = true;
1000 1061
1001 if (!do_audio && !do_video) { 1062 if (!do_audio && !do_video) {
1002 GetMediaTaskRunner()->PostTask( 1063 GetMediaTaskRunner()->PostTask(
1003 FROM_HERE, base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_)); 1064 FROM_HERE, base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1065 DemuxerStream::UNKNOWN));
1004 return; 1066 return;
1005 } 1067 }
1006 1068
1007 if (do_audio) 1069 if (do_audio)
1008 audio_decoder_->RequestToStop(); 1070 audio_decoder_->RequestToStop();
1009 if (do_video) 1071 if (do_video)
1010 video_decoder_->RequestToStop(); 1072 video_decoder_->RequestToStop();
1011 } 1073 }
1012 1074
1013 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time, 1075 void MediaCodecPlayer::RequestDemuxerSeek(base::TimeDelta seek_time,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread()); 1108 DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
1047 DVLOG(1) << __FUNCTION__; 1109 DVLOG(1) << __FUNCTION__;
1048 1110
1049 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_); 1111 internal_error_cb_ = base::Bind(&MediaCodecPlayer::OnError, media_weak_this_);
1050 1112
1051 audio_decoder_.reset(new MediaCodecAudioDecoder( 1113 audio_decoder_.reset(new MediaCodecAudioDecoder(
1052 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 1114 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
1053 media_weak_this_, DemuxerStream::AUDIO), 1115 media_weak_this_, DemuxerStream::AUDIO),
1054 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 1116 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
1055 DemuxerStream::AUDIO), 1117 DemuxerStream::AUDIO),
1056 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), 1118 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_,
1119 DemuxerStream::AUDIO),
1120 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1121 DemuxerStream::AUDIO),
1057 internal_error_cb_, 1122 internal_error_cb_,
1058 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 1123 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
1059 DemuxerStream::AUDIO))); 1124 DemuxerStream::AUDIO)));
1060 1125
1061 video_decoder_.reset(new MediaCodecVideoDecoder( 1126 video_decoder_.reset(new MediaCodecVideoDecoder(
1062 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData, 1127 GetMediaTaskRunner(), base::Bind(&MediaCodecPlayer::RequestDemuxerData,
1063 media_weak_this_, DemuxerStream::VIDEO), 1128 media_weak_this_, DemuxerStream::VIDEO),
1064 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_, 1129 base::Bind(&MediaCodecPlayer::OnStarvation, media_weak_this_,
1065 DemuxerStream::VIDEO), 1130 DemuxerStream::VIDEO),
1066 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_), 1131 base::Bind(&MediaCodecPlayer::OnDecoderDrained, media_weak_this_,
1132 DemuxerStream::VIDEO),
1133 base::Bind(&MediaCodecPlayer::OnStopDone, media_weak_this_,
1134 DemuxerStream::VIDEO),
1067 internal_error_cb_, 1135 internal_error_cb_,
1068 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_, 1136 base::Bind(&MediaCodecPlayer::OnTimeIntervalUpdate, media_weak_this_,
1069 DemuxerStream::VIDEO), 1137 DemuxerStream::VIDEO),
1070 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_), 1138 base::Bind(&MediaCodecPlayer::OnVideoResolutionChanged, media_weak_this_),
1071 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_))); 1139 base::Bind(&MediaCodecPlayer::OnVideoCodecCreated, media_weak_this_)));
1072 } 1140 }
1073 1141
1074 bool MediaCodecPlayer::AudioFinished() const { 1142 bool MediaCodecPlayer::AudioFinished() const {
1075 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream(); 1143 return audio_decoder_->IsCompleted() || !audio_decoder_->HasStream();
1076 } 1144 }
(...skipping 24 matching lines...) Expand all
1101 RETURN_STRING(kStateWaitingForSurface); 1169 RETURN_STRING(kStateWaitingForSurface);
1102 RETURN_STRING(kStateWaitingForSeek); 1170 RETURN_STRING(kStateWaitingForSeek);
1103 RETURN_STRING(kStateError); 1171 RETURN_STRING(kStateError);
1104 } 1172 }
1105 return nullptr; // crash early 1173 return nullptr; // crash early
1106 } 1174 }
1107 1175
1108 #undef RETURN_STRING 1176 #undef RETURN_STRING
1109 1177
1110 } // namespace media 1178 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698