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

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

Issue 1806313003: Pass task runners to AudioManager constructor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 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
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 <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 358
359 bool is_suspending_; 359 bool is_suspending_;
360 const bool is_monitoring_; 360 const bool is_monitoring_;
361 base::TimeTicks earliest_start_time_; 361 base::TimeTicks earliest_start_time_;
362 base::ThreadChecker thread_checker_; 362 base::ThreadChecker thread_checker_;
363 size_t num_resume_notifications_; 363 size_t num_resume_notifications_;
364 364
365 DISALLOW_COPY_AND_ASSIGN(AudioPowerObserver); 365 DISALLOW_COPY_AND_ASSIGN(AudioPowerObserver);
366 }; 366 };
367 367
368 AudioManagerMac::AudioManagerMac(AudioLogFactory* audio_log_factory) 368 AudioManagerMac::AudioManagerMac(
369 : AudioManagerBase(audio_log_factory), 369 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
370 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
371 AudioLogFactory* audio_log_factory)
372 : AudioManagerBase(std::move(task_runner),
373 std::move(worker_task_runner),
374 audio_log_factory),
370 current_sample_rate_(0), 375 current_sample_rate_(0),
371 current_output_device_(kAudioDeviceUnknown) { 376 current_output_device_(kAudioDeviceUnknown) {
372 SetMaxOutputStreamsAllowed(kMaxOutputStreams); 377 SetMaxOutputStreamsAllowed(kMaxOutputStreams);
373 378
374 // CoreAudio calls must occur on the main thread of the process, which in our
375 // case is sadly the browser UI thread. Failure to execute calls on the right
376 // thread leads to crashes and odd behavior. See http://crbug.com/158170.
377 // TODO(dalecurtis): We should require the message loop to be passed in.
378 task_runner_ = base::MessageLoopForUI::IsCurrent()
379 ? base::ThreadTaskRunnerHandle::Get()
380 : AudioManagerBase::GetTaskRunner();
381
382 // Task must be posted last to avoid races from handing out "this" to the 379 // Task must be posted last to avoid races from handing out "this" to the
383 // audio thread. Always PostTask even if we're on the right thread since 380 // audio thread. Always PostTask even if we're on the right thread since
384 // AudioManager creation is on the startup path and this may be slow. 381 // AudioManager creation is on the startup path and this may be slow.
385 task_runner_->PostTask(FROM_HERE, 382 GetTaskRunner()->PostTask(
386 base::Bind(&AudioManagerMac::InitializeOnAudioThread, 383 FROM_HERE, base::Bind(&AudioManagerMac::InitializeOnAudioThread,
387 base::Unretained(this))); 384 base::Unretained(this)));
388 } 385 }
389 386
390 AudioManagerMac::~AudioManagerMac() { 387 AudioManagerMac::~AudioManagerMac() {
391 if (task_runner_->BelongsToCurrentThread()) { 388 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
392 ShutdownOnAudioThread();
393 } else {
394 // It's safe to post a task here since Shutdown() will wait for all tasks to
395 // complete before returning.
396 task_runner_->PostTask(FROM_HERE,
397 base::Bind(&AudioManagerMac::ShutdownOnAudioThread,
398 base::Unretained(this)));
399 }
400 389
401 Shutdown(); 390 Shutdown();
402 } 391 ShutdownOnAudioThread();
DaleCurtis 2016/04/05 21:55:36 Ditto. Also these methods are confusing now. Maybe
403
404 scoped_refptr<base::SingleThreadTaskRunner> AudioManagerMac::GetTaskRunner() {
405 return task_runner_;
406 }
407
408 scoped_refptr<base::SingleThreadTaskRunner>
409 AudioManagerMac::GetWorkerTaskRunner() {
410 if (!worker_thread_) {
411 worker_thread_.reset(new base::Thread("AudioWorkerThread"));
412 CHECK(worker_thread_->Start());
413 }
414 return worker_thread_->task_runner();
415 } 392 }
416 393
417 bool AudioManagerMac::HasAudioOutputDevices() { 394 bool AudioManagerMac::HasAudioOutputDevices() {
418 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); 395 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice);
419 } 396 }
420 397
421 bool AudioManagerMac::HasAudioInputDevices() { 398 bool AudioManagerMac::HasAudioInputDevices() {
422 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); 399 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice);
423 } 400 }
424 401
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 const int buffer_size = ChooseBufferSize(true, sample_rate); 521 const int buffer_size = ChooseBufferSize(true, sample_rate);
545 522
546 // TODO(xians): query the native channel layout for the specific device. 523 // TODO(xians): query the native channel layout for the specific device.
547 return AudioParameters( 524 return AudioParameters(
548 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 525 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
549 sample_rate, 16, buffer_size); 526 sample_rate, 16, buffer_size);
550 } 527 }
551 528
552 std::string AudioManagerMac::GetAssociatedOutputDeviceID( 529 std::string AudioManagerMac::GetAssociatedOutputDeviceID(
553 const std::string& input_device_id) { 530 const std::string& input_device_id) {
554 DCHECK(task_runner_->BelongsToCurrentThread()); 531 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
555 AudioDeviceID device = GetAudioDeviceIdByUId(true, input_device_id); 532 AudioDeviceID device = GetAudioDeviceIdByUId(true, input_device_id);
556 if (device == kAudioObjectUnknown) 533 if (device == kAudioObjectUnknown)
557 return std::string(); 534 return std::string();
558 535
559 UInt32 size = 0; 536 UInt32 size = 0;
560 AudioObjectPropertyAddress pa = { 537 AudioObjectPropertyAddress pa = {
561 kAudioDevicePropertyRelatedDevices, 538 kAudioDevicePropertyRelatedDevices,
562 kAudioDevicePropertyScopeOutput, 539 kAudioDevicePropertyScopeOutput,
563 kAudioObjectPropertyElementMaster 540 kAudioObjectPropertyElementMaster
564 }; 541 };
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 // rates on OSX. 646 // rates on OSX.
670 current_sample_rate_ = params.sample_rate(); 647 current_sample_rate_ = params.sample_rate();
671 } 648 }
672 649
673 AUHALStream* stream = new AUHALStream(this, params, device); 650 AUHALStream* stream = new AUHALStream(this, params, device);
674 output_streams_.push_back(stream); 651 output_streams_.push_back(stream);
675 return stream; 652 return stream;
676 } 653 }
677 654
678 std::string AudioManagerMac::GetDefaultOutputDeviceID() { 655 std::string AudioManagerMac::GetDefaultOutputDeviceID() {
679 DCHECK(task_runner_->BelongsToCurrentThread()); 656 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
680 AudioDeviceID device_id = kAudioObjectUnknown; 657 AudioDeviceID device_id = kAudioObjectUnknown;
681 if (!GetDefaultOutputDevice(&device_id)) 658 if (!GetDefaultOutputDevice(&device_id))
682 return std::string(); 659 return std::string();
683 660
684 const AudioObjectPropertyAddress property_address = { 661 const AudioObjectPropertyAddress property_address = {
685 kAudioDevicePropertyDeviceUID, 662 kAudioDevicePropertyDeviceUID,
686 kAudioObjectPropertyScopeGlobal, 663 kAudioObjectPropertyScopeGlobal,
687 kAudioObjectPropertyElementMaster 664 kAudioObjectPropertyElementMaster
688 }; 665 };
689 CFStringRef device_uid = NULL; 666 CFStringRef device_uid = NULL;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 channel_layout = CHANNEL_LAYOUT_DISCRETE; 745 channel_layout = CHANNEL_LAYOUT_DISCRETE;
769 } 746 }
770 747
771 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, 748 AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
772 hardware_sample_rate, 16, buffer_size); 749 hardware_sample_rate, 16, buffer_size);
773 params.set_channels_for_discrete(output_channels); 750 params.set_channels_for_discrete(output_channels);
774 return params; 751 return params;
775 } 752 }
776 753
777 void AudioManagerMac::InitializeOnAudioThread() { 754 void AudioManagerMac::InitializeOnAudioThread() {
778 DCHECK(task_runner_->BelongsToCurrentThread()); 755 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
779 power_observer_.reset(new AudioPowerObserver()); 756 power_observer_.reset(new AudioPowerObserver());
780 } 757 }
781 758
782 void AudioManagerMac::ShutdownOnAudioThread() { 759 void AudioManagerMac::ShutdownOnAudioThread() {
783 DCHECK(task_runner_->BelongsToCurrentThread()); 760 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
784 output_device_listener_.reset(); 761 output_device_listener_.reset();
785 power_observer_.reset(); 762 power_observer_.reset();
786 763
787 // Since CoreAudio calls have to run on the UI thread and browser shutdown 764 // Since CoreAudio calls have to run on the UI thread and browser shutdown
788 // doesn't wait for outstanding tasks to complete, we may have input/output 765 // doesn't wait for outstanding tasks to complete, we may have input/output
789 // streams still running at shutdown. 766 // streams still running at shutdown.
790 // 767 //
791 // To avoid calls into destructed classes, we need to stop the OS callbacks 768 // To avoid calls into destructed classes, we need to stop the OS callbacks
792 // by stopping the streams. Note: The streams are leaked since process 769 // by stopping the streams. Note: The streams are leaked since process
793 // destruction is imminent. 770 // destruction is imminent.
794 // 771 //
795 // See http://crbug.com/354139 for crash details. 772 // See http://crbug.com/354139 for crash details.
796 StopStreams(&basic_input_streams_); 773 StopStreams(&basic_input_streams_);
797 StopStreams(&low_latency_input_streams_); 774 StopStreams(&low_latency_input_streams_);
798 StopStreams(&output_streams_); 775 StopStreams(&output_streams_);
799 } 776 }
800 777
801 void AudioManagerMac::HandleDeviceChanges() { 778 void AudioManagerMac::HandleDeviceChanges() {
802 DCHECK(task_runner_->BelongsToCurrentThread()); 779 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
803 const int new_sample_rate = HardwareSampleRate(); 780 const int new_sample_rate = HardwareSampleRate();
804 AudioDeviceID new_output_device; 781 AudioDeviceID new_output_device;
805 GetDefaultOutputDevice(&new_output_device); 782 GetDefaultOutputDevice(&new_output_device);
806 783
807 if (current_sample_rate_ == new_sample_rate && 784 if (current_sample_rate_ == new_sample_rate &&
808 current_output_device_ == new_output_device) { 785 current_output_device_ == new_output_device) {
809 return; 786 return;
810 } 787 }
811 788
812 current_sample_rate_ = new_sample_rate; 789 current_sample_rate_ = new_sample_rate;
(...skipping 21 matching lines...) Expand all
834 if (sample_rate <= 96000) 811 if (sample_rate <= 96000)
835 buffer_size = 2 * kMinimumInputOutputBufferSize; 812 buffer_size = 2 * kMinimumInputOutputBufferSize;
836 else if (sample_rate <= 192000) 813 else if (sample_rate <= 192000)
837 buffer_size = 4 * kMinimumInputOutputBufferSize; 814 buffer_size = 4 * kMinimumInputOutputBufferSize;
838 } 815 }
839 816
840 return buffer_size; 817 return buffer_size;
841 } 818 }
842 819
843 bool AudioManagerMac::ShouldDeferStreamStart() const { 820 bool AudioManagerMac::ShouldDeferStreamStart() const {
844 DCHECK(task_runner_->BelongsToCurrentThread()); 821 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
845 return power_observer_->ShouldDeferStreamStart(); 822 return power_observer_->ShouldDeferStreamStart();
846 } 823 }
847 824
848 bool AudioManagerMac::IsOnBatteryPower() const { 825 bool AudioManagerMac::IsOnBatteryPower() const {
849 DCHECK(task_runner_->BelongsToCurrentThread()); 826 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
850 return power_observer_->IsOnBatteryPower(); 827 return power_observer_->IsOnBatteryPower();
851 } 828 }
852 829
853 size_t AudioManagerMac::GetNumberOfResumeNotifications() const { 830 size_t AudioManagerMac::GetNumberOfResumeNotifications() const {
854 DCHECK(task_runner_->BelongsToCurrentThread()); 831 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
855 return power_observer_->num_resume_notifications(); 832 return power_observer_->num_resume_notifications();
856 } 833 }
857 834
858 bool AudioManagerMac::MaybeChangeBufferSize(AudioDeviceID device_id, 835 bool AudioManagerMac::MaybeChangeBufferSize(AudioDeviceID device_id,
859 AudioUnit audio_unit, 836 AudioUnit audio_unit,
860 AudioUnitElement element, 837 AudioUnitElement element,
861 size_t desired_buffer_size, 838 size_t desired_buffer_size,
862 bool* size_was_changed, 839 bool* size_was_changed,
863 size_t* io_buffer_frame_size) { 840 size_t* io_buffer_frame_size) {
864 DCHECK(task_runner_->BelongsToCurrentThread()); 841 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
865 const bool is_input = (element == 1); 842 const bool is_input = (element == 1);
866 DVLOG(1) << "MaybeChangeBufferSize(id=0x" << std::hex << device_id 843 DVLOG(1) << "MaybeChangeBufferSize(id=0x" << std::hex << device_id
867 << ", is_input=" << is_input << ", desired_buffer_size=" << std::dec 844 << ", is_input=" << is_input << ", desired_buffer_size=" << std::dec
868 << desired_buffer_size << ")"; 845 << desired_buffer_size << ")";
869 846
870 *size_was_changed = false; 847 *size_was_changed = false;
871 *io_buffer_frame_size = 0; 848 *io_buffer_frame_size = 0;
872 849
873 // Log the device name (and id) for debugging purposes. 850 // Log the device name (and id) for debugging purposes.
874 std::string device_name = GetAudioDeviceNameFromDeviceId(device_id, is_input); 851 std::string device_name = GetAudioDeviceNameFromDeviceId(device_id, is_input);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 basic_input_streams_.end(), 951 basic_input_streams_.end(),
975 stream); 952 stream);
976 if (stream_it == basic_input_streams_.end()) 953 if (stream_it == basic_input_streams_.end())
977 low_latency_input_streams_.remove(static_cast<AUAudioInputStream*>(stream)); 954 low_latency_input_streams_.remove(static_cast<AUAudioInputStream*>(stream));
978 else 955 else
979 basic_input_streams_.erase(stream_it); 956 basic_input_streams_.erase(stream_it);
980 957
981 AudioManagerBase::ReleaseInputStream(stream); 958 AudioManagerBase::ReleaseInputStream(stream);
982 } 959 }
983 960
984 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { 961 ScopedAudioManagerPtr CreateAudioManager(
985 return new AudioManagerMac(audio_log_factory); 962 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
963 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
964 AudioLogFactory* audio_log_factory) {
965 return ScopedAudioManagerPtr(
966 new AudioManagerMac(std::move(task_runner), std::move(worker_task_runner),
967 audio_log_factory));
986 } 968 }
987 969
988 } // namespace media 970 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698