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/audio_output_resampler.h" | 5 #include "media/audio/audio_output_resampler.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 UMA_HISTOGRAM_ENUMERATION( | 117 UMA_HISTOGRAM_ENUMERATION( |
118 "Media.FallbackHardwareAudioSamplesPerSecond", | 118 "Media.FallbackHardwareAudioSamplesPerSecond", |
119 asr, kUnexpectedAudioSampleRate); | 119 asr, kUnexpectedAudioSampleRate); |
120 } else { | 120 } else { |
121 UMA_HISTOGRAM_COUNTS( | 121 UMA_HISTOGRAM_COUNTS( |
122 "Media.FallbackHardwareAudioSamplesPerSecondUnexpected", | 122 "Media.FallbackHardwareAudioSamplesPerSecondUnexpected", |
123 output_params.sample_rate()); | 123 output_params.sample_rate()); |
124 } | 124 } |
125 } | 125 } |
126 | 126 |
| 127 // Only Windows has a high latency output driver that is not the same as the low |
| 128 // latency path. |
| 129 #if defined(OS_WIN) |
127 // Converts low latency based |output_params| into high latency appropriate | 130 // Converts low latency based |output_params| into high latency appropriate |
128 // output parameters in error situations. | 131 // output parameters in error situations. |
129 static AudioParameters SetupFallbackParams( | 132 static AudioParameters SetupFallbackParams( |
130 const AudioParameters& input_params, const AudioParameters& output_params) { | 133 const AudioParameters& input_params, const AudioParameters& output_params) { |
131 // Choose AudioParameters appropriate for opening the device in high latency | 134 // Choose AudioParameters appropriate for opening the device in high latency |
132 // mode. |kMinLowLatencyFrameSize| is arbitrarily based on Pepper Flash's | 135 // mode. |kMinLowLatencyFrameSize| is arbitrarily based on Pepper Flash's |
133 // MAXIMUM frame size for low latency. | 136 // MAXIMUM frame size for low latency. |
134 static const int kMinLowLatencyFrameSize = 2048; | 137 static const int kMinLowLatencyFrameSize = 2048; |
135 int frames_per_buffer = std::min( | 138 int frames_per_buffer = std::min( |
136 std::max(input_params.frames_per_buffer(), kMinLowLatencyFrameSize), | 139 std::max(input_params.frames_per_buffer(), kMinLowLatencyFrameSize), |
137 static_cast<int>( | 140 static_cast<int>( |
138 GetHighLatencyOutputBufferSize(input_params.sample_rate()))); | 141 GetHighLatencyOutputBufferSize(input_params.sample_rate()))); |
139 | 142 |
140 return AudioParameters( | 143 return AudioParameters( |
141 AudioParameters::AUDIO_PCM_LINEAR, input_params.channel_layout(), | 144 AudioParameters::AUDIO_PCM_LINEAR, input_params.channel_layout(), |
142 input_params.sample_rate(), input_params.bits_per_sample(), | 145 input_params.sample_rate(), input_params.bits_per_sample(), |
143 frames_per_buffer); | 146 frames_per_buffer); |
144 } | 147 } |
| 148 #endif |
145 | 149 |
146 AudioOutputResampler::AudioOutputResampler(AudioManager* audio_manager, | 150 AudioOutputResampler::AudioOutputResampler(AudioManager* audio_manager, |
147 const AudioParameters& input_params, | 151 const AudioParameters& input_params, |
148 const AudioParameters& output_params, | 152 const AudioParameters& output_params, |
149 const base::TimeDelta& close_delay) | 153 const base::TimeDelta& close_delay) |
150 : AudioOutputDispatcher(audio_manager, input_params), | 154 : AudioOutputDispatcher(audio_manager, input_params), |
151 close_delay_(close_delay), | 155 close_delay_(close_delay), |
152 output_params_(output_params), | 156 output_params_(output_params), |
153 streams_opened_(false) { | 157 streams_opened_(false) { |
154 DCHECK(input_params.IsValid()); | 158 DCHECK(input_params.IsValid()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 | 199 |
196 DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); | 200 DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); |
197 | 201 |
198 if (CommandLine::ForCurrentProcess()->HasSwitch( | 202 if (CommandLine::ForCurrentProcess()->HasSwitch( |
199 switches::kDisableAudioFallback)) { | 203 switches::kDisableAudioFallback)) { |
200 LOG(ERROR) << "Open failed and automatic fallback to high latency audio " | 204 LOG(ERROR) << "Open failed and automatic fallback to high latency audio " |
201 << "path is disabled, aborting."; | 205 << "path is disabled, aborting."; |
202 return false; | 206 return false; |
203 } | 207 } |
204 | 208 |
205 DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling " | |
206 << "back to high latency audio output."; | |
207 | |
208 // Record UMA statistics about the hardware which triggered the failure so | 209 // Record UMA statistics about the hardware which triggered the failure so |
209 // we can debug and triage later. | 210 // we can debug and triage later. |
210 RecordFallbackStats(output_params_); | 211 RecordFallbackStats(output_params_); |
| 212 |
| 213 // Only Windows has a high latency output driver that is not the same as the |
| 214 // low latency path. |
| 215 #if defined(OS_WIN) |
| 216 DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling " |
| 217 << "back to high latency audio output."; |
| 218 |
211 output_params_ = SetupFallbackParams(params_, output_params_); | 219 output_params_ = SetupFallbackParams(params_, output_params_); |
212 Initialize(); | 220 Initialize(); |
213 if (dispatcher_->OpenStream()) { | 221 if (dispatcher_->OpenStream()) { |
214 streams_opened_ = true; | 222 streams_opened_ = true; |
215 return true; | 223 return true; |
216 } | 224 } |
| 225 #endif |
217 | 226 |
218 DLOG(ERROR) << "Unable to open audio device in high latency mode. Falling " | 227 DLOG(ERROR) << "Unable to open audio device in high latency mode. Falling " |
219 << "back to fake audio output."; | 228 << "back to fake audio output."; |
220 | 229 |
221 // Finally fall back to a fake audio output device. | 230 // Finally fall back to a fake audio output device. |
222 output_params_.Reset( | 231 output_params_.Reset( |
223 AudioParameters::AUDIO_FAKE, params_.channel_layout(), | 232 AudioParameters::AUDIO_FAKE, params_.channel_layout(), |
224 params_.channels(), params_.input_channels(), params_.sample_rate(), | 233 params_.channels(), params_.input_channels(), params_.sample_rate(), |
225 params_.bits_per_sample(), params_.frames_per_buffer()); | 234 params_.bits_per_sample(), params_.frames_per_buffer()); |
226 Initialize(); | 235 Initialize(); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 source_callback_->OnError(stream); | 400 source_callback_->OnError(stream); |
392 } | 401 } |
393 | 402 |
394 void OnMoreDataConverter::WaitTillDataReady() { | 403 void OnMoreDataConverter::WaitTillDataReady() { |
395 base::AutoLock auto_lock(source_lock_); | 404 base::AutoLock auto_lock(source_lock_); |
396 if (source_callback_) | 405 if (source_callback_) |
397 source_callback_->WaitTillDataReady(); | 406 source_callback_->WaitTillDataReady(); |
398 } | 407 } |
399 | 408 |
400 } // namespace media | 409 } // namespace media |
OLD | NEW |