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

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 (sink_) {
74 // If Render() is in process, this call will wait for Render() to finish.
scherkus (not reviewing) 2014/07/21 23:38:20 s/process/progress/?
xhwang 2014/07/21 23:56:33 Done.
75 // After this call, the |sink_| will not call back into |this| anymore.
76 sink_->Stop();
77 sink_ = NULL;
scherkus (not reviewing) 2014/07/21 23:38:20 is this required to force the ref-count to zero? i
xhwang 2014/07/21 23:56:33 Probably not needed. The ref-count will be dropped
78 }
79
80 if (!init_cb_.is_null())
81 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
73 } 82 }
74 83
75 void AudioRendererImpl::StartRendering() { 84 void AudioRendererImpl::StartRendering() {
76 DVLOG(1) << __FUNCTION__; 85 DVLOG(1) << __FUNCTION__;
77 DCHECK(task_runner_->BelongsToCurrentThread()); 86 DCHECK(task_runner_->BelongsToCurrentThread());
78 DCHECK(!rendering_); 87 DCHECK(!rendering_);
79 rendering_ = true; 88 rendering_ = true;
80 89
81 base::AutoLock auto_lock(lock_); 90 base::AutoLock auto_lock(lock_);
82 // Wait for an eventual call to SetPlaybackRate() to start rendering. 91 // Wait for an eventual call to SetPlaybackRate() to start rendering.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 DCHECK_EQ(state_, kFlushed); 165 DCHECK_EQ(state_, kFlushed);
157 166
158 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, 167 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
159 weak_factory_.GetWeakPtr())); 168 weak_factory_.GetWeakPtr()));
160 } 169 }
161 170
162 void AudioRendererImpl::ResetDecoderDone() { 171 void AudioRendererImpl::ResetDecoderDone() {
163 DCHECK(task_runner_->BelongsToCurrentThread()); 172 DCHECK(task_runner_->BelongsToCurrentThread());
164 { 173 {
165 base::AutoLock auto_lock(lock_); 174 base::AutoLock auto_lock(lock_);
166 if (state_ == kStopped)
167 return;
168 175
169 DCHECK_EQ(state_, kFlushed); 176 DCHECK_EQ(state_, kFlushed);
170 DCHECK(!flush_cb_.is_null()); 177 DCHECK(!flush_cb_.is_null());
171 178
172 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); 179 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
173 received_end_of_stream_ = false; 180 received_end_of_stream_ = false;
174 rendered_end_of_stream_ = false; 181 rendered_end_of_stream_ = false;
175 182
176 // Flush() may have been called while underflowed/not fully buffered. 183 // Flush() may have been called while underflowed/not fully buffered.
177 if (buffering_state_ != BUFFERING_HAVE_NOTHING) 184 if (buffering_state_ != BUFFERING_HAVE_NOTHING)
178 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); 185 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
179 186
180 splicer_->Reset(); 187 splicer_->Reset();
181 if (buffer_converter_) 188 if (buffer_converter_)
182 buffer_converter_->Reset(); 189 buffer_converter_->Reset();
183 algorithm_->FlushBuffers(); 190 algorithm_->FlushBuffers();
184 } 191 }
185 192
186 // Changes in buffering state are always posted. Flush callback must only be 193 // Changes in buffering state are always posted. Flush callback must only be
187 // run after buffering state has been set back to nothing. 194 // run after buffering state has been set back to nothing.
188 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_)); 195 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
189 } 196 }
190 197
191 void AudioRendererImpl::Stop(const base::Closure& callback) {
192 DVLOG(1) << __FUNCTION__;
193 DCHECK(task_runner_->BelongsToCurrentThread());
194 DCHECK(!callback.is_null());
195
196 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
197 // task-running guards that check |state_| with DCHECK().
198
199 {
200 base::AutoLock auto_lock(lock_);
201
202 if (state_ == kStopped) {
203 task_runner_->PostTask(FROM_HERE, callback);
204 return;
205 }
206
207 ChangeState_Locked(kStopped);
208 algorithm_.reset();
209 time_cb_.Reset();
210 flush_cb_.Reset();
211 }
212
213 if (sink_) {
214 sink_->Stop();
215 sink_ = NULL;
216 }
217
218 audio_buffer_stream_.reset();
219 task_runner_->PostTask(FROM_HERE, callback);
220 }
221
222 void AudioRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { 198 void AudioRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) {
223 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InMicroseconds() << ")"; 199 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InMicroseconds() << ")";
224 DCHECK(task_runner_->BelongsToCurrentThread()); 200 DCHECK(task_runner_->BelongsToCurrentThread());
225 201
226 base::AutoLock auto_lock(lock_); 202 base::AutoLock auto_lock(lock_);
227 DCHECK(!sink_playing_); 203 DCHECK(!sink_playing_);
228 DCHECK_EQ(state_, kFlushed); 204 DCHECK_EQ(state_, kFlushed);
229 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING); 205 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
230 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 206 DCHECK(!pending_read_) << "Pending read must complete before seeking";
231 207
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 statistics_cb, 279 statistics_cb,
304 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 280 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
305 weak_factory_.GetWeakPtr())); 281 weak_factory_.GetWeakPtr()));
306 } 282 }
307 283
308 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { 284 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
309 DCHECK(task_runner_->BelongsToCurrentThread()); 285 DCHECK(task_runner_->BelongsToCurrentThread());
310 286
311 base::AutoLock auto_lock(lock_); 287 base::AutoLock auto_lock(lock_);
312 288
313 if (state_ == kStopped) {
314 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
315 return;
316 }
317
318 if (!success) { 289 if (!success) {
319 state_ = kUninitialized; 290 state_ = kUninitialized;
320 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 291 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
321 return; 292 return;
322 } 293 }
323 294
324 if (!audio_parameters_.IsValid()) { 295 if (!audio_parameters_.IsValid()) {
325 ChangeState_Locked(kUninitialized); 296 ChangeState_Locked(kUninitialized);
326 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 297 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
327 return; 298 return;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (trim_time > base::TimeDelta()) { 409 if (trim_time > base::TimeDelta()) {
439 buffer->TrimStart(buffer->frame_count() * 410 buffer->TrimStart(buffer->frame_count() *
440 (static_cast<double>(trim_time.InMicroseconds()) / 411 (static_cast<double>(trim_time.InMicroseconds()) /
441 buffer->duration().InMicroseconds())); 412 buffer->duration().InMicroseconds()));
442 } 413 }
443 // If the entire buffer was trimmed, request a new one. 414 // If the entire buffer was trimmed, request a new one.
444 if (!buffer->frame_count()) 415 if (!buffer->frame_count())
445 return true; 416 return true;
446 } 417 }
447 418
448 if (state_ != kUninitialized && state_ != kStopped) 419 if (state_ != kUninitialized)
449 algorithm_->EnqueueBuffer(buffer); 420 algorithm_->EnqueueBuffer(buffer);
450 } 421 }
451 422
452 switch (state_) { 423 switch (state_) {
453 case kUninitialized: 424 case kUninitialized:
454 case kInitializing: 425 case kInitializing:
455 case kFlushing: 426 case kFlushing:
456 NOTREACHED(); 427 NOTREACHED();
457 return false; 428 return false;
458 429
459 case kFlushed: 430 case kFlushed:
460 DCHECK(!pending_read_); 431 DCHECK(!pending_read_);
461 return false; 432 return false;
462 433
463 case kPlaying: 434 case kPlaying:
464 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) { 435 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) {
465 if (buffering_state_ == BUFFERING_HAVE_NOTHING) 436 if (buffering_state_ == BUFFERING_HAVE_NOTHING)
466 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH); 437 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH);
467 return false; 438 return false;
468 } 439 }
469 return true; 440 return true;
470
471 case kStopped:
472 return false;
473 } 441 }
474 return false; 442 return false;
475 } 443 }
476 444
477 void AudioRendererImpl::AttemptRead() { 445 void AudioRendererImpl::AttemptRead() {
478 base::AutoLock auto_lock(lock_); 446 base::AutoLock auto_lock(lock_);
479 AttemptRead_Locked(); 447 AttemptRead_Locked();
480 } 448 }
481 449
482 void AudioRendererImpl::AttemptRead_Locked() { 450 void AudioRendererImpl::AttemptRead_Locked() {
483 DCHECK(task_runner_->BelongsToCurrentThread()); 451 DCHECK(task_runner_->BelongsToCurrentThread());
484 lock_.AssertAcquired(); 452 lock_.AssertAcquired();
485 453
486 if (!CanRead_Locked()) 454 if (!CanRead_Locked())
487 return; 455 return;
488 456
489 pending_read_ = true; 457 pending_read_ = true;
490 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, 458 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
491 weak_factory_.GetWeakPtr())); 459 weak_factory_.GetWeakPtr()));
492 } 460 }
493 461
494 bool AudioRendererImpl::CanRead_Locked() { 462 bool AudioRendererImpl::CanRead_Locked() {
495 lock_.AssertAcquired(); 463 lock_.AssertAcquired();
496 464
497 switch (state_) { 465 switch (state_) {
498 case kUninitialized: 466 case kUninitialized:
499 case kInitializing: 467 case kInitializing:
500 case kFlushing: 468 case kFlushing:
501 case kFlushed: 469 case kFlushed:
502 case kStopped:
503 return false; 470 return false;
504 471
505 case kPlaying: 472 case kPlaying:
506 break; 473 break;
507 } 474 }
508 475
509 return !pending_read_ && !received_end_of_stream_ && 476 return !pending_read_ && !received_end_of_stream_ &&
510 !algorithm_->IsQueueFull(); 477 !algorithm_->IsQueueFull();
511 } 478 }
512 479
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 DoFlush_Locked(); 626 DoFlush_Locked();
660 return; 627 return;
661 } 628 }
662 629
663 error_cb_.Run(status); 630 error_cb_.Run(status);
664 base::ResetAndReturn(&flush_cb_).Run(); 631 base::ResetAndReturn(&flush_cb_).Run();
665 return; 632 return;
666 633
667 case kFlushed: 634 case kFlushed:
668 case kPlaying: 635 case kPlaying:
669 case kStopped:
670 if (status != PIPELINE_OK) 636 if (status != PIPELINE_OK)
671 error_cb_.Run(status); 637 error_cb_.Run(status);
672 return; 638 return;
673 } 639 }
674 } 640 }
675 641
676 void AudioRendererImpl::ChangeState_Locked(State new_state) { 642 void AudioRendererImpl::ChangeState_Locked(State new_state) {
677 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 643 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
678 lock_.AssertAcquired(); 644 lock_.AssertAcquired();
679 state_ = new_state; 645 state_ = new_state;
(...skipping 21 matching lines...) Expand all
701 << buffering_state; 667 << buffering_state;
702 DCHECK_NE(buffering_state_, buffering_state); 668 DCHECK_NE(buffering_state_, buffering_state);
703 lock_.AssertAcquired(); 669 lock_.AssertAcquired();
704 buffering_state_ = buffering_state; 670 buffering_state_ = buffering_state;
705 671
706 task_runner_->PostTask(FROM_HERE, 672 task_runner_->PostTask(FROM_HERE,
707 base::Bind(buffering_state_cb_, buffering_state_)); 673 base::Bind(buffering_state_cb_, buffering_state_));
708 } 674 }
709 675
710 } // namespace media 676 } // 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