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 27 matching lines...) Expand all Loading... |
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), | 46 weak_factory_(this), |
47 sink_(sink), | 47 sink_(sink), |
48 decoder_selector_(new AudioDecoderSelector( | 48 audio_buffer_stream_(task_runner, |
49 task_runner, decoders.Pass(), set_decryptor_ready_cb)), | 49 decoders.Pass(), |
| 50 set_decryptor_ready_cb), |
50 now_cb_(base::Bind(&base::TimeTicks::Now)), | 51 now_cb_(base::Bind(&base::TimeTicks::Now)), |
51 state_(kUninitialized), | 52 state_(kUninitialized), |
52 sink_playing_(false), | 53 sink_playing_(false), |
53 pending_read_(false), | 54 pending_read_(false), |
54 received_end_of_stream_(false), | 55 received_end_of_stream_(false), |
55 rendered_end_of_stream_(false), | 56 rendered_end_of_stream_(false), |
56 audio_time_buffered_(kNoTimestamp()), | 57 audio_time_buffered_(kNoTimestamp()), |
57 current_time_(kNoTimestamp()), | 58 current_time_(kNoTimestamp()), |
58 underflow_disabled_(false), | 59 underflow_disabled_(false), |
59 preroll_aborted_(false) { | 60 preroll_aborted_(false) {} |
60 } | |
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 if (decrypting_demuxer_stream_) { | 149 audio_buffer_stream_.Reset( |
150 decrypting_demuxer_stream_->Reset( | 150 base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)); |
151 base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_)); | |
152 return; | |
153 } | |
154 | |
155 ResetDecoder(); | |
156 } | |
157 | |
158 void AudioRendererImpl::ResetDecoder() { | |
159 DCHECK(task_runner_->BelongsToCurrentThread()); | |
160 decoder_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)); | |
161 } | 151 } |
162 | 152 |
163 void AudioRendererImpl::ResetDecoderDone() { | 153 void AudioRendererImpl::ResetDecoderDone() { |
164 DCHECK(task_runner_->BelongsToCurrentThread()); | 154 DCHECK(task_runner_->BelongsToCurrentThread()); |
165 { | 155 { |
166 base::AutoLock auto_lock(lock_); | 156 base::AutoLock auto_lock(lock_); |
167 if (state_ == kStopped) | 157 if (state_ == kStopped) |
168 return; | 158 return; |
169 | 159 |
170 DCHECK_EQ(state_, kPaused); | 160 DCHECK_EQ(state_, kPaused); |
171 DCHECK(!flush_cb_.is_null()); | 161 DCHECK(!flush_cb_.is_null()); |
172 | 162 |
173 audio_time_buffered_ = kNoTimestamp(); | 163 audio_time_buffered_ = kNoTimestamp(); |
174 current_time_ = kNoTimestamp(); | 164 current_time_ = kNoTimestamp(); |
175 received_end_of_stream_ = false; | 165 received_end_of_stream_ = false; |
176 rendered_end_of_stream_ = false; | 166 rendered_end_of_stream_ = false; |
177 preroll_aborted_ = false; | 167 preroll_aborted_ = false; |
178 | 168 |
179 earliest_end_time_ = now_cb_.Run(); | 169 earliest_end_time_ = now_cb_.Run(); |
180 splicer_->Reset(); | 170 splicer_->Reset(); |
181 algorithm_->FlushBuffers(); | 171 algorithm_->FlushBuffers(); |
182 } | 172 } |
183 base::ResetAndReturn(&flush_cb_).Run(); | 173 base::ResetAndReturn(&flush_cb_).Run(); |
184 } | 174 } |
185 | 175 |
186 void AudioRendererImpl::Stop(const base::Closure& callback) { | 176 void AudioRendererImpl::Stop(const base::Closure& callback) { |
187 DCHECK(task_runner_->BelongsToCurrentThread()); | 177 DCHECK(task_runner_->BelongsToCurrentThread()); |
188 DCHECK(!callback.is_null()); | 178 DCHECK(!callback.is_null()); |
189 DCHECK(stop_cb_.is_null()); | |
190 | |
191 stop_cb_ = callback; | |
192 | 179 |
193 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing | 180 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing |
194 // task-running guards that check |state_| with DCHECK(). | 181 // task-running guards that check |state_| with DCHECK(). |
195 | 182 |
196 { | 183 { |
197 base::AutoLock auto_lock(lock_); | 184 base::AutoLock auto_lock(lock_); |
198 if (state_ == kInitializing) { | 185 |
199 decoder_selector_->Abort(); | 186 if (state_ == kStopped) { |
| 187 task_runner_->PostTask(FROM_HERE, callback); |
200 return; | 188 return; |
201 } | 189 } |
202 | 190 |
203 if (state_ == kStopped) { | |
204 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); | |
205 return; | |
206 } | |
207 | |
208 ChangeState_Locked(kStopped); | 191 ChangeState_Locked(kStopped); |
209 algorithm_.reset(); | 192 algorithm_.reset(); |
210 underflow_cb_.Reset(); | 193 underflow_cb_.Reset(); |
211 time_cb_.Reset(); | 194 time_cb_.Reset(); |
212 flush_cb_.Reset(); | 195 flush_cb_.Reset(); |
213 } | 196 } |
214 | 197 |
215 if (sink_) { | 198 if (sink_) { |
216 sink_->Stop(); | 199 sink_->Stop(); |
217 sink_ = NULL; | 200 sink_ = NULL; |
218 } | 201 } |
219 | 202 |
220 if (decrypting_demuxer_stream_) { | 203 audio_buffer_stream_.Stop(callback); |
221 decrypting_demuxer_stream_->Stop( | |
222 base::Bind(&AudioRendererImpl::StopDecoder, weak_this_)); | |
223 return; | |
224 } | |
225 | |
226 StopDecoder(); | |
227 } | |
228 | |
229 void AudioRendererImpl::StopDecoder() { | |
230 DCHECK(task_runner_->BelongsToCurrentThread()); | |
231 DCHECK(!stop_cb_.is_null()); | |
232 | |
233 if (decoder_) { | |
234 decoder_->Stop(base::ResetAndReturn(&stop_cb_)); | |
235 return; | |
236 } | |
237 | |
238 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); | |
239 } | 204 } |
240 | 205 |
241 void AudioRendererImpl::Preroll(base::TimeDelta time, | 206 void AudioRendererImpl::Preroll(base::TimeDelta time, |
242 const PipelineStatusCB& cb) { | 207 const PipelineStatusCB& cb) { |
243 DCHECK(task_runner_->BelongsToCurrentThread()); | 208 DCHECK(task_runner_->BelongsToCurrentThread()); |
244 | 209 |
245 base::AutoLock auto_lock(lock_); | 210 base::AutoLock auto_lock(lock_); |
246 DCHECK(!sink_playing_); | 211 DCHECK(!sink_playing_); |
247 DCHECK_EQ(state_, kPaused); | 212 DCHECK_EQ(state_, kPaused); |
248 DCHECK(!pending_read_) << "Pending read must complete before seeking"; | 213 DCHECK(!pending_read_) << "Pending read must complete before seeking"; |
(...skipping 24 matching lines...) Expand all Loading... |
273 DCHECK(!ended_cb.is_null()); | 238 DCHECK(!ended_cb.is_null()); |
274 DCHECK(!disabled_cb.is_null()); | 239 DCHECK(!disabled_cb.is_null()); |
275 DCHECK(!error_cb.is_null()); | 240 DCHECK(!error_cb.is_null()); |
276 DCHECK_EQ(kUninitialized, state_); | 241 DCHECK_EQ(kUninitialized, state_); |
277 DCHECK(sink_); | 242 DCHECK(sink_); |
278 | 243 |
279 state_ = kInitializing; | 244 state_ = kInitializing; |
280 | 245 |
281 weak_this_ = weak_factory_.GetWeakPtr(); | 246 weak_this_ = weak_factory_.GetWeakPtr(); |
282 init_cb_ = init_cb; | 247 init_cb_ = init_cb; |
283 statistics_cb_ = statistics_cb; | |
284 underflow_cb_ = underflow_cb; | 248 underflow_cb_ = underflow_cb; |
285 time_cb_ = time_cb; | 249 time_cb_ = time_cb; |
286 ended_cb_ = ended_cb; | 250 ended_cb_ = ended_cb; |
287 disabled_cb_ = disabled_cb; | 251 disabled_cb_ = disabled_cb; |
288 error_cb_ = error_cb; | 252 error_cb_ = error_cb; |
289 | 253 |
290 decoder_selector_->SelectDecoder( | 254 audio_buffer_stream_.Initialize( |
291 stream, | 255 stream, |
292 statistics_cb, | 256 statistics_cb, |
293 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); | 257 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
| 258 weak_this_)); |
294 } | 259 } |
295 | 260 |
296 void AudioRendererImpl::OnDecoderSelected( | 261 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { |
297 scoped_ptr<AudioDecoder> decoder, | |
298 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | |
299 DCHECK(task_runner_->BelongsToCurrentThread()); | 262 DCHECK(task_runner_->BelongsToCurrentThread()); |
300 | 263 |
301 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); | 264 base::AutoLock auto_lock(lock_); |
302 decoder_ = decoder.Pass(); | |
303 | 265 |
304 if (!decoder_ || !stop_cb_.is_null()) { | 266 if (state_ == kStopped) { |
305 { | 267 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
306 base::AutoLock auto_lock(lock_); | |
307 ChangeState_Locked(kUninitialized); | |
308 } | |
309 // Stop() called during initialization. | |
310 if (!stop_cb_.is_null()) { | |
311 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | |
312 Stop(base::ResetAndReturn(&stop_cb_)); | |
313 } else { | |
314 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | |
315 } | |
316 return; | 268 return; |
317 } | 269 } |
318 | 270 |
319 base::AutoLock auto_lock(lock_); | 271 if (!success) { |
320 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); | 272 state_ = kUninitialized; |
| 273 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 274 return; |
| 275 } |
321 | 276 |
322 int sample_rate = decoder_->samples_per_second(); | 277 int sample_rate = audio_buffer_stream_.decoder()->samples_per_second(); |
323 | 278 |
324 // The actual buffer size is controlled via the size of the AudioBus | 279 // The actual buffer size is controlled via the size of the AudioBus |
325 // provided to Render(), so just choose something reasonable here for looks. | 280 // provided to Render(), so just choose something reasonable here for looks. |
326 int buffer_size = decoder_->samples_per_second() / 100; | 281 int buffer_size = audio_buffer_stream_.decoder()->samples_per_second() / 100; |
327 audio_parameters_ = AudioParameters( | 282 |
328 AudioParameters::AUDIO_PCM_LOW_LATENCY, decoder_->channel_layout(), | 283 // TODO(rileya): Remove the channel_layout/bits_per_channel/samples_per_second |
329 sample_rate, decoder_->bits_per_channel(), buffer_size); | 284 // getters from AudioDecoder, and adjust this accordingly. |
| 285 audio_parameters_ = |
| 286 AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 287 audio_buffer_stream_.decoder()->channel_layout(), |
| 288 sample_rate, |
| 289 audio_buffer_stream_.decoder()->bits_per_channel(), |
| 290 buffer_size); |
330 if (!audio_parameters_.IsValid()) { | 291 if (!audio_parameters_.IsValid()) { |
331 ChangeState_Locked(kUninitialized); | 292 ChangeState_Locked(kUninitialized); |
332 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 293 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
333 return; | 294 return; |
334 } | 295 } |
335 | 296 |
336 splicer_.reset(new AudioSplicer(sample_rate)); | 297 splicer_.reset(new AudioSplicer(sample_rate)); |
337 | 298 |
338 // We're all good! Continue initializing the rest of the audio renderer | 299 // We're all good! Continue initializing the rest of the audio renderer |
339 // based on the decoder format. | 300 // based on the decoder format. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 } | 336 } |
376 } | 337 } |
377 | 338 |
378 void AudioRendererImpl::SetVolume(float volume) { | 339 void AudioRendererImpl::SetVolume(float volume) { |
379 DCHECK(task_runner_->BelongsToCurrentThread()); | 340 DCHECK(task_runner_->BelongsToCurrentThread()); |
380 DCHECK(sink_); | 341 DCHECK(sink_); |
381 sink_->SetVolume(volume); | 342 sink_->SetVolume(volume); |
382 } | 343 } |
383 | 344 |
384 void AudioRendererImpl::DecodedAudioReady( | 345 void AudioRendererImpl::DecodedAudioReady( |
385 AudioDecoder::Status status, | 346 AudioBufferStream::Status status, |
386 const scoped_refptr<AudioBuffer>& buffer) { | 347 const scoped_refptr<AudioBuffer>& buffer) { |
387 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; | 348 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; |
388 DCHECK(task_runner_->BelongsToCurrentThread()); | 349 DCHECK(task_runner_->BelongsToCurrentThread()); |
389 | 350 |
390 base::AutoLock auto_lock(lock_); | 351 base::AutoLock auto_lock(lock_); |
391 DCHECK(state_ != kUninitialized); | 352 DCHECK(state_ != kUninitialized); |
392 | 353 |
393 CHECK(pending_read_); | 354 CHECK(pending_read_); |
394 pending_read_ = false; | 355 pending_read_ = false; |
395 | 356 |
396 if (status == AudioDecoder::kAborted) { | 357 if (status == AudioBufferStream::ABORTED || |
| 358 status == AudioBufferStream::DEMUXER_READ_ABORTED) { |
397 HandleAbortedReadOrDecodeError(false); | 359 HandleAbortedReadOrDecodeError(false); |
398 return; | 360 return; |
399 } | 361 } |
400 | 362 |
401 if (status == AudioDecoder::kDecodeError) { | 363 if (status == AudioBufferStream::DECODE_ERROR) { |
402 HandleAbortedReadOrDecodeError(true); | 364 HandleAbortedReadOrDecodeError(true); |
403 return; | 365 return; |
404 } | 366 } |
405 | 367 |
406 DCHECK_EQ(status, AudioDecoder::kOk); | 368 DCHECK_EQ(status, AudioBufferStream::OK); |
407 DCHECK(buffer.get()); | 369 DCHECK(buffer.get()); |
408 | 370 |
409 if (state_ == kFlushing) { | 371 if (state_ == kFlushing) { |
410 ChangeState_Locked(kPaused); | 372 ChangeState_Locked(kPaused); |
411 DoFlush_Locked(); | 373 DoFlush_Locked(); |
412 return; | 374 return; |
413 } | 375 } |
414 | 376 |
415 if (!splicer_->AddInput(buffer)) { | 377 if (!splicer_->AddInput(buffer)) { |
416 HandleAbortedReadOrDecodeError(true); | 378 HandleAbortedReadOrDecodeError(true); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 } | 465 } |
504 | 466 |
505 void AudioRendererImpl::AttemptRead_Locked() { | 467 void AudioRendererImpl::AttemptRead_Locked() { |
506 DCHECK(task_runner_->BelongsToCurrentThread()); | 468 DCHECK(task_runner_->BelongsToCurrentThread()); |
507 lock_.AssertAcquired(); | 469 lock_.AssertAcquired(); |
508 | 470 |
509 if (!CanRead_Locked()) | 471 if (!CanRead_Locked()) |
510 return; | 472 return; |
511 | 473 |
512 pending_read_ = true; | 474 pending_read_ = true; |
513 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); | 475 audio_buffer_stream_.Read( |
| 476 base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); |
514 } | 477 } |
515 | 478 |
516 bool AudioRendererImpl::CanRead_Locked() { | 479 bool AudioRendererImpl::CanRead_Locked() { |
517 lock_.AssertAcquired(); | 480 lock_.AssertAcquired(); |
518 | 481 |
519 switch (state_) { | 482 switch (state_) { |
520 case kUninitialized: | 483 case kUninitialized: |
521 case kInitializing: | 484 case kInitializing: |
522 case kPaused: | 485 case kPaused: |
523 case kFlushing: | 486 case kFlushing: |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 } | 705 } |
743 } | 706 } |
744 | 707 |
745 void AudioRendererImpl::ChangeState_Locked(State new_state) { | 708 void AudioRendererImpl::ChangeState_Locked(State new_state) { |
746 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; | 709 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; |
747 lock_.AssertAcquired(); | 710 lock_.AssertAcquired(); |
748 state_ = new_state; | 711 state_ = new_state; |
749 } | 712 } |
750 | 713 |
751 } // namespace media | 714 } // namespace media |
OLD | NEW |