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 26 matching lines...) Expand all Loading... | |
37 } // namespace | 37 } // namespace |
38 | 38 |
39 AudioRendererImpl::AudioRendererImpl( | 39 AudioRendererImpl::AudioRendererImpl( |
40 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 40 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
41 media::AudioRendererSink* sink, | 41 media::AudioRendererSink* sink, |
42 ScopedVector<AudioDecoder> decoders, | 42 ScopedVector<AudioDecoder> decoders, |
43 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 43 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
44 : task_runner_(task_runner), | 44 : task_runner_(task_runner), |
45 weak_factory_(this), | 45 weak_factory_(this), |
46 sink_(sink), | 46 sink_(sink), |
47 decoder_selector_(new AudioDecoderSelector( | 47 audio_buffer_stream_(task_runner, |
48 task_runner, decoders.Pass(), set_decryptor_ready_cb)), | 48 decoders.Pass(), |
49 set_decryptor_ready_cb), | |
49 now_cb_(base::Bind(&base::TimeTicks::Now)), | 50 now_cb_(base::Bind(&base::TimeTicks::Now)), |
50 state_(kUninitialized), | 51 state_(kUninitialized), |
51 sink_playing_(false), | 52 sink_playing_(false), |
52 pending_read_(false), | 53 pending_read_(false), |
53 received_end_of_stream_(false), | 54 received_end_of_stream_(false), |
54 rendered_end_of_stream_(false), | 55 rendered_end_of_stream_(false), |
55 audio_time_buffered_(kNoTimestamp()), | 56 audio_time_buffered_(kNoTimestamp()), |
56 current_time_(kNoTimestamp()), | 57 current_time_(kNoTimestamp()), |
57 underflow_disabled_(false), | 58 underflow_disabled_(false), |
58 preroll_aborted_(false) { | 59 preroll_aborted_(false) {} |
59 } | |
60 | 60 |
61 AudioRendererImpl::~AudioRendererImpl() { | 61 AudioRendererImpl::~AudioRendererImpl() { |
62 base::AutoLock auto_lock(lock_); | |
DaleCurtis
2014/02/21 21:48:48
What's this for? To ensure outstanding calls have
rileya (GONE FROM CHROMIUM)
2014/02/21 23:04:02
Yeah, I added this because of VRI doing it, I wasn
xhwang
2014/02/21 23:57:56
Yeah, this shouldn't be necessary unless someone i
rileya (GONE FROM CHROMIUM)
2014/02/24 21:04:11
Alright, removed it. The one in VRI should probabl
| |
62 // Stop() should have been called and |algorithm_| should have been destroyed. | 63 // Stop() should have been called and |algorithm_| should have been destroyed. |
63 DCHECK(state_ == kUninitialized || state_ == kStopped); | 64 DCHECK(state_ == kUninitialized || state_ == kStopped); |
64 DCHECK(!algorithm_.get()); | 65 DCHECK(!algorithm_.get()); |
65 } | 66 } |
66 | 67 |
67 void AudioRendererImpl::Play(const base::Closure& callback) { | 68 void AudioRendererImpl::Play(const base::Closure& callback) { |
68 DCHECK(task_runner_->BelongsToCurrentThread()); | 69 DCHECK(task_runner_->BelongsToCurrentThread()); |
69 | 70 |
70 base::AutoLock auto_lock(lock_); | 71 base::AutoLock auto_lock(lock_); |
71 DCHECK_EQ(state_, kPaused); | 72 DCHECK_EQ(state_, kPaused); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 DoFlush_Locked(); | 139 DoFlush_Locked(); |
139 } | 140 } |
140 | 141 |
141 void AudioRendererImpl::DoFlush_Locked() { | 142 void AudioRendererImpl::DoFlush_Locked() { |
142 DCHECK(task_runner_->BelongsToCurrentThread()); | 143 DCHECK(task_runner_->BelongsToCurrentThread()); |
143 lock_.AssertAcquired(); | 144 lock_.AssertAcquired(); |
144 | 145 |
145 DCHECK(!pending_read_); | 146 DCHECK(!pending_read_); |
146 DCHECK_EQ(state_, kPaused); | 147 DCHECK_EQ(state_, kPaused); |
147 | 148 |
148 if (decrypting_demuxer_stream_) { | 149 audio_buffer_stream_.Reset( |
149 decrypting_demuxer_stream_->Reset( | 150 base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)); |
150 base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_)); | |
151 return; | |
152 } | |
153 | |
154 ResetDecoder(); | |
155 } | |
156 | |
157 void AudioRendererImpl::ResetDecoder() { | |
158 DCHECK(task_runner_->BelongsToCurrentThread()); | |
159 decoder_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)); | |
160 } | 151 } |
161 | 152 |
162 void AudioRendererImpl::ResetDecoderDone() { | 153 void AudioRendererImpl::ResetDecoderDone() { |
163 DCHECK(task_runner_->BelongsToCurrentThread()); | 154 DCHECK(task_runner_->BelongsToCurrentThread()); |
164 { | 155 { |
165 base::AutoLock auto_lock(lock_); | 156 base::AutoLock auto_lock(lock_); |
166 if (state_ == kStopped) | 157 if (state_ == kStopped) |
167 return; | 158 return; |
168 | 159 |
169 DCHECK_EQ(state_, kPaused); | 160 DCHECK_EQ(state_, kPaused); |
(...skipping 17 matching lines...) Expand all Loading... | |
187 DCHECK(!callback.is_null()); | 178 DCHECK(!callback.is_null()); |
188 DCHECK(stop_cb_.is_null()); | 179 DCHECK(stop_cb_.is_null()); |
189 | 180 |
190 stop_cb_ = callback; | 181 stop_cb_ = callback; |
191 | 182 |
192 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing | 183 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing |
193 // task-running guards that check |state_| with DCHECK(). | 184 // task-running guards that check |state_| with DCHECK(). |
194 | 185 |
195 { | 186 { |
196 base::AutoLock auto_lock(lock_); | 187 base::AutoLock auto_lock(lock_); |
197 if (state_ == kInitializing) { | |
198 decoder_selector_->Abort(); | |
199 return; | |
200 } | |
201 | 188 |
202 if (state_ == kStopped) { | 189 if (state_ == kStopped) { |
203 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); | 190 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); |
204 return; | 191 return; |
205 } | 192 } |
206 | 193 |
207 ChangeState_Locked(kStopped); | 194 ChangeState_Locked(kStopped); |
208 algorithm_.reset(); | 195 algorithm_.reset(); |
209 underflow_cb_.Reset(); | 196 underflow_cb_.Reset(); |
210 time_cb_.Reset(); | 197 time_cb_.Reset(); |
211 flush_cb_.Reset(); | 198 flush_cb_.Reset(); |
212 } | 199 } |
213 | 200 |
214 if (sink_) { | 201 if (sink_) { |
215 sink_->Stop(); | 202 sink_->Stop(); |
216 sink_ = NULL; | 203 sink_ = NULL; |
217 } | 204 } |
218 | 205 |
219 if (decoder_) { | 206 audio_buffer_stream_.Stop(base::ResetAndReturn(&stop_cb_)); |
220 decoder_->Stop(base::ResetAndReturn(&stop_cb_)); | |
221 return; | |
222 } | |
223 | |
224 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); | |
225 } | 207 } |
226 | 208 |
227 void AudioRendererImpl::Preroll(base::TimeDelta time, | 209 void AudioRendererImpl::Preroll(base::TimeDelta time, |
228 const PipelineStatusCB& cb) { | 210 const PipelineStatusCB& cb) { |
229 DCHECK(task_runner_->BelongsToCurrentThread()); | 211 DCHECK(task_runner_->BelongsToCurrentThread()); |
230 | 212 |
231 base::AutoLock auto_lock(lock_); | 213 base::AutoLock auto_lock(lock_); |
232 DCHECK(!sink_playing_); | 214 DCHECK(!sink_playing_); |
233 DCHECK_EQ(state_, kPaused); | 215 DCHECK_EQ(state_, kPaused); |
234 DCHECK(!pending_read_) << "Pending read must complete before seeking"; | 216 DCHECK(!pending_read_) << "Pending read must complete before seeking"; |
(...skipping 24 matching lines...) Expand all Loading... | |
259 DCHECK(!ended_cb.is_null()); | 241 DCHECK(!ended_cb.is_null()); |
260 DCHECK(!disabled_cb.is_null()); | 242 DCHECK(!disabled_cb.is_null()); |
261 DCHECK(!error_cb.is_null()); | 243 DCHECK(!error_cb.is_null()); |
262 DCHECK_EQ(kUninitialized, state_); | 244 DCHECK_EQ(kUninitialized, state_); |
263 DCHECK(sink_); | 245 DCHECK(sink_); |
264 | 246 |
265 state_ = kInitializing; | 247 state_ = kInitializing; |
266 | 248 |
267 weak_this_ = weak_factory_.GetWeakPtr(); | 249 weak_this_ = weak_factory_.GetWeakPtr(); |
268 init_cb_ = init_cb; | 250 init_cb_ = init_cb; |
269 statistics_cb_ = statistics_cb; | |
270 underflow_cb_ = underflow_cb; | 251 underflow_cb_ = underflow_cb; |
271 time_cb_ = time_cb; | 252 time_cb_ = time_cb; |
272 ended_cb_ = ended_cb; | 253 ended_cb_ = ended_cb; |
273 disabled_cb_ = disabled_cb; | 254 disabled_cb_ = disabled_cb; |
274 error_cb_ = error_cb; | 255 error_cb_ = error_cb; |
275 | 256 |
276 decoder_selector_->SelectDecoder( | 257 audio_buffer_stream_.Initialize( |
277 stream, | 258 stream, |
278 statistics_cb, | 259 statistics_cb, |
279 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); | 260 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
261 weak_this_)); | |
280 } | 262 } |
281 | 263 |
282 void AudioRendererImpl::OnDecoderSelected( | 264 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { |
283 scoped_ptr<AudioDecoder> decoder, | |
284 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | |
285 DCHECK(task_runner_->BelongsToCurrentThread()); | 265 DCHECK(task_runner_->BelongsToCurrentThread()); |
286 | 266 |
287 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); | |
288 | 267 |
289 if (!decoder) { | 268 base::AutoLock auto_lock(lock_); |
290 { | 269 |
291 base::AutoLock auto_lock(lock_); | 270 if (!success) { |
292 ChangeState_Locked(kUninitialized); | 271 state_ = kUninitialized; |
293 } | 272 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
294 // Stop() called during initialization. | |
295 if (!stop_cb_.is_null()) { | |
296 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | |
297 Stop(base::ResetAndReturn(&stop_cb_)); | |
298 } else { | |
299 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | |
300 } | |
301 return; | 273 return; |
302 } | 274 } |
303 | 275 |
304 base::AutoLock auto_lock(lock_); | 276 int sample_rate = audio_buffer_stream_.decoder()->samples_per_second(); |
305 decoder_ = decoder.Pass(); | |
306 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); | |
307 | |
308 int sample_rate = decoder_->samples_per_second(); | |
309 | 277 |
310 // The actual buffer size is controlled via the size of the AudioBus | 278 // The actual buffer size is controlled via the size of the AudioBus |
311 // provided to Render(), so just choose something reasonable here for looks. | 279 // provided to Render(), so just choose something reasonable here for looks. |
312 int buffer_size = decoder_->samples_per_second() / 100; | 280 int buffer_size = audio_buffer_stream_.decoder()->samples_per_second() / 100; |
313 audio_parameters_ = AudioParameters( | 281 |
314 AudioParameters::AUDIO_PCM_LOW_LATENCY, decoder_->channel_layout(), | 282 // TODO(rileya): Remove the channel_layout/bits_per_channel/samples_per_second |
315 sample_rate, decoder_->bits_per_channel(), buffer_size); | 283 // getters from AudioDecoder, and adjust this accordingly. |
rileya (GONE FROM CHROMIUM)
2014/02/19 22:37:51
This will require some plumbing that's beyond the
DaleCurtis
2014/02/21 21:48:48
My plan was for ARI and ARA to be agnostic to conf
| |
284 audio_parameters_ = | |
285 AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, | |
286 audio_buffer_stream_.decoder()->channel_layout(), | |
287 sample_rate, | |
288 audio_buffer_stream_.decoder()->bits_per_channel(), | |
289 buffer_size); | |
316 if (!audio_parameters_.IsValid()) { | 290 if (!audio_parameters_.IsValid()) { |
317 ChangeState_Locked(kUninitialized); | 291 ChangeState_Locked(kUninitialized); |
318 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 292 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
319 return; | 293 return; |
320 } | 294 } |
321 | 295 |
322 splicer_.reset(new AudioSplicer(sample_rate)); | 296 splicer_.reset(new AudioSplicer(sample_rate)); |
323 | 297 |
324 // We're all good! Continue initializing the rest of the audio renderer | 298 // We're all good! Continue initializing the rest of the audio renderer |
325 // based on the decoder format. | 299 // based on the decoder format. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 } | 335 } |
362 } | 336 } |
363 | 337 |
364 void AudioRendererImpl::SetVolume(float volume) { | 338 void AudioRendererImpl::SetVolume(float volume) { |
365 DCHECK(task_runner_->BelongsToCurrentThread()); | 339 DCHECK(task_runner_->BelongsToCurrentThread()); |
366 DCHECK(sink_); | 340 DCHECK(sink_); |
367 sink_->SetVolume(volume); | 341 sink_->SetVolume(volume); |
368 } | 342 } |
369 | 343 |
370 void AudioRendererImpl::DecodedAudioReady( | 344 void AudioRendererImpl::DecodedAudioReady( |
371 AudioDecoder::Status status, | 345 AudioBufferStream::Status status, |
372 const scoped_refptr<AudioBuffer>& buffer) { | 346 const scoped_refptr<AudioBuffer>& buffer) { |
373 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; | 347 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; |
374 DCHECK(task_runner_->BelongsToCurrentThread()); | 348 DCHECK(task_runner_->BelongsToCurrentThread()); |
375 | 349 |
376 base::AutoLock auto_lock(lock_); | 350 base::AutoLock auto_lock(lock_); |
377 DCHECK(state_ != kUninitialized); | 351 DCHECK(state_ != kUninitialized); |
378 | 352 |
379 CHECK(pending_read_); | 353 CHECK(pending_read_); |
380 pending_read_ = false; | 354 pending_read_ = false; |
381 | 355 |
382 if (status == AudioDecoder::kAborted) { | 356 if (status == AudioBufferStream::ABORTED || |
357 status == AudioBufferStream::DEMUXER_READ_ABORTED) { | |
383 HandleAbortedReadOrDecodeError(false); | 358 HandleAbortedReadOrDecodeError(false); |
384 return; | 359 return; |
385 } | 360 } |
386 | 361 |
387 if (status == AudioDecoder::kDecodeError) { | 362 if (status == AudioBufferStream::DECODE_ERROR) { |
388 HandleAbortedReadOrDecodeError(true); | 363 HandleAbortedReadOrDecodeError(true); |
389 return; | 364 return; |
390 } | 365 } |
391 | 366 |
392 DCHECK_EQ(status, AudioDecoder::kOk); | 367 DCHECK_EQ(status, AudioBufferStream::OK); |
393 DCHECK(buffer.get()); | 368 DCHECK(buffer.get()); |
394 | 369 |
395 if (state_ == kFlushing) { | 370 if (state_ == kFlushing) { |
396 ChangeState_Locked(kPaused); | 371 ChangeState_Locked(kPaused); |
397 DoFlush_Locked(); | 372 DoFlush_Locked(); |
398 return; | 373 return; |
399 } | 374 } |
400 | 375 |
401 if (!splicer_->AddInput(buffer)) { | 376 if (!splicer_->AddInput(buffer)) { |
402 HandleAbortedReadOrDecodeError(true); | 377 HandleAbortedReadOrDecodeError(true); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 } | 464 } |
490 | 465 |
491 void AudioRendererImpl::AttemptRead_Locked() { | 466 void AudioRendererImpl::AttemptRead_Locked() { |
492 DCHECK(task_runner_->BelongsToCurrentThread()); | 467 DCHECK(task_runner_->BelongsToCurrentThread()); |
493 lock_.AssertAcquired(); | 468 lock_.AssertAcquired(); |
494 | 469 |
495 if (!CanRead_Locked()) | 470 if (!CanRead_Locked()) |
496 return; | 471 return; |
497 | 472 |
498 pending_read_ = true; | 473 pending_read_ = true; |
499 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); | 474 audio_buffer_stream_.Read( |
475 base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); | |
500 } | 476 } |
501 | 477 |
502 bool AudioRendererImpl::CanRead_Locked() { | 478 bool AudioRendererImpl::CanRead_Locked() { |
503 lock_.AssertAcquired(); | 479 lock_.AssertAcquired(); |
504 | 480 |
505 switch (state_) { | 481 switch (state_) { |
506 case kUninitialized: | 482 case kUninitialized: |
507 case kInitializing: | 483 case kInitializing: |
508 case kPaused: | 484 case kPaused: |
509 case kFlushing: | 485 case kFlushing: |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
728 } | 704 } |
729 } | 705 } |
730 | 706 |
731 void AudioRendererImpl::ChangeState_Locked(State new_state) { | 707 void AudioRendererImpl::ChangeState_Locked(State new_state) { |
732 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; | 708 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; |
733 lock_.AssertAcquired(); | 709 lock_.AssertAcquired(); |
734 state_ = new_state; | 710 state_ = new_state; |
735 } | 711 } |
736 | 712 |
737 } // namespace media | 713 } // namespace media |
OLD | NEW |