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 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/message_loop_proxy.h" | 16 #include "base/message_loop_proxy.h" |
| 17 #include "base/metrics/histogram.h" |
17 #include "media/audio/audio_util.h" | 18 #include "media/audio/audio_util.h" |
18 #include "media/base/audio_splicer.h" | 19 #include "media/base/audio_splicer.h" |
19 #include "media/base/bind_to_loop.h" | 20 #include "media/base/bind_to_loop.h" |
20 #include "media/base/data_buffer.h" | 21 #include "media/base/data_buffer.h" |
21 #include "media/base/demuxer_stream.h" | 22 #include "media/base/demuxer_stream.h" |
22 #include "media/base/media_switches.h" | 23 #include "media/base/media_switches.h" |
23 #include "media/filters/audio_decoder_selector.h" | 24 #include "media/filters/audio_decoder_selector.h" |
24 #include "media/filters/decrypting_demuxer_stream.h" | 25 #include "media/filters/decrypting_demuxer_stream.h" |
25 | 26 |
26 namespace media { | 27 namespace media { |
27 | 28 |
| 29 namespace { |
| 30 |
| 31 enum AudioRendererEvent { |
| 32 INITIALIZED, |
| 33 RENDER_ERROR, |
| 34 MAX_EVENTS |
| 35 }; |
| 36 |
| 37 void HistogramRendererEvent(AudioRendererEvent event) { |
| 38 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS); |
| 39 } |
| 40 |
| 41 } // namespace |
| 42 |
28 AudioRendererImpl::AudioRendererImpl( | 43 AudioRendererImpl::AudioRendererImpl( |
29 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 44 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
30 media::AudioRendererSink* sink, | 45 media::AudioRendererSink* sink, |
31 ScopedVector<AudioDecoder> decoders, | 46 ScopedVector<AudioDecoder> decoders, |
32 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 47 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
33 : message_loop_(message_loop), | 48 : message_loop_(message_loop), |
34 weak_factory_(this), | 49 weak_factory_(this), |
35 sink_(sink), | 50 sink_(sink), |
36 decoder_selector_(new AudioDecoderSelector( | 51 decoder_selector_(new AudioDecoderSelector( |
37 message_loop, decoders.Pass(), set_decryptor_ready_cb)), | 52 message_loop, decoders.Pass(), set_decryptor_ready_cb)), |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 int bytes_per_frame = channels * decoder_->bits_per_channel() / 8; | 292 int bytes_per_frame = channels * decoder_->bits_per_channel() / 8; |
278 splicer_.reset(new AudioSplicer(bytes_per_frame, sample_rate)); | 293 splicer_.reset(new AudioSplicer(bytes_per_frame, sample_rate)); |
279 | 294 |
280 // We're all good! Continue initializing the rest of the audio renderer based | 295 // We're all good! Continue initializing the rest of the audio renderer based |
281 // on the decoder format. | 296 // on the decoder format. |
282 algorithm_.reset(new AudioRendererAlgorithm()); | 297 algorithm_.reset(new AudioRendererAlgorithm()); |
283 algorithm_->Initialize(0, audio_parameters_); | 298 algorithm_->Initialize(0, audio_parameters_); |
284 | 299 |
285 state_ = kPaused; | 300 state_ = kPaused; |
286 | 301 |
| 302 HistogramRendererEvent(INITIALIZED); |
| 303 |
287 sink_->Initialize(audio_parameters_, weak_this_); | 304 sink_->Initialize(audio_parameters_, weak_this_); |
288 sink_->Start(); | 305 sink_->Start(); |
289 | 306 |
290 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 307 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
291 } | 308 } |
292 | 309 |
293 void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) { | 310 void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) { |
294 DCHECK(message_loop_->BelongsToCurrentThread()); | 311 DCHECK(message_loop_->BelongsToCurrentThread()); |
295 base::AutoLock auto_lock(lock_); | 312 base::AutoLock auto_lock(lock_); |
296 if (state_ == kUnderflow) { | 313 if (state_ == kUnderflow) { |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 base::TimeDelta predicted_play_time = base::TimeDelta::FromMicroseconds( | 639 base::TimeDelta predicted_play_time = base::TimeDelta::FromMicroseconds( |
623 static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond / | 640 static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond / |
624 audio_parameters_.sample_rate()); | 641 audio_parameters_.sample_rate()); |
625 | 642 |
626 lock_.AssertAcquired(); | 643 lock_.AssertAcquired(); |
627 earliest_end_time_ = std::max( | 644 earliest_end_time_ = std::max( |
628 earliest_end_time_, time_now + playback_delay + predicted_play_time); | 645 earliest_end_time_, time_now + playback_delay + predicted_play_time); |
629 } | 646 } |
630 | 647 |
631 void AudioRendererImpl::OnRenderError() { | 648 void AudioRendererImpl::OnRenderError() { |
| 649 HistogramRendererEvent(RENDER_ERROR); |
632 disabled_cb_.Run(); | 650 disabled_cb_.Run(); |
633 } | 651 } |
634 | 652 |
635 void AudioRendererImpl::DisableUnderflowForTesting() { | 653 void AudioRendererImpl::DisableUnderflowForTesting() { |
636 underflow_disabled_ = true; | 654 underflow_disabled_ = true; |
637 } | 655 } |
638 | 656 |
639 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) { | 657 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) { |
640 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK; | 658 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK; |
641 switch (state_) { | 659 switch (state_) { |
(...skipping 15 matching lines...) Expand all Loading... |
657 case kUnderflow: | 675 case kUnderflow: |
658 case kRebuffering: | 676 case kRebuffering: |
659 case kStopped: | 677 case kStopped: |
660 if (status != PIPELINE_OK) | 678 if (status != PIPELINE_OK) |
661 error_cb_.Run(status); | 679 error_cb_.Run(status); |
662 return; | 680 return; |
663 } | 681 } |
664 } | 682 } |
665 | 683 |
666 } // namespace media | 684 } // namespace media |
OLD | NEW |