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

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

Issue 6686061: PipelineError is dead. Long live PipelineStatus! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Double-delete fix for PipelineStatusNotification Created 9 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/stl_util-inl.h" 10 #include "base/stl_util-inl.h"
11 #include "base/synchronization/condition_variable.h" 11 #include "base/synchronization/condition_variable.h"
12 #include "media/base/clock.h" 12 #include "media/base/clock.h"
13 #include "media/base/filter_collection.h" 13 #include "media/base/filter_collection.h"
14 #include "media/base/media_format.h" 14 #include "media/base/media_format.h"
15 #include "media/base/pipeline_impl.h" 15 #include "media/base/pipeline_impl.h"
16 16
17 namespace media { 17 namespace media {
18 18
19 PipelineStatusNotification::PipelineStatusNotification()
20 : cv_(&lock_), status_(PIPELINE_OK), notified_(false) {
21 callback_.reset(::NewCallback(this, &PipelineStatusNotification::Notify));
acolwell GONE FROM CHROMIUM 2011/03/15 03:56:28 Is :: necessary here?
Ami GONE FROM CHROMIUM 2011/03/15 17:37:18 Not anymore (it used to be, back when I had PSN::C
22 }
23
24 PipelineStatusNotification::~PipelineStatusNotification() {
25 DCHECK(notified_);
26 }
27
28 media::PipelineStatusCallback* PipelineStatusNotification::Callback() {
29 return callback_.release();
30 }
31
32 void PipelineStatusNotification::Notify(media::PipelineStatus status) {
33 base::AutoLock auto_lock(lock_);
34 DCHECK(!notified_);
35 notified_ = true;
36 status_ = status;
37 cv_.Signal();
38 }
39
40 void PipelineStatusNotification::Wait() {
41 base::AutoLock auto_lock(lock_);
42 while (!notified_)
43 cv_.Wait();
44 }
45
46 media::PipelineStatus PipelineStatusNotification::status() {
47 base::AutoLock auto_lock(lock_);
48 DCHECK(notified_);
49 return status_;
50 }
51
19 class PipelineImpl::PipelineInitState { 52 class PipelineImpl::PipelineInitState {
20 public: 53 public:
21 scoped_refptr<Demuxer> demuxer_; 54 scoped_refptr<Demuxer> demuxer_;
22 scoped_refptr<AudioDecoder> audio_decoder_; 55 scoped_refptr<AudioDecoder> audio_decoder_;
23 scoped_refptr<VideoDecoder> video_decoder_; 56 scoped_refptr<VideoDecoder> video_decoder_;
24 scoped_refptr<CompositeFilter> composite_; 57 scoped_refptr<CompositeFilter> composite_;
25 }; 58 };
26 59
27 PipelineImpl::PipelineImpl(MessageLoop* message_loop) 60 PipelineImpl::PipelineImpl(MessageLoop* message_loop)
28 : message_loop_(message_loop), 61 : message_loop_(message_loop),
29 clock_(new Clock(&base::Time::Now)), 62 clock_(new Clock(&base::Time::Now)),
30 waiting_for_clock_update_(false), 63 waiting_for_clock_update_(false),
31 state_(kCreated), 64 state_(kCreated),
32 current_bytes_(0) { 65 current_bytes_(0) {
33 ResetState(); 66 ResetState();
34 } 67 }
35 68
36 PipelineImpl::~PipelineImpl() { 69 PipelineImpl::~PipelineImpl() {
37 base::AutoLock auto_lock(lock_); 70 base::AutoLock auto_lock(lock_);
38 DCHECK(!running_) << "Stop() must complete before destroying object"; 71 DCHECK(!running_) << "Stop() must complete before destroying object";
39 DCHECK(!stop_pending_); 72 DCHECK(!stop_pending_);
40 DCHECK(!seek_pending_); 73 DCHECK(!seek_pending_);
41 } 74 }
42 75
43 void PipelineImpl::Init(PipelineCallback* ended_callback, 76 void PipelineImpl::Init(PipelineStatusCallback* ended_callback,
44 PipelineCallback* error_callback, 77 PipelineStatusCallback* error_callback,
45 PipelineCallback* network_callback) { 78 PipelineStatusCallback* network_callback) {
46 DCHECK(!IsRunning()) 79 DCHECK(!IsRunning())
47 << "Init() should be called before the pipeline has started"; 80 << "Init() should be called before the pipeline has started";
48 ended_callback_.reset(ended_callback); 81 ended_callback_.reset(ended_callback);
49 error_callback_.reset(error_callback); 82 error_callback_.reset(error_callback);
50 network_callback_.reset(network_callback); 83 network_callback_.reset(network_callback);
51 } 84 }
52 85
53 // Creates the PipelineInternal and calls it's start method. 86 // Creates the PipelineInternal and calls it's start method.
54 bool PipelineImpl::Start(FilterCollection* collection, 87 bool PipelineImpl::Start(FilterCollection* collection,
55 const std::string& url, 88 const std::string& url,
56 PipelineCallback* start_callback) { 89 PipelineStatusCallback* start_callback) {
57 base::AutoLock auto_lock(lock_); 90 base::AutoLock auto_lock(lock_);
58 scoped_ptr<PipelineCallback> callback(start_callback); 91 scoped_ptr<PipelineStatusCallback> callback(start_callback);
59 scoped_ptr<FilterCollection> filter_collection(collection); 92 scoped_ptr<FilterCollection> filter_collection(collection);
60 93
61 if (running_) { 94 if (running_) {
62 VLOG(1) << "Media pipeline is already running"; 95 VLOG(1) << "Media pipeline is already running";
63 return false; 96 return false;
64 } 97 }
65 98
66 if (collection->IsEmpty()) { 99 if (collection->IsEmpty()) {
67 return false; 100 return false;
68 } 101 }
69 102
70 // Kick off initialization! 103 // Kick off initialization!
71 running_ = true; 104 running_ = true;
72 message_loop_->PostTask( 105 message_loop_->PostTask(
73 FROM_HERE, 106 FROM_HERE,
74 NewRunnableMethod(this, 107 NewRunnableMethod(this,
75 &PipelineImpl::StartTask, 108 &PipelineImpl::StartTask,
76 filter_collection.release(), 109 filter_collection.release(),
77 url, 110 url,
78 callback.release())); 111 callback.release()));
79 return true; 112 return true;
80 } 113 }
81 114
82 void PipelineImpl::Stop(PipelineCallback* stop_callback) { 115 void PipelineImpl::Stop(PipelineStatusCallback* stop_callback) {
83 base::AutoLock auto_lock(lock_); 116 base::AutoLock auto_lock(lock_);
84 scoped_ptr<PipelineCallback> callback(stop_callback); 117 scoped_ptr<PipelineStatusCallback> callback(stop_callback);
85 if (!running_) { 118 if (!running_) {
86 VLOG(1) << "Media pipeline has already stopped"; 119 VLOG(1) << "Media pipeline has already stopped";
87 return; 120 return;
88 } 121 }
89 122
90 // Stop the pipeline, which will set |running_| to false on behalf. 123 // Stop the pipeline, which will set |running_| to false on behalf.
91 message_loop_->PostTask(FROM_HERE, 124 message_loop_->PostTask(FROM_HERE,
92 NewRunnableMethod(this, &PipelineImpl::StopTask, callback.release())); 125 NewRunnableMethod(this, &PipelineImpl::StopTask, callback.release()));
93 } 126 }
94 127
95 void PipelineImpl::Seek(base::TimeDelta time, 128 void PipelineImpl::Seek(base::TimeDelta time,
96 PipelineCallback* seek_callback) { 129 PipelineStatusCallback* seek_callback) {
97 base::AutoLock auto_lock(lock_); 130 base::AutoLock auto_lock(lock_);
98 scoped_ptr<PipelineCallback> callback(seek_callback); 131 scoped_ptr<PipelineStatusCallback> callback(seek_callback);
99 if (!running_) { 132 if (!running_) {
100 VLOG(1) << "Media pipeline must be running"; 133 VLOG(1) << "Media pipeline must be running";
101 return; 134 return;
102 } 135 }
103 136
104 message_loop_->PostTask(FROM_HERE, 137 message_loop_->PostTask(FROM_HERE,
105 NewRunnableMethod(this, &PipelineImpl::SeekTask, time, 138 NewRunnableMethod(this, &PipelineImpl::SeekTask, time,
106 callback.release())); 139 callback.release()));
107 } 140 }
108 141
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 bool PipelineImpl::IsStreaming() const { 297 bool PipelineImpl::IsStreaming() const {
265 base::AutoLock auto_lock(lock_); 298 base::AutoLock auto_lock(lock_);
266 return streaming_; 299 return streaming_;
267 } 300 }
268 301
269 bool PipelineImpl::IsLoaded() const { 302 bool PipelineImpl::IsLoaded() const {
270 base::AutoLock auto_lock(lock_); 303 base::AutoLock auto_lock(lock_);
271 return loaded_; 304 return loaded_;
272 } 305 }
273 306
274 PipelineError PipelineImpl::GetError() const {
275 base::AutoLock auto_lock(lock_);
276 return error_;
277 }
278
279 PipelineStatistics PipelineImpl::GetStatistics() const { 307 PipelineStatistics PipelineImpl::GetStatistics() const {
280 base::AutoLock auto_lock(lock_); 308 base::AutoLock auto_lock(lock_);
281 return statistics_; 309 return statistics_;
282 } 310 }
283 311
284 void PipelineImpl::SetClockForTesting(Clock* clock) { 312 void PipelineImpl::SetClockForTesting(Clock* clock) {
285 clock_.reset(clock); 313 clock_.reset(clock);
286 } 314 }
287 315
288 void PipelineImpl::SetCurrentReadPosition(int64 offset) { 316 void PipelineImpl::SetCurrentReadPosition(int64 offset) {
(...skipping 26 matching lines...) Expand all
315 duration_ = kZero; 343 duration_ = kZero;
316 buffered_time_ = kZero; 344 buffered_time_ = kZero;
317 buffered_bytes_ = 0; 345 buffered_bytes_ = 0;
318 streaming_ = false; 346 streaming_ = false;
319 loaded_ = false; 347 loaded_ = false;
320 total_bytes_ = 0; 348 total_bytes_ = 0;
321 video_width_ = 0; 349 video_width_ = 0;
322 video_height_ = 0; 350 video_height_ = 0;
323 volume_ = 1.0f; 351 volume_ = 1.0f;
324 playback_rate_ = 0.0f; 352 playback_rate_ = 0.0f;
325 error_ = PIPELINE_OK; 353 status_ = PIPELINE_OK;
326 has_audio_ = false; 354 has_audio_ = false;
327 has_video_ = false; 355 has_video_ = false;
328 waiting_for_clock_update_ = false; 356 waiting_for_clock_update_ = false;
329 audio_disabled_ = false; 357 audio_disabled_ = false;
330 clock_->SetTime(kZero); 358 clock_->SetTime(kZero);
331 } 359 }
332 360
333 void PipelineImpl::set_state(State next_state) { 361 void PipelineImpl::set_state(State next_state) {
334 state_ = next_state; 362 state_ = next_state;
335 } 363 }
336 364
337 bool PipelineImpl::IsPipelineOk() { 365 bool PipelineImpl::IsPipelineOk() {
338 return PIPELINE_OK == GetError(); 366 base::AutoLock auto_lock(lock_);
367 return status_ == PIPELINE_OK;
339 } 368 }
340 369
341 bool PipelineImpl::IsPipelineStopped() { 370 bool PipelineImpl::IsPipelineStopped() {
342 DCHECK_EQ(MessageLoop::current(), message_loop_); 371 DCHECK_EQ(MessageLoop::current(), message_loop_);
343 return state_ == kStopped || state_ == kError; 372 return state_ == kStopped || state_ == kError;
344 } 373 }
345 374
346 bool PipelineImpl::IsPipelineTearingDown() { 375 bool PipelineImpl::IsPipelineTearingDown() {
347 DCHECK_EQ(MessageLoop::current(), message_loop_); 376 DCHECK_EQ(MessageLoop::current(), message_loop_);
348 return tearing_down_; 377 return tearing_down_;
(...skipping 12 matching lines...) Expand all
361 kFlushing == state_ || kStarting == state_) 390 kFlushing == state_ || kStarting == state_)
362 << "Current state : " << state_; 391 << "Current state : " << state_;
363 return true; 392 return true;
364 } 393 }
365 394
366 void PipelineImpl::FinishInitialization() { 395 void PipelineImpl::FinishInitialization() {
367 DCHECK_EQ(MessageLoop::current(), message_loop_); 396 DCHECK_EQ(MessageLoop::current(), message_loop_);
368 // Execute the seek callback, if present. Note that this might be the 397 // Execute the seek callback, if present. Note that this might be the
369 // initial callback passed into Start(). 398 // initial callback passed into Start().
370 if (seek_callback_.get()) { 399 if (seek_callback_.get()) {
371 seek_callback_->Run(); 400 seek_callback_->Run(status_);
372 seek_callback_.reset(); 401 seek_callback_.reset();
373 } 402 }
374 } 403 }
375 404
376 // static 405 // static
377 bool PipelineImpl::TransientState(State state) { 406 bool PipelineImpl::TransientState(State state) {
378 return state == kPausing || 407 return state == kPausing ||
379 state == kFlushing || 408 state == kFlushing ||
380 state == kSeeking || 409 state == kSeeking ||
381 state == kStarting || 410 state == kStarting ||
(...skipping 16 matching lines...) Expand all
398 return kStarting; 427 return kStarting;
399 } else if (current == kStarting) { 428 } else if (current == kStarting) {
400 return kStarted; 429 return kStarted;
401 } else if (current == kStopping) { 430 } else if (current == kStopping) {
402 return error_caused_teardown_ ? kError : kStopped; 431 return error_caused_teardown_ ? kError : kStopped;
403 } else { 432 } else {
404 return current; 433 return current;
405 } 434 }
406 } 435 }
407 436
408 void PipelineImpl::SetError(PipelineError error) { 437 void PipelineImpl::SetError(PipelineStatus error) {
409 DCHECK(IsRunning()); 438 DCHECK(IsRunning());
410 DCHECK(error != PIPELINE_OK) << "PIPELINE_OK isn't an error!"; 439 DCHECK(error != PIPELINE_OK) << "PIPELINE_OK isn't an error!";
411 VLOG(1) << "Media pipeline error: " << error; 440 VLOG(1) << "Media pipeline error: " << error;
412 441
413 message_loop_->PostTask(FROM_HERE, 442 message_loop_->PostTask(FROM_HERE,
414 NewRunnableMethod(this, &PipelineImpl::ErrorChangedTask, error)); 443 NewRunnableMethod(this, &PipelineImpl::ErrorChangedTask, error));
415 } 444 }
416 445
417 base::TimeDelta PipelineImpl::GetTime() const { 446 base::TimeDelta PipelineImpl::GetTime() const {
418 DCHECK(IsRunning()); 447 DCHECK(IsRunning());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats) { 563 void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats) {
535 base::AutoLock auto_lock(lock_); 564 base::AutoLock auto_lock(lock_);
536 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; 565 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded;
537 statistics_.video_bytes_decoded += stats.video_bytes_decoded; 566 statistics_.video_bytes_decoded += stats.video_bytes_decoded;
538 statistics_.video_frames_decoded += stats.video_frames_decoded; 567 statistics_.video_frames_decoded += stats.video_frames_decoded;
539 statistics_.video_frames_dropped += stats.video_frames_dropped; 568 statistics_.video_frames_dropped += stats.video_frames_dropped;
540 } 569 }
541 570
542 void PipelineImpl::StartTask(FilterCollection* filter_collection, 571 void PipelineImpl::StartTask(FilterCollection* filter_collection,
543 const std::string& url, 572 const std::string& url,
544 PipelineCallback* start_callback) { 573 PipelineStatusCallback* start_callback) {
545 DCHECK_EQ(MessageLoop::current(), message_loop_); 574 DCHECK_EQ(MessageLoop::current(), message_loop_);
546 DCHECK_EQ(kCreated, state_); 575 DCHECK_EQ(kCreated, state_);
547 filter_collection_.reset(filter_collection); 576 filter_collection_.reset(filter_collection);
548 url_ = url; 577 url_ = url;
549 seek_callback_.reset(start_callback); 578 seek_callback_.reset(start_callback);
550 579
551 // Kick off initialization. 580 // Kick off initialization.
552 set_state(kInitDemuxer); 581 set_state(kInitDemuxer);
553 pipeline_init_state_.reset(new PipelineInitState()); 582 pipeline_init_state_.reset(new PipelineInitState());
554 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); 583 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_);
(...skipping 16 matching lines...) Expand all
571 // FilterHost's InitializationComplete() method, the pipeline will update its 600 // FilterHost's InitializationComplete() method, the pipeline will update its
572 // state to kStarted and |init_callback_|, will be executed. 601 // state to kStarted and |init_callback_|, will be executed.
573 // 602 //
574 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It 603 // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It
575 // works like a big state change table. If we no longer need to start filters 604 // works like a big state change table. If we no longer need to start filters
576 // in order, we need to get rid of all the state change. 605 // in order, we need to get rid of all the state change.
577 void PipelineImpl::InitializeTask() { 606 void PipelineImpl::InitializeTask() {
578 DCHECK_EQ(MessageLoop::current(), message_loop_); 607 DCHECK_EQ(MessageLoop::current(), message_loop_);
579 608
580 // If we have received the stop or error signal, return immediately. 609 // If we have received the stop or error signal, return immediately.
581 if (IsPipelineStopPending() || 610 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk())
582 IsPipelineStopped() ||
583 PIPELINE_OK != GetError()) {
584 return; 611 return;
585 }
586 612
587 DCHECK(state_ == kInitDemuxer || 613 DCHECK(state_ == kInitDemuxer ||
588 state_ == kInitAudioDecoder || 614 state_ == kInitAudioDecoder ||
589 state_ == kInitAudioRenderer || 615 state_ == kInitAudioRenderer ||
590 state_ == kInitVideoDecoder || 616 state_ == kInitVideoDecoder ||
591 state_ == kInitVideoRenderer); 617 state_ == kInitVideoRenderer);
592 618
593 619
594 // Demuxer created, create audio decoder. 620 // Demuxer created, create audio decoder.
595 if (state_ == kInitDemuxer) { 621 if (state_ == kInitDemuxer) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 } 688 }
663 } 689 }
664 690
665 // This method is called as a result of the client calling Pipeline::Stop() or 691 // This method is called as a result of the client calling Pipeline::Stop() or
666 // as the result of an error condition. 692 // as the result of an error condition.
667 // We stop the filters in the reverse order. 693 // We stop the filters in the reverse order.
668 // 694 //
669 // TODO(scherkus): beware! this can get posted multiple times since we post 695 // TODO(scherkus): beware! this can get posted multiple times since we post
670 // Stop() tasks even if we've already stopped. Perhaps this should no-op for 696 // Stop() tasks even if we've already stopped. Perhaps this should no-op for
671 // additional calls, however most of this logic will be changing. 697 // additional calls, however most of this logic will be changing.
672 void PipelineImpl::StopTask(PipelineCallback* stop_callback) { 698 void PipelineImpl::StopTask(PipelineStatusCallback* stop_callback) {
673 DCHECK_EQ(MessageLoop::current(), message_loop_); 699 DCHECK_EQ(MessageLoop::current(), message_loop_);
674 DCHECK(!IsPipelineStopPending()); 700 DCHECK(!IsPipelineStopPending());
675 DCHECK_NE(state_, kStopped); 701 DCHECK_NE(state_, kStopped);
676 702
677 if (state_ == kStopped) { 703 if (state_ == kStopped) {
678 // Already stopped so just run callback. 704 // Already stopped so just run callback.
679 stop_callback->Run(); 705 stop_callback->Run(status_);
680 delete stop_callback; 706 delete stop_callback;
681 return; 707 return;
682 } 708 }
683 709
684 if (IsPipelineTearingDown() && error_caused_teardown_) { 710 if (IsPipelineTearingDown() && error_caused_teardown_) {
685 // If we are stopping due to SetError(), stop normally instead of 711 // If we are stopping due to SetError(), stop normally instead of
686 // going to error state and calling |error_callback_|. This converts 712 // going to error state and calling |error_callback_|. This converts
687 // the teardown in progress from an error teardown into one that acts 713 // the teardown in progress from an error teardown into one that acts
688 // like the error never occurred. 714 // like the error never occurred.
689 base::AutoLock auto_lock(lock_); 715 base::AutoLock auto_lock(lock_);
690 error_ = PIPELINE_OK; 716 status_ = PIPELINE_OK;
691 error_caused_teardown_ = false; 717 error_caused_teardown_ = false;
692 } 718 }
693 719
694 stop_callback_.reset(stop_callback); 720 stop_callback_.reset(stop_callback);
695 721
696 stop_pending_ = true; 722 stop_pending_ = true;
697 if (!IsPipelineSeeking() && !IsPipelineTearingDown()) { 723 if (!IsPipelineSeeking() && !IsPipelineTearingDown()) {
698 // We will tear down pipeline immediately when there is no seek operation 724 // We will tear down pipeline immediately when there is no seek operation
699 // pending and no teardown in progress. This should include the case where 725 // pending and no teardown in progress. This should include the case where
700 // we are partially initialized. 726 // we are partially initialized.
701 TearDownPipeline(); 727 TearDownPipeline();
702 } 728 }
703 } 729 }
704 730
705 void PipelineImpl::ErrorChangedTask(PipelineError error) { 731 void PipelineImpl::ErrorChangedTask(PipelineStatus error) {
706 DCHECK_EQ(MessageLoop::current(), message_loop_); 732 DCHECK_EQ(MessageLoop::current(), message_loop_);
707 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; 733 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!";
708 734
709 // Suppress executing additional error logic. Note that if we are currently 735 // Suppress executing additional error logic. Note that if we are currently
710 // performing a normal stop, then we return immediately and continue the 736 // performing a normal stop, then we return immediately and continue the
711 // normal stop. 737 // normal stop.
712 if (IsPipelineStopped() || IsPipelineTearingDown()) { 738 if (IsPipelineStopped() || IsPipelineTearingDown()) {
713 return; 739 return;
714 } 740 }
715 741
716 base::AutoLock auto_lock(lock_); 742 base::AutoLock auto_lock(lock_);
717 error_ = error; 743 status_ = error;
718 744
719 error_caused_teardown_ = true; 745 error_caused_teardown_ = true;
720 746
721 // Posting TearDownPipeline() to message loop so that we can make sure 747 // Posting TearDownPipeline() to message loop so that we can make sure
722 // it runs after any pending callbacks that are already queued. 748 // it runs after any pending callbacks that are already queued.
723 // |tearing_down_| is set early here to make sure that pending callbacks 749 // |tearing_down_| is set early here to make sure that pending callbacks
724 // don't modify the state before TeadDownPipeline() can run. 750 // don't modify the state before TeadDownPipeline() can run.
725 tearing_down_ = true; 751 tearing_down_ = true;
726 message_loop_->PostTask(FROM_HERE, 752 message_loop_->PostTask(FROM_HERE,
727 NewRunnableMethod(this, &PipelineImpl::TearDownPipeline)); 753 NewRunnableMethod(this, &PipelineImpl::TearDownPipeline));
(...skipping 16 matching lines...) Expand all
744 770
745 void PipelineImpl::VolumeChangedTask(float volume) { 771 void PipelineImpl::VolumeChangedTask(float volume) {
746 DCHECK_EQ(MessageLoop::current(), message_loop_); 772 DCHECK_EQ(MessageLoop::current(), message_loop_);
747 773
748 if (audio_renderer_) { 774 if (audio_renderer_) {
749 audio_renderer_->SetVolume(volume); 775 audio_renderer_->SetVolume(volume);
750 } 776 }
751 } 777 }
752 778
753 void PipelineImpl::SeekTask(base::TimeDelta time, 779 void PipelineImpl::SeekTask(base::TimeDelta time,
754 PipelineCallback* seek_callback) { 780 PipelineStatusCallback* seek_callback) {
755 DCHECK_EQ(MessageLoop::current(), message_loop_); 781 DCHECK_EQ(MessageLoop::current(), message_loop_);
756 DCHECK(!IsPipelineStopPending()); 782 DCHECK(!IsPipelineStopPending());
757 783
758 // Suppress seeking if we're not fully started. 784 // Suppress seeking if we're not fully started.
759 if (state_ != kStarted && state_ != kEnded) { 785 if (state_ != kStarted && state_ != kEnded) {
760 // TODO(scherkus): should we run the callback? I'm tempted to say the API 786 // TODO(scherkus): should we run the callback? I'm tempted to say the API
761 // will only execute the first Seek() request. 787 // will only execute the first Seek() request.
762 VLOG(1) << "Media pipeline has not started, ignoring seek to " 788 VLOG(1) << "Media pipeline has not started, ignoring seek to "
763 << time.InMicroseconds(); 789 << time.InMicroseconds();
764 delete seek_callback; 790 delete seek_callback;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 } 840 }
815 } 841 }
816 842
817 if (video_renderer_ && !video_renderer_->HasEnded()) { 843 if (video_renderer_ && !video_renderer_->HasEnded()) {
818 return; 844 return;
819 } 845 }
820 846
821 // Transition to ended, executing the callback if present. 847 // Transition to ended, executing the callback if present.
822 set_state(kEnded); 848 set_state(kEnded);
823 if (ended_callback_.get()) { 849 if (ended_callback_.get()) {
824 ended_callback_->Run(); 850 ended_callback_->Run(status_);
825 } 851 }
826 } 852 }
827 853
828 void PipelineImpl::NotifyNetworkEventTask() { 854 void PipelineImpl::NotifyNetworkEventTask() {
829 DCHECK_EQ(MessageLoop::current(), message_loop_); 855 DCHECK_EQ(MessageLoop::current(), message_loop_);
830 if (network_callback_.get()) { 856 if (network_callback_.get()) {
831 network_callback_->Run(); 857 network_callback_->Run(status_);
832 } 858 }
833 } 859 }
834 860
835 void PipelineImpl::DisableAudioRendererTask() { 861 void PipelineImpl::DisableAudioRendererTask() {
836 DCHECK_EQ(MessageLoop::current(), message_loop_); 862 DCHECK_EQ(MessageLoop::current(), message_loop_);
837 863
838 base::AutoLock auto_lock(lock_); 864 base::AutoLock auto_lock(lock_);
839 has_audio_ = false; 865 has_audio_ = false;
840 audio_disabled_ = true; 866 audio_disabled_ = true;
841 867
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 void PipelineImpl::FinishDestroyingFiltersTask() { 984 void PipelineImpl::FinishDestroyingFiltersTask() {
959 DCHECK_EQ(MessageLoop::current(), message_loop_); 985 DCHECK_EQ(MessageLoop::current(), message_loop_);
960 DCHECK(IsPipelineStopped()); 986 DCHECK(IsPipelineStopped());
961 987
962 // Clear renderer references. 988 // Clear renderer references.
963 audio_renderer_ = NULL; 989 audio_renderer_ = NULL;
964 video_renderer_ = NULL; 990 video_renderer_ = NULL;
965 991
966 pipeline_filter_ = NULL; 992 pipeline_filter_ = NULL;
967 993
968 if (error_caused_teardown_ && GetError() != PIPELINE_OK && 994 if (error_caused_teardown_ && !IsPipelineOk() && error_callback_.get())
969 error_callback_.get()) { 995 error_callback_->Run(status_);
970 error_callback_->Run();
971 }
972 996
973 if (stop_pending_) { 997 if (stop_pending_) {
974 stop_pending_ = false; 998 stop_pending_ = false;
975 ResetState(); 999 ResetState();
976 scoped_ptr<PipelineCallback> stop_callback(stop_callback_.release()); 1000 scoped_ptr<PipelineStatusCallback> stop_callback(stop_callback_.release());
977 // Notify the client that stopping has finished. 1001 // Notify the client that stopping has finished.
978 if (stop_callback.get()) { 1002 if (stop_callback.get()) {
979 stop_callback->Run(); 1003 stop_callback->Run(status_);
980 } 1004 }
981 } 1005 }
982 1006
983 tearing_down_ = false; 1007 tearing_down_ = false;
984 error_caused_teardown_ = false; 1008 error_caused_teardown_ = false;
985 } 1009 }
986 1010
987 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { 1011 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) {
988 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); 1012 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get());
989 1013
990 if (!ret) { 1014 if (!ret) {
991 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); 1015 SetError(PIPELINE_ERROR_INITIALIZATION_FAILED);
992 } 1016 }
993 return ret; 1017 return ret;
994 } 1018 }
995 1019
996 void PipelineImpl::InitializeDemuxer() { 1020 void PipelineImpl::InitializeDemuxer() {
997 DCHECK_EQ(MessageLoop::current(), message_loop_); 1021 DCHECK_EQ(MessageLoop::current(), message_loop_);
998 DCHECK(IsPipelineOk()); 1022 DCHECK(IsPipelineOk());
999 1023
1000 filter_collection_->GetDemuxerFactory()->Build(url_, 1024 filter_collection_->GetDemuxerFactory()->Build(url_,
1001 NewCallback(this, &PipelineImpl::OnDemuxerBuilt)); 1025 NewCallback(this, &PipelineImpl::OnDemuxerBuilt));
1002 } 1026 }
1003 1027
1004 void PipelineImpl::OnDemuxerBuilt(PipelineError error, 1028 void PipelineImpl::OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer) {
1005 Demuxer* demuxer) {
1006 if (MessageLoop::current() != message_loop_) { 1029 if (MessageLoop::current() != message_loop_) {
1007 message_loop_->PostTask(FROM_HERE, 1030 message_loop_->PostTask(FROM_HERE,
1008 NewRunnableMethod(this, 1031 NewRunnableMethod(this,
1009 &PipelineImpl::OnDemuxerBuilt, 1032 &PipelineImpl::OnDemuxerBuilt,
1010 error, 1033 status,
1011 make_scoped_refptr(demuxer))); 1034 make_scoped_refptr(demuxer)));
1012 return; 1035 return;
1013 } 1036 }
1014 1037
1015 if (error != PIPELINE_OK) { 1038 if (status != PIPELINE_OK) {
1016 SetError(error); 1039 SetError(status);
1017 return; 1040 return;
1018 } 1041 }
1019 1042
1020 if (!demuxer) { 1043 if (!demuxer) {
1021 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 1044 SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
1022 return; 1045 return;
1023 } 1046 }
1024 1047
1025 if (!PrepareFilter(demuxer)) 1048 if (!PrepareFilter(demuxer))
1026 return; 1049 return;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 case kStopping: 1236 case kStopping:
1214 case kStopped: 1237 case kStopped:
1215 NOTREACHED() << "Unexpected state for teardown: " << state_; 1238 NOTREACHED() << "Unexpected state for teardown: " << state_;
1216 break; 1239 break;
1217 // default: intentionally left out to force new states to cause compiler 1240 // default: intentionally left out to force new states to cause compiler
1218 // errors. 1241 // errors.
1219 }; 1242 };
1220 } 1243 }
1221 1244
1222 } // namespace media 1245 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698