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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 if (!streams_opened_ && | 181 if (!streams_opened_ && |
182 output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 182 output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
183 UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false); | 183 UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false); |
184 } | 184 } |
185 streams_opened_ = true; | 185 streams_opened_ = true; |
186 return true; | 186 return true; |
187 } | 187 } |
188 | 188 |
189 // If we've already tried to open the stream in high latency mode or we've | 189 // If we've already tried to open the stream in high latency mode or we've |
190 // successfully opened a stream previously, there's nothing more to be done. | 190 // successfully opened a stream previously, there's nothing more to be done. |
191 if (output_params_.format() == AudioParameters::AUDIO_PCM_LINEAR || | 191 if (output_params_.format() != AudioParameters::AUDIO_PCM_LOW_LATENCY || |
192 streams_opened_ || !callbacks_.empty()) { | 192 streams_opened_ || !callbacks_.empty()) { |
193 return false; | 193 return false; |
194 } | 194 } |
195 | 195 |
196 DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); | 196 DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); |
197 | 197 |
198 if (CommandLine::ForCurrentProcess()->HasSwitch( | 198 if (CommandLine::ForCurrentProcess()->HasSwitch( |
199 switches::kDisableAudioFallback)) { | 199 switches::kDisableAudioFallback)) { |
200 LOG(ERROR) << "Open failed and automatic fallback to high latency audio " | 200 LOG(ERROR) << "Open failed and automatic fallback to high latency audio " |
201 << "path is disabled, aborting."; | 201 << "path is disabled, aborting."; |
202 return false; | 202 return false; |
203 } | 203 } |
204 | 204 |
205 DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling " | 205 DLOG(ERROR) << "Unable to open audio device in low latency mode. Falling " |
206 << "back to high latency audio output."; | 206 << "back to high latency audio output."; |
207 | 207 |
208 // Record UMA statistics about the hardware which triggered the failure so | 208 // Record UMA statistics about the hardware which triggered the failure so |
209 // we can debug and triage later. | 209 // we can debug and triage later. |
210 RecordFallbackStats(output_params_); | 210 RecordFallbackStats(output_params_); |
211 output_params_ = SetupFallbackParams(params_, output_params_); | 211 output_params_ = SetupFallbackParams(params_, output_params_); |
212 Initialize(); | 212 Initialize(); |
| 213 if (dispatcher_->OpenStream()) { |
| 214 streams_opened_ = true; |
| 215 return true; |
| 216 } |
213 | 217 |
214 // Retry, if this fails, there's nothing left to do but report the error back. | 218 DLOG(ERROR) << "Unable to open audio device in high latency mode. Falling " |
215 return dispatcher_->OpenStream(); | 219 << "back to fake audio output."; |
| 220 |
| 221 // Finally fall back to a fake audio output device. |
| 222 output_params_.Reset( |
| 223 AudioParameters::AUDIO_FAKE, params_.channel_layout(), |
| 224 params_.input_channels(), params_.sample_rate(), |
| 225 params_.bits_per_sample(), params_.frames_per_buffer()); |
| 226 Initialize(); |
| 227 if (dispatcher_->OpenStream()) { |
| 228 streams_opened_ = true; |
| 229 return true; |
| 230 } |
| 231 |
| 232 return false; |
216 } | 233 } |
217 | 234 |
218 bool AudioOutputResampler::StartStream( | 235 bool AudioOutputResampler::StartStream( |
219 AudioOutputStream::AudioSourceCallback* callback, | 236 AudioOutputStream::AudioSourceCallback* callback, |
220 AudioOutputProxy* stream_proxy) { | 237 AudioOutputProxy* stream_proxy) { |
221 DCHECK_EQ(MessageLoop::current(), message_loop_); | 238 DCHECK_EQ(MessageLoop::current(), message_loop_); |
222 | 239 |
223 OnMoreDataConverter* resampler_callback = NULL; | 240 OnMoreDataConverter* resampler_callback = NULL; |
224 CallbackMap::iterator it = callbacks_.find(stream_proxy); | 241 CallbackMap::iterator it = callbacks_.find(stream_proxy); |
225 if (it == callbacks_.end()) { | 242 if (it == callbacks_.end()) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 source_callback_->OnError(stream, code); | 382 source_callback_->OnError(stream, code); |
366 } | 383 } |
367 | 384 |
368 void OnMoreDataConverter::WaitTillDataReady() { | 385 void OnMoreDataConverter::WaitTillDataReady() { |
369 base::AutoLock auto_lock(source_lock_); | 386 base::AutoLock auto_lock(source_lock_); |
370 if (source_callback_) | 387 if (source_callback_) |
371 source_callback_->WaitTillDataReady(); | 388 source_callback_->WaitTillDataReady(); |
372 } | 389 } |
373 | 390 |
374 } // namespace media | 391 } // namespace media |
OLD | NEW |