| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/filters/pipeline_controller.h" | 5 #include "media/filters/pipeline_controller.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "media/base/bind_to_current_loop.h" | 9 #include "media/base/bind_to_current_loop.h" |
| 10 #include "media/base/demuxer.h" | 10 #include "media/base/demuxer.h" |
| 11 | 11 |
| 12 namespace media { | 12 namespace media { |
| 13 | 13 |
| 14 PipelineController::PipelineController( | 14 PipelineController::PipelineController( |
| 15 Pipeline* pipeline, | 15 Pipeline* pipeline, |
| 16 const RendererFactoryCB& renderer_factory_cb, | 16 const RendererFactoryCB& renderer_factory_cb, |
| 17 const SeekedCB& seeked_cb, | 17 const SeekedCB& seeked_cb, |
| 18 const SuspendedCB& suspended_cb, | 18 const SuspendedCB& suspended_cb, |
| 19 const ResumedCB& resumed_cb, | |
| 20 const PipelineStatusCB& error_cb) | 19 const PipelineStatusCB& error_cb) |
| 21 : pipeline_(pipeline), | 20 : pipeline_(pipeline), |
| 22 renderer_factory_cb_(renderer_factory_cb), | 21 renderer_factory_cb_(renderer_factory_cb), |
| 23 seeked_cb_(seeked_cb), | 22 seeked_cb_(seeked_cb), |
| 24 suspended_cb_(suspended_cb), | 23 suspended_cb_(suspended_cb), |
| 25 resumed_cb_(resumed_cb), | |
| 26 error_cb_(error_cb), | 24 error_cb_(error_cb), |
| 27 weak_factory_(this) { | 25 weak_factory_(this) { |
| 28 DCHECK(pipeline_); | 26 DCHECK(pipeline_); |
| 29 DCHECK(!renderer_factory_cb_.is_null()); | 27 DCHECK(!renderer_factory_cb_.is_null()); |
| 30 DCHECK(!seeked_cb_.is_null()); | 28 DCHECK(!seeked_cb_.is_null()); |
| 31 DCHECK(!suspended_cb_.is_null()); | 29 DCHECK(!suspended_cb_.is_null()); |
| 32 DCHECK(!resumed_cb_.is_null()); | |
| 33 DCHECK(!error_cb_.is_null()); | 30 DCHECK(!error_cb_.is_null()); |
| 34 } | 31 } |
| 35 | 32 |
| 36 PipelineController::~PipelineController() { | 33 PipelineController::~PipelineController() { |
| 37 DCHECK(thread_checker_.CalledOnValidThread()); | 34 DCHECK(thread_checker_.CalledOnValidThread()); |
| 38 } | 35 } |
| 39 | 36 |
| 40 // TODO(sandersd): If there is a pending suspend, don't call pipeline_.Start() | 37 // TODO(sandersd): If there is a pending suspend, don't call pipeline_.Start() |
| 41 // until Resume(). | 38 // until Resume(). |
| 42 void PipelineController::Start( | 39 void PipelineController::Start( |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 DCHECK(thread_checker_.CalledOnValidThread()); | 104 DCHECK(thread_checker_.CalledOnValidThread()); |
| 108 pending_suspend_ = false; | 105 pending_suspend_ = false; |
| 109 if (state_ == State::SUSPENDING || state_ == State::SUSPENDED) { | 106 if (state_ == State::SUSPENDING || state_ == State::SUSPENDED) { |
| 110 pending_resume_ = true; | 107 pending_resume_ = true; |
| 111 Dispatch(); | 108 Dispatch(); |
| 112 } | 109 } |
| 113 } | 110 } |
| 114 | 111 |
| 115 bool PipelineController::IsStable() { | 112 bool PipelineController::IsStable() { |
| 116 DCHECK(thread_checker_.CalledOnValidThread()); | 113 DCHECK(thread_checker_.CalledOnValidThread()); |
| 117 return (state_ == State::PLAYING); | 114 return state_ == State::PLAYING; |
| 118 } | 115 } |
| 119 | 116 |
| 120 bool PipelineController::IsSuspended() { | 117 bool PipelineController::IsSuspended() { |
| 121 DCHECK(thread_checker_.CalledOnValidThread()); | 118 DCHECK(thread_checker_.CalledOnValidThread()); |
| 122 return (state_ == State::SUSPENDED); | 119 return (pending_suspend_ || state_ == State::SUSPENDED) && !pending_resume_; |
| 120 } |
| 121 |
| 122 bool PipelineController::IsPipelineSuspended() { |
| 123 DCHECK(thread_checker_.CalledOnValidThread()); |
| 124 return state_ == State::SUSPENDED; |
| 123 } | 125 } |
| 124 | 126 |
| 125 void PipelineController::OnPipelineStatus(State state, | 127 void PipelineController::OnPipelineStatus(State state, |
| 126 PipelineStatus pipeline_status) { | 128 PipelineStatus pipeline_status) { |
| 127 DCHECK(thread_checker_.CalledOnValidThread()); | 129 DCHECK(thread_checker_.CalledOnValidThread()); |
| 128 | 130 |
| 129 if (pipeline_status != PIPELINE_OK) { | 131 if (pipeline_status != PIPELINE_OK) { |
| 130 error_cb_.Run(pipeline_status); | 132 error_cb_.Run(pipeline_status); |
| 131 return; | 133 return; |
| 132 } | 134 } |
| 133 | 135 |
| 134 state_ = state; | 136 state_ = state; |
| 135 | 137 |
| 136 if (state == State::PLAYING) { | 138 if (state == State::PLAYING) { |
| 137 // Start(), Seek(), or Resume() completed; we can be sure that | 139 // Start(), Seek(), or Resume() completed; we can be sure that |
| 138 // |demuxer_| got the seek it was waiting for. | 140 // |demuxer_| got the seek it was waiting for. |
| 139 waiting_for_seek_ = false; | 141 waiting_for_seek_ = false; |
| 140 if (pending_resumed_cb_) { | |
| 141 pending_resumed_cb_ = false; | |
| 142 | |
| 143 // Warning: possibly reentrant. The state may change inside this callback. | |
| 144 // It must be safe to call Dispatch() twice in a row here. | |
| 145 resumed_cb_.Run(); | |
| 146 } | |
| 147 } else if (state == State::SUSPENDED) { | 142 } else if (state == State::SUSPENDED) { |
| 148 pending_resumed_cb_ = true; | |
| 149 | |
| 150 // Warning: possibly reentrant. The state may change inside this callback. | 143 // Warning: possibly reentrant. The state may change inside this callback. |
| 151 // It must be safe to call Dispatch() twice in a row here. | 144 // It must be safe to call Dispatch() twice in a row here. |
| 152 suspended_cb_.Run(); | 145 suspended_cb_.Run(); |
| 153 } | 146 } |
| 154 | 147 |
| 155 Dispatch(); | 148 Dispatch(); |
| 156 } | 149 } |
| 157 | 150 |
| 158 // Note: Dispatch() may be called re-entrantly (by callbacks internally) or | 151 // Note: Dispatch() may be called re-entrantly (by callbacks internally) or |
| 159 // twice in a row (by OnPipelineStatus()). | 152 // twice in a row (by OnPipelineStatus()). |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 pending_seeked_cb_ = false; | 239 pending_seeked_cb_ = false; |
| 247 bool was_pending_time_updated = pending_time_updated_; | 240 bool was_pending_time_updated = pending_time_updated_; |
| 248 pending_time_updated_ = false; | 241 pending_time_updated_ = false; |
| 249 seeked_cb_.Run(was_pending_time_updated); | 242 seeked_cb_.Run(was_pending_time_updated); |
| 250 return; | 243 return; |
| 251 } | 244 } |
| 252 } | 245 } |
| 253 } | 246 } |
| 254 | 247 |
| 255 } // namespace media | 248 } // namespace media |
| OLD | NEW |