shout2: use gstpoll for timeouts
authorWim Taymans <wim.taymans@collabora.co.uk>
Sat, 28 Nov 2009 18:23:26 +0000 (19:23 +0100)
committerWim Taymans <wim@metal.(none)>
Sat, 28 Nov 2009 18:23:26 +0000 (19:23 +0100)
Use our own GstPoll based timeout instead of the shout sleep so that we can
interrupt when doing a state change and shutting down.

Fixes #602887

ext/shout2/gstshout2.c
ext/shout2/gstshout2.h

index 4a10317..61d25ba 100644 (file)
@@ -89,6 +89,8 @@ static void gst_shout2send_init (GstShout2send * shout2send);
 static void gst_shout2send_finalize (GstShout2send * shout2send);
 
 static gboolean gst_shout2send_event (GstBaseSink * sink, GstEvent * event);
+static gboolean gst_shout2send_unlock (GstBaseSink * basesink);
+static gboolean gst_shout2send_unlock_stop (GstBaseSink * basesink);
 static GstFlowReturn gst_shout2send_render (GstBaseSink * sink,
     GstBuffer * buffer);
 static gboolean gst_shout2send_start (GstBaseSink * basesink);
@@ -237,6 +239,9 @@ gst_shout2send_class_init (GstShout2sendClass * klass)
 
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_shout2send_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_shout2send_stop);
+  gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_shout2send_unlock);
+  gstbasesink_class->unlock_stop =
+      GST_DEBUG_FUNCPTR (gst_shout2send_unlock_stop);
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_shout2send_render);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_shout2send_event);
 }
@@ -249,6 +254,8 @@ gst_shout2send_init (GstShout2send * shout2send)
   gst_pad_set_setcaps_function (GST_BASE_SINK_PAD (shout2send),
       GST_DEBUG_FUNCPTR (gst_shout2send_setcaps));
 
+  shout2send->timer = gst_poll_new_timer ();
+
   shout2send->ip = g_strdup (DEFAULT_IP);
   shout2send->port = DEFAULT_PORT;
   shout2send->password = g_strdup (DEFAULT_PASSWORD);
@@ -283,6 +290,8 @@ gst_shout2send_finalize (GstShout2send * shout2send)
 
   gst_tag_list_free (shout2send->tags);
 
+  gst_poll_free (shout2send->timer);
+
   G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (shout2send));
 }
 
@@ -585,11 +594,39 @@ gst_shout2send_stop (GstBaseSink * basesink)
   return TRUE;
 }
 
+static gboolean
+gst_shout2send_unlock (GstBaseSink * basesink)
+{
+  GstShout2send *sink;
+
+  sink = GST_SHOUT2SEND (basesink);
+
+  GST_DEBUG_OBJECT (basesink, "unlock");
+  gst_poll_set_flushing (sink->timer, TRUE);
+
+  return TRUE;
+}
+
+static gboolean
+gst_shout2send_unlock_stop (GstBaseSink * basesink)
+{
+  GstShout2send *sink;
+
+  sink = GST_SHOUT2SEND (basesink);
+
+  GST_DEBUG_OBJECT (basesink, "unlock_stop");
+  gst_poll_set_flushing (sink->timer, FALSE);
+
+  return TRUE;
+}
+
 static GstFlowReturn
 gst_shout2send_render (GstBaseSink * basesink, GstBuffer * buf)
 {
   GstShout2send *sink;
   glong ret;
+  gint delay;
+  GstFlowReturn fret;
 
   sink = GST_SHOUT2SEND (basesink);
 
@@ -600,9 +637,16 @@ gst_shout2send_render (GstBaseSink * basesink, GstBuffer * buf)
       return GST_FLOW_ERROR;
   }
 
-  /* FIXME: do we want to do syncing here at all? (tpm) */
-  /* GST_LOG_OBJECT (sink, "using libshout to sync"); */
-  shout_sync (sink->conn);
+  delay = shout_delay (sink->conn);
+
+  GST_LOG_OBJECT (sink, "waiting %d msec", delay);
+  if (gst_poll_wait (sink->timer, 1000 * delay) == -1) {
+    GST_LOG_OBJECT (sink, "unlocked");
+
+    fret = gst_base_sink_wait_preroll (basesink);
+    if (fret != GST_FLOW_OK)
+      return fret;
+  }
 
   GST_LOG_OBJECT (sink, "sending %u bytes of data", GST_BUFFER_SIZE (buf));
   ret = shout_send (sink->conn, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
index 3e1d917..6f97c77 100644 (file)
@@ -42,6 +42,8 @@ struct _GstShout2send {
 
   GstShout2SendProtocol protocol;
 
+  GstPoll *timer;
+
   shout_t *conn;
 
   gchar *ip;