validate:flow: Make field filtering in what is logged more generic
authorThibault Saunier <tsaunier@igalia.com>
Tue, 4 Feb 2020 21:14:25 +0000 (18:14 -0300)
committerThibault Saunier <tsaunier@gnome.org>
Thu, 13 Feb 2020 00:11:45 +0000 (00:11 +0000)
Instead of forcing it on event, allow specifying filters on anything
we log, meaning also buffers

docs/plugins/validateflow.md
validate/plugins/flow/formatting.c
validate/plugins/flow/formatting.h
validate/plugins/flow/gstvalidateflow.c

index 8b51864..850137a 100644 (file)
@@ -85,8 +85,8 @@ In order to use the plugin a validate configuration file must be provided, conta
  * `pad`: Required. Name of the pad that will be monitored.
  * `record-buffers`: Default: false. Whether buffers will be logged. By default only events are logged.
  * `buffers-checksum`: Default: false. Whether a checkum of the buffer data is logged. Implies `record-buffers`.
- * `ignored-event-fields`: Default: `"stream-start={ stream-id }"` (as they are often non reproducible). Key with a serialized GstValueList(str) of fields to not record.
- * `logged-event-fields`: Default: `NULL` Key with a serialized GstValueList(str) of fields to record, eg. `logged-event-fields="stream-start={flags}, caps={width, height, framerate}"`. Overrides `ignored-event-fields` for specified event types.
+ * `ignored-fields`: Default: `"stream-start={ stream-id }"` (as they are often non reproducible). Key with a serialized GstValueList(str) of fields to not record.
+ * `logged-fields`: Default: `NULL` Key with a serialized GstValueList(str) of fields to record, eg. `logged-event-fields="stream-start={flags}, caps={width, height, framerate}, buffer={pts}"`. Overrides `ignored-event-fields` for specified event types.
  * `ignored-event-types`: Default: `{ }`. List of event type names to not record
  * `logged-event-types`: Default: `NULL`. List of event type names to not record, if noone provided, all events are logged, except the ones defined in the `ignored-event-types`.
  * `expectations-dir`: Path to the directory where the expectations will be written if they don't exist, relative to the current working directory. By default the current working directory is used, but this setting is usually set automatically as part of the `%(validateflow)s` expansion to a correct path like `~/gst-validate/gst-integration-testsuites/flow-expectations/<test name>`.
index d971aee..40b190b 100644 (file)
 
 typedef void (*Uint64Formatter) (gchar * dest, guint64 time);
 
+#define CONSTIFY(strv) ((const gchar * const *) strv)
+
+static gboolean
+use_field (const gchar * field, gchar ** logged, gchar ** ignored)
+{
+  if (logged)
+    return g_strv_contains (CONSTIFY (logged), field);
+
+  if (ignored)
+    return !g_strv_contains (CONSTIFY (ignored), field);
+
+  return TRUE;
+}
+
+
 void
 format_time (gchar * dest_str, guint64 time)
 {
@@ -54,11 +69,12 @@ format_number (gchar * dest_str, guint64 number)
 }
 
 gchar *
-validate_flow_format_segment (const GstSegment * segment)
+validate_flow_format_segment (const GstSegment * segment,
+    gchar ** logged_fields, gchar ** ignored_fields)
 {
   Uint64Formatter uint64_format;
   gchar *segment_str;
-  gchar *parts[7];
+  gchar *parts[10];
   GString *format;
   gchar start_str[32], offset_str[32], stop_str[32], time_str[32], base_str[32],
       position_str[32], duration_str[32];
@@ -76,9 +92,19 @@ validate_flow_format_segment (const GstSegment * segment)
 
   format = g_string_new (gst_format_get_name (segment->format));
   format = g_string_ascii_up (format);
-  parts[parts_index++] =
-      g_strdup_printf ("format=%s, start=%s, offset=%s, stop=%s", format->str,
-      start_str, offset_str, stop_str);
+
+  if (use_field ("format", logged_fields, ignored_fields))
+    parts[parts_index++] = g_strdup_printf ("format=%s", format->str);
+
+  if (use_field ("start", logged_fields, ignored_fields))
+    parts[parts_index++] = g_strdup_printf ("start=%s", start_str);
+
+  if (use_field ("offset", logged_fields, ignored_fields))
+    parts[parts_index++] = g_strdup_printf ("offset=%s", offset_str);
+
+  if (use_field ("stop", logged_fields, ignored_fields))
+    parts[parts_index++] = g_strdup_printf ("stop=%s", stop_str);
+
   if (segment->rate != 1.0)
     parts[parts_index++] = g_strdup_printf ("rate=%f", segment->rate);
   if (segment->applied_rate != 1.0)
@@ -193,15 +219,23 @@ buffer_get_meta_string (GstBuffer * buffer)
 }
 
 gchar *
