Commit a1ced36b authored by scherkus@chromium.org's avatar scherkus@chromium.org

Make pulseaudio available for all posix platforms and add support on OpenBSD.

Patch by robert.nagy@gmail.com:
http://codereview.chromium.org/8499029/

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110584 0039d316-1c4b-4281-b951-d872f2087c98
parent 3ab4c0af
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "media/audio/linux/alsa_output.h" #include "media/audio/linux/alsa_output.h"
#include "media/audio/linux/alsa_wrapper.h" #include "media/audio/linux/alsa_wrapper.h"
#if defined(USE_PULSEAUDIO) #if defined(USE_PULSEAUDIO)
#include "media/audio/linux/pulse_output.h" #include "media/audio/pulse/pulse_output.h"
#endif #endif
#include "media/base/limits.h" #include "media/base/limits.h"
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
......
...@@ -4,19 +4,71 @@ ...@@ -4,19 +4,71 @@
#include "media/audio/openbsd/audio_manager_openbsd.h" #include "media/audio/openbsd/audio_manager_openbsd.h"
#include "base/command_line.h"
#include "base/stl_util.h"
#include "media/audio/audio_output_dispatcher.h"
#include "media/audio/fake_audio_input_stream.h"
#include "media/audio/fake_audio_output_stream.h"
#if defined(USE_PULSEAUDIO)
#include "media/audio/pulse/pulse_output.h"
#endif
#include "media/base/limits.h"
#include "media/base/media_switches.h"
#include <fcntl.h>
// Maximum number of output streams that can be open simultaneously.
static const size_t kMaxOutputStreams = 50;
// Implementation of AudioManager. // Implementation of AudioManager.
bool AudioManagerOpenBSD::HasAudioOutputDevices() { static bool HasAudioHardware() {
NOTIMPLEMENTED(); int fd;
const char *file;
if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0')
file = "/dev/audioctl";
if ((fd = open(file, O_RDONLY)) < 0)
return false; return false;
close(fd);
return true;
}
bool AudioManagerOpenBSD::HasAudioOutputDevices() {
return HasAudioHardware();
} }
bool AudioManagerOpenBSD::HasAudioInputDevices() { bool AudioManagerOpenBSD::HasAudioInputDevices() {
NOTIMPLEMENTED(); return HasAudioHardware();
return false;
} }
AudioOutputStream* AudioManagerOpenBSD::MakeAudioOutputStream( AudioOutputStream* AudioManagerOpenBSD::MakeAudioOutputStream(
const AudioParameters& params) { const AudioParameters& params) {
// Early return for testing hook. Do this before checking for
// |initialized_|.
if (params.format == AudioParameters::AUDIO_MOCK) {
return FakeAudioOutputStream::MakeFakeStream(params);
}
if (!initialized()) {
return NULL;
}
// Don't allow opening more than |kMaxOutputStreams| streams.
if (active_streams_.size() >= kMaxOutputStreams) {
return NULL;
}
AudioOutputStream* stream;
#if defined(USE_PULSEAUDIO)
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUsePulseAudio)) {
stream = new PulseAudioOutputStream(params, this, GetMessageLoop());
active_streams_.insert(stream);
return stream;
}
#endif
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return NULL; return NULL;
} }
...@@ -31,6 +83,23 @@ AudioManagerOpenBSD::AudioManagerOpenBSD() { ...@@ -31,6 +83,23 @@ AudioManagerOpenBSD::AudioManagerOpenBSD() {
} }
AudioManagerOpenBSD::~AudioManagerOpenBSD() { AudioManagerOpenBSD::~AudioManagerOpenBSD() {
// Make sure we stop the thread first. If we allow the default destructor to
// destroy the members, we may destroy audio streams before stopping the
// thread, resulting an unexpected behavior.
// This way we make sure activities of the audio streams are all stopped
// before we destroy them.
audio_thread_.Stop();
// Free output dispatchers, closing all remaining open streams.
output_dispatchers_.clear();
// Delete all the streams. Have to do it manually, we don't have ScopedSet<>,
// and we are not using ScopedVector<> because search there is slow.
STLDeleteElements(&active_streams_);
}
void AudioManagerOpenBSD::Init() {
AudioManagerBase::Init();
} }
void AudioManagerOpenBSD::MuteAll() { void AudioManagerOpenBSD::MuteAll() {
...@@ -41,9 +110,11 @@ void AudioManagerOpenBSD::UnMuteAll() { ...@@ -41,9 +110,11 @@ void AudioManagerOpenBSD::UnMuteAll() {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
bool AudioManagerOpenBSD::IsRecordingInProgress() { void AudioManagerOpenBSD::ReleaseOutputStream(AudioOutputStream* stream) {
NOTIMPLEMENTED(); if (stream) {
return false; active_streams_.erase(stream);
delete stream;
}
} }
// static // static
......
...@@ -5,27 +5,37 @@ ...@@ -5,27 +5,37 @@
#ifndef MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_ #ifndef MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_
#define MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_ #define MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_
#include "base/basictypes.h" #include <set>
#include "base/compiler_specific.h"
#include "media/audio/audio_manager_base.h" #include "media/audio/audio_manager_base.h"
class AudioManagerOpenBSD : public AudioManagerBase { class MEDIA_EXPORT AudioManagerOpenBSD : public AudioManagerBase {
public: public:
AudioManagerOpenBSD(); AudioManagerOpenBSD();
// Call before using a newly created AudioManagerOpenBSD instance.
virtual void Init() OVERRIDE;
// Implementation of AudioManager. // Implementation of AudioManager.
virtual bool HasAudioOutputDevices() OVERRIDE; virtual bool HasAudioOutputDevices() OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE; virtual bool HasAudioInputDevices() OVERRIDE;
virtual AudioOutputStream* MakeAudioOutputStream( virtual AudioOutputStream* MakeAudioOutputStream(
const AudioParameters& params) OVERRIDE; const AudioParameters& params) OVERRIDE;
virtual AudioInputStream* MakeAudioInputStream( virtual AudioInputStream* MakeAudioInputStream(const AudioParameters& params)
const AudioParameters& params) OVERRIDE; OVERRIDE;
virtual bool IsRecordingInProgress() OVERRIDE;
virtual void MuteAll() OVERRIDE; virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE; virtual void UnMuteAll() OVERRIDE;
private: virtual void ReleaseOutputStream(AudioOutputStream* stream);
protected:
virtual ~AudioManagerOpenBSD(); virtual ~AudioManagerOpenBSD();
private:
std::set<AudioOutputStream*> active_streams_;
DISALLOW_COPY_AND_ASSIGN(AudioManagerOpenBSD); DISALLOW_COPY_AND_ASSIGN(AudioManagerOpenBSD);
}; };
......
...@@ -2,13 +2,17 @@ ...@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "media/audio/linux/pulse_output.h" #include "media/audio/pulse/pulse_output.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "media/audio/audio_parameters.h" #include "media/audio/audio_parameters.h"
#include "media/audio/audio_util.h" #include "media/audio/audio_util.h"
#if defined(OS_LINUX)
#include "media/audio/linux/audio_manager_linux.h" #include "media/audio/linux/audio_manager_linux.h"
#elif defined(OS_OPENBSD)
#include "media/audio/openbsd/audio_manager_openbsd.h"
#endif
#include "media/base/data_buffer.h" #include "media/base/data_buffer.h"
#include "media/base/seekable_buffer.h" #include "media/base/seekable_buffer.h"
...@@ -128,7 +132,7 @@ void PulseAudioOutputStream::WriteRequestCallback( ...@@ -128,7 +132,7 @@ void PulseAudioOutputStream::WriteRequestCallback(
} }
PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params, PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params,
AudioManagerLinux* manager, AudioManagerPulse* manager,
MessageLoop* message_loop) MessageLoop* message_loop)
: channel_layout_(params.channel_layout), : channel_layout_(params.channel_layout),
channel_count_(ChannelLayoutToChannelCount(channel_layout_)), channel_count_(ChannelLayoutToChannelCount(channel_layout_)),
...@@ -156,7 +160,7 @@ PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params, ...@@ -156,7 +160,7 @@ PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params,
PulseAudioOutputStream::~PulseAudioOutputStream() { PulseAudioOutputStream::~PulseAudioOutputStream() {
// All internal structures should already have been freed in Close(), // All internal structures should already have been freed in Close(),
// which calls AudioManagerLinux::Release which deletes this object. // which calls AudioManagerPulse::Release which deletes this object.
DCHECK(!playback_handle_); DCHECK(!playback_handle_);
DCHECK(!pa_context_); DCHECK(!pa_context_);
DCHECK(!pa_mainloop_); DCHECK(!pa_mainloop_);
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
// inside PulseAudio in Start() and repeated during playback, waiting for // inside PulseAudio in Start() and repeated during playback, waiting for
// PulseAudio write callbacks to occur. // PulseAudio write callbacks to occur.
#ifndef MEDIA_AUDIO_LINUX_PULSE_OUTPUT_H_ #ifndef MEDIA_AUDIO_PULSE_PULSE_OUTPUT_H_
#define MEDIA_AUDIO_LINUX_PULSE_OUTPUT_H_ #define MEDIA_AUDIO_PULSE_PULSE_OUTPUT_H_
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
...@@ -31,14 +31,23 @@ namespace media { ...@@ -31,14 +31,23 @@ namespace media {
class SeekableBuffer; class SeekableBuffer;
} }
#if defined(OS_LINUX)
class AudioManagerLinux; class AudioManagerLinux;
typedef AudioManagerLinux AudioManagerPulse;
#elif defined(OS_OPENBSD)
class AudioManagerOpenBSD;
typedef AudioManagerOpenBSD AudioManagerPulse;
#else
#error Unsupported platform
#endif
struct AudioParameters; struct AudioParameters;
class MessageLoop; class MessageLoop;
class PulseAudioOutputStream : public AudioOutputStream { class PulseAudioOutputStream : public AudioOutputStream {
public: public:
PulseAudioOutputStream(const AudioParameters& params, PulseAudioOutputStream(const AudioParameters& params,
AudioManagerLinux* manager, AudioManagerPulse* manager,
MessageLoop* message_loop); MessageLoop* message_loop);
virtual ~PulseAudioOutputStream(); virtual ~PulseAudioOutputStream();
...@@ -86,7 +95,7 @@ class PulseAudioOutputStream : public AudioOutputStream { ...@@ -86,7 +95,7 @@ class PulseAudioOutputStream : public AudioOutputStream {
const uint32 bytes_per_frame_; const uint32 bytes_per_frame_;
// Audio manager that created us. Used to report that we've closed. // Audio manager that created us. Used to report that we've closed.
AudioManagerLinux* manager_; AudioManagerPulse* manager_;
// PulseAudio API structs. // PulseAudio API structs.
pa_context* pa_context_; pa_context* pa_context_;
...@@ -128,4 +137,4 @@ class PulseAudioOutputStream : public AudioOutputStream { ...@@ -128,4 +137,4 @@ class PulseAudioOutputStream : public AudioOutputStream {
DISALLOW_COPY_AND_ASSIGN(PulseAudioOutputStream); DISALLOW_COPY_AND_ASSIGN(PulseAudioOutputStream);
}; };
#endif // MEDIA_AUDIO_LINUX_PULSE_OUTPUT_H_ #endif // MEDIA_AUDIO_PULSE_PULSE_OUTPUT_H_
...@@ -13,8 +13,10 @@ const char kAlsaOutputDevice[] = "alsa-output-device"; ...@@ -13,8 +13,10 @@ const char kAlsaOutputDevice[] = "alsa-output-device";
const char kAlsaInputDevice[] = "alsa-input-device"; const char kAlsaInputDevice[] = "alsa-input-device";
#endif #endif
// Use PulseAudio instead of ALSA on Linux. #if defined(OS_POSIX) && !defined(OS_MACOSX)
// Use PulseAudio on platforms that support it.
const char kUsePulseAudio[] = "use-pulseaudio"; const char kUsePulseAudio[] = "use-pulseaudio";
#endif
// Set number of threads to use for video decoding. // Set number of threads to use for video decoding.
const char kVideoThreads[] = "video-threads"; const char kVideoThreads[] = "video-threads";
......
...@@ -17,7 +17,10 @@ extern const char kAlsaOutputDevice[]; ...@@ -17,7 +17,10 @@ extern const char kAlsaOutputDevice[];
extern const char kAlsaInputDevice[]; extern const char kAlsaInputDevice[];
#endif #endif
#if defined(OS_POSIX) && !defined(OS_MACOSX)
MEDIA_EXPORT extern const char kUsePulseAudio[]; MEDIA_EXPORT extern const char kUsePulseAudio[];
#endif
MEDIA_EXPORT extern const char kVideoThreads[]; MEDIA_EXPORT extern const char kVideoThreads[];
} // namespace switches } // namespace switches
......
...@@ -63,8 +63,6 @@ ...@@ -63,8 +63,6 @@
'audio/linux/alsa_util.h', 'audio/linux/alsa_util.h',
'audio/linux/alsa_wrapper.cc', 'audio/linux/alsa_wrapper.cc',
'audio/linux/alsa_wrapper.h', 'audio/linux/alsa_wrapper.h',
'audio/linux/pulse_output.cc',
'audio/linux/pulse_output.h',
'audio/openbsd/audio_manager_openbsd.cc', 'audio/openbsd/audio_manager_openbsd.cc',
'audio/openbsd/audio_manager_openbsd.h', 'audio/openbsd/audio_manager_openbsd.h',
'audio/mac/audio_input_mac.cc', 'audio/mac/audio_input_mac.cc',
...@@ -77,6 +75,8 @@ ...@@ -77,6 +75,8 @@
'audio/mac/audio_manager_mac.h', 'audio/mac/audio_manager_mac.h',
'audio/mac/audio_output_mac.cc', 'audio/mac/audio_output_mac.cc',
'audio/mac/audio_output_mac.h', 'audio/mac/audio_output_mac.h',
'audio/pulse/pulse_output.cc',
'audio/pulse/pulse_output.h',
'audio/simple_sources.cc', 'audio/simple_sources.cc',
'audio/simple_sources.h', 'audio/simple_sources.h',
'audio/win/audio_low_latency_input_win.cc', 'audio/win/audio_low_latency_input_win.cc',
...@@ -299,32 +299,10 @@ ...@@ -299,32 +299,10 @@
'-lasound', '-lasound',
], ],
}, },
'conditions': [
['OS=="linux"', {
'conditions': [
['use_pulseaudio == 1', {
'link_settings': {
'libraries': [
'-lpulse',
],
},
'defines': [
'USE_PULSEAUDIO',
],
}, { # else: use_pulseaudio == 0
'sources!': [
'audio/linux/pulse_output.cc',
'audio/linux/pulse_output.h',
],
}],
],
}],
],
}], }],
['OS=="openbsd"', { ['OS=="openbsd"', {
'sources/': [ ['exclude', '/alsa_' ], 'sources/': [ ['exclude', '/alsa_' ],
['exclude', '/audio_manager_linux' ], ['exclude', '/audio_manager_linux' ] ],
['exclude', '/pulse_' ] ],
'link_settings': { 'link_settings': {
'libraries': [ 'libraries': [
], ],
...@@ -337,6 +315,26 @@ ...@@ -337,6 +315,26 @@
], ],
}], }],
['os_posix == 1', { ['os_posix == 1', {
'conditions': [
['use_pulseaudio == 1', {
'cflags': [
'<!@(pkg-config --cflags libpulse)',
],
'link_settings': {
'libraries': [
'<!@(pkg-config --libs-only-l libpulse)',
],
},
'defines': [
'USE_PULSEAUDIO',
],
}, { # else: use_pulseaudio == 0
'sources!': [
'audio/pulse/pulse_output.cc',
'audio/pulse/pulse_output.h',
],
}],
],
'sources!': [ 'sources!': [
'video/capture/video_capture_device_dummy.cc', 'video/capture/video_capture_device_dummy.cc',
'video/capture/video_capture_device_dummy.h', 'video/capture/video_capture_device_dummy.h',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment