identity: With sync=true, don't pre-roll
authorOlivier Crête <olivier.crete@collabora.com>
Mon, 20 Apr 2015 23:31:37 +0000 (19:31 -0400)
committerOlivier Crête <olivier.crete@collabora.com>
Mon, 27 Apr 2015 16:27:40 +0000 (12:27 -0400)
To act like a real live element, block the streaming when paused, and
return NO_PREROLL.

https://bugzilla.gnome.org/show_bug.cgi?id=601853

plugins/elements/gstidentity.c
plugins/elements/gstidentity.h

index 79d3a35..03fe93d 100644 (file)
@@ -127,6 +127,7 @@ gst_identity_finalize (GObject * object)
   identity = GST_IDENTITY (object);
 
   g_free (identity->last_message);
+  g_cond_clear (&identity->blocked_cond);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -259,6 +260,7 @@ gst_identity_init (GstIdentity * identity)
   identity->dump = DEFAULT_DUMP;
   identity->last_message = NULL;
   identity->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
+  g_cond_init (&identity->blocked_cond);
 
   gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM_CAST (identity), TRUE);
 }
@@ -568,6 +570,11 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
     GstClock *clock;
 
     GST_OBJECT_LOCK (identity);
+
+    while (identity->blocked)
+      g_cond_wait (&identity->blocked_cond, GST_OBJECT_GET_LOCK (identity));
+
+
     if ((clock = GST_ELEMENT (identity)->clock)) {
       GstClockReturn cret;
       GstClockTime timestamp;
@@ -840,13 +847,23 @@ gst_identity_change_state (GstElement * element, GstStateChange transition)
 {
   GstStateChangeReturn ret;
   GstIdentity *identity = GST_IDENTITY (element);
+  gboolean no_preroll = FALSE;
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
+      GST_OBJECT_LOCK (identity);
+      identity->blocked = TRUE;
+      GST_OBJECT_UNLOCK (identity);
+      if (identity->sync)
+        no_preroll = TRUE;
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+      GST_OBJECT_LOCK (identity);
+      identity->blocked = FALSE;
+      g_cond_broadcast (&identity->blocked_cond);
+      GST_OBJECT_UNLOCK (identity);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       GST_OBJECT_LOCK (identity);
@@ -856,6 +873,8 @@ gst_identity_change_state (GstElement * element, GstStateChange transition)
         gst_clock_id_unref (identity->clock_id);
         identity->clock_id = NULL;
       }
+      identity->blocked = FALSE;
+      g_cond_broadcast (&identity->blocked_cond);
       GST_OBJECT_UNLOCK (identity);
       break;
     default:
@@ -868,7 +887,10 @@ gst_identity_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       GST_OBJECT_LOCK (identity);
       identity->upstream_latency = 0;
+      identity->blocked = TRUE;
       GST_OBJECT_UNLOCK (identity);
+      if (identity->sync)
+        no_preroll = TRUE;
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       break;
@@ -878,5 +900,8 @@ gst_identity_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
+  if (no_preroll && ret == GST_STATE_CHANGE_SUCCESS)
+    ret = GST_STATE_CHANGE_NO_PREROLL;
+
   return ret;
 }
index f7fbb7f..315cdbd 100644 (file)
@@ -73,6 +73,8 @@ struct _GstIdentity {
   guint64        offset;
   gboolean       signal_handoffs;
   GstClockTime   upstream_latency;
+  GCond          blocked_cond;
+  gboolean       blocked;
 };
 
 struct _GstIdentityClass {