| OLD | NEW |
| 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 "media/base/pipeline_impl.h" | 8 #include "media/base/pipeline_impl.h" |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/synchronization/condition_variable.h" | 17 #include "base/synchronization/condition_variable.h" |
| 18 #include "media/base/clock.h" | 18 #include "media/base/clock.h" |
| 19 #include "media/base/filter_collection.h" | 19 #include "media/base/filter_collection.h" |
| 20 | 20 |
| 21 namespace media { | 21 namespace media { |
| 22 | 22 |
| 23 const char kRawMediaScheme[] = "x-raw-media"; | 23 const char kRawMediaScheme[] = "x-raw-media"; |
| 24 | 24 |
| 25 PipelineStatusNotification::PipelineStatusNotification() | 25 PipelineStatusNotification::PipelineStatusNotification() |
| 26 : cv_(&lock_), status_(PIPELINE_OK), notified_(false) { | 26 : cv_(&lock_), status_(PIPELINE_OK), notified_(false) { |
| 27 callback_.reset(NewCallback(this, &PipelineStatusNotification::Notify)); | |
| 28 } | 27 } |
| 29 | 28 |
| 30 PipelineStatusNotification::~PipelineStatusNotification() { | 29 PipelineStatusNotification::~PipelineStatusNotification() { |
| 31 DCHECK(notified_); | 30 DCHECK(notified_); |
| 32 } | 31 } |
| 33 | 32 |
| 34 media::PipelineStatusCallback* PipelineStatusNotification::Callback() { | 33 PipelineStatusCB PipelineStatusNotification::Callback() { |
| 35 return callback_.release(); | 34 return base::Bind(&PipelineStatusNotification::Notify, |
| 35 base::Unretained(this)); |
| 36 } | 36 } |
| 37 | 37 |
| 38 void PipelineStatusNotification::Notify(media::PipelineStatus status) { | 38 void PipelineStatusNotification::Notify(media::PipelineStatus status) { |
| 39 base::AutoLock auto_lock(lock_); | 39 base::AutoLock auto_lock(lock_); |
| 40 DCHECK(!notified_); | 40 DCHECK(!notified_); |
| 41 notified_ = true; | 41 notified_ = true; |
| 42 status_ = status; | 42 status_ = status; |
| 43 cv_.Signal(); | 43 cv_.Signal(); |
| 44 } | 44 } |
| 45 | 45 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 71 ResetState(); | 71 ResetState(); |
| 72 } | 72 } |
| 73 | 73 |
| 74 PipelineImpl::~PipelineImpl() { | 74 PipelineImpl::~PipelineImpl() { |
| 75 base::AutoLock auto_lock(lock_); | 75 base::AutoLock auto_lock(lock_); |
| 76 DCHECK(!running_) << "Stop() must complete before destroying object"; | 76 DCHECK(!running_) << "Stop() must complete before destroying object"; |
| 77 DCHECK(!stop_pending_); | 77 DCHECK(!stop_pending_); |
| 78 DCHECK(!seek_pending_); | 78 DCHECK(!seek_pending_); |
| 79 } | 79 } |
| 80 | 80 |
| 81 void PipelineImpl::Init(PipelineStatusCallback* ended_callback, | 81 void PipelineImpl::Init(const PipelineStatusCB& ended_callback, |
| 82 PipelineStatusCallback* error_callback, | 82 const PipelineStatusCB& error_callback, |
| 83 PipelineStatusCallback* network_callback) { | 83 const PipelineStatusCB& network_callback) { |
| 84 DCHECK(!IsRunning()) | 84 DCHECK(!IsRunning()) |
| 85 << "Init() should be called before the pipeline has started"; | 85 << "Init() should be called before the pipeline has started"; |
| 86 ended_callback_.reset(ended_callback); | 86 ended_callback_ = ended_callback; |
| 87 error_callback_.reset(error_callback); | 87 error_callback_ = error_callback; |
| 88 network_callback_.reset(network_callback); | 88 network_callback_ = network_callback; |
| 89 } | 89 } |
| 90 | 90 |
| 91 // Creates the PipelineInternal and calls it's start method. | 91 // Creates the PipelineInternal and calls it's start method. |
| 92 bool PipelineImpl::Start(FilterCollection* collection, | 92 bool PipelineImpl::Start(FilterCollection* collection, |
| 93 const std::string& url, | 93 const std::string& url, |
| 94 PipelineStatusCallback* start_callback) { | 94 const PipelineStatusCB& start_callback) { |
| 95 base::AutoLock auto_lock(lock_); | 95 base::AutoLock auto_lock(lock_); |
| 96 scoped_ptr<PipelineStatusCallback> callback(start_callback); | |
| 97 scoped_ptr<FilterCollection> filter_collection(collection); | 96 scoped_ptr<FilterCollection> filter_collection(collection); |
| 98 | 97 |
| 99 if (running_) { | 98 if (running_) { |
| 100 VLOG(1) << "Media pipeline is already running"; | 99 VLOG(1) << "Media pipeline is already running"; |
| 101 return false; | 100 return false; |
| 102 } | 101 } |
| 103 | 102 |
| 104 if (collection->IsEmpty()) { | 103 if (collection->IsEmpty()) { |
| 105 return false; | 104 return false; |
| 106 } | 105 } |
| 107 | 106 |
| 108 // Kick off initialization! | 107 // Kick off initialization! |
| 109 running_ = true; | 108 running_ = true; |
| 110 message_loop_->PostTask( | 109 message_loop_->PostTask( |
| 111 FROM_HERE, | 110 FROM_HERE, |
| 112 NewRunnableMethod(this, | 111 NewRunnableMethod(this, |
| 113 &PipelineImpl::StartTask, | 112 &PipelineImpl::StartTask, |
| 114 filter_collection.release(), | 113 filter_collection.release(), |
| 115 url, | 114 url, |
| 116 callback.release())); | 115 start_callback)); |
| 117 return true; | 116 return true; |
| 118 } | 117 } |
| 119 | 118 |
| 120 void PipelineImpl::Stop(PipelineStatusCallback* stop_callback) { | 119 void PipelineImpl::Stop(const PipelineStatusCB& stop_callback) { |
| 121 base::AutoLock auto_lock(lock_); | 120 base::AutoLock auto_lock(lock_); |
| 122 scoped_ptr<PipelineStatusCallback> callback(stop_callback); | |
| 123 if (!running_) { | 121 if (!running_) { |
| 124 VLOG(1) << "Media pipeline has already stopped"; | 122 VLOG(1) << "Media pipeline has already stopped"; |
| 125 return; | 123 return; |
| 126 } | 124 } |
| 127 | 125 |
| 128 // Stop the pipeline, which will set |running_| to false on behalf. | 126 // Stop the pipeline, which will set |running_| to false on behalf. |
| 129 message_loop_->PostTask(FROM_HERE, | 127 message_loop_->PostTask(FROM_HERE, |
| 130 NewRunnableMethod(this, &PipelineImpl::StopTask, callback.release())); | 128 NewRunnableMethod(this, &PipelineImpl::StopTask, stop_callback)); |
| 131 } | 129 } |
| 132 | 130 |
| 133 void PipelineImpl::Seek(base::TimeDelta time, | 131 void PipelineImpl::Seek(base::TimeDelta time, |
| 134 PipelineStatusCallback* seek_callback) { | 132 const PipelineStatusCB& seek_callback) { |
| 135 base::AutoLock auto_lock(lock_); | 133 base::AutoLock auto_lock(lock_); |
| 136 scoped_ptr<PipelineStatusCallback> callback(seek_callback); | |
| 137 if (!running_) { | 134 if (!running_) { |
| 138 VLOG(1) << "Media pipeline must be running"; | 135 VLOG(1) << "Media pipeline must be running"; |
| 139 return; | 136 return; |
| 140 } | 137 } |
| 141 | 138 |
| 142 message_loop_->PostTask(FROM_HERE, | 139 message_loop_->PostTask(FROM_HERE, |
| 143 NewRunnableMethod(this, &PipelineImpl::SeekTask, time, | 140 NewRunnableMethod(this, &PipelineImpl::SeekTask, time, seek_callback)); |
| 144 callback.release())); | |
| 145 } | 141 } |
| 146 | 142 |
| 147 bool PipelineImpl::IsRunning() const { | 143 bool PipelineImpl::IsRunning() const { |
| 148 base::AutoLock auto_lock(lock_); | 144 base::AutoLock auto_lock(lock_); |
| 149 return running_; | 145 return running_; |
| 150 } | 146 } |
| 151 | 147 |
| 152 bool PipelineImpl::IsInitialized() const { | 148 bool PipelineImpl::IsInitialized() const { |
| 153 // TODO(scherkus): perhaps replace this with a bool that is set/get under the | 149 // TODO(scherkus): perhaps replace this with a bool that is set/get under the |
| 154 // lock, because this is breaching the contract that |state_| is only accessed | 150 // lock, because this is breaching the contract that |state_| is only accessed |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 DCHECK(kSeeking == state_ || kPausing == state_ || | 408 DCHECK(kSeeking == state_ || kPausing == state_ || |
| 413 kFlushing == state_ || kStarting == state_) | 409 kFlushing == state_ || kStarting == state_) |
| 414 << "Current state : " << state_; | 410 << "Current state : " << state_; |
| 415 return true; | 411 return true; |
| 416 } | 412 } |
| 417 | 413 |
| 418 void PipelineImpl::FinishInitialization() { | 414 void PipelineImpl::FinishInitialization() { |
| 419 DCHECK_EQ(MessageLoop::current(), message_loop_); | 415 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 420 // Execute the seek callback, if present. Note that this might be the | 416 // Execute the seek callback, if present. Note that this might be the |
| 421 // initial callback passed into Start(). | 417 // initial callback passed into Start(). |
| 422 if (seek_callback_.get()) { | 418 if (!seek_callback_.is_null()) { |
| 423 seek_callback_->Run(status_); | 419 seek_callback_.Run(status_); |
| 424 seek_callback_.reset(); | 420 seek_callback_.Reset(); |
| 425 } | 421 } |
| 426 } | 422 } |
| 427 | 423 |
| 428 // static | 424 // static |
| 429 bool PipelineImpl::TransientState(State state) { | 425 bool PipelineImpl::TransientState(State state) { |
| 430 return state == kPausing || | 426 return state == kPausing || |
| 431 state == kFlushing || | 427 state == kFlushing || |
| 432 state == kSeeking || | 428 state == kSeeking || |
| 433 state == kStarting || | 429 state == kStarting || |
| 434 state == kStopping; | 430 state == kStopping; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats) { | 595 void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats) { |
| 600 base::AutoLock auto_lock(lock_); | 596 base::AutoLock auto_lock(lock_); |
| 601 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; | 597 statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; |
| 602 statistics_.video_bytes_decoded += stats.video_bytes_decoded; | 598 statistics_.video_bytes_decoded += stats.video_bytes_decoded; |
| 603 statistics_.video_frames_decoded += stats.video_frames_decoded; | 599 statistics_.video_frames_decoded += stats.video_frames_decoded; |
| 604 statistics_.video_frames_dropped += stats.video_frames_dropped; | 600 statistics_.video_frames_dropped += stats.video_frames_dropped; |
| 605 } | 601 } |
| 606 | 602 |
| 607 void PipelineImpl::StartTask(FilterCollection* filter_collection, | 603 void PipelineImpl::StartTask(FilterCollection* filter_collection, |
| 608 const std::string& url, | 604 const std::string& url, |
| 609 PipelineStatusCallback* start_callback) { | 605 const PipelineStatusCB& start_callback) { |
| 610 DCHECK_EQ(MessageLoop::current(), message_loop_); | 606 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 611 DCHECK_EQ(kCreated, state_); | 607 DCHECK_EQ(kCreated, state_); |
| 612 filter_collection_.reset(filter_collection); | 608 filter_collection_.reset(filter_collection); |
| 613 url_ = url; | 609 url_ = url; |
| 614 seek_callback_.reset(start_callback); | 610 seek_callback_ = start_callback; |
| 615 | 611 |
| 616 // Kick off initialization. | 612 // Kick off initialization. |
| 617 pipeline_init_state_.reset(new PipelineInitState()); | 613 pipeline_init_state_.reset(new PipelineInitState()); |
| 618 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); | 614 pipeline_init_state_->composite_ = new CompositeFilter(message_loop_); |
| 619 pipeline_init_state_->composite_->set_host(this); | 615 pipeline_init_state_->composite_->set_host(this); |
| 620 | 616 |
| 621 bool raw_media = (base::strncasecmp(url.c_str(), kRawMediaScheme, | 617 bool raw_media = (base::strncasecmp(url.c_str(), kRawMediaScheme, |
| 622 strlen(kRawMediaScheme)) == 0); | 618 strlen(kRawMediaScheme)) == 0); |
| 623 if (raw_media) { | 619 if (raw_media) { |
| 624 set_state(kInitVideoDecoder); | 620 set_state(kInitVideoDecoder); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 } | 733 } |
| 738 } | 734 } |
| 739 | 735 |
| 740 // This method is called as a result of the client calling Pipeline::Stop() or | 736 // This method is called as a result of the client calling Pipeline::Stop() or |
| 741 // as the result of an error condition. | 737 // as the result of an error condition. |
| 742 // We stop the filters in the reverse order. | 738 // We stop the filters in the reverse order. |
| 743 // | 739 // |
| 744 // TODO(scherkus): beware! this can get posted multiple times since we post | 740 // TODO(scherkus): beware! this can get posted multiple times since we post |
| 745 // Stop() tasks even if we've already stopped. Perhaps this should no-op for | 741 // Stop() tasks even if we've already stopped. Perhaps this should no-op for |
| 746 // additional calls, however most of this logic will be changing. | 742 // additional calls, however most of this logic will be changing. |
| 747 void PipelineImpl::StopTask(PipelineStatusCallback* stop_callback) { | 743 void PipelineImpl::StopTask(const PipelineStatusCB& stop_callback) { |
| 748 DCHECK_EQ(MessageLoop::current(), message_loop_); | 744 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 749 DCHECK(!IsPipelineStopPending()); | 745 DCHECK(!IsPipelineStopPending()); |
| 750 DCHECK_NE(state_, kStopped); | 746 DCHECK_NE(state_, kStopped); |
| 751 | 747 |
| 752 if (state_ == kStopped) { | 748 if (state_ == kStopped) { |
| 753 // Already stopped so just run callback. | 749 // Already stopped so just run callback. |
| 754 stop_callback->Run(status_); | 750 stop_callback.Run(status_); |
| 755 delete stop_callback; | |
| 756 return; | 751 return; |
| 757 } | 752 } |
| 758 | 753 |
| 759 if (IsPipelineTearingDown() && error_caused_teardown_) { | 754 if (IsPipelineTearingDown() && error_caused_teardown_) { |
| 760 // If we are stopping due to SetError(), stop normally instead of | 755 // If we are stopping due to SetError(), stop normally instead of |
| 761 // going to error state and calling |error_callback_|. This converts | 756 // going to error state and calling |error_callback_|. This converts |
| 762 // the teardown in progress from an error teardown into one that acts | 757 // the teardown in progress from an error teardown into one that acts |
| 763 // like the error never occurred. | 758 // like the error never occurred. |
| 764 base::AutoLock auto_lock(lock_); | 759 base::AutoLock auto_lock(lock_); |
| 765 status_ = PIPELINE_OK; | 760 status_ = PIPELINE_OK; |
| 766 error_caused_teardown_ = false; | 761 error_caused_teardown_ = false; |
| 767 } | 762 } |
| 768 | 763 |
| 769 stop_callback_.reset(stop_callback); | 764 stop_callback_ = stop_callback; |
| 770 | 765 |
| 771 stop_pending_ = true; | 766 stop_pending_ = true; |
| 772 if (!IsPipelineSeeking() && !IsPipelineTearingDown()) { | 767 if (!IsPipelineSeeking() && !IsPipelineTearingDown()) { |
| 773 // We will tear down pipeline immediately when there is no seek operation | 768 // We will tear down pipeline immediately when there is no seek operation |
| 774 // pending and no teardown in progress. This should include the case where | 769 // pending and no teardown in progress. This should include the case where |
| 775 // we are partially initialized. | 770 // we are partially initialized. |
| 776 TearDownPipeline(); | 771 TearDownPipeline(); |
| 777 } | 772 } |
| 778 } | 773 } |
| 779 | 774 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 } | 828 } |
| 834 } | 829 } |
| 835 | 830 |
| 836 void PipelineImpl::PreloadChangedTask(Preload preload) { | 831 void PipelineImpl::PreloadChangedTask(Preload preload) { |
| 837 DCHECK_EQ(MessageLoop::current(), message_loop_); | 832 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 838 if (demuxer_) | 833 if (demuxer_) |
| 839 demuxer_->SetPreload(preload); | 834 demuxer_->SetPreload(preload); |
| 840 } | 835 } |
| 841 | 836 |
| 842 void PipelineImpl::SeekTask(base::TimeDelta time, | 837 void PipelineImpl::SeekTask(base::TimeDelta time, |
| 843 PipelineStatusCallback* seek_callback) { | 838 const PipelineStatusCB& seek_callback) { |
| 844 DCHECK_EQ(MessageLoop::current(), message_loop_); | 839 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 845 DCHECK(!IsPipelineStopPending()); | 840 DCHECK(!IsPipelineStopPending()); |
| 846 | 841 |
| 847 // Suppress seeking if we're not fully started. | 842 // Suppress seeking if we're not fully started. |
| 848 if (state_ != kStarted && state_ != kEnded) { | 843 if (state_ != kStarted && state_ != kEnded) { |
| 849 // TODO(scherkus): should we run the callback? I'm tempted to say the API | 844 // TODO(scherkus): should we run the callback? I'm tempted to say the API |
| 850 // will only execute the first Seek() request. | 845 // will only execute the first Seek() request. |
| 851 VLOG(1) << "Media pipeline has not started, ignoring seek to " | 846 VLOG(1) << "Media pipeline has not started, ignoring seek to " |
| 852 << time.InMicroseconds(); | 847 << time.InMicroseconds(); |
| 853 delete seek_callback; | |
| 854 return; | 848 return; |
| 855 } | 849 } |
| 856 | 850 |
| 857 DCHECK(!seek_pending_); | 851 DCHECK(!seek_pending_); |
| 858 seek_pending_ = true; | 852 seek_pending_ = true; |
| 859 | 853 |
| 860 // We'll need to pause every filter before seeking. The state transition | 854 // We'll need to pause every filter before seeking. The state transition |
| 861 // is as follows: | 855 // is as follows: |
| 862 // kStarted/kEnded | 856 // kStarted/kEnded |
| 863 // kPausing (for each filter) | 857 // kPausing (for each filter) |
| 864 // kSeeking (for each filter) | 858 // kSeeking (for each filter) |
| 865 // kStarting (for each filter) | 859 // kStarting (for each filter) |
| 866 // kStarted | 860 // kStarted |
| 867 set_state(kPausing); | 861 set_state(kPausing); |
| 868 seek_timestamp_ = time; | 862 seek_timestamp_ = time; |
| 869 seek_callback_.reset(seek_callback); | 863 seek_callback_ = seek_callback; |
| 870 | 864 |
| 871 // Kick off seeking! | 865 // Kick off seeking! |
| 872 { | 866 { |
| 873 base::AutoLock auto_lock(lock_); | 867 base::AutoLock auto_lock(lock_); |
| 874 // If we are waiting for a clock update, the clock hasn't been played yet. | 868 // If we are waiting for a clock update, the clock hasn't been played yet. |
| 875 if (!waiting_for_clock_update_) | 869 if (!waiting_for_clock_update_) |
| 876 clock_->Pause(); | 870 clock_->Pause(); |
| 877 } | 871 } |
| 878 pipeline_filter_->Pause( | 872 pipeline_filter_->Pause( |
| 879 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 873 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 902 clock_->Play(); | 896 clock_->Play(); |
| 903 } | 897 } |
| 904 } | 898 } |
| 905 | 899 |
| 906 if (video_renderer_ && !video_renderer_->HasEnded()) { | 900 if (video_renderer_ && !video_renderer_->HasEnded()) { |
| 907 return; | 901 return; |
| 908 } | 902 } |
| 909 | 903 |
| 910 // Transition to ended, executing the callback if present. | 904 // Transition to ended, executing the callback if present. |
| 911 set_state(kEnded); | 905 set_state(kEnded); |
| 912 if (ended_callback_.get()) { | 906 if (!ended_callback_.is_null()) { |
| 913 ended_callback_->Run(status_); | 907 ended_callback_.Run(status_); |
| 914 } | 908 } |
| 915 } | 909 } |
| 916 | 910 |
| 917 void PipelineImpl::NotifyNetworkEventTask() { | 911 void PipelineImpl::NotifyNetworkEventTask() { |
| 918 DCHECK_EQ(MessageLoop::current(), message_loop_); | 912 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 919 if (network_callback_.get()) { | 913 if (!network_callback_.is_null()) { |
| 920 network_callback_->Run(status_); | 914 network_callback_.Run(status_); |
| 921 } | 915 } |
| 922 } | 916 } |
| 923 | 917 |
| 924 void PipelineImpl::DisableAudioRendererTask() { | 918 void PipelineImpl::DisableAudioRendererTask() { |
| 925 DCHECK_EQ(MessageLoop::current(), message_loop_); | 919 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 926 | 920 |
| 927 base::AutoLock auto_lock(lock_); | 921 base::AutoLock auto_lock(lock_); |
| 928 has_audio_ = false; | 922 has_audio_ = false; |
| 929 audio_disabled_ = true; | 923 audio_disabled_ = true; |
| 930 | 924 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 DCHECK_EQ(MessageLoop::current(), message_loop_); | 1049 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 1056 DCHECK(IsPipelineStopped()); | 1050 DCHECK(IsPipelineStopped()); |
| 1057 | 1051 |
| 1058 // Clear filter references. | 1052 // Clear filter references. |
| 1059 audio_renderer_ = NULL; | 1053 audio_renderer_ = NULL; |
| 1060 video_renderer_ = NULL; | 1054 video_renderer_ = NULL; |
| 1061 demuxer_ = NULL; | 1055 demuxer_ = NULL; |
| 1062 | 1056 |
| 1063 pipeline_filter_ = NULL; | 1057 pipeline_filter_ = NULL; |
| 1064 | 1058 |
| 1065 if (error_caused_teardown_ && !IsPipelineOk() && error_callback_.get()) | 1059 if (error_caused_teardown_ && !IsPipelineOk() && !error_callback_.is_null()) |
| 1066 error_callback_->Run(status_); | 1060 error_callback_.Run(status_); |
| 1067 | 1061 |
| 1068 if (stop_pending_) { | 1062 if (stop_pending_) { |
| 1069 stop_pending_ = false; | 1063 stop_pending_ = false; |
| 1070 ResetState(); | 1064 ResetState(); |
| 1071 scoped_ptr<PipelineStatusCallback> stop_callback(stop_callback_.release()); | 1065 PipelineStatusCB stop_cb; |
| 1066 std::swap(stop_cb, stop_callback_); |
| 1072 // Notify the client that stopping has finished. | 1067 // Notify the client that stopping has finished. |
| 1073 if (stop_callback.get()) { | 1068 if (!stop_cb.is_null()) { |
| 1074 stop_callback->Run(status_); | 1069 stop_cb.Run(status_); |
| 1075 } | 1070 } |
| 1076 } | 1071 } |
| 1077 | 1072 |
| 1078 tearing_down_ = false; | 1073 tearing_down_ = false; |
| 1079 error_caused_teardown_ = false; | 1074 error_caused_teardown_ = false; |
| 1080 } | 1075 } |
| 1081 | 1076 |
| 1082 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { | 1077 bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { |
| 1083 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); | 1078 bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); |
| 1084 | 1079 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 case kStopping: | 1298 case kStopping: |
| 1304 case kStopped: | 1299 case kStopped: |
| 1305 NOTREACHED() << "Unexpected state for teardown: " << state_; | 1300 NOTREACHED() << "Unexpected state for teardown: " << state_; |
| 1306 break; | 1301 break; |
| 1307 // default: intentionally left out to force new states to cause compiler | 1302 // default: intentionally left out to force new states to cause compiler |
| 1308 // errors. | 1303 // errors. |
| 1309 }; | 1304 }; |
| 1310 } | 1305 } |
| 1311 | 1306 |
| 1312 } // namespace media | 1307 } // namespace media |
| OLD | NEW |