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/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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 string16 AudioManagerBase::GetAudioInputDeviceModel() { | 72 string16 AudioManagerBase::GetAudioInputDeviceModel() { |
| 70 return string16(); | 73 return string16(); |
| 71 } | 74 } |
| 72 | 75 |
| 73 scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() { | 76 scoped_refptr<base::MessageLoopProxy> AudioManagerBase::GetMessageLoop() { |
| 74 return message_loop_; | 77 return message_loop_; |
| 75 } | 78 } |
| 76 | 79 |
| 77 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( | 80 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
| 78 const AudioParameters& params) { | 81 const AudioParameters& params) { |
| 82 DCHECK_EQ(MessageLoop::current(), audio_thread_->message_loop()); | |
| 79 if (!params.IsValid()) { | 83 if (!params.IsValid()) { |
| 80 DLOG(ERROR) << "Audio parameters are invalid"; | 84 DLOG(ERROR) << "Audio parameters are invalid"; |
| 81 return NULL; | 85 return NULL; |
| 82 } | 86 } |
| 83 | 87 |
| 84 // Limit the number of audio streams opened. This is to prevent using | 88 // Limit the number of audio streams opened. This is to prevent using |
| 85 // excessive resources for a large number of audio streams. More | 89 // excessive resources for a large number of audio streams. More |
| 86 // importantly it prevents instability on certain systems. | 90 // importantly it prevents instability on certain systems. |
| 87 // See bug: http://crbug.com/30242. | 91 // See bug: http://crbug.com/30242. |
| 88 if (num_output_streams_ >= max_num_output_streams_) { | 92 if (num_output_streams_ >= max_num_output_streams_) { |
| 89 DLOG(ERROR) << "Number of opened output audio streams " | 93 DLOG(ERROR) << "Number of opened output audio streams " |
| 90 << num_output_streams_ | 94 << num_output_streams_ |
| 91 << " exceed the max allowed number " | 95 << " exceed the max allowed number " |
| 92 << max_num_output_streams_; | 96 << max_num_output_streams_; |
| 93 return NULL; | 97 return NULL; |
| 94 } | 98 } |
| 95 | 99 |
| 96 // If there are no audio output devices we should use a FakeAudioOutputStream | 100 // If there are no audio output devices we should use a FakeAudioOutputStream |
| 97 // to ensure video playback continues to work. | 101 // to ensure video playback continues to work. |
| 98 bool audio_output_disabled = | 102 bool audio_output_disabled = |
| 99 params.format() == AudioParameters::AUDIO_FAKE || | 103 params.format() == AudioParameters::AUDIO_FAKE || |
| 100 !HasAudioOutputDevices(); | 104 !HasAudioOutputDevices(); |
| 101 | 105 |
| 102 AudioOutputStream* stream = NULL; | 106 AudioOutputStream* stream = NULL; |
| 103 if (audio_output_disabled) { | 107 |
| 108 // Temp hack to use virtual device for everything except webRTC output. | |
| 109 bool use_virtual_device = params.sample_rate() != 48000; | |
| 110 | |
| 111 if (use_virtual_device) { | |
| 112 stream = VirtualAudioOutputStream::MakeStream(this, params); | |
| 113 RegisterVirtualAudioOutputStream(stream); | |
| 114 } else if (audio_output_disabled) { | |
| 104 stream = FakeAudioOutputStream::MakeFakeStream(this, params); | 115 stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
| 105 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 116 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
| 106 stream = MakeLinearOutputStream(params); | 117 stream = MakeLinearOutputStream(params); |
| 107 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 118 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 108 stream = MakeLowLatencyOutputStream(params); | 119 stream = MakeLowLatencyOutputStream(params); |
| 109 } | 120 } |
| 110 | 121 |
| 111 if (stream) | 122 if (stream) |
| 112 ++num_output_streams_; | 123 ++num_output_streams_; |
| 113 | 124 |
| 114 return stream; | 125 return stream; |
| 115 } | 126 } |
| 116 | 127 |
| 128 void AudioManagerBase::RegisterVirtualAudioOutputStream( | |
| 129 AudioOutputStream* stream) { | |
| 130 virtual_audio_output_streams_.insert(stream); | |
| 131 } | |
| 132 | |
| 133 void AudioManagerBase::UnregisterVirtualAudioOutputStream( | |
| 134 AudioOutputStream* stream) { | |
| 135 virtual_audio_output_streams_.erase(stream); | |
| 136 | |
| 137 } | |
| 138 | |
| 139 AudioManagerBase::AudioOutputStreamList | |
| 140 AudioManagerBase::GetVirtualAudioOutputStreams() { | |
| 141 return virtual_audio_output_streams_; | |
| 142 } | |
| 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 |
| 132 AudioInputStream* stream = NULL; | 159 AudioInputStream* stream = NULL; |
| 133 if (params.format() == AudioParameters::AUDIO_FAKE) { | 160 if (params.format() == AudioParameters::AUDIO_WEB_CONTENTS) { |
| 161 stream = VirtualAudioInputStream::MakeStream(this, params); | |
| 162 // SwapToVirtual. | |
| 163 } else if (params.format() == AudioParameters::AUDIO_FAKE) { | |
| 134 stream = FakeAudioInputStream::MakeFakeStream(this, params); | 164 stream = FakeAudioInputStream::MakeFakeStream(this, params); |
| 135 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { | 165 } else if (params.format() == AudioParameters::AUDIO_PCM_LINEAR) { |
| 136 stream = MakeLinearInputStream(params, device_id); | 166 stream = MakeLinearInputStream(params, device_id); |
| 137 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { | 167 } else if (params.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { |
| 138 stream = MakeLowLatencyInputStream(params, device_id); | 168 stream = MakeLowLatencyInputStream(params, device_id); |
| 139 } | 169 } |
| 140 | 170 |
| 141 if (stream) | 171 if (stream) |
| 142 ++num_input_streams_; | 172 ++num_input_streams_; |
| 143 | 173 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 } | 256 } |
| 227 | 257 |
| 228 void AudioManagerBase::ShowAudioInputSettings() { | 258 void AudioManagerBase::ShowAudioInputSettings() { |
| 229 } | 259 } |
| 230 | 260 |
| 231 void AudioManagerBase::GetAudioInputDeviceNames( | 261 void AudioManagerBase::GetAudioInputDeviceNames( |
| 232 media::AudioDeviceNames* device_names) { | 262 media::AudioDeviceNames* device_names) { |
| 233 } | 263 } |
| 234 | 264 |
| 235 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { | 265 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
| 266 DCHECK_EQ(MessageLoop::current(), audio_thread_->message_loop()); | |
|
DaleCurtis
2012/11/20 20:00:46
Just DCHECK(message_loop_->BelongsToCurrentThread(
justinlin
2012/11/21 08:09:54
Removed this. Don't really need it anymore.
| |
| 236 DCHECK(stream); | 267 DCHECK(stream); |
| 237 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. | 268 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
| 238 // For example, pass the ownership to AudioManager so it can delete the | 269 // For example, pass the ownership to AudioManager so it can delete the |
| 239 // streams. | 270 // streams. |
| 271 | |
| 272 UnregisterVirtualAudioOutputStream(stream); | |
| 273 | |
| 240 num_output_streams_--; | 274 num_output_streams_--; |
| 241 delete stream; | 275 delete stream; |
| 242 } | 276 } |
| 243 | 277 |
| 244 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { | 278 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
| 245 DCHECK(stream); | 279 DCHECK(stream); |
| 246 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. | 280 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
| 247 num_input_streams_--; | 281 num_input_streams_--; |
| 248 delete stream; | 282 delete stream; |
| 249 } | 283 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 output_listeners_.RemoveObserver(listener); | 374 output_listeners_.RemoveObserver(listener); |
| 341 } | 375 } |
| 342 | 376 |
| 343 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { | 377 void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { |
| 344 DCHECK(message_loop_->BelongsToCurrentThread()); | 378 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 345 DVLOG(1) << "Firing OnDeviceChange() notifications."; | 379 DVLOG(1) << "Firing OnDeviceChange() notifications."; |
| 346 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); | 380 FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); |
| 347 } | 381 } |
| 348 | 382 |
| 349 } // namespace media | 383 } // namespace media |
| OLD | NEW |