[Bug 692953] alsa modules are silent or noisy after several hours of use
GStreamer (bugzilla.gnome.org)
bugzilla at gnome.org
Tue Sep 10 16:59:39 PDT 2013
https://bugzilla.gnome.org/show_bug.cgi?id=692953
GStreamer | gst-plugins-base | 1.0.9
--- Comment #132 from Thomas DEBESSE <thomas.debesse at rcf.fr> 2013-09-10 23:59:30 UTC ---
Remember Comment #42, we have logged this:
1:39:18.548386467 26625 0x7f8b2c003a30 DEBUG alsa
gstalsasink.c:1014:gst_alsasink_write:<alsasink0> wait error, -32
##############################################################################
I found that in gst-plugins-base/ext/alsa/gstalsasink.c:
---8<-------------------------------------------------------------------------
static gint
> gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
> {
> GstAlsaSink *alsa;
> gint err;
> gint cptr;
> gint16 *ptr = data;
>
> alsa = GST_ALSA_SINK (asink);
>
> if (alsa->iec958 && alsa->need_swap) {
> guint i;
>
> GST_DEBUG_OBJECT (asink, "swapping bytes");
> for (i = 0; i < length / 2; i++) {
> ptr[i] = GUINT16_SWAP_LE_BE (ptr[i]);
> }
> }
>
> GST_LOG_OBJECT (asink, "received audio samples buffer of %u bytes", length);
>
> cptr = length / alsa->bpf;
>
> GST_ALSA_SINK_LOCK (asink);
> while (cptr > 0) {
> /* start by doing a blocking wait for free space. Set the timeout
> * to 4 times the period time */
> err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
> if (err < 0) {
> GST_DEBUG_OBJECT (asink, "wait error, %d", err);
> } else {
> GST_DELAY_SINK_LOCK (asink);
> err = snd_pcm_writei (alsa->handle, ptr, cptr);
> GST_DELAY_SINK_UNLOCK (asink);
> }
>
> GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr);
> if (err < 0) {
> GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
> if (err == -EAGAIN) {
> continue;
> } else if (err == -ENODEV) {
> goto device_disappeared;
> } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
> goto write_error;
> }
> continue;
> }
>
> ptr += snd_pcm_frames_to_bytes (alsa->handle, err);
> cptr -= err;
> }
> GST_ALSA_SINK_UNLOCK (asink);
>
> return length - (cptr * alsa->bpf);
>
> write_error:
> {
> GST_ALSA_SINK_UNLOCK (asink);
> return length; /* skip one period */
> }
> device_disappeared:
> {
> GST_ELEMENT_ERROR (asink, RESOURCE, WRITE,
> (_("Error outputting to audio device. "
> "The device has been disconnected.")), (NULL));
> goto write_error;
> }
> }
---8<-------------------------------------------------------------------------
Perhaps the bug is somewhere here ?
In comparison we have that in gst-plugins-base/ext/alsa/gstalsasrc.c:
---8<-------------------------------------------------------------------------
> static guint
> gst_alsasrc_read (GstAudioSrc * asrc, gpointer data, guint length,
> GstClockTime * timestamp)
> {
> GstAlsaSrc *alsa;
> gint err;
> gint cptr;
> gint16 *ptr;
>
> alsa = GST_ALSA_SRC (asrc);
>
> cptr = length / alsa->bpf;
> ptr = data;
>
> GST_ALSA_SRC_LOCK (asrc);
> while (cptr > 0) {
> if ((err = snd_pcm_readi (alsa->handle, ptr, cptr)) < 0) {
> if (err == -EAGAIN) {
> GST_DEBUG_OBJECT (asrc, "Read error: %s", snd_strerror (err));
> continue;
> } else if (err == -ENODEV) {
> goto device_disappeared;
> } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
> goto read_error;
> }
> continue;
> }
>
> ptr += err * alsa->channels;
> cptr -= err;
> }
> GST_ALSA_SRC_UNLOCK (asrc);
>
> /* if driver timestamps are enabled we need to return this here */
> if (alsa->driver_timestamps && timestamp)
> *timestamp = gst_alsasrc_get_timestamp (alsa);
>
> return length - (cptr * alsa->bpf);
>
> read_error:
> {
> GST_ALSA_SRC_UNLOCK (asrc);
> return length; /* skip one period */
> }
> device_disappeared:
> {
> GST_ELEMENT_ERROR (asrc, RESOURCE, READ,
> (_("Error recording from audio device. "
> "The device has been disconnected.")), (NULL));
> GST_ALSA_SRC_UNLOCK (asrc);
> return (guint) - 1;
> }
> }
---8<-------------------------------------------------------------------------
##############################################################################
There is two notable difference between them.
The first notable difference is:
in gstalsasrc.c:
> while (cptr > 0) {
> /* some code */
> ptr += err * alsa->channels;
> cptr -= err;
> }
in gstalsasink.c:
> while (cptr > 0) {
> /* some code */
> ptr += snd_pcm_frames_to_bytes (alsa->handle, err);
> cptr -= err;
> }
I do not know if this is normal and if this is the expected operation.
The second notable difference is:
in gstalsasrc.c, err is always assigned like that:
> err = snd_pcm_readi (alsa->handle, ptr, cptr)
in gstalsasink.c, err can be assigned in two ways:
> err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
or, if err >= 0:
> err = snd_pcm_writei (alsa->handle, ptr, cptr);
##############################################################################
There is another noticeable thing !
We read in gstalsasink.c:
> err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000));
And this the snd_pcm_wait code in alsa-lib/src/pcm/pcm.c:
> int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
> {
> if (!snd_pcm_may_wait_for_avail_min(pcm, snd_pcm_mmap_avail(pcm))) {
> /* check more precisely */
> switch (snd_pcm_state(pcm)) {
> case SND_PCM_STATE_XRUN:
> return -EPIPE;
> case SND_PCM_STATE_SUSPENDED:
> return -ESTRPIPE;
> case SND_PCM_STATE_DISCONNECTED:
> return -ENODEV;
> default:
> return 1;
> }
> }
> return snd_pcm_wait_nocheck(pcm, timeout);
> }
snd_pcm_wait can return -EPIPE in case of SND_PCM_STATE_XRUN
We can remember that EPIPE is 32.
In gst-plugins-base/ext/alsa/gstalsasink.c we can see that -EPIPE is not
handled:
> if (err < 0) {
> GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err));
> if (err == -EAGAIN) {
> continue;
> } else if (err == -ENODEV) {
> goto device_disappeared;
> } else if (xrun_recovery (alsa, alsa->handle, err) < 0) {
> goto write_error;
> }
> continue;
> }
There is no "if (err == -EPIPE)" at all.
In case of "alsasrc ! alsasink" pipeline, when the alsasink get -EPIPE, this is
the alsasrc module that catch this error and complains:
1:39:18.548478614 26625 0x7f8b2c003630 DEBUG alsa
gstalsasrc.c:808:xrun_recovery:<alsasrc0> xrun recovery -32: Erreur inconnue
-32
Does anyone have an idea?
--
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
More information about the gstreamer-bugs
mailing list