[PATCH] alsa-plugins: Pulse: only underrun if no more data has been written
If more data has already been written after the underrun, the underrun will automatically end and therefore we should not report it or restart the stream.
Signed-off-by: David Henningsson david.henningsson@canonical.com --- configure.in | 7 +++++++ pulse/pcm_pulse.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/configure.in b/configure.in index ccf59ba..f6886b1 100644 --- a/configure.in +++ b/configure.in @@ -31,8 +31,14 @@ AC_ARG_ENABLE([pulseaudio],
if test "x$enable_pulseaudio" != "xno"; then PKG_CHECK_MODULES(pulseaudio, [libpulse >= 0.9.11], [HAVE_PULSE=yes], [HAVE_PULSE=no]) + PKG_CHECK_MODULES(pulseaudio_099, [libpulse >= 0.99.1], + [HAVE_PULSE_UNDERRUN_INDEX=yes], [HAVE_PULSE_UNDERRUN_INDEX=no]) + fi AM_CONDITIONAL(HAVE_PULSE, test x$HAVE_PULSE = xyes) +if test "$HAVE_PULSE_UNDERRUN_INDEX" = "yes"; then + AC_DEFINE([HAVE_PULSE_UNDERRUN_INDEX], 1, Pulseaudio underrun index available) +fi
AC_ARG_ENABLE([samplerate], AS_HELP_STRING([--disable-samplerate], [Disable building of samplerate plugin])) @@ -185,6 +191,7 @@ echo "Pulseaudio plugin: $HAVE_PULSE" if test "$HAVE_PULSE" = "yes"; then echo " pulseaudio_CFLAGS: $pulseaudio_CFLAGS" echo " pulseaudio_LIBS: $pulseaudio_LIBS" + echo " pulseaudio underrun index: $HAVE_PULSE_UNDERRUN_INDEX" fi echo "Samplerate plugin: $HAVE_SAMPLERATE" if test "$HAVE_SAMPLERATE" = "yes"; then diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c index d6c6792..61f1c0c 100644 --- a/pulse/pcm_pulse.c +++ b/pulse/pcm_pulse.c @@ -26,6 +26,10 @@ #include <alsa/asoundlib.h> #include <alsa/pcm_external.h>
+#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "pulse.h"
typedef struct snd_pcm_pulse { @@ -39,9 +43,10 @@ typedef struct snd_pcm_pulse { size_t last_size; size_t ptr; int underrun; - int handle_underrun; + int handle_underrun; /* can be 0=never, 1=always or 2,3=only if more data has not been written */
size_t offset; + int64_t written;
pa_stream *stream;
@@ -459,6 +464,7 @@ static snd_pcm_sframes_t pulse_write(snd_pcm_ioplug_t * io, }
/* Make sure the buffer pointer is in sync */ + pcm->written += writebytes; pcm->last_size -= writebytes; ret = update_ptr(pcm); if (ret < 0) @@ -594,7 +600,12 @@ static void stream_underrun_cb(pa_stream * p, void *userdata) if (!pcm->p) return;
- pcm->underrun = 1; + if (pcm->handle_underrun == 1 +#ifdef HAVE_PULSE_UNDERRUN_INDEX + || pcm->written <= pa_stream_get_underflow_index(p) +#endif + ) + pcm->underrun = 1; }
static void stream_latency_cb(pa_stream *p, void *userdata) { @@ -691,6 +702,7 @@ static int pulse_prepare(snd_pcm_ioplug_t * io) goto finish; }
+ pcm->written = 0; pa_stream_set_state_callback(pcm->stream, stream_state_cb, pcm); pa_stream_set_latency_update_callback(pcm->stream, stream_latency_cb, pcm);
@@ -983,7 +995,11 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse) const char *server = NULL; const char *device = NULL; const char *fallback_name = NULL; +#ifdef HAVE_PULSE_UNDERRUN_INDEX + int handle_underrun = 2; +#else int handle_underrun = 0; +#endif int err; snd_pcm_pulse_t *pcm;
@@ -1017,6 +1033,14 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse) handle_underrun = err; continue; } + if (strcmp(id, "handle_underrun_detect") == 0) { + if ((err = snd_config_get_bool(n)) < 0) { + SNDERR("Invalid value for %s", id); + return -EINVAL; + } + handle_underrun = err ? handle_underrun | 2 : handle_underrun & ~2; + continue; + } if (strcmp(id, "fallback") == 0) { if (snd_config_get_string(n, &fallback_name) < 0) { SNDERR("Invalid value for %s", id);
participants (1)
-
David Henningsson