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