Chromium Code Reviews| 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) { | |
|
DaleCurtis
2013/04/25 17:33:06
Unnamed namespace in media?! :)
scherkus (not reviewing)
2013/04/25 18:28:49
The enum declaration made me do it! (prevents poss
| |
| 38 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS); | |
| 39 } | |
| 40 | |
| 41 } // namespace | |
| 42 | |
|
DaleCurtis
2013/04/25 17:33:06
extra line.
scherkus (not reviewing)
2013/04/25 18:28:49
Done.
| |
| 43 | |
| 28 AudioRendererImpl::AudioRendererImpl( | 44 AudioRendererImpl::AudioRendererImpl( |
| 29 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 45 const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| 30 media::AudioRendererSink* sink, | 46 media::AudioRendererSink* sink, |
| 31 ScopedVector<AudioDecoder> decoders, | 47 ScopedVector<AudioDecoder> decoders, |
| 32 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 48 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
| 33 : message_loop_(message_loop), | 49 : message_loop_(message_loop), |
| 34 weak_factory_(this), | 50 weak_factory_(this), |
| 35 sink_(sink), | 51 sink_(sink), |
| 36 decoder_selector_(new AudioDecoderSelector( | 52 decoder_selector_(new AudioDecoderSelector( |
| 37 message_loop, decoders.Pass(), set_decryptor_ready_cb)), | 53 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; | 293 int bytes_per_frame = channels * decoder_->bits_per_channel() / 8; |
| 278 splicer_.reset(new AudioSplicer(bytes_per_frame, sample_rate)); | 294 splicer_.reset(new AudioSplicer(bytes_per_frame, sample_rate)); |
| 279 | 295 |
| 280 // We're all good! Continue initializing the rest of the audio renderer based | 296 // We're all good! Continue initializing the rest of the audio renderer based |
| 281 // on the decoder format. | 297 // on the decoder format. |
| 282 algorithm_.reset(new AudioRendererAlgorithm()); | 298 algorithm_.reset(new AudioRendererAlgorithm()); |
| 283 algorithm_->Initialize(0, audio_parameters_); | 299 algorithm_->Initialize(0, audio_parameters_); |
| 284 | 300 |
| 285 state_ = kPaused; | 301 state_ = kPaused; |
| 286 | 302 |
| 303 HistogramRendererEvent(INITIALIZED); | |
| 304 | |
| 287 sink_->Initialize(audio_parameters_, weak_this_); | 305 sink_->Initialize(audio_parameters_, weak_this_); |
| 288 sink_->Start(); | 306 sink_->Start(); |
| 289 | 307 |
| 290 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 308 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 291 } | 309 } |
| 292 | 310 |
| 293 void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) { | 311 void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) { |
| 294 DCHECK(message_loop_->BelongsToCurrentThread()); | 312 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 295 base::AutoLock auto_lock(lock_); | 313 base::AutoLock auto_lock(lock_); |
| 296 if (state_ == kUnderflow) { | 314 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( | 640 base::TimeDelta predicted_play_time = base::TimeDelta::FromMicroseconds( |
| 623 static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond / | 641 static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond / |
| 624 audio_parameters_.sample_rate()); | 642 audio_parameters_.sample_rate()); |
| 625 | 643 |
| 626 lock_.AssertAcquired(); | 644 lock_.AssertAcquired(); |
| 627 earliest_end_time_ = std::max( | 645 earliest_end_time_ = std::max( |
| 628 earliest_end_time_, time_now + playback_delay + predicted_play_time); | 646 earliest_end_time_, time_now + playback_delay + predicted_play_time); |
| 629 } | 647 } |
| 630 | 648 |
| 631 void AudioRendererImpl::OnRenderError() { | 649 void AudioRendererImpl::OnRenderError() { |
| 650 HistogramRendererEvent(RENDER_ERROR); | |
| 632 disabled_cb_.Run(); | 651 disabled_cb_.Run(); |
| 633 } | 652 } |
| 634 | 653 |
| 635 void AudioRendererImpl::DisableUnderflowForTesting() { | 654 void AudioRendererImpl::DisableUnderflowForTesting() { |
| 636 underflow_disabled_ = true; | 655 underflow_disabled_ = true; |
| 637 } | 656 } |
| 638 | 657 |
| 639 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) { | 658 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) { |
| 640 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK; | 659 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK; |
| 641 switch (state_) { | 660 switch (state_) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 657 case kUnderflow: | 676 case kUnderflow: |
| 658 case kRebuffering: | 677 case kRebuffering: |
| 659 case kStopped: | 678 case kStopped: |
| 660 if (status != PIPELINE_OK) | 679 if (status != PIPELINE_OK) |
| 661 error_cb_.Run(status); | 680 error_cb_.Run(status); |
| 662 return; | 681 return; |
| 663 } | 682 } |
| 664 } | 683 } |
| 665 | 684 |
| 666 } // namespace media | 685 } // namespace media |
| OLD | NEW |