+2008-11-03 Wim Taymans <wim.taymans@collabora.co.uk>
+
+ Based on patch by: Matthias Kretz <kretz at kde dot org>
+
+ * ext/alsa/gstalsasink.c: (gst_alsasink_open),
+ (gst_alsasink_prepare), (gst_alsasink_unprepare),
+ (gst_alsasink_write):
+ Make all access non-blocking so that we can better handle unplugging
+ of usb devices. Fixes #559111
+
2008-11-03 Wim Taymans <wim.taymans@collabora.co.uk>
Patch by: Damien Lespiau <damien.lespiau gmail com>
alsa = GST_ALSA_SINK (asink);
+ /* open in non-blocking mode, we'll use snd_pcm_wait() for space to become
+ * available. */
CHECK (snd_pcm_open (&alsa->handle, alsa->device, SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK), open_error);
GST_LOG_OBJECT (alsa, "Opened device %s", alsa->device);
if (!alsasink_parse_spec (alsa, spec))
goto spec_parse;
- CHECK (snd_pcm_nonblock (alsa->handle, 0), non_block);
-
CHECK (set_hwparams (alsa), hw_params_failed);
CHECK (set_swparams (alsa), sw_params_failed);
("Error parsing spec"));
return FALSE;
}
-non_block:
- {
- GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
- ("Could not set device to blocking: %s", snd_strerror (err)));
- return FALSE;
- }
hw_params_failed:
{
GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
CHECK (snd_pcm_hw_free (alsa->handle), hw_free);
- CHECK (snd_pcm_nonblock (alsa->handle, 1), non_block);
-
return TRUE;
/* ERRORS */
("Could not free hw params: %s", snd_strerror (err)));
return FALSE;
}
-non_block:
- {
- GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
- ("Could not set device to nonblocking: %s", snd_strerror (err)));
- return FALSE;
- }
}
static gboolean
GST_ALSA_SINK_LOCK (asink);
while (cptr > 0) {
- err = snd_pcm_writei (alsa->handle, ptr, cptr);
+ /* 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 timeout, %d", err);
+ } else {
+ err = snd_pcm_writei (alsa->handle, ptr, cptr);
+ }
GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr);
if (err < 0) {