| OLD | NEW |
| 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 NewRunnableMethod(this, &PipelineInternal::PlaybackRateChangedTask, | 321 NewRunnableMethod(this, &PipelineInternal::PlaybackRateChangedTask, |
| 322 playback_rate)); | 322 playback_rate)); |
| 323 } | 323 } |
| 324 | 324 |
| 325 // Called on client's thread. | 325 // Called on client's thread. |
| 326 void PipelineInternal::VolumeChanged(float volume) { | 326 void PipelineInternal::VolumeChanged(float volume) { |
| 327 message_loop_->PostTask(FROM_HERE, | 327 message_loop_->PostTask(FROM_HERE, |
| 328 NewRunnableMethod(this, &PipelineInternal::VolumeChangedTask, volume)); | 328 NewRunnableMethod(this, &PipelineInternal::VolumeChangedTask, volume)); |
| 329 } | 329 } |
| 330 | 330 |
| 331 // Called from any thread. | |
| 332 void PipelineInternal::InitializationComplete(FilterHostImpl* host) { | |
| 333 if (IsPipelineOk()) { | |
| 334 // Continue the initialize task by proceeding to the next stage. | |
| 335 message_loop_->PostTask(FROM_HERE, | |
| 336 NewRunnableMethod(this, &PipelineInternal::InitializeTask)); | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 // Called from any thread. Updates the pipeline time. | 331 // Called from any thread. Updates the pipeline time. |
| 341 void PipelineInternal::SetTime(base::TimeDelta time) { | 332 void PipelineInternal::SetTime(base::TimeDelta time) { |
| 342 // TODO(scherkus): why not post a task? | 333 // TODO(scherkus): why not post a task? |
| 343 pipeline_->SetTime(time); | 334 pipeline_->SetTime(time); |
| 344 } | 335 } |
| 345 | 336 |
| 346 // Called from any thread. Sets the pipeline |error_| member and destroys all | 337 // Called from any thread. Sets the pipeline |error_| member and destroys all |
| 347 // filters. | 338 // filters. |
| 348 void PipelineInternal::Error(PipelineError error) { | 339 void PipelineInternal::Error(PipelineError error) { |
| 349 message_loop_->PostTask(FROM_HERE, | 340 message_loop_->PostTask(FROM_HERE, |
| 350 NewRunnableMethod(this, &PipelineInternal::ErrorTask, error)); | 341 NewRunnableMethod(this, &PipelineInternal::ErrorTask, error)); |
| 351 } | 342 } |
| 352 | 343 |
| 344 // Called from any thread. |
| 345 void PipelineInternal::OnFilterInitialize() { |
| 346 // Continue the initialize task by proceeding to the next stage. |
| 347 message_loop_->PostTask(FROM_HERE, |
| 348 NewRunnableMethod(this, &PipelineInternal::InitializeTask)); |
| 349 } |
| 350 |
| 351 // Called from any thread. |
| 352 void PipelineInternal::OnFilterSeek() { |
| 353 // TODO(scherkus): have PipelineInternal wait to receive replies from every |
| 354 // filter before calling the client's |seek_callback_|. |
| 355 } |
| 356 |
| 353 void PipelineInternal::StartTask(FilterFactory* filter_factory, | 357 void PipelineInternal::StartTask(FilterFactory* filter_factory, |
| 354 const std::string& url, | 358 const std::string& url, |
| 355 PipelineCallback* start_callback) { | 359 PipelineCallback* start_callback) { |
| 356 DCHECK_EQ(MessageLoop::current(), message_loop_); | 360 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 357 DCHECK_EQ(kCreated, state_); | 361 DCHECK_EQ(kCreated, state_); |
| 358 filter_factory_ = filter_factory; | 362 filter_factory_ = filter_factory; |
| 359 url_ = url; | 363 url_ = url; |
| 360 start_callback_.reset(start_callback); | 364 start_callback_.reset(start_callback); |
| 361 | 365 |
| 362 // Kick off initialization. | 366 // Kick off initialization. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 376 // When all required filters have been created and have called their | 380 // When all required filters have been created and have called their |
| 377 // FilterHost's InitializationComplete() method, the pipeline will update its | 381 // FilterHost's InitializationComplete() method, the pipeline will update its |
| 378 // state to kStarted and |init_callback_|, will be executed. | 382 // state to kStarted and |init_callback_|, will be executed. |
| 379 // | 383 // |
| 380 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It | 384 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It |
| 381 // works like a big state change table. If we no longer need to start filters | 385 // works like a big state change table. If we no longer need to start filters |
| 382 // in order, we need to get rid of all the state change. | 386 // in order, we need to get rid of all the state change. |
| 383 void PipelineInternal::InitializeTask() { | 387 void PipelineInternal::InitializeTask() { |
| 384 DCHECK_EQ(MessageLoop::current(), message_loop_); | 388 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 385 | 389 |
| 386 // If we have received the stop signal, return immediately. | 390 // If we have received the stop or error signal, return immediately. |
| 387 if (state_ == kStopped) | 391 if (state_ == kStopped || state_ == kError) |
| 388 return; | 392 return; |
| 389 | 393 |
| 390 DCHECK(state_ == kCreated || IsPipelineInitializing()); | 394 DCHECK(state_ == kCreated || IsPipelineInitializing()); |
| 391 | 395 |
| 392 // Just created, create data source. | 396 // Just created, create data source. |
| 393 if (state_ == kCreated) { | 397 if (state_ == kCreated) { |
| 394 state_ = kInitDataSource; | 398 state_ = kInitDataSource; |
| 395 CreateDataSource(); | 399 CreateDataSource(); |
| 396 return; | 400 return; |
| 397 } | 401 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 seek_callback_.reset(seek_callback); | 548 seek_callback_.reset(seek_callback); |
| 545 | 549 |
| 546 // Supress seeking if we haven't fully started. | 550 // Supress seeking if we haven't fully started. |
| 547 if (state_ != kStarted) { | 551 if (state_ != kStarted) { |
| 548 return; | 552 return; |
| 549 } | 553 } |
| 550 | 554 |
| 551 for (FilterHostVector::iterator iter = filter_hosts_.begin(); | 555 for (FilterHostVector::iterator iter = filter_hosts_.begin(); |
| 552 iter != filter_hosts_.end(); | 556 iter != filter_hosts_.end(); |
| 553 ++iter) { | 557 ++iter) { |
| 554 (*iter)->media_filter()->Seek(time); | 558 (*iter)->media_filter()->Seek(time, |
| 559 NewCallback(this, &PipelineInternal::OnFilterSeek)); |
| 555 } | 560 } |
| 556 | 561 |
| 557 // TODO(hclam): we should set the time when the above seek operations were all | 562 // TODO(hclam): we should set the time when the above seek operations were all |
| 558 // successful and first frame/packet at the desired time is decoded. I'm | 563 // successful and first frame/packet at the desired time is decoded. I'm |
| 559 // setting the time here because once we do the callback the user can ask for | 564 // setting the time here because once we do the callback the user can ask for |
| 560 // current time immediately, which is the old time. In order to get rid this | 565 // current time immediately, which is the old time. In order to get rid this |
| 561 // little glitch, we either assume the seek was successful and time is updated | 566 // little glitch, we either assume the seek was successful and time is updated |
| 562 // immediately here or we set time and do callback when we have new | 567 // immediately here or we set time and do callback when we have new |
| 563 // frames/packets. | 568 // frames/packets. |
| 564 SetTime(time); | 569 SetTime(time); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 595 filter_threads_.push_back(thread.release()); | 600 filter_threads_.push_back(thread.release()); |
| 596 } | 601 } |
| 597 | 602 |
| 598 // Create the filter's host. | 603 // Create the filter's host. |
| 599 DCHECK(IsPipelineOk()); | 604 DCHECK(IsPipelineOk()); |
| 600 scoped_ptr<FilterHostImpl> host(new FilterHostImpl(this, filter.get())); | 605 scoped_ptr<FilterHostImpl> host(new FilterHostImpl(this, filter.get())); |
| 601 filter->set_host(host.get()); | 606 filter->set_host(host.get()); |
| 602 filter_hosts_.push_back(host.release()); | 607 filter_hosts_.push_back(host.release()); |
| 603 | 608 |
| 604 // Now initialize the filter. | 609 // Now initialize the filter. |
| 605 if (!filter->Initialize(source)) { | 610 filter->Initialize(source, |
| 606 Error(PIPELINE_ERROR_INITIALIZATION_FAILED); | 611 NewCallback(this, &PipelineInternal::OnFilterInitialize)); |
| 607 } | |
| 608 } | 612 } |
| 609 | 613 |
| 610 void PipelineInternal::CreateDataSource() { | 614 void PipelineInternal::CreateDataSource() { |
| 611 DCHECK_EQ(MessageLoop::current(), message_loop_); | 615 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 612 DCHECK(IsPipelineOk()); | 616 DCHECK(IsPipelineOk()); |
| 613 | 617 |
| 614 MediaFormat url_format; | 618 MediaFormat url_format; |
| 615 url_format.SetAsString(MediaFormat::kMimeType, mime_type::kURL); | 619 url_format.SetAsString(MediaFormat::kMimeType, mime_type::kURL); |
| 616 url_format.SetAsString(MediaFormat::kURL, url_); | 620 url_format.SetAsString(MediaFormat::kURL, url_); |
| 617 CreateFilter<DataSource>(filter_factory_, url_, url_format); | 621 CreateFilter<DataSource>(filter_factory_, url_, url_format); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 } | 726 } |
| 723 | 727 |
| 724 // Reset the pipeline, which will decrement a reference to this object. | 728 // Reset the pipeline, which will decrement a reference to this object. |
| 725 // We will get destroyed as soon as the remaining tasks finish executing. | 729 // We will get destroyed as soon as the remaining tasks finish executing. |
| 726 // To be safe, we'll set our pipeline reference to NULL. | 730 // To be safe, we'll set our pipeline reference to NULL. |
| 727 STLDeleteElements(&filter_hosts_); | 731 STLDeleteElements(&filter_hosts_); |
| 728 STLDeleteElements(&filter_threads_); | 732 STLDeleteElements(&filter_threads_); |
| 729 } | 733 } |
| 730 | 734 |
| 731 } // namespace media | 735 } // namespace media |
| OLD | NEW |