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

Side by Side Diff: media/base/pipeline.cc

Issue 10836167: Move VideoDecoder initialization into VideoRendererBase. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/pipeline.h" 5 #include "media/base/pipeline.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 } 56 }
57 57
58 media::PipelineStatus PipelineStatusNotification::status() { 58 media::PipelineStatus PipelineStatusNotification::status() {
59 base::AutoLock auto_lock(lock_); 59 base::AutoLock auto_lock(lock_);
60 DCHECK(notified_); 60 DCHECK(notified_);
61 return status_; 61 return status_;
62 } 62 }
63 63
64 struct Pipeline::PipelineInitState { 64 struct Pipeline::PipelineInitState {
65 scoped_refptr<AudioDecoder> audio_decoder; 65 scoped_refptr<AudioDecoder> audio_decoder;
66 scoped_refptr<VideoDecoder> video_decoder;
67 }; 66 };
68 67
69 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) 68 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log)
70 : message_loop_(message_loop->message_loop_proxy()), 69 : message_loop_(message_loop->message_loop_proxy()),
71 media_log_(media_log), 70 media_log_(media_log),
72 running_(false), 71 running_(false),
73 seek_pending_(false), 72 seek_pending_(false),
74 tearing_down_(false), 73 tearing_down_(false),
75 playback_rate_change_pending_(false), 74 playback_rate_change_pending_(false),
76 did_loading_progress_(false), 75 did_loading_progress_(false),
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 // FilterHost's InitializationComplete() method, the pipeline will update its 576 // FilterHost's InitializationComplete() method, the pipeline will update its
578 // state to kStarted and |init_cb_|, will be executed. 577 // state to kStarted and |init_cb_|, will be executed.
579 // 578 //
580 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It 579 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It
581 // works like a big state change table. If we no longer need to start filters 580 // works like a big state change table. If we no longer need to start filters
582 // in order, we need to get rid of all the state change. 581 // in order, we need to get rid of all the state change.
583 void Pipeline::InitializeTask(PipelineStatus last_stage_status) { 582 void Pipeline::InitializeTask(PipelineStatus last_stage_status) {
584 DCHECK(message_loop_->BelongsToCurrentThread()); 583 DCHECK(message_loop_->BelongsToCurrentThread());
585 584
586 if (last_stage_status != PIPELINE_OK) { 585 if (last_stage_status != PIPELINE_OK) {
587 // Currently only VideoDecoders have a recoverable error code. 586 SetError(last_stage_status);
588 if (state_ == kInitVideoDecoder && 587 return;
589 last_stage_status == DECODER_ERROR_NOT_SUPPORTED) {
590 state_ = kInitAudioRenderer;
591 } else {
592 SetError(last_stage_status);
593 return;
594 }
595 } 588 }
596 589
597 // If we have received the stop or error signal, return immediately. 590 // If we have received the stop or error signal, return immediately.
598 if (!stop_cb_.is_null() || state_ == kStopped || !IsPipelineOk()) 591 if (!stop_cb_.is_null() || state_ == kStopped || !IsPipelineOk())
599 return; 592 return;
600 593
601 DCHECK(state_ == kInitDemuxer || 594 DCHECK(state_ == kInitDemuxer ||
602 state_ == kInitAudioDecoder || 595 state_ == kInitAudioDecoder ||
603 state_ == kInitAudioRenderer || 596 state_ == kInitAudioRenderer ||
604 state_ == kInitVideoDecoder ||
605 state_ == kInitVideoRenderer); 597 state_ == kInitVideoRenderer);
606 598
607 // Demuxer created, create audio decoder. 599 // Demuxer created, create audio decoder.
608 if (state_ == kInitDemuxer) { 600 if (state_ == kInitDemuxer) {
609 SetState(kInitAudioDecoder); 601 SetState(kInitAudioDecoder);
610 // If this method returns false, then there's no audio stream. 602 // If this method returns false, then there's no audio stream.
611 if (InitializeAudioDecoder(demuxer_)) 603 if (InitializeAudioDecoder(demuxer_))
612 return; 604 return;
613 } 605 }
614 606
615 // Assuming audio decoder was created, create audio renderer. 607 // Assuming audio decoder was created, create audio renderer.
616 if (state_ == kInitAudioDecoder) { 608 if (state_ == kInitAudioDecoder) {
617 SetState(kInitAudioRenderer); 609 SetState(kInitAudioRenderer);
618 610
619 // Returns false if there's no audio stream. 611 // Returns false if there's no audio stream.
620 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder)) { 612 if (InitializeAudioRenderer(pipeline_init_state_->audio_decoder)) {
621 base::AutoLock auto_lock(lock_); 613 base::AutoLock auto_lock(lock_);
622 has_audio_ = true; 614 has_audio_ = true;
623 return; 615 return;
624 } 616 }
625 } 617 }
626 618
627 // Assuming audio renderer was created, create video decoder. 619 // Assuming audio renderer was created, create video renderer.
628 if (state_ == kInitAudioRenderer) { 620 if (state_ == kInitAudioRenderer) {
629 // Then perform the stage of initialization, i.e. initialize video decoder.
630 SetState(kInitVideoDecoder);
631 if (InitializeVideoDecoder(demuxer_))
632 return;
633 }
634
635 // Assuming video decoder was created, create video renderer.
636 if (state_ == kInitVideoDecoder) {
637 SetState(kInitVideoRenderer); 621 SetState(kInitVideoRenderer);
638 if (InitializeVideoRenderer(pipeline_init_state_->video_decoder)) { 622 if (InitializeVideoRenderer(demuxer_->GetStream(DemuxerStream::VIDEO))) {
639 base::AutoLock auto_lock(lock_); 623 base::AutoLock auto_lock(lock_);
640 has_video_ = true; 624 has_video_ = true;
641 return; 625 return;
642 } 626 }
643 } 627 }
644 628
645 if (state_ == kInitVideoRenderer) { 629 if (state_ == kInitVideoRenderer) {
646 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) { 630 if (!IsPipelineOk() || !(HasAudio() || HasVideo())) {
647 SetError(PIPELINE_ERROR_COULD_NOT_RENDER); 631 SetError(PIPELINE_ERROR_COULD_NOT_RENDER);
648 return; 632 return;
(...skipping 27 matching lines...) Expand all
676 // additional calls, however most of this logic will be changing. 660 // additional calls, however most of this logic will be changing.
677 void Pipeline::StopTask(const base::Closure& stop_cb) { 661 void Pipeline::StopTask(const base::Closure& stop_cb) {
678 DCHECK(message_loop_->BelongsToCurrentThread()); 662 DCHECK(message_loop_->BelongsToCurrentThread());
679 DCHECK(stop_cb_.is_null()); 663 DCHECK(stop_cb_.is_null());
680 664
681 if (state_ == kStopped) { 665 if (state_ == kStopped) {
682 stop_cb.Run(); 666 stop_cb.Run();
683 return; 667 return;
684 } 668 }
685 669
686 if (video_decoder_) { 670 if (video_renderer_)
687 video_decoder_->PrepareForShutdownHack(); 671 video_renderer_->PrepareForShutdownHack();
688 video_decoder_ = NULL;
689 }
690 672
691 if (tearing_down_ && status_ != PIPELINE_OK) { 673 if (tearing_down_ && status_ != PIPELINE_OK) {
692 // If we are stopping due to SetError(), stop normally instead of 674 // If we are stopping due to SetError(), stop normally instead of
693 // going to error state and calling |error_cb_|. This converts 675 // going to error state and calling |error_cb_|. This converts
694 // the teardown in progress from an error teardown into one that acts 676 // the teardown in progress from an error teardown into one that acts
695 // like the error never occurred. 677 // like the error never occurred.
696 base::AutoLock auto_lock(lock_); 678 base::AutoLock auto_lock(lock_);
697 status_ = PIPELINE_OK; 679 status_ = PIPELINE_OK;
698 } 680 }
699 681
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 break; 945 break;
964 case kFlushing: 946 case kFlushing:
965 SetState(kStopping); 947 SetState(kStopping);
966 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); 948 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
967 break; 949 break;
968 950
969 case kCreated: 951 case kCreated:
970 case kInitDemuxer: 952 case kInitDemuxer:
971 case kInitAudioDecoder: 953 case kInitAudioDecoder:
972 case kInitAudioRenderer: 954 case kInitAudioRenderer:
973 case kInitVideoDecoder:
974 case kInitVideoRenderer: 955 case kInitVideoRenderer:
975 case kSeeking: 956 case kSeeking:
976 case kStarting: 957 case kStarting:
977 case kStopped: 958 case kStopped:
978 case kStarted: 959 case kStarted:
979 NOTREACHED() << "Unexpected state for teardown: " << state_; 960 NOTREACHED() << "Unexpected state for teardown: " << state_;
980 break; 961 break;
981 // default: intentionally left out to force new states to cause compiler 962 // default: intentionally left out to force new states to cause compiler
982 // errors. 963 // errors.
983 }; 964 };
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 return false; 1038 return false;
1058 } 1039 }
1059 1040
1060 pipeline_init_state_->audio_decoder->Initialize( 1041 pipeline_init_state_->audio_decoder->Initialize(
1061 stream, 1042 stream,
1062 base::Bind(&Pipeline::OnFilterInitialize, this), 1043 base::Bind(&Pipeline::OnFilterInitialize, this),
1063 base::Bind(&Pipeline::OnUpdateStatistics, this)); 1044 base::Bind(&Pipeline::OnUpdateStatistics, this));
1064 return true; 1045 return true;
1065 } 1046 }
1066 1047
1067 bool Pipeline::InitializeVideoDecoder(
1068 const scoped_refptr<Demuxer>& demuxer) {
1069 DCHECK(message_loop_->BelongsToCurrentThread());
1070 DCHECK(IsPipelineOk());
1071 DCHECK(demuxer);
1072
1073 scoped_refptr<DemuxerStream> stream =
1074 demuxer->GetStream(DemuxerStream::VIDEO);
1075
1076 if (!stream)
1077 return false;
1078
1079 filter_collection_->SelectVideoDecoder(&pipeline_init_state_->video_decoder);
1080
1081 if (!pipeline_init_state_->video_decoder) {
1082 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1083 return false;
1084 }
1085
1086 pipeline_init_state_->video_decoder->Initialize(
1087 stream,
1088 base::Bind(&Pipeline::OnFilterInitialize, this),
1089 base::Bind(&Pipeline::OnUpdateStatistics, this));
1090
1091 video_decoder_ = pipeline_init_state_->video_decoder;
1092 return true;
1093 }
1094
1095 bool Pipeline::InitializeAudioRenderer( 1048 bool Pipeline::InitializeAudioRenderer(
1096 const scoped_refptr<AudioDecoder>& decoder) { 1049 const scoped_refptr<AudioDecoder>& decoder) {
1097 DCHECK(message_loop_->BelongsToCurrentThread()); 1050 DCHECK(message_loop_->BelongsToCurrentThread());
1098 DCHECK(IsPipelineOk()); 1051 DCHECK(IsPipelineOk());
1099 1052
1100 if (!decoder) 1053 if (!decoder)
1101 return false; 1054 return false;
1102 1055
1103 filter_collection_->SelectAudioRenderer(&audio_renderer_); 1056 filter_collection_->SelectAudioRenderer(&audio_renderer_);
1104 if (!audio_renderer_) { 1057 if (!audio_renderer_) {
1105 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1058 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1106 return false; 1059 return false;
1107 } 1060 }
1108 1061
1109 audio_renderer_->Initialize( 1062 audio_renderer_->Initialize(
1110 decoder, 1063 decoder,
1111 base::Bind(&Pipeline::OnFilterInitialize, this), 1064 base::Bind(&Pipeline::OnFilterInitialize, this),
1112 base::Bind(&Pipeline::OnAudioUnderflow, this), 1065 base::Bind(&Pipeline::OnAudioUnderflow, this),
1113 base::Bind(&Pipeline::OnAudioTimeUpdate, this), 1066 base::Bind(&Pipeline::OnAudioTimeUpdate, this),
1114 base::Bind(&Pipeline::OnAudioRendererEnded, this), 1067 base::Bind(&Pipeline::OnAudioRendererEnded, this),
1115 base::Bind(&Pipeline::OnAudioDisabled, this), 1068 base::Bind(&Pipeline::OnAudioDisabled, this),
1116 base::Bind(&Pipeline::SetError, this)); 1069 base::Bind(&Pipeline::SetError, this));
1117 return true; 1070 return true;
1118 } 1071 }
1119 1072
1120 bool Pipeline::InitializeVideoRenderer( 1073 bool Pipeline::InitializeVideoRenderer(
1121 const scoped_refptr<VideoDecoder>& decoder) { 1074 const scoped_refptr<DemuxerStream>& stream) {
1122 DCHECK(message_loop_->BelongsToCurrentThread()); 1075 DCHECK(message_loop_->BelongsToCurrentThread());
1123 DCHECK(IsPipelineOk()); 1076 DCHECK(IsPipelineOk());
1124 1077
1125 if (!decoder) 1078 if (!stream)
1126 return false; 1079 return false;
1127 1080
1128 filter_collection_->SelectVideoRenderer(&video_renderer_); 1081 filter_collection_->SelectVideoRenderer(&video_renderer_);
1129 if (!video_renderer_) { 1082 if (!video_renderer_) {
1130 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1083 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1131 return false; 1084 return false;
1132 } 1085 }
1133 1086
1134 video_renderer_->Initialize( 1087 video_renderer_->Initialize(
1135 decoder, 1088 stream,
1089 *filter_collection_->GetVideoDecoders(),
1136 base::Bind(&Pipeline::OnFilterInitialize, this), 1090 base::Bind(&Pipeline::OnFilterInitialize, this),
1137 base::Bind(&Pipeline::OnUpdateStatistics, this), 1091 base::Bind(&Pipeline::OnUpdateStatistics, this),
1138 base::Bind(&Pipeline::OnVideoTimeUpdate, this), 1092 base::Bind(&Pipeline::OnVideoTimeUpdate, this),
1139 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this), 1093 base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this),
1140 base::Bind(&Pipeline::OnVideoRendererEnded, this), 1094 base::Bind(&Pipeline::OnVideoRendererEnded, this),
1141 base::Bind(&Pipeline::SetError, this), 1095 base::Bind(&Pipeline::SetError, this),
1142 base::Bind(&Pipeline::GetMediaTime, this), 1096 base::Bind(&Pipeline::GetMediaTime, this),
1143 base::Bind(&Pipeline::GetMediaDuration, this)); 1097 base::Bind(&Pipeline::GetMediaDuration, this));
1098 filter_collection_->GetVideoDecoders()->clear();
1144 return true; 1099 return true;
1145 } 1100 }
1146 1101
1147 void Pipeline::TearDownPipeline() { 1102 void Pipeline::TearDownPipeline() {
1148 DCHECK(message_loop_->BelongsToCurrentThread()); 1103 DCHECK(message_loop_->BelongsToCurrentThread());
1149 DCHECK_NE(kStopped, state_); 1104 DCHECK_NE(kStopped, state_);
1150 1105
1151 // We're either... 1106 // We're either...
1152 // 1) ...tearing down due to Stop() (it doesn't set tearing_down_) 1107 // 1) ...tearing down due to Stop() (it doesn't set tearing_down_)
1153 // 2) ...tearing down due to an error (it does set tearing_down_) 1108 // 2) ...tearing down due to an error (it does set tearing_down_)
(...skipping 13 matching lines...) Expand all
1167 SetState(kStopped); 1122 SetState(kStopped);
1168 // Need to put this in the message loop to make sure that it comes 1123 // Need to put this in the message loop to make sure that it comes
1169 // after any pending callback tasks that are already queued. 1124 // after any pending callback tasks that are already queued.
1170 message_loop_->PostTask(FROM_HERE, base::Bind( 1125 message_loop_->PostTask(FROM_HERE, base::Bind(
1171 &Pipeline::FinishDestroyingFiltersTask, this)); 1126 &Pipeline::FinishDestroyingFiltersTask, this));
1172 break; 1127 break;
1173 1128
1174 case kInitDemuxer: 1129 case kInitDemuxer:
1175 case kInitAudioDecoder: 1130 case kInitAudioDecoder:
1176 case kInitAudioRenderer: 1131 case kInitAudioRenderer:
1177 case kInitVideoDecoder:
1178 case kInitVideoRenderer: 1132 case kInitVideoRenderer:
1179 // Make it look like initialization was successful. 1133 // Make it look like initialization was successful.
1180 filter_collection_.reset(); 1134 filter_collection_.reset();
1181 pipeline_init_state_.reset(); 1135 pipeline_init_state_.reset();
1182 1136
1183 SetState(kStopping); 1137 SetState(kStopping);
1184 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); 1138 DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this));
1185 1139
1186 FinishInitialization(); 1140 FinishInitialization();
1187 break; 1141 break;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { 1210 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() {
1257 lock_.AssertAcquired(); 1211 lock_.AssertAcquired();
1258 if (!waiting_for_clock_update_) 1212 if (!waiting_for_clock_update_)
1259 return; 1213 return;
1260 1214
1261 waiting_for_clock_update_ = false; 1215 waiting_for_clock_update_ = false;
1262 clock_->Play(); 1216 clock_->Play();
1263 } 1217 }
1264 1218
1265 } // namespace media 1219 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698