validate: Print actions directly from the scenario
authorThibault Saunier <tsaunier@gnome.org>
Tue, 17 Feb 2015 13:56:47 +0000 (14:56 +0100)
committerThibault Saunier <tsaunier@gnome.org>
Tue, 17 Feb 2015 16:11:51 +0000 (17:11 +0100)
Avoiding user to have to print them in each and every action type
implementation.

This requires adding some API to prepare actions before printing them.
Preparing action in that case mean parsing the values contained in the
GstStructure parsing equations and setting back the actual value
afterward

API:
  * GstValidatePrepateAction
  * gst_validate_action_type_set_prepare_function

validate/gst/validate/gst-validate-report.c
validate/gst/validate/gst-validate-scenario.c
validate/gst/validate/gst-validate-scenario.h

index 3de1a17..23a8f44 100644 (file)
@@ -506,6 +506,27 @@ gst_validate_printf (gpointer source, const gchar * format, ...)
   va_end (var_args);
 }
 
+static gboolean
+_append_value (GQuark field_id, const GValue * value, GString * string)
+{
+  gchar *val_str = NULL;
+
+  if (G_VALUE_TYPE (value) == GST_TYPE_CLOCK_TIME)
+    val_str = g_strdup_printf ("%" GST_TIME_FORMAT,
+        GST_TIME_ARGS (g_value_get_uint64 (value)));
+  else
+    val_str = gst_value_serialize (value);
+
+  g_string_append (string, g_quark_to_string (field_id));
+  g_string_append_len (string, "=", 1);
+  g_string_append (string, val_str);
+  g_string_append_len (string, " ", 1);
+
+  g_free (val_str);
+
+  return TRUE;
+}
+
 /**
  * gst_validate_print_action:
  * @action: (allow-none): The source object to log
@@ -516,7 +537,22 @@ gst_validate_printf (gpointer source, const gchar * format, ...)
 void
 gst_validate_print_action (GstValidateAction * action, const gchar * message)
 {
+  GString *string = NULL;
+
+  if (message == NULL) {
+    GString *string = g_string_new (gst_structure_get_name (action->structure));
+
+    g_string_append_len (string, ": ", 2);
+    gst_structure_foreach (action->structure,
+        (GstStructureForeachFunc) _append_value, string);
+    g_string_append_len (string, "\n", 1);
+    message = string->str;
+  }
+
   gst_validate_printf (action, "%s", message);
+
+  if (string)
+    g_string_free (string, TRUE);
 }
 
 static void
@@ -589,11 +625,11 @@ gst_validate_printf_valist (gpointer source, const gchar * format, va_list args)
     if (*(GType *) source == GST_TYPE_VALIDATE_ACTION) {
       GstValidateAction *action = (GstValidateAction *) source;
 
-      g_string_printf (string,
-          "\n(Executing action: %s, number: %u at position: %" GST_TIME_FORMAT
-          " repeat: %i) | ", g_strcmp0 (action->name,
-              "") == 0 ? "Unnamed" : action->name, action->action_number,
-          GST_TIME_ARGS (action->playback_time), action->repeat);
+      if (action->printed)
+        return;
+
+      action->printed = TRUE;
+      g_string_printf (string, "Executing ");
 
     } else if (*(GType *) source == GST_TYPE_VALIDATE_ACTION_TYPE) {
       gint i;
index d8f1fd9..44d4417 100644 (file)
@@ -368,13 +368,24 @@ gst_validate_action_get_clocktime (GstValidateScenario * scenario,
 {
   gdouble val;
   const gchar *strval;
+  const GValue *gvalue = gst_structure_get_value (action->structure, name);
+
+  if (gvalue == NULL) {
+    return -1;
+  }
+
+  if (G_VALUE_TYPE (gvalue) == GST_TYPE_CLOCK_TIME) {
+    *retval = g_value_get_uint64 (gvalue);
+
+    return TRUE;
+  }
 
   if (!gst_structure_get_double (action->structure, name, &val)) {
     gchar *error = NULL;
 
     if (!(strval = gst_structure_get_string (action->structure, name))) {
       GST_INFO_OBJECT (scenario, "Could not find %s", name);
-      return FALSE;
+      return -1;
     }
     val =
         gst_validate_utils_parse_expression (strval, _set_variable_func,
@@ -482,10 +493,6 @@ _execute_seek (GstValidateScenario * scenario, GstValidateAction * action)
 
   gst_validate_action_get_clocktime (scenario, action, "stop", &stop);
 
-  gst_validate_printf (action, "seeking to: %" GST_TIME_FORMAT
-      " stop: %" GST_TIME_FORMAT " Rate %lf\n",
-      GST_TIME_ARGS (start), GST_TIME_ARGS (stop), rate);
-
   return gst_validate_scenario_execute_seek (scenario, action, rate, format,
       flags, start_type, start, stop_type, stop);
 }
@@ -525,8 +532,6 @@ _execute_set_state (GstValidateScenario * scenario, GstValidateAction * action)
   scenario->priv->changing_state = TRUE;
   scenario->priv->seeked_in_pause = FALSE;
 
-  gst_validate_printf (action, "Setting state to %s\n", str_state);
-
   ret = gst_element_set_state (scenario->pipeline, state);
 
   if (ret == GST_STATE_CHANGE_FAILURE) {
@@ -553,9 +558,6 @@ _execute_pause (GstValidateScenario * scenario, GstValidateAction * action)
   GstStateChangeReturn ret;
 
   gst_structure_get_double (action->structure, "duration", &duration);
-  gst_validate_printf (action, "pausing for %" GST_TIME_FORMAT "\n",
-      GST_TIME_ARGS (duration * GST_SECOND));
-
   gst_structure_set (action->structure, "state", G_TYPE_STRING, "paused", NULL);
 
   GST_DEBUG ("Pausing for %" GST_TIME_FORMAT,
@@ -606,8 +608,6 @@ _execute_stop (GstValidateScenario * scenario, GstValidateAction * action)
 {
   GstBus *bus = gst_element_get_bus (scenario->pipeline);
 
-  gst_validate_printf (action, "Stoping pipeline\n");
-
   gst_bus_post (bus,
       gst_message_new_request_state (GST_OBJECT_CAST (scenario),
           GST_STATE_NULL));
@@ -618,9 +618,6 @@ _execute_stop (GstValidateScenario * scenario, GstValidateAction * action)
 static gboolean
 _execute_eos (GstValidateScenario * scenario, GstValidateAction * action)
 {
-  gst_validate_printf (action, "sending EOS at %" GST_TIME_FORMAT "\n",
-      GST_TIME_ARGS (action->playback_time));
-
   GST_DEBUG ("Sending eos to pipeline at %" GST_TIME_FORMAT,
       GST_TIME_ARGS (action->playback_time));
 
@@ -808,10 +805,6 @@ _execute_switch_track (GstValidateScenario * scenario,
 
     pad = find_nth_sink_pad (input_selector, index);
     g_object_get (input_selector, "active-pad", &cpad, NULL);
-    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");
@@ -972,6 +965,17 @@ gst_validate_execute_action (GstValidateActionType * action_type,
   g_return_val_if_fail (g_strcmp0 (action_type->name, action->type) == 0,
       GST_VALIDATE_EXECUTE_ACTION_ERROR);
 
+  if (action_type->prepare) {
+    if (action_type->prepare (action) == FALSE) {
+      GST_ERROR_OBJECT (action->scenario, "Action %" GST_PTR_FORMAT
+          " could not be prepared", action->structure);
+
+      return GST_VALIDATE_EXECUTE_ACTION_ERROR;
+    }
+  }
+
+  gst_validate_print_action (action, NULL);
+
   res = action_type->execute (action->scenario, action);
 
   if (!gst_structure_has_field (action->structure, "sub-action")) {
@@ -1212,9 +1216,6 @@ _execute_wait (GstValidateScenario * scenario, GstValidateAction * action)
   }
 
   duration *= wait_multiplier;
-  gst_validate_printf (action,
-      "Waiting for %" GST_TIME_FORMAT " (wait_multiplier: %f)\n",
-      GST_TIME_ARGS (duration), wait_multiplier);
 
   SCENARIO_LOCK (scenario);
   if (priv->get_pos_id) {
@@ -1246,7 +1247,6 @@ _execute_dot_pipeline (GstValidateScenario * scenario,
   else
     dotname = g_strdup ("validate.action.unnamed");
 
-  gst_validate_printf (action, "Doting pipeline (name %s)\n", dotname);
   GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (scenario->pipeline),
       details, dotname);
 
@@ -1310,8 +1310,6 @@ _execute_set_property (GstValidateScenario * scenario,
   property_value = gst_structure_get_value (action->structure,
       "property-value");
 
-  gst_validate_printf (action, "Setting property %s to %s\n",
-      property, gst_value_serialize (property_value));
   ret = _object_set_property (G_OBJECT (target), property, property_value);
 
   gst_object_unref (target);
@@ -1340,11 +1338,6 @@ _execute_set_debug_threshold (GstValidateScenario * scenario,
 
   gst_structure_get_boolean (action->structure, "reset", &reset);
 
-  gst_validate_printf (action,
-      "%s -- Set debug threshold to '%s', %sreseting all\n",
-      gst_structure_to_string (action->structure), threshold_str,
-      reset ? "" : "NOT ");
-
   gst_debug_set_threshold_from_string (threshold_str, reset);
 
   if (str)
@@ -1443,6 +1436,36 @@ _set_action_playback_time (GstValidateScenario * scenario,
     return FALSE;
   }
 
+  gst_structure_set (action->structure, "playback-time", GST_TYPE_CLOCK_TIME,
+      action->playback_time, NULL);
+
+  return TRUE;
+}
+
+static gboolean
+gst_validate_action_default_prepare_func (GstValidateAction * action)
+{
+  gulong i;
+  GstClockTime time;
+  const gchar *vars[] = { "duration", "start", "stop" };
+
+  for (i = 0; i < G_N_ELEMENTS (vars); i++) {
+    gint res =
+        gst_validate_action_get_clocktime (action->scenario, action, vars[i],
+        &time);
+    if (res == FALSE) {
+      GST_ERROR_OBJECT (action->scenario, "Could not get clocktime for"
+          " variable %s", vars[i]);
+
+      return FALSE;
+    } else if (res == -1) {
+      continue;
+    }
+
+    gst_structure_set (action->structure, vars[i], GST_TYPE_CLOCK_TIME,
+        time, NULL);
+  }
+
   return TRUE;
 }
 
@@ -2446,6 +2469,7 @@ gst_validate_register_action_type_dynamic (GstPlugin * plugin,
         sizeof (GstValidateActionParameter) * (n_params));
   }
 
+  type->prepare = gst_validate_action_default_prepare_func;
   type->execute = function;
   type->name = g_strdup (type_name);
   if (plugin)
index fe0c27d..3cc7b5f 100644 (file)
@@ -65,6 +65,19 @@ enum
  */
 typedef GstValidateExecuteActionReturn (*GstValidateExecuteAction) (GstValidateScenario * scenario, GstValidateAction * action);
 
