| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/condition_variable.h" | 10 #include "base/condition_variable.h" |
| 11 #include "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
| 12 #include "media/base/clock_impl.h" | 12 #include "media/base/clock_impl.h" |
| 13 #include "media/base/filter_collection.h" |
| 13 #include "media/base/media_format.h" | 14 #include "media/base/media_format.h" |
| 14 #include "media/base/pipeline_impl.h" | 15 #include "media/base/pipeline_impl.h" |
| 15 | 16 |
| 16 namespace media { | 17 namespace media { |
| 17 | 18 |
| 18 PipelineImpl::PipelineImpl(MessageLoop* message_loop) | 19 PipelineImpl::PipelineImpl(MessageLoop* message_loop) |
| 19 : message_loop_(message_loop), | 20 : message_loop_(message_loop), |
| 20 clock_(new ClockImpl(&base::Time::Now)), | 21 clock_(new ClockImpl(&base::Time::Now)), |
| 21 waiting_for_clock_update_(false), | 22 waiting_for_clock_update_(false), |
| 22 state_(kCreated), | 23 state_(kCreated), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 36 PipelineCallback* error_callback, | 37 PipelineCallback* error_callback, |
| 37 PipelineCallback* network_callback) { | 38 PipelineCallback* network_callback) { |
| 38 DCHECK(!IsRunning()) | 39 DCHECK(!IsRunning()) |
| 39 << "Init() should be called before the pipeline has started"; | 40 << "Init() should be called before the pipeline has started"; |
| 40 ended_callback_.reset(ended_callback); | 41 ended_callback_.reset(ended_callback); |
| 41 error_callback_.reset(error_callback); | 42 error_callback_.reset(error_callback); |
| 42 network_callback_.reset(network_callback); | 43 network_callback_.reset(network_callback); |
| 43 } | 44 } |
| 44 | 45 |
| 45 // Creates the PipelineInternal and calls it's start method. | 46 // Creates the PipelineInternal and calls it's start method. |
| 46 bool PipelineImpl::Start(MediaFilterCollection* collection, | 47 bool PipelineImpl::Start(FilterCollection* collection, |
| 47 const std::string& url, | 48 const std::string& url, |
| 48 PipelineCallback* start_callback) { | 49 PipelineCallback* start_callback) { |
| 49 AutoLock auto_lock(lock_); | 50 AutoLock auto_lock(lock_); |
| 50 scoped_ptr<PipelineCallback> callback(start_callback); | 51 scoped_ptr<PipelineCallback> callback(start_callback); |
| 51 scoped_ptr<MediaFilterCollection> filter_collection(collection); | 52 scoped_ptr<FilterCollection> filter_collection(collection); |
| 52 | 53 |
| 53 if (running_) { | 54 if (running_) { |
| 54 VLOG(1) << "Media pipeline is already running"; | 55 VLOG(1) << "Media pipeline is already running"; |
| 55 return false; | 56 return false; |
| 56 } | 57 } |
| 57 | 58 |
| 58 if (collection->IsEmpty()) { | 59 if (collection->IsEmpty()) { |
| 59 return false; | 60 return false; |
| 60 } | 61 } |
| 61 | 62 |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 NewRunnableMethod(this, &PipelineImpl::InitializeTask)); | 513 NewRunnableMethod(this, &PipelineImpl::InitializeTask)); |
| 513 } | 514 } |
| 514 | 515 |
| 515 // Called from any thread. | 516 // Called from any thread. |
| 516 void PipelineImpl::OnFilterStateTransition() { | 517 void PipelineImpl::OnFilterStateTransition() { |
| 517 // Continue walking down the filters. | 518 // Continue walking down the filters. |
| 518 message_loop_->PostTask(FROM_HERE, | 519 message_loop_->PostTask(FROM_HERE, |
| 519 NewRunnableMethod(this, &PipelineImpl::FilterStateTransitionTask)); | 520 NewRunnableMethod(this, &PipelineImpl::FilterStateTransitionTask)); |
| 520 } | 521 } |
| 521 | 522 |
| 522 void PipelineImpl::StartTask(MediaFilterCollection* filter_collection, | 523 void PipelineImpl::StartTask(FilterCollection* filter_collection, |
| 523 const std::string& url, | 524 const std::string& url, |
| 524 PipelineCallback* start_callback) { | 525 PipelineCallback* start_callback) { |
| 525 DCHECK_EQ(MessageLoop::current(), message_loop_); | 526 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 526 DCHECK_EQ(kCreated, state_); | 527 DCHECK_EQ(kCreated, state_); |
| 527 filter_collection_.reset(filter_collection); | 528 filter_collection_.reset(filter_collection); |
| 528 url_ = url; | 529 url_ = url; |
| 529 seek_callback_.reset(start_callback); | 530 seek_callback_.reset(start_callback); |
| 530 | 531 |
| 531 // Kick off initialization. | 532 // Kick off initialization. |
| 532 InitializeTask(); | 533 InitializeTask(); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 clock_->SetTime(seek_timestamp_); | 838 clock_->SetTime(seek_timestamp_); |
| 838 } | 839 } |
| 839 | 840 |
| 840 if (TransientState(state_)) { | 841 if (TransientState(state_)) { |
| 841 remaining_transitions_ = filters_.size(); | 842 remaining_transitions_ = filters_.size(); |
| 842 } | 843 } |
| 843 } | 844 } |
| 844 | 845 |
| 845 // Carry out the action for the current state. | 846 // Carry out the action for the current state. |
| 846 if (TransientState(state_)) { | 847 if (TransientState(state_)) { |
| 847 MediaFilter* filter = filters_[filters_.size() - remaining_transitions_]; | 848 Filter* filter = filters_[filters_.size() - remaining_transitions_]; |
| 848 if (state_ == kPausing) { | 849 if (state_ == kPausing) { |
| 849 filter->Pause(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 850 filter->Pause(NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
| 850 } else if (state_ == kFlushing) { | 851 } else if (state_ == kFlushing) { |
| 851 // We had to use parallel flushing all filters. | 852 // We had to use parallel flushing all filters. |
| 852 if (remaining_transitions_ == filters_.size()) { | 853 if (remaining_transitions_ == filters_.size()) { |
| 853 for (size_t i = 0; i < filters_.size(); i++) { | 854 for (size_t i = 0; i < filters_.size(); i++) { |
| 854 filters_[i]->Flush( | 855 filters_[i]->Flush( |
| 855 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 856 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
| 856 } | 857 } |
| 857 } | 858 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 } else { | 931 } else { |
| 931 // Destroying filters due to SetError(). | 932 // Destroying filters due to SetError(). |
| 932 state_ = kError; | 933 state_ = kError; |
| 933 // If our owner has requested to be notified of an error. | 934 // If our owner has requested to be notified of an error. |
| 934 if (error_callback_.get()) { | 935 if (error_callback_.get()) { |
| 935 error_callback_->Run(); | 936 error_callback_->Run(); |
| 936 } | 937 } |
| 937 } | 938 } |
| 938 } | 939 } |
| 939 | 940 |
| 940 bool PipelineImpl::PrepareFilter(scoped_refptr<MediaFilter> filter) { | 941 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { |
| 941 DCHECK_EQ(MessageLoop::current(), message_loop_); | 942 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 942 DCHECK(IsPipelineOk()); | 943 DCHECK(IsPipelineOk()); |
| 943 | 944 |
| 944 // Create a dedicated thread for this filter if applicable. | 945 // Create a dedicated thread for this filter if applicable. |
| 945 if (filter->requires_message_loop()) { | 946 if (filter->requires_message_loop()) { |
| 946 scoped_ptr<base::Thread> thread( | 947 scoped_ptr<base::Thread> thread( |
| 947 new base::Thread(filter->message_loop_name())); | 948 new base::Thread(filter->message_loop_name())); |
| 948 if (!thread.get() || !thread->Start()) { | 949 if (!thread.get() || !thread->Start()) { |
| 949 NOTREACHED() << "Could not start filter thread"; | 950 NOTREACHED() << "Could not start filter thread"; |
| 950 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); | 951 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 this, &PipelineImpl::OnFilterStateTransition)); | 1153 this, &PipelineImpl::OnFilterStateTransition)); |
| 1153 } | 1154 } |
| 1154 } else { | 1155 } else { |
| 1155 state_ = kStopped; | 1156 state_ = kStopped; |
| 1156 message_loop_->PostTask(FROM_HERE, | 1157 message_loop_->PostTask(FROM_HERE, |
| 1157 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1158 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
| 1158 } | 1159 } |
| 1159 } | 1160 } |
| 1160 | 1161 |
| 1161 } // namespace media | 1162 } // namespace media |
| OLD | NEW |