Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: media/renderers/audio_renderer_impl.cc

Issue 2089503002: Merge M52: "Freeze media time and audio rendering when the system suspends." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2743
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/renderers/audio_renderer_impl.h ('k') | media/renderers/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/renderers/audio_renderer_impl.h ('k') | media/renderers/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698