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/command_line.h" | 9 #include "base/command_line.h" |
9 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.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" |
17 #include "media/audio/virtual_audio_input_stream.h" | 18 #include "media/audio/virtual_audio_input_stream.h" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 params.format() == AudioParameters::AUDIO_FAKE || | 116 params.format() == AudioParameters::AUDIO_FAKE || |
116 !HasAudioOutputDevices(); | 117 !HasAudioOutputDevices(); |
117 | 118 |
118 AudioOutputStream* stream = NULL; | 119 AudioOutputStream* stream = NULL; |
119 if (virtual_audio_input_stream_) { | 120 if (virtual_audio_input_stream_) { |
120 #if defined(OS_IOS) | 121 #if defined(OS_IOS) |
121 // We do not currently support iOS. It does not link. | 122 // We do not currently support iOS. It does not link. |
122 NOTIMPLEMENTED(); | 123 NOTIMPLEMENTED(); |
123 return NULL; | 124 return NULL; |
124 #else | 125 #else |
125 stream = VirtualAudioOutputStream::MakeStream(this, params, message_loop_, | 126 stream = new VirtualAudioOutputStream( |
126 virtual_audio_input_stream_); | 127 params, message_loop_, virtual_audio_input_stream_, |
| 128 base::Bind(&AudioManagerBase::ReleaseVirtualOutputStream, |
| 129 base::Unretained(this))); |
127 #endif | 130 #endif |
128 } else if (audio_output_disabled) { | 131 } else if (audio_output_disabled) { |
129 stream = FakeAudioOutputStream::MakeFakeStream(this, params); | 132 stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
130 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 133 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
131 stream = MakeLinearOutputStream(params); | 134 stream = MakeLinearOutputStream(params); |
132 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 135 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
133 stream = MakeLowLatencyOutputStream(params); | 136 stream = MakeLowLatencyOutputStream(params); |
134 } | 137 } |
135 | 138 |
136 if (stream) | 139 if (stream) |
(...skipping 24 matching lines...) Expand all Loading... |
161 AudioInputStream* stream = NULL; | 164 AudioInputStream* stream = NULL; |
162 if (params.format() == AudioParameters::AUDIO_VIRTUAL) { | 165 if (params.format() == AudioParameters::AUDIO_VIRTUAL) { |
163 #if defined(OS_IOS) | 166 #if defined(OS_IOS) |
164 // We do not currently support iOS. | 167 // We do not currently support iOS. |
165 NOTIMPLEMENTED(); | 168 NOTIMPLEMENTED(); |
166 return NULL; | 169 return NULL; |
167 #else | 170 #else |
168 // TODO(justinlin): Currently, audio mirroring will only work for the first | 171 // TODO(justinlin): Currently, audio mirroring will only work for the first |
169 // request. Subsequent requests will not get audio. | 172 // request. Subsequent requests will not get audio. |
170 if (!virtual_audio_input_stream_) { | 173 if (!virtual_audio_input_stream_) { |
171 virtual_audio_input_stream_ = | 174 virtual_audio_input_stream_ = new VirtualAudioInputStream( |
172 VirtualAudioInputStream::MakeStream(this, params, message_loop_); | 175 params, message_loop_, |
| 176 base::Bind(&AudioManagerBase::ReleaseVirtualInputStream, |
| 177 base::Unretained(this))); |
173 stream = virtual_audio_input_stream_; | 178 stream = virtual_audio_input_stream_; |
174 DVLOG(1) << "Virtual audio input stream created."; | 179 DVLOG(1) << "Virtual audio input stream created."; |
175 | 180 |
176 // Make all current output streams recreate themselves as | 181 // Make all current output streams recreate themselves as |
177 // VirtualAudioOutputStreams that will attach to the above | 182 // VirtualAudioOutputStreams that will attach to the above |
178 // VirtualAudioInputStream. | 183 // VirtualAudioInputStream. |
179 NotifyAllOutputDeviceChangeListeners(); | 184 NotifyAllOutputDeviceChangeListeners(); |
180 } else { | 185 } else { |
181 stream = NULL; | 186 stream = NULL; |
182 } | 187 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 292 |
288 void AudioManagerBase::GetAudioInputDeviceNames( | 293 void AudioManagerBase::GetAudioInputDeviceNames( |
289 media::AudioDeviceNames* device_names) { | 294 media::AudioDeviceNames* device_names) { |
290 } | 295 } |
291 | 296 |
292 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { | 297 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
293 DCHECK(stream); | 298 DCHECK(stream); |
294 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. | 299 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
295 // For example, pass the ownership to AudioManager so it can delete the | 300 // For example, pass the ownership to AudioManager so it can delete the |
296 // streams. | 301 // streams. |
297 num_output_streams_--; | 302 --num_output_streams_; |
298 delete stream; | 303 delete stream; |
299 } | 304 } |
300 | 305 |
301 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { | 306 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
302 DCHECK(stream); | 307 DCHECK(stream); |
303 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. | 308 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
304 | 309 --num_input_streams_; |
305 if (virtual_audio_input_stream_ == stream) { | |
306 DVLOG(1) << "Virtual audio input stream stopping."; | |
307 virtual_audio_input_stream_->Stop(); | |
308 virtual_audio_input_stream_ = NULL; | |
309 | |
310 // Make all VirtualAudioOutputStreams unregister from the | |
311 // VirtualAudioInputStream and recreate themselves as regular audio streams | |
312 // to return sound to hardware. | |
313 NotifyAllOutputDeviceChangeListeners(); | |
314 } | |
315 | |
316 num_input_streams_--; | |
317 delete stream; | 310 delete stream; |
318 } | 311 } |
319 | 312 |
| 313 void AudioManagerBase::ReleaseVirtualInputStream( |
| 314 VirtualAudioInputStream* stream) { |
| 315 DCHECK_EQ(virtual_audio_input_stream_, stream); |
| 316 |
| 317 virtual_audio_input_stream_ = NULL; |
| 318 |
| 319 // Notify listeners to re-create output streams. This will cause all |
| 320 // outstanding VirtualAudioOutputStreams pointing at the |
| 321 // VirtualAudioInputStream to be closed and destroyed. Once this has |
| 322 // happened, there will be no other references to the input stream, and it |
| 323 // will then be safe to delete it. |
| 324 NotifyAllOutputDeviceChangeListeners(); |
| 325 |
| 326 ReleaseInputStream(stream); |
| 327 } |
| 328 |
| 329 void AudioManagerBase::ReleaseVirtualOutputStream( |
| 330 VirtualAudioOutputStream* stream) { |
| 331 ReleaseOutputStream(stream); |
| 332 } |
| 333 |
320 void AudioManagerBase::IncreaseActiveInputStreamCount() { | 334 void AudioManagerBase::IncreaseActiveInputStreamCount() { |
321 base::AtomicRefCountInc(&num_active_input_streams_); | 335 base::AtomicRefCountInc(&num_active_input_streams_); |
322 } | 336 } |
323 | 337 |
324 void AudioManagerBase::DecreaseActiveInputStreamCount() { | 338 void AudioManagerBase::DecreaseActiveInputStreamCount() { |
325 DCHECK(IsRecordingInProcess()); | 339 DCHECK(IsRecordingInProcess()); |
326 base::AtomicRefCountDec(&num_active_input_streams_); | 340 base::AtomicRefCountDec(&num_active_input_streams_); |
327 } | 341 } |
328 | 342 |
329 bool AudioManagerBase::IsRecordingInProcess() { | 343 bool AudioManagerBase::IsRecordingInProcess() { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 output_listeners_.RemoveObserver(listener); | 423 output_listeners_.RemoveObserver(listener); |
410 } | 424 } |
411 | 425 |
412 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { | 426 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { |
413 DCHECK(message_loop_->BelongsToCurrentThread()); | 427 DCHECK(message_loop_->BelongsToCurrentThread()); |
414 DVLOG(1) << "Firing OnDeviceChange() notifications."; | 428 DVLOG(1) << "Firing OnDeviceChange() notifications."; |
415 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); | 429 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); |
416 } | 430 } |
417 | 431 |
418 } // namespace media | 432 } // namespace media |
OLD | NEW |