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

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

Issue 407583002: Fold AudioRenderer::Stop() into the dtor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix ClocklessAudioSink Created 6 years, 5 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/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/audio_renderer_impl.h" 5 #include "media/filters/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 received_end_of_stream_(false), 60 received_end_of_stream_(false),
61 rendered_end_of_stream_(false), 61 rendered_end_of_stream_(false),
62 weak_factory_(this) { 62 weak_factory_(this) {
63 audio_buffer_stream_->set_splice_observer(base::Bind( 63 audio_buffer_stream_->set_splice_observer(base::Bind(
64 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); 64 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
65 audio_buffer_stream_->set_config_change_observer(base::Bind( 65 audio_buffer_stream_->set_config_change_observer(base::Bind(
66 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); 66 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
67 } 67 }
68 68
69 AudioRendererImpl::~AudioRendererImpl() { 69 AudioRendererImpl::~AudioRendererImpl() {
70 // Stop() should have been called and |algorithm_| should have been destroyed. 70 DVLOG(1) << __FUNCTION__;
71 DCHECK(state_ == kUninitialized || state_ == kStopped); 71 DCHECK(task_runner_->BelongsToCurrentThread());
72 DCHECK(!algorithm_.get()); 72
73 // If Render() is in progress, this call will wait for Render() to finish.
74 // After this call, the |sink_| will not call back into |this| anymore.
75 sink_->Stop();
76
77 if (!init_cb_.is_null())
78 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
73 } 79 }
74 80
75 void AudioRendererImpl::StartTicking() { 81 void AudioRendererImpl::StartTicking() {
76 DVLOG(1) << __FUNCTION__; 82 DVLOG(1) << __FUNCTION__;
77 DCHECK(task_runner_->BelongsToCurrentThread()); 83 DCHECK(task_runner_->BelongsToCurrentThread());
78 DCHECK(!rendering_); 84 DCHECK(!rendering_);
79 rendering_ = true; 85 rendering_ = true;
80 86
81 base::AutoLock auto_lock(lock_); 87 base::AutoLock auto_lock(lock_);
82 // Wait for an eventual call to SetPlaybackRate() to start rendering. 88 // Wait for an eventual call to SetPlaybackRate() to start rendering.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 DCHECK_EQ(state_, kFlushed); 188 DCHECK_EQ(state_, kFlushed);
183 189
184 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, 190 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
185 weak_factory_.GetWeakPtr())); 191 weak_factory_.GetWeakPtr()));
186 } 192 }
187 193
188 void AudioRendererImpl::ResetDecoderDone() { 194 void AudioRendererImpl::ResetDecoderDone() {
189 DCHECK(task_runner_->BelongsToCurrentThread()); 195 DCHECK(task_runner_->BelongsToCurrentThread());
190 { 196 {
191 base::AutoLock auto_lock(lock_); 197 base::AutoLock auto_lock(lock_);
192 if (state_ == kStopped)
193 return;
194 198
195 DCHECK_EQ(state_, kFlushed); 199 DCHECK_EQ(state_, kFlushed);
196 DCHECK(!flush_cb_.is_null()); 200 DCHECK(!flush_cb_.is_null());
197 201
198 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); 202 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
199 received_end_of_stream_ = false; 203 received_end_of_stream_ = false;
200 rendered_end_of_stream_ = false; 204 rendered_end_of_stream_ = false;
201 205
202 // Flush() may have been called while underflowed/not fully buffered. 206 // Flush() may have been called while underflowed/not fully buffered.
203 if (buffering_state_ != BUFFERING_HAVE_NOTHING) 207 if (buffering_state_ != BUFFERING_HAVE_NOTHING)
204 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); 208 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
205 209
206 splicer_->Reset(); 210 splicer_->Reset();
207 if (buffer_converter_) 211 if (buffer_converter_)
208 buffer_converter_->Reset(); 212 buffer_converter_->Reset();
209 algorithm_->FlushBuffers(); 213 algorithm_->FlushBuffers();
210 } 214 }
211 215
212 // Changes in buffering state are always posted. Flush callback must only be 216 // Changes in buffering state are always posted. Flush callback must only be
213 // run after buffering state has been set back to nothing. 217 // run after buffering state has been set back to nothing.
214 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_)); 218 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
215 } 219 }
216 220
217 void AudioRendererImpl::Stop(const base::Closure& callback) {
218 DVLOG(1) << __FUNCTION__;
219 DCHECK(task_runner_->BelongsToCurrentThread());
220 DCHECK(!callback.is_null());
221
222 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
223 // task-running guards that check |state_| with DCHECK().
224
225 {
226 base::AutoLock auto_lock(lock_);
227
228 if (state_ == kStopped) {
229 task_runner_->PostTask(FROM_HERE, callback);
230 return;
231 }
232
233 ChangeState_Locked(kStopped);
234 algorithm_.reset();
235 time_cb_.Reset();
236 flush_cb_.Reset();
237 }
238
239 if (sink_) {
240 sink_->Stop();
241 sink_ = NULL;
242 }
243
244 audio_buffer_stream_.reset();
245 task_runner_->PostTask(FROM_HERE, callback);
246 }
247
248 void AudioRendererImpl::StartPlaying() { 221 void AudioRendererImpl::StartPlaying() {
249 DVLOG(1) << __FUNCTION__; 222 DVLOG(1) << __FUNCTION__;
250 DCHECK(task_runner_->BelongsToCurrentThread()); 223 DCHECK(task_runner_->BelongsToCurrentThread());
251 224
252 base::AutoLock auto_lock(lock_); 225 base::AutoLock auto_lock(lock_);
253 DCHECK(!sink_playing_); 226 DCHECK(!sink_playing_);
254 DCHECK_EQ(state_, kFlushed); 227 DCHECK_EQ(state_, kFlushed);
255 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 228 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
256 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 229 DCHECK(!pending_read_) << "Pending read must complete before seeking";
257 230
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 statistics_cb, 300 statistics_cb,
328 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 301 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
329 weak_factory_.GetWeakPtr())); 302 weak_factory_.GetWeakPtr()));
330 } 303 }
331 304
332 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { 305 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
333 DCHECK(task_runner_->BelongsToCurrentThread()); 306 DCHECK(task_runner_->BelongsToCurrentThread());
334 307
335 base::AutoLock auto_lock(lock_); 308 base::AutoLock auto_lock(lock_);
336 309
337 if (state_ == kStopped) {
338 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
339 return;
340 }
341
342 if (!success) { 310 if (!success) {
343 state_ = kUninitialized; 311 state_ = kUninitialized;
344 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 312 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
345 return; 313 return;
346 } 314 }
347 315
348 if (!audio_parameters_.IsValid()) { 316 if (!audio_parameters_.IsValid()) {
349 ChangeState_Locked(kUninitialized); 317 ChangeState_Locked(kUninitialized);
350 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 318 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
351 return; 319 return;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 if (trim_time > base::TimeDelta()) { 430 if (trim_time > base::TimeDelta()) {
463 buffer->TrimStart(buffer->frame_count() * 431 buffer->TrimStart(buffer->frame_count() *
464 (static_cast<double>(trim_time.InMicroseconds()) / 432 (static_cast<double>(trim_time.InMicroseconds()) /
465 buffer->duration().InMicroseconds())); 433 buffer->duration().InMicroseconds()));
466 } 434 }
467 // If the entire buffer was trimmed, request a new one. 435 // If the entire buffer was trimmed, request a new one.
468 if (!buffer->frame_count()) 436 if (!buffer->frame_count())
469 return true; 437 return true;
470 } 438 }
471 439
472 if (state_ != kUninitialized && state_ != kStopped) 440 if (state_ != kUninitialized)
473 algorithm_->EnqueueBuffer(buffer); 441 algorithm_->EnqueueBuffer(buffer);
474 } 442 }
475 443
476 switch (state_) { 444 switch (state_) {
477 case kUninitialized: 445 case kUninitialized:
478 case kInitializing: 446 case kInitializing:
479 case kFlushing: 447 case kFlushing:
480 NOTREACHED(); 448 NOTREACHED();
481 return false; 449 return false;
482 450
483 case kFlushed: 451 case kFlushed:
484 DCHECK(!pending_read_); 452 DCHECK(!pending_read_);
485 return false; 453 return false;
486 454
487 case kPlaying: 455 case kPlaying:
488 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) { 456 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) {
489 if (buffering_state_ == BUFFERING_HAVE_NOTHING) 457 if (buffering_state_ == BUFFERING_HAVE_NOTHING)
490 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH); 458 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH);
491 return false; 459 return false;
492 } 460 }
493 return true; 461 return true;
494
495 case kStopped:
496 return false;
497 } 462 }
498 return false; 463 return false;
499 } 464 }
500 465
501 void AudioRendererImpl::AttemptRead() { 466 void AudioRendererImpl::AttemptRead() {
502 base::AutoLock auto_lock(lock_); 467 base::AutoLock auto_lock(lock_);
503 AttemptRead_Locked(); 468 AttemptRead_Locked();
504 } 469 }
505 470
506 void AudioRendererImpl::AttemptRead_Locked() { 471 void AudioRendererImpl::AttemptRead_Locked() {
507 DCHECK(task_runner_->BelongsToCurrentThread()); 472 DCHECK(task_runner_->BelongsToCurrentThread());
508 lock_.AssertAcquired(); 473 lock_.AssertAcquired();
509 474
510 if (!CanRead_Locked()) 475 if (!CanRead_Locked())
511 return; 476 return;
512 477
513 pending_read_ = true; 478 pending_read_ = true;
514 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, 479 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
515 weak_factory_.GetWeakPtr())); 480 weak_factory_.GetWeakPtr()));
516 } 481 }
517 482
518 bool AudioRendererImpl::CanRead_Locked() { 483 bool AudioRendererImpl::CanRead_Locked() {
519 lock_.AssertAcquired(); 484 lock_.AssertAcquired();
520 485
521 switch (state_) { 486 switch (state_) {
522 case kUninitialized: 487 case kUninitialized:
523 case kInitializing: 488 case kInitializing:
524 case kFlushing: 489 case kFlushing:
525 case kFlushed: 490 case kFlushed:
526 case kStopped:
527 return false; 491 return false;
528 492
529 case kPlaying: 493 case kPlaying:
530 break; 494 break;
531 } 495 }
532 496
533 return !pending_read_ && !received_end_of_stream_ && 497 return !pending_read_ && !received_end_of_stream_ &&
534 !algorithm_->IsQueueFull(); 498 !algorithm_->IsQueueFull();
535 } 499 }
536 500
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 DoFlush_Locked(); 647 DoFlush_Locked();
684 return; 648 return;
685 } 649 }
686 650
687 error_cb_.Run(status); 651 error_cb_.Run(status);
688 base::ResetAndReturn(&flush_cb_).Run(); 652 base::ResetAndReturn(&flush_cb_).Run();
689 return; 653 return;
690 654
691 case kFlushed: 655 case kFlushed:
692 case kPlaying: 656 case kPlaying:
693 case kStopped:
694 if (status != PIPELINE_OK) 657 if (status != PIPELINE_OK)
695 error_cb_.Run(status); 658 error_cb_.Run(status);
696 return; 659 return;
697 } 660 }
698 } 661 }
699 662
700 void AudioRendererImpl::ChangeState_Locked(State new_state) { 663 void AudioRendererImpl::ChangeState_Locked(State new_state) {
701 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 664 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
702 lock_.AssertAcquired(); 665 lock_.AssertAcquired();
703 state_ = new_state; 666 state_ = new_state;
(...skipping 21 matching lines...) Expand all
725 << buffering_state; 688 << buffering_state;
726 DCHECK_NE(buffering_state_, buffering_state); 689 DCHECK_NE(buffering_state_, buffering_state);
727 lock_.AssertAcquired(); 690 lock_.AssertAcquired();
728 buffering_state_ = buffering_state; 691 buffering_state_ = buffering_state;
729 692
730 task_runner_->PostTask(FROM_HERE, 693 task_runner_->PostTask(FROM_HERE,
731 base::Bind(buffering_state_cb_, buffering_state_)); 694 base::Bind(buffering_state_cb_, buffering_state_));
732 } 695 }
733 696
734 } // namespace media 697 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698