[arch-commits] Commit in alsa-plugins/trunk (2 files)
Jan Steffens
heftig at archlinux.org
Fri Nov 19 16:25:41 UTC 2010
Date: Friday, November 19, 2010 @ 11:25:41
Author: heftig
Revision: 99957
Oops, forgot patches
Added:
alsa-plugins/trunk/Add_handle_underrun_option.patch
alsa-plugins/trunk/Fix_invalid_buffer_pointer_return_value.patch
-----------------------------------------------+
Add_handle_underrun_option.patch | 86 ++++++++++++++++++++++++
Fix_invalid_buffer_pointer_return_value.patch | 75 ++++++++++++++++++++
2 files changed, 161 insertions(+)
Added: Add_handle_underrun_option.patch
===================================================================
--- Add_handle_underrun_option.patch (rev 0)
+++ Add_handle_underrun_option.patch 2010-11-19 16:25:41 UTC (rev 99957)
@@ -0,0 +1,86 @@
+From: Takashi Iwai <tiwai at suse.de>
+Date: Fri, 9 Jul 2010 12:05:03 +0000 (+0200)
+Subject: pulse: Add handle_underrun option
+X-Git-Url: http://git.alsa-project.org/?p=alsa-plugins.git;a=commitdiff_plain;h=c20d516e229620129ee20175d8fee8511cc3a4bd
+
+pulse: Add handle_underrun option
+
+Added a config option "handle_underrun" to specify whether pulse plugin
+handles the underrun reported from PA. The default value is now set to
+false, i.e. it will ignore underruns in PA (for good reasons below).
+You can take back to the old behavior by setting handle_underrun true.
+
+The original idea was brought by David Henningsson <diwic at ubuntu.com>,
+while this patch is simplified and makes the behavior configurable.
+
+The reasons for avoiding underruns (cited from David's original patch):
+
+ Reporting underruns to ALSA seems to do more bad than good, for these reasons:
+ * If pulseaudio gets an underrun, the normal way to end that underrun is to
+ feed it with more buffers. This is different from the ALSA way of dealing
+ with underruns, which requires hardware buffer pointers to be reset.
+ * In addition, underrun signals are delivered asynchronously from pulseaudio.
+ This means that there might be more buffers on the way to pulseaudio when
+ the underrun is reported, making the underrun obsolete. Unfortunately,
+ there is currently no known way to determine whether this is the case or
+ not.
+
+Signed-off-by: Takashi Iwai <tiwai at suse.de>
+---
+
+diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c
+index b322898..2df0a80 100644
+--- a/pulse/pcm_pulse.c
++++ b/pulse/pcm_pulse.c
+@@ -39,6 +39,7 @@ typedef struct snd_pcm_pulse {
+ size_t last_size;
+ size_t ptr;
+ int underrun;
++ int handle_underrun;
+
+ size_t offset;
+
+@@ -696,8 +697,9 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
+ if (io->stream == SND_PCM_STREAM_PLAYBACK) {
+ pa_stream_set_write_callback(pcm->stream,
+ stream_request_cb, pcm);
+- pa_stream_set_underflow_callback(pcm->stream,
+- stream_underrun_cb, pcm);
++ if (pcm->handle_underrun)
++ pa_stream_set_underflow_callback(pcm->stream,
++ stream_underrun_cb, pcm);
+ r = pa_stream_connect_playback(pcm->stream, pcm->device,
+ &pcm->buffer_attr,
+ PA_STREAM_AUTO_TIMING_UPDATE |
+@@ -980,6 +982,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse)
+ snd_config_iterator_t i, next;
+ const char *server = NULL;
+ const char *device = NULL;
++ int handle_underrun = 0;
+ int err;
+ snd_pcm_pulse_t *pcm;
+
+@@ -1005,6 +1008,14 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse)
+ }
+ continue;
+ }
++ if (strcmp(id, "handle_underrun") == 0) {
++ if ((err = snd_config_get_bool(n)) < 0) {
++ SNDERR("Invalid value for %s", id);
++ return -EINVAL;
++ }
++ handle_underrun = err;
++ continue;
++ }
+ SNDERR("Unknown field %s", id);
+ return -EINVAL;
+ }
+@@ -1028,6 +1039,8 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse)
+ goto error;
+ }
+
++ pcm->handle_underrun = handle_underrun;
++
+ err = pulse_connect(pcm->p, server);
+ if (err < 0)
+ goto error;
Added: Fix_invalid_buffer_pointer_return_value.patch
===================================================================
--- Fix_invalid_buffer_pointer_return_value.patch (rev 0)
+++ Fix_invalid_buffer_pointer_return_value.patch 2010-11-19 16:25:41 UTC (rev 99957)
@@ -0,0 +1,75 @@
+From: David Henningsson <diwic at ubuntu.com>
+Date: Sat, 9 Jan 2010 08:09:14 +0000 (+0100)
+Subject: pulse: Fix invalid buffer pointer return value
+X-Git-Url: http://git.alsa-project.org/?p=alsa-plugins.git;a=commitdiff_plain;h=1675414eca06dcfc20899adf104ace05acfe26a0
+
+pulse: Fix invalid buffer pointer return value
+
+This patch improves recovering from underruns, and prevents hangs inside
+snd_pcm_write* and snd_pcm_read* due to snd_pcm_avail* returning too
+low values. It especially helps low latency situations.
+
+Signed-off-by: David Henningsson <diwic at ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai at suse.de>
+---
+
+diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c
+index 02a837e..b322898 100644
+--- a/pulse/pcm_pulse.c
++++ b/pulse/pcm_pulse.c
+@@ -90,6 +90,10 @@ static int update_ptr(snd_pcm_pulse_t *pcm)
+ if (pcm->io.stream == SND_PCM_STREAM_CAPTURE)
+ size -= pcm->offset;
+
++ /* Prevent accidental overrun of the fake ringbuffer */
++ if (size >= pcm->buffer_attr.tlength)
++ size = pcm->buffer_attr.tlength-1;
++
+ if (size > pcm->last_size) {
+ pcm->ptr += size - pcm->last_size;
+ pcm->ptr %= pcm->buffer_attr.tlength;
+@@ -424,6 +428,7 @@ static snd_pcm_sframes_t pulse_write(snd_pcm_ioplug_t * io,
+ snd_pcm_pulse_t *pcm = io->private_data;
+ const char *buf;
+ snd_pcm_sframes_t ret = 0;
++ size_t writebytes;
+
+ assert(pcm);
+
+@@ -445,13 +450,15 @@ static snd_pcm_sframes_t pulse_write(snd_pcm_ioplug_t * io,
+ (char *) areas->addr + (areas->first +
+ areas->step * offset) / 8;
+
+- ret = pa_stream_write(pcm->stream, buf, size * pcm->frame_size, NULL, 0, 0);
++ writebytes = size * pcm->frame_size;
++ ret = pa_stream_write(pcm->stream, buf, writebytes, NULL, 0, 0);
+ if (ret < 0) {
+ ret = -EIO;
+ goto finish;
+ }
+
+ /* Make sure the buffer pointer is in sync */
++ pcm->last_size -= writebytes;
+ ret = update_ptr(pcm);
+ if (ret < 0)
+ goto finish;
+@@ -528,6 +535,7 @@ static snd_pcm_sframes_t pulse_read(snd_pcm_ioplug_t * io,
+
+ dst_buf = (char *) dst_buf + frag_length;
+ remain_size -= frag_length;
++ pcm->last_size -= frag_length;
+ }
+
+ /* Make sure the buffer pointer is in sync */
+@@ -730,6 +738,11 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
+ pcm->offset = 0;
+ pcm->underrun = 0;
+
++ /* Reset fake ringbuffer */
++ pcm->last_size = 0;
++ pcm->ptr = 0;
++ update_ptr(pcm);
++
+ finish:
+ pa_threaded_mainloop_unlock(pcm->p->mainloop);
+
More information about the arch-commits
mailing list