validate: scenario: Implement 'repeat' by copying actions
authorThibault Saunier <tsaunier@igalia.com>
Mon, 15 Jun 2020 13:17:55 +0000 (09:17 -0400)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 22 Jun 2020 17:20:32 +0000 (17:20 +0000)
Instead of trying to reuse the same action structure and deal with
that in a complex way, copy the action the required number of times.

And add a simple test

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-devtools/-/merge_requests/207>

validate/gst/validate/gst-validate-scenario.c
validate/gst/validate/gst-validate-scenario.h
validate/tests/launcher_tests/simple_repeat.validatetest [new file with mode: 0644]
validate/tests/launcher_tests/simple_repeat/flow-expectations/log-sink-sink-expected [new file with mode: 0644]

index de1d052641b94ed91f5071d7bc51de46f704e5ad..992e5c65dbc356159fa4110a432be1c40b517e6a 100644 (file)
@@ -452,6 +452,7 @@ _action_copy (GstValidateAction * act)
   GST_VALIDATE_ACTION_FILENAME (copy) =
       g_strdup (GST_VALIDATE_ACTION_FILENAME (act));
   GST_VALIDATE_ACTION_DEBUG (copy) = g_strdup (GST_VALIDATE_ACTION_DEBUG (act));
+  GST_VALIDATE_ACTION_N_REPEATS (copy) = GST_VALIDATE_ACTION_N_REPEATS (act);
 
   return copy;
 }
@@ -2645,8 +2646,7 @@ execute_next_action_full (GstValidateScenario * scenario, GstMessage * message)
 
     if (act->priv->state == GST_VALIDATE_EXECUTE_ACTION_IN_PROGRESS) {
       return G_SOURCE_CONTINUE;
-    } else if (act->priv->state == GST_VALIDATE_EXECUTE_ACTION_OK
-        && act->repeat <= 0) {
+    } else if (act->priv->state == GST_VALIDATE_EXECUTE_ACTION_OK) {
       tmp = priv->actions;
       priv->actions = g_list_remove_link (priv->actions, tmp);
 
@@ -2730,15 +2730,11 @@ execute_next_action_full (GstValidateScenario * scenario, GstMessage * message)
     g_free (str);
   }
 
-  if (act->repeat > 0 && !gst_validate_action_is_subaction (act)) {
-    act->repeat--;
-  }
-
   if (act->priv->state == GST_VALIDATE_EXECUTE_ACTION_OK) {
     act->priv->state = _execute_sub_action_action (act);
   }
 
