| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 | 49 |
| 50 AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( | 50 AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( |
| 51 const AudioParameters& params) { | 51 const AudioParameters& params) { |
| 52 // Early return for testing hook. Do this before checking for | 52 // Early return for testing hook. Do this before checking for |
| 53 // |initialized_|. | 53 // |initialized_|. |
| 54 if (params.format == AudioParameters::AUDIO_MOCK) { | 54 if (params.format == AudioParameters::AUDIO_MOCK) { |
| 55 return FakeAudioOutputStream::MakeFakeStream(params); | 55 return FakeAudioOutputStream::MakeFakeStream(params); |
| 56 } | 56 } |
| 57 | 57 |
| 58 if (!initialized()) { | 58 if (!initialized()) { |
| 59 // We should never get here since this method is called on the audio thread. |
| 60 NOTREACHED(); |
| 59 return NULL; | 61 return NULL; |
| 60 } | 62 } |
| 61 | 63 |
| 62 // Don't allow opening more than |kMaxOutputStreams| streams. | 64 // Don't allow opening more than |kMaxOutputStreams| streams. |
| 63 if (active_streams_.size() >= kMaxOutputStreams) { | 65 if (active_output_stream_count_ >= kMaxOutputStreams) |
| 64 return NULL; | 66 return NULL; |
| 65 } | |
| 66 | 67 |
| 67 AudioOutputStream* stream; | 68 AudioOutputStream* stream; |
| 68 #if defined(USE_PULSEAUDIO) | 69 #if defined(USE_PULSEAUDIO) |
| 69 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) { | 70 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) { |
| 70 stream = new PulseAudioOutputStream(params, this, GetMessageLoop()); | 71 stream = new PulseAudioOutputStream(params, this, GetMessageLoop()); |
| 71 } else { | 72 } else { |
| 72 #endif | 73 #endif |
| 73 std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice; | 74 std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice; |
| 74 if (CommandLine::ForCurrentProcess()->HasSwitch( | 75 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 75 switches::kAlsaOutputDevice)) { | 76 switches::kAlsaOutputDevice)) { |
| 76 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 77 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 77 switches::kAlsaOutputDevice); | 78 switches::kAlsaOutputDevice); |
| 78 } | 79 } |
| 79 stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this, | 80 stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this, |
| 80 GetMessageLoop()); | 81 GetMessageLoop()); |
| 81 #if defined(USE_PULSEAUDIO) | 82 #if defined(USE_PULSEAUDIO) |
| 82 } | 83 } |
| 83 #endif | 84 #endif |
| 84 active_streams_.insert(stream); | 85 ++active_output_stream_count_; |
| 85 return stream; | 86 return stream; |
| 86 } | 87 } |
| 87 | 88 |
| 88 AudioInputStream* AudioManagerLinux::MakeAudioInputStream( | 89 AudioInputStream* AudioManagerLinux::MakeAudioInputStream( |
| 89 const AudioParameters& params, const std::string& device_id) { | 90 const AudioParameters& params, const std::string& device_id) { |
| 90 if (!params.IsValid() || params.channels > kMaxInputChannels || | 91 if (!params.IsValid() || params.channels > kMaxInputChannels || |
| 91 device_id.empty()) | 92 device_id.empty()) { |
| 92 return NULL; | 93 return NULL; |
| 94 } |
| 93 | 95 |
| 94 if (params.format == AudioParameters::AUDIO_MOCK) { | 96 if (params.format == AudioParameters::AUDIO_MOCK) { |
| 95 return FakeAudioInputStream::MakeFakeStream(params); | 97 return FakeAudioInputStream::MakeFakeStream(params); |
| 96 } else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) { | 98 } else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) { |
| 97 return NULL; | 99 return NULL; |
| 98 } | 100 } |
| 99 | 101 |
| 100 if (!initialized()) | 102 if (!initialized()) |
| 101 return NULL; | 103 return NULL; |
| 102 | 104 |
| 103 std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ? | 105 std::string device_name = (device_id == AudioManagerBase::kDefaultDeviceId) ? |
| 104 AlsaPcmInputStream::kAutoSelectDevice : device_id; | 106 AlsaPcmInputStream::kAutoSelectDevice : device_id; |
| 105 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) { | 107 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) { |
| 106 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 108 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 107 switches::kAlsaInputDevice); | 109 switches::kAlsaInputDevice); |
| 108 } | 110 } |
| 109 | 111 |
| 110 AlsaPcmInputStream* stream = new AlsaPcmInputStream( | 112 AlsaPcmInputStream* stream = new AlsaPcmInputStream(this, |
| 111 device_name, params, wrapper_.get()); | 113 device_name, params, wrapper_.get()); |
| 112 | 114 |
| 113 return stream; | 115 return stream; |
| 114 } | 116 } |
| 115 | 117 |
| 116 AudioManagerLinux::AudioManagerLinux() { | 118 AudioManagerLinux::AudioManagerLinux() : active_output_stream_count_(0U) { |
| 117 } | 119 } |
| 118 | 120 |
| 119 AudioManagerLinux::~AudioManagerLinux() { | 121 AudioManagerLinux::~AudioManagerLinux() { |
| 120 // Make sure we stop the thread first. If we allow the default destructor to | 122 Shutdown(); |
| 121 // destroy the members, we may destroy audio streams before stopping the | 123 // All the streams should have been deleted on the audio thread via Shutdown. |
| 122 // thread, resulting an unexpected behavior. | 124 CHECK_EQ(active_output_stream_count_, 0U); |
| 123 // This way we make sure activities of the audio streams are all stopped | |
| 124 // before we destroy them. | |
| 125 audio_thread_.Stop(); | |
| 126 | |
| 127 // Free output dispatchers, closing all remaining open streams. | |
| 128 output_dispatchers_.clear(); | |
| 129 | |
| 130 // Delete all the streams. Have to do it manually, we don't have ScopedSet<>, | |
| 131 // and we are not using ScopedVector<> because search there is slow. | |
| 132 STLDeleteElements(&active_streams_); | |
| 133 } | 125 } |
| 134 | 126 |
| 135 void AudioManagerLinux::Init() { | 127 void AudioManagerLinux::Init() { |
| 136 AudioManagerBase::Init(); | 128 AudioManagerBase::Init(); |
| 137 wrapper_.reset(new AlsaWrapper()); | 129 wrapper_.reset(new AlsaWrapper()); |
| 138 } | 130 } |
| 139 | 131 |
| 140 void AudioManagerLinux::MuteAll() { | 132 void AudioManagerLinux::MuteAll() { |
| 141 NOTIMPLEMENTED(); | 133 NOTIMPLEMENTED(); |
| 142 } | 134 } |
| 143 | 135 |
| 144 void AudioManagerLinux::UnMuteAll() { | 136 void AudioManagerLinux::UnMuteAll() { |
| 145 NOTIMPLEMENTED(); | 137 NOTIMPLEMENTED(); |
| 146 } | 138 } |
| 147 | 139 |
| 148 void AudioManagerLinux::ReleaseOutputStream(AudioOutputStream* stream) { | 140 void AudioManagerLinux::ReleaseOutputStream(AudioOutputStream* stream) { |
| 149 if (stream) { | 141 if (stream) { |
| 150 active_streams_.erase(stream); | |
| 151 delete stream; | 142 delete stream; |
| 143 --active_output_stream_count_; |
| 144 DCHECK_GE(active_output_stream_count_, 0U); |
| 152 } | 145 } |
| 153 } | 146 } |
| 154 | 147 |
| 155 bool AudioManagerLinux::CanShowAudioInputSettings() { | 148 bool AudioManagerLinux::CanShowAudioInputSettings() { |
| 156 scoped_ptr<base::Environment> env(base::Environment::Create()); | 149 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 157 base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment( | 150 base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment( |
| 158 env.get()); | 151 env.get()); |
| 159 return (desktop == base::nix::DESKTOP_ENVIRONMENT_GNOME || | 152 return (desktop == base::nix::DESKTOP_ENVIRONMENT_GNOME || |
| 160 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE3 || | 153 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE3 || |
| 161 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE4); | 154 desktop == base::nix::DESKTOP_ENVIRONMENT_KDE4); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } | 314 } |
| 322 } | 315 } |
| 323 | 316 |
| 324 return has_device; | 317 return has_device; |
| 325 } | 318 } |
| 326 | 319 |
| 327 // static | 320 // static |
| 328 AudioManager* AudioManager::CreateAudioManager() { | 321 AudioManager* AudioManager::CreateAudioManager() { |
| 329 return new AudioManagerLinux(); | 322 return new AudioManagerLinux(); |
| 330 } | 323 } |
| OLD | NEW |