[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