OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, | 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, |
6 // potential deadlocks, etc... | 6 // potential deadlocks, etc... |
7 | 7 |
8 #include "media/base/pipeline_impl.h" | 8 #include "media/base/pipeline_impl.h" |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 DCHECK(IsRunning()); | 579 DCHECK(IsRunning()); |
580 | 580 |
581 // Disable renderer on the message loop. | 581 // Disable renderer on the message loop. |
582 message_loop_->PostTask(FROM_HERE, | 582 message_loop_->PostTask(FROM_HERE, |
583 base::Bind(&PipelineImpl::DisableAudioRendererTask, this)); | 583 base::Bind(&PipelineImpl::DisableAudioRendererTask, this)); |
584 media_log_->AddEvent( | 584 media_log_->AddEvent( |
585 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); | 585 media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); |
586 } | 586 } |
587 | 587 |
588 // Called from any thread. | 588 // Called from any thread. |
589 void PipelineImpl::OnFilterInitialize(PipelineStatus status) { | 589 void PipelineImpl::OnFilterInitialize() { |
590 // Continue the initialize task by proceeding to the next stage. | 590 // Continue the initialize task by proceeding to the next stage. |
591 message_loop_->PostTask( | 591 message_loop_->PostTask(FROM_HERE, |
592 FROM_HERE, base::Bind(&PipelineImpl::InitializeTask, this, status)); | 592 base::Bind(&PipelineImpl::InitializeTask, this)); |
593 } | 593 } |
594 | 594 |
595 // Called from any thread. | 595 // Called from any thread. |
596 void PipelineImpl::OnFilterStateTransition() { | 596 void PipelineImpl::OnFilterStateTransition() { |
597 message_loop_->PostTask(FROM_HERE, | 597 message_loop_->PostTask(FROM_HERE, |
598 base::Bind(&PipelineImpl::FilterStateTransitionTask, this)); | 598 base::Bind(&PipelineImpl::FilterStateTransitionTask, this)); |
599 } | 599 } |
600 | 600 |
601 // Called from any thread. | 601 // Called from any thread. |
602 // This method makes the FilterStatusCB behave like a Closure. It | 602 // This method makes the FilterStatusCB behave like a Closure. It |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 // VideoDecoder to the Demuxer's video stream, and then connects the | 654 // VideoDecoder to the Demuxer's video stream, and then connects the |
655 // VideoDecoder to a VideoRenderer. | 655 // VideoDecoder to a VideoRenderer. |
656 // | 656 // |
657 // When all required filters have been created and have called their | 657 // When all required filters have been created and have called their |
658 // FilterHost's InitializationComplete() method, the pipeline will update its | 658 // FilterHost's InitializationComplete() method, the pipeline will update its |
659 // state to kStarted and |init_callback_|, will be executed. | 659 // state to kStarted and |init_callback_|, will be executed. |
660 // | 660 // |
661 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It | 661 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It |
662 // works like a big state change table. If we no longer need to start filters | 662 // works like a big state change table. If we no longer need to start filters |
663 // in order, we need to get rid of all the state change. | 663 // in order, we need to get rid of all the state change. |
664 void PipelineImpl::InitializeTask(PipelineStatus last_stage_status) { | 664 void PipelineImpl::InitializeTask() { |
665 DCHECK_EQ(MessageLoop::current(), message_loop_); | 665 DCHECK_EQ(MessageLoop::current(), message_loop_); |
666 | 666 |
667 if (last_stage_status != PIPELINE_OK) { | |
668 // Currently only VideoDecoders have a recoverable error code. | |
669 if (state_ == kInitVideoDecoder && | |
670 last_stage_status == DECODER_ERROR_NOT_SUPPORTED) { | |
671 pipeline_init_state_->composite_->RemoveFilter( | |
672 pipeline_init_state_->video_decoder_.get()); | |
673 state_ = kInitAudioRenderer; | |
674 } else { | |
675 SetError(last_stage_status); | |
676 } | |
677 } | |
678 | |
679 // If we have received the stop or error signal, return immediately. | 667 // If we have received the stop or error signal, return immediately. |
680 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) | 668 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) |
681 return; | 669 return; |
682 | 670 |
683 DCHECK(state_ == kInitDemuxer || | 671 DCHECK(state_ == kInitDemuxer || |
684 state_ == kInitAudioDecoder || | 672 state_ == kInitAudioDecoder || |
685 state_ == kInitAudioRenderer || | 673 state_ == kInitAudioRenderer || |
686 state_ == kInitVideoDecoder || | 674 state_ == kInitVideoDecoder || |
687 state_ == kInitVideoRenderer); | 675 state_ == kInitVideoRenderer); |
688 | 676 |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 stop_cb.Run(status_); | 1104 stop_cb.Run(status_); |
1117 } | 1105 } |
1118 } | 1106 } |
1119 | 1107 |
1120 tearing_down_ = false; | 1108 tearing_down_ = false; |
1121 error_caused_teardown_ = false; | 1109 error_caused_teardown_ = false; |
1122 } | 1110 } |
1123 | 1111 |
1124 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { | 1112 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { |
1125 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); | 1113 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); |
1126 if (!ret) | 1114 |
| 1115 if (!ret) { |
1127 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); | 1116 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| 1117 } |
1128 return ret; | 1118 return ret; |
1129 } | 1119 } |
1130 | 1120 |
1131 void PipelineImpl::InitializeDemuxer() { | 1121 void PipelineImpl::InitializeDemuxer() { |
1132 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1122 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1133 DCHECK(IsPipelineOk()); | 1123 DCHECK(IsPipelineOk()); |
1134 | 1124 |
1135 filter_collection_->GetDemuxerFactory()->Build( | 1125 filter_collection_->GetDemuxerFactory()->Build( |
1136 url_, base::Bind(&PipelineImpl::OnDemuxerBuilt, this)); | 1126 url_, base::Bind(&PipelineImpl::OnDemuxerBuilt, this)); |
1137 } | 1127 } |
(...skipping 20 matching lines...) Expand all Loading... |
1158 demuxer_ = demuxer; | 1148 demuxer_ = demuxer; |
1159 demuxer_->set_host(this); | 1149 demuxer_->set_host(this); |
1160 | 1150 |
1161 { | 1151 { |
1162 base::AutoLock auto_lock(lock_); | 1152 base::AutoLock auto_lock(lock_); |
1163 // We do not want to start the clock running. We only want to set the base | 1153 // We do not want to start the clock running. We only want to set the base |
1164 // media time so our timestamp calculations will be correct. | 1154 // media time so our timestamp calculations will be correct. |
1165 clock_->SetTime(demuxer_->GetStartTime()); | 1155 clock_->SetTime(demuxer_->GetStartTime()); |
1166 } | 1156 } |
1167 | 1157 |
1168 OnFilterInitialize(PIPELINE_OK); | 1158 OnFilterInitialize(); |
1169 } | 1159 } |
1170 | 1160 |
1171 bool PipelineImpl::InitializeAudioDecoder( | 1161 bool PipelineImpl::InitializeAudioDecoder( |
1172 const scoped_refptr<Demuxer>& demuxer) { | 1162 const scoped_refptr<Demuxer>& demuxer) { |
1173 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1163 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1174 DCHECK(IsPipelineOk()); | 1164 DCHECK(IsPipelineOk()); |
1175 | 1165 |
1176 scoped_refptr<DemuxerStream> stream = | 1166 scoped_refptr<DemuxerStream> stream = |
1177 demuxer->GetStream(DemuxerStream::AUDIO); | 1167 demuxer->GetStream(DemuxerStream::AUDIO); |
1178 | 1168 |
1179 if (!stream) | 1169 if (!stream) |
1180 return false; | 1170 return false; |
1181 | 1171 |
1182 scoped_refptr<AudioDecoder> audio_decoder; | 1172 scoped_refptr<AudioDecoder> audio_decoder; |
1183 filter_collection_->SelectAudioDecoder(&audio_decoder); | 1173 filter_collection_->SelectAudioDecoder(&audio_decoder); |
1184 | 1174 |
1185 if (!audio_decoder) { | 1175 if (!audio_decoder) { |
1186 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1176 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1187 return false; | 1177 return false; |
1188 } | 1178 } |
1189 | 1179 |
1190 if (!PrepareFilter(audio_decoder)) | 1180 if (!PrepareFilter(audio_decoder)) |
1191 return false; | 1181 return false; |
1192 | 1182 |
1193 pipeline_init_state_->audio_decoder_ = audio_decoder; | 1183 pipeline_init_state_->audio_decoder_ = audio_decoder; |
1194 audio_decoder->Initialize( | 1184 audio_decoder->Initialize( |
1195 stream, | 1185 stream, |
1196 base::Bind(&PipelineImpl::OnFilterInitialize, this, PIPELINE_OK), | 1186 base::Bind(&PipelineImpl::OnFilterInitialize, this), |
1197 base::Bind(&PipelineImpl::OnUpdateStatistics, this)); | 1187 base::Bind(&PipelineImpl::OnUpdateStatistics, this)); |
1198 return true; | 1188 return true; |
1199 } | 1189 } |
1200 | 1190 |
1201 bool PipelineImpl::InitializeVideoDecoder( | 1191 bool PipelineImpl::InitializeVideoDecoder( |
1202 const scoped_refptr<Demuxer>& demuxer) { | 1192 const scoped_refptr<Demuxer>& demuxer) { |
1203 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1193 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1204 DCHECK(IsPipelineOk()); | 1194 DCHECK(IsPipelineOk()); |
1205 | 1195 |
1206 scoped_refptr<DemuxerStream> stream; | 1196 scoped_refptr<DemuxerStream> stream; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 if (!audio_renderer_) { | 1233 if (!audio_renderer_) { |
1244 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1234 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1245 return false; | 1235 return false; |
1246 } | 1236 } |
1247 | 1237 |
1248 if (!PrepareFilter(audio_renderer_)) | 1238 if (!PrepareFilter(audio_renderer_)) |
1249 return false; | 1239 return false; |
1250 | 1240 |
1251 audio_renderer_->Initialize( | 1241 audio_renderer_->Initialize( |
1252 decoder, | 1242 decoder, |
1253 base::Bind(&PipelineImpl::OnFilterInitialize, this, PIPELINE_OK), | 1243 base::Bind(&PipelineImpl::OnFilterInitialize, this), |
1254 base::Bind(&PipelineImpl::OnAudioUnderflow, this)); | 1244 base::Bind(&PipelineImpl::OnAudioUnderflow, this)); |
1255 return true; | 1245 return true; |
1256 } | 1246 } |
1257 | 1247 |
1258 bool PipelineImpl::InitializeVideoRenderer( | 1248 bool PipelineImpl::InitializeVideoRenderer( |
1259 const scoped_refptr<VideoDecoder>& decoder) { | 1249 const scoped_refptr<VideoDecoder>& decoder) { |
1260 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1250 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1261 DCHECK(IsPipelineOk()); | 1251 DCHECK(IsPipelineOk()); |
1262 | 1252 |
1263 if (!decoder) | 1253 if (!decoder) |
1264 return false; | 1254 return false; |
1265 | 1255 |
1266 filter_collection_->SelectVideoRenderer(&video_renderer_); | 1256 filter_collection_->SelectVideoRenderer(&video_renderer_); |
1267 if (!video_renderer_) { | 1257 if (!video_renderer_) { |
1268 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1258 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
1269 return false; | 1259 return false; |
1270 } | 1260 } |
1271 | 1261 |
1272 if (!PrepareFilter(video_renderer_)) | 1262 if (!PrepareFilter(video_renderer_)) |
1273 return false; | 1263 return false; |
1274 | 1264 |
1275 video_renderer_->Initialize( | 1265 video_renderer_->Initialize( |
1276 decoder, | 1266 decoder, |
1277 base::Bind(&PipelineImpl::OnFilterInitialize, this, PIPELINE_OK), | 1267 base::Bind(&PipelineImpl::OnFilterInitialize, this), |
1278 base::Bind(&PipelineImpl::OnUpdateStatistics, this)); | 1268 base::Bind(&PipelineImpl::OnUpdateStatistics, this)); |
1279 return true; | 1269 return true; |
1280 } | 1270 } |
1281 | 1271 |
1282 void PipelineImpl::TearDownPipeline() { | 1272 void PipelineImpl::TearDownPipeline() { |
1283 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1273 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1284 DCHECK_NE(kStopped, state_); | 1274 DCHECK_NE(kStopped, state_); |
1285 | 1275 |
1286 DCHECK(!tearing_down_ || // Teardown on Stop(). | 1276 DCHECK(!tearing_down_ || // Teardown on Stop(). |
1287 (tearing_down_ && error_caused_teardown_) || // Teardown on error. | 1277 (tearing_down_ && error_caused_teardown_) || // Teardown on error. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 message_loop_->PostTask(FROM_HERE, | 1414 message_loop_->PostTask(FROM_HERE, |
1425 base::Bind(&PipelineImpl::NotifyCanPlayThrough, this)); | 1415 base::Bind(&PipelineImpl::NotifyCanPlayThrough, this)); |
1426 } | 1416 } |
1427 | 1417 |
1428 void PipelineImpl::NotifyCanPlayThrough() { | 1418 void PipelineImpl::NotifyCanPlayThrough() { |
1429 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1419 DCHECK_EQ(MessageLoop::current(), message_loop_); |
1430 NotifyNetworkEventTask(CAN_PLAY_THROUGH); | 1420 NotifyNetworkEventTask(CAN_PLAY_THROUGH); |
1431 } | 1421 } |
1432 | 1422 |
1433 } // namespace media | 1423 } // namespace media |
OLD | NEW |