validate: Wait for switch-track to complete before executing next action
authorThibault Saunier <tsaunier@gnome.org>
Thu, 11 Dec 2014 13:21:12 +0000 (14:21 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Sat, 14 Feb 2015 15:32:08 +0000 (16:32 +0100)
This action type can take some time, we need to make sure that the
combiner/input-selector element properly pushed a buffer marked
as DISCONT to concider the action is done.

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

validate/gst/validate/gst-validate-scenario.c
validate/tools/gst-validate.c

index d5d4723..86c72fe 100644 (file)
@@ -702,6 +702,19 @@ find_sink_pad_index (GstElement * element, GstPad * pad)
   return index;
 }
 
+static GstPadProbeReturn
+_check_select_pad_done (GstPad * pad, GstPadProbeInfo * info,
+    GstValidateAction * action)
+{
+  if (GST_BUFFER_FLAG_IS_SET (info->data, GST_BUFFER_FLAG_DISCONT)) {
+    gst_validate_action_set_done (action);
+
+    return GST_PAD_PROBE_REMOVE;
+  }
+
+  return GST_PAD_PROBE_OK;
+}
+
 static gboolean
 _execute_switch_track (GstValidateScenario * scenario,
     GstValidateAction * action)
@@ -718,7 +731,10 @@ _execute_switch_track (GstValidateScenario * scenario,
   input_selector =
       find_input_selector_with_type (GST_BIN (scenario->pipeline), type);
   if (input_selector) {
-    GstPad *pad, *cpad;
+    GstState state, next;
+    GstPad *pad, *cpad, *srcpad;
+
+    GstValidateExecuteActionReturn res = GST_VALIDATE_EXECUTE_ACTION_OK;
 
     if ((str_index = gst_structure_get_string (action->structure, "index"))) {
       if (!gst_structure_get_uint (action->structure, "index", &index)) {
@@ -748,16 +764,28 @@ _execute_switch_track (GstValidateScenario * scenario,
     gst_validate_printf (action, "Switching to track number: %i,"
         " (from %s:%s to %s:%s)\n",
         index, GST_DEBUG_PAD_NAME (cpad), GST_DEBUG_PAD_NAME (pad));
+
+    if (gst_element_get_state (scenario->pipeline, &state, &next, 0) &&
+        state == GST_STATE_PLAYING && next == GST_STATE_VOID_PENDING) {
+      srcpad = gst_element_get_static_pad (input_selector, "src");
+
+      gst_pad_add_probe (srcpad,
+          GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
+          (GstPadProbeCallback) _check_select_pad_done, action, NULL);
+      res = GST_VALIDATE_EXECUTE_ACTION_ASYNC;
+      gst_object_unref (srcpad);
+    }
+
     g_object_set (input_selector, "active-pad", pad, NULL);
     gst_object_unref (pad);
     gst_object_unref (cpad);
     gst_object_unref (input_selector);
 
-    return TRUE;
+    return res;
   }
 
   /* No selector found -> Failed */
-  return FALSE;
+  return GST_VALIDATE_EXECUTE_ACTION_ERROR;
 }
 
 static gboolean
index 79aa169..f507c2e 100644 (file)
@@ -236,18 +236,35 @@ _execute_set_subtitles (GstValidateScenario * scenario,
   return TRUE;
 }
 
+static GstPadProbeReturn
+_check_pad_selection_done (GstPad * pad, GstPadProbeInfo * info,
+    GstValidateAction * action)
+{
+  if (GST_BUFFER_FLAG_IS_SET (info->data, GST_BUFFER_FLAG_DISCONT)) {
+    gst_validate_action_set_done (action);
+
+    return GST_PAD_PROBE_REMOVE;
+  }
+
+  return GST_PAD_PROBE_OK;
+}
+
 static gboolean
 _execute_switch_track (GstValidateScenario * scenario,
     GstValidateAction * action)
 {
   gint index, n;
+  GstPad *srcpad;
+  GstElement *combiner;
   GstPad *oldpad, *newpad;
-  gboolean relative = FALSE, disabling = FALSE;
   const gchar *type, *str_index;
 
   gint flags, current, tflag;
   gchar *tmp, *current_txt;
 
+  gint res = GST_VALIDATE_EXECUTE_ACTION_OK;
+  gboolean relative = FALSE, disabling = FALSE;
+
   if (!(type = gst_structure_get_string (action->structure, "type")))
     type = "audio";
 
@@ -285,6 +302,7 @@ _execute_switch_track (GstValidateScenario * scenario,
   }
 
   if (!disabling) {
+    GstState state, next;
     tmp = g_strdup_printf ("get-%s-pad", type);
     g_signal_emit_by_name (G_OBJECT (scenario->pipeline), tmp, current,
         &oldpad);
@@ -295,6 +313,22 @@ _execute_switch_track (GstValidateScenario * scenario,
         GST_DEBUG_PAD_NAME (newpad));
     flags |= tflag;
     g_free (tmp);
+
+    if (gst_element_get_state (scenario->pipeline, &state, &next, 0) &&
+        state == GST_STATE_PLAYING && next == GST_STATE_VOID_PENDING) {
+
+      combiner = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (newpad)));
+      srcpad = gst_element_get_static_pad (combiner, "src");
+      gst_object_unref (combiner);
+
+      gst_pad_add_probe (srcpad,
+          GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
+          (GstPadProbeCallback) _check_pad_selection_done, action, NULL);
+      gst_object_unref (srcpad);
+
+      res = GST_VALIDATE_EXECUTE_ACTION_ASYNC;
+    }
+
   } else {
     gst_validate_printf (action, "Disabling track type %s", type);
   }
@@ -302,7 +336,7 @@ _execute_switch_track (GstValidateScenario * scenario,
   g_object_set (scenario->pipeline, "flags", flags, current_txt, index, NULL);
   g_free (current_txt);
 
-  return TRUE;
+  return res;
 }
 
 static void