Chromium Code Reviews| 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 struct Adapter { |
|
DaleCurtis
2013/01/17 01:15:52
Why is this necessary? What was wrong with your or
miu
2013/01/17 05:33:55
Two things going on here:
1. Bind() needs to retu
DaleCurtis
2013/01/17 21:11:11
I still don't follow why the VirtualAudioOutputStr
miu
2013/01/17 22:44:11
Because VAOS is not always created/owned by AudioM
| |
| 126 virtual_audio_input_stream_); | 127 static void ReleaseVirtualOutputStream(AudioManagerBase* audio_manager, |
| 128 VirtualAudioOutputStream* stream) { | |
| 129 audio_manager->ReleaseOutputStream(stream); | |
| 130 } | |
| 131 }; | |
| 132 stream = new VirtualAudioOutputStream( | |
| 133 params, message_loop_, virtual_audio_input_stream_, | |
| 134 base::Bind(&Adapter::ReleaseVirtualOutputStream, | |
| 135 base::Unretained(this))); | |
| 127 #endif | 136 #endif |
| 128 } else if (audio_output_disabled) { | 137 } else if (audio_output_disabled) { |
| 129 stream = FakeAudioOutputStream::MakeFakeStream(this, params); | 138 stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
| 130 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 139 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
| 131 stream = MakeLinearOutputStream(params); | 140 stream = MakeLinearOutputStream(params); |
| 132 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 141 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 133 stream = MakeLowLatencyOutputStream(params); | 142 stream = MakeLowLatencyOutputStream(params); |
| 134 } | 143 } |
| 135 | 144 |
| 136 if (stream) | 145 if (stream) |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 161 AudioInputStream* stream = NULL; | 170 AudioInputStream* stream = NULL; |
| 162 if (params.format() == AudioParameters::AUDIO_VIRTUAL) { | 171 if (params.format() == AudioParameters::AUDIO_VIRTUAL) { |
| 163 #if defined(OS_IOS) | 172 #if defined(OS_IOS) |
| 164 // We do not currently support iOS. | 173 // We do not currently support iOS. |
| 165 NOTIMPLEMENTED(); | 174 NOTIMPLEMENTED(); |
| 166 return NULL; | 175 return NULL; |
| 167 #else | 176 #else |
| 168 // TODO(justinlin): Currently, audio mirroring will only work for the first | 177 // TODO(justinlin): Currently, audio mirroring will only work for the first |
| 169 // request. Subsequent requests will not get audio. | 178 // request. Subsequent requests will not get audio. |
| 170 if (!virtual_audio_input_stream_) { | 179 if (!virtual_audio_input_stream_) { |
| 171 virtual_audio_input_stream_ = | 180 virtual_audio_input_stream_ = new VirtualAudioInputStream( |
| 172 VirtualAudioInputStream::MakeStream(this, params, message_loop_); | 181 params, message_loop_, |
| 182 base::Bind(&AudioManagerBase::ReleaseVirtualInputStream, | |
| 183 base::Unretained(this))); | |
| 173 stream = virtual_audio_input_stream_; | 184 stream = virtual_audio_input_stream_; |
| 174 DVLOG(1) << "Virtual audio input stream created."; | 185 DVLOG(1) << "Virtual audio input stream created."; |
| 175 | 186 |
| 176 // Make all current output streams recreate themselves as | 187 // Make all current output streams recreate themselves as |
| 177 // VirtualAudioOutputStreams that will attach to the above | 188 // VirtualAudioOutputStreams that will attach to the above |
| 178 // VirtualAudioInputStream. | 189 // VirtualAudioInputStream. |
| 179 NotifyAllOutputDeviceChangeListeners(); | 190 NotifyAllOutputDeviceChangeListeners(); |
| 180 } else { | 191 } else { |
| 181 stream = NULL; | 192 stream = NULL; |
| 182 } | 193 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 | 292 |
| 282 void AudioManagerBase::GetAudioInputDeviceNames( | 293 void AudioManagerBase::GetAudioInputDeviceNames( |
| 283 media::AudioDeviceNames* device_names) { | 294 media::AudioDeviceNames* device_names) { |
| 284 } | 295 } |
| 285 | 296 |
| 286 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { | 297 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
| 287 DCHECK(stream); | 298 DCHECK(stream); |
| 288 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. | 299 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
| 289 // 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 |
| 290 // streams. | 301 // streams. |
| 291 num_output_streams_--; | 302 --num_output_streams_; |
| 292 delete stream; | 303 delete stream; |
| 293 } | 304 } |
| 294 | 305 |
| 295 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { | 306 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
| 296 DCHECK(stream); | 307 DCHECK(stream); |
| 297 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. | 308 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
| 298 | 309 --num_input_streams_; |
| 299 if (virtual_audio_input_stream_ == stream) { | |
| 300 DVLOG(1) << "Virtual audio input stream stopping."; | |
| 301 virtual_audio_input_stream_->Stop(); | |
| 302 virtual_audio_input_stream_ = NULL; | |
| 303 | |
| 304 // Make all VirtualAudioOutputStreams unregister from the | |
| 305 // VirtualAudioInputStream and recreate themselves as regular audio streams | |
| 306 // to return sound to hardware. | |
| 307 NotifyAllOutputDeviceChangeListeners(); | |
| 308 } | |
| 309 | |
| 310 num_input_streams_--; | |
| 311 delete stream; | 310 delete stream; |
| 312 } | 311 } |
| 313 | 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 --num_input_streams_; | |
|
DaleCurtis
2013/01/17 01:15:52
Funnel to ReleaseInputStream() ?
miu
2013/01/17 05:33:55
Done. Good idea.
| |
| 327 delete stream; | |
| 328 } | |
| 329 | |
| 314 void AudioManagerBase::IncreaseActiveInputStreamCount() { | 330 void AudioManagerBase::IncreaseActiveInputStreamCount() { |
| 315 base::AtomicRefCountInc(&num_active_input_streams_); | 331 base::AtomicRefCountInc(&num_active_input_streams_); |
| 316 } | 332 } |
| 317 | 333 |
| 318 void AudioManagerBase::DecreaseActiveInputStreamCount() { | 334 void AudioManagerBase::DecreaseActiveInputStreamCount() { |
| 319 DCHECK(IsRecordingInProcess()); | 335 DCHECK(IsRecordingInProcess()); |
| 320 base::AtomicRefCountDec(&num_active_input_streams_); | 336 base::AtomicRefCountDec(&num_active_input_streams_); |
| 321 } | 337 } |
| 322 | 338 |
| 323 bool AudioManagerBase::IsRecordingInProcess() { | 339 bool AudioManagerBase::IsRecordingInProcess() { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 output_listeners_.RemoveObserver(listener); | 419 output_listeners_.RemoveObserver(listener); |
| 404 } | 420 } |
| 405 | 421 |
| 406 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { | 422 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { |
| 407 DCHECK(message_loop_->BelongsToCurrentThread()); | 423 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 408 DVLOG(1) << "Firing OnDeviceChange() notifications."; | 424 DVLOG(1) << "Firing OnDeviceChange() notifications."; |
| 409 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); | 425 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); |
| 410 } | 426 } |
| 411 | 427 |
| 412 } // namespace media | 428 } // namespace media |
| OLD | NEW |