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

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: Add files in content/renderer/media 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
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 HandleError(PIPELINE_ERROR_INVALID_STATE);
281 } 279 }
282 } 280 }
283 281
284 void CompositeFilter::DispatchPendingCallback() { 282 void CompositeFilter::DispatchPendingCallback() {
283 if (!status_cb_.is_null()) {
Ami GONE FROM CHROMIUM 2011/05/12 20:42:16 DCHECK not both fields are set?
acolwell GONE FROM CHROMIUM 2011/05/12 22:30:40 Done.
284 CopyAndResetCB(status_cb_).Run(PIPELINE_OK);
285 return;
286 }
287
285 if (callback_.get()) { 288 if (callback_.get()) {
286 scoped_ptr<FilterCallback> callback(callback_.release()); 289 scoped_ptr<FilterCallback> callback(callback_.release());
287 callback->Run(); 290 callback->Run();
288 } 291 }
289 } 292 }
290 293
291 CompositeFilter::State CompositeFilter::GetNextState(State state) const { 294 CompositeFilter::State CompositeFilter::GetNextState(State state) const {
292 State ret = kInvalid; 295 State ret = kInvalid;
293 switch (state) { 296 switch (state) {
294 case kPlayPending: 297 case kPlayPending:
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 } 393 }
391 } 394 }
392 395
393 void CompositeFilter::SendErrorToHost(PipelineStatus error) { 396 void CompositeFilter::SendErrorToHost(PipelineStatus error) {
394 if (host_impl_.get()) 397 if (host_impl_.get())
395 host_impl_.get()->host()->SetError(error); 398 host_impl_.get()->host()->SetError(error);
396 } 399 }
397 400
398 void CompositeFilter::HandleError(PipelineStatus error) { 401 void CompositeFilter::HandleError(PipelineStatus error) {
399 DCHECK_NE(error, PIPELINE_OK); 402 DCHECK_NE(error, PIPELINE_OK);
403
404 if (!status_cb_.is_null()) {
Ami GONE FROM CHROMIUM 2011/05/12 20:42:16 This duplicates code in DispatchPendingCallback. C
acolwell GONE FROM CHROMIUM 2011/05/12 22:30:40 Done. Merge functionality into DispatchPendingCall
405 CopyAndResetCB(status_cb_).Run(error);
406 return;
407 }
408
400 SendErrorToHost(error); 409 SendErrorToHost(error);
401 DispatchPendingCallback(); 410 DispatchPendingCallback();
402 } 411 }
403 412
404 FilterCallback* CompositeFilter::NewThreadSafeCallback( 413 FilterCallback* CompositeFilter::NewThreadSafeCallback(
405 void (CompositeFilter::*method)()) { 414 void (CompositeFilter::*method)()) {
406 return TaskToCallbackAdapter::NewCallback( 415 return TaskToCallbackAdapter::NewCallback(
407 NewRunnableFunction(&CompositeFilter::OnCallback, 416 NewRunnableFunction(&CompositeFilter::OnCallback,
408 message_loop_, 417 message_loop_,
409 runnable_factory_->NewRunnableMethod(method))); 418 runnable_factory_->NewRunnableMethod(method)));
(...skipping 15 matching lines...) Expand all
425 } 434 }
426 435
427 task->Run(); 436 task->Run();
428 delete task; 437 delete task;
429 } 438 }
430 439
431 bool CompositeFilter::CanForwardError() { 440 bool CompositeFilter::CanForwardError() {
432 return (state_ == kCreated) || (state_ == kPlaying) || (state_ == kPaused); 441 return (state_ == kCreated) || (state_ == kPlaying) || (state_ == kPaused);
433 } 442 }
434 443
444 bool CompositeFilter::IsOperationPending() const {
445 return callback_.get() || !status_cb_.is_null();
Ami GONE FROM CHROMIUM 2011/05/12 20:42:16 DCHECK !&& ?
acolwell GONE FROM CHROMIUM 2011/05/12 22:30:40 Done.
446 }
447
448 void CompositeFilter::OnStatusCB(FilterCallback* callback,
449 PipelineStatus status) {
450 if (status != PIPELINE_OK)
451 SetError(status);
452
453 callback->Run();
454 delete callback;
455 }
456
435 void CompositeFilter::SetError(PipelineStatus error) { 457 void CompositeFilter::SetError(PipelineStatus error) {
436 // TODO(acolwell): Temporary hack to handle errors that occur 458 // TODO(acolwell): Temporary hack to handle errors that occur
437 // during filter initialization. In this case we just forward 459 // during filter initialization. In this case we just forward
438 // the error to the host even if it is on the wrong thread. We 460 // 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 461 // 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 462 // 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. 463 // is executed. This will be cleaned up when filter init is refactored.
442 if (state_ == kCreated) { 464 if (state_ == kCreated) {
443 SendErrorToHost(error); 465 SendErrorToHost(error);
444 return; 466 return;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 557
536 void CompositeFilter::FilterHostImpl::SetCurrentReadPosition(int64 offset) { 558 void CompositeFilter::FilterHostImpl::SetCurrentReadPosition(int64 offset) {
537 host_->SetCurrentReadPosition(offset); 559 host_->SetCurrentReadPosition(offset);
538 } 560 }
539 561
540 int64 CompositeFilter::FilterHostImpl::GetCurrentReadPosition() { 562 int64 CompositeFilter::FilterHostImpl::GetCurrentReadPosition() {
541 return host_->GetCurrentReadPosition(); 563 return host_->GetCurrentReadPosition();
542 } 564 }
543 565
544 } // namespace media 566 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698