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_manager_base.h" | 5 #include "media/audio/audio_manager_base.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/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 static const int kMaxInputChannels = 2; | 31 static const int kMaxInputChannels = 2; |
32 | 32 |
33 const char AudioManagerBase::kDefaultDeviceName[] = "Default"; | 33 const char AudioManagerBase::kDefaultDeviceName[] = "Default"; |
34 const char AudioManagerBase::kDefaultDeviceId[] = "default"; | 34 const char AudioManagerBase::kDefaultDeviceId[] = "default"; |
35 const char AudioManagerBase::kLoopbackInputDeviceId[] = "loopback"; | 35 const char AudioManagerBase::kLoopbackInputDeviceId[] = "loopback"; |
36 | 36 |
37 struct AudioManagerBase::DispatcherParams { | 37 struct AudioManagerBase::DispatcherParams { |
38 DispatcherParams(const AudioParameters& input, | 38 DispatcherParams(const AudioParameters& input, |
39 const AudioParameters& output, | 39 const AudioParameters& output, |
40 const std::string& output_device_id, | 40 const std::string& output_device_id) |
41 const std::string& input_device_id) | |
42 : input_params(input), | 41 : input_params(input), |
43 output_params(output), | 42 output_params(output) {} |
44 input_device_id(input_device_id), | |
45 output_device_id(output_device_id) {} | |
46 ~DispatcherParams() {} | 43 ~DispatcherParams() {} |
47 | 44 |
48 const AudioParameters input_params; | 45 const AudioParameters input_params; |
49 const AudioParameters output_params; | 46 const AudioParameters output_params; |
50 const std::string input_device_id; | |
51 const std::string output_device_id; | 47 const std::string output_device_id; |
52 scoped_refptr<AudioOutputDispatcher> dispatcher; | 48 scoped_refptr<AudioOutputDispatcher> dispatcher; |
53 | 49 |
54 private: | 50 private: |
55 DISALLOW_COPY_AND_ASSIGN(DispatcherParams); | 51 DISALLOW_COPY_AND_ASSIGN(DispatcherParams); |
56 }; | 52 }; |
57 | 53 |
58 class AudioManagerBase::CompareByParams { | 54 class AudioManagerBase::CompareByParams { |
59 public: | 55 public: |
60 explicit CompareByParams(const DispatcherParams* dispatcher) | 56 explicit CompareByParams(const DispatcherParams* dispatcher) |
61 : dispatcher_(dispatcher) {} | 57 : dispatcher_(dispatcher) {} |
62 bool operator()(DispatcherParams* dispatcher_in) const { | 58 bool operator()(DispatcherParams* dispatcher_in) const { |
63 // We will reuse the existing dispatcher when: | 59 // We will reuse the existing dispatcher when: |
64 // 1) Unified IO is not used, input_params and output_params of the | 60 // 1) Unified IO is not used, input_params and output_params of the |
65 // existing dispatcher are the same as the requested dispatcher. | 61 // existing dispatcher are the same as the requested dispatcher. |
66 // 2) Unified IO is used, input_params, output_params and input_device_id | 62 // 2) Unified IO is used, input_params and output_params of the existing |
67 // of the existing dispatcher are the same as the request dispatcher. | 63 // dispatcher are the same as the request dispatcher. |
68 return (dispatcher_->input_params == dispatcher_in->input_params && | 64 return (dispatcher_->input_params == dispatcher_in->input_params && |
69 dispatcher_->output_params == dispatcher_in->output_params && | 65 dispatcher_->output_params == dispatcher_in->output_params && |
70 dispatcher_->output_device_id == dispatcher_in->output_device_id && | 66 dispatcher_->output_device_id == dispatcher_in->output_device_id); |
71 (!dispatcher_->input_params.input_channels() || | |
72 dispatcher_->input_device_id == dispatcher_in->input_device_id)); | |
73 } | 67 } |
74 | 68 |
75 private: | 69 private: |
76 const DispatcherParams* dispatcher_; | 70 const DispatcherParams* dispatcher_; |
77 }; | 71 }; |
78 | 72 |
79 AudioManagerBase::AudioManagerBase(AudioLogFactory* audio_log_factory) | 73 AudioManagerBase::AudioManagerBase(AudioLogFactory* audio_log_factory) |
80 : max_num_output_streams_(kDefaultMaxOutputStreams), | 74 : max_num_output_streams_(kDefaultMaxOutputStreams), |
81 max_num_input_streams_(kDefaultMaxInputStreams), | 75 max_num_input_streams_(kDefaultMaxInputStreams), |
82 num_output_streams_(0), | 76 num_output_streams_(0), |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 AudioManagerBase::GetWorkerTaskRunner() { | 126 AudioManagerBase::GetWorkerTaskRunner() { |
133 // Lazily start the worker thread. | 127 // Lazily start the worker thread. |
134 if (!audio_thread_.IsRunning()) | 128 if (!audio_thread_.IsRunning()) |
135 CHECK(audio_thread_.Start()); | 129 CHECK(audio_thread_.Start()); |
136 | 130 |
137 return audio_thread_.message_loop_proxy(); | 131 return audio_thread_.message_loop_proxy(); |
138 } | 132 } |
139 | 133 |
140 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( | 134 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
141 const AudioParameters& params, | 135 const AudioParameters& params, |
142 const std::string& device_id, | 136 const std::string& device_id) { |
143 const std::string& input_device_id) { | |
144 // TODO(miu): Fix ~50 call points across several unit test modules to call | 137 // TODO(miu): Fix ~50 call points across several unit test modules to call |
145 // this method on the audio thread, then uncomment the following: | 138 // this method on the audio thread, then uncomment the following: |
146 // DCHECK(task_runner_->BelongsToCurrentThread()); | 139 // DCHECK(task_runner_->BelongsToCurrentThread()); |
147 | 140 |
148 if (!params.IsValid()) { | 141 if (!params.IsValid()) { |
149 DLOG(ERROR) << "Audio parameters are invalid"; | 142 DLOG(ERROR) << "Audio parameters are invalid"; |
150 return NULL; | 143 return NULL; |
151 } | 144 } |
152 | 145 |
153 // Limit the number of audio streams opened. This is to prevent using | 146 // Limit the number of audio streams opened. This is to prevent using |
154 // excessive resources for a large number of audio streams. More | 147 // excessive resources for a large number of audio streams. More |
155 // importantly it prevents instability on certain systems. | 148 // importantly it prevents instability on certain systems. |
156 // See bug: http://crbug.com/30242. | 149 // See bug: http://crbug.com/30242. |
157 if (num_output_streams_ >= max_num_output_streams_) { | 150 if (num_output_streams_ >= max_num_output_streams_) { |
158 DLOG(ERROR) << "Number of opened output audio streams " | 151 DLOG(ERROR) << "Number of opened output audio streams " |
159 << num_output_streams_ | 152 << num_output_streams_ |
160 << " exceed the max allowed number " | 153 << " exceed the max allowed number " |
161 << max_num_output_streams_; | 154 << max_num_output_streams_; |
162 return NULL; | 155 return NULL; |
163 } | 156 } |
164 | 157 |
165 AudioOutputStream* stream; | 158 AudioOutputStream* stream; |
166 switch (params.format()) { | 159 switch (params.format()) { |
167 case AudioParameters::AUDIO_PCM_LINEAR: | 160 case AudioParameters::AUDIO_PCM_LINEAR: |
168 DCHECK(device_id.empty()) | 161 DCHECK(device_id.empty()) |
169 << "AUDIO_PCM_LINEAR supports only the default device."; | 162 << "AUDIO_PCM_LINEAR supports only the default device."; |
170 stream = MakeLinearOutputStream(params); | 163 stream = MakeLinearOutputStream(params); |
171 break; | 164 break; |
172 case AudioParameters::AUDIO_PCM_LOW_LATENCY: | 165 case AudioParameters::AUDIO_PCM_LOW_LATENCY: |
173 stream = MakeLowLatencyOutputStream(params, device_id, input_device_id); | 166 stream = MakeLowLatencyOutputStream(params, device_id); |
174 break; | 167 break; |
175 case AudioParameters::AUDIO_FAKE: | 168 case AudioParameters::AUDIO_FAKE: |
176 stream = FakeAudioOutputStream::MakeFakeStream(this, params); | 169 stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
177 break; | 170 break; |
178 default: | 171 default: |
179 stream = NULL; | 172 stream = NULL; |
180 break; | 173 break; |
181 } | 174 } |
182 | 175 |
183 if (stream) { | 176 if (stream) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 | 218 |
226 if (stream) { | 219 if (stream) { |
227 ++num_input_streams_; | 220 ++num_input_streams_; |
228 } | 221 } |
229 | 222 |
230 return stream; | 223 return stream; |
231 } | 224 } |
232 | 225 |
233 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( | 226 AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( |
234 const AudioParameters& params, | 227 const AudioParameters& params, |
235 const std::string& device_id, | 228 const std::string& device_id) { |
236 const std::string& input_device_id) { | |
237 DCHECK(task_runner_->BelongsToCurrentThread()); | 229 DCHECK(task_runner_->BelongsToCurrentThread()); |
238 | 230 |
239 // If the caller supplied an empty device id to select the default device, | 231 // If the caller supplied an empty device id to select the default device, |
240 // we fetch the actual device id of the default device so that the lookup | 232 // we fetch the actual device id of the default device so that the lookup |
241 // will find the correct device regardless of whether it was opened as | 233 // will find the correct device regardless of whether it was opened as |
242 // "default" or via the specific id. | 234 // "default" or via the specific id. |
243 // NOTE: Implementations that don't yet support opening non-default output | 235 // NOTE: Implementations that don't yet support opening non-default output |
244 // devices may return an empty string from GetDefaultOutputDeviceID(). | 236 // devices may return an empty string from GetDefaultOutputDeviceID(). |
245 std::string output_device_id = device_id.empty() ? | 237 std::string output_device_id = device_id.empty() ? |
246 GetDefaultOutputDeviceID() : device_id; | 238 GetDefaultOutputDeviceID() : device_id; |
(...skipping 19 matching lines...) Expand all Loading... |
266 | 258 |
267 // Tell the AudioManager to create a fake output device. | 259 // Tell the AudioManager to create a fake output device. |
268 output_params = AudioParameters( | 260 output_params = AudioParameters( |
269 AudioParameters::AUDIO_FAKE, params.channel_layout(), | 261 AudioParameters::AUDIO_FAKE, params.channel_layout(), |
270 params.sample_rate(), params.bits_per_sample(), | 262 params.sample_rate(), params.bits_per_sample(), |
271 params.frames_per_buffer()); | 263 params.frames_per_buffer()); |
272 } | 264 } |
273 } | 265 } |
274 | 266 |
275 DispatcherParams* dispatcher_params = | 267 DispatcherParams* dispatcher_params = |
276 new DispatcherParams(params, output_params, output_device_id, | 268 new DispatcherParams(params, output_params, output_device_id); |
277 input_device_id); | |
278 | 269 |
279 AudioOutputDispatchers::iterator it = | 270 AudioOutputDispatchers::iterator it = |
280 std::find_if(output_dispatchers_.begin(), output_dispatchers_.end(), | 271 std::find_if(output_dispatchers_.begin(), output_dispatchers_.end(), |
281 CompareByParams(dispatcher_params)); | 272 CompareByParams(dispatcher_params)); |
282 if (it != output_dispatchers_.end()) { | 273 if (it != output_dispatchers_.end()) { |
283 delete dispatcher_params; | 274 delete dispatcher_params; |
284 return new AudioOutputProxy((*it)->dispatcher.get()); | 275 return new AudioOutputProxy((*it)->dispatcher.get()); |
285 } | 276 } |
286 | 277 |
287 const base::TimeDelta kCloseDelay = | 278 const base::TimeDelta kCloseDelay = |
288 base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds); | 279 base::TimeDelta::FromSeconds(kStreamCloseDelaySeconds); |
289 scoped_refptr<AudioOutputDispatcher> dispatcher; | 280 scoped_refptr<AudioOutputDispatcher> dispatcher; |
290 if (output_params.format() != AudioParameters::AUDIO_FAKE) { | 281 if (output_params.format() != AudioParameters::AUDIO_FAKE) { |
291 dispatcher = new AudioOutputResampler(this, params, output_params, | 282 dispatcher = new AudioOutputResampler(this, params, output_params, |
292 output_device_id, input_device_id, | 283 output_device_id, |
293 kCloseDelay); | 284 kCloseDelay); |
294 } else { | 285 } else { |
295 dispatcher = new AudioOutputDispatcherImpl(this, output_params, | 286 dispatcher = new AudioOutputDispatcherImpl(this, output_params, |
296 output_device_id, | 287 output_device_id, |
297 input_device_id, kCloseDelay); | 288 kCloseDelay); |
298 } | 289 } |
299 | 290 |
300 dispatcher_params->dispatcher = dispatcher; | 291 dispatcher_params->dispatcher = dispatcher; |
301 output_dispatchers_.push_back(dispatcher_params); | 292 output_dispatchers_.push_back(dispatcher_params); |
302 return new AudioOutputProxy(dispatcher.get()); | 293 return new AudioOutputProxy(dispatcher.get()); |
303 } | 294 } |
304 | 295 |
305 void AudioManagerBase::ShowAudioInputSettings() { | 296 void AudioManagerBase::ShowAudioInputSettings() { |
306 } | 297 } |
307 | 298 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 (*it)->dispatcher->CloseStreamsForWedgeFix(); | 436 (*it)->dispatcher->CloseStreamsForWedgeFix(); |
446 } | 437 } |
447 for (AudioOutputDispatchers::iterator it = output_dispatchers_.begin(); | 438 for (AudioOutputDispatchers::iterator it = output_dispatchers_.begin(); |
448 it != output_dispatchers_.end(); ++it) { | 439 it != output_dispatchers_.end(); ++it) { |
449 (*it)->dispatcher->RestartStreamsForWedgeFix(); | 440 (*it)->dispatcher->RestartStreamsForWedgeFix(); |
450 } | 441 } |
451 #endif | 442 #endif |
452 } | 443 } |
453 | 444 |
454 } // namespace media | 445 } // namespace media |
OLD | NEW |