identity: unlock clock wait when appropriate
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 2 Dec 2011 12:19:38 +0000 (13:19 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 2 Dec 2011 12:41:54 +0000 (13:41 +0100)
... notably FLUSH and state change to READY.

plugins/elements/gstidentity.c

index ba2026d4b10c1feeb9fe101a2d010cfaca6b2d99..f51ca5ae7591f819f98283f030326176aaa63fd7 100644 (file)
@@ -111,6 +111,8 @@ static GstFlowReturn gst_identity_prepare_output_buffer (GstBaseTransform
     GstBuffer ** out_buf);
 static gboolean gst_identity_start (GstBaseTransform * trans);
 static gboolean gst_identity_stop (GstBaseTransform * trans);
+static GstStateChangeReturn gst_identity_change_state (GstElement * element,
+    GstStateChange transition);
 
 static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
 
@@ -179,9 +181,11 @@ static void
 gst_identity_class_init (GstIdentityClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseTransformClass *gstbasetrans_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
 
   gobject_class->set_property = gst_identity_set_property;
@@ -271,6 +275,9 @@ gst_identity_class_init (GstIdentityClass * klass)
 
   gobject_class->finalize = gst_identity_finalize;
 
+  gstelement_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_identity_change_state);
+
   gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_identity_event);
   gstbasetrans_class->transform_ip =
       GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
@@ -377,6 +384,17 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
 
   ret = parent_class->event (trans, event);
 
+  if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
+    GST_OBJECT_LOCK (identity);
+    if (identity->clock_id) {
+      GST_DEBUG_OBJECT (identity, "unlock clock wait");
+      gst_clock_id_unschedule (identity->clock_id);
+      gst_clock_id_unref (identity->clock_id);
+      identity->clock_id = NULL;
+    }
+    GST_OBJECT_UNLOCK (identity);
+  }
+
   if (identity->single_segment
       && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
     /* eat up segments */
@@ -656,7 +674,6 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
       timestamp = runtimestamp + GST_ELEMENT (identity)->base_time;
 
       /* save id if we need to unlock */
-      /* FIXME: actually unlock this somewhere in the state changes */
       identity->clock_id = gst_clock_new_single_shot_id (clock, timestamp);
       GST_OBJECT_UNLOCK (identity);
 
@@ -825,3 +842,46 @@ gst_identity_stop (GstBaseTransform * trans)
 
   return TRUE;
 }
+
+static GstStateChangeReturn
+gst_identity_change_state (GstElement * element, GstStateChange transition)
+{
+  GstStateChangeReturn ret;
+  GstIdentity *identity = GST_IDENTITY (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      break;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      GST_OBJECT_LOCK (identity);
+      if (identity->clock_id) {
+        GST_DEBUG_OBJECT (identity, "unlock clock wait");
+        gst_clock_id_unschedule (identity->clock_id);
+        gst_clock_id_unref (identity->clock_id);
+        identity->clock_id = NULL;
+      }
+      GST_OBJECT_UNLOCK (identity);
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}