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

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: comments addressed 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();
DaleCurtis 2014/07/22 00:15:48 Correct, once this returns no further calls to the
76
77 if (!init_cb_.is_null())
78 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
73 } 79 }
74 80
75 void AudioRendererImpl::StartRendering() { 81 void AudioRendererImpl::StartRendering() {
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 DCHECK_EQ(state_, kFlushed); 173 DCHECK_EQ(state_, kFlushed);
168 174
169 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, 175 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
170 weak_factory_.GetWeakPtr())); 176 weak_factory_.GetWeakPtr()));
171 } 177 }
172 178
173 void AudioRendererImpl::ResetDecoderDone() { 179 void AudioRendererImpl::ResetDecoderDone() {
174 DCHECK(task_runner_->BelongsToCurrentThread()); 180 DCHECK(task_runner_->BelongsToCurrentThread());
175 { 181 {
176 base::AutoLock auto_lock(lock_); 182 base::AutoLock auto_lock(lock_);
177 if (state_ == kStopped)
178 return;
179 183
180 DCHECK_EQ(state_, kFlushed); 184 DCHECK_EQ(state_, kFlushed);
181 DCHECK(!flush_cb_.is_null()); 185 DCHECK(!flush_cb_.is_null());
182 186
183 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); 187 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
184 received_end_of_stream_ = false; 188 received_end_of_stream_ = false;
185 rendered_end_of_stream_ = false; 189 rendered_end_of_stream_ = false;
186 190
187 // Flush() may have been called while underflowed/not fully buffered. 191 // Flush() may have been called while underflowed/not fully buffered.
188 if (buffering_state_ != BUFFERING_HAVE_NOTHING) 192 if (buffering_state_ != BUFFERING_HAVE_NOTHING)
189 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); 193 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
190 194
191 splicer_->Reset(); 195 splicer_->Reset();
192 if (buffer_converter_) 196 if (buffer_converter_)
193 buffer_converter_->Reset(); 197 buffer_converter_->Reset();
194 algorithm_->FlushBuffers(); 198 algorithm_->FlushBuffers();
195 } 199 }
196 200
197 // Changes in buffering state are always posted. Flush callback must only be 201 // Changes in buffering state are always posted. Flush callback must only be
198 // run after buffering state has been set back to nothing. 202 // run after buffering state has been set back to nothing.
199 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_)); 203 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
200 } 204 }
201 205
202 void AudioRendererImpl::Stop(const base::Closure& callback) {
203 DVLOG(1) << __FUNCTION__;
204 DCHECK(task_runner_->BelongsToCurrentThread());
205 DCHECK(!callback.is_null());
206
207 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
208 // task-running guards that check |state_| with DCHECK().
209
210 {
211 base::AutoLock auto_lock(lock_);
212
213 if (state_ == kStopped) {
214 task_runner_->PostTask(FROM_HERE, callback);
215 return;
216 }
217
218 ChangeState_Locked(kStopped);
219 algorithm_.reset();
220 time_cb_.Reset();
221 flush_cb_.Reset();
222 }
223
224 if (sink_) {
225 sink_->Stop();
226 sink_ = NULL;
227 }
228
229 audio_buffer_stream_.reset();
230 task_runner_->PostTask(FROM_HERE, callback);
231 }
232
233 void AudioRendererImpl::StartPlaying() { 206 void AudioRendererImpl::StartPlaying() {
234 DVLOG(1) << __FUNCTION__; 207 DVLOG(1) << __FUNCTION__;
235 DCHECK(task_runner_->BelongsToCurrentThread()); 208 DCHECK(task_runner_->BelongsToCurrentThread());
236 209
237 base::AutoLock auto_lock(lock_); 210 base::AutoLock auto_lock(lock_);
238 DCHECK(!sink_playing_); 211 DCHECK(!sink_playing_);
239 DCHECK_EQ(state_, kFlushed); 212 DCHECK_EQ(state_, kFlushed);
240 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 213 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
241 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 214 DCHECK(!pending_read_) << "Pending read must complete before seeking";
242 215
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 statistics_cb, 285 statistics_cb,
313 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 286 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
314 weak_factory_.GetWeakPtr())); 287 weak_factory_.GetWeakPtr()));
315 } 288 }
316 289
317 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { 290 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
318 DCHECK(task_runner_->BelongsToCurrentThread()); 291 DCHECK(task_runner_->BelongsToCurrentThread());
319 292
320 base::AutoLock auto_lock(lock_); 293 base::AutoLock auto_lock(lock_);
321 294
322 if (state_ == kStopped) {
323 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
324 return;
325 }
326
327 if (!success) { 295 if (!success) {
328 state_ = kUninitialized; 296 state_ = kUninitialized;
329 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 297 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
330 return; 298 return;
331 } 299 }
332 300
333 if (!audio_parameters_.IsValid()) { 301 if (!audio_parameters_.IsValid()) {
334 ChangeState_Locked(kUninitialized); 302 ChangeState_Locked(kUninitialized);
335 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 303 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
336 return; 304 return;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 if (trim_time > base::TimeDelta()) { 415 if (trim_time > base::TimeDelta()) {
448 buffer->TrimStart(buffer->frame_count() * 416 buffer->TrimStart(buffer->frame_count() *
449 (static_cast<double>(trim_time.InMicroseconds()) / 417 (static_cast<double>(trim_time.InMicroseconds()) /
450 buffer->duration().InMicroseconds())); 418 buffer->duration().InMicroseconds()));
451 } 419 }
452 // If the entire buffer was trimmed, request a new one. 420 // If the entire buffer was trimmed, request a new one.
453 if (!buffer->frame_count()) 421 if (!buffer->frame_count())
454 return true; 422 return true;
455 } 423 }
456 424
457 if (state_ != kUninitialized && state_ != kStopped) 425 if (state_ != kUninitialized)
458 algorithm_->EnqueueBuffer(buffer); 426 algorithm_->EnqueueBuffer(buffer);
459 } 427 }
460 428
461 switch (state_) { 429 switch (state_) {
462 case kUninitialized: 430 case kUninitialized:
463 case kInitializing: 431 case kInitializing:
464 case kFlushing: 432 case kFlushing:
465 NOTREACHED(); 433 NOTREACHED();
466 return false; 434 return false;
467 435
468 case kFlushed: 436 case kFlushed:
469 DCHECK(!pending_read_); 437 DCHECK(!pending_read_);
470 return false; 438 return false;
471 439
472 case kPlaying: 440 case kPlaying:
473 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) { 441 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) {
474 if (buffering_state_ == BUFFERING_HAVE_NOTHING) 442 if (buffering_state_ == BUFFERING_HAVE_NOTHING)
475 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH); 443 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH);
476 return false; 444 return false;
477 } 445 }
478 return true; 446 return true;
479
480 case kStopped:
481 return false;
482 } 447 }
483 return false; 448 return false;
484 } 449 }
485 450
486 void AudioRendererImpl::AttemptRead() { 451 void AudioRendererImpl::AttemptRead() {
487 base::AutoLock auto_lock(lock_); 452 base::AutoLock auto_lock(lock_);
488 AttemptRead_Locked(); 453 AttemptRead_Locked();
489 } 454 }
490 455
491 void AudioRendererImpl::AttemptRead_Locked() { 456 void AudioRendererImpl::AttemptRead_Locked() {
492 DCHECK(task_runner_->BelongsToCurrentThread()); 457 DCHECK(task_runner_->BelongsToCurrentThread());
493 lock_.AssertAcquired(); 458 lock_.AssertAcquired();
494 459
495 if (!CanRead_Locked()) 460 if (!CanRead_Locked())
496 return; 461 return;
497 462
498 pending_read_ = true; 463 pending_read_ = true;
499 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, 464 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
500 weak_factory_.GetWeakPtr())); 465 weak_factory_.GetWeakPtr()));
501 } 466 }
502 467
503 bool AudioRendererImpl::CanRead_Locked() { 468 bool AudioRendererImpl::CanRead_Locked() {
504 lock_.AssertAcquired(); 469 lock_.AssertAcquired();
505 470
506 switch (state_) { 471 switch (state_) {
507 case kUninitialized: 472 case kUninitialized:
508 case kInitializing: 473 case kInitializing:
509 case kFlushing: 474 case kFlushing:
510 case kFlushed: 475 case kFlushed:
511 case kStopped:
512 return false; 476 return false;
513 477
514 case kPlaying: 478 case kPlaying:
515 break; 479 break;
516 } 480 }
517 481
518 return !pending_read_ && !received_end_of_stream_ && 482 return !pending_read_ && !received_end_of_stream_ &&
519 !algorithm_->IsQueueFull(); 483 !algorithm_->IsQueueFull();
520 } 484 }
521 485
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 DoFlush_Locked(); 632 DoFlush_Locked();
669 return; 633 return;
670 } 634 }
671 635
672 error_cb_.Run(status); 636 error_cb_.Run(status);
673 base::ResetAndReturn(&flush_cb_).Run(); 637 base::ResetAndReturn(&flush_cb_).Run();
674 return; 638 return;
675 639
676 case kFlushed: 640 case kFlushed:
677 case kPlaying: 641 case kPlaying:
678 case kStopped:
679 if (status != PIPELINE_OK) 642 if (status != PIPELINE_OK)
680 error_cb_.Run(status); 643 error_cb_.Run(status);
681 return; 644 return;
682 } 645 }
683 } 646 }
684 647
685 void AudioRendererImpl::ChangeState_Locked(State new_state) { 648 void AudioRendererImpl::ChangeState_Locked(State new_state) {
686 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 649 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
687 lock_.AssertAcquired(); 650 lock_.AssertAcquired();
688 state_ = new_state; 651 state_ = new_state;
(...skipping 21 matching lines...) Expand all
710 << buffering_state; 673 << buffering_state;
711 DCHECK_NE(buffering_state_, buffering_state); 674 DCHECK_NE(buffering_state_, buffering_state);
712 lock_.AssertAcquired(); 675 lock_.AssertAcquired();
713 buffering_state_ = buffering_state; 676 buffering_state_ = buffering_state;
714 677
715 task_runner_->PostTask(FROM_HERE, 678 task_runner_->PostTask(FROM_HERE,
716 base::Bind(buffering_state_cb_, buffering_state_)); 679 base::Bind(buffering_state_cb_, buffering_state_));
717 } 680 }
718 681
719 } // namespace media 682 } // 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