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

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

Issue 2908073002: Make OS audio buffer size limits visible. (Closed)
Patch Set: Created 3 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
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 <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 23 matching lines...) Expand all
34 // Maximum number of output streams that can be open simultaneously. 34 // Maximum number of output streams that can be open simultaneously.
35 static const int kMaxOutputStreams = 50; 35 static const int kMaxOutputStreams = 50;
36 36
37 // Define bounds for for low-latency input and output streams. 37 // Define bounds for for low-latency input and output streams.
38 static const int kMinimumInputOutputBufferSize = 128; 38 static const int kMinimumInputOutputBufferSize = 128;
39 static const int kMaximumInputOutputBufferSize = 4096; 39 static const int kMaximumInputOutputBufferSize = 4096;
40 40
41 // Default sample-rate on most Apple hardware. 41 // Default sample-rate on most Apple hardware.
42 static const int kFallbackSampleRate = 44100; 42 static const int kFallbackSampleRate = 44100;
43 43
44 static int GetDefaultBufferSize(bool is_input, int sample_rate) {
45 // kMinimumInputOutputBufferSize is too small for the output side because
46 // CoreAudio can get into under-run if the renderer fails delivering data
47 // to the browser within the allowed time by the OS. The workaround is to
48 // use 256 samples as the default output buffer size for sample rates
49 // smaller than 96KHz.
50 // TODO(xians): Remove this workaround after WebAudio supports user defined
51 // buffer size. See https://github.com/WebAudio/web-audio-api/issues/348
52 // for details.
53 int buffer_size = is_input ? kMinimumInputOutputBufferSize
54 : 2 * kMinimumInputOutputBufferSize;
55 if (sample_rate > 48000) {
56 // The default buffer size is too small for higher sample rates and may lead
57 // to glitching. Adjust upwards by multiples of the default size.
58 if (sample_rate <= 96000)
59 buffer_size = 2 * kMinimumInputOutputBufferSize;
60 else if (sample_rate <= 192000)
61 buffer_size = 4 * kMinimumInputOutputBufferSize;
62 }
63 return buffer_size;
64 }
65
44 // Helper method to construct AudioObjectPropertyAddress structure given 66 // Helper method to construct AudioObjectPropertyAddress structure given
45 // property selector and scope. The property element is always set to 67 // property selector and scope. The property element is always set to
46 // kAudioObjectPropertyElementMaster. 68 // kAudioObjectPropertyElementMaster.
47 static AudioObjectPropertyAddress GetAudioObjectPropertyAddress( 69 static AudioObjectPropertyAddress GetAudioObjectPropertyAddress(
48 AudioObjectPropertySelector selector, 70 AudioObjectPropertySelector selector,
49 bool is_input) { 71 bool is_input) {
50 AudioObjectPropertyScope scope = is_input ? kAudioObjectPropertyScopeInput 72 AudioObjectPropertyScope scope = is_input ? kAudioObjectPropertyScopeInput
51 : kAudioObjectPropertyScopeOutput; 73 : kAudioObjectPropertyScopeOutput;
52 AudioObjectPropertyAddress property_address = { 74 AudioObjectPropertyAddress property_address = {
53 selector, scope, kAudioObjectPropertyElementMaster}; 75 selector, scope, kAudioObjectPropertyElementMaster};
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 const bool has_valid_input_params = input_params.IsValid(); 855 const bool has_valid_input_params = input_params.IsValid();
834 const int hardware_sample_rate = HardwareSampleRateForDevice(device); 856 const int hardware_sample_rate = HardwareSampleRateForDevice(device);
835 857
836 // Allow pass through buffer sizes. If concurrent input and output streams 858 // Allow pass through buffer sizes. If concurrent input and output streams
837 // exist, they will use the smallest buffer size amongst them. As such, each 859 // exist, they will use the smallest buffer size amongst them. As such, each
838 // stream must be able to FIFO requests appropriately when this happens. 860 // stream must be able to FIFO requests appropriately when this happens.
839 int buffer_size = ChooseBufferSize(false, hardware_sample_rate); 861 int buffer_size = ChooseBufferSize(false, hardware_sample_rate);
840 if (has_valid_input_params) { 862 if (has_valid_input_params) {
841 buffer_size = 863 buffer_size =
842 std::min(kMaximumInputOutputBufferSize, 864 std::min(kMaximumInputOutputBufferSize,
843 std::max(input_params.frames_per_buffer(), buffer_size)); 865 std::max(input_params.frames_per_buffer(),
866 GetMinimumAudioBufferSize(hardware_sample_rate)));
844 } 867 }
845 868
846 int hardware_channels; 869 int hardware_channels;
847 if (!GetDeviceChannels(device, AUElement::OUTPUT, &hardware_channels)) 870 if (!GetDeviceChannels(device, AUElement::OUTPUT, &hardware_channels))
848 hardware_channels = 2; 871 hardware_channels = 2;
849 872
850 // Use the input channel count and channel layout if possible. Let OSX take 873 // Use the input channel count and channel layout if possible. Let OSX take
851 // care of remapping the channels; this lets user specified channel layouts 874 // care of remapping the channels; this lets user specified channel layouts
852 // work correctly. 875 // work correctly.
853 int output_channels = input_params.channels(); 876 int output_channels = input_params.channels();
(...skipping 26 matching lines...) Expand all
880 current_output_device_ == new_output_device) { 903 current_output_device_ == new_output_device) {
881 return; 904 return;
882 } 905 }
883 906
884 current_sample_rate_ = new_sample_rate; 907 current_sample_rate_ = new_sample_rate;
885 current_output_device_ = new_output_device; 908 current_output_device_ = new_output_device;
886 NotifyAllOutputDeviceChangeListeners(); 909 NotifyAllOutputDeviceChangeListeners();
887 } 910 }
888 911
889 int AudioManagerMac::ChooseBufferSize(bool is_input, int sample_rate) { 912 int AudioManagerMac::ChooseBufferSize(bool is_input, int sample_rate) {
890 // kMinimumInputOutputBufferSize is too small for the output side because
891 // CoreAudio can get into under-run if the renderer fails delivering data
892 // to the browser within the allowed time by the OS. The workaround is to
893 // use 256 samples as the default output buffer size for sample rates
894 // smaller than 96KHz.
895 // TODO(xians): Remove this workaround after WebAudio supports user defined
896 // buffer size. See https://github.com/WebAudio/web-audio-api/issues/348
897 // for details.
898 int buffer_size = is_input ?
899 kMinimumInputOutputBufferSize : 2 * kMinimumInputOutputBufferSize;
900 const int user_buffer_size = GetUserBufferSize(); 913 const int user_buffer_size = GetUserBufferSize();
901 if (user_buffer_size) { 914 if (user_buffer_size)
902 buffer_size = user_buffer_size; 915 return user_buffer_size;
903 } else if (sample_rate > 48000) { 916 return GetDefaultBufferSize(is_input, sample_rate);
904 // The default buffer size is too small for higher sample rates and may lead
905 // to glitching. Adjust upwards by multiples of the default size.
906 if (sample_rate <= 96000)
907 buffer_size = 2 * kMinimumInputOutputBufferSize;
908 else if (sample_rate <= 192000)
909 buffer_size = 4 * kMinimumInputOutputBufferSize;
910 }
911
912 return buffer_size;
913 } 917 }
914 918
915 bool AudioManagerMac::IsSuspending() const { 919 bool AudioManagerMac::IsSuspending() const {
916 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 920 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
917 return power_observer_->IsSuspending(); 921 return power_observer_->IsSuspending();
918 } 922 }
919 923
920 bool AudioManagerMac::ShouldDeferStreamStart() const { 924 bool AudioManagerMac::ShouldDeferStreamStart() const {
921 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 925 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
922 return power_observer_->ShouldDeferStreamStart(); 926 return power_observer_->ShouldDeferStreamStart();
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 AudioManagerBase::ReleaseInputStream(stream); 1186 AudioManagerBase::ReleaseInputStream(stream);
1183 } 1187 }
1184 1188
1185 std::unique_ptr<AudioManager> CreateAudioManager( 1189 std::unique_ptr<AudioManager> CreateAudioManager(
1186 std::unique_ptr<AudioThread> audio_thread, 1190 std::unique_ptr<AudioThread> audio_thread,
1187 AudioLogFactory* audio_log_factory) { 1191 AudioLogFactory* audio_log_factory) {
1188 return base::MakeUnique<AudioManagerMac>(std::move(audio_thread), 1192 return base::MakeUnique<AudioManagerMac>(std::move(audio_thread),
1189 audio_log_factory); 1193 audio_log_factory);
1190 } 1194 }
1191 1195
1196 int AudioManager::GetMinimumAudioBufferSize(int sample_rate) {
1197 return GetDefaultBufferSize(false, sample_rate);
1198 }
1199
1200 int AudioManager::GetMaximumAudioBufferSize(int sample_rate) {
1201 return kMaximumInputOutputBufferSize;
1202 }
1203
1192 } // namespace media 1204 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698