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

Side by Side Diff: media/filters/pipeline_controller.cc

Issue 2366373003: Not for submission. fastSeek prototype. (Closed)
Patch Set: Created 4 years, 2 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/filters/pipeline_controller.h ('k') | media/mojo/clients/mojo_renderer.h » ('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 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 "media/base/demuxer.h" 8 #include "media/base/demuxer.h"
9 9
10 namespace media { 10 namespace media {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 state_ = State::STARTING; 48 state_ = State::STARTING;
49 49
50 demuxer_ = demuxer; 50 demuxer_ = demuxer;
51 is_streaming_ = is_streaming; 51 is_streaming_ = is_streaming;
52 is_static_ = is_static; 52 is_static_ = is_static;
53 pipeline_->Start(demuxer, renderer_factory_cb_.Run(), client, 53 pipeline_->Start(demuxer, renderer_factory_cb_.Run(), client,
54 base::Bind(&PipelineController::OnPipelineStatus, 54 base::Bind(&PipelineController::OnPipelineStatus,
55 weak_factory_.GetWeakPtr(), State::PLAYING)); 55 weak_factory_.GetWeakPtr(), State::PLAYING));
56 } 56 }
57 57
58 void PipelineController::Seek(base::TimeDelta time, bool time_updated) { 58 void PipelineController::Seek(StreamPosition position, bool time_updated) {
59 DCHECK(thread_checker_.CalledOnValidThread()); 59 DCHECK(thread_checker_.CalledOnValidThread());
60 60
61 // It would be slightly more clear to set this in Dispatch(), but we want to 61 // It would be slightly more clear to set this in Dispatch(), but we want to
62 // be sure it gets updated even if the seek is elided. 62 // be sure it gets updated even if the seek is elided.
63 if (time_updated) 63 if (time_updated)
64 pending_time_updated_ = true; 64 pending_time_updated_ = true;
65 pending_seeked_cb_ = true; 65 pending_seeked_cb_ = true;
66 66
67 // If we are already seeking to |time|, and the media is static, elide the 67 // If we are already seeking to |time|, and the media is static, elide the
68 // seek. 68 // seek.
69 if ((state_ == State::SEEKING || state_ == State::RESUMING) && 69 if ((state_ == State::SEEKING || state_ == State::RESUMING) &&
70 seek_time_ == time && is_static_) { 70 seek_position_ == position && is_static_) {
71 pending_seek_ = false; 71 pending_seek_ = false;
72 return; 72 return;
73 } 73 }
74 74
75 pending_seek_time_ = time; 75 pending_seek_position_ = position;
76 pending_seek_ = true; 76 pending_seek_ = true;
77 Dispatch(); 77 Dispatch();
78 } 78 }
79 79
80 // TODO(sandersd): It may be easier to use this interface if |suspended_cb_| is 80 // TODO(sandersd): It may be easier to use this interface if |suspended_cb_| is
81 // executed when Suspend() is called while already suspended. 81 // executed when Suspend() is called while already suspended.
82 void PipelineController::Suspend() { 82 void PipelineController::Suspend() {
83 DCHECK(thread_checker_.CalledOnValidThread()); 83 DCHECK(thread_checker_.CalledOnValidThread());
84 pending_resume_ = false; 84 pending_resume_ = false;
85 if (state_ != State::SUSPENDING && state_ != State::SUSPENDED) { 85 if (state_ != State::SUSPENDING && state_ != State::SUSPENDED) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 state_ = State::SUSPENDING; 150 state_ = State::SUSPENDING;
151 pipeline_->Suspend(base::Bind(&PipelineController::OnPipelineStatus, 151 pipeline_->Suspend(base::Bind(&PipelineController::OnPipelineStatus,
152 weak_factory_.GetWeakPtr(), 152 weak_factory_.GetWeakPtr(),
153 State::SUSPENDED)); 153 State::SUSPENDED));
154 return; 154 return;
155 } 155 }
156 156
157 if (pending_resume_ && state_ == State::SUSPENDED) { 157 if (pending_resume_ && state_ == State::SUSPENDED) {
158 // If there is a pending seek, resume to that time instead... 158 // If there is a pending seek, resume to that time instead...
159 if (pending_seek_) { 159 if (pending_seek_) {
160 seek_time_ = pending_seek_time_; 160 seek_position_ = StreamPosition::Precise(pending_seek_position_.time);
161 pending_seek_ = false; 161 pending_seek_ = false;
162 } else { 162 } else {
163 seek_time_ = pipeline_->GetMediaTime(); 163 seek_position_ = StreamPosition::Precise(pipeline_->GetMediaTime());
164 } 164 }
165 165
166 // ...unless the media is streaming, in which case we resume at the start 166 // ...unless the media is streaming, in which case we resume at the start
167 // because seeking doesn't work well. 167 // because seeking doesn't work well.
168 if (is_streaming_ && !seek_time_.is_zero()) { 168 if (is_streaming_ && !seek_position_.time.is_zero()) {
169 seek_time_ = base::TimeDelta(); 169 seek_position_ = StreamPosition::Precise(base::TimeDelta());
170 170
171 // In this case we want to make sure that the controls get updated 171 // In this case we want to make sure that the controls get updated
172 // immediately, so we don't try to hide the seek. 172 // immediately, so we don't try to hide the seek.
173 pending_time_updated_ = true; 173 pending_time_updated_ = true;
174 } 174 }
175 175
176 // Tell |demuxer_| to expect our resume. 176 // Tell |demuxer_| to expect our resume.
177 DCHECK(!waiting_for_seek_); 177 DCHECK(!waiting_for_seek_);
178 waiting_for_seek_ = true; 178 waiting_for_seek_ = true;
179 demuxer_->StartWaitingForSeek(seek_time_); 179 demuxer_->StartWaitingForSeek(seek_position_.time);
180 180
181 pending_resume_ = false; 181 pending_resume_ = false;
182 state_ = State::RESUMING; 182 state_ = State::RESUMING;
183 pipeline_->Resume(renderer_factory_cb_.Run(), seek_time_, 183 pipeline_->Resume(renderer_factory_cb_.Run(), seek_position_.time,
184 base::Bind(&PipelineController::OnPipelineStatus, 184 base::Bind(&PipelineController::OnPipelineStatus,
185 weak_factory_.GetWeakPtr(), State::PLAYING)); 185 weak_factory_.GetWeakPtr(), State::PLAYING));
186 return; 186 return;
187 } 187 }
188 188
189 // If we have pending operations, and a seek is ongoing, abort it. 189 // If we have pending operations, and a seek is ongoing, abort it.
190 if ((pending_seek_ || pending_suspend_) && waiting_for_seek_) { 190 if ((pending_seek_ || pending_suspend_) && waiting_for_seek_) {
191 // If there is no pending seek, return the current seek to pending status. 191 // If there is no pending seek, return the current seek to pending status.
192 if (!pending_seek_) { 192 if (!pending_seek_) {
193 pending_seek_time_ = seek_time_; 193 pending_seek_position_ = seek_position_;
194 pending_seek_ = true; 194 pending_seek_ = true;
195 } 195 }
196 196
197 // CancelPendingSeek() may be reentrant, so update state first and return 197 // CancelPendingSeek() may be reentrant, so update state first and return
198 // immediately. 198 // immediately.
199 waiting_for_seek_ = false; 199 waiting_for_seek_ = false;
200 demuxer_->CancelPendingSeek(pending_seek_time_); 200 demuxer_->CancelPendingSeek(pending_seek_position_.time);
201 return; 201 return;
202 } 202 }
203 203
204 // Ordinary seeking. 204 // Ordinary seeking.
205 if (pending_seek_ && state_ == State::PLAYING) { 205 if (pending_seek_ && state_ == State::PLAYING) {
206 seek_time_ = pending_seek_time_; 206 seek_position_ = pending_seek_position_;
207 207
208 // Tell |demuxer_| to expect our seek. 208 // Tell |demuxer_| to expect our seek.
209 DCHECK(!waiting_for_seek_); 209 DCHECK(!waiting_for_seek_);
210 waiting_for_seek_ = true; 210 waiting_for_seek_ = true;
211 demuxer_->StartWaitingForSeek(seek_time_); 211 demuxer_->StartWaitingForSeek(seek_position_.time);
212 212
213 pending_seek_ = false; 213 pending_seek_ = false;
214 state_ = State::SEEKING; 214 state_ = State::SEEKING;
215 pipeline_->Seek(seek_time_, 215 pipeline_->Seek(seek_position_,
216 base::Bind(&PipelineController::OnPipelineStatus, 216 base::Bind(&PipelineController::OnPipelineStatus,
217 weak_factory_.GetWeakPtr(), State::PLAYING)); 217 weak_factory_.GetWeakPtr(), State::PLAYING));
218 return; 218 return;
219 } 219 }
220 220
221 // If |state_| is PLAYING and we didn't trigger an operation above then we 221 // If |state_| is PLAYING and we didn't trigger an operation above then we
222 // are in a stable state. If there is a seeked callback pending, emit it. 222 // are in a stable state. If there is a seeked callback pending, emit it.
223 if (state_ == State::PLAYING) { 223 if (state_ == State::PLAYING) {
224 if (pending_seeked_cb_) { 224 if (pending_seeked_cb_) {
225 // |seeked_cb_| may be reentrant, so update state first and return 225 // |seeked_cb_| may be reentrant, so update state first and return
226 // immediately. 226 // immediately.
227 pending_seeked_cb_ = false; 227 pending_seeked_cb_ = false;
228 bool was_pending_time_updated = pending_time_updated_; 228 bool was_pending_time_updated = pending_time_updated_;
229 pending_time_updated_ = false; 229 pending_time_updated_ = false;
230 seeked_cb_.Run(was_pending_time_updated); 230 seeked_cb_.Run(was_pending_time_updated);
231 return; 231 return;
232 } 232 }
233 } 233 }
234 } 234 }
235 235
236 } // namespace media 236 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/pipeline_controller.h ('k') | media/mojo/clients/mojo_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698