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

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

Issue 154543002: Cleanup AudioManager initialization on OSX to reduce startup delay. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 6 years, 10 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"
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 bool is_suspending_; 254 bool is_suspending_;
255 const bool is_monitoring_; 255 const bool is_monitoring_;
256 base::TimeTicks earliest_start_time_; 256 base::TimeTicks earliest_start_time_;
257 base::ThreadChecker thread_checker_; 257 base::ThreadChecker thread_checker_;
258 258
259 DISALLOW_COPY_AND_ASSIGN(AudioPowerObserver); 259 DISALLOW_COPY_AND_ASSIGN(AudioPowerObserver);
260 }; 260 };
261 261
262 AudioManagerMac::AudioManagerMac(AudioLogFactory* audio_log_factory) 262 AudioManagerMac::AudioManagerMac(AudioLogFactory* audio_log_factory)
263 : AudioManagerBase(audio_log_factory), 263 : AudioManagerBase(audio_log_factory),
264 current_sample_rate_(0) { 264 current_sample_rate_(0),
265 current_output_device_ = kAudioDeviceUnknown; 265 current_output_device_(kAudioDeviceUnknown) {
266
267 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 266 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
268 267
269 // Task must be posted last to avoid races from handing out "this" to the 268 // Task must be posted last to avoid races from handing out "this" to the
270 // audio thread. Always PostTask even if we're on the right thread since 269 // audio thread. Always PostTask even if we're on the right thread since
271 // AudioManager creation is on the startup path and this may be slow. 270 // AudioManager creation is on the startup path and this may be slow.
272 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( 271 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
273 &AudioManagerMac::CreateDeviceListener, base::Unretained(this))); 272 &AudioManagerMac::InitializeOnAudioThread, base::Unretained(this)));
274 } 273 }
275 274
276 AudioManagerMac::~AudioManagerMac() { 275 AudioManagerMac::~AudioManagerMac() {
277 if (GetTaskRunner()->BelongsToCurrentThread()) { 276 if (GetTaskRunner()->BelongsToCurrentThread()) {
278 DestroyDeviceListener(); 277 ShutdownOnAudioThread();
279 } else { 278 } else {
280 // It's safe to post a task here since Shutdown() will wait for all tasks to 279 // It's safe to post a task here since Shutdown() will wait for all tasks to
281 // complete before returning. 280 // complete before returning.
282 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( 281 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
283 &AudioManagerMac::DestroyDeviceListener, base::Unretained(this))); 282 &AudioManagerMac::ShutdownOnAudioThread, base::Unretained(this)));
284 } 283 }
285 284
286 Shutdown(); 285 Shutdown();
287 } 286 }
288 287
289 bool AudioManagerMac::HasAudioOutputDevices() { 288 bool AudioManagerMac::HasAudioOutputDevices() {
290 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); 289 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice);
291 } 290 }
292 291
293 bool AudioManagerMac::HasAudioInputDevices() { 292 bool AudioManagerMac::HasAudioInputDevices() {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 } 557 }
559 558
560 AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream( 559 AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
561 const AudioParameters& params, 560 const AudioParameters& params,
562 const std::string& device_id) { 561 const std::string& device_id) {
563 AudioDeviceID device = GetAudioDeviceIdByUId(false, device_id); 562 AudioDeviceID device = GetAudioDeviceIdByUId(false, device_id);
564 if (device == kAudioObjectUnknown) { 563 if (device == kAudioObjectUnknown) {
565 DLOG(ERROR) << "Failed to open output device: " << device_id; 564 DLOG(ERROR) << "Failed to open output device: " << device_id;
566 return NULL; 565 return NULL;
567 } 566 }
567
568 // Lazily create the audio device listener on the first stream creation.
569 if (!output_device_listener_) {
570 output_device_listener_.reset(new AudioDeviceListenerMac(base::Bind(
571 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this))));
572 // Only set the current output device for the default device.
573 if (device_id == AudioManagerBase::kDefaultDeviceId || device_id.empty())
574 current_output_device_ = device;
575 // Just use the current sample rate since we don't allow non-native sample
576 // rates on OSX.
577 current_sample_rate_ = params.sample_rate();
578 }
579
568 return new AUHALStream(this, params, device); 580 return new AUHALStream(this, params, device);
569 } 581 }
570 582
571 std::string AudioManagerMac::GetDefaultOutputDeviceID() { 583 std::string AudioManagerMac::GetDefaultOutputDeviceID() {
572 AudioDeviceID device_id = kAudioObjectUnknown; 584 AudioDeviceID device_id = kAudioObjectUnknown;
573 if (!GetDefaultOutputDevice(&device_id)) 585 if (!GetDefaultOutputDevice(&device_id))
574 return std::string(); 586 return std::string();
575 587
576 const AudioObjectPropertyAddress property_address = { 588 const AudioObjectPropertyAddress property_address = {
577 kAudioDevicePropertyDeviceUID, 589 kAudioDevicePropertyDeviceUID,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // can be removed as part of the work to consolidate these back-ends. 680 // can be removed as part of the work to consolidate these back-ends.
669 channel_layout = CHANNEL_LAYOUT_STEREO; 681 channel_layout = CHANNEL_LAYOUT_STEREO;
670 } 682 }
671 683
672 return AudioParameters( 684 return AudioParameters(
673 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, output_channels, 685 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, output_channels,
674 input_channels, hardware_sample_rate, 16, buffer_size, 686 input_channels, hardware_sample_rate, 16, buffer_size,
675 AudioParameters::NO_EFFECTS); 687 AudioParameters::NO_EFFECTS);
676 } 688 }
677 689
678 void AudioManagerMac::CreateDeviceListener() { 690 void AudioManagerMac::InitializeOnAudioThread() {
679 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 691 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
680
681 // Get a baseline for the sample-rate and current device,
682 // so we can intelligently handle device notifications only when necessary.
683 current_sample_rate_ = HardwareSampleRate();
684 if (!GetDefaultOutputDevice(&current_output_device_))
685 current_output_device_ = kAudioDeviceUnknown;
686
687 output_device_listener_.reset(new AudioDeviceListenerMac(base::Bind(
688 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this))));
689 power_observer_.reset(new AudioPowerObserver()); 692 power_observer_.reset(new AudioPowerObserver());
690 } 693 }
691 694
692 void AudioManagerMac::DestroyDeviceListener() { 695 void AudioManagerMac::ShutdownOnAudioThread() {
693 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 696 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
694 output_device_listener_.reset(); 697 output_device_listener_.reset();
695 power_observer_.reset(); 698 power_observer_.reset();
696 } 699 }
697 700
698 void AudioManagerMac::HandleDeviceChanges() { 701 void AudioManagerMac::HandleDeviceChanges() {
699 if (!GetTaskRunner()->BelongsToCurrentThread()) { 702 if (!GetTaskRunner()->BelongsToCurrentThread()) {
700 GetTaskRunner()->PostTask(FROM_HERE, base::Bind( 703 GetTaskRunner()->PostTask(FROM_HERE, base::Bind(
701 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this))); 704 &AudioManagerMac::HandleDeviceChanges, base::Unretained(this)));
702 return; 705 return;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 bool AudioManagerMac::ShouldDeferOutputStreamStart() { 738 bool AudioManagerMac::ShouldDeferOutputStreamStart() {
736 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 739 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
737 return power_observer_->ShouldDeferOutputStreamStart(); 740 return power_observer_->ShouldDeferOutputStreamStart();
738 } 741 }
739 742
740 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 743 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
741 return new AudioManagerMac(audio_log_factory); 744 return new AudioManagerMac(audio_log_factory);
742 } 745 }
743 746
744 } // namespace media 747 } // 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