audio/alsa: Exit write loop if underlying device is already paused.

If the alsasink thread starts the write loop but another thread pauses
the underlying alsa device, the sink thread will endlessly loop.

snd_pcm_writei() will return 0 if the state is SND_PCM_STATE_PAUSED
and the loop will never make any progress.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1097>
This commit is contained in:
Doug Nazar 2021-04-07 04:25:47 -04:00 committed by GStreamer Marge Bot
parent f38d2d3820
commit 1d5ad7d1da
2 changed files with 7 additions and 0 deletions

View file

@ -1089,6 +1089,10 @@ gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
goto write_error; goto write_error;
} }
continue; continue;
} else if (err == 0 && alsa->hw_support_pause) {
/* We might be already paused, if so, just bail */
if (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PAUSED)
break;
} }
ptr += snd_pcm_frames_to_bytes (alsa->handle, err); ptr += snd_pcm_frames_to_bytes (alsa->handle, err);

View file

@ -254,6 +254,9 @@ audioringbuffer_thread_func (GstAudioRingBuffer * buf)
GST_DEBUG_FUNCPTR_NAME (writefunc), GST_DEBUG_FUNCPTR_NAME (writefunc),
(errno > 1 ? g_strerror (errno) : "unknown"), left, written); (errno > 1 ? g_strerror (errno) : "unknown"), left, written);
break; break;
} else if (written == 0 && G_UNLIKELY (g_atomic_int_get (&buf->state) !=
GST_AUDIO_RING_BUFFER_STATE_STARTED)) {
break;
} }
left -= written; left -= written;
readptr += written; readptr += written;