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...) 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...) 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...) 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...) 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 |