From ace000d3a03181607b130c28da69652f5f60f7d6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Tue, 19 Dec 2006 19:10:50 +0000 Subject: Mark string-type configuration items according to whether they're plain strings or names of files, device nodes or directories. This information is available to front ends (via .num_value) so that they can present file/dir-open dialogue boxes if they so choose. Subtitle font selection is split up due to this. CVS patchset: 8425 CVS date: 2006/12/19 19:10:50 --- src/audio_out/audio_sun_out.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_sun_out.c b/src/audio_out/audio_sun_out.c index 95e38d811..15bd3b72d 100644 --- a/src/audio_out/audio_sun_out.c +++ b/src/audio_out/audio_sun_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_sun_out.c,v 1.45 2006/07/16 16:18:09 dsalt Exp $ + * $Id: audio_sun_out.c,v 1.46 2006/12/19 19:10:51 dsalt Exp $ */ #ifdef HAVE_CONFIG_H @@ -888,9 +888,10 @@ static ao_driver_t *ao_sun_open_plugin (audio_driver_class_t *class_gen, const v audiodev = getenv("AUDIODEV"); /* This config entry is security critical, is it really necessary? */ - devname = config->register_string(config, + devname = config->register_filename(config, "audio.device.sun_audio_device", audiodev && *audiodev ? audiodev : "/dev/audio", + XINE_CONFIG_STRING_IS_DEVICE_NAME, _("Sun audio device name"), _("Specifies the file name for the Sun audio device " "to be used.\nThis setting is security critical, " -- cgit v1.2.3 From a2bdad28270b35136aaa3241bd6f0b85b6a51339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Mon, 25 Dec 2006 18:32:54 +0000 Subject: The alsa audio output plugin uses threads, so link it correctly. CVS patchset: 8446 CVS date: 2006/12/25 18:32:54 --- src/audio_out/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/audio_out') diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 445622765..3a5c78147 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -94,7 +94,7 @@ xineplug_ao_out_oss_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_oss_la_LDFLAGS = -avoid-version -module xineplug_ao_out_alsa_la_SOURCES = audio_alsa_out.c -xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(XINE_LIB) +xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(XINE_LIB) $(THREAD_LIBS) xineplug_ao_out_alsa_la_CFLAGS = $(VISIBILITY_FLAG) $(ALSA_CFLAGS) xineplug_ao_out_alsa_la_LDFLAGS = -avoid-version -module -- cgit v1.2.3 From b8a5182e6866201f6c21e727197404d75a1aa899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 27 Dec 2006 22:14:45 +0000 Subject: Link to libxine when needed. CVS patchset: 8465 CVS date: 2006/12/27 22:14:45 --- src/audio_out/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/audio_out') diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 3a5c78147..918f4829e 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -104,6 +104,7 @@ xineplug_ao_out_esd_la_CFLAGS = $(VISIBILITY_FLAG) $(ESD_CFLAGS) xineplug_ao_out_esd_la_LDFLAGS = -avoid-version -module xineplug_ao_out_sun_la_SOURCES = audio_sun_out.c +xineplug_ao_out_sun_la_LIBADD = $(XINE_LIB) xineplug_ao_out_sun_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module @@ -113,7 +114,7 @@ xineplug_ao_out_sun_la_LDFLAGS = -avoid-version -module #xineplug_ao_out_irixal_la_LDFLAGS = -avoid-version -module xineplug_ao_out_arts_la_SOURCES = audio_arts_out.c -xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) +xineplug_ao_out_arts_la_LIBADD = $(ARTS_LIBS) $(XINE_LIB) xineplug_ao_out_arts_la_CFLAGS = $(VISIBILITY_FLAG) $(ARTS_CFLAGS) xineplug_ao_out_arts_la_LDFLAGS = -avoid-version -module -- cgit v1.2.3 From 3478c4f76e3c2c1c280476852ca32f0a8052d8c5 Mon Sep 17 00:00:00 2001 From: Claudio Ciccani Date: Mon, 29 Jan 2007 14:39:59 +0000 Subject: Release stream and playback in ao_fusionsound_exit(). CVS patchset: 8578 CVS date: 2007/01/29 14:39:59 --- src/audio_out/audio_fusionsound_out.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_fusionsound_out.c b/src/audio_out/audio_fusionsound_out.c index 1a6f44972..71a17f6e6 100644 --- a/src/audio_out/audio_fusionsound_out.c +++ b/src/audio_out/audio_fusionsound_out.c @@ -262,6 +262,12 @@ static uint32_t ao_fusionsound_get_capabilities(ao_driver_t *ao_driver) { static void ao_fusionsound_exit(ao_driver_t *ao_driver) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; + if (this->playback) + this->playback->Release (this->playback); + + if (this->stream) + this->stream->Release (this->stream); + if (this->sound) this->sound->Release (this->sound); -- cgit v1.2.3 From 0bc8ceaec5d62bac80808240f04f93170fd93316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Fri, 2 Feb 2007 23:36:57 +0000 Subject: Make use of threaded mainloop rather than calling it manually, this makes xine not lock up if a pulseaudio connection can't be established. CVS patchset: 8579 CVS date: 2007/02/02 23:36:57 --- src/audio_out/audio_pulse_out.c | 62 ++++++++++++----------------------------- 1 file changed, 18 insertions(+), 44 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 2cef1992d..8b6d52040 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.5 2006/11/10 12:10:54 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.6 2007/02/02 23:36:57 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -44,8 +44,6 @@ #include #include -#include -#include #include "xine_internal.h" #include "xineutils.h" @@ -76,7 +74,7 @@ typedef struct pulse_driver_s { struct pa_context *context; /** Main event loop object */ - struct pa_mainloop *mainloop; + struct pa_threaded_mainloop *mainloop; pa_volume_t swvolume; pa_cvolume cvolume; @@ -101,34 +99,18 @@ typedef struct { xine_t *xine; } pulse_class_t; +int wait_for_operation(pulse_driver_t *this, pa_operation *o) +{ + assert(this && o && this->mainloop); -/** Make sure that the connection context doesn't starve to death */ -static void keep_alive(pulse_driver_t *this) { - assert(this->context && this->mainloop); - - while (pa_mainloop_iterate(this->mainloop, 0, NULL) > 0); -} - -/** Wait until no further actions are pending on the connection context */ -static void wait_for_completion(pulse_driver_t *this) { - assert(this->context && this->mainloop); - - while (pa_context_is_pending(this->context)) { - int r = pa_mainloop_iterate(this->mainloop, 1, NULL); - assert(r >= 0); - } -} - -/** Wait until the specified operation completes */ -static void wait_for_operation(pulse_driver_t *this, struct pa_operation *o) { - assert(o && this->context && this->mainloop); - - while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) { - int r = pa_mainloop_iterate(this->mainloop, 1, NULL); - assert(r >= 0); - } + pa_threaded_mainloop_lock(this->mainloop); + + while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(this->mainloop); + + pa_threaded_mainloop_unlock(this->mainloop); - pa_operation_unref(o); + return 0; } /* @@ -189,16 +171,15 @@ static int ao_pulse_open(ao_driver_t *this_gen, goto fail; } - this->mainloop = pa_mainloop_new(); - assert(this->mainloop); + this->mainloop = pa_threaded_mainloop_new(); + pa_threaded_mainloop_start(this->mainloop); + _x_assert(this->mainloop); - this->context = pa_context_new(pa_mainloop_get_api(this->mainloop), __progname); - assert(this->context); + this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), __progname); + _x_assert(this->context); pa_context_connect(this->context, this->host, 1, NULL); - wait_for_completion(this); - if (pa_context_get_state(this->context) != PA_CONTEXT_READY) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", pa_strerror(pa_context_errno(this->context))); @@ -218,8 +199,6 @@ static int ao_pulse_open(ao_driver_t *this_gen, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, &this->cvolume, NULL); - wait_for_completion(this); - if (pa_stream_get_state(this->stream) != PA_STREAM_READY) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", pa_strerror(pa_context_errno(this->context))); @@ -271,13 +250,10 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, while (size > 0) { size_t l; - keep_alive(this); - while (!(l = pa_stream_writable_size(this->stream))) { pthread_mutex_unlock(&this->lock); xine_usec_sleep (10000); pthread_mutex_lock(&this->lock); - keep_alive(this); } if (l > size) @@ -316,7 +292,6 @@ static int ao_pulse_delay (ao_driver_t *this_gen) if (pa_context_errno(this->context) != PA_ERR_NODATA) { /* error */ } - keep_alive(this); } pthread_mutex_unlock(&this->lock); @@ -350,7 +325,7 @@ static void ao_pulse_close(ao_driver_t *this_gen) } if (this->mainloop) { - pa_mainloop_free(this->mainloop); + pa_threaded_mainloop_free(this->mainloop); this->mainloop = NULL; } pthread_mutex_unlock(&this->lock); @@ -451,7 +426,6 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { assert(o1 && o2); wait_for_operation(this,o1); wait_for_operation(this,o2); - wait_for_completion(this); } break; -- cgit v1.2.3 From 2b3e16c2ea777daaac4875e0566871f499bbf21c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Fri, 2 Feb 2007 23:43:01 +0000 Subject: We don't need to lock anymore as we're using the threaded mainloop, that already is taking care of serialising calls. CVS patchset: 8580 CVS date: 2007/02/02 23:43:01 --- src/audio_out/audio_pulse_out.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 8b6d52040..a5f7b5b8e 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2006 the xine project + * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a free video player. * @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.6 2007/02/02 23:36:57 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.7 2007/02/02 23:43:01 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -89,8 +89,6 @@ typedef struct pulse_driver_s { uint32_t frames_written; - pthread_mutex_t lock; - } pulse_driver_t; typedef struct { @@ -164,8 +162,6 @@ static int ao_pulse_open(ao_driver_t *this_gen, break; } - pthread_mutex_lock(&this->lock); - if (!pa_sample_spec_valid(&ss)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Invalid sample spec\n"); goto fail; @@ -204,14 +200,11 @@ static int ao_pulse_open(ao_driver_t *this_gen, pa_strerror(pa_context_errno(this->context))); goto fail; } - pthread_mutex_unlock(&this->lock); - this->frames_written = 0; return this->sample_rate; fail: - pthread_mutex_unlock(&this->lock); this_gen->close(this_gen); return 0; } @@ -243,17 +236,13 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, assert(this->stream && this->context); - pthread_mutex_lock(&this->lock); - if (pa_stream_get_state(this->stream) == PA_STREAM_READY) { while (size > 0) { size_t l; while (!(l = pa_stream_writable_size(this->stream))) { - pthread_mutex_unlock(&this->lock); xine_usec_sleep (10000); - pthread_mutex_lock(&this->lock); } if (l > size) @@ -271,7 +260,6 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, if (pa_stream_get_state(this->stream) == PA_STREAM_READY) ret = 1; } - pthread_mutex_unlock(&this->lock); return ret; } @@ -283,8 +271,6 @@ static int ao_pulse_delay (ao_driver_t *this_gen) pa_usec_t latency = 0; int delay_frames; - pthread_mutex_lock(&this->lock); - for (;;) { if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) break; @@ -294,8 +280,6 @@ static int ao_pulse_delay (ao_driver_t *this_gen) } } - pthread_mutex_unlock(&this->lock); - /* convert latency (us) to frame units. */ delay_frames = (int)(latency * this->sample_rate / 1000000); @@ -309,7 +293,6 @@ static void ao_pulse_close(ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; - pthread_mutex_lock(&this->lock); if (this->stream) { if (pa_stream_get_state(this->stream) == PA_STREAM_READY) wait_for_operation(this, pa_stream_drain(this->stream, NULL, NULL)); @@ -328,7 +311,6 @@ static void ao_pulse_close(ao_driver_t *this_gen) pa_threaded_mainloop_free(this->mainloop); this->mainloop = NULL; } - pthread_mutex_unlock(&this->lock); } static uint32_t ao_pulse_get_capabilities (ao_driver_t *this_gen) { @@ -368,11 +350,9 @@ static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - pthread_mutex_lock(&this->lock); if( this->stream && this->context ) wait_for_operation(this, pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), info_func, this)); - pthread_mutex_unlock(&this->lock); return (int) (pa_sw_volume_to_linear(this->swvolume)*100); break; case AO_PROP_MUTE_VOL: @@ -388,7 +368,6 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - pthread_mutex_lock(&this->lock); this->swvolume = pa_sw_volume_from_linear((double)value/100.0); if( this->stream && this->context ) { pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); @@ -396,7 +375,6 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream), &this->cvolume, NULL, NULL)); } - pthread_mutex_unlock(&this->lock); break; case AO_PROP_MUTE_VOL: break; @@ -408,7 +386,6 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { pulse_driver_t *this = (pulse_driver_t *) this_gen; - pthread_mutex_lock(&this->lock); switch (cmd) { case AO_CTRL_PLAY_PAUSE: @@ -436,7 +413,6 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { this->frames_written = 0; break; } - pthread_mutex_unlock(&this->lock); return 0; } @@ -505,8 +481,6 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n", this->host ? this->host : "(null)", this->sink ? this->sink : "(null)"); - pthread_mutex_init (&this->lock, NULL); - /* test pulseaudio connection */ if( this->ao_driver.open(&this->ao_driver, 16, 44100, AO_CAP_MODE_STEREO) != 0 ) { this->ao_driver.close(&this->ao_driver); -- cgit v1.2.3 From 47300569d5a7b9f09ffae8ff7fdd2fe4fea2f3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Fri, 2 Feb 2007 23:45:23 +0000 Subject: Replace assert() calls with _x_assert(). CVS patchset: 8581 CVS date: 2007/02/02 23:45:23 --- src/audio_out/audio_pulse_out.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index a5f7b5b8e..88dc25e0b 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.7 2007/02/02 23:43:01 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.8 2007/02/02 23:45:23 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -99,7 +98,7 @@ typedef struct { int wait_for_operation(pulse_driver_t *this, pa_operation *o) { - assert(this && o && this->mainloop); + _x_assert(this && o && this->mainloop); pa_threaded_mainloop_lock(this->mainloop); @@ -183,7 +182,7 @@ static int ao_pulse_open(ao_driver_t *this_gen, } this->stream = pa_stream_new(this->context, "audio stream", &ss, NULL); - assert(this->stream); + _x_assert(this->stream); a.maxlength = pa_bytes_per_second(&ss)*1; a.tlength = a.maxlength*9/10; @@ -234,7 +233,7 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, int size = num_frames * this->bytes_per_frame; int ret = 0; - assert(this->stream && this->context); + _x_assert(this->stream && this->context); if (pa_stream_get_state(this->stream) == PA_STREAM_READY) { @@ -389,25 +388,25 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { switch (cmd) { case AO_CTRL_PLAY_PAUSE: - assert(this->stream && this->context ); + _x_assert(this->stream && this->context ); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) wait_for_operation(this,pa_stream_cork(this->stream, 1, NULL, NULL)); break; case AO_CTRL_PLAY_RESUME: - assert(this->stream && this->context); + _x_assert(this->stream && this->context); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) { struct pa_operation *o2, *o1; o1 = pa_stream_prebuf(this->stream, NULL, NULL); o2 = pa_stream_cork(this->stream, 0, NULL, NULL); - assert(o1 && o2); + _x_assert(o1 && o2); wait_for_operation(this,o1); wait_for_operation(this,o2); } break; case AO_CTRL_FLUSH_BUFFERS: - assert(this->stream && this->context); + _x_assert(this->stream && this->context); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) wait_for_operation(this,pa_stream_flush(this->stream, NULL, NULL)); this->frames_written = 0; -- cgit v1.2.3 From 9d1bb205475c5e2287d94c23d738c89204105415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 3 Feb 2007 10:41:09 +0000 Subject: Restructure the plugin a bit: create the mainloop and the context immediately on class load, this way they will be shared by all PulseAudio outputs; connect to the context when opening the output device, rather than the first time you play the stream (this way avoids latency while playing multiple tracks). The result is only one connection is present for xine instance, even if multiple streams are called on it. CVS patchset: 8582 CVS date: 2007/02/03 10:41:09 --- src/audio_out/audio_pulse_out.c | 237 ++++++++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 68 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 88dc25e0b..8f0c6aab5 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.8 2007/02/02 23:45:23 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.9 2007/02/03 10:41:09 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -94,9 +94,115 @@ typedef struct { audio_driver_class_t driver_class; xine_t *xine; + + /** Pulseaudio connection context */ + struct pa_context *context; + + /** Main event loop object */ + struct pa_threaded_mainloop *mainloop; } pulse_class_t; -int wait_for_operation(pulse_driver_t *this, pa_operation *o) +/** + * @brief Callback function called when the status of the PulseAudio + * context changes + * @param ctx Context that changed (same as class->context) + * @param class_gen pulse_class_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_ctx_state_callback(pa_context *const ctx, void *const class_gen) +{ + pulse_class_t *const class = (pulse_class_t*)class_gen; + + _x_assert(ctx); _x_assert(class); + _x_assert(ctx == class->context); + + pa_threaded_mainloop_signal(class->mainloop, 0); +} + +/** + * @brief Callback function called when the status of the PulseAudio + * stream changes + * @param stream Stream that changed (same as this->stream) + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_stream_state_callback(pa_stream *const stream, void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; + + _x_assert(stream); _x_assert(this); + _x_assert(stream == this->stream); + + pa_threaded_mainloop_signal(this->mainloop, 0); +} + +/** + * @brief Callback function called when a stream operation succeed + * @param stream Stream which operation has succeeded + * @param success The success value for the operation (ignored) + * @param this_Gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_stream_success_callback(pa_stream *const stream, const int success, + void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; + + _x_assert(stream); _x_assert(this); + _x_assert(stream == this->stream); + + pa_threaded_mainloop_signal(this->mainloop, 0); +} + +/** + * @brief Callback function called when a context operation succeed + * @param ctx Context which operation has succeeded + * @param success The success value for the operation (ignored) + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_context_success_callback(pa_context *const ctx, const int success, + void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; + + _x_assert(ctx); _x_assert(this); + _x_assert(ctx == this->context); + + pa_threaded_mainloop_signal(this->mainloop, 0); +} + +/** + * @brief Callback function called when the information on the + * context's sink is retrieved. + * @param ctx Context which operation has succeeded + * @param info Structure containing the sink's information + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + * + * This function saves the volume field of the passed structure to the + * @c cvolume variable of the output instance. + */ +static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_input_info *const info, + const int is_last, void *const userdata) { + + pulse_driver_t *const this = (pulse_driver_t *) userdata; + + if (is_last < 0) { + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", + pa_strerror(pa_context_errno(this->context))); + return; + } + + if (!info) + return; + + this->cvolume = info->volume; + + __xine_pa_context_success_callback(ctx, 0, this); +} + +static int wait_for_operation(pulse_driver_t *this, pa_operation *o) { _x_assert(this && o && this->mainloop); @@ -119,6 +225,7 @@ static int ao_pulse_open(ao_driver_t *this_gen, pulse_driver_t *this = (pulse_driver_t *) this_gen; struct pa_sample_spec ss; struct pa_buffer_attr a; + pa_stream_state_t streamstate; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); @@ -166,24 +273,11 @@ static int ao_pulse_open(ao_driver_t *this_gen, goto fail; } - this->mainloop = pa_threaded_mainloop_new(); - pa_threaded_mainloop_start(this->mainloop); - _x_assert(this->mainloop); - - this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), __progname); - _x_assert(this->context); - - pa_context_connect(this->context, this->host, 1, NULL); - - if (pa_context_get_state(this->context) != PA_CONTEXT_READY) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", - pa_strerror(pa_context_errno(this->context))); - goto fail; - } - this->stream = pa_stream_new(this->context, "audio stream", &ss, NULL); _x_assert(this->stream); + pa_stream_set_state_callback(this->stream, __xine_pa_stream_state_callback, this); + a.maxlength = pa_bytes_per_second(&ss)*1; a.tlength = a.maxlength*9/10; a.prebuf = a.tlength/2; @@ -194,8 +288,15 @@ static int ao_pulse_open(ao_driver_t *this_gen, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, &this->cvolume, NULL); - if (pa_stream_get_state(this->stream) != PA_STREAM_READY) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", + do { + xine_usec_sleep (100); + + streamstate = pa_stream_get_state(this->stream); + fprintf(stderr, "PulseAudio stream state: %d\n", streamstate); + } while (streamstate < PA_STREAM_READY); + + if (streamstate != PA_STREAM_READY) { + xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_pulse_out: Failed to connect to server: %s\n", pa_strerror(pa_context_errno(this->context))); goto fail; } @@ -250,8 +351,6 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE); data = (int16_t *) ((uint8_t*) data + l); size -= l; - - wait_for_completion(this); } this->frames_written += num_frames; @@ -294,22 +393,11 @@ static void ao_pulse_close(ao_driver_t *this_gen) if (this->stream) { if (pa_stream_get_state(this->stream) == PA_STREAM_READY) - wait_for_operation(this, pa_stream_drain(this->stream, NULL, NULL)); + wait_for_operation(this, pa_stream_drain(this->stream, __xine_pa_stream_success_callback, this)); pa_stream_disconnect(this->stream); pa_stream_unref(this->stream); this->stream = NULL; } - - if (this->context) { - pa_context_disconnect(this->context); - pa_context_unref(this->context); - this->context = NULL; - } - - if (this->mainloop) { - pa_threaded_mainloop_free(this->mainloop); - this->mainloop = NULL; - } } static uint32_t ao_pulse_get_capabilities (ao_driver_t *this_gen) { @@ -324,25 +412,6 @@ static void ao_pulse_exit(ao_driver_t *this_gen) free (this); } -/** A callback function that is called when the - * pa_context_get_sink_input_info() operation completes. Saves the - * volume field of the specified structure to the global variable volume. */ -static void info_func(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) { - - pulse_driver_t *this = (pulse_driver_t *) userdata; - if (is_last < 0) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", - pa_strerror(pa_context_errno(this->context))); - return; - } - - if (!i) - return; - - this->cvolume = i->volume; -} - - static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { pulse_driver_t *this = (pulse_driver_t *) this_gen; @@ -351,7 +420,8 @@ static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { case AO_PROP_MIXER_VOL: if( this->stream && this->context ) wait_for_operation(this, - pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), info_func, this)); + pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), + __xine_pa_sink_info_callback, this)); return (int) (pa_sw_volume_to_linear(this->swvolume)*100); break; case AO_PROP_MUTE_VOL: @@ -372,7 +442,7 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); wait_for_operation(this, pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream), - &this->cvolume, NULL, NULL)); + &this->cvolume, __xine_pa_context_success_callback, this)); } break; case AO_PROP_MUTE_VOL: @@ -390,25 +460,25 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { case AO_CTRL_PLAY_PAUSE: _x_assert(this->stream && this->context ); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) - wait_for_operation(this,pa_stream_cork(this->stream, 1, NULL, NULL)); + wait_for_operation(this,pa_stream_cork(this->stream, 1, __xine_pa_stream_success_callback, this)); break; case AO_CTRL_PLAY_RESUME: _x_assert(this->stream && this->context); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) { struct pa_operation *o2, *o1; - o1 = pa_stream_prebuf(this->stream, NULL, NULL); - o2 = pa_stream_cork(this->stream, 0, NULL, NULL); - _x_assert(o1 && o2); - wait_for_operation(this,o1); - wait_for_operation(this,o2); + o1 = pa_stream_prebuf(this->stream, __xine_pa_stream_success_callback, this); + _x_assert(o1); wait_for_operation(this, o1); + + o2 = pa_stream_cork(this->stream, 0, __xine_pa_stream_success_callback, this); + _x_assert(o2); wait_for_operation(this,o2); } break; case AO_CTRL_FLUSH_BUFFERS: _x_assert(this->stream && this->context); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) - wait_for_operation(this,pa_stream_flush(this->stream, NULL, NULL)); + wait_for_operation(this,pa_stream_flush(this->stream, __xine_pa_stream_success_callback, this)); this->frames_written = 0; break; } @@ -421,6 +491,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da pulse_driver_t *this; char hn[128]; char *device; + pa_context_state_t ctxstate; lprintf ("audio_pulse_out: open_plugin called\n"); @@ -480,16 +551,31 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n", this->host ? this->host : "(null)", this->sink ? this->sink : "(null)"); - /* test pulseaudio connection */ - if( this->ao_driver.open(&this->ao_driver, 16, 44100, AO_CAP_MODE_STEREO) != 0 ) { - this->ao_driver.close(&this->ao_driver); - } else { - free(this); - xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: open_plugin failed.\n"); - return NULL; + this->mainloop = class->mainloop; + this->context = class->context; + + if ( pa_context_get_state(this->context) != PA_CONTEXT_READY ){ + pa_context_connect(this->context, this->host, 1, NULL); + + do { + xine_usec_sleep (100); + + ctxstate = pa_context_get_state(this->context); + } while (ctxstate < PA_CONTEXT_READY); + + if (ctxstate != PA_CONTEXT_READY) { + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", + pa_strerror(pa_context_errno(this->context))); + goto fail; + } } return &this->ao_driver; + + fail: + free(this); + xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: open_plugin failed.\n"); + return NULL; } /* @@ -508,6 +594,11 @@ static void dispose_class (audio_driver_class_t *this_gen) { pulse_class_t *this = (pulse_class_t *) this_gen; + pa_context_unref(this->context); + + pa_threaded_mainloop_stop(this->mainloop); + pa_threaded_mainloop_free(this->mainloop); + free (this); } @@ -528,6 +619,16 @@ static void *init_class (xine_t *xine, void *data) { this->xine = xine; + this->mainloop = pa_threaded_mainloop_new(); + _x_assert(this->mainloop); + + pa_threaded_mainloop_start(this->mainloop); + + this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), __progname); + _x_assert(this->context); + + pa_context_set_state_callback(this->context, __xine_pa_ctx_state_callback, this); + return this; } -- cgit v1.2.3 From 3bdbac87849cdb158ca3e963c3659d84c6323a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 3 Feb 2007 10:45:02 +0000 Subject: Remove the state callbacks, it's simpler to just wait a bit for the connection, as that's just what is going on those given moments, and avoids stray signals along the way. CVS patchset: 8583 CVS date: 2007/02/03 10:45:02 --- src/audio_out/audio_pulse_out.c | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 8f0c6aab5..834429d10 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.9 2007/02/03 10:41:09 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.10 2007/02/03 10:45:02 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -102,40 +102,6 @@ typedef struct { struct pa_threaded_mainloop *mainloop; } pulse_class_t; -/** - * @brief Callback function called when the status of the PulseAudio - * context changes - * @param ctx Context that changed (same as class->context) - * @param class_gen pulse_class_t pointer for the PulseAudio output - * instance. - */ -static void __xine_pa_ctx_state_callback(pa_context *const ctx, void *const class_gen) -{ - pulse_class_t *const class = (pulse_class_t*)class_gen; - - _x_assert(ctx); _x_assert(class); - _x_assert(ctx == class->context); - - pa_threaded_mainloop_signal(class->mainloop, 0); -} - -/** - * @brief Callback function called when the status of the PulseAudio - * stream changes - * @param stream Stream that changed (same as this->stream) - * @param this_gen pulse_driver_t pointer for the PulseAudio output - * instance. - */ -static void __xine_pa_stream_state_callback(pa_stream *const stream, void *const this_gen) -{ - pulse_driver_t *const this = (pulse_driver_t*)this_gen; - - _x_assert(stream); _x_assert(this); - _x_assert(stream == this->stream); - - pa_threaded_mainloop_signal(this->mainloop, 0); -} - /** * @brief Callback function called when a stream operation succeed * @param stream Stream which operation has succeeded @@ -276,8 +242,6 @@ static int ao_pulse_open(ao_driver_t *this_gen, this->stream = pa_stream_new(this->context, "audio stream", &ss, NULL); _x_assert(this->stream); - pa_stream_set_state_callback(this->stream, __xine_pa_stream_state_callback, this); - a.maxlength = pa_bytes_per_second(&ss)*1; a.tlength = a.maxlength*9/10; a.prebuf = a.tlength/2; @@ -627,8 +591,6 @@ static void *init_class (xine_t *xine, void *data) { this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), __progname); _x_assert(this->context); - pa_context_set_state_callback(this->context, __xine_pa_ctx_state_callback, this); - return this; } -- cgit v1.2.3 From 77280e7059f4bd9f52ac606a2190af78a1b55c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 3 Feb 2007 10:46:14 +0000 Subject: Remove a debug output. CVS patchset: 8584 CVS date: 2007/02/03 10:46:14 --- src/audio_out/audio_pulse_out.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 834429d10..d04856c61 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.10 2007/02/03 10:45:02 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.11 2007/02/03 10:46:14 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -256,7 +256,6 @@ static int ao_pulse_open(ao_driver_t *this_gen, xine_usec_sleep (100); streamstate = pa_stream_get_state(this->stream); - fprintf(stderr, "PulseAudio stream state: %d\n", streamstate); } while (streamstate < PA_STREAM_READY); if (streamstate != PA_STREAM_READY) { -- cgit v1.2.3 From 71bd3ff4ab60d4ae510b1d7fb8d0ffe80f8c227d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Tue, 20 Feb 2007 00:04:50 +0000 Subject: Mark speaker arrangement array constant. CVS patchset: 8607 CVS date: 2007/02/20 00:04:50 --- src/audio_out/audio_alsa_out.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c index da8b87fc5..24d597d50 100644 --- a/src/audio_out/audio_alsa_out.c +++ b/src/audio_out/audio_alsa_out.c @@ -26,7 +26,7 @@ * (c) 2001 James Courtier-Dutton * * - * $Id: audio_alsa_out.c,v 1.165 2006/09/08 20:40:34 miguelfreitas Exp $ + * $Id: audio_alsa_out.c,v 1.166 2007/02/20 00:04:50 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -1321,7 +1321,7 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da char *pcm_device; snd_pcm_hw_params_t *params; /* for usability reasons, keep this in sync with audio_oss_out.c */ - static char *speaker_arrangement[] = {"Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1", + static const char *speaker_arrangement[] = {"Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1", "Surround 3.0", "Surround 4.0", "Surround 4.1", "Surround 5.0", "Surround 5.1", "Surround 6.0", "Surround 6.1", "Surround 7.1", "Pass Through", NULL}; #define MONO 0 -- cgit v1.2.3 From 1c71b178c70bb1712667c4238d3ab3e4345a3c04 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sun, 25 Feb 2007 21:54:03 +0000 Subject: Fix race condition in alsa audio out driver. thanks Kirill Belokurov and Matthias Kretz CVS patchset: 8629 CVS date: 2007/02/25 21:54:03 --- src/audio_out/audio_alsa_out.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c index 24d597d50..1f3ec700d 100644 --- a/src/audio_out/audio_alsa_out.c +++ b/src/audio_out/audio_alsa_out.c @@ -26,7 +26,7 @@ * (c) 2001 James Courtier-Dutton * * - * $Id: audio_alsa_out.c,v 1.166 2007/02/20 00:04:50 dgp85 Exp $ + * $Id: audio_alsa_out.c,v 1.167 2007/02/25 21:54:04 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -162,7 +162,6 @@ static int my_snd_mixer_wait(snd_mixer_t *mixer, int timeout) { static void *ao_alsa_handle_event_thread(void *data) { alsa_driver_t *this = (alsa_driver_t *) data; - this->mixer.running = 1; do { if(my_snd_mixer_wait(this->mixer.handle, 333) > 0) { @@ -1292,6 +1291,8 @@ static void ao_alsa_mixer_init(ao_driver_t *this_gen) { if (send_events && found) { pthread_attr_t pth_attrs; struct sched_param pth_params; + + this->mixer.running = 1; pthread_attr_init(&pth_attrs); -- cgit v1.2.3 From 49da4ad331daa0a943397f408695b033f2b8aaa9 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sun, 25 Feb 2007 22:33:25 +0000 Subject: alsa patches from Julian Scheel and Matthias Kretz CVS patchset: 8630 CVS date: 2007/02/25 22:33:25 --- src/audio_out/audio_alsa_out.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_alsa_out.c b/src/audio_out/audio_alsa_out.c index 1f3ec700d..3651d21da 100644 --- a/src/audio_out/audio_alsa_out.c +++ b/src/audio_out/audio_alsa_out.c @@ -26,7 +26,7 @@ * (c) 2001 James Courtier-Dutton * * - * $Id: audio_alsa_out.c,v 1.167 2007/02/25 21:54:04 miguelfreitas Exp $ + * $Id: audio_alsa_out.c,v 1.168 2007/02/25 22:33:25 miguelfreitas Exp $ */ #ifdef HAVE_CONFIG_H @@ -664,6 +664,15 @@ static int ao_alsa_delay (ao_driver_t *this_gen) { printf("audio_alsa_out:delay:ENTERED\n"); #endif err=snd_pcm_delay( this->audio_fd, &delay ); + + int state = snd_pcm_state(this->audio_fd); + + /* check for idle states, which need to be handled as delay=0 */ + if(state == SND_PCM_STATE_PREPARED || state == SND_PCM_STATE_PAUSED || + state == SND_PCM_STATE_OPEN || SND_PCM_STATE_XRUN) { + return 0; + } + #ifdef LOG_DEBUG printf("audio_alsa_out:delay:delay all=%ld err=%d\n",delay, err); gettimeofday(&now, 0); @@ -1505,6 +1514,13 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da this->capabilities |= AO_CAP_FLOAT32; xprintf(class->xine, XINE_VERBOSITY_LOG, _("32bit ")); } + if (0 == (this->capabilities & (AO_CAP_FLOAT32 | AO_CAP_24BITS | AO_CAP_16BITS | AO_CAP_8BITS))) { + xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, + "\naudio_alsa_out: no supported PCM format found\n"); + snd_pcm_close(this->audio_fd); + free(this); + return NULL; + } if (!(snd_pcm_hw_params_test_channels(this->audio_fd, params, 1))) { this->capabilities |= AO_CAP_MODE_MONO; xprintf(class->xine, XINE_VERBOSITY_LOG, _("mono ")); -- cgit v1.2.3 From dc9b368b5535812336b715656f809f7f4fa63456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Fri, 9 Mar 2007 23:56:42 +0000 Subject: Use OSS 3.0 API, and retain compatibility with older versions. Patch by Albert Lee. CVS patchset: 8651 CVS date: 2007/03/09 23:56:42 --- src/audio_out/audio_oss_out.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c index 366fa250c..ccb142eb5 100644 --- a/src/audio_out/audio_oss_out.c +++ b/src/audio_out/audio_oss_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_oss_out.c,v 1.117 2006/07/16 16:18:09 dsalt Exp $ + * $Id: audio_oss_out.c,v 1.118 2007/03/09 23:56:42 dgp85 Exp $ * * 20-8-2001 First implementation of Audio sync and Audio driver separation. * Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk @@ -75,6 +75,16 @@ #include +#ifndef SNDCTL_DSP_SETFMT +/* Deprecated OSS API */ +#define SNDCTL_DSP_SETFMT SOUND_PCM_SETFMT +#endif + +#ifndef SNDCTL_DSP_SPEED +/* Deprecated OSS API */ +#define SNDCTL_DSP_SPEED SOUND_PCM_WRITE_RATE +#endif + #ifndef AFMT_S16_NE # if defined(sparc) || defined(__sparc__) || defined(PPC) /* Big endian machines */ @@ -789,9 +799,9 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da */ arg = AFMT_S16_NE; - status = ioctl(audio_fd, SOUND_PCM_SETFMT, &arg); + status = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg); arg = 44100; - status = ioctl(audio_fd, SOUND_PCM_WRITE_RATE, &arg); + status = ioctl(audio_fd, SNDCTL_DSP_SPEED, &arg); /* * find out which sync method to use @@ -903,12 +913,12 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da this->capabilities = 0; arg = AFMT_U8; - if( ioctl(audio_fd, SOUND_PCM_SETFMT, &arg) != -1 && arg == AFMT_U8) + if( ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg) != -1 && arg == AFMT_U8) this->capabilities |= AO_CAP_8BITS; /* switch back to 16bits, because some soundcards otherwise do not report all their capabilities */ arg = AFMT_S16_NE; - if (ioctl(audio_fd, SOUND_PCM_SETFMT, &arg) == -1 || arg != AFMT_S16_NE) { + if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg) == -1 || arg != AFMT_S16_NE) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: switching the soundcard to 16 bits mode failed\n"); free(this); close(audio_fd); -- cgit v1.2.3 From daa2eb3c9c1fad22c9b361f4713ca130cab33ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 10 Mar 2007 00:55:14 +0000 Subject: Don't use Solaris workarounds on other OSes (namely NetBSD). Patch by Sergey Svishchev, see bug #1667848. CVS patchset: 8658 CVS date: 2007/03/10 00:55:14 --- src/audio_out/audio_sun_out.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_sun_out.c b/src/audio_out/audio_sun_out.c index 15bd3b72d..93361d2f3 100644 --- a/src/audio_out/audio_sun_out.c +++ b/src/audio_out/audio_sun_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_sun_out.c,v 1.46 2006/12/19 19:10:51 dsalt Exp $ + * $Id: audio_sun_out.c,v 1.47 2007/03/10 00:55:14 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H @@ -41,13 +41,20 @@ #ifdef __svr4__ #include #endif +#include + +#if (defined(BSD) && BSD >= 199306) +typedef unsigned uint_t; +#endif #include "xine_internal.h" #include "xineutils.h" #include "audio_out.h" +#ifdef __svr4__ #define CS4231_WORKAROUND 1 /* enable workaround for audiocs play.samples bug */ #define SW_SAMPLE_COUNT 1 +#endif #ifndef AUDIO_CHANNELS_MONO @@ -89,7 +96,9 @@ typedef struct sun_driver_s { uint32_t num_channels; int bytes_per_frame; +#ifdef __svr4__ uint32_t frames_in_buffer; /* number of frames writen to audio hardware */ +#endif enum { RTSC_UNKNOWN = 0, @@ -114,12 +123,14 @@ typedef struct sun_driver_s { unsigned buf_len; #endif +#ifdef __svr4__ #if SW_SAMPLE_COUNT struct timeval tv0; uint_t sample0; #endif uint_t last_samplecnt; +#endif } sun_driver_t; @@ -129,6 +140,7 @@ typedef struct sun_driver_s { */ static int realtime_samplecounter_available(xine_t *xine, char *dev) { +#ifdef __svr4__ int fd = -1; audio_info_t info; int rtsc_ok = RTSC_DISABLED; @@ -247,6 +259,9 @@ error: } return rtsc_ok; +#else + return RTSC_ENABLED; +#endif } @@ -430,7 +445,9 @@ static int ao_sun_open(ao_driver_t *this_gen, this->mode = mode; this->input_sample_rate = rate; +#ifdef __svr4__ this->frames_in_buffer = 0; +#endif /* * open audio device @@ -462,6 +479,9 @@ static int ao_sun_open(ao_driver_t *this_gen, info.play.sample_rate = this->input_sample_rate; info.play.eof = 0; info.play.samples = 0; +#ifndef __svr4__ + info.blocksize = 1024; +#endif this->convert_u8_s8 = 0; @@ -523,7 +543,9 @@ static int ao_sun_open(ao_driver_t *this_gen, return 0; } +#ifdef __svr4__ this->last_samplecnt = 0; +#endif this->output_sample_rate = info.play.sample_rate; this->num_channels = info.play.channels; @@ -564,6 +586,7 @@ static int ao_sun_delay(ao_driver_t *this_gen) sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; +#ifdef __svr4__ if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) == 0 && (this->frames_in_buffer == 0 || info.play.samples > 0)) { @@ -610,6 +633,10 @@ static int ao_sun_delay(ao_driver_t *this_gen) } #endif } +#else + if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) == 0) + return info.play.seek / this->bytes_per_frame; +#endif return NOT_REAL_TIME; } @@ -718,7 +745,9 @@ static int ao_sun_write(ao_driver_t *this_gen, if (num_written > 0) { int buffered_samples; +#ifdef __svr4__ this->frames_in_buffer += num_written / this->bytes_per_frame; +#endif /* * Avoid storing too much data in the sound driver's buffers. @@ -861,6 +890,9 @@ static int ao_sun_ctrl(ao_driver_t *this_gen, int cmd, ...) { this->frames_in_buffer = 0; this->last_samplecnt = 0; +#endif +#ifdef __NetBSD__ + ioctl(this->audio_fd, AUDIO_FLUSH); #endif break; } @@ -946,7 +978,10 @@ static ao_driver_t *ao_sun_open_plugin (audio_driver_class_t *class_gen, const v */ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_8BITS - | AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL; + | AO_CAP_16BITS | AO_CAP_PCM_VOL; +#ifdef __svr4__ + this->capabilities |= AO_CAP_MUTE_VOL; +#endif /* * get initial mixer volume -- cgit v1.2.3 From 701d89533d14c303fa2ba880f2b6b3cc24562f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Fri, 16 Mar 2007 17:13:57 +0000 Subject: Fix FreeBSD PR 91728 (problem with ioctl() request parameter being unsigned long rather than int). This patch is less invasive and portable. CVS patchset: 8676 CVS date: 2007/03/16 17:13:57 --- src/audio_out/audio_oss_out.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c index ccb142eb5..12a52b997 100644 --- a/src/audio_out/audio_oss_out.c +++ b/src/audio_out/audio_oss_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_oss_out.c,v 1.118 2007/03/09 23:56:42 dgp85 Exp $ + * $Id: audio_oss_out.c,v 1.119 2007/03/16 17:13:57 dgp85 Exp $ * * 20-8-2001 First implementation of Audio sync and Audio driver separation. * Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk @@ -115,6 +115,13 @@ #define OSS_SYNC_SOFTSYNC 3 #define OSS_SYNC_PROBEBUFFER 4 +/* On FreeBSD the request type is unsigned long rather than int */ +#ifdef __FreeBSD__ +typedef unsigned long ioctl_request_t; +#else +typedef int ioctl_request_t; +#endif + typedef struct oss_driver_s { ao_driver_t ao_driver; @@ -525,7 +532,7 @@ static int ao_oss_get_property (ao_driver_t *this_gen, int property) { if(!this->mixer.mute) { if(this->mixer.fd != -1) { - int cmd = 0; + ioctl_request_t cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -564,7 +571,7 @@ static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) if(!this->mixer.mute) { if(this->mixer.fd != -1) { - int cmd = 0; + ioctl_request_t cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -593,7 +600,7 @@ static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) if(this->mixer.mute) { if(this->mixer.fd != -1) { - int cmd = 0; + ioctl_request_t cmd = 0; int v = 0; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); -- cgit v1.2.3 From 2fa61afb4e8d575c3d5facf4072e91187945e163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 17 Mar 2007 06:59:31 +0000 Subject: Clean up configure checks for OSS support. Check for the various soundcard.h headers, and then include the best one that has been found on the system. Check for definition of SNDCTL_DSP_SETFRAGMENT in those headers. Check for the correct request parameter type for ioctl(), as also modern Linux uses unsigned long. Don't list all the big endian machines (as they aren't reliable to list anyway, some of them might work with both endians), use WORDS_BIGENDIAN instead. CVS patchset: 8697 CVS date: 2007/03/17 06:59:31 --- src/audio_out/audio_oss_out.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c index 12a52b997..793b47650 100644 --- a/src/audio_out/audio_oss_out.c +++ b/src/audio_out/audio_oss_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_oss_out.c,v 1.119 2007/03/16 17:13:57 dgp85 Exp $ + * $Id: audio_oss_out.c,v 1.120 2007/03/17 06:59:31 dgp85 Exp $ * * 20-8-2001 First implementation of Audio sync and Audio driver separation. * Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk @@ -48,20 +48,19 @@ #include #include #include -#if defined(__OpenBSD__) -# include -#elif defined (__FreeBSD__) -# if __FreeBSD__ < 4 -# include -# else -# include -# endif -#else -# include -#endif #include #include +#ifdef HAVE_SYS_SOUNDCARD_H +# include +#endif +#ifdef HAVE_MACHINE_SOUNDCARD_H +# include +#endif +#ifdef HAVE_SOUNDCARD_H +# include +#endif + #define LOG_MODULE "audio_oss_out" #define LOG_VERBOSE /* @@ -86,8 +85,7 @@ #endif #ifndef AFMT_S16_NE -# if defined(sparc) || defined(__sparc__) || defined(PPC) -/* Big endian machines */ +# ifdef WORDS_BIGENDIAN # define AFMT_S16_NE AFMT_S16_BE # else # define AFMT_S16_NE AFMT_S16_LE @@ -115,13 +113,6 @@ #define OSS_SYNC_SOFTSYNC 3 #define OSS_SYNC_PROBEBUFFER 4 -/* On FreeBSD the request type is unsigned long rather than int */ -#ifdef __FreeBSD__ -typedef unsigned long ioctl_request_t; -#else -typedef int ioctl_request_t; -#endif - typedef struct oss_driver_s { ao_driver_t ao_driver; @@ -532,7 +523,7 @@ static int ao_oss_get_property (ao_driver_t *this_gen, int property) { if(!this->mixer.mute) { if(this->mixer.fd != -1) { - ioctl_request_t cmd = 0; + IOCTL_REQUEST_TYPE cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -571,7 +562,7 @@ static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) if(!this->mixer.mute) { if(this->mixer.fd != -1) { - ioctl_request_t cmd = 0; + IOCTL_REQUEST_TYPE cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); @@ -600,7 +591,7 @@ static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) if(this->mixer.mute) { if(this->mixer.fd != -1) { - ioctl_request_t cmd = 0; + IOCTL_REQUEST_TYPE cmd = 0; int v = 0; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); -- cgit v1.2.3 From 5ffabbd9b6ad0cc31b6316d3239326f40ed2db11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 17 Mar 2007 20:57:59 +0000 Subject: Use the Native Endian variants for 16 and 32 bit samples. CVS patchset: 8709 CVS date: 2007/03/17 20:57:59 --- src/audio_out/audio_pulse_out.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index d04856c61..214ad9725 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.11 2007/02/03 10:46:14 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.12 2007/03/17 20:57:59 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -223,14 +223,10 @@ static int ao_pulse_open(ao_driver_t *this_gen, ss.format = PA_SAMPLE_U8; break; case 16: -#ifdef WORDS_BIGENDIAN - ss.format = PA_SAMPLE_S16BE; -#else - ss.format = PA_SAMPLE_S16LE; -#endif + ss.format = PA_SAMPLE_S16NE; break; case 32: - ss.format = PA_SAMPLE_FLOAT32; + ss.format = PA_SAMPLE_FLOAT32NE; break; } -- cgit v1.2.3 From 1faa9f0138196c10ffee925a9398bd4562f8f2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Mon, 19 Mar 2007 23:48:58 +0000 Subject: Don't assume that CoreAudio output is Big Endian (it is not on newer Mac based on Intel CPUs). Patch by Martin Aumueller. CVS patchset: 8723 CVS date: 2007/03/19 23:48:58 --- src/audio_out/audio_coreaudio_out.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_coreaudio_out.c b/src/audio_out/audio_coreaudio_out.c index 80cab6d71..22f53c0ef 100644 --- a/src/audio_out/audio_coreaudio_out.c +++ b/src/audio_out/audio_coreaudio_out.c @@ -265,7 +265,9 @@ static int ao_coreaudio_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate format.mSampleRate = rate; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger +#ifdef WORDS_BIGENDIAN | kLinearPCMFormatFlagIsBigEndian +#endif | kLinearPCMFormatFlagIsPacked; format.mBitsPerChannel = this->bits_per_sample; format.mChannelsPerFrame = this->num_channels; -- cgit v1.2.3 From 62b1bb0c213c37b58e5a7bb8359f41168c34f817 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Thu, 22 Mar 2007 20:44:58 +0000 Subject: Fix crosscompile to use build and host definition from autoconf, rather than using hacksaround. Also replace the whole pthread check with an improved macro originally written for XCB, this way it's not going to try linking the fake -lpthread on Darwin, and it also does not force a -I/usr/local/include on FreeBSD. The new macro respects the same variables set by ports, so that it's even more transparent to FreeBSD users. CVS patchset: 8739 CVS date: 2007/03/22 20:44:58 --- src/audio_out/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/Makefile.am b/src/audio_out/Makefile.am index 918f4829e..d52f700f3 100644 --- a/src/audio_out/Makefile.am +++ b/src/audio_out/Makefile.am @@ -94,7 +94,7 @@ xineplug_ao_out_oss_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_oss_la_LDFLAGS = -avoid-version -module xineplug_ao_out_alsa_la_SOURCES = audio_alsa_out.c -xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(XINE_LIB) $(THREAD_LIBS) +xineplug_ao_out_alsa_la_LIBADD = $(ALSA_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) xineplug_ao_out_alsa_la_CFLAGS = $(VISIBILITY_FLAG) $(ALSA_CFLAGS) xineplug_ao_out_alsa_la_LDFLAGS = -avoid-version -module @@ -141,7 +141,7 @@ xineplug_ao_out_pulseaudio_la_LDFLAGS = -avoid-version -module xineplug_ao_out_directx2_la_SOURCES = audio_directx2_out.c xineplug_ao_out_directx2_la_CPPFLAGS = $(DIRECTX_CPPFLAGS) -xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(THREAD_LIBS) +xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(PTHREAD_LIBS) xineplug_ao_out_directx2_la_CFLAGS = $(VISIBILITY_FLAG) xineplug_ao_out_directx2_la_LDFLAGS = -avoid-version -module -- cgit v1.2.3 From d69b1376b70acc5b721e2bea1cb8a92cb97b8735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 31 Mar 2007 20:58:51 +0000 Subject: Add a mutex on all PulseAudio operations, PA is thread-safe by itself, but xine's plugin wasn't, this caused race conditions similar to the old ones with ALSA output. Also instead of copying two pointers (three with the mutex) from the class to the output instance, just copy a pointer to the class. CVS patchset: 8775 CVS date: 2007/03/31 20:58:51 --- src/audio_out/audio_pulse_out.c | 145 +++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 63 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 214ad9725..5fa945f3d 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.12 2007/03/17 20:57:59 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.13 2007/03/31 20:58:51 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -54,54 +54,40 @@ /* CHECKME: should this be conditional on autotools? */ extern const char *__progname; -typedef struct pulse_driver_s { - - ao_driver_t ao_driver; - - xine_t *xine; - - /** The host to connect to */ - char *host; +typedef struct { + audio_driver_class_t driver_class; + xine_t *xine; - /** The sink to connect to */ - char *sink; + pthread_mutex_t pa_mutex; /*< Mutex controlling PulseAudio access. */ + struct pa_context *context; /*< Pulseaudio connection context */ + struct pa_threaded_mainloop *mainloop; /*< Main event loop object */ +} pulse_class_t; - /** Pulseaudio playback stream object */ - struct pa_stream *stream; +typedef struct pulse_driver_s { + ao_driver_t ao_driver; + xine_t *xine; - /** Pulseaudio connection context */ - struct pa_context *context; + pulse_class_t *pa_class; - /** Main event loop object */ - struct pa_threaded_mainloop *mainloop; + char *host; /*< The host to connect to */ + char *sink; /*< The sink to connect to */ + struct pa_stream *stream; /*< Pulseaudio playback stream object */ - pa_volume_t swvolume; - pa_cvolume cvolume; + pa_volume_t swvolume; + pa_cvolume cvolume; - int capabilities; - int mode; + int capabilities; + int mode; - int32_t sample_rate; - uint32_t num_channels; - uint32_t bits_per_sample; - uint32_t bytes_per_frame; + int32_t sample_rate; + uint32_t num_channels; + uint32_t bits_per_sample; + uint32_t bytes_per_frame; - uint32_t frames_written; + uint32_t frames_written; } pulse_driver_t; -typedef struct { - audio_driver_class_t driver_class; - - xine_t *xine; - - /** Pulseaudio connection context */ - struct pa_context *context; - - /** Main event loop object */ - struct pa_threaded_mainloop *mainloop; -} pulse_class_t; - /** * @brief Callback function called when a stream operation succeed * @param stream Stream which operation has succeeded @@ -117,7 +103,7 @@ static void __xine_pa_stream_success_callback(pa_stream *const stream, const int _x_assert(stream); _x_assert(this); _x_assert(stream == this->stream); - pa_threaded_mainloop_signal(this->mainloop, 0); + pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); } /** @@ -133,9 +119,9 @@ static void __xine_pa_context_success_callback(pa_context *const ctx, const int pulse_driver_t *const this = (pulse_driver_t*)this_gen; _x_assert(ctx); _x_assert(this); - _x_assert(ctx == this->context); + _x_assert(ctx == this->pa_class->context); - pa_threaded_mainloop_signal(this->mainloop, 0); + pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); } /** @@ -156,7 +142,7 @@ static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_in if (is_last < 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", - pa_strerror(pa_context_errno(this->context))); + pa_strerror(pa_context_errno(this->pa_class->context))); return; } @@ -170,14 +156,14 @@ static void __xine_pa_sink_info_callback(pa_context *const ctx, const pa_sink_in static int wait_for_operation(pulse_driver_t *this, pa_operation *o) { - _x_assert(this && o && this->mainloop); + _x_assert(this && o && this->pa_class->mainloop); - pa_threaded_mainloop_lock(this->mainloop); + pa_threaded_mainloop_lock(this->pa_class->mainloop); while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(this->mainloop); + pa_threaded_mainloop_wait(this->pa_class->mainloop); - pa_threaded_mainloop_unlock(this->mainloop); + pa_threaded_mainloop_unlock(this->pa_class->mainloop); return 0; } @@ -235,7 +221,7 @@ static int ao_pulse_open(ao_driver_t *this_gen, goto fail; } - this->stream = pa_stream_new(this->context, "audio stream", &ss, NULL); + this->stream = pa_stream_new(this->pa_class->context, "audio stream", &ss, NULL); _x_assert(this->stream); a.maxlength = pa_bytes_per_second(&ss)*1; @@ -256,7 +242,7 @@ static int ao_pulse_open(ao_driver_t *this_gen, if (streamstate != PA_STREAM_READY) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_pulse_out: Failed to connect to server: %s\n", - pa_strerror(pa_context_errno(this->context))); + pa_strerror(pa_context_errno(this->pa_class->context))); goto fail; } this->frames_written = 0; @@ -293,7 +279,7 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, int size = num_frames * this->bytes_per_frame; int ret = 0; - _x_assert(this->stream && this->context); + _x_assert(this->stream && this->pa_class->context); if (pa_stream_get_state(this->stream) == PA_STREAM_READY) { @@ -332,7 +318,7 @@ static int ao_pulse_delay (ao_driver_t *this_gen) if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) break; - if (pa_context_errno(this->context) != PA_ERR_NODATA) { + if (pa_context_errno(this->pa_class->context) != PA_ERR_NODATA) { /* error */ } } @@ -351,11 +337,15 @@ static void ao_pulse_close(ao_driver_t *this_gen) pulse_driver_t *this = (pulse_driver_t *) this_gen; if (this->stream) { + pthread_mutex_lock(&this->pa_class->pa_mutex); + if (pa_stream_get_state(this->stream) == PA_STREAM_READY) wait_for_operation(this, pa_stream_drain(this->stream, __xine_pa_stream_success_callback, this)); pa_stream_disconnect(this->stream); pa_stream_unref(this->stream); this->stream = NULL; + + pthread_mutex_unlock(&this->pa_class->pa_mutex); } } @@ -377,12 +367,16 @@ static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - if( this->stream && this->context ) + if( this->stream && this->pa_class->context ) { + pthread_mutex_lock(&this->pa_class->pa_mutex); wait_for_operation(this, - pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), + pa_context_get_sink_input_info(this->pa_class->context, pa_stream_get_index(this->stream), __xine_pa_sink_info_callback, this)); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + } return (int) (pa_sw_volume_to_linear(this->swvolume)*100); break; + case AO_PROP_MUTE_VOL: break; } @@ -397,11 +391,13 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: this->swvolume = pa_sw_volume_from_linear((double)value/100.0); - if( this->stream && this->context ) { + if( this->stream && this->pa_class->context ) { + pthread_mutex_lock(&this->pa_class->pa_mutex); pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); wait_for_operation(this, - pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream), + pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream), &this->cvolume, __xine_pa_context_success_callback, this)); + pthread_mutex_unlock(&this->pa_class->pa_mutex); } break; case AO_PROP_MUTE_VOL: @@ -417,13 +413,19 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { switch (cmd) { case AO_CTRL_PLAY_PAUSE: - _x_assert(this->stream && this->context ); + _x_assert(this->stream && this->pa_class->context ); + + pthread_mutex_lock(&this->pa_class->pa_mutex); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) wait_for_operation(this,pa_stream_cork(this->stream, 1, __xine_pa_stream_success_callback, this)); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + break; case AO_CTRL_PLAY_RESUME: - _x_assert(this->stream && this->context); + _x_assert(this->stream && this->pa_class->context); + + pthread_mutex_lock(&this->pa_class->pa_mutex); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) { struct pa_operation *o2, *o1; o1 = pa_stream_prebuf(this->stream, __xine_pa_stream_success_callback, this); @@ -432,13 +434,20 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { o2 = pa_stream_cork(this->stream, 0, __xine_pa_stream_success_callback, this); _x_assert(o2); wait_for_operation(this,o2); } + pthread_mutex_unlock(&this->pa_class->pa_mutex); + break; case AO_CTRL_FLUSH_BUFFERS: - _x_assert(this->stream && this->context); + _x_assert(this->stream && this->pa_class->context); + + pthread_mutex_lock(&this->pa_class->pa_mutex); if(pa_stream_get_state(this->stream) == PA_STREAM_READY) wait_for_operation(this,pa_stream_flush(this->stream, __xine_pa_stream_success_callback, this)); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + this->frames_written = 0; + break; } @@ -510,28 +519,30 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n", this->host ? this->host : "(null)", this->sink ? this->sink : "(null)"); - this->mainloop = class->mainloop; - this->context = class->context; + this->pa_class = class; - if ( pa_context_get_state(this->context) != PA_CONTEXT_READY ){ - pa_context_connect(this->context, this->host, 1, NULL); + pthread_mutex_lock(&this->pa_class->pa_mutex); + if ( pa_context_get_state(this->pa_class->context) != PA_CONTEXT_READY ){ + pa_context_connect(this->pa_class->context, this->host, 1, NULL); do { xine_usec_sleep (100); - ctxstate = pa_context_get_state(this->context); + ctxstate = pa_context_get_state(this->pa_class->context); } while (ctxstate < PA_CONTEXT_READY); if (ctxstate != PA_CONTEXT_READY) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", - pa_strerror(pa_context_errno(this->context))); + pa_strerror(pa_context_errno(this->pa_class->context))); goto fail; } } + pthread_mutex_unlock(&this->pa_class->pa_mutex); return &this->ao_driver; fail: + pthread_mutex_lock(&this->pa_class->pa_mutex); free(this); xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: open_plugin failed.\n"); return NULL; @@ -553,11 +564,14 @@ static void dispose_class (audio_driver_class_t *this_gen) { pulse_class_t *this = (pulse_class_t *) this_gen; + pthread_mutex_lock(&this->pa_mutex); + pa_context_unref(this->context); pa_threaded_mainloop_stop(this->mainloop); pa_threaded_mainloop_free(this->mainloop); + pthread_mutex_destroy(&this->pa_mutex); free (this); } @@ -578,6 +592,9 @@ static void *init_class (xine_t *xine, void *data) { this->xine = xine; + pthread_mutex_init(&this->pa_mutex, NULL); + pthread_mutex_lock(&this->pa_mutex); + this->mainloop = pa_threaded_mainloop_new(); _x_assert(this->mainloop); @@ -586,6 +603,8 @@ static void *init_class (xine_t *xine, void *data) { this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), __progname); _x_assert(this->context); + pthread_mutex_unlock(&this->pa_mutex); + return this; } -- cgit v1.2.3 From a0c5680524d41ff0971b5cc2c7790ac32c15f800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 31 Mar 2007 21:16:22 +0000 Subject: Implement AO_PROP_MUTE_VOL (both set and get), and cleanup the setter and getter methods, returning the correct value in case the property is not implemented. CVS patchset: 8776 CVS date: 2007/03/31 21:16:22 --- src/audio_out/audio_pulse_out.c | 60 ++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 19 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 5fa945f3d..9221cbe5a 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.13 2007/03/31 20:58:51 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.14 2007/03/31 21:16:22 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -363,48 +363,70 @@ static void ao_pulse_exit(ao_driver_t *this_gen) static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { pulse_driver_t *this = (pulse_driver_t *) this_gen; + int result = 0; + if ( ! this->stream || ! this->pa_class->context ) + return 0; + + pthread_mutex_lock(&this->pa_class->pa_mutex); + switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - if( this->stream && this->pa_class->context ) { - pthread_mutex_lock(&this->pa_class->pa_mutex); - wait_for_operation(this, - pa_context_get_sink_input_info(this->pa_class->context, pa_stream_get_index(this->stream), - __xine_pa_sink_info_callback, this)); - pthread_mutex_unlock(&this->pa_class->pa_mutex); - } - return (int) (pa_sw_volume_to_linear(this->swvolume)*100); + wait_for_operation(this, + pa_context_get_sink_input_info(this->pa_class->context, pa_stream_get_index(this->stream), + __xine_pa_sink_info_callback, this)); + result = (pa_sw_volume_to_linear(this->swvolume)*100); break; case AO_PROP_MUTE_VOL: + result = pa_cvolume_is_muted(&this->cvolume); break; } - return 0; + pthread_mutex_unlock(&this->pa_class->pa_mutex); + + return result; } static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value) { pulse_driver_t *this = (pulse_driver_t *) this_gen; + int result = ~value; + + if ( ! this->stream || ! this->pa_class->context ) + return result; + + pthread_mutex_lock(&this->pa_class->pa_mutex); switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: this->swvolume = pa_sw_volume_from_linear((double)value/100.0); - if( this->stream && this->pa_class->context ) { - pthread_mutex_lock(&this->pa_class->pa_mutex); - pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); - wait_for_operation(this, - pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream), - &this->cvolume, __xine_pa_context_success_callback, this)); - pthread_mutex_unlock(&this->pa_class->pa_mutex); - } + pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); + wait_for_operation(this, + pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream), + &this->cvolume, __xine_pa_context_success_callback, this)); + + result = value; break; + case AO_PROP_MUTE_VOL: + if ( value ) + pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels); + else + pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); + + wait_for_operation(this, + pa_context_set_sink_input_volume(this->pa_class->context, pa_stream_get_index(this->stream), + &this->cvolume, __xine_pa_context_success_callback, this)); + + result = value; break; } - return 0; + pthread_mutex_unlock(&this->pa_class->pa_mutex); + + return result; } static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { -- cgit v1.2.3 From 356c822e295cb4417fe5f4f821a36e17ea24e73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 31 Mar 2007 21:22:58 +0000 Subject: Lock/Unlock on opening. CVS patchset: 8777 CVS date: 2007/03/31 21:22:58 --- src/audio_out/audio_pulse_out.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index 9221cbe5a..f0b4d659a 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.14 2007/03/31 21:16:22 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.15 2007/03/31 21:22:58 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -229,11 +229,15 @@ static int ao_pulse_open(ao_driver_t *this_gen, a.prebuf = a.tlength/2; a.minreq = a.tlength/10; + pthread_mutex_lock(&this->pa_class->pa_mutex); + pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); pa_stream_connect_playback(this->stream, this->sink, &a, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, &this->cvolume, NULL); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + do { xine_usec_sleep (100); -- cgit v1.2.3 From fc47d546f3ddf86f117a331ff870316511e5505d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sat, 31 Mar 2007 22:06:54 +0000 Subject: Set the volume of the stream to 100% by default. CVS patchset: 8778 CVS date: 2007/03/31 22:06:54 --- src/audio_out/audio_pulse_out.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index f0b4d659a..dbfc4b9f0 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.15 2007/03/31 21:22:58 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.16 2007/03/31 22:06:54 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -231,12 +231,9 @@ static int ao_pulse_open(ao_driver_t *this_gen, pthread_mutex_lock(&this->pa_class->pa_mutex); - pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); pa_stream_connect_playback(this->stream, this->sink, &a, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, - &this->cvolume, NULL); - - pthread_mutex_unlock(&this->pa_class->pa_mutex); + NULL, NULL); do { xine_usec_sleep (100); @@ -244,6 +241,8 @@ static int ao_pulse_open(ao_driver_t *this_gen, streamstate = pa_stream_get_state(this->stream); } while (streamstate < PA_STREAM_READY); + pthread_mutex_unlock(&this->pa_class->pa_mutex); + if (streamstate != PA_STREAM_READY) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_pulse_out: Failed to connect to server: %s\n", pa_strerror(pa_context_errno(this->pa_class->context))); @@ -251,6 +250,8 @@ static int ao_pulse_open(ao_driver_t *this_gen, } this->frames_written = 0; + this->ao_driver.set_property(this, AO_PROP_PCM_VOL, 100); + return this->sample_rate; fail: @@ -504,7 +505,6 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da AO_CAP_16BITS | AO_CAP_FLOAT32; this->sample_rate = 0; - this->swvolume = PA_VOLUME_NORM; this->ao_driver.get_capabilities = ao_pulse_get_capabilities; this->ao_driver.get_property = ao_pulse_get_property; -- cgit v1.2.3 From b622467479eebe6efc02374f0f7e08fcc2caaae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Sun, 1 Apr 2007 00:32:29 +0000 Subject: Try to improve response when the plugin can't connect to PulseAudio. Unfortunately if the server dies during playback xine will be too messed up to recover. This is the same issue as unplugged USB devices, it requires a proper generic handling of these cases. CVS patchset: 8779 CVS date: 2007/04/01 00:32:29 --- src/audio_out/audio_pulse_out.c | 165 +++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 52 deletions(-) (limited to 'src/audio_out') diff --git a/src/audio_out/audio_pulse_out.c b/src/audio_out/audio_pulse_out.c index dbfc4b9f0..9e6089730 100644 --- a/src/audio_out/audio_pulse_out.c +++ b/src/audio_out/audio_pulse_out.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_pulse_out.c,v 1.16 2007/03/31 22:06:54 dgp85 Exp $ + * $Id: audio_pulse_out.c,v 1.17 2007/04/01 00:32:29 dgp85 Exp $ * * ao plugin for pulseaudio (rename of polypaudio): * http://0pointer.de/lennart/projects/pulsaudio/ @@ -106,6 +106,34 @@ static void __xine_pa_stream_success_callback(pa_stream *const stream, const int pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); } +/** + * @brief Callback function called when the state of the context is changed + * @param ctx Context which operation has succeeded + * @param this_gen pulse_driver_t pointer for the PulseAudio output + * instance. + */ +static void __xine_pa_context_status_callback(pa_context *const ctx, void *const this_gen) +{ + pulse_driver_t *const this = (pulse_driver_t*)this_gen; + + _x_assert(ctx); _x_assert(this); + _x_assert(ctx == this->pa_class->context); + + switch (pa_context_get_state(ctx)) { + case PA_CONTEXT_READY: + case PA_CONTEXT_TERMINATED: + case PA_CONTEXT_FAILED: + pa_threaded_mainloop_signal(this->pa_class->mainloop, 0); + break; + + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + } +} + /** * @brief Callback function called when a context operation succeed * @param ctx Context which operation has succeeded @@ -221,6 +249,39 @@ static int ao_pulse_open(ao_driver_t *this_gen, goto fail; } + pthread_mutex_lock(&this->pa_class->pa_mutex); + if ( this->pa_class->context && pa_context_get_state(this->pa_class->context) > PA_CONTEXT_READY ) { + pa_context_unref(this->pa_class->context); + this->pa_class->context = NULL; + } + + if ( this->pa_class->context == NULL ) { + this->pa_class->context = pa_context_new(pa_threaded_mainloop_get_api(this->pa_class->mainloop), + __progname); + } + + pa_context_ref(this->pa_class->context); + + if ( pa_context_get_state(this->pa_class->context) == PA_CONTEXT_UNCONNECTED ) { + int ret; + + pa_threaded_mainloop_lock(this->pa_class->mainloop); + ret = pa_context_connect(this->pa_class->context, this->host, 1, NULL); + if ( ret < 0 ) + goto fail; + + pa_context_set_state_callback(this->pa_class->context, __xine_pa_context_status_callback, this); + + pa_threaded_mainloop_wait(this->pa_class->mainloop); + pa_threaded_mainloop_unlock(this->pa_class->mainloop); + } + + if (pa_context_get_state(this->pa_class->context) != PA_CONTEXT_READY) { + xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", + pa_strerror(pa_context_errno(this->pa_class->context))); + goto fail; + } + this->stream = pa_stream_new(this->pa_class->context, "audio stream", &ss, NULL); _x_assert(this->stream); @@ -229,8 +290,6 @@ static int ao_pulse_open(ao_driver_t *this_gen, a.prebuf = a.tlength/2; a.minreq = a.tlength/10; - pthread_mutex_lock(&this->pa_class->pa_mutex); - pa_stream_connect_playback(this->stream, this->sink, &a, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL); @@ -255,6 +314,8 @@ static int ao_pulse_open(ao_driver_t *this_gen, return this->sample_rate; fail: + pa_threaded_mainloop_unlock(this->pa_class->mainloop); + pthread_mutex_unlock(&this->pa_class->pa_mutex); this_gen->close(this_gen); return 0; } @@ -284,10 +345,11 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, int size = num_frames * this->bytes_per_frame; int ret = 0; - _x_assert(this->stream && this->pa_class->context); - - if (pa_stream_get_state(this->stream) == PA_STREAM_READY) { + if ( !this->stream || !this->pa_class->context) + return -1; + switch( pa_stream_get_state(this->stream) ) { + case PA_STREAM_READY: while (size > 0) { size_t l; @@ -307,6 +369,8 @@ static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, if (pa_stream_get_state(this->stream) == PA_STREAM_READY) ret = 1; + + break; } return ret; @@ -319,15 +383,25 @@ static int ao_pulse_delay (ao_driver_t *this_gen) pa_usec_t latency = 0; int delay_frames; - for (;;) { - if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) - break; + if ( ! this->stream ) return this->frames_written; - if (pa_context_errno(this->pa_class->context) != PA_ERR_NODATA) { - /* error */ - } + pthread_mutex_lock(&this->pa_class->pa_mutex); + + if (pa_stream_get_latency(this->stream, &latency, NULL) < 0) { + pa_context_unref(this->pa_class->context); + this->pa_class->context = NULL; + + pa_stream_disconnect(this->stream); + pa_stream_unref(this->stream); + this->stream = NULL; + + pthread_mutex_unlock(&this->pa_class->pa_mutex); + + return 0; } + pthread_mutex_unlock(&this->pa_class->pa_mutex); + /* convert latency (us) to frame units. */ delay_frames = (int)(latency * this->sample_rate / 1000000); @@ -350,6 +424,8 @@ static void ao_pulse_close(ao_driver_t *this_gen) pa_stream_unref(this->stream); this->stream = NULL; + pa_context_unref(this->pa_class->context); + pthread_mutex_unlock(&this->pa_class->pa_mutex); } } @@ -378,10 +454,15 @@ static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: - wait_for_operation(this, - pa_context_get_sink_input_info(this->pa_class->context, pa_stream_get_index(this->stream), - __xine_pa_sink_info_callback, this)); - result = (pa_sw_volume_to_linear(this->swvolume)*100); + { + pa_operation *o = pa_context_get_sink_input_info(this->pa_class->context, + pa_stream_get_index(this->stream), + __xine_pa_sink_info_callback, this); + if ( ! o ) return 0; + wait_for_operation(this, o); + + result = (pa_sw_volume_to_linear(this->swvolume)*100); + } break; case AO_PROP_MUTE_VOL: @@ -437,6 +518,8 @@ static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { pulse_driver_t *this = (pulse_driver_t *) this_gen; + if ( ! this->stream ) return 0; + switch (cmd) { case AO_CTRL_PLAY_PAUSE: @@ -484,9 +567,7 @@ static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { pulse_class_t *class = (pulse_class_t *) class_gen; pulse_driver_t *this; - char hn[128]; char *device; - pa_context_state_t ctxstate; lprintf ("audio_pulse_out: open_plugin called\n"); @@ -505,6 +586,8 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da AO_CAP_16BITS | AO_CAP_FLOAT32; this->sample_rate = 0; + this->host = NULL; + this->sink = NULL; this->ao_driver.get_capabilities = ao_pulse_get_capabilities; this->ao_driver.get_property = ao_pulse_get_property; @@ -528,18 +611,13 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da 10, NULL, NULL); - if (device && strlen(device)) { - int i = strcspn(device, ":"); - if (i >= sizeof(hn)) - i = sizeof(hn)-1; - - if (i > 0) { - strncpy(this->host = hn, device, i); - hn[i] = 0; - } - - if (device[i] == ':') - this->sink = device+i+1; + if (device && *device) { + char *sep = strchr(device, ':'); + if ( sep ) { + this->host = strndup(device, sep-device); + this->sink = strdup(&sep[1]); + } else + this->host = strdup(device); } xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n", @@ -547,28 +625,10 @@ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *da this->pa_class = class; - pthread_mutex_lock(&this->pa_class->pa_mutex); - if ( pa_context_get_state(this->pa_class->context) != PA_CONTEXT_READY ){ - pa_context_connect(this->pa_class->context, this->host, 1, NULL); - - do { - xine_usec_sleep (100); - - ctxstate = pa_context_get_state(this->pa_class->context); - } while (ctxstate < PA_CONTEXT_READY); - - if (ctxstate != PA_CONTEXT_READY) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to connect to server: %s\n", - pa_strerror(pa_context_errno(this->pa_class->context))); - goto fail; - } - } - - pthread_mutex_unlock(&this->pa_class->pa_mutex); return &this->ao_driver; fail: - pthread_mutex_lock(&this->pa_class->pa_mutex); + pthread_mutex_unlock(&this->pa_class->pa_mutex); free(this); xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: open_plugin failed.\n"); return NULL; @@ -592,7 +652,8 @@ static void dispose_class (audio_driver_class_t *this_gen) { pthread_mutex_lock(&this->pa_mutex); - pa_context_unref(this->context); + if ( this->context ) + pa_context_unref(this->context); pa_threaded_mainloop_stop(this->mainloop); pa_threaded_mainloop_free(this->mainloop); @@ -626,8 +687,7 @@ static void *init_class (xine_t *xine, void *data) { pa_threaded_mainloop_start(this->mainloop); - this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), __progname); - _x_assert(this->context); + this->context = NULL; pthread_mutex_unlock(&this->pa_mutex); @@ -648,3 +708,4 @@ const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; + -- cgit v1.2.3 From 6ff7b823ea37c8baa725fad659b06b23e1d92d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Mon, 2 Apr 2007 20:44:04 +0200 Subject: Migrate all .cvsignore files to .hgignore. --HG-- rename : .cvsignore => .hgignore rename : doc/.cvsignore => doc/.hgignore rename : doc/faq/.cvsignore => doc/faq/.hgignore rename : doc/hackersguide/.cvsignore => doc/hackersguide/.hgignore rename : doc/man/.cvsignore => doc/man/.hgignore rename : doc/man/en/.cvsignore => doc/man/en/.hgignore rename : include/.cvsignore => include/.hgignore rename : intl/.cvsignore => intl/.hgignore rename : lib/.cvsignore => lib/.hgignore rename : m4/.cvsignore => m4/.hgignore rename : misc/.cvsignore => misc/.hgignore rename : misc/fonts/.cvsignore => misc/fonts/.hgignore rename : po/.cvsignore => po/.hgignore rename : src/.cvsignore => src/.hgignore rename : src/audio_out/.cvsignore => src/audio_out/.hgignore rename : src/combined/.cvsignore => src/combined/.hgignore rename : src/demuxers/.cvsignore => src/demuxers/.hgignore rename : src/dxr3/.cvsignore => src/dxr3/.hgignore rename : src/input/.cvsignore => src/input/.hgignore rename : src/input/dvb/.cvsignore => src/input/dvb/.hgignore rename : src/input/libdvdnav/.cvsignore => src/input/libdvdnav/.hgignore rename : src/input/libreal/.cvsignore => src/input/libreal/.hgignore rename : src/input/librtsp/.cvsignore => src/input/librtsp/.hgignore rename : src/input/vcd/.cvsignore => src/input/vcd/.hgignore rename : src/input/vcd/libcdio/.cvsignore => src/input/vcd/libcdio/.hgignore rename : src/input/vcd/libcdio/MSWindows/.cvsignore => src/input/vcd/libcdio/MSWindows/.hgignore rename : src/input/vcd/libcdio/cdio/.cvsignore => src/input/vcd/libcdio/cdio/.hgignore rename : src/input/vcd/libcdio/image/.cvsignore => src/input/vcd/libcdio/image/.hgignore rename : src/input/vcd/libvcd/.cvsignore => src/input/vcd/libvcd/.hgignore rename : src/input/vcd/libvcd/libvcd/.cvsignore => src/input/vcd/libvcd/libvcd/.hgignore rename : src/liba52/.cvsignore => src/liba52/.hgignore rename : src/libdts/.cvsignore => src/libdts/.hgignore rename : src/libfaad/.cvsignore => src/libfaad/.hgignore rename : src/libfaad/codebook/.cvsignore => src/libfaad/codebook/.hgignore rename : src/libffmpeg/.cvsignore => src/libffmpeg/.hgignore rename : src/libffmpeg/libavcodec/.cvsignore => src/libffmpeg/libavcodec/.hgignore rename : src/libffmpeg/libavcodec/alpha/.cvsignore => src/libffmpeg/libavcodec/alpha/.hgignore rename : src/libffmpeg/libavcodec/armv4l/.cvsignore => src/libffmpeg/libavcodec/armv4l/.hgignore rename : src/libffmpeg/libavcodec/i386/.cvsignore => src/libffmpeg/libavcodec/i386/.hgignore rename : src/libffmpeg/libavcodec/libpostproc/.cvsignore => src/libffmpeg/libavcodec/libpostproc/.hgignore rename : src/libffmpeg/libavcodec/mlib/.cvsignore => src/libffmpeg/libavcodec/mlib/.hgignore rename : src/libffmpeg/libavcodec/ppc/.cvsignore => src/libffmpeg/libavcodec/ppc/.hgignore rename : src/libffmpeg/libavcodec/sparc/.cvsignore => src/libffmpeg/libavcodec/sparc/.hgignore rename : src/libffmpeg/libavutil/.cvsignore => src/libffmpeg/libavutil/.hgignore rename : src/libflac/.cvsignore => src/libflac/.hgignore rename : src/liblpcm/.cvsignore => src/liblpcm/.hgignore rename : src/libmad/.cvsignore => src/libmad/.hgignore rename : src/libmpeg2/.cvsignore => src/libmpeg2/.hgignore rename : src/libmpeg2new/.cvsignore => src/libmpeg2new/.hgignore rename : src/libmpeg2new/include/.cvsignore => src/libmpeg2new/include/.hgignore rename : src/libmpeg2new/libmpeg2/.cvsignore => src/libmpeg2new/libmpeg2/.hgignore rename : src/libmusepack/.cvsignore => src/libmusepack/.hgignore rename : src/libmusepack/musepack/.cvsignore => src/libmusepack/musepack/.hgignore rename : src/libreal/.cvsignore => src/libreal/.hgignore rename : src/libspeex/.cvsignore => src/libspeex/.hgignore rename : src/libspucc/.cvsignore => src/libspucc/.hgignore rename : src/libspucmml/.cvsignore => src/libspucmml/.hgignore rename : src/libspudec/.cvsignore => src/libspudec/.hgignore rename : src/libspudvb/.cvsignore => src/libspudvb/.hgignore rename : src/libsputext/.cvsignore => src/libsputext/.hgignore rename : src/libtheora/.cvsignore => src/libtheora/.hgignore rename : src/libvorbis/.cvsignore => src/libvorbis/.hgignore rename : src/libw32dll/.cvsignore => src/libw32dll/.hgignore rename : src/libw32dll/DirectShow/.cvsignore => src/libw32dll/DirectShow/.hgignore rename : src/libw32dll/dmo/.cvsignore => src/libw32dll/dmo/.hgignore rename : src/libw32dll/qtx/.cvsignore => src/libw32dll/qtx/.hgignore rename : src/libw32dll/qtx/qtxsdk/.cvsignore => src/libw32dll/qtx/qtxsdk/.hgignore rename : src/libw32dll/wine/.cvsignore => src/libw32dll/wine/.hgignore rename : src/libxineadec/.cvsignore => src/libxineadec/.hgignore rename : src/libxineadec/gsm610/.cvsignore => src/libxineadec/gsm610/.hgignore rename : src/libxineadec/nosefart/.cvsignore => src/libxineadec/nosefart/.hgignore rename : src/libxinevdec/.cvsignore => src/libxinevdec/.hgignore rename : src/post/.cvsignore => src/post/.hgignore rename : src/post/audio/.cvsignore => src/post/audio/.hgignore rename : src/post/deinterlace/.cvsignore => src/post/deinterlace/.hgignore rename : src/post/deinterlace/plugins/.cvsignore => src/post/deinterlace/plugins/.hgignore rename : src/post/goom/.cvsignore => src/post/goom/.hgignore rename : src/post/mosaico/.cvsignore => src/post/mosaico/.hgignore rename : src/post/planar/.cvsignore => src/post/planar/.hgignore rename : src/post/visualizations/.cvsignore => src/post/visualizations/.hgignore rename : src/video_out/.cvsignore => src/video_out/.hgignore rename : src/video_out/libdha/.cvsignore => src/video_out/libdha/.hgignore rename : src/video_out/libdha/bin/.cvsignore => src/video_out/libdha/bin/.hgignore rename : src/video_out/libdha/kernelhelper/.cvsignore => src/video_out/libdha/kernelhelper/.hgignore rename : src/video_out/libdha/oth/.cvsignore => src/video_out/libdha/oth/.hgignore rename : src/video_out/libdha/sysdep/.cvsignore => src/video_out/libdha/sysdep/.hgignore rename : src/video_out/macosx/.cvsignore => src/video_out/macosx/.hgignore rename : src/video_out/vidix/.cvsignore => src/video_out/vidix/.hgignore rename : src/video_out/vidix/drivers/.cvsignore => src/video_out/vidix/drivers/.hgignore rename : src/xine-engine/.cvsignore => src/xine-engine/.hgignore rename : src/xine-utils/.cvsignore => src/xine-utils/.hgignore rename : win32/.cvsignore => win32/.hgignore rename : win32/include/.cvsignore => win32/include/.hgignore --- src/audio_out/.cvsignore | 6 ------ src/audio_out/.hgignore | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 src/audio_out/.cvsignore create mode 100644 src/audio_out/.hgignore (limited to 'src/audio_out') diff --git a/src/audio_out/.cvsignore b/src/audio_out/.cvsignore deleted file mode 100644 index 7d926a554..000000000 --- a/src/audio_out/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -Makefile.in -.libs -.deps -*.lo -*.la diff --git a/src/audio_out/.hgignore b/src/audio_out/.hgignore new file mode 100644 index 000000000..7d926a554 --- /dev/null +++ b/src/audio_out/.hgignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +.libs +.deps +*.lo +*.la -- cgit v1.2.3