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/linux/audio_manager_linux.h" | 5 #include "media/audio/linux/audio_manager_linux.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/environment.h" | 8 #include "base/environment.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/nix/xdg_util.h" | 10 #include "base/nix/xdg_util.h" |
| 11 #include "base/process_util.h" | 11 #include "base/process_util.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "media/audio/audio_output_dispatcher.h" | 13 #include "media/audio/audio_output_dispatcher.h" |
| 14 #include "media/audio/fake_audio_input_stream.h" | |
| 15 #include "media/audio/fake_audio_output_stream.h" | |
| 16 #include "media/audio/linux/alsa_input.h" | 14 #include "media/audio/linux/alsa_input.h" |
| 17 #include "media/audio/linux/alsa_output.h" | 15 #include "media/audio/linux/alsa_output.h" |
| 18 #include "media/audio/linux/alsa_wrapper.h" | 16 #include "media/audio/linux/alsa_wrapper.h" |
| 19 #if defined(USE_PULSEAUDIO) | 17 #if defined(USE_PULSEAUDIO) |
| 20 #include "media/audio/pulse/pulse_output.h" | 18 #include "media/audio/pulse/pulse_output.h" |
| 21 #endif | 19 #endif |
| 22 #include "media/base/limits.h" | 20 #include "media/base/limits.h" |
| 23 #include "media/base/media_switches.h" | 21 #include "media/base/media_switches.h" |
| 24 | 22 |
| 25 // Maximum number of output streams that can be open simultaneously. | 23 // Maximum number of output streams that can be open simultaneously. |
| 26 static const size_t kMaxOutputStreams = 50; | 24 static const int kMaxOutputStreams = 50; |
| 27 | 25 |
| 28 static const int kMaxInputChannels = 2; | 26 static const int kMaxInputChannels = 2; |
| 29 | 27 |
| 30 // Since "default", "pulse" and "dmix" devices are virtual devices mapped to | 28 // Since "default", "pulse" and "dmix" devices are virtual devices mapped to |
| 31 // real devices, we remove them from the list to avoiding duplicate counting. | 29 // real devices, we remove them from the list to avoiding duplicate counting. |
| 32 // In addition, note that we support no more than 2 channels for recording, | 30 // In addition, note that we support no more than 2 channels for recording, |
| 33 // hence surround devices are not stored in the list. | 31 // hence surround devices are not stored in the list. |
| 34 static const char* kInvalidAudioInputDevices[] = { | 32 static const char* kInvalidAudioInputDevices[] = { |
| 35 "default", | 33 "default", |
| 36 "null", | 34 "null", |
| 37 "pulse", | 35 "pulse", |
| 38 "dmix", | 36 "dmix", |
| 39 }; | 37 }; |
| 40 | 38 |
| 41 // Implementation of AudioManager. | 39 // Implementation of AudioManager. |
| 42 bool AudioManagerLinux::HasAudioOutputDevices() { | 40 bool AudioManagerLinux::HasAudioOutputDevices() { |
| 43 return HasAnyAlsaAudioDevice(kStreamPlayback); | 41 return HasAnyAlsaAudioDevice(kStreamPlayback); |
| 44 } | 42 } |
| 45 | 43 |
| 46 bool AudioManagerLinux::HasAudioInputDevices() { | 44 bool AudioManagerLinux::HasAudioInputDevices() { |
| 47 return HasAnyAlsaAudioDevice(kStreamCapture); | 45 return HasAnyAlsaAudioDevice(kStreamCapture); |
| 48 } | 46 } |
| 49 | 47 |
| 50 AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( | 48 AudioManagerLinux::AudioManagerLinux() {} |
| 51 const AudioParameters& params) { | |
| 52 // Early return for testing hook. | |
| 53 if (params.format == AudioParameters::AUDIO_MOCK) | |
| 54 return FakeAudioOutputStream::MakeFakeStream(params); | |
| 55 | |
| 56 // Don't allow opening more than |kMaxOutputStreams| streams. | |
| 57 if (active_output_stream_count_ >= kMaxOutputStreams) | |
| 58 return NULL; | |
| 59 | |
| 60 AudioOutputStream* stream = NULL; | |
| 61 #if defined(USE_PULSEAUDIO) | |
| 62 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) { | |
| 63 stream = new PulseAudioOutputStream(params, this); | |
| 64 } else { | |
| 65 #endif | |
| 66 std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice; | |
| 67 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 68 switches::kAlsaOutputDevice)) { | |
| 69 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 70 switches::kAlsaOutputDevice); | |
| 71 } | |
| 72 stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this); | |
| 73 #if defined(USE_PULSEAUDIO) | |
| 74 } | |
| 75 #endif | |
| 76 ++active_output_stream_count_; | |
| 77 DCHECK(stream); | |
| 78 return stream; | |
| 79 } | |
| 80 | |
| 81 AudioInputStream* AudioManagerLinux::MakeAudioInputStream( | |
| 82 const AudioParameters& params, const std::string& device_id) { | |
| 83 if (!params.IsValid() || params.channels > kMaxInputChannels || | |
| 84 device_id.empty()) { | |
| 85 return NULL; | |
| 86 } | |
| 87 | |
| 88 if (params.format == AudioParameters::AUDIO_MOCK) { | |
| 89 return FakeAudioInputStream::MakeFakeStream(params); | |
| 90 } | |
| 91 | |
| 92 std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ? | |
| 93 AlsaPcmInputStream::kAutoSelectDevice : device_id; | |
| 94 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) { | |
| 95 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 96 switches::kAlsaInputDevice); | |
| 97 } | |
| 98 | |
| 99 AlsaPcmInputStream* stream = new AlsaPcmInputStream(this, | |
| 100 device_name, params, wrapper_.get()); | |
| 101 | |
| 102 return stream; | |
| 103 } | |
| 104 | |
| 105 AudioManagerLinux::AudioManagerLinux() : active_output_stream_count_(0U) {} | |
| 106 | 49 |
| 107 AudioManagerLinux::~AudioManagerLinux() { | 50 AudioManagerLinux::~AudioManagerLinux() { |
| 108 Shutdown(); | 51 Shutdown(); |
| 109 // All the streams should have been deleted on the audio thread via Shutdown. | |
| 110 CHECK_EQ(active_output_stream_count_, 0U); | |
| 111 } | 52 } |
| 112 | 53 |
| 113 void AudioManagerLinux::Init() { | 54 void AudioManagerLinux::Init() { |
| 114 AudioManagerBase::Init(); | 55 AudioManagerBase::Init(); |
| 115 wrapper_.reset(new AlsaWrapper()); | 56 wrapper_.reset(new AlsaWrapper()); |
| 116 } | 57 } |
| 117 | 58 |
| 118 void AudioManagerLinux::MuteAll() { | 59 void AudioManagerLinux::MuteAll() { |
| 119 NOTIMPLEMENTED(); | 60 NOTIMPLEMENTED(); |
| 120 } | 61 } |
| 121 | 62 |
| 122 void AudioManagerLinux::UnMuteAll() { | 63 void AudioManagerLinux::UnMuteAll() { |
| 123 NOTIMPLEMENTED(); | 64 NOTIMPLEMENTED(); |
| 124 } | 65 } |
| 125 | 66 |
| 126 void AudioManagerLinux::ReleaseOutputStream(AudioOutputStream* stream) { | |
| 127 if (stream) { | |
| 128 delete stream; | |
| 129 --active_output_stream_count_; | |
| 130 DCHECK_GE(active_output_stream_count_, 0U); | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 bool AudioManagerLinux::CanShowAudioInputSettings() { | 67 bool AudioManagerLinux::CanShowAudioInputSettings() { |
| 135 scoped_ptr<base::Environment> env(base::Environment::Create()); | 68 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 136 base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment( | 69 base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment( |
| 137 env.get()); | 70 env.get()); |
| 138 return (desktop == base::nix::DESKTOP_ENVIRONMENT_GNOME || | 71 return (desktop == base::nix::DESKTOP_ENVIRONMENT_GNOME || |
| 139 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE3 || | 72 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE3 || |
| 140 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE4); | 73 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE4); |
| 141 } | 74 } |
| 142 | 75 |
| 143 void AudioManagerLinux::ShowAudioInputSettings() { | 76 void AudioManagerLinux::ShowAudioInputSettings() { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 hints = NULL; | 229 hints = NULL; |
| 297 } else { | 230 } else { |
| 298 DLOG(WARNING) << "HasAnyAudioDevice: unable to get device hints: " | 231 DLOG(WARNING) << "HasAnyAudioDevice: unable to get device hints: " |
| 299 << wrapper_->StrError(error); | 232 << wrapper_->StrError(error); |
| 300 } | 233 } |
| 301 } | 234 } |
| 302 | 235 |
| 303 return has_device; | 236 return has_device; |
| 304 } | 237 } |
| 305 | 238 |
| 239 int AudioManagerLinux::GetMaxAudioOutputStreamsAllowed() { | |
| 240 return kMaxOutputStreams; | |
| 241 } | |
| 242 | |
| 243 AudioOutputStream* AudioManagerLinux::MakeAudioLinearOutputStream( | |
| 244 const AudioParameters& params) { | |
| 245 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); | |
| 246 return MakeOutputStream(params); | |
| 247 } | |
| 248 | |
| 249 AudioOutputStream* AudioManagerLinux::MakeAudioLowLatencyOutputStream( | |
| 250 const AudioParameters& params) { | |
| 251 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); | |
| 252 return MakeOutputStream(params); | |
| 253 } | |
| 254 | |
| 255 AudioInputStream* AudioManagerLinux::MakeAudioLinearInputStream( | |
| 256 const AudioParameters& params, const std::string& device_id) { | |
| 257 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format); | |
| 258 return MakeInputStream(params, device_id); | |
| 259 } | |
| 260 | |
| 261 AudioInputStream* AudioManagerLinux::MakeAudioLowLatencyInputStream( | |
| 262 const AudioParameters& params, const std::string& device_id) { | |
| 263 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format); | |
| 264 return MakeInputStream(params, device_id); | |
| 265 } | |
| 266 | |
| 267 AudioOutputStream* AudioManagerLinux::MakeOutputStream( | |
| 268 const AudioParameters& params) { | |
| 269 AudioOutputStream* stream = NULL; | |
| 270 #if defined(USE_PULSEAUDIO) | |
| 271 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) { | |
| 272 stream = new PulseAudioOutputStream(params, this); | |
| 273 } else { | |
| 274 #endif | |
| 275 std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice; | |
| 276 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 277 switches::kAlsaOutputDevice)) { | |
|
tommi (sloooow) - chröme
2012/03/05 14:28:28
indent feels off to me
Foo(arg1,
arg2)
compared
no longer working on chromium
2012/03/06 15:27:07
Done.
| |
| 278 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 279 switches::kAlsaOutputDevice); | |
| 280 } | |
| 281 stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this); | |
| 282 #if defined(USE_PULSEAUDIO) | |
| 283 } | |
| 284 #endif | |
| 285 DCHECK(stream); | |
| 286 return stream; | |
| 287 } | |
| 288 | |
| 289 AudioInputStream* AudioManagerLinux::MakeInputStream( | |
| 290 const AudioParameters& params, const std::string& device_id) { | |
| 291 if (params.channels > kMaxInputChannels) | |
| 292 return NULL; | |
| 293 | |
| 294 std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ? | |
| 295 AlsaPcmInputStream::kAutoSelectDevice : device_id; | |
| 296 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) { | |
| 297 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 298 switches::kAlsaInputDevice); | |
| 299 } | |
| 300 | |
| 301 return new AlsaPcmInputStream(this, device_name, params, wrapper_.get()); | |
| 302 } | |
| 303 | |
| 306 AudioManager* CreateAudioManager() { | 304 AudioManager* CreateAudioManager() { |
| 307 return new AudioManagerLinux(); | 305 return new AudioManagerLinux(); |
| 308 } | 306 } |
| OLD | NEW |