+/**
+ * GstValidatePrepareAction:
+ * @action: The #GstValidateAction to prepare before execution
+ *
+ * A function that prepares @action so it can be executed right after.
+ * Most of the time that function is used to parse and set field with
+ * equations in the action structure.
+ *
+ * Returns: a %TRUE if the action could be prepared and is ready to be run
+ *          %FALSE otherwise
+ */
+typedef gboolean (*GstValidatePrepareAction) (GstValidateAction * action);
+
 
 /**
  * GstValidateAction:
@@ -92,8 +105,9 @@ struct _GstValidateAction
   gint repeat;
   GstClockTime playback_time;
   GstValidateExecuteActionReturn state; /* Actually ActionState */
+  gboolean printed;
 
-  gpointer _gst_reserved[GST_PADDING_LARGE - sizeof (gint) - 2];
+  gpointer _gst_reserved[GST_PADDING_LARGE - sizeof (gint) - 2 - sizeof(gboolean)];
 };
 
 void gst_validate_action_set_done (GstValidateAction *action);
@@ -144,6 +158,7 @@ struct _GstValidateActionType
   gchar *name;
   gchar *implementer_namespace;
 
+  GstValidatePrepareAction prepare;
   GstValidateExecuteAction execute;
 
   GstValidateActionParameter *parameters;
@@ -244,6 +259,10 @@ gst_validate_register_action_type      (const gchar *type_name,
                                         const gchar *description,
                                         GstValidateActionTypeFlags flags);
 
+void
+gst_validate_action_type_set_prepare_function (GstValidateActionType *type,
+                                               GstValidatePrepareAction prepare_action);
+
 GstValidateActionType *
 gst_validate_register_action_type_dynamic (GstPlugin *plugin,
                                            const gchar * type_name,