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

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

Issue 6969026: Convert Filter::Seek() to use new callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More CR fixes Created 9 years, 7 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
« no previous file with comments | « media/base/composite_filter.h ('k') | media/base/composite_filter_unittest.cc » ('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 (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 #include "media/base/composite_filter.h" 5 #include "media/base/composite_filter.h"
6 6
7 #include "base/bind.h"
7 #include "base/message_loop.h" 8 #include "base/message_loop.h"
8 #include "base/stl_util-inl.h" 9 #include "base/stl_util-inl.h"
9 #include "media/base/callback.h" 10 #include "media/base/callback.h"
10 11
11 namespace media { 12 namespace media {
12 13
13 class CompositeFilter::FilterHostImpl : public FilterHost { 14 class CompositeFilter::FilterHostImpl : public FilterHost {
14 public: 15 public:
15 FilterHostImpl(CompositeFilter* parent, FilterHost* host); 16 FilterHostImpl(CompositeFilter* parent, FilterHost* host);
16 17
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 host_impl_.reset(new FilterHostImpl(this, host)); 77 host_impl_.reset(new FilterHostImpl(this, host));
77 } 78 }
78 79
79 FilterHost* CompositeFilter::host() { 80 FilterHost* CompositeFilter::host() {
80 return host_impl_.get() ? host_impl_->host() : NULL; 81 return host_impl_.get() ? host_impl_->host() : NULL;
81 } 82 }
82 83
83 void CompositeFilter::Play(FilterCallback* play_callback) { 84 void CompositeFilter::Play(FilterCallback* play_callback) {
84 DCHECK_EQ(message_loop_, MessageLoop::current()); 85 DCHECK_EQ(message_loop_, MessageLoop::current());
85 scoped_ptr<FilterCallback> callback(play_callback); 86 scoped_ptr<FilterCallback> callback(play_callback);
86 if (callback_.get()) { 87 if (IsOperationPending()) {
87 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING); 88 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
88 callback->Run(); 89 callback->Run();
89 return; 90 return;
90 } else if (state_ == kPlaying) { 91 } else if (state_ == kPlaying) {
91 callback->Run(); 92 callback->Run();
92 return; 93 return;
93 } else if (!host() || (state_ != kPaused && state_ != kCreated)) { 94 } else if (!host() || (state_ != kPaused && state_ != kCreated)) {
94 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE); 95 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
95 callback->Run(); 96 callback->Run();
96 return; 97 return;
97 } 98 }
98 99
99 ChangeState(kPlayPending); 100 ChangeState(kPlayPending);
100 callback_.reset(callback.release()); 101 callback_.reset(callback.release());
101 StartSerialCallSequence(); 102 StartSerialCallSequence();
102 } 103 }
103 104
104 void CompositeFilter::Pause(FilterCallback* pause_callback) { 105 void CompositeFilter::Pause(FilterCallback* pause_callback) {
105 DCHECK_EQ(message_loop_, MessageLoop::current()); 106 DCHECK_EQ(message_loop_, MessageLoop::current());
106 scoped_ptr<FilterCallback> callback(pause_callback); 107 scoped_ptr<FilterCallback> callback(pause_callback);
107 if (callback_.get()) { 108 if (IsOperationPending()) {
108 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING); 109 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
109 callback->Run(); 110 callback->Run();
110 return; 111 return;
111 } else if (state_ == kPaused) { 112 } else if (state_ == kPaused) {
112 callback->Run(); 113 callback->Run();
113 return; 114 return;
114 } else if (!host() || state_ != kPlaying) { 115 } else if (!host() || state_ != kPlaying) {
115 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE); 116 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
116 callback->Run(); 117 callback->Run();
117 return; 118 return;
118 } 119 }
119 120
120 ChangeState(kPausePending); 121 ChangeState(kPausePending);
121 callback_.reset(callback.release()); 122 callback_.reset(callback.release());
122 StartSerialCallSequence(); 123 StartSerialCallSequence();
123 } 124 }
124 125
125 void CompositeFilter::Flush(FilterCallback* flush_callback) { 126 void CompositeFilter::Flush(FilterCallback* flush_callback) {
126 DCHECK_EQ(message_loop_, MessageLoop::current()); 127 DCHECK_EQ(message_loop_, MessageLoop::current());
127 scoped_ptr<FilterCallback> callback(flush_callback); 128 scoped_ptr<FilterCallback> callback(flush_callback);
128 if (callback_.get()) { 129 if (IsOperationPending()) {
129 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING); 130 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING);
130 callback->Run(); 131 callback->Run();
131 return; 132 return;
132 } else if (!host() || (state_ != kCreated && state_ != kPaused)) { 133 } else if (!host() || (state_ != kCreated && state_ != kPaused)) {
133 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE); 134 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE);
134 callback->Run(); 135 callback->Run();
135 return; 136 return;
136 } 137 }
137 138
138 ChangeState(kFlushPending); 139 ChangeState(kFlushPending);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 void CompositeFilter::SetPlaybackRate(float playback_rate) { 187 void CompositeFilter::SetPlaybackRate(float playback_rate) {
187 DCHECK_EQ(message_loop_, MessageLoop::current()); 188 DCHECK_EQ(message_loop_, MessageLoop::current());
188 for (FilterVector::iterator iter = filters_.begin(); 189 for (FilterVector::iterator iter = filters_.begin();
189 iter != filters_.end(); 190 iter != filters_.end();
190 ++iter) { 191 ++iter) {
191 (*iter)->SetPlaybackRate(playback_rate); 192 (*iter)->SetPlaybackRate(playback_rate);
192 } 193 }
193 } 194 }
194 195
195 void CompositeFilter::Seek(base::TimeDelta time, 196 void CompositeFilter::Seek(base::TimeDelta time,
196 FilterCallback* seek_callback) { 197 const FilterStatusCB& seek_cb) {
197 DCHECK_EQ(message_loop_, MessageLoop::current()); 198 DCHECK_EQ(message_loop_, MessageLoop::current());
198 scoped_ptr<FilterCallback> callback(seek_callback); 199
199 if (callback_.get()) { 200 if (IsOperationPending()) {
200 SendErrorToHost(PIPELINE_ERROR_OPERATION_PENDING); 201 seek_cb.Run(PIPELINE_ERROR_OPERATION_PENDING);
201 callback->Run();
202 return; 202 return;
203 } else if (!host() || (state_ != kPaused && state_ != kCreated)) { 203 } else if (!host() || (state_ != kPaused && state_ != kCreated)) {
204 SendErrorToHost(PIPELINE_ERROR_INVALID_STATE); 204 seek_cb.Run(PIPELINE_ERROR_INVALID_STATE);
205 callback->Run();
206 return; 205 return;
207 } 206 }
208 207
209 ChangeState(kSeekPending); 208 ChangeState(kSeekPending);
210 callback_.reset(callback.release()); 209 status_cb_ = seek_cb;
211 pending_seek_time_ = time; 210 pending_seek_time_ = time;
212 StartSerialCallSequence(); 211 StartSerialCallSequence();
213 } 212 }
214 213
215 void CompositeFilter::OnAudioRendererDisabled() { 214 void CompositeFilter::OnAudioRendererDisabled() {
216 DCHECK_EQ(message_loop_, MessageLoop::current()); 215 DCHECK_EQ(message_loop_, MessageLoop::current());
217 for (FilterVector::iterator iter = filters_.begin(); 216 for (FilterVector::iterator iter = filters_.begin();
218 iter != filters_.end(); 217 iter != filters_.end();
219 ++iter) { 218 ++iter) {
220 (*iter)->OnAudioRendererDisabled(); 219 (*iter)->OnAudioRendererDisabled();
221 } 220 }
222 } 221 }
223 222
224 void CompositeFilter::ChangeState(State new_state) { 223 void CompositeFilter::ChangeState(State new_state) {
225 DCHECK_EQ(message_loop_, MessageLoop::current()); 224 DCHECK_EQ(message_loop_, MessageLoop::current());
226 state_ = new_state; 225 state_ = new_state;
227 } 226 }
228 227
229 void CompositeFilter::StartSerialCallSequence() { 228 void CompositeFilter::StartSerialCallSequence() {
230 DCHECK_EQ(message_loop_, MessageLoop::current()); 229 DCHECK_EQ(message_loop_, MessageLoop::current());
231 status_ = PIPELINE_OK; 230 status_ = PIPELINE_OK;
231 sequence_index_ = 0;
232 232
233 if (!filters_.empty()) { 233 if (!filters_.empty()) {
234 sequence_index_ = 0;
235 CallFilter(filters_[sequence_index_], 234 CallFilter(filters_[sequence_index_],
236 NewThreadSafeCallback(&CompositeFilter::SerialCallback)); 235 NewThreadSafeCallback(&CompositeFilter::SerialCallback));
237 } else { 236 } else {
238 sequence_index_ = 0;
239 SerialCallback(); 237 SerialCallback();
240 } 238 }
241 } 239 }
242 240
243 void CompositeFilter::StartParallelCallSequence() { 241 void CompositeFilter::StartParallelCallSequence() {
244 DCHECK_EQ(message_loop_, MessageLoop::current()); 242 DCHECK_EQ(message_loop_, MessageLoop::current());
245 status_ = PIPELINE_OK; 243 status_ = PIPELINE_OK;
244 sequence_index_ = 0;
246 245
247 if (!filters_.empty()) { 246 if (!filters_.empty()) {
248 sequence_index_ = 0;
249 for (size_t i = 0; i < filters_.size(); i++) { 247 for (size_t i = 0; i < filters_.size(); i++) {
250 CallFilter(filters_[i], 248 CallFilter(filters_[i],
251 NewThreadSafeCallback(&CompositeFilter::ParallelCallback)); 249 NewThreadSafeCallback(&CompositeFilter::ParallelCallback));
252 } 250 }
253 } else { 251 } else {
254 sequence_index_ = 0;
255 ParallelCallback(); 252 ParallelCallback();
256 } 253 }
257 } 254 }
258 255
259 void CompositeFilter::CallFilter(scoped_refptr<Filter>& filter, 256 void CompositeFilter::CallFilter(scoped_refptr<Filter>& filter,
260 FilterCallback* callback) { 257 FilterCallback* callback) {
261 switch (state_) { 258 switch (state_) {
262 case kPlayPending: 259 case kPlayPending:
263 filter->Play(callback); 260 filter->Play(callback);
264 break; 261 break;
265 case kPausePending: 262 case kPausePending:
266 filter->Pause(callback); 263 filter->Pause(callback);
267 break; 264 break;
268 case kFlushPending: 265 case kFlushPending:
269 filter->Flush(callback); 266 filter->Flush(callback);
270 break; 267 break;
271 case kStopPending: 268 case kStopPending:
272 filter->Stop(callback); 269 filter->Stop(callback);
273 break; 270 break;
274 case kSeekPending: 271 case kSeekPending:
275 filter->Seek(pending_seek_time_, callback); 272 filter->Seek(pending_seek_time_,
273 base::Bind(&CompositeFilter::OnStatusCB, this, callback));
276 break; 274 break;
277 default: 275 default:
278 delete callback; 276 delete callback;
279 ChangeState(kError); 277 ChangeState(kError);
280 HandleError(PIPELINE_ERROR_INVALID_STATE); 278 DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE);
281 } 279 }
282 } 280 }
283 281
284 void CompositeFilter::DispatchPendingCallback() { 282 void CompositeFilter::DispatchPendingCallback(PipelineStatus status) {
283 DCHECK((status_cb_.is_null() && callback_.get()) ||
284 (!status_cb_.is_null() && !callback_.get()));
285
286 if (!status_cb_.is_null()) {
287 ResetAndRunCB(&status_cb_, status);
288 return;
289 }
290
285 if (callback_.get()) { 291 if (callback_.get()) {
292 if (status != PIPELINE_OK)
293 SendErrorToHost(status);
294
286 scoped_ptr<FilterCallback> callback(callback_.release()); 295 scoped_ptr<FilterCallback> callback(callback_.release());
287 callback->Run(); 296 callback->Run();
288 } 297 }
289 } 298 }
290 299
291 CompositeFilter::State CompositeFilter::GetNextState(State state) const { 300 CompositeFilter::State CompositeFilter::GetNextState(State state) const {
292 State ret = kInvalid; 301 State ret = kInvalid;
293 switch (state) { 302 switch (state) {
294 case kPlayPending: 303 case kPlayPending:
295 ret = kPlaying; 304 ret = kPlaying;
(...skipping 28 matching lines...) Expand all
324 } 333 }
325 334
326 return ret; 335 return ret;
327 } 336 }
328 337
329 void CompositeFilter::SerialCallback() { 338 void CompositeFilter::SerialCallback() {
330 DCHECK_EQ(message_loop_, MessageLoop::current()); 339 DCHECK_EQ(message_loop_, MessageLoop::current());
331 if (status_ != PIPELINE_OK) { 340 if (status_ != PIPELINE_OK) {
332 // We encountered an error. Terminate the sequence now. 341 // We encountered an error. Terminate the sequence now.
333 ChangeState(kError); 342 ChangeState(kError);
334 HandleError(status_); 343 DispatchPendingCallback(status_);
335 return; 344 return;
336 } 345 }
337 346
338 if (!filters_.empty()) 347 if (!filters_.empty())
339 sequence_index_++; 348 sequence_index_++;
340 349
341 if (sequence_index_ == filters_.size()) { 350 if (sequence_index_ == filters_.size()) {
342 // All filters have been successfully called without error. 351 // All filters have been successfully called without error.
343 OnCallSequenceDone(); 352 OnCallSequenceDone();
344 } else if (GetNextState(state_) == kStopPending) { 353 } else if (GetNextState(state_) == kStopPending) {
(...skipping 10 matching lines...) Expand all
355 void CompositeFilter::ParallelCallback() { 364 void CompositeFilter::ParallelCallback() {
356 DCHECK_EQ(message_loop_, MessageLoop::current()); 365 DCHECK_EQ(message_loop_, MessageLoop::current());
357 366
358 if (!filters_.empty()) 367 if (!filters_.empty())
359 sequence_index_++; 368 sequence_index_++;
360 369
361 if (sequence_index_ == filters_.size()) { 370 if (sequence_index_ == filters_.size()) {
362 if (status_ != PIPELINE_OK) { 371 if (status_ != PIPELINE_OK) {
363 // We encountered an error. 372 // We encountered an error.
364 ChangeState(kError); 373 ChangeState(kError);
365 HandleError(status_); 374 DispatchPendingCallback(status_);
366 return; 375 return;
367 } 376 }
368 377
369 OnCallSequenceDone(); 378 OnCallSequenceDone();
370 } 379 }
371 } 380 }
372 381
373 void CompositeFilter::OnCallSequenceDone() { 382 void CompositeFilter::OnCallSequenceDone() {
374 State next_state = GetNextState(state_); 383 State next_state = GetNextState(state_);
375 384
376 if (next_state == kInvalid) { 385 if (next_state == kInvalid) {
377 // We somehow got into an unexpected state. 386 // We somehow got into an unexpected state.
378 ChangeState(kError); 387 ChangeState(kError);
379 HandleError(PIPELINE_ERROR_INVALID_STATE); 388 DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE);
389 return;
380 } 390 }
381 391
382 ChangeState(next_state); 392 ChangeState(next_state);
383 393
384 if (state_ == kStopPending) { 394 if (state_ == kStopPending) {
385 // Handle a deferred Stop(). 395 // Handle a deferred Stop().
386 StartSerialCallSequence(); 396 StartSerialCallSequence();
387 } else { 397 } else {
388 // Call the callback to indicate that the operation has completed. 398 // Call the callback to indicate that the operation has completed.
389 DispatchPendingCallback(); 399 DispatchPendingCallback(PIPELINE_OK);
390 } 400 }
391 } 401 }
392 402
393 void CompositeFilter::SendErrorToHost(PipelineStatus error) { 403 void CompositeFilter::SendErrorToHost(PipelineStatus error) {
394 if (host_impl_.get()) 404 if (host_impl_.get())
395 host_impl_.get()->host()->SetError(error); 405 host_impl_.get()->host()->SetError(error);
396 } 406 }
397 407
398 void CompositeFilter::HandleError(PipelineStatus error) {
399 DCHECK_NE(error, PIPELINE_OK);
400 SendErrorToHost(error);
401 DispatchPendingCallback();
402 }
403
404 FilterCallback* CompositeFilter::NewThreadSafeCallback( 408 FilterCallback* CompositeFilter::NewThreadSafeCallback(
405 void (CompositeFilter::*method)()) { 409 void (CompositeFilter::*method)()) {
406 return TaskToCallbackAdapter::NewCallback( 410 return TaskToCallbackAdapter::NewCallback(
407 NewRunnableFunction(&CompositeFilter::OnCallback, 411 NewRunnableFunction(&CompositeFilter::OnCallback,
408 message_loop_, 412 message_loop_,
409 runnable_factory_->NewRunnableMethod(method))); 413 runnable_factory_->NewRunnableMethod(method)));
410 } 414 }
411 415
412 // This method is intentionally static so that no reference to the composite 416 // This method is intentionally static so that no reference to the composite
413 // is needed to call it. This method may be called by other threads and we 417 // is needed to call it. This method may be called by other threads and we
(...skipping 11 matching lines...) Expand all
425 } 429 }
426 430
427 task->Run(); 431 task->Run();
428 delete task; 432 delete task;
429 } 433 }
430 434
431 bool CompositeFilter::CanForwardError() { 435 bool CompositeFilter::CanForwardError() {
432 return (state_ == kCreated) || (state_ == kPlaying) || (state_ == kPaused); 436 return (state_ == kCreated) || (state_ == kPlaying) || (state_ == kPaused);
433 } 437 }
434 438
439 bool CompositeFilter::IsOperationPending() const {
440 DCHECK(!(callback_.get() && !status_cb_.is_null()));
441
442 return callback_.get() || !status_cb_.is_null();
443 }
444
445 void CompositeFilter::OnStatusCB(FilterCallback* callback,
446 PipelineStatus status) {
447 if (status != PIPELINE_OK)
448 SetError(status);
449
450 callback->Run();
451 delete callback;
452 }
453
435 void CompositeFilter::SetError(PipelineStatus error) { 454 void CompositeFilter::SetError(PipelineStatus error) {
436 // TODO(acolwell): Temporary hack to handle errors that occur 455 // TODO(acolwell): Temporary hack to handle errors that occur
437 // during filter initialization. In this case we just forward 456 // during filter initialization. In this case we just forward
438 // the error to the host even if it is on the wrong thread. We 457 // the error to the host even if it is on the wrong thread. We
439 // have to do this because if we defer the call, we can't be 458 // have to do this because if we defer the call, we can't be
440 // sure the host will get the error before the "init done" callback 459 // sure the host will get the error before the "init done" callback
441 // is executed. This will be cleaned up when filter init is refactored. 460 // is executed. This will be cleaned up when filter init is refactored.
442 if (state_ == kCreated) { 461 if (state_ == kCreated) {
443 SendErrorToHost(error); 462 SendErrorToHost(error);
444 return; 463 return;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 554
536 void CompositeFilter::FilterHostImpl::SetCurrentReadPosition(int64 offset) { 555 void CompositeFilter::FilterHostImpl::SetCurrentReadPosition(int64 offset) {
537 host_->SetCurrentReadPosition(offset); 556 host_->SetCurrentReadPosition(offset);
538 } 557 }
539 558
540 int64 CompositeFilter::FilterHostImpl::GetCurrentReadPosition() { 559 int64 CompositeFilter::FilterHostImpl::GetCurrentReadPosition() {
541 return host_->GetCurrentReadPosition(); 560 return host_->GetCurrentReadPosition();
542 } 561 }
543 562
544 } // namespace media 563 } // namespace media
OLDNEW
« no previous file with comments | « media/base/composite_filter.h ('k') | media/base/composite_filter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698