OLD | NEW |
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 25 matching lines...) Expand all Loading... |
36 } | 36 } |
37 | 37 |
38 } // namespace | 38 } // namespace |
39 | 39 |
40 AudioRendererImpl::AudioRendererImpl( | 40 AudioRendererImpl::AudioRendererImpl( |
41 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 41 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
42 media::AudioRendererSink* sink, | 42 media::AudioRendererSink* sink, |
43 ScopedVector<AudioDecoder> decoders, | 43 ScopedVector<AudioDecoder> decoders, |
44 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 44 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
45 : task_runner_(task_runner), | 45 : task_runner_(task_runner), |
46 weak_factory_(this), | |
47 sink_(sink), | 46 sink_(sink), |
48 audio_buffer_stream_(task_runner, | 47 audio_buffer_stream_(task_runner, |
49 decoders.Pass(), | 48 decoders.Pass(), |
50 set_decryptor_ready_cb), | 49 set_decryptor_ready_cb), |
51 now_cb_(base::Bind(&base::TimeTicks::Now)), | 50 now_cb_(base::Bind(&base::TimeTicks::Now)), |
52 state_(kUninitialized), | 51 state_(kUninitialized), |
53 sink_playing_(false), | 52 sink_playing_(false), |
54 pending_read_(false), | 53 pending_read_(false), |
55 received_end_of_stream_(false), | 54 received_end_of_stream_(false), |
56 rendered_end_of_stream_(false), | 55 rendered_end_of_stream_(false), |
57 audio_time_buffered_(kNoTimestamp()), | 56 audio_time_buffered_(kNoTimestamp()), |
58 current_time_(kNoTimestamp()), | 57 current_time_(kNoTimestamp()), |
59 underflow_disabled_(false), | 58 underflow_disabled_(false), |
60 preroll_aborted_(false) {} | 59 preroll_aborted_(false), |
| 60 weak_factory_(this) {} |
61 | 61 |
62 AudioRendererImpl::~AudioRendererImpl() { | 62 AudioRendererImpl::~AudioRendererImpl() { |
63 // Stop() should have been called and |algorithm_| should have been destroyed. | 63 // Stop() should have been called and |algorithm_| should have been destroyed. |
64 DCHECK(state_ == kUninitialized || state_ == kStopped); | 64 DCHECK(state_ == kUninitialized || state_ == kStopped); |
65 DCHECK(!algorithm_.get()); | 65 DCHECK(!algorithm_.get()); |
66 } | 66 } |
67 | 67 |
68 void AudioRendererImpl::Play(const base::Closure& callback) { | 68 void AudioRendererImpl::Play(const base::Closure& callback) { |
69 DCHECK(task_runner_->BelongsToCurrentThread()); | 69 DCHECK(task_runner_->BelongsToCurrentThread()); |
70 | 70 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 DoFlush_Locked(); | 139 DoFlush_Locked(); |
140 } | 140 } |
141 | 141 |
142 void AudioRendererImpl::DoFlush_Locked() { | 142 void AudioRendererImpl::DoFlush_Locked() { |
143 DCHECK(task_runner_->BelongsToCurrentThread()); | 143 DCHECK(task_runner_->BelongsToCurrentThread()); |
144 lock_.AssertAcquired(); | 144 lock_.AssertAcquired(); |
145 | 145 |
146 DCHECK(!pending_read_); | 146 DCHECK(!pending_read_); |
147 DCHECK_EQ(state_, kPaused); | 147 DCHECK_EQ(state_, kPaused); |
148 | 148 |
149 audio_buffer_stream_.Reset( | 149 audio_buffer_stream_.Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, |
150 base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)); | 150 weak_factory_.GetWeakPtr())); |
151 } | 151 } |
152 | 152 |
153 void AudioRendererImpl::ResetDecoderDone() { | 153 void AudioRendererImpl::ResetDecoderDone() { |
154 DCHECK(task_runner_->BelongsToCurrentThread()); | 154 DCHECK(task_runner_->BelongsToCurrentThread()); |
155 { | 155 { |
156 base::AutoLock auto_lock(lock_); | 156 base::AutoLock auto_lock(lock_); |
157 if (state_ == kStopped) | 157 if (state_ == kStopped) |
158 return; | 158 return; |
159 | 159 |
160 DCHECK_EQ(state_, kPaused); | 160 DCHECK_EQ(state_, kPaused); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 DCHECK(!underflow_cb.is_null()); | 236 DCHECK(!underflow_cb.is_null()); |
237 DCHECK(!time_cb.is_null()); | 237 DCHECK(!time_cb.is_null()); |
238 DCHECK(!ended_cb.is_null()); | 238 DCHECK(!ended_cb.is_null()); |
239 DCHECK(!disabled_cb.is_null()); | 239 DCHECK(!disabled_cb.is_null()); |
240 DCHECK(!error_cb.is_null()); | 240 DCHECK(!error_cb.is_null()); |
241 DCHECK_EQ(kUninitialized, state_); | 241 DCHECK_EQ(kUninitialized, state_); |
242 DCHECK(sink_); | 242 DCHECK(sink_); |
243 | 243 |
244 state_ = kInitializing; | 244 state_ = kInitializing; |
245 | 245 |
246 weak_this_ = weak_factory_.GetWeakPtr(); | |
247 init_cb_ = init_cb; | 246 init_cb_ = init_cb; |
248 underflow_cb_ = underflow_cb; | 247 underflow_cb_ = underflow_cb; |
249 time_cb_ = time_cb; | 248 time_cb_ = time_cb; |
250 ended_cb_ = ended_cb; | 249 ended_cb_ = ended_cb; |
251 disabled_cb_ = disabled_cb; | 250 disabled_cb_ = disabled_cb; |
252 error_cb_ = error_cb; | 251 error_cb_ = error_cb; |
253 | 252 |
254 audio_buffer_stream_.Initialize( | 253 audio_buffer_stream_.Initialize( |
255 stream, | 254 stream, |
256 statistics_cb, | 255 statistics_cb, |
257 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 256 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
258 weak_this_)); | 257 weak_factory_.GetWeakPtr())); |
259 } | 258 } |
260 | 259 |
261 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { | 260 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { |
262 DCHECK(task_runner_->BelongsToCurrentThread()); | 261 DCHECK(task_runner_->BelongsToCurrentThread()); |
263 | 262 |
264 base::AutoLock auto_lock(lock_); | 263 base::AutoLock auto_lock(lock_); |
265 | 264 |
266 if (state_ == kStopped) { | 265 if (state_ == kStopped) { |
267 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | 266 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
268 return; | 267 return; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 // based on the decoder format. | 299 // based on the decoder format. |
301 algorithm_.reset(new AudioRendererAlgorithm()); | 300 algorithm_.reset(new AudioRendererAlgorithm()); |
302 algorithm_->Initialize(0, audio_parameters_); | 301 algorithm_->Initialize(0, audio_parameters_); |
303 | 302 |
304 ChangeState_Locked(kPaused); | 303 ChangeState_Locked(kPaused); |
305 | 304 |
306 HistogramRendererEvent(INITIALIZED); | 305 HistogramRendererEvent(INITIALIZED); |
307 | 306 |
308 { | 307 { |
309 base::AutoUnlock auto_unlock(lock_); | 308 base::AutoUnlock auto_unlock(lock_); |
310 sink_->Initialize(audio_parameters_, weak_this_.get()); | 309 sink_->Initialize(audio_parameters_, this); |
311 sink_->Start(); | 310 sink_->Start(); |
312 | 311 |
313 // Some sinks play on start... | 312 // Some sinks play on start... |
314 sink_->Pause(); | 313 sink_->Pause(); |
315 } | 314 } |
316 | 315 |
317 DCHECK(!sink_playing_); | 316 DCHECK(!sink_playing_); |
318 | 317 |
319 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 318 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
320 } | 319 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 } | 464 } |
466 | 465 |
467 void AudioRendererImpl::AttemptRead_Locked() { | 466 void AudioRendererImpl::AttemptRead_Locked() { |
468 DCHECK(task_runner_->BelongsToCurrentThread()); | 467 DCHECK(task_runner_->BelongsToCurrentThread()); |
469 lock_.AssertAcquired(); | 468 lock_.AssertAcquired(); |
470 | 469 |
471 if (!CanRead_Locked()) | 470 if (!CanRead_Locked()) |
472 return; | 471 return; |
473 | 472 |
474 pending_read_ = true; | 473 pending_read_ = true; |
475 audio_buffer_stream_.Read( | 474 audio_buffer_stream_.Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, |
476 base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); | 475 weak_factory_.GetWeakPtr())); |
477 } | 476 } |
478 | 477 |
479 bool AudioRendererImpl::CanRead_Locked() { | 478 bool AudioRendererImpl::CanRead_Locked() { |
480 lock_.AssertAcquired(); | 479 lock_.AssertAcquired(); |
481 | 480 |
482 switch (state_) { | 481 switch (state_) { |
483 case kUninitialized: | 482 case kUninitialized: |
484 case kInitializing: | 483 case kInitializing: |
485 case kPaused: | 484 case kPaused: |
486 case kFlushing: | 485 case kFlushing: |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 ChangeState_Locked(kUnderflow); | 577 ChangeState_Locked(kUnderflow); |
579 underflow_cb = underflow_cb_; | 578 underflow_cb = underflow_cb_; |
580 } else { | 579 } else { |
581 // We can't write any data this cycle. For example, we may have | 580 // We can't write any data this cycle. For example, we may have |
582 // sent all available data to the audio device while not reaching | 581 // sent all available data to the audio device while not reaching |
583 // |earliest_end_time_|. | 582 // |earliest_end_time_|. |
584 } | 583 } |
585 } | 584 } |
586 | 585 |
587 if (CanRead_Locked()) { | 586 if (CanRead_Locked()) { |
588 task_runner_->PostTask(FROM_HERE, base::Bind( | 587 task_runner_->PostTask(FROM_HERE, |
589 &AudioRendererImpl::AttemptRead, weak_this_)); | 588 base::Bind(&AudioRendererImpl::AttemptRead, |
| 589 weak_factory_.GetWeakPtr())); |
590 } | 590 } |
591 | 591 |
592 // The |audio_time_buffered_| is the ending timestamp of the last frame | 592 // The |audio_time_buffered_| is the ending timestamp of the last frame |
593 // buffered at the audio device. |playback_delay| is the amount of time | 593 // buffered at the audio device. |playback_delay| is the amount of time |
594 // buffered at the audio device. The current time can be computed by their | 594 // buffered at the audio device. The current time can be computed by their |
595 // difference. | 595 // difference. |
596 if (audio_time_buffered_ != kNoTimestamp()) { | 596 if (audio_time_buffered_ != kNoTimestamp()) { |
597 // Adjust the delay according to playback rate. | 597 // Adjust the delay according to playback rate. |
598 base::TimeDelta adjusted_playback_delay = | 598 base::TimeDelta adjusted_playback_delay = |
599 base::TimeDelta::FromMicroseconds(ceil( | 599 base::TimeDelta::FromMicroseconds(ceil( |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 } | 705 } |
706 } | 706 } |
707 | 707 |
708 void AudioRendererImpl::ChangeState_Locked(State new_state) { | 708 void AudioRendererImpl::ChangeState_Locked(State new_state) { |
709 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; | 709 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; |
710 lock_.AssertAcquired(); | 710 lock_.AssertAcquired(); |
711 state_ = new_state; | 711 state_ = new_state; |
712 } | 712 } |
713 | 713 |
714 } // namespace media | 714 } // namespace media |
OLD | NEW |