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