Chromium Code Reviews| 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 "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/stl_util-inl.h" | 10 #include "base/stl_util-inl.h" |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 void PipelineImpl::StartTask(FilterCollection* filter_collection, | 550 void PipelineImpl::StartTask(FilterCollection* filter_collection, |
| 551 const std::string& url, | 551 const std::string& url, |
| 552 PipelineCallback* start_callback) { | 552 PipelineCallback* start_callback) { |
| 553 DCHECK_EQ(MessageLoop::current(), message_loop_); | 553 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 554 DCHECK_EQ(kCreated, state_); | 554 DCHECK_EQ(kCreated, state_); |
| 555 filter_collection_.reset(filter_collection); | 555 filter_collection_.reset(filter_collection); |
| 556 url_ = url; | 556 url_ = url; |
| 557 seek_callback_.reset(start_callback); | 557 seek_callback_.reset(start_callback); |
| 558 | 558 |
| 559 // Kick off initialization. | 559 // Kick off initialization. |
| 560 set_state(kInitDataSource); | 560 set_state(kInitDemuxer); |
| 561 pipeline_init_state_.reset(new PipelineInitState()); | 561 pipeline_init_state_.reset(new PipelineInitState()); |
| 562 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); | 562 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); |
| 563 pipeline_init_state_->composite_->set_host(this); | 563 pipeline_init_state_->composite_->set_host(this); |
| 564 | 564 |
| 565 InitializeDataSource(); | 565 InitializeDemuxer(); |
| 566 } | 566 } |
| 567 | 567 |
| 568 // Main initialization method called on the pipeline thread. This code attempts | 568 // Main initialization method called on the pipeline thread. This code attempts |
| 569 // to use the specified filter factory to build a pipeline. | 569 // to use the specified filter factory to build a pipeline. |
| 570 // Initialization step performed in this method depends on current state of this | 570 // Initialization step performed in this method depends on current state of this |
| 571 // object, indicated by |state_|. After each step of initialization, this | 571 // object, indicated by |state_|. After each step of initialization, this |
| 572 // object transits to the next stage. It starts by creating a DataSource, | 572 // object transits to the next stage. It starts by creating a Demuxer, and then |
| 573 // connects it to a Demuxer, and then connects the Demuxer's audio stream to an | 573 // connects the Demuxer's audio stream to an AudioDecoder which is then |
| 574 // AudioDecoder which is then connected to an AudioRenderer. If the media has | 574 // connected to an AudioRenderer. If the media has video, then it connects a |
| 575 // video, then it connects a VideoDecoder to the Demuxer's video stream, and | 575 // VideoDecoder to the Demuxer's video stream, and then connects the |
| 576 // then connects the VideoDecoder to a VideoRenderer. | 576 // VideoDecoder to a VideoRenderer. |
| 577 // | 577 // |
| 578 // When all required filters have been created and have called their | 578 // When all required filters have been created and have called their |
| 579 // FilterHost's InitializationComplete() method, the pipeline will update its | 579 // FilterHost's InitializationComplete() method, the pipeline will update its |
| 580 // state to kStarted and |init_callback_|, will be executed. | 580 // state to kStarted and |init_callback_|, will be executed. |
| 581 // | 581 // |
| 582 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It | 582 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It |
| 583 // works like a big state change table. If we no longer need to start filters | 583 // works like a big state change table. If we no longer need to start filters |
| 584 // in order, we need to get rid of all the state change. | 584 // in order, we need to get rid of all the state change. |
| 585 void PipelineImpl::InitializeTask() { | 585 void PipelineImpl::InitializeTask() { |
|
acolwell GONE FROM CHROMIUM
2011/03/08 21:48:09
Indentation
Ami GONE FROM CHROMIUM
2011/03/08 22:44:48
Done.
| |
| 586 DCHECK_EQ(MessageLoop::current(), message_loop_); | 586 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 587 | 587 |
| 588 // If we have received the stop or error signal, return immediately. | 588 // If we have received the stop or error signal, return immediately. |
| 589 if (IsPipelineStopPending() || | 589 if (IsPipelineStopPending() || |
| 590 IsPipelineStopped() || | 590 IsPipelineStopped() || |
| 591 PIPELINE_OK != GetError()) { | 591 PIPELINE_OK != GetError()) { |
| 592 return; | 592 return; |
| 593 } | 593 } |
| 594 | 594 |
| 595 DCHECK(state_ == kInitDemuxer || | 595 DCHECK(state_ == kInitDemuxer || |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 942 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 943 break; | 943 break; |
| 944 case kFlushing: | 944 case kFlushing: |
| 945 set_state(kStopping); | 945 set_state(kStopping); |
| 946 pipeline_filter_->Stop( | 946 pipeline_filter_->Stop( |
| 947 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); | 947 NewCallback(this, &PipelineImpl::OnTeardownStateTransition)); |
| 948 break; | 948 break; |
| 949 | 949 |
| 950 case kCreated: | 950 case kCreated: |
| 951 case kError: | 951 case kError: |
| 952 case kInitDataSource: | |
| 953 case kInitDemuxer: | 952 case kInitDemuxer: |
| 954 case kInitAudioDecoder: | 953 case kInitAudioDecoder: |
| 955 case kInitAudioRenderer: | 954 case kInitAudioRenderer: |
| 956 case kInitVideoDecoder: | 955 case kInitVideoDecoder: |
| 957 case kInitVideoRenderer: | 956 case kInitVideoRenderer: |
| 958 case kSeeking: | 957 case kSeeking: |
| 959 case kStarting: | 958 case kStarting: |
| 960 case kStopped: | 959 case kStopped: |
| 961 case kStarted: | 960 case kStarted: |
| 962 case kEnded: | 961 case kEnded: |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 | 997 |
| 999 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { | 998 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { |
| 1000 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); | 999 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); |
| 1001 | 1000 |
| 1002 if (!ret) { | 1001 if (!ret) { |
| 1003 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); | 1002 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| 1004 } | 1003 } |
| 1005 return ret; | 1004 return ret; |
| 1006 } | 1005 } |
| 1007 | 1006 |
| 1008 void PipelineImpl::InitializeDataSource() { | 1007 void PipelineImpl::InitializeDemuxer() { |
| 1009 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1008 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1010 DCHECK(IsPipelineOk()); | 1009 DCHECK(IsPipelineOk()); |
| 1011 | 1010 |
| 1012 filter_collection_->GetDataSourceFactory()->Build(url_, | 1011 filter_collection_->GetDemuxerFactory()->Build(url_, |
| 1013 NewCallback(this, &PipelineImpl::OnDataSourceBuilt)); | 1012 NewCallback(this, &PipelineImpl::OnDemuxerBuilt)); |
| 1014 } | 1013 } |
| 1015 | 1014 |
| 1016 void PipelineImpl::OnDataSourceBuilt(PipelineError error, | 1015 void PipelineImpl::OnDemuxerBuilt(PipelineError error, |
| 1017 DataSource* data_source) { | 1016 Demuxer* demuxer) { |
| 1018 if (MessageLoop::current() != message_loop_) { | 1017 if (MessageLoop::current() != message_loop_) { |
| 1019 message_loop_->PostTask(FROM_HERE, | 1018 message_loop_->PostTask(FROM_HERE, |
| 1020 NewRunnableMethod(this, | 1019 NewRunnableMethod(this, |
| 1021 &PipelineImpl::OnDataSourceBuilt, | 1020 &PipelineImpl::OnDemuxerBuilt, |
| 1022 error, | 1021 error, |
| 1023 make_scoped_refptr(data_source))); | 1022 make_scoped_refptr(demuxer))); |
| 1024 return; | 1023 return; |
| 1025 } | 1024 } |
| 1026 | 1025 |
| 1027 if (error != PIPELINE_OK) { | 1026 if (error != PIPELINE_OK) { |
| 1028 SetError(error); | 1027 SetError(error); |
| 1029 return; | 1028 return; |
| 1030 } | 1029 } |
| 1031 | 1030 |
| 1032 PrepareFilter(data_source); | |
| 1033 | |
| 1034 set_state(kInitDemuxer); | |
| 1035 InitializeDemuxer(data_source); | |
| 1036 } | |
| 1037 | |
| 1038 void PipelineImpl::InitializeDemuxer( | |
| 1039 const scoped_refptr<DataSource>& data_source) { | |
| 1040 DCHECK_EQ(MessageLoop::current(), message_loop_); | |
| 1041 DCHECK(IsPipelineOk()); | |
| 1042 | |
| 1043 scoped_refptr<Demuxer> demuxer; | |
| 1044 | |
| 1045 CHECK(data_source); | |
| 1046 | |
| 1047 filter_collection_->SelectDemuxer(&demuxer); | |
| 1048 if (!demuxer) { | 1031 if (!demuxer) { |
| 1049 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); | 1032 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); |
| 1050 return; | 1033 return; |
| 1051 } | 1034 } |
| 1052 | 1035 |
| 1053 if (!PrepareFilter(demuxer)) | 1036 if (!PrepareFilter(demuxer)) |
| 1054 return; | 1037 return; |
| 1055 | 1038 |
| 1056 pipeline_init_state_->demuxer_ = demuxer; | 1039 pipeline_init_state_->demuxer_ = make_scoped_refptr(demuxer); |
|
acolwell GONE FROM CHROMIUM
2011/03/08 21:48:09
I don't think you need make_scoped_refptr() here.
Ami GONE FROM CHROMIUM
2011/03/08 22:44:48
Done.
| |
| 1057 demuxer->Initialize(data_source, | 1040 OnFilterInitialize(); |
|
acolwell GONE FROM CHROMIUM
2011/03/08 21:48:09
I think you can call InitializeTask() from here in
Ami GONE FROM CHROMIUM
2011/03/08 22:44:48
But calling OFI() has the additional benefit of de
acolwell GONE FROM CHROMIUM
2011/03/08 23:19:00
Ok. Sounds reasonable to me.
| |
| 1058 NewCallback(this, &PipelineImpl::OnFilterInitialize)); | |
| 1059 } | 1041 } |
| 1060 | 1042 |
| 1061 bool PipelineImpl::InitializeAudioDecoder( | 1043 bool PipelineImpl::InitializeAudioDecoder( |
| 1062 const scoped_refptr<Demuxer>& demuxer) { | 1044 const scoped_refptr<Demuxer>& demuxer) { |
| 1063 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1045 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1064 DCHECK(IsPipelineOk()); | 1046 DCHECK(IsPipelineOk()); |
| 1065 | 1047 |
| 1066 scoped_refptr<DemuxerStream> stream = | 1048 scoped_refptr<DemuxerStream> stream = |
| 1067 FindDemuxerStream(demuxer, mime_type::kMajorTypeAudio); | 1049 FindDemuxerStream(demuxer, mime_type::kMajorTypeAudio); |
| 1068 | 1050 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1195 switch(state_) { | 1177 switch(state_) { |
| 1196 case kCreated: | 1178 case kCreated: |
| 1197 case kError: | 1179 case kError: |
| 1198 set_state(kStopped); | 1180 set_state(kStopped); |
| 1199 // Need to put this in the message loop to make sure that it comes | 1181 // Need to put this in the message loop to make sure that it comes |
| 1200 // after any pending callback tasks that are already queued. | 1182 // after any pending callback tasks that are already queued. |
| 1201 message_loop_->PostTask(FROM_HERE, | 1183 message_loop_->PostTask(FROM_HERE, |
| 1202 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1184 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
| 1203 break; | 1185 break; |
| 1204 | 1186 |
| 1205 case kInitDataSource: | |
| 1206 case kInitDemuxer: | 1187 case kInitDemuxer: |
| 1207 case kInitAudioDecoder: | 1188 case kInitAudioDecoder: |
| 1208 case kInitAudioRenderer: | 1189 case kInitAudioRenderer: |
| 1209 case kInitVideoDecoder: | 1190 case kInitVideoDecoder: |
| 1210 case kInitVideoRenderer: | 1191 case kInitVideoRenderer: |
| 1211 // Make it look like initialization was successful. | 1192 // Make it look like initialization was successful. |
| 1212 pipeline_filter_ = pipeline_init_state_->composite_; | 1193 pipeline_filter_ = pipeline_init_state_->composite_; |
| 1213 pipeline_init_state_.reset(); | 1194 pipeline_init_state_.reset(); |
| 1214 filter_collection_.reset(); | 1195 filter_collection_.reset(); |
| 1215 | 1196 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1245 case kStopping: | 1226 case kStopping: |
| 1246 case kStopped: | 1227 case kStopped: |
| 1247 NOTREACHED() << "Unexpected state for teardown: " << state_; | 1228 NOTREACHED() << "Unexpected state for teardown: " << state_; |
| 1248 break; | 1229 break; |
| 1249 // default: intentionally left out to force new states to cause compiler | 1230 // default: intentionally left out to force new states to cause compiler |
| 1250 // errors. | 1231 // errors. |
| 1251 }; | 1232 }; |
| 1252 } | 1233 } |
| 1253 | 1234 |
| 1254 } // namespace media | 1235 } // namespace media |
| OLD | NEW |