| 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/renderers/audio_renderer_impl.h" | 5 #include "media/renderers/audio_renderer_impl.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/power_monitor/power_monitor.h" |
| 17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 18 #include "base/time/default_tick_clock.h" | 19 #include "base/time/default_tick_clock.h" |
| 19 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 20 #include "media/base/audio_buffer.h" | 21 #include "media/base/audio_buffer.h" |
| 21 #include "media/base/audio_buffer_converter.h" | 22 #include "media/base/audio_buffer_converter.h" |
| 22 #include "media/base/audio_hardware_config.h" | 23 #include "media/base/audio_hardware_config.h" |
| 23 #include "media/base/audio_splicer.h" | 24 #include "media/base/audio_splicer.h" |
| 24 #include "media/base/bind_to_current_loop.h" | 25 #include "media/base/bind_to_current_loop.h" |
| 25 #include "media/base/demuxer_stream.h" | 26 #include "media/base/demuxer_stream.h" |
| 26 #include "media/base/media_log.h" | 27 #include "media/base/media_log.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 48 last_audio_memory_usage_(0), | 49 last_audio_memory_usage_(0), |
| 49 last_decoded_sample_rate_(0), | 50 last_decoded_sample_rate_(0), |
| 50 playback_rate_(0.0), | 51 playback_rate_(0.0), |
| 51 state_(kUninitialized), | 52 state_(kUninitialized), |
| 52 buffering_state_(BUFFERING_HAVE_NOTHING), | 53 buffering_state_(BUFFERING_HAVE_NOTHING), |
| 53 rendering_(false), | 54 rendering_(false), |
| 54 sink_playing_(false), | 55 sink_playing_(false), |
| 55 pending_read_(false), | 56 pending_read_(false), |
| 56 received_end_of_stream_(false), | 57 received_end_of_stream_(false), |
| 57 rendered_end_of_stream_(false), | 58 rendered_end_of_stream_(false), |
| 59 is_suspending_(false), |
| 58 weak_factory_(this) { | 60 weak_factory_(this) { |
| 59 audio_buffer_stream_->set_splice_observer(base::Bind( | 61 audio_buffer_stream_->set_splice_observer(base::Bind( |
| 60 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); | 62 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); |
| 61 audio_buffer_stream_->set_config_change_observer(base::Bind( | 63 audio_buffer_stream_->set_config_change_observer(base::Bind( |
| 62 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); | 64 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); |
| 65 |
| 66 // Tests may not have a power monitor. |
| 67 base::PowerMonitor* monitor = base::PowerMonitor::Get(); |
| 68 if (!monitor) |
| 69 return; |
| 70 |
| 71 // PowerObserver's must be added and removed from the same thread, but we |
| 72 // won't remove the observer until we're destructed on |task_runner_| so we |
| 73 // must post it here if we're on the wrong thread. |
| 74 if (task_runner_->BelongsToCurrentThread()) { |
| 75 monitor->AddObserver(this); |
| 76 } else { |
| 77 // Safe to post this without a WeakPtr because this class must be destructed |
| 78 // on the same thread and construction has not completed yet. |
| 79 task_runner_->PostTask(FROM_HERE, |
| 80 base::Bind(&base::PowerMonitor::AddObserver, |
| 81 base::Unretained(monitor), this)); |
| 82 } |
| 83 // Do not add anything below this line since the above actions are only safe |
| 84 // as the last lines of the constructor. |
| 63 } | 85 } |
| 64 | 86 |
| 65 AudioRendererImpl::~AudioRendererImpl() { | 87 AudioRendererImpl::~AudioRendererImpl() { |
| 66 DVLOG(1) << __FUNCTION__; | 88 DVLOG(1) << __FUNCTION__; |
| 67 DCHECK(task_runner_->BelongsToCurrentThread()); | 89 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 90 if (base::PowerMonitor::Get()) |
| 91 base::PowerMonitor::Get()->RemoveObserver(this); |
| 68 | 92 |
| 69 // If Render() is in progress, this call will wait for Render() to finish. | 93 // If Render() is in progress, this call will wait for Render() to finish. |
| 70 // After this call, the |sink_| will not call back into |this| anymore. | 94 // After this call, the |sink_| will not call back into |this| anymore. |
| 71 sink_->Stop(); | 95 sink_->Stop(); |
| 72 | 96 |
| 73 if (!init_cb_.is_null()) | 97 if (!init_cb_.is_null()) |
| 74 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); | 98 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
| 75 } | 99 } |
| 76 | 100 |
| 77 void AudioRendererImpl::StartTicking() { | 101 void AudioRendererImpl::StartTicking() { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 bool AudioRendererImpl::GetWallClockTimes( | 206 bool AudioRendererImpl::GetWallClockTimes( |
| 183 const std::vector<base::TimeDelta>& media_timestamps, | 207 const std::vector<base::TimeDelta>& media_timestamps, |
| 184 std::vector<base::TimeTicks>* wall_clock_times) { | 208 std::vector<base::TimeTicks>* wall_clock_times) { |
| 185 base::AutoLock auto_lock(lock_); | 209 base::AutoLock auto_lock(lock_); |
| 186 DCHECK(wall_clock_times->empty()); | 210 DCHECK(wall_clock_times->empty()); |
| 187 | 211 |
| 188 // When playback is paused (rate is zero), assume a rate of 1.0. | 212 // When playback is paused (rate is zero), assume a rate of 1.0. |
| 189 const double playback_rate = playback_rate_ ? playback_rate_ : 1.0; | 213 const double playback_rate = playback_rate_ ? playback_rate_ : 1.0; |
| 190 const bool is_time_moving = sink_playing_ && playback_rate_ && | 214 const bool is_time_moving = sink_playing_ && playback_rate_ && |
| 191 !last_render_time_.is_null() && | 215 !last_render_time_.is_null() && |
| 192 stop_rendering_time_.is_null(); | 216 stop_rendering_time_.is_null() && !is_suspending_; |
| 193 | 217 |
| 194 // Pre-compute the time until playback of the audio buffer extents, since | 218 // Pre-compute the time until playback of the audio buffer extents, since |
| 195 // these values are frequently used below. | 219 // these values are frequently used below. |
| 196 const base::TimeDelta time_until_front = | 220 const base::TimeDelta time_until_front = |
| 197 audio_clock_->TimeUntilPlayback(audio_clock_->front_timestamp()); | 221 audio_clock_->TimeUntilPlayback(audio_clock_->front_timestamp()); |
| 198 const base::TimeDelta time_until_back = | 222 const base::TimeDelta time_until_back = |
| 199 audio_clock_->TimeUntilPlayback(audio_clock_->back_timestamp()); | 223 audio_clock_->TimeUntilPlayback(audio_clock_->back_timestamp()); |
| 200 | 224 |
| 201 if (media_timestamps.empty()) { | 225 if (media_timestamps.empty()) { |
| 202 // Return the current media time as a wall clock time while accounting for | 226 // Return the current media time as a wall clock time while accounting for |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 DCHECK(task_runner_->BelongsToCurrentThread()); | 518 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 495 client_->OnWaitingForDecryptionKey(); | 519 client_->OnWaitingForDecryptionKey(); |
| 496 } | 520 } |
| 497 | 521 |
| 498 void AudioRendererImpl::SetVolume(float volume) { | 522 void AudioRendererImpl::SetVolume(float volume) { |
| 499 DCHECK(task_runner_->BelongsToCurrentThread()); | 523 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 500 DCHECK(sink_.get()); | 524 DCHECK(sink_.get()); |
| 501 sink_->SetVolume(volume); | 525 sink_->SetVolume(volume); |
| 502 } | 526 } |
| 503 | 527 |
| 528 void AudioRendererImpl::OnSuspend() { |
| 529 base::AutoLock auto_lock(lock_); |
| 530 is_suspending_ = true; |
| 531 } |
| 532 |
| 533 void AudioRendererImpl::OnResume() { |
| 534 base::AutoLock auto_lock(lock_); |
| 535 is_suspending_ = false; |
| 536 } |
| 537 |
| 504 void AudioRendererImpl::DecodedAudioReady( | 538 void AudioRendererImpl::DecodedAudioReady( |
| 505 AudioBufferStream::Status status, | 539 AudioBufferStream::Status status, |
| 506 const scoped_refptr<AudioBuffer>& buffer) { | 540 const scoped_refptr<AudioBuffer>& buffer) { |
| 507 DVLOG(2) << __FUNCTION__ << "(" << status << ")"; | 541 DVLOG(2) << __FUNCTION__ << "(" << status << ")"; |
| 508 DCHECK(task_runner_->BelongsToCurrentThread()); | 542 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 509 | 543 |
| 510 base::AutoLock auto_lock(lock_); | 544 base::AutoLock auto_lock(lock_); |
| 511 DCHECK(state_ != kUninitialized); | 545 DCHECK(state_ != kUninitialized); |
| 512 | 546 |
| 513 CHECK(pending_read_); | 547 CHECK(pending_read_); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 stop_rendering_time_ = base::TimeTicks(); | 778 stop_rendering_time_ = base::TimeTicks(); |
| 745 } | 779 } |
| 746 | 780 |
| 747 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. | 781 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. |
| 748 if (!algorithm_) { | 782 if (!algorithm_) { |
| 749 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, | 783 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, |
| 750 playback_rate_); | 784 playback_rate_); |
| 751 return 0; | 785 return 0; |
| 752 } | 786 } |
| 753 | 787 |
| 754 if (playback_rate_ == 0) { | 788 if (playback_rate_ == 0 || is_suspending_) { |
| 755 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, | 789 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, |
| 756 playback_rate_); | 790 playback_rate_); |
| 757 return 0; | 791 return 0; |
| 758 } | 792 } |
| 759 | 793 |
| 760 // Mute audio by returning 0 when not playing. | 794 // Mute audio by returning 0 when not playing. |
| 761 if (state_ != kPlaying) { | 795 if (state_ != kPlaying) { |
| 762 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, | 796 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, |
| 763 playback_rate_); | 797 playback_rate_); |
| 764 return 0; | 798 return 0; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 DCHECK_NE(buffering_state_, buffering_state); | 959 DCHECK_NE(buffering_state_, buffering_state); |
| 926 lock_.AssertAcquired(); | 960 lock_.AssertAcquired(); |
| 927 buffering_state_ = buffering_state; | 961 buffering_state_ = buffering_state; |
| 928 | 962 |
| 929 task_runner_->PostTask( | 963 task_runner_->PostTask( |
| 930 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, | 964 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, |
| 931 weak_factory_.GetWeakPtr(), buffering_state_)); | 965 weak_factory_.GetWeakPtr(), buffering_state_)); |
| 932 } | 966 } |
| 933 | 967 |
| 934 } // namespace media | 968 } // namespace media |
| OLD | NEW |