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/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
10 #include "base/string_util.h" | |
10 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
11 #include "media/audio/audio_output_dispatcher_impl.h" | 12 #include "media/audio/audio_output_dispatcher_impl.h" |
12 #include "media/audio/audio_output_proxy.h" | 13 #include "media/audio/audio_output_proxy.h" |
13 #include "media/audio/audio_output_resampler.h" | 14 #include "media/audio/audio_output_resampler.h" |
14 #include "media/audio/audio_util.h" | 15 #include "media/audio/audio_util.h" |
15 #include "media/audio/fake_audio_input_stream.h" | 16 #include "media/audio/fake_audio_input_stream.h" |
16 #include "media/audio/fake_audio_output_stream.h" | 17 #include "media/audio/fake_audio_output_stream.h" |
18 #include "media/audio/virtual_audio_input_stream.h" | |
19 #include "media/audio/virtual_audio_output_stream.h" | |
17 #include "media/base/media_switches.h" | 20 #include "media/base/media_switches.h" |
18 | 21 |
19 // TODO(dalecurtis): Temporarily disabled while switching pipeline to use float, | 22 // TODO(dalecurtis): Temporarily disabled while switching pipeline to use float, |
20 // http://crbug.com/114700 | 23 // http://crbug.com/114700 |
21 #if defined(ENABLE_AUDIO_MIXER) | 24 #if defined(ENABLE_AUDIO_MIXER) |
22 #include "media/audio/audio_output_mixer.h" | 25 #include "media/audio/audio_output_mixer.h" |
23 #endif | 26 #endif |
24 | 27 |
25 namespace media { | 28 namespace media { |
26 | 29 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 return NULL; | 96 return NULL; |
94 } | 97 } |
95 | 98 |
96 // If there are no audio output devices we should use a FakeAudioOutputStream | 99 // If there are no audio output devices we should use a FakeAudioOutputStream |
97 // to ensure video playback continues to work. | 100 // to ensure video playback continues to work. |
98 bool audio_output_disabled = | 101 bool audio_output_disabled = |
99 params.format() == AudioParameters::AUDIO_FAKE || | 102 params.format() == AudioParameters::AUDIO_FAKE || |
100 !HasAudioOutputDevices(); | 103 !HasAudioOutputDevices(); |
101 | 104 |
102 AudioOutputStream* stream = NULL; | 105 AudioOutputStream* stream = NULL; |
106 | |
107 // Temp hack to use virtual device for everything except webRTC output. | |
108 bool use_virtual_device = params.sample_rate() != 48000; | |
109 | |
110 if (use_virtual_device) { | |
111 stream = VirtualAudioOutputStream::MakeStream(this, params); | |
112 audio_thread_->message_loop()->PostTask(FROM_HERE, base::Bind( | |
DaleCurtis
2012/11/07 23:34:17
I believe this is already on the audio thread, no?
justinlin
2012/11/20 08:56:10
Done.
| |
113 &AudioManagerBase::RegisterVirtualAudioOutputStream, | |
114 base::Unretained(this), stream)); | |
115 return stream; | |
116 } | |
117 | |
103 if (audio_output_disabled) { | 118 if (audio_output_disabled) { |
104 stream = FakeAudioOutputStream::MakeFakeStream(this, params); | 119 stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
105 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 120 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
106 stream = MakeLinearOutputStream(params); | 121 stream = MakeLinearOutputStream(params); |
107 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 122 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
108 stream = MakeLowLatencyOutputStream(params); | 123 stream = MakeLowLatencyOutputStream(params); |
109 } | 124 } |
110 | 125 |
111 if (stream) | 126 return stream; |
112 ++num_output_streams_; | 127 } |
113 | 128 |
114 return stream; | 129 void AudioManagerBase::RegisterVirtualAudioOutputStream( |
130 AudioOutputStream* stream) { | |
131 virtual_audio_output_streams_.insert(stream); | |
132 } | |
133 | |
134 void AudioManagerBase::UnregisterVirtualAudioOutputStream( | |
135 AudioOutputStream* stream) { | |
136 virtual_audio_output_streams_.erase(stream); | |
137 } | |
138 | |
139 AudioManagerBase::AudioOutputStreamList | |
140 AudioManagerBase::GetVirtualAudioOutputStreams() { | |
141 return virtual_audio_output_streams_; | |
115 } | 142 } |
116 | 143 |
117 AudioInputStream* AudioManagerBase::MakeAudioInputStream( | 144 AudioInputStream* AudioManagerBase::MakeAudioInputStream( |
118 const AudioParameters& params, const std::string& device_id) { | 145 const AudioParameters& params, const std::string& device_id) { |
119 if (!params.IsValid() || (params.channels() > kMaxInputChannels) || | 146 if (!params.IsValid() || (params.channels() > kMaxInputChannels) || |
120 device_id.empty()) { | 147 device_id.empty()) { |
121 DLOG(ERROR) << "Audio parameters are invalid for device " << device_id; | 148 DLOG(ERROR) << "Audio parameters are invalid for device " << device_id; |
122 return NULL; | 149 return NULL; |
123 } | 150 } |
124 | 151 |
125 if (num_input_streams_ >= max_num_input_streams_) { | 152 if (num_input_streams_ >= max_num_input_streams_) { |
126 DLOG(ERROR) << "Number of opened input audio streams " | 153 DLOG(ERROR) << "Number of opened input audio streams " |
127 << num_input_streams_ | 154 << num_input_streams_ |
128 << " exceed the max allowed number " << max_num_input_streams_; | 155 << " exceed the max allowed number " << max_num_input_streams_; |
129 return NULL; | 156 return NULL; |
130 } | 157 } |
131 | 158 |
159 // TODO(justinlin): Bah! Linking issues with content::, fix this later. | |
160 const std::string kMediaStreamTabDeviceScheme = "virtual://"; | |
161 | |
132 AudioInputStream* stream = NULL; | 162 AudioInputStream* stream = NULL; |
133 if (params.format() == AudioParameters::AUDIO_FAKE) { | 163 if (StartsWithASCII(device_id, |
164 kMediaStreamTabDeviceScheme, true)) { | |
165 stream = VirtualAudioInputStream::MakeStream(this, params); | |
166 } else if (params.format() == AudioParameters::AUDIO_FAKE) { | |
134 stream = FakeAudioInputStream::MakeFakeStream(this, params); | 167 stream = FakeAudioInputStream::MakeFakeStream(this, params); |
135 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 168 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
136 stream = MakeLinearInputStream(params, device_id); | 169 stream = MakeLinearInputStream(params, device_id); |
137 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 170 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
138 stream = MakeLowLatencyInputStream(params, device_id); | 171 stream = MakeLowLatencyInputStream(params, device_id); |
139 } | 172 } |
140 | 173 |
141 if (stream) | 174 if (stream) |
142 ++num_input_streams_; | 175 ++num_input_streams_; |
143 | 176 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 | 263 |
231 void AudioManagerBase::GetAudioInputDeviceNames( | 264 void AudioManagerBase::GetAudioInputDeviceNames( |
232 media::AudioDeviceNames* device_names) { | 265 media::AudioDeviceNames* device_names) { |
233 } | 266 } |
234 | 267 |
235 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { | 268 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
236 DCHECK(stream); | 269 DCHECK(stream); |
237 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. | 270 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
238 // For example, pass the ownership to AudioManager so it can delete the | 271 // For example, pass the ownership to AudioManager so it can delete the |
239 // streams. | 272 // streams. |
273 | |
274 audio_thread_->message_loop()->PostTask(FROM_HERE, base::Bind( | |
DaleCurtis
2012/11/07 23:34:17
Ditto.
justinlin
2012/11/20 08:56:10
Done.
| |
275 &AudioManagerBase::UnregisterVirtualAudioOutputStream, | |
276 base::Unretained(this), stream)); | |
277 | |
240 num_output_streams_--; | 278 num_output_streams_--; |
241 delete stream; | 279 delete stream; |
242 } | 280 } |
243 | 281 |
244 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { | 282 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
245 DCHECK(stream); | 283 DCHECK(stream); |
246 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. | 284 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
247 num_input_streams_--; | 285 num_input_streams_--; |
248 delete stream; | 286 delete stream; |
249 } | 287 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 output_listeners_.RemoveObserver(listener); | 378 output_listeners_.RemoveObserver(listener); |
341 } | 379 } |
342 | 380 |
343 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { | 381 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { |
344 DCHECK(message_loop_->BelongsToCurrentThread()); | 382 DCHECK(message_loop_->BelongsToCurrentThread()); |
345 DVLOG(1) << "Firing OnDeviceChange() notifications."; | 383 DVLOG(1) << "Firing OnDeviceChange() notifications."; |
346 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); | 384 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); |
347 } | 385 } |
348 | 386 |
349 } // namespace media | 387 } // namespace media |
OLD | NEW |