Chromium Code Reviews| 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/audio/mac/audio_low_latency_input_mac.h" | 5 #include "media/audio/mac/audio_low_latency_input_mac.h" |
| 6 #include <CoreServices/CoreServices.h> | 6 #include <CoreServices/CoreServices.h> |
| 7 #include <mach/mach.h> | 7 #include <mach/mach.h> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/mac/mac_logging.h" | 12 #include "base/mac/mac_logging.h" |
| 12 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
| 14 #include "base/sys_info.h" | 15 #include "base/sys_info.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 #include "media/audio/mac/audio_manager_mac.h" | 17 #include "media/audio/mac/audio_manager_mac.h" |
| 17 #include "media/base/audio_bus.h" | 18 #include "media/base/audio_bus.h" |
| 18 #include "media/base/data_buffer.h" | 19 #include "media/base/data_buffer.h" |
| 19 | 20 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 input_callback_is_active_(false), | 196 input_callback_is_active_(false), |
| 196 start_was_deferred_(false), | 197 start_was_deferred_(false), |
| 197 buffer_size_was_changed_(false), | 198 buffer_size_was_changed_(false), |
| 198 audio_unit_render_has_worked_(false), | 199 audio_unit_render_has_worked_(false), |
| 199 device_listener_is_active_(false), | 200 device_listener_is_active_(false), |
| 200 started_(false), | 201 started_(false), |
| 201 last_sample_time_(0.0), | 202 last_sample_time_(0.0), |
| 202 last_number_of_frames_(0), | 203 last_number_of_frames_(0), |
| 203 total_lost_frames_(0), | 204 total_lost_frames_(0), |
| 204 largest_glitch_frames_(0), | 205 largest_glitch_frames_(0), |
| 205 glitches_detected_(0) { | 206 glitches_detected_(0), |
| 207 weak_factory_(this) { | |
| 206 DCHECK(manager_); | 208 DCHECK(manager_); |
| 207 | 209 |
| 208 // Set up the desired (output) format specified by the client. | 210 // Set up the desired (output) format specified by the client. |
| 209 format_.mSampleRate = input_params.sample_rate(); | 211 format_.mSampleRate = input_params.sample_rate(); |
| 210 format_.mFormatID = kAudioFormatLinearPCM; | 212 format_.mFormatID = kAudioFormatLinearPCM; |
| 211 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | | 213 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | |
| 212 kLinearPCMFormatFlagIsSignedInteger; | 214 kLinearPCMFormatFlagIsSignedInteger; |
| 213 DCHECK(FormatIsInterleaved(format_.mFormatFlags)); | 215 DCHECK(FormatIsInterleaved(format_.mFormatFlags)); |
| 214 format_.mBitsPerChannel = input_params.bits_per_sample(); | 216 format_.mBitsPerChannel = input_params.bits_per_sample(); |
| 215 format_.mChannelsPerFrame = input_params.channels(); | 217 format_.mChannelsPerFrame = input_params.channels(); |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 896 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_)); | 898 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_)); |
| 897 | 899 |
| 898 // Compensate the audio delay caused by the FIFO. | 900 // Compensate the audio delay caused by the FIFO. |
| 899 capture_delay_bytes += fifo_.GetAvailableFrames() * format_.mBytesPerFrame; | 901 capture_delay_bytes += fifo_.GetAvailableFrames() * format_.mBytesPerFrame; |
| 900 sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume); | 902 sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume); |
| 901 } | 903 } |
| 902 | 904 |
| 903 return noErr; | 905 return noErr; |
| 904 } | 906 } |
| 905 | 907 |
| 908 void AUAudioInputStream::DevicePropertyChangedOnMainThread( | |
| 909 const std::vector<UInt32>& properties) { | |
| 910 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 911 DCHECK(device_listener_is_active_); | |
| 912 // Use property as key to a map and increase its value. We are not | |
| 913 // interested in all property changes but store all here anyhow. | |
| 914 // Filtering will be done later in AddDevicePropertyChangesToUMA(); | |
| 915 for (auto property : properties) { | |
| 916 DVLOG(2) << "=> " << FourCharFormatCodeToString(property); | |
| 917 ++device_property_changes_map_[property]; | |
| 918 } | |
| 919 } | |
| 920 | |
| 906 OSStatus AUAudioInputStream::OnDevicePropertyChanged( | 921 OSStatus AUAudioInputStream::OnDevicePropertyChanged( |
| 907 AudioObjectID object_id, | 922 AudioObjectID object_id, |
| 908 UInt32 num_addresses, | 923 UInt32 num_addresses, |
| 909 const AudioObjectPropertyAddress addresses[], | 924 const AudioObjectPropertyAddress addresses[], |
| 910 void* context) { | 925 void* context) { |
| 911 AUAudioInputStream* self = static_cast<AUAudioInputStream*>(context); | 926 AUAudioInputStream* self = static_cast<AUAudioInputStream*>(context); |
| 912 return self->DevicePropertyChanged(object_id, num_addresses, addresses); | 927 return self->DevicePropertyChanged(object_id, num_addresses, addresses); |
| 913 } | 928 } |
| 914 | 929 |
| 915 OSStatus AUAudioInputStream::DevicePropertyChanged( | 930 OSStatus AUAudioInputStream::DevicePropertyChanged( |
| 916 AudioObjectID object_id, | 931 AudioObjectID object_id, |
| 917 UInt32 num_addresses, | 932 UInt32 num_addresses, |
| 918 const AudioObjectPropertyAddress addresses[]) { | 933 const AudioObjectPropertyAddress addresses[]) { |
| 919 if (object_id != input_device_id_) | 934 if (object_id != input_device_id_) |
| 920 return noErr; | 935 return noErr; |
| 921 | 936 |
| 922 // Listeners will be called when possibly many properties have changed. | 937 // Listeners will be called when possibly many properties have changed. |
| 923 // Consequently, the implementation of a listener must go through the array of | 938 // Consequently, the implementation of a listener must go through the array of |
| 924 // addresses to see what exactly has changed. | 939 // addresses to see what exactly has changed. Copy values into a local vector |
| 940 // and update the |device_property_changes_map_| on the main thread to avoid | |
| 941 // potential race conditions. | |
| 942 std::vector<UInt32> properties; | |
| 943 properties.reserve(num_addresses); | |
| 925 for (UInt32 i = 0; i < num_addresses; ++i) { | 944 for (UInt32 i = 0; i < num_addresses; ++i) { |
|
tommi (sloooow) - chröme
2016/03/18 10:22:39
nit: no {}
henrika (OOO until Aug 14)
2016/03/18 10:26:34
Done.
| |
| 926 const UInt32 property = addresses[i].mSelector; | 945 properties.push_back(addresses[i].mSelector); |
| 927 // Use selector as key to a map and increase its value. We are not | |
| 928 // interested in all property changes but store all here anyhow. | |
| 929 // Filtering will be done later in AddDevicePropertyChangesToUMA(); | |
| 930 ++device_property_changes_map_[property]; | |
| 931 } | 946 } |
| 947 manager_->GetTaskRunner()->PostTask( | |
| 948 FROM_HERE, | |
| 949 base::Bind(&AUAudioInputStream::DevicePropertyChangedOnMainThread, | |
| 950 weak_factory_.GetWeakPtr(), properties)); | |
| 932 return noErr; | 951 return noErr; |
| 933 } | 952 } |
| 934 | 953 |
| 935 void AUAudioInputStream::RegisterDeviceChangeListener() { | 954 void AUAudioInputStream::RegisterDeviceChangeListener() { |
| 936 DCHECK(thread_checker_.CalledOnValidThread()); | 955 DCHECK(thread_checker_.CalledOnValidThread()); |
| 937 DCHECK(!device_listener_is_active_); | 956 DCHECK(!device_listener_is_active_); |
| 938 DVLOG(1) << "RegisterDeviceChangeListener"; | 957 DVLOG(1) << "RegisterDeviceChangeListener"; |
| 939 if (input_device_id_ == kAudioObjectUnknown) | 958 if (input_device_id_ == kAudioObjectUnknown) |
| 940 return; | 959 return; |
| 941 device_property_changes_map_.clear(); | 960 device_property_changes_map_.clear(); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1330 | 1349 |
| 1331 number_of_frames_provided_ = 0; | 1350 number_of_frames_provided_ = 0; |
| 1332 glitches_detected_ = 0; | 1351 glitches_detected_ = 0; |
| 1333 last_sample_time_ = 0; | 1352 last_sample_time_ = 0; |
| 1334 last_number_of_frames_ = 0; | 1353 last_number_of_frames_ = 0; |
| 1335 total_lost_frames_ = 0; | 1354 total_lost_frames_ = 0; |
| 1336 largest_glitch_frames_ = 0; | 1355 largest_glitch_frames_ = 0; |
| 1337 } | 1356 } |
| 1338 | 1357 |
| 1339 } // namespace media | 1358 } // namespace media |
| OLD | NEW |