| 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 #include "media/base/composite_filter.h" | 5 #include "media/base/composite_filter.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" |
| 7 #include "base/stl_util-inl.h" | 8 #include "base/stl_util-inl.h" |
| 8 #include "media/base/callback.h" | 9 #include "media/base/callback.h" |
| 9 | 10 |
| 10 namespace media { | 11 namespace media { |
| 11 | 12 |
| 12 class CompositeFilter::FilterHostImpl : public FilterHost { | 13 class CompositeFilter::FilterHostImpl : public FilterHost { |
| 13 public: | 14 public: |
| 14 FilterHostImpl(CompositeFilter* parent, FilterHost* host); | 15 FilterHostImpl(CompositeFilter* parent, FilterHost* host); |
| 15 | 16 |
| 16 FilterHost* host(); | 17 FilterHost* host(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 33 virtual void SetCurrentReadPosition(int64 offset); | 34 virtual void SetCurrentReadPosition(int64 offset); |
| 34 virtual int64 GetCurrentReadPosition(); | 35 virtual int64 GetCurrentReadPosition(); |
| 35 | 36 |
| 36 private: | 37 private: |
| 37 CompositeFilter* parent_; | 38 CompositeFilter* parent_; |
| 38 FilterHost* host_; | 39 FilterHost* host_; |
| 39 | 40 |
| 40 DISALLOW_COPY_AND_ASSIGN(FilterHostImpl); | 41 DISALLOW_COPY_AND_ASSIGN(FilterHostImpl); |
| 41 }; | 42 }; |
| 42 | 43 |
| 43 CompositeFilter::CompositeFilter(MessageLoop* message_loop) { | 44 CompositeFilter::CompositeFilter(MessageLoop* message_loop) |
| 44 Init(message_loop, NULL); | 45 : state_(kCreated), |
| 45 } | 46 sequence_index_(0), |
| 46 | 47 message_loop_(message_loop), |
| 47 CompositeFilter::CompositeFilter(MessageLoop* message_loop, | 48 error_(PIPELINE_OK) { |
| 48 ThreadFactoryFunction thread_factory) { | |
| 49 DCHECK(thread_factory); | |
| 50 Init(message_loop, thread_factory); | |
| 51 } | |
| 52 | |
| 53 void CompositeFilter::Init(MessageLoop* message_loop, | |
| 54 ThreadFactoryFunction thread_factory) { | |
| 55 DCHECK(message_loop); | 49 DCHECK(message_loop); |
| 56 message_loop_ = message_loop; | |
| 57 thread_factory_ = thread_factory; | |
| 58 runnable_factory_.reset( | 50 runnable_factory_.reset( |
| 59 new ScopedRunnableMethodFactory<CompositeFilter>(this)); | 51 new ScopedRunnableMethodFactory<CompositeFilter>(this)); |
| 60 | |
| 61 if (!thread_factory_) { | |
| 62 thread_factory_ = &CompositeFilter::DefaultThreadFactory; | |
| 63 } | |
| 64 | |
| 65 state_ = kCreated; | |
| 66 sequence_index_ = 0; | |
| 67 error_ = PIPELINE_OK; | |
| 68 } | 52 } |
| 69 | 53 |
| 70 CompositeFilter::~CompositeFilter() { | 54 CompositeFilter::~CompositeFilter() { |
| 71 DCHECK_EQ(message_loop_, MessageLoop::current()); | 55 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 72 DCHECK(state_ == kCreated || state_ == kStopped); | 56 DCHECK(state_ == kCreated || state_ == kStopped); |
| 73 | 57 |
| 74 // Stop every running filter thread. | |
| 75 for (FilterThreadVector::iterator iter = filter_threads_.begin(); | |
| 76 iter != filter_threads_.end(); | |
| 77 ++iter) { | |
| 78 (*iter)->Stop(); | |
| 79 } | |
| 80 | |
| 81 filters_.clear(); | 58 filters_.clear(); |
| 82 STLDeleteElements(&filter_threads_); | |
| 83 } | 59 } |
| 84 | 60 |
| 85 bool CompositeFilter::AddFilter(scoped_refptr<Filter> filter) { | 61 bool CompositeFilter::AddFilter(scoped_refptr<Filter> filter) { |
| 86 DCHECK_EQ(message_loop_, MessageLoop::current()); | 62 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 87 if (!filter.get() || state_ != kCreated || !host()) | 63 if (!filter.get() || state_ != kCreated || !host()) |
| 88 return false; | 64 return false; |
| 89 | 65 |
| 90 // Create a dedicated thread for this filter if applicable. | |
| 91 if (filter->requires_message_loop()) { | |
| 92 scoped_ptr<base::Thread> thread( | |
| 93 thread_factory_(filter->message_loop_name())); | |
| 94 | |
| 95 if (!thread.get() || !thread->Start()) { | |
| 96 return false; | |
| 97 } | |
| 98 | |
| 99 filter->set_message_loop(thread->message_loop()); | |
| 100 filter_threads_.push_back(thread.release()); | |
| 101 } | |
| 102 | |
| 103 // Register ourselves as the filter's host. | 66 // Register ourselves as the filter's host. |
| 104 filter->set_host(host_impl_.get()); | 67 filter->set_host(host_impl_.get()); |
| 105 filters_.push_back(make_scoped_refptr(filter.get())); | 68 filters_.push_back(make_scoped_refptr(filter.get())); |
| 106 return true; | 69 return true; |
| 107 } | 70 } |
| 108 | 71 |
| 109 const char* CompositeFilter::major_mime_type() const { | 72 const char* CompositeFilter::major_mime_type() const { |
| 110 return ""; | 73 return ""; |
| 111 } | 74 } |
| 112 | 75 |
| 113 void CompositeFilter::set_host(FilterHost* host) { | 76 void CompositeFilter::set_host(FilterHost* host) { |
| 114 DCHECK_EQ(message_loop_, MessageLoop::current()); | 77 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 115 DCHECK(host); | 78 DCHECK(host); |
| 116 DCHECK(!host_impl_.get()); | 79 DCHECK(!host_impl_.get()); |
| 117 host_impl_.reset(new FilterHostImpl(this, host)); | 80 host_impl_.reset(new FilterHostImpl(this, host)); |
| 118 } | 81 } |
| 119 | 82 |
| 120 FilterHost* CompositeFilter::host() { | 83 FilterHost* CompositeFilter::host() { |
| 121 return host_impl_.get() ? host_impl_->host() : NULL; | 84 return host_impl_.get() ? host_impl_->host() : NULL; |
| 122 } | 85 } |
| 123 | 86 |
| 124 bool CompositeFilter::requires_message_loop() const { | |
| 125 return false; | |
| 126 } | |
| 127 | |
| 128 const char* CompositeFilter::message_loop_name() const { | |
| 129 return "CompositeFilter"; | |
| 130 } | |
| 131 | |
| 132 void CompositeFilter::set_message_loop(MessageLoop* message_loop) { | |
| 133 NOTREACHED() << "Message loop should not be set."; | |
| 134 } | |
| 135 | |
| 136 MessageLoop* CompositeFilter::message_loop() { | |
| 137 return NULL; | |
| 138 } | |
| 139 | |
| 140 void CompositeFilter::Play(FilterCallback* play_callback) { | 87 void CompositeFilter::Play(FilterCallback* play_callback) { |
| 141 DCHECK_EQ(message_loop_, MessageLoop::current()); | 88 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 142 scoped_ptr<FilterCallback> callback(play_callback); | 89 scoped_ptr<FilterCallback> callback(play_callback); |
| 143 if (callback_.get()) { | 90 if (callback_.get()) { |
| 144 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING); | 91 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING); |
| 145 callback->Run(); | 92 callback->Run(); |
| 146 return; | 93 return; |
| 147 } else if (state_ == kPlaying) { | 94 } else if (state_ == kPlaying) { |
| 148 callback->Run(); | 95 callback->Run(); |
| 149 return; | 96 return; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 218 |
| 272 void CompositeFilter::OnAudioRendererDisabled() { | 219 void CompositeFilter::OnAudioRendererDisabled() { |
| 273 DCHECK_EQ(message_loop_, MessageLoop::current()); | 220 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 274 for (FilterVector::iterator iter = filters_.begin(); | 221 for (FilterVector::iterator iter = filters_.begin(); |
| 275 iter != filters_.end(); | 222 iter != filters_.end(); |
| 276 ++iter) { | 223 ++iter) { |
| 277 (*iter)->OnAudioRendererDisabled(); | 224 (*iter)->OnAudioRendererDisabled(); |
| 278 } | 225 } |
| 279 } | 226 } |
| 280 | 227 |
| 281 base::Thread* CompositeFilter::DefaultThreadFactory( | |
| 282 const char* thread_name) { | |
| 283 return new base::Thread(thread_name); | |
| 284 } | |
| 285 | |
| 286 void CompositeFilter::ChangeState(State new_state) { | 228 void CompositeFilter::ChangeState(State new_state) { |
| 287 DCHECK_EQ(message_loop_, MessageLoop::current()); | 229 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 288 state_ = new_state; | 230 state_ = new_state; |
| 289 } | 231 } |
| 290 | 232 |
| 291 void CompositeFilter::StartSerialCallSequence() { | 233 void CompositeFilter::StartSerialCallSequence() { |
| 292 DCHECK_EQ(message_loop_, MessageLoop::current()); | 234 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 293 error_ = PIPELINE_OK; | 235 error_ = PIPELINE_OK; |
| 294 | 236 |
| 295 if (filters_.size() > 0) { | 237 if (filters_.size() > 0) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 // to deal with errors it can't do anything about. | 464 // to deal with errors it can't do anything about. |
| 523 if (state_ == kStopPending || state_ == kStopped) | 465 if (state_ == kStopPending || state_ == kStopped) |
| 524 return; | 466 return; |
| 525 | 467 |
| 526 error_ = error; | 468 error_ = error; |
| 527 if (CanForwardError()) | 469 if (CanForwardError()) |
| 528 SendErrorToHost(error); | 470 SendErrorToHost(error); |
| 529 } | 471 } |
| 530 | 472 |
| 531 CompositeFilter::FilterHostImpl::FilterHostImpl(CompositeFilter* parent, | 473 CompositeFilter::FilterHostImpl::FilterHostImpl(CompositeFilter* parent, |
| 532 FilterHost* host) : | 474 FilterHost* host) |
| 533 parent_(parent), | 475 : parent_(parent), |
| 534 host_(host) { | 476 host_(host) { |
| 535 } | 477 } |
| 536 | 478 |
| 537 FilterHost* CompositeFilter::FilterHostImpl::host() { | 479 FilterHost* CompositeFilter::FilterHostImpl::host() { |
| 538 return host_; | 480 return host_; |
| 539 } | 481 } |
| 540 | 482 |
| 541 // media::FilterHost methods. | 483 // media::FilterHost methods. |
| 542 void CompositeFilter::FilterHostImpl::SetError(PipelineError error) { | 484 void CompositeFilter::FilterHostImpl::SetError(PipelineError error) { |
| 543 parent_->SetError(error); | 485 parent_->SetError(error); |
| 544 } | 486 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 | 542 |
| 601 void CompositeFilter::FilterHostImpl::SetCurrentReadPosition(int64 offset) { | 543 void CompositeFilter::FilterHostImpl::SetCurrentReadPosition(int64 offset) { |
| 602 host_->SetCurrentReadPosition(offset); | 544 host_->SetCurrentReadPosition(offset); |
| 603 } | 545 } |
| 604 | 546 |
| 605 int64 CompositeFilter::FilterHostImpl::GetCurrentReadPosition() { | 547 int64 CompositeFilter::FilterHostImpl::GetCurrentReadPosition() { |
| 606 return host_->GetCurrentReadPosition(); | 548 return host_->GetCurrentReadPosition(); |
| 607 } | 549 } |
| 608 | 550 |
| 609 } // namespace media | 551 } // namespace media |
| OLD | NEW |