-validate_flow_format_buffer (GstBuffer * buffer, gboolean add_checksum)
+validate_flow_format_buffer (GstBuffer * buffer, gboolean add_checksum,
+    GstStructure * logged_fields_struct, GstStructure * ignored_fields_struct)
 {
   gchar *flags_str, *meta_str, *buffer_str;
   gchar *buffer_parts[7];
   int buffer_parts_index = 0;
   gchar *sum;
   GstMapInfo map;
-
-  if (add_checksum) {
+  gchar **logged_fields =
+      logged_fields_struct ? gst_validate_utils_get_strv (logged_fields_struct,
+      "buffer") : NULL;
+  gchar **ignored_fields =
+      ignored_fields_struct ?
+      gst_validate_utils_get_strv (ignored_fields_struct, "buffer") : NULL;
+
+  if (add_checksum || (logged_fields
+          && g_strv_contains (CONSTIFY (logged_fields), "checksum"))) {
     if (!gst_buffer_map (buffer, &map, GST_MAP_READ)) {
       GST_ERROR ("Buffer could not be mapped.");
     } else {
@@ -213,32 +247,35 @@ validate_flow_format_buffer (GstBuffer * buffer, gboolean add_checksum)
     }
   }
 
-  if (GST_CLOCK_TIME_IS_VALID (buffer->dts)) {
+  if (GST_CLOCK_TIME_IS_VALID (buffer->dts)
+      && use_field ("dts", logged_fields, ignored_fields)) {
     gchar time_str[32];
     format_time (time_str, buffer->dts);
     buffer_parts[buffer_parts_index++] = g_strdup_printf ("dts=%s", time_str);
   }
 
-  if (GST_CLOCK_TIME_IS_VALID (buffer->pts)) {
+  if (GST_CLOCK_TIME_IS_VALID (buffer->pts)
+      && use_field ("pts", logged_fields, ignored_fields)) {
     gchar time_str[32];
     format_time (time_str, buffer->pts);
     buffer_parts[buffer_parts_index++] = g_strdup_printf ("pts=%s", time_str);
   }
 
-  if (GST_CLOCK_TIME_IS_VALID (buffer->duration)) {
+  if (GST_CLOCK_TIME_IS_VALID (buffer->duration)
+      && use_field ("dur", logged_fields, ignored_fields)) {
     gchar time_str[32];
     format_time (time_str, buffer->duration);
     buffer_parts[buffer_parts_index++] = g_strdup_printf ("dur=%s", time_str);
   }
 
   flags_str = buffer_get_flags_string (buffer);
-  if (flags_str) {
+  if (flags_str && use_field ("flags", logged_fields, ignored_fields)) {
     buffer_parts[buffer_parts_index++] =
         g_strdup_printf ("flags=%s", flags_str);
   }
 
   meta_str = buffer_get_meta_string (buffer);
-  if (meta_str)
+  if (meta_str && use_field ("meta", logged_fields, ignored_fields))
     buffer_parts[buffer_parts_index++] = g_strdup_printf ("meta=%s", meta_str);
 
   buffer_parts[buffer_parts_index] = NULL;
@@ -257,8 +294,8 @@ validate_flow_format_buffer (GstBuffer * buffer, gboolean add_checksum)
 gchar *
 validate_flow_format_event (GstEvent * event,
     const gchar * const *caps_properties,
-    GstStructure * logged_event_fields,
-    GstStructure * ignored_event_fields,
+    GstStructure * logged_fields_struct,
+    GstStructure * ignored_fields_struct,
     const gchar * const *ignored_event_types,
     const gchar * const *logged_event_types)
 {
@@ -276,11 +313,17 @@ validate_flow_format_event (GstEvent * event,
   if (ignored_event_types && g_strv_contains (ignored_event_types, event_type))
     return NULL;
 
-  logged_fields = gst_validate_utils_get_strv (logged_event_fields, event_type);
+  logged_fields =
+      logged_fields_struct ? gst_validate_utils_get_strv (logged_fields_struct,
+      event_type) : NULL;
+  ignored_fields =
+      ignored_fields_struct ?
+      gst_validate_utils_get_strv (ignored_fields_struct, event_type) : NULL;
   if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
     const GstSegment *segment;
     gst_event_parse_segment (event, &segment);
-    structure_string = validate_flow_format_segment (segment);
+    structure_string =
+        validate_flow_format_segment (segment, logged_fields, ignored_fields);
   } else if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
     GstCaps *caps;
     gst_event_parse_caps (event, &caps);
@@ -298,8 +341,6 @@ validate_flow_format_event (GstEvent * event,
       gst_structure_filter_and_map_in_place (printable,
           (GstStructureFilterMapFunc) structure_only_given_keys, logged_fields);
     } else {
-      ignored_fields =
-          gst_validate_utils_get_strv (ignored_event_fields, event_type);
       if (ignored_fields) {
         gint i = 0;
         gchar *field;
index 5d6344a..4199327 100644 (file)
 
 void format_time(gchar* dest_str, guint64 time);
 
-gchar* validate_flow_format_segment (const GstSegment *segment);
+gchar* validate_flow_format_segment(const GstSegment* segment, gchar** logged_fields, gchar** ignored_fields);
 
 gchar* validate_flow_format_caps (const GstCaps* caps, gchar **keys_to_print);
 
-gchar* validate_flow_format_buffer (GstBuffer *buffer, gboolean add_checksum);
+gchar* validate_flow_format_buffer(GstBuffer* buffer, gboolean add_checksum, GstStructure* logged_fields_struct, GstStructure* ignored_fields_struct);
 
 gchar* validate_flow_format_event(GstEvent* event, const gchar* const* caps_properties, GstStructure* logged_event_fields, GstStructure* ignored_event_fields, const gchar* const* ignored_event_types, const gchar* const* logged_event_types);
 
index 1114b65..0eab865 100644 (file)
@@ -59,8 +59,8 @@ struct _ValidateFlowOverride
   gchar *actual_results_dir;
   gboolean error_writing_file;
   gchar **caps_properties;
-  GstStructure *ignored_event_fields;
-  GstStructure *logged_event_fields;
+  GstStructure *ignored_fields;
+  GstStructure *logged_fields;
 
   gchar **logged_event_types;
   gchar **ignored_event_types;
@@ -164,8 +164,8 @@ validate_flow_override_event_handler (GstValidateOverride * override,
 
   event_string = validate_flow_format_event (event,
       (const gchar * const *) flow->caps_properties,
-      flow->logged_event_fields,
-      flow->ignored_event_fields,
+      flow->logged_fields,
+      flow->ignored_fields,
       (const gchar * const *) flow->ignored_event_types,
       (const gchar * const *) flow->logged_event_types);
 
@@ -185,7 +185,9 @@ validate_flow_override_buffer_handler (GstValidateOverride * override,
   if (flow->error_writing_file || !flow->record_buffers)
     return;
 
-  buffer_str = validate_flow_format_buffer (buffer, flow->buffers_checksum);
+  buffer_str =
+      validate_flow_format_buffer (buffer, flow->buffers_checksum,
+      flow->logged_fields, flow->ignored_fields);
   validate_flow_override_printf (flow, "buffer: %s\n", buffer_str);
   g_free (buffer_str);
 }
@@ -218,7 +220,7 @@ validate_flow_override_new (GstStructure * config)
 {
   ValidateFlowOverride *flow;
   GstValidateOverride *override;
-  gchar *ignored_event_fields, *logged_event_fields;
+  gchar *ignored_fields, *logged_fields;
 
   flow = g_object_new (VALIDATE_TYPE_FLOW_OVERRIDE, NULL);
   override = GST_VALIDATE_OVERRIDE (flow);
@@ -252,40 +254,36 @@ validate_flow_override_new (GstStructure * config)
   flow->ignored_event_types =
       gst_validate_utils_get_strv (config, "ignored-event-types");
 
-  ignored_event_fields =
-      (gchar *) gst_structure_get_string (config, "ignored-event-fields");
-  if (ignored_event_fields) {
-    ignored_event_fields = g_strdup_printf ("ignored,%s", ignored_event_fields);
-    flow->ignored_event_fields =
-        gst_structure_new_from_string (ignored_event_fields);
-    if (!flow->ignored_event_fields)
+  ignored_fields =
+      (gchar *) gst_structure_get_string (config, "ignored-fields");
+  if (ignored_fields) {
+    ignored_fields = g_strdup_printf ("ignored,%s", ignored_fields);
+    flow->ignored_fields = gst_structure_new_from_string (ignored_fields);
+    if (!flow->ignored_fields)
       g_error ("Could not parse 'ignored-event-fields' %s in %s",
-          ignored_event_fields, gst_structure_to_string (config));
-    g_free (ignored_event_fields);
+          ignored_fields, gst_structure_to_string (config));
+    g_free (ignored_fields);
   } else {
-    flow->ignored_event_fields =
+    flow->ignored_fields =
         gst_structure_new_from_string ("ignored,stream-start={stream-id}");
   }
 
-  if (!gst_structure_has_field (flow->ignored_event_fields, "stream-start"))
-    gst_structure_set (flow->ignored_event_fields, "stream-start",
-        G_TYPE_STRING, "{stream-id}", NULL);
-
-  logged_event_fields =
-      (gchar *) gst_structure_get_string (config, "logged-event-fields");
-  if (logged_event_fields) {
-    logged_event_fields = g_strdup_printf ("logged,%s", logged_event_fields);
-    flow->logged_event_fields =
-        gst_structure_new_from_string (logged_event_fields);
-    if (!flow->logged_event_fields)
-      g_error ("Could not parse 'logged-event-fields' %s in %s",
-          logged_event_fields, gst_structure_to_string (config));
-    g_free (logged_event_fields);
+  if (!gst_structure_has_field (flow->ignored_fields, "stream-start"))
+    gst_structure_set (flow->ignored_fields, "stream-start",
+        G_TYPE_STRING, "stream-id", NULL);
+
+  logged_fields = (gchar *) gst_structure_get_string (config, "logged-fields");
+  if (logged_fields) {
+    logged_fields = g_strdup_printf ("logged,%s", logged_fields);
+    flow->logged_fields = gst_structure_new_from_string (logged_fields);
+    if (!flow->logged_fields)
+      g_error ("Could not parse 'logged-fields' %s in %s",
+          logged_fields, gst_structure_to_string (config));
+    g_free (logged_fields);
   } else {
-    flow->logged_event_fields = NULL;
+    flow->logged_fields = NULL;
   }
 
-
   /* expectations-dir: Path to the directory where the expectations will be
    * written if they don't exist, relative to the current working directory.
    * By default the current working directory is used. */
@@ -507,8 +505,8 @@ validate_flow_override_finalize (GObject * object)
   g_strfreev (flow->caps_properties);
   g_strfreev (flow->logged_event_types);
   g_strfreev (flow->ignored_event_types);
-  if (flow->ignored_event_fields)
-    gst_structure_free (flow->ignored_event_fields);
+  if (flow->ignored_fields)
+    gst_structure_free (flow->ignored_fields);
 
   G_OBJECT_CLASS (validate_flow_override_parent_class)->finalize (object);
 }