Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(892)

Side by Side Diff: media/base/pipeline_impl.cc

Issue 149215: Big media::Pipeline cleanup. (Closed)
Patch Set: Test Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/filters/video_renderer_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008-2009 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/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/condition_variable.h" 9 #include "base/condition_variable.h"
10 #include "base/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 } // namespace 47 } // namespace
48 48
49 PipelineImpl::PipelineImpl() { 49 PipelineImpl::PipelineImpl() {
50 ResetState(); 50 ResetState();
51 } 51 }
52 52
53 PipelineImpl::~PipelineImpl() { 53 PipelineImpl::~PipelineImpl() {
54 Stop(); 54 Stop();
55 } 55 }
56 56
57 bool PipelineImpl::IsInitialized() const {
58 AutoLock auto_lock(const_cast<Lock&>(lock_));
59 return initialized_;
60 }
61
62 base::TimeDelta PipelineImpl::GetDuration() const {
63 AutoLock auto_lock(const_cast<Lock&>(lock_));
64 return duration_;
65 }
66
67 base::TimeDelta PipelineImpl::GetBufferedTime() const {
68 AutoLock auto_lock(const_cast<Lock&>(lock_));
69 return buffered_time_;
70 }
71
72 int64 PipelineImpl::GetTotalBytes() const {
73 AutoLock auto_lock(const_cast<Lock&>(lock_));
74 return total_bytes_;
75 }
76
77 int64 PipelineImpl::GetBufferedBytes() const {
78 AutoLock auto_lock(const_cast<Lock&>(lock_));
79 return buffered_bytes_;
80 }
81
82 void PipelineImpl::GetVideoSize(size_t* width_out, size_t* height_out) const {
83 DCHECK(width_out);
84 DCHECK(height_out);
85 AutoLock auto_lock(const_cast<Lock&>(lock_));
86 *width_out = video_width_;
87 *height_out = video_height_;
88 }
89
90 float PipelineImpl::GetVolume() const {
91 AutoLock auto_lock(const_cast<Lock&>(lock_));
92 return volume_;
93 }
94
95 float PipelineImpl::GetPlaybackRate() const {
96 AutoLock auto_lock(const_cast<Lock&>(lock_));
97 return playback_rate_;
98 }
99
100 base::TimeDelta PipelineImpl::GetTime() const {
101 AutoLock auto_lock(const_cast<Lock&>(lock_));
102 return time_;
103 }
104
105 base::TimeDelta PipelineImpl::GetInterpolatedTime() const {
106 AutoLock auto_lock(const_cast<Lock&>(lock_));
107 base::TimeDelta time = time_;
108 if (playback_rate_ > 0.0f) {
109 base::TimeDelta delta = base::TimeTicks::Now() - ticks_at_last_set_time_;
110 if (playback_rate_ == 1.0f) {
111 time += delta;
112 } else {
113 int64 adjusted_delta = static_cast<int64>(delta.InMicroseconds() *
114 playback_rate_);
115 time += base::TimeDelta::FromMicroseconds(adjusted_delta);
116 }
117 }
118 return time;
119 }
120
121 void PipelineImpl::SetTime(base::TimeDelta time) {
122 AutoLock auto_lock(lock_);
123 time_ = time;
124 ticks_at_last_set_time_ = base::TimeTicks::Now();
125 }
126
127 void PipelineImpl::InternalSetPlaybackRate(float rate) {
128 AutoLock auto_lock(lock_);
129 if (playback_rate_ == 0.0f && rate > 0.0f) {
130 ticks_at_last_set_time_ = base::TimeTicks::Now();
131 }
132 playback_rate_ = rate;
133 }
134
135 PipelineError PipelineImpl::GetError() const {
136 AutoLock auto_lock(const_cast<Lock&>(lock_));
137 return error_;
138 }
139
140 bool PipelineImpl::IsRendered(const std::string& major_mime_type) const {
141 AutoLock auto_lock(const_cast<Lock&>(lock_));
142 bool is_rendered = (rendered_mime_types_.find(major_mime_type) !=
143 rendered_mime_types_.end());
144 return is_rendered;
145 }
146
147
148 bool PipelineImpl::InternalSetError(PipelineError error) {
149 // Don't want callers to set an error of "OK". STOPPING is a special value
150 // that should only be used internally by the StopTask() method.
151 DCHECK(PIPELINE_OK != error && PIPELINE_STOPPING != error);
152 AutoLock auto_lock(lock_);
153 bool changed_error = false;
154 if (PIPELINE_OK == error_) {
155 error_ = error;
156 changed_error = true;
157 }
158 return changed_error;
159 }
160
161 // Creates the PipelineThread and calls it's start method. 57 // Creates the PipelineThread and calls it's start method.
162 bool PipelineImpl::Start(FilterFactory* factory, 58 bool PipelineImpl::Start(FilterFactory* factory,
163 const std::string& url, 59 const std::string& url,
164 PipelineCallback* init_complete_callback) { 60 PipelineCallback* init_complete_callback) {
165 DCHECK(!pipeline_thread_); 61 DCHECK(!pipeline_thread_);
166 DCHECK(factory); 62 DCHECK(factory);
167 DCHECK(!initialized_); 63 DCHECK(!initialized_);
168 DCHECK(!IsPipelineThread()); 64 DCHECK(!IsPipelineThread());
169 if (!pipeline_thread_ && factory) { 65 if (!pipeline_thread_ && factory) {
170 pipeline_thread_ = new PipelineThread(this); 66 pipeline_thread_ = new PipelineThread(this);
(...skipping 14 matching lines...) Expand all
185 // created PipelineImpl object. 81 // created PipelineImpl object.
186 void PipelineImpl::Stop() { 82 void PipelineImpl::Stop() {
187 DCHECK(!IsPipelineThread()); 83 DCHECK(!IsPipelineThread());
188 84
189 if (pipeline_thread_) { 85 if (pipeline_thread_) {
190 pipeline_thread_->Stop(); 86 pipeline_thread_->Stop();
191 } 87 }
192 ResetState(); 88 ResetState();
193 } 89 }
194 90
91 void PipelineImpl::Seek(base::TimeDelta time,
92 PipelineCallback* seek_callback) {
93 DCHECK(!IsPipelineThread());
94
95 if (IsPipelineOk()) {
96 pipeline_thread_->Seek(time, seek_callback);
97 } else {
98 NOTREACHED();
99 }
100 }
101
102 bool PipelineImpl::IsInitialized() const {
103 AutoLock auto_lock(lock_);
104 return initialized_;
105 }
106
107 bool PipelineImpl::IsRendered(const std::string& major_mime_type) const {
108 AutoLock auto_lock(lock_);
109 bool is_rendered = (rendered_mime_types_.find(major_mime_type) !=
110 rendered_mime_types_.end());
111 return is_rendered;
112 }
113
114 float PipelineImpl::GetPlaybackRate() const {
115 AutoLock auto_lock(lock_);
116 return playback_rate_;
117 }
118
195 void PipelineImpl::SetPlaybackRate(float rate) { 119 void PipelineImpl::SetPlaybackRate(float rate) {
196 DCHECK(!IsPipelineThread()); 120 DCHECK(!IsPipelineThread());
197 121
198 if (IsPipelineOk() && rate >= 0.0f) { 122 if (IsPipelineOk() && rate >= 0.0f) {
199 pipeline_thread_->SetPlaybackRate(rate); 123 pipeline_thread_->SetPlaybackRate(rate);
200 } else { 124 } else {
201 // It's OK for a client to call SetPlaybackRate(0.0f) if we're stopped. 125 // It's OK for a client to call SetPlaybackRate(0.0f) if we're stopped.
202 DCHECK(rate == 0.0f && playback_rate_ == 0.0f); 126 DCHECK(rate == 0.0f && playback_rate_ == 0.0f);
203 } 127 }
204 } 128 }
205 129
206 void PipelineImpl::Seek(base::TimeDelta time, 130 float PipelineImpl::GetVolume() const {
207 PipelineCallback* seek_callback) { 131 AutoLock auto_lock(lock_);
208 DCHECK(!IsPipelineThread()); 132 return volume_;
209
210 if (IsPipelineOk()) {
211 pipeline_thread_->Seek(time, seek_callback);
212 } else {
213 NOTREACHED();
214 }
215 } 133 }
216 134
217 void PipelineImpl::SetVolume(float volume) { 135 void PipelineImpl::SetVolume(float volume) {
218 DCHECK(!IsPipelineThread()); 136 DCHECK(!IsPipelineThread());
219 137
220 if (IsPipelineOk() && volume >= 0.0f && volume <= 1.0f) { 138 if (IsPipelineOk() && volume >= 0.0f && volume <= 1.0f) {
221 pipeline_thread_->SetVolume(volume); 139 pipeline_thread_->SetVolume(volume);
222 } else { 140 } else {
223 NOTREACHED(); 141 NOTREACHED();
224 } 142 }
225 } 143 }
226 144
145 base::TimeDelta PipelineImpl::GetTime() const {
146 AutoLock auto_lock(lock_);
147 return time_;
148 }
149
150 base::TimeDelta PipelineImpl::GetBufferedTime() const {
151 AutoLock auto_lock(lock_);
152 return buffered_time_;
153 }
154
155 base::TimeDelta PipelineImpl::GetDuration() const {
156 AutoLock auto_lock(lock_);
157 return duration_;
158 }
159
160 int64 PipelineImpl::GetBufferedBytes() const {
161 AutoLock auto_lock(lock_);
162 return buffered_bytes_;
163 }
164
165 int64 PipelineImpl::GetTotalBytes() const {
166 AutoLock auto_lock(lock_);
167 return total_bytes_;
168 }
169
170 void PipelineImpl::GetVideoSize(size_t* width_out, size_t* height_out) const {
171 CHECK(width_out);
172 CHECK(height_out);
173 AutoLock auto_lock(lock_);
174 *width_out = video_width_;
175 *height_out = video_height_;
176 }
177
178 PipelineError PipelineImpl::GetError() const {
179 AutoLock auto_lock(lock_);
180 return error_;
181 }
182
227 void PipelineImpl::ResetState() { 183 void PipelineImpl::ResetState() {
228 AutoLock auto_lock(lock_); 184 AutoLock auto_lock(lock_);
229 pipeline_thread_ = NULL; 185 pipeline_thread_ = NULL;
230 initialized_ = false; 186 initialized_ = false;
231 duration_ = base::TimeDelta(); 187 duration_ = base::TimeDelta();
232 buffered_time_ = base::TimeDelta(); 188 buffered_time_ = base::TimeDelta();
233 buffered_bytes_ = 0; 189 buffered_bytes_ = 0;
234 total_bytes_ = 0; 190 total_bytes_ = 0;
235 video_width_ = 0; 191 video_width_ = 0;
236 video_height_ = 0; 192 video_height_ = 0;
237 volume_ = 0.0f; 193 volume_ = 0.0f;
238 playback_rate_ = 0.0f; 194 playback_rate_ = 0.0f;
239 error_ = PIPELINE_OK; 195 error_ = PIPELINE_OK;
240 time_ = base::TimeDelta(); 196 time_ = base::TimeDelta();
241 ticks_at_last_set_time_ = base::TimeTicks::Now();
242 rendered_mime_types_.clear(); 197 rendered_mime_types_.clear();
243 } 198 }
244 199
245 bool PipelineImpl::IsPipelineOk() const { 200 bool PipelineImpl::IsPipelineOk() const {
246 return pipeline_thread_ && initialized_ && PIPELINE_OK == error_; 201 return pipeline_thread_ && initialized_ && PIPELINE_OK == error_;
247 } 202 }
248 203
249 bool PipelineImpl::IsPipelineThread() const { 204 bool PipelineImpl::IsPipelineThread() const {
250 return pipeline_thread_ && 205 return pipeline_thread_ &&
251 PlatformThread::CurrentId() == pipeline_thread_->thread_id(); 206 PlatformThread::CurrentId() == pipeline_thread_->thread_id();
(...skipping 18 matching lines...) Expand all
270 AutoLock auto_lock(lock_); 225 AutoLock auto_lock(lock_);
271 buffered_bytes_ = buffered_bytes; 226 buffered_bytes_ = buffered_bytes;
272 } 227 }
273 228
274 void PipelineImpl::SetVideoSize(size_t width, size_t height) { 229 void PipelineImpl::SetVideoSize(size_t width, size_t height) {
275 AutoLock auto_lock(lock_); 230 AutoLock auto_lock(lock_);
276 video_width_ = width; 231 video_width_ = width;
277 video_height_ = height; 232 video_height_ = height;
278 } 233 }
279 234
235 void PipelineImpl::SetTime(base::TimeDelta time) {
236 AutoLock auto_lock(lock_);
237 time_ = time;
238 }
239
240 void PipelineImpl::InternalSetPlaybackRate(float rate) {
241 AutoLock auto_lock(lock_);
242 playback_rate_ = rate;
243 }
244
245 bool PipelineImpl::InternalSetError(PipelineError error) {
246 // Don't want callers to set an error of "OK". STOPPING is a special value
247 // that should only be used internally by the StopTask() method.
248 DCHECK(PIPELINE_OK != error && PIPELINE_STOPPING != error);
249 AutoLock auto_lock(lock_);
250 bool changed_error = false;
251 if (PIPELINE_OK == error_) {
252 error_ = error;
253 changed_error = true;
254 }
255 return changed_error;
256 }
257
280 void PipelineImpl::InsertRenderedMimeType(const std::string& major_mime_type) { 258 void PipelineImpl::InsertRenderedMimeType(const std::string& major_mime_type) {
281 AutoLock auto_lock(lock_); 259 AutoLock auto_lock(lock_);
282 rendered_mime_types_.insert(major_mime_type); 260 rendered_mime_types_.insert(major_mime_type);
283 } 261 }
284 262
285 263
286 //----------------------------------------------------------------------------- 264 //-----------------------------------------------------------------------------
287 265
288 PipelineThread::PipelineThread(PipelineImpl* pipeline) 266 PipelineThread::PipelineThread(PipelineImpl* pipeline)
289 : pipeline_(pipeline), 267 : pipeline_(pipeline),
290 thread_("PipelineThread"), 268 thread_("PipelineThread"),
291 time_update_callback_scheduled_(false),
292 state_(kCreated) { 269 state_(kCreated) {
293 } 270 }
294 271
295 PipelineThread::~PipelineThread() { 272 PipelineThread::~PipelineThread() {
296 Stop(); 273 Stop();
297 DCHECK(state_ == kStopped || state_ == kError); 274 DCHECK(state_ == kStopped || state_ == kError);
298 } 275 }
299 276
300 // This method is called on the client's thread. It starts the pipeline's 277 // This method is called on the client's thread. It starts the pipeline's
301 // dedicated thread and posts a task to call the StartTask() method on that 278 // dedicated thread and posts a task to call the StartTask() method on that
302 // thread. 279 // thread.
303 bool PipelineThread::Start(FilterFactory* filter_factory, 280 bool PipelineThread::Start(FilterFactory* filter_factory,
304 const std::string& url, 281 const std::string& url,
305 PipelineCallback* init_complete_callback) { 282 PipelineCallback* init_complete_callback) {
306 DCHECK_EQ(kCreated, state_); 283 DCHECK_EQ(kCreated, state_);
307 if (thread_.Start()) { 284 if (thread_.Start()) {
308 filter_factory_ = filter_factory; 285 filter_factory_ = filter_factory;
309 url_ = url; 286 url_ = url;
310 init_callback_.reset(init_complete_callback); 287 init_callback_.reset(init_complete_callback);
311 PostTask(NewRunnableMethod(this, &PipelineThread::StartTask)); 288 message_loop()->PostTask(FROM_HERE,
289 NewRunnableMethod(this, &PipelineThread::StartTask));
312 return true; 290 return true;
313 } 291 }
314 return false; 292 return false;
315 } 293 }
316 294
317 // Called on the client's thread. If the thread has been started, then posts 295 // Called on the client's thread. If the thread has been started, then posts
318 // a task to call the StopTask() method, then waits until the thread has 296 // a task to call the StopTask() method, then waits until the thread has
319 // stopped. 297 // stopped.
320 void PipelineThread::Stop() { 298 void PipelineThread::Stop() {
321 if (thread_.IsRunning()) { 299 if (thread_.IsRunning()) {
322 PostTask(NewRunnableMethod(this, &PipelineThread::StopTask)); 300 message_loop()->PostTask(FROM_HERE,
301 NewRunnableMethod(this, &PipelineThread::StopTask));
323 thread_.Stop(); 302 thread_.Stop();
324 } 303 }
325 DCHECK(filter_hosts_.empty()); 304 DCHECK(filter_hosts_.empty());
326 DCHECK(filter_threads_.empty()); 305 DCHECK(filter_threads_.empty());
327 } 306 }
328 307
329 // Called on client's thread. 308 // Called on client's thread.
330 void PipelineThread::SetPlaybackRate(float rate) {
331 PostTask(NewRunnableMethod(this, &PipelineThread::SetPlaybackRateTask, rate));
332 }
333
334 // Called on client's thread.
335 void PipelineThread::Seek(base::TimeDelta time, 309 void PipelineThread::Seek(base::TimeDelta time,
336 PipelineCallback* seek_callback) { 310 PipelineCallback* seek_callback) {
337 PostTask(NewRunnableMethod(this, &PipelineThread::SeekTask, time, 311 message_loop()->PostTask(FROM_HERE,
338 seek_callback)); 312 NewRunnableMethod(this, &PipelineThread::SeekTask, time, seek_callback));
313 }
314
315 // Called on client's thread.
316 void PipelineThread::SetPlaybackRate(float rate) {
317 message_loop()->PostTask(FROM_HERE,
318 NewRunnableMethod(this, &PipelineThread::SetPlaybackRateTask, rate));
339 } 319 }
340 320
341 // Called on client's thread. 321 // Called on client's thread.
342 void PipelineThread::SetVolume(float volume) { 322 void PipelineThread::SetVolume(float volume) {
343 PostTask(NewRunnableMethod(this, &PipelineThread::SetVolumeTask, volume)); 323 message_loop()->PostTask(FROM_HERE,
324 NewRunnableMethod(this, &PipelineThread::SetVolumeTask, volume));
344 } 325 }
345 326
327 // Called from any thread.
346 void PipelineThread::InitializationComplete(FilterHostImpl* host) { 328 void PipelineThread::InitializationComplete(FilterHostImpl* host) {
347 if (IsPipelineOk()) { 329 if (IsPipelineOk()) {
348 // Continue the start task by proceeding to the next stage. 330 // Continue the start task by proceeding to the next stage.
349 PostTask(NewRunnableMethod(this, &PipelineThread::StartTask)); 331 message_loop()->PostTask(FROM_HERE,
332 NewRunnableMethod(this, &PipelineThread::StartTask));
350 } 333 }
351 } 334 }
352 335
353 // Called from any thread. Updates the pipeline time and schedules a task to 336 // Called from any thread. Updates the pipeline time.
354 // call back to filters that have registered a callback for time updates.
355 void PipelineThread::SetTime(base::TimeDelta time) { 337 void PipelineThread::SetTime(base::TimeDelta time) {
356 pipeline()->SetTime(time); 338 pipeline()->SetTime(time);
357 if (!time_update_callback_scheduled_) {
358 time_update_callback_scheduled_ = true;
359 PostTask(NewRunnableMethod(this, &PipelineThread::SetTimeTask));
360 }
361 } 339 }
362 340
363 // Called from any thread. Sets the pipeline |error_| member and schedules a 341 // Called from any thread. Sets the pipeline |error_| member and schedules a
364 // task to stop all the filters in the pipeline. Note that the thread will 342 // task to stop all the filters in the pipeline. Note that the thread will
365 // continue to run until the client calls Pipeline::Stop(), but nothing will 343 // continue to run until the client calls Pipeline::Stop(), but nothing will
366 // be processed since filters will not be able to post tasks. 344 // be processed since filters will not be able to post tasks.
367 void PipelineThread::Error(PipelineError error) { 345 void PipelineThread::Error(PipelineError error) {
368 // If this method returns false, then an error has already happened, so no 346 // If this method returns false, then an error has already happened, so no
369 // reason to run the StopTask again. It's going to happen. 347 // reason to run the StopTask again. It's going to happen.
370 if (pipeline()->InternalSetError(error)) { 348 if (pipeline()->InternalSetError(error)) {
371 PostTask(NewRunnableMethod(this, &PipelineThread::StopTask)); 349 message_loop()->PostTask(FROM_HERE,
350 NewRunnableMethod(this, &PipelineThread::StopTask));
372 } 351 }
373 } 352 }
374 353
375 // This is a helper method to post task on message_loop(). This method is only 354 // Called as a result of destruction of the thread.
376 // called from this class or from Pipeline. 355 //
377 void PipelineThread::PostTask(Task* task) { 356 // TODO(scherkus): this can block the client due to synchronous Stop() API call.
378 message_loop()->PostTask(FROM_HERE, task); 357 void PipelineThread::WillDestroyCurrentMessageLoop() {
358 STLDeleteElements(&filter_hosts_);
359 STLDeleteElements(&filter_threads_);
379 } 360 }
380 361
381
382 // Main initialization method called on the pipeline thread. This code attempts 362 // Main initialization method called on the pipeline thread. This code attempts
383 // to use the specified filter factory to build a pipeline. 363 // to use the specified filter factory to build a pipeline.
384 // Initialization step performed in this method depends on current state of this 364 // Initialization step performed in this method depends on current state of this
385 // object, indicated by |state_|. After each step of initialization, this 365 // object, indicated by |state_|. After each step of initialization, this
386 // object transits to the next stage. It starts by creating a DataSource, 366 // object transits to the next stage. It starts by creating a DataSource,
387 // connects it to a Demuxer, and then connects the Demuxer's audio stream to an 367 // connects it to a Demuxer, and then connects the Demuxer's audio stream to an
388 // AudioDecoder which is then connected to an AudioRenderer. If the media has 368 // AudioDecoder which is then connected to an AudioRenderer. If the media has
389 // video, then it connects a VideoDecoder to the Demuxer's video stream, and 369 // video, then it connects a VideoDecoder to the Demuxer's video stream, and
390 // then connects the VideoDecoder to a VideoRenderer. 370 // then connects the VideoDecoder to a VideoRenderer.
391 // 371 //
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id()); 576 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
597 577
598 pipeline_->volume_ = volume; 578 pipeline_->volume_ = volume;
599 scoped_refptr<AudioRenderer> audio_renderer; 579 scoped_refptr<AudioRenderer> audio_renderer;
600 GetFilter(&audio_renderer); 580 GetFilter(&audio_renderer);
601 if (audio_renderer) { 581 if (audio_renderer) {
602 audio_renderer->SetVolume(volume); 582 audio_renderer->SetVolume(volume);
603 } 583 }
604 } 584 }
605 585
606 void PipelineThread::SetTimeTask() {
607 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
608
609 time_update_callback_scheduled_ = false;
610 for (FilterHostVector::iterator iter = filter_hosts_.begin();
611 iter != filter_hosts_.end();
612 ++iter) {
613 (*iter)->RunTimeUpdateCallback(pipeline_->time_);
614 }
615 }
616
617 template <class Filter>
618 void PipelineThread::GetFilter(scoped_refptr<Filter>* filter_out) const {
619 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
620
621 *filter_out = NULL;
622 for (FilterHostVector::const_iterator iter = filter_hosts_.begin();
623 iter != filter_hosts_.end() && NULL == *filter_out;
624 iter++) {
625 (*iter)->GetFilter(filter_out);
626 }
627 }
628
629 template <class Filter, class Source> 586 template <class Filter, class Source>
630 void PipelineThread::CreateFilter(FilterFactory* filter_factory, 587 void PipelineThread::CreateFilter(FilterFactory* filter_factory,
631 Source source, 588 Source source,
632 const MediaFormat& media_format) { 589 const MediaFormat& media_format) {
633 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id()); 590 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
634 DCHECK(IsPipelineOk()); 591 DCHECK(IsPipelineOk());
635 592
636 scoped_refptr<Filter> filter = filter_factory->Create<Filter>(media_format); 593 scoped_refptr<Filter> filter = filter_factory->Create<Filter>(media_format);
637 if (!filter) { 594 if (!filter) {
638 Error(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 595 Error(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 673
717 if (decoder) { 674 if (decoder) {
718 // If the decoder was created. 675 // If the decoder was created.
719 const std::string major_mime_type = Decoder::major_mime_type(); 676 const std::string major_mime_type = Decoder::major_mime_type();
720 CreateFilter<Renderer, Decoder>(filter_factory_, decoder); 677 CreateFilter<Renderer, Decoder>(filter_factory_, decoder);
721 return true; 678 return true;
722 } 679 }
723 return false; 680 return false;
724 } 681 }
725 682
726 // Called as a result of destruction of the thread. 683 template <class Filter>
727 // 684 void PipelineThread::GetFilter(scoped_refptr<Filter>* filter_out) const {
728 // TODO(scherkus): this can block the client due to synchronous Stop() API call. 685 DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
729 void PipelineThread::WillDestroyCurrentMessageLoop() { 686
730 STLDeleteElements(&filter_hosts_); 687 *filter_out = NULL;
731 STLDeleteElements(&filter_threads_); 688 for (FilterHostVector::const_iterator iter = filter_hosts_.begin();
689 iter != filter_hosts_.end() && NULL == *filter_out;
690 iter++) {
691 (*iter)->GetFilter(filter_out);
692 }
732 } 693 }
733 694
734 } // namespace media 695 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/filters/video_renderer_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698