watchdog: Properly handle PAUSED state
authorThibault Saunier <tsaunier@gnome.org>
Wed, 26 Nov 2014 14:43:12 +0000 (15:43 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Thu, 27 Nov 2014 18:10:58 +0000 (19:10 +0100)
In PAUSED state we should just preroll, so get one buffer
and stop monitoring.

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

gst/debugutils/gstwatchdog.c
gst/debugutils/gstwatchdog.h

index eb77765f34cd65b5dec46958fbc360b52240df57..1a30ed1f63c696d702a7c139574a868b27526642 100644 (file)
@@ -66,7 +66,8 @@ static gboolean gst_watchdog_src_event (GstBaseTransform * trans,
     GstEvent * event);
 static GstFlowReturn gst_watchdog_transform_ip (GstBaseTransform * trans,
     GstBuffer * buf);
-static void gst_watchdog_feed (GstWatchdog * watchdog);
+static void gst_watchdog_feed (GstWatchdog * watchdog, gpointer mini_object,
+    gboolean force);
 
 static GstStateChangeReturn
 gst_watchdog_change_state (GstElement * element, GstStateChange transition);
@@ -140,7 +141,7 @@ gst_watchdog_set_property (GObject * object, guint property_id,
     case PROP_TIMEOUT:
       GST_OBJECT_LOCK (watchdog);
       watchdog->timeout = g_value_get_int (value);
-      gst_watchdog_feed (watchdog);
+      gst_watchdog_feed (watchdog, NULL, FALSE);
       GST_OBJECT_UNLOCK (watchdog);
       break;
     default:
@@ -207,20 +208,41 @@ gst_watchdog_quit_mainloop (gpointer ptr)
 }
 
 static void
-gst_watchdog_feed (GstWatchdog * watchdog)
+gst_watchdog_feed (GstWatchdog * watchdog, gpointer mini_object, gboolean force)
 {
   if (watchdog->source) {
+    if (watchdog->waiting_for_a_buffer) {
+      if (mini_object && GST_IS_BUFFER (mini_object)) {
+        watchdog->waiting_for_a_buffer = FALSE;
+        GST_DEBUG_OBJECT (watchdog, "Got a buffer \\o/");
+      } else {
+        GST_DEBUG_OBJECT (watchdog, "Waiting for a buffer and did not get it,"
+            " keep trying even in PAUSED state");
+        force = TRUE;
+      }
+    }
     g_source_destroy (watchdog->source);
     g_source_unref (watchdog->source);
     watchdog->source = NULL;
+
   }
 
-  if (watchdog->timeout != 0 && watchdog->main_context) {
+  GST_STATE_LOCK (watchdog);
+
+  if (watchdog->timeout == 0) {
+    GST_LOG_OBJECT (watchdog, "Timeout is 0 => nothing to do");
+  } else if (watchdog->main_context == NULL) {
+    GST_LOG_OBJECT (watchdog, "No maincontext => nothing to do");
+  } else if ((GST_STATE (watchdog) != GST_STATE_PLAYING) && force == FALSE) {
+    GST_LOG_OBJECT (watchdog,
+        "Not in playing and force is FALSE => Nothing to do");
+  } else {
     watchdog->source = g_timeout_source_new (watchdog->timeout);
-    g_source_set_callback (watchdog->source, gst_watchdog_trigger, gst_object_ref (watchdog),
-        gst_object_unref);
+    g_source_set_callback (watchdog->source, gst_watchdog_trigger,
+        gst_object_ref (watchdog), gst_object_unref);
     g_source_attach (watchdog->source, watchdog->main_context);
   }
+  GST_STATE_UNLOCK (watchdog);
 }
 
 static gboolean
@@ -283,7 +305,7 @@ gst_watchdog_sink_event (GstBaseTransform * trans, GstEvent * event)
   GST_DEBUG_OBJECT (watchdog, "sink_event");
 
   GST_OBJECT_LOCK (watchdog);
-  gst_watchdog_feed (watchdog);
+  gst_watchdog_feed (watchdog, event, FALSE);
   GST_OBJECT_UNLOCK (watchdog);
 
   return
@@ -294,12 +316,25 @@ gst_watchdog_sink_event (GstBaseTransform * trans, GstEvent * event)
 static gboolean
 gst_watchdog_src_event (GstBaseTransform * trans, GstEvent * event)
 {
+  gboolean force = FALSE;
   GstWatchdog *watchdog = GST_WATCHDOG (trans);
 
   GST_DEBUG_OBJECT (watchdog, "src_event");
 
   GST_OBJECT_LOCK (watchdog);
-  gst_watchdog_feed (watchdog);
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
+    GstSeekFlags flags;
+
+    gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, NULL);
+
+    if (flags & GST_SEEK_FLAG_FLUSH) {
+      force = TRUE;
+      GST_DEBUG_OBJECT (watchdog, "Got a FLUSHING seek, we need a buffer now!");
+      watchdog->waiting_for_a_buffer = TRUE;
+    }
+  }
+
+  gst_watchdog_feed (watchdog, event, force);
   GST_OBJECT_UNLOCK (watchdog);
 
   return GST_BASE_TRANSFORM_CLASS (gst_watchdog_parent_class)->src_event (trans,
@@ -314,7 +349,7 @@ gst_watchdog_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
   GST_DEBUG_OBJECT (watchdog, "transform_ip");
 
   GST_OBJECT_LOCK (watchdog);
-  gst_watchdog_feed (watchdog);
+  gst_watchdog_feed (watchdog, buf, FALSE);
   GST_OBJECT_UNLOCK (watchdog);
 
   return GST_FLOW_OK;
@@ -332,11 +367,10 @@ gst_watchdog_change_state (GstElement * element, GstStateChange transition)
   GST_DEBUG_OBJECT (watchdog, "gst_watchdog_change_state");
 
   switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       /* Activate timer */
       GST_OBJECT_LOCK (watchdog);
-      gst_watchdog_feed (watchdog);
+      gst_watchdog_feed (watchdog, NULL, FALSE);
       GST_OBJECT_UNLOCK (watchdog);
       break;
     default:
@@ -348,6 +382,12 @@ gst_watchdog_change_state (GstElement * element, GstStateChange transition)
       transition);
 
   switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      GST_OBJECT_LOCK (watchdog);
+      watchdog->waiting_for_a_buffer = TRUE;
+      gst_watchdog_feed (watchdog, NULL, TRUE);
+      GST_OBJECT_UNLOCK (watchdog);
+      break;
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       /* Disable the timer */
       GST_OBJECT_LOCK (watchdog);
index 40740ef4019203e8f4bf75ba06bb51041d35ec29..c146c66dbd93782a187e025406fc7c47e9b70651 100644 (file)
@@ -45,6 +45,8 @@ struct _GstWatchdog
   GMainLoop *main_loop;
   GThread *thread;
   GSource *source;
+
+  gboolean waiting_for_a_buffer;
 };
 
 struct _GstWatchdogClass