ext/alsa/gstalsasink.c: Make all access non-blocking so that we can better handle...
authorMatthias Kretz <kretz@kde.org>
Mon, 3 Nov 2008 15:30:14 +0000 (15:30 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 3 Nov 2008 15:30:14 +0000 (15:30 +0000)
Original commit message from CVS:
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

ChangeLog
ext/alsa/gstalsasink.c

index 56fd837..708ae7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 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>
 
        * gst-libs/gst/rtsp/gstrtspconnection.c:
index f2657ac..f9a10e4 100644 (file)
@@ -671,6 +671,8 @@ gst_alsasink_open (GstAudioSink * asink)
 
   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);
@@ -714,8 +716,6 @@ gst_alsasink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
   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);
 
@@ -754,12 +754,6 @@ spec_parse:
         ("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),
@@ -786,8 +780,6 @@ gst_alsasink_unprepare (GstAudioSink * asink)
 
   CHECK (snd_pcm_hw_free (alsa->handle), hw_free);
 
-  CHECK (snd_pcm_nonblock (alsa->handle, 1), non_block);
-
   return TRUE;
 
   /* ERRORS */
@@ -803,12 +795,6 @@ hw_free:
         ("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
@@ -891,7 +877,14 @@ gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length)
 
   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) {