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 @@
#include "media/audio/linux/alsa_output.h"
#include "media/audio/linux/alsa_wrapper.h"
#if defined(USE_PULSEAUDIO)
#include "media/audio/linux/pulse_output.h"
#include "media/audio/pulse/pulse_output.h"
#endif
#include "media/base/limits.h"
#include "media/base/media_switches.h"
......
......@@ -4,19 +4,71 @@
#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.
static bool HasAudioHardware() {
int fd;
const char *file;
if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0')
file = "/dev/audioctl";
if ((fd = open(file, O_RDONLY)) < 0)
return false;
close(fd);
return true;
}
bool AudioManagerOpenBSD::HasAudioOutputDevices() {
NOTIMPLEMENTED();
return false;
return HasAudioHardware();
}
bool AudioManagerOpenBSD::HasAudioInputDevices() {
NOTIMPLEMENTED();
return false;
return HasAudioHardware();
}
AudioOutputStream* AudioManagerOpenBSD::MakeAudioOutputStream(
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();
return NULL;
}
......@@ -31,6 +83,23 @@ 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() {
......@@ -41,9 +110,11 @@ void AudioManagerOpenBSD::UnMuteAll() {
NOTIMPLEMENTED();
}
bool AudioManagerOpenBSD::IsRecordingInProgress() {
NOTIMPLEMENTED();
return false;
void AudioManagerOpenBSD::ReleaseOutputStream(AudioOutputStream* stream) {
if (stream) {
active_streams_.erase(stream);
delete stream;
}
}
// static
......
......@@ -5,27 +5,37 @@
#ifndef 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"
class AudioManagerOpenBSD : public AudioManagerBase {
class MEDIA_EXPORT AudioManagerOpenBSD : public AudioManagerBase {
public:
AudioManagerOpenBSD();
// Call before using a newly created AudioManagerOpenBSD instance.
virtual void Init() OVERRIDE;
// Implementation of AudioManager.
virtual bool HasAudioOutputDevices() OVERRIDE;
virtual bool HasAudioInputDevices() OVERRIDE;
virtual AudioOutputStream* MakeAudioOutputStream(
const AudioParameters& params) OVERRIDE;
virtual AudioInputStream* MakeAudioInputStream(
const AudioParameters& params) OVERRIDE;
virtual bool IsRecordingInProgress() OVERRIDE;
virtual AudioInputStream* MakeAudioInputStream(const AudioParameters& params)
OVERRIDE;
virtual void MuteAll() OVERRIDE;
virtual void UnMuteAll() OVERRIDE;
private:
virtual void ReleaseOutputStream(AudioOutputStream* stream);
protected:
virtual ~AudioManagerOpenBSD();
private:
std::set<AudioOutputStream*> active_streams_;
DISALLOW_COPY_AND_ASSIGN(AudioManagerOpenBSD);
};
......
......@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// 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/message_loop.h"
#include "media/audio/audio_parameters.h"
#include "media/audio/audio_util.h"
#if defined(OS_LINUX)
#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/seekable_buffer.h"
......@@ -128,7 +132,7 @@ void PulseAudioOutputStream::WriteRequestCallback(
}
PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params,
AudioManagerLinux* manager,
AudioManagerPulse* manager,
MessageLoop* message_loop)
: channel_layout_(params.channel_layout),
channel_count_(ChannelLayoutToChannelCount(channel_layout_)),
......@@ -156,7 +160,7 @@ PulseAudioOutputStream::PulseAudioOutputStream(const AudioParameters& params,
PulseAudioOutputStream::~PulseAudioOutputStream() {
// 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(!pa_context_);
DCHECK(!pa_mainloop_);
......
......@@ -16,8 +16,8 @@
// inside PulseAudio in Start() and repeated during playback, waiting for
// PulseAudio write callbacks to occur.
#ifndef MEDIA_AUDIO_LINUX_PULSE_OUTPUT_H_
#define MEDIA_AUDIO_LINUX_PULSE_OUTPUT_H_
#ifndef MEDIA_AUDIO_PULSE_PULSE_OUTPUT_H_
#define MEDIA_AUDIO_PULSE_PULSE_OUTPUT_H_
#include <pulse/pulseaudio.h>
......@@ -31,14 +31,23 @@ namespace media {
class SeekableBuffer;
}
#if defined(OS_LINUX)
class AudioManagerLinux;
typedef AudioManagerLinux AudioManagerPulse;
#elif defined(OS_OPENBSD)
class AudioManagerOpenBSD;
typedef AudioManagerOpenBSD AudioManagerPulse;
#else
#error Unsupported platform
#endif
struct AudioParameters;
class MessageLoop;
class PulseAudioOutputStream : public AudioOutputStream {
public:
PulseAudioOutputStream(const AudioParameters& params,
AudioManagerLinux* manager,
AudioManagerPulse* manager,
MessageLoop* message_loop);
virtual ~PulseAudioOutputStream();
......@@ -86,7 +95,7 @@ class PulseAudioOutputStream : public AudioOutputStream {
const uint32 bytes_per_frame_;
// Audio manager that created us. Used to report that we've closed.
AudioManagerLinux* manager_;
AudioManagerPulse* manager_;
// PulseAudio API structs.
pa_context* pa_context_;
......@@ -128,4 +137,4 @@ class PulseAudioOutputStream : public AudioOutputStream {
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";
const char kAlsaInputDevice[] = "alsa-input-device";
#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";
#endif
// Set number of threads to use for video decoding.
const char kVideoThreads[] = "video-threads";
......
......@@ -17,7 +17,10 @@ extern const char kAlsaOutputDevice[];
extern const char kAlsaInputDevice[];
#endif
#if defined(OS_POSIX) && !defined(OS_MACOSX)
MEDIA_EXPORT extern const char kUsePulseAudio[];
#endif
MEDIA_EXPORT extern const char kVideoThreads[];
} // namespace switches
......
......@@ -63,8 +63,6 @@
'audio/linux/alsa_util.h',
'audio/linux/alsa_wrapper.cc',
'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.h',
'audio/mac/audio_input_mac.cc',
......@@ -77,6 +75,8 @@
'audio/mac/audio_manager_mac.h',
'audio/mac/audio_output_mac.cc',
'audio/mac/audio_output_mac.h',
'audio/pulse/pulse_output.cc',
'audio/pulse/pulse_output.h',
'audio/simple_sources.cc',
'audio/simple_sources.h',
'audio/win/audio_low_latency_input_win.cc',
......@@ -299,32 +299,10 @@
'-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"', {
'sources/': [ ['exclude', '/alsa_' ],
['exclude', '/audio_manager_linux' ],
['exclude', '/pulse_' ] ],
['exclude', '/audio_manager_linux' ] ],
'link_settings': {
'libraries': [
],
......@@ -337,6 +315,26 @@
],
}],
['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!': [
'video/capture/video_capture_device_dummy.cc',
'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