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

Side by Side Diff: media/audio/mac/audio_manager_mac.cc

Issue 135853022: Defer OSX output stream Start() around system supend and resume. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Wait for initialization. Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « media/audio/mac/audio_manager_mac.h ('k') | no next file » | 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/audio/mac/audio_manager_mac.h" 5 #include "media/audio/mac/audio_manager_mac.h"
6 6
7 #include <CoreAudio/AudioHardware.h> 7 #include <CoreAudio/AudioHardware.h>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/mac/mac_logging.h" 12 #include "base/mac/mac_logging.h"
13 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
14 #include "base/power_monitor/power_monitor.h"
15 #include "base/power_monitor/power_observer.h"
14 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
17 #include "base/threading/thread_checker.h"
15 #include "media/audio/audio_parameters.h" 18 #include "media/audio/audio_parameters.h"
16 #include "media/audio/mac/audio_auhal_mac.h" 19 #include "media/audio/mac/audio_auhal_mac.h"
17 #include "media/audio/mac/audio_input_mac.h" 20 #include "media/audio/mac/audio_input_mac.h"
18 #include "media/audio/mac/audio_low_latency_input_mac.h" 21 #include "media/audio/mac/audio_low_latency_input_mac.h"
19 #include "media/audio/mac/audio_low_latency_output_mac.h" 22 #include "media/audio/mac/audio_low_latency_output_mac.h"
20 #include "media/audio/mac/audio_synchronized_mac.h" 23 #include "media/audio/mac/audio_synchronized_mac.h"
21 #include "media/audio/mac/audio_unified_mac.h" 24 #include "media/audio/mac/audio_unified_mac.h"
22 #include "media/base/bind_to_current_loop.h" 25 #include "media/base/bind_to_current_loop.h"
23 #include "media/base/channel_layout.h" 26 #include "media/base/channel_layout.h"
24 #include "media/base/limits.h" 27 #include "media/base/limits.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 216 }
214 217
215 if (result) { 218 if (result) {
216 OSSTATUS_DLOG(WARNING, result) << "Unable to query device " << device_id 219 OSSTATUS_DLOG(WARNING, result) << "Unable to query device " << device_id
217 << " for AudioDeviceID"; 220 << " for AudioDeviceID";
218 } 221 }
219 222
220 return audio_device_id; 223 return audio_device_id;
221 } 224 }
222 225
226 class AudioManagerMac::AudioPowerObserver : public base::PowerObserver {
227 public:
228 AudioPowerObserver()
229 : is_suspending_(false),
230 is_monitoring_(base::PowerMonitor::Get()) {
231 // The PowerMonitor requires signifcant setup (a CFRunLoop and preallocated
232 // IO ports) so it's not available under unit tests. See the OSX impl of
233 // base::PowerMonitorDeviceSource for more details.
234 if (!is_monitoring_)
235 return;
236 base::PowerMonitor::Get()->AddObserver(this);
237 }
238
239 virtual ~AudioPowerObserver() {
240 DCHECK(thread_checker_.CalledOnValidThread());
241 if (!is_monitoring_)
242 return;
243 base::PowerMonitor::Get()->RemoveObserver(this);
244 }
245
246 bool ShouldDeferOutputStreamStart() {
247 DCHECK(thread_checker_.CalledOnValidThread());
248 // Start() should be deferred if the system is in the middle of a suspend or
249 // has recently started the process of resuming.
250 return is_suspending_ || base::TimeTicks::Now() < earliest_start_time_;
251 }
252
253 private:
254 virtual void OnSuspend() OVERRIDE {
255 DCHECK(thread_checker_.CalledOnValidThread());
256 is_suspending_ = true;
257 }
258
259 virtual void OnResume() OVERRIDE {
260 DCHECK(thread_checker_.CalledOnValidThread());
261 is_suspending_ = false;
262 earliest_start_time_ = base::TimeTicks::Now() +
263 base::TimeDelta::FromSeconds(kStartDelayInSecsForPowerEvents);
264 }
265
266 bool is_suspending_;
267 const bool is_monitoring_;
268 base::TimeTicks earliest_start_time_;
269 base::ThreadChecker thread_checker_;
270
271 DISALLOW_COPY_AND_ASSIGN(AudioPowerObserver);
272 };
273
223 AudioManagerMac::AudioManagerMac(AudioLogFactory* audio_log_factory) 274 AudioManagerMac::AudioManagerMac(AudioLogFactory* audio_log_factory)
224 : AudioManagerBase(audio_log_factory), 275 : AudioManagerBase(audio_log_factory),
225 current_sample_rate_(0) { 276 current_sample_rate_(0) {
226 current_output_device_ = kAudioDeviceUnknown; 277 current_output_device_ = kAudioDeviceUnknown;
227 278
228 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 279 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
229 280
230 // Task must be posted last to avoid races from handing out "this" to the 281 // Task must be posted last to avoid races from handing out "this" to the
231 // audio thread. Always PostTask even if we're on the right thread since 282 // audio thread. Always PostTask even if we're on the right thread since
232 // AudioManager creation is on the startup path and this may be slow. 283 // AudioManager creation is on the startup path and this may be slow.
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 745 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
695 746
696 // Get a baseline for the sample-rate and current device, 747 // Get a baseline for the sample-rate and current device,
697 // so we can intelligently handle device notifications only when necessary. 748 // so we can intelligently handle device notifications only when necessary.
698 current_sample_rate_ = HardwareSampleRate(); 749 current_sample_rate_ = HardwareSampleRate();
699 if (!GetDefaultOutputDevice(&current_output_device_)) 750 if (!GetDefaultOutputDevice(&current_output_device_))
700 current_output_device_ = kAudioDeviceUnknown; 751 current_output_device_ = kAudioDeviceUnknown;
701 752
702 output_device_listener_.reset(new AudioDeviceListenerMac(base::Bind( 753 output_device_listener_.reset(new AudioDeviceListenerMac(base::Bind(
703 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this)))); 754 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this))));
755 power_observer_.reset(new AudioPowerObserver());
704 } 756 }
705 757
706 void AudioManagerMac::DestroyDeviceListener() { 758 void AudioManagerMac::DestroyDeviceListener() {
707 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 759 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
708 output_device_listener_.reset(); 760 output_device_listener_.reset();
761 power_observer_.reset();
709 } 762 }
710 763
711 void AudioManagerMac::HandleDeviceChanges() { 764 void AudioManagerMac::HandleDeviceChanges() {
712 if (!GetTaskRunner()->BelongsToCurrentThread()) { 765 if (!GetTaskRunner()->BelongsToCurrentThread()) {
713 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( 766 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
714 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this))); 767 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this)));
715 return; 768 return;
716 } 769 }
717 770
718 int new_sample_rate = HardwareSampleRate(); 771 int new_sample_rate = HardwareSampleRate();
(...skipping 19 matching lines...) Expand all
738 // to glitching. Adjust upwards by multiples of the default size. 791 // to glitching. Adjust upwards by multiples of the default size.
739 if (output_sample_rate <= 96000) 792 if (output_sample_rate <= 96000)
740 buffer_size = 2 * kDefaultLowLatencyBufferSize; 793 buffer_size = 2 * kDefaultLowLatencyBufferSize;
741 else if (output_sample_rate <= 192000) 794 else if (output_sample_rate <= 192000)
742 buffer_size = 4 * kDefaultLowLatencyBufferSize; 795 buffer_size = 4 * kDefaultLowLatencyBufferSize;
743 } 796 }
744 797
745 return buffer_size; 798 return buffer_size;
746 } 799 }
747 800
801 bool AudioManagerMac::ShouldDeferOutputStreamStart() {
802 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
803 return power_observer_->ShouldDeferOutputStreamStart();
804 }
805
748 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 806 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
749 return new AudioManagerMac(audio_log_factory); 807 return new AudioManagerMac(audio_log_factory);
750 } 808 }
751 809
752 } // namespace media 810 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/mac/audio_manager_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698