]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blobdiff - plugins/elements/gstidentity.c
identity: unlock clock wait when appropriate
[glsdk/gstreamer0-10.git] / plugins / elements / gstidentity.c
index f49054a4ebe176b5d8a68e8193e36100bedfa5b5..f51ca5ae7591f819f98283f030326176aaa63fd7 100644 (file)
@@ -23,7 +23,7 @@
 /**
  * SECTION:element-identity
  *
- * Dummy element that passes incomming data through unmodified. It has some
+ * Dummy element that passes incoming data through unmodified. It has some
  * useful diagnostic functions, such as offset and timestamp checking.
  */
 
@@ -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);
@@ -315,7 +322,7 @@ gst_identity_notify_last_message (GstIdentity * identity)
    * for an in-band buffer or event. This is fixed in GLib >= 2.26 */
 #if !GLIB_CHECK_VERSION(2,26,0)
   g_static_rec_mutex_lock (&identity->notify_lock);
-  g_object_notify ((GObject *) identity, "last_message");
+  g_object_notify ((GObject *) identity, "last-message");
   g_static_rec_mutex_unlock (&identity->notify_lock);
 #else
   g_object_notify_by_pspec ((GObject *) identity, pspec_last_message);
@@ -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 */
@@ -548,6 +566,40 @@ gst_identity_check_imperfect_offset (GstIdentity * identity, GstBuffer * buf)
   }
 }
 
+static const gchar *
+print_pretty_time (gchar * ts_str, gsize ts_str_len, GstClockTime ts)
+{
+  if (ts == GST_CLOCK_TIME_NONE)
+    return "none";
+
+  g_snprintf (ts_str, ts_str_len, "%" GST_TIME_FORMAT, GST_TIME_ARGS (ts));
+  return ts_str;
+}
+
+static void
+gst_identity_update_last_message_for_buffer (GstIdentity * identity,
+    const gchar * action, GstBuffer * buf)
+{
+  gchar ts_str[64], dur_str[64];
+
+  GST_OBJECT_LOCK (identity);
+
+  g_free (identity->last_message);
+  identity->last_message = g_strdup_printf ("%s   ******* (%s:%s)i "
+      "(%u bytes, timestamp: %s, duration: %s, offset: %" G_GINT64_FORMAT ", "
+      "offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", action,
+      GST_DEBUG_PAD_NAME (GST_BASE_TRANSFORM_CAST (identity)->sinkpad),
+      GST_BUFFER_SIZE (buf),
+      print_pretty_time (ts_str, sizeof (ts_str), GST_BUFFER_TIMESTAMP (buf)),
+      print_pretty_time (dur_str, sizeof (dur_str), GST_BUFFER_DURATION (buf)),
+      GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
+      GST_BUFFER_FLAGS (buf), buf);
+
+  GST_OBJECT_UNLOCK (identity);
+
+  gst_identity_notify_last_message (identity);
+}
+
 static GstFlowReturn
 gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
 {
@@ -580,19 +632,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
   if (identity->drop_probability > 0.0) {
     if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) {
       if (!identity->silent) {
-        GST_OBJECT_LOCK (identity);
-        g_free (identity->last_message);
-        identity->last_message =
-            g_strdup_printf
-            ("dropping   ******* (%s:%s)i (%d bytes, timestamp: %"
-            GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %"
-            G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT
-            ", flags: %d) %p", GST_DEBUG_PAD_NAME (trans->sinkpad),
-            GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
-            GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
-            GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf);
-        GST_OBJECT_UNLOCK (identity);
-        gst_identity_notify_last_message (identity);
+        gst_identity_update_last_message_for_buffer (identity, "dropping", buf);
       }
       /* return DROPPED to basetransform. */
       return GST_BASE_TRANSFORM_FLOW_DROPPED;
@@ -604,19 +644,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
   }
 
   if (!identity->silent) {
-    GST_OBJECT_LOCK (identity);
-    g_free (identity->last_message);
-    identity->last_message =
-        g_strdup_printf ("chain   ******* (%s:%s)i (%d bytes, timestamp: %"
-        GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %"
-        G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p",
-        GST_DEBUG_PAD_NAME (trans->sinkpad), GST_BUFFER_SIZE (buf),
-        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
-        GST_TIME_ARGS (GST_BUFFER_DURATION (buf)),
-        GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
-        GST_BUFFER_FLAGS (buf), buf);
-    GST_OBJECT_UNLOCK (identity);
-    gst_identity_notify_last_message (identity);
+    gst_identity_update_last_message_for_buffer (identity, "chain", buf);
   }
 
   if (identity->datarate > 0) {
@@ -646,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);
 
@@ -815,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;
+}