-  if (act->priv->state != GST_VALIDATE_EXECUTE_ACTION_ASYNC && act->repeat <= 0) {
+  if (act->priv->state != GST_VALIDATE_EXECUTE_ACTION_ASYNC) {
     tmp = priv->actions;
     priv->actions = g_list_remove_link (priv->actions, tmp);
 
@@ -3611,62 +3607,88 @@ _execute_disable_plugin (GstValidateScenario * scenario,
   return GST_VALIDATE_EXECUTE_ACTION_OK;
 }
 
-static GstValidateExecuteActionReturn
-gst_validate_action_default_prepare_func (GstValidateAction * action)
+static gboolean
+gst_validate_action_setup_repeat (GstValidateScenario * scenario,
+    GstValidateAction * action)
 {
-  gint i;
-  GstClockTime tmp;
   gchar *repeat_expr;
   gchar *error = NULL;
-  GstValidateExecuteActionReturn res = GST_VALIDATE_EXECUTE_ACTION_OK;
-  GstValidateActionType *type = gst_validate_get_action_type (action->type);
-  GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
-
-  g_assert (scenario);
-
-  _update_well_known_vars (scenario);
-  gst_validate_structure_resolve_variables (action, action->structure,
-      scenario->priv->vars);
-  for (i = 0; type->parameters[i].name; i++) {
-    if (type->parameters[i].types &&
-        g_str_has_suffix (type->parameters[i].types, "(GstClockTime)"))
-      gst_validate_action_get_clocktime (scenario, action,
-          type->parameters[i].name, &tmp);
-  }
-
-  if (action->repeat > 0)
-    goto done;
+  gint repeat, position, i;
 
   if (!gst_structure_has_field (action->structure, "repeat"))
-    goto done;
+    return TRUE;
 
-  if (gst_structure_get_int (action->structure, "repeat", &action->repeat))
+  if (gst_structure_get_int (action->structure, "repeat", &repeat))
     goto done;
 
   if (gst_structure_get_double (action->structure, "repeat",
-          (gdouble *) & action->repeat))
+          (gdouble *) & repeat))
     goto done;
 
-  repeat_expr =
-      g_strdup (gst_structure_get_string (action->structure, "repeat"));
+  repeat_expr = gst_validate_replace_variables_in_string (action,
+      scenario->priv->vars, gst_structure_get_string (action->structure,
+          "repeat"));
   if (!repeat_expr) {
     gst_validate_error_structure (action, "Invalid value for 'repeat'");
-    goto err;
+    return FALSE;
   }
 
-  action->repeat =
-      gst_validate_utils_parse_expression (repeat_expr, _set_variable_func,
+  repeat = gst_validate_utils_parse_expression (repeat_expr, _set_variable_func,
       scenario, &error);
   if (error) {
-    gst_validate_error_structure (action, "Invalid value for 'repeat'");
-    goto err;
+    gst_validate_error_structure (action, "Invalid value for 'repeat': %s",
+        error);
+    g_free (error);
+    return FALSE;
   }
   g_free (repeat_expr);
 
-  gst_structure_set (action->structure, "repeat", G_TYPE_INT, action->repeat,
-      NULL);
-  gst_structure_set (action->priv->main_structure, "repeat", G_TYPE_INT,
-      action->repeat, NULL);
+done:
+  gst_structure_remove_field (action->structure, "repeat");
+  gst_structure_remove_field (action->priv->main_structure, "repeat");
+
+  action->repeat = 0;
+  GST_VALIDATE_ACTION_N_REPEATS (action) = repeat;
+
+  SCENARIO_LOCK (scenario);
+  position = g_list_index (scenario->priv->actions, action);
+  g_assert (position >= 0);
+  for (i = 1; i < repeat; i++) {
+    GstValidateAction *copy = _action_copy (action);
+
+    copy->repeat = i;
+    scenario->priv->actions =
+        g_list_insert (scenario->priv->actions, copy, position + i);
+  }
+  SCENARIO_UNLOCK (scenario);
+  return TRUE;
+}
+
+static GstValidateExecuteActionReturn
+gst_validate_action_default_prepare_func (GstValidateAction * action)
+{
+  gint i;
+  GstClockTime tmp;
+  GstValidateExecuteActionReturn res = GST_VALIDATE_EXECUTE_ACTION_OK;
+  GstValidateActionType *type = gst_validate_get_action_type (action->type);
+  GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
+
+  _update_well_known_vars (scenario);
+  if (!gst_validate_action_setup_repeat (scenario, action))
+    goto err;
+
+  if (GST_VALIDATE_ACTION_N_REPEATS (action))
+    gst_structure_set (scenario->priv->vars,
+        "repeat", G_TYPE_INT, action->repeat, NULL);
+  gst_validate_structure_resolve_variables (action, action->structure,
+      scenario->priv->vars);
+  for (i = 0; type->parameters[i].name; i++) {
+    if (type->parameters[i].types
+        && g_str_has_suffix (type->parameters[i].types, "(GstClockTime)"))
+      gst_validate_action_get_clocktime (scenario, action,
+          type->parameters[i].name, &tmp);
+  }
+
 
 done:
   gst_clear_mini_object ((GstMiniObject **) & type);
index cfce7fcef4e8dadb118d5b036cc8fd8d5e3201a5..628c0be5369f2a31165556055f9c04eab5b14508 100644 (file)
@@ -92,6 +92,7 @@ typedef struct _GstValidateActionPrivate          GstValidateActionPrivate;
 #define GST_VALIDATE_ACTION_LINENO(action) (((GstValidateAction*) action)->ABI.abi.lineno)
 #define GST_VALIDATE_ACTION_FILENAME(action) (((GstValidateAction*) action)->ABI.abi.filename)
 #define GST_VALIDATE_ACTION_DEBUG(action) (((GstValidateAction*) action)->ABI.abi.debug)
+#define GST_VALIDATE_ACTION_N_REPEATS(action) (((GstValidateAction*) action)->ABI.abi.n_repeats)
 
 /**
  * GstValidateAction:
@@ -131,6 +132,7 @@ struct _GstValidateAction
       gint lineno;
       gchar *filename;
       gchar *debug;
+      gint n_repeats;
     } abi;
   } ABI;
 };
diff --git a/validate/tests/launcher_tests/simple_repeat.validatetest b/validate/tests/launcher_tests/simple_repeat.validatetest
new file mode 100644 (file)
index 0000000..941a06e
--- /dev/null
@@ -0,0 +1,15 @@
+meta,
+    handles-states=true,
+    args = {
+        "videotestsrc pattern=ball animation-mode=frames num-buffers=30 ! video/x-raw,framerate=10/1 ! $(videosink) name=sink sync=true",
+    },
+    configs = {
+       "$(validateflow), pad=sink:sink, buffers-checksum=true",
+    }
+
+pause;
+seek, start="$(position)+0.1", repeat=10, flags="accurate+flush"
+priv_check-action-type-calls, type=seek, n=10
+check-position, expected-position=1.0
+priv_check-action-type-calls, type=check-position, n=1
+stop
\ No newline at end of file
diff --git a/validate/tests/launcher_tests/simple_repeat/flow-expectations/log-sink-sink-expected b/validate/tests/launcher_tests/simple_repeat/flow-expectations/log-sink-sink-expected
new file mode 100644 (file)
index 0000000..b59379d
--- /dev/null
@@ -0,0 +1,88 @@
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
+event caps: video/x-raw, format=(string)AYUV64, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
+event caps: video/x-raw, format=(string)AYUV64, width=(int)320, height=(int)240, framerate=(fraction)10/1, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive;
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
+buffer: checksum=5d4a9a9aa2038170a66bb2c675a16672fe70efbe, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=5d4a9a9aa2038170a66bb2c675a16672fe70efbe, pts=0:00:00.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.100000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.100000000, base=0:00:00.000000000, position=0:00:00.100000000
+event segment: format=TIME, start=0:00:00.100000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.100000000, base=0:00:00.000000000, position=0:00:00.100000000
+buffer: checksum=ace920a5c387c5d216c7bf4fdc83df6ac9d2656e, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=ace920a5c387c5d216c7bf4fdc83df6ac9d2656e, pts=0:00:00.100000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.200000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.200000000, base=0:00:00.000000000, position=0:00:00.200000000
+event segment: format=TIME, start=0:00:00.200000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.200000000, base=0:00:00.000000000, position=0:00:00.200000000
+buffer: checksum=b4a5b43f70ad1a1adb1f5e414b39d6bfb5718373, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=b4a5b43f70ad1a1adb1f5e414b39d6bfb5718373, pts=0:00:00.200000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.300000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.300000000, base=0:00:00.000000000, position=0:00:00.300000000
+event segment: format=TIME, start=0:00:00.300000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.300000000, base=0:00:00.000000000, position=0:00:00.300000000
+buffer: checksum=9dd6d94a11092f698af7c1a0771ad23445659e2f, pts=0:00:00.300000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=9dd6d94a11092f698af7c1a0771ad23445659e2f, pts=0:00:00.300000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.400000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.400000000, base=0:00:00.000000000, position=0:00:00.400000000
+event segment: format=TIME, start=0:00:00.400000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.400000000, base=0:00:00.000000000, position=0:00:00.400000000
+buffer: checksum=319d16fff322be3938dacf51b06d9fe6f8252e13, pts=0:00:00.400000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=319d16fff322be3938dacf51b06d9fe6f8252e13, pts=0:00:00.400000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.500000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.500000000, base=0:00:00.000000000, position=0:00:00.500000000
+event segment: format=TIME, start=0:00:00.500000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.500000000, base=0:00:00.000000000, position=0:00:00.500000000
+buffer: checksum=f8172402fe1df5b501044463234cdcd85d912257, pts=0:00:00.500000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=f8172402fe1df5b501044463234cdcd85d912257, pts=0:00:00.500000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.600000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.600000000, base=0:00:00.000000000, position=0:00:00.600000000
+event segment: format=TIME, start=0:00:00.600000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.600000000, base=0:00:00.000000000, position=0:00:00.600000000
+buffer: checksum=4b19a11f95babc8bffccafde3a12d72de6d160e0, pts=0:00:00.600000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=4b19a11f95babc8bffccafde3a12d72de6d160e0, pts=0:00:00.600000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.700000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.700000000, base=0:00:00.000000000, position=0:00:00.700000000
+event segment: format=TIME, start=0:00:00.700000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.700000000, base=0:00:00.000000000, position=0:00:00.700000000
+buffer: checksum=421d394aad2e819d1c64f795b8370b7fae86d67f, pts=0:00:00.700000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=421d394aad2e819d1c64f795b8370b7fae86d67f, pts=0:00:00.700000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.800000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.800000000, base=0:00:00.000000000, position=0:00:00.800000000
+event segment: format=TIME, start=0:00:00.800000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.800000000, base=0:00:00.000000000, position=0:00:00.800000000
+buffer: checksum=eaaf9c6b1c138aceab33003ed174782cfc9e49b0, pts=0:00:00.800000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=eaaf9c6b1c138aceab33003ed174782cfc9e49b0, pts=0:00:00.800000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:00.900000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.900000000, base=0:00:00.000000000, position=0:00:00.900000000
+event segment: format=TIME, start=0:00:00.900000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:00.900000000, base=0:00:00.000000000, position=0:00:00.900000000
+buffer: checksum=d5f276bf018900cd1f5e56110d5548aab1a554a6, pts=0:00:00.900000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=d5f276bf018900cd1f5e56110d5548aab1a554a6, pts=0:00:00.900000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+event flush-start: (no structure)
+event flush-start: (no structure)
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
+event segment: format=TIME, start=0:00:01.000000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:01.000000000, base=0:00:00.000000000, position=0:00:01.000000000
+event segment: format=TIME, start=0:00:01.000000000, offset=0:00:00.000000000, stop=none, flags=0x01, time=0:00:01.000000000, base=0:00:00.000000000, position=0:00:01.000000000
+buffer: checksum=2d539cab006ef26cb022f0bc3277664ad7d34786, pts=0:00:01.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta
+buffer: checksum=2d539cab006ef26cb022f0bc3277664ad7d34786, pts=0:00:01.000000000, dur=0:00:00.100000000, flags=discont, meta=GstVideoMeta