qa-report: adds qa-report for reporting errors to GstQaRunner
authorThiago Santos <thiago.sousa.santos@collabora.com>
Fri, 12 Jul 2013 05:10:06 +0000 (02:10 -0300)
committerThiago Santos <thiago.sousa.santos@collabora.com>
Fri, 12 Jul 2013 15:43:07 +0000 (12:43 -0300)
The errors are printed directly to stdout and are accumulated at
GstQaRunner for being printed at the end if requested

validate/gst/qa/Makefile.am
validate/gst/qa/gst-qa-monitor.c
validate/gst/qa/gst-qa-monitor.h
validate/gst/qa/gst-qa-pad-monitor.c
validate/gst/qa/gst-qa-report.c [new file with mode: 0644]
validate/gst/qa/gst-qa-report.h [new file with mode: 0644]
validate/gst/qa/gst-qa-runner.c
validate/gst/qa/gst-qa-runner.h
validate/gst/qa/gst-qa.c

index d3bb1a7..3e54fd2 100644 (file)
@@ -8,6 +8,7 @@ c_sources = \
        gst-qa-bin-monitor.c \
        gst-qa-pad-monitor.c \
        gst-qa-monitor-factory.c \
+       gst-qa-report.c \
        gst-qa-monitor-preload.c
 
 noinst_HEADERS = 
index 6b6d80a..6cee777 100644 (file)
@@ -52,6 +52,10 @@ gst_qa_monitor_get_property (GObject * object, guint prop_id,
 static void
 gst_qa_monitor_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
+static GObject *gst_qa_monitor_constructor (GType type,
+    guint n_construct_params, GObjectConstructParam * construct_params);
+
+gboolean gst_qa_monitor_setup (GstQaMonitor * monitor);
 
 static void
 gst_qa_monitor_dispose (GObject * object)
@@ -76,16 +80,30 @@ gst_qa_monitor_class_init (GstQaMonitorClass * klass)
   gobject_class->get_property = gst_qa_monitor_get_property;
   gobject_class->set_property = gst_qa_monitor_set_property;
   gobject_class->dispose = gst_qa_monitor_dispose;
+  gobject_class->constructor = gst_qa_monitor_constructor;
 
   klass->setup = gst_qa_monitor_do_setup;
 
   g_object_class_install_property (gobject_class, PROP_OBJECT,
       g_param_spec_object ("object", "Object", "The object to be monitored",
-          G_TYPE_OBJECT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+          GST_TYPE_OBJECT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_RUNNER,
       g_param_spec_object ("qa-runner", "QA Runner", "The QA runner to "
-          "report errors to", GST_TYPE_QA_RUNNER, G_PARAM_READWRITE));
+          "report errors to", GST_TYPE_QA_RUNNER,
+          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+}
+
+static GObject *
+gst_qa_monitor_constructor (GType type, guint n_construct_params,
+    GObjectConstructParam * construct_params)
+{
+  GstQaMonitor *monitor =
+      GST_QA_MONITOR_CAST (G_OBJECT_CLASS (parent_class)->constructor (type,
+          n_construct_params,
+          construct_params));
+  gst_qa_monitor_setup (monitor);
+  return (GObject *) monitor;
 }
 
 static void
@@ -139,7 +157,6 @@ gst_qa_monitor_set_property (GObject * object, guint prop_id,
     case PROP_OBJECT:
       g_assert (monitor->object == NULL);
       monitor->object = g_value_dup_object (value);
-      gst_qa_monitor_setup (monitor);
       break;
     case PROP_RUNNER:
       /* we assume the runner is valid as long as this monitor is,
@@ -175,3 +192,24 @@ gst_qa_monitor_get_property (GObject * object, guint prop_id,
       break;
   }
 }
+
+void
+gst_qa_monitor_post_error (GstQaMonitor * monitor, GstQaErrorArea area,
+    const gchar * message, const gchar * detail)
+{
+  GstQaErrorReport *report;
+
+  report =
+      gst_qa_error_report_new (GST_OBJECT_CAST (GST_QA_MONITOR_GET_OBJECT
+          (monitor)), area, message, detail);
+
+  GST_WARNING_OBJECT (monitor, "Received error report %d : %s : %s",
+      area, message, detail);
+  gst_qa_error_report_printf (report);
+  if (GST_QA_MONITOR_GET_RUNNER (monitor)) {
+    gst_qa_runner_add_error_report (GST_QA_MONITOR_GET_RUNNER (monitor),
+        report);
+  } else {
+    gst_qa_error_report_free (report);
+  }
+}
index 4913644..64f0f66 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <glib-object.h>
 #include <gst/gst.h>
+#include "gst-qa-report.h"
 #include "gst-qa-runner.h"
 
 G_BEGIN_DECLS
@@ -55,7 +56,7 @@ typedef struct _GstQaMonitorClass GstQaMonitorClass;
 struct _GstQaMonitor {
   GObject       parent;
 
-  GObject       *object;
+  GstObject     *object;
   GMutex         mutex;
 
   GstQaRunner   *runner;
@@ -78,6 +79,8 @@ struct _GstQaMonitorClass {
 /* normal GObject stuff */
 GType          gst_qa_monitor_get_type         (void);
 
+void            gst_qa_monitor_post_error       (GstQaMonitor * monitor, GstQaErrorArea area, const gchar * message, const gchar * detail);
+
 G_END_DECLS
 
 #endif /* __GST_QA_MONITOR_H__ */
index 8545d49..d42f279 100644 (file)
@@ -144,12 +144,17 @@ gst_qa_pad_monitor_event_func (GstPad * pad, GstEvent * event)
         if (seqnum == pad_monitor->pending_flush_start_seqnum) {
           pad_monitor->pending_flush_start_seqnum = 0;
         } else {
-          /* TODO error */
+          gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor),
+              GST_QA_ERROR_AREA_EVENT, "Wrong flush-start seqnum",
+              "The expected flush-start seqnum should be the same as the "
+              "one from the event that caused it (probably a seek)");
         }
       }
 
       if (pad_monitor->pending_flush_stop) {
-        /* TODO ERROR, do report */
+        gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor),
+            GST_QA_ERROR_AREA_EVENT, "Received flush-start when flush-stop was "
+            "expected", NULL);
       }
     }
       break;
@@ -159,12 +164,16 @@ gst_qa_pad_monitor_event_func (GstPad * pad, GstEvent * event)
         if (seqnum == pad_monitor->pending_flush_stop_seqnum) {
           pad_monitor->pending_flush_stop_seqnum = 0;
         } else {
-          /* TODO error */
+          gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor),
+              GST_QA_ERROR_AREA_EVENT, "Wrong flush-stop seqnum",
+              "The expected flush-stop seqnum should be the same as the "
+              "one from the event that caused it (probably a seek)");
         }
       }
 
       if (!pad_monitor->pending_flush_stop) {
-        /* TODO ERROR, do report */
+        gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor),
+            GST_QA_ERROR_AREA_EVENT, "Unexpected flush-stop", NULL);
       }
     }
       break;
diff --git a/validate/gst/qa/gst-qa-report.c b/validate/gst/qa/gst-qa-report.c
new file mode 100644 (file)
index 0000000..10bbb76
--- /dev/null
@@ -0,0 +1,72 @@
+/* GStreamer
+ * Copyright (C) 2013 Thiago Santos <thiago.sousa.santos@collabora.com>
+ *
+ * gst-qa-monitor-preload.c - QA Element monitors preload functions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include "gst-qa-report.h"
+
+const gchar *
+gst_qa_error_area_get_name (GstQaErrorArea area)
+{
+  switch (area) {
+    case GST_QA_ERROR_AREA_EVENT:
+      return "event";
+    case GST_QA_ERROR_AREA_BUFFER:
+      return "buffer";
+    case GST_QA_ERROR_AREA_QUERY:
+      return "query";
+    case GST_QA_ERROR_AREA_OTHER:
+      return "other";
+    default:
+      g_assert_not_reached ();
+      return "unknown";
+  }
+}
+
+GstQaErrorReport *
+gst_qa_error_report_new (GstObject * source, GstQaErrorArea area,
+    const gchar * message, const gchar * detail)
+{
+  GstQaErrorReport *report = g_slice_new0 (GstQaErrorReport);
+
+  report->source = g_object_ref (source);
+  report->area = area;
+  report->message = g_strdup (message);
+  report->detail = g_strdup (detail);
+
+  return report;
+}
+
+void
+gst_qa_error_report_free (GstQaErrorReport * report)
+{
+  g_free (report->message);
+  g_free (report->detail);
+  g_object_unref (report->source);
+  g_slice_free (GstQaErrorReport, report);
+}
+
+void
+gst_qa_error_report_printf (GstQaErrorReport * report)
+{
+  g_print (GST_QA_ERROR_REPORT_PRINT_FORMAT "\n",
+      GST_QA_REPORT_PRINT_ARGS (report));
+}
diff --git a/validate/gst/qa/gst-qa-report.h b/validate/gst/qa/gst-qa-report.h
new file mode 100644 (file)
index 0000000..dec0134
--- /dev/null
@@ -0,0 +1,58 @@
+/* GStreamer
+ * Copyright (C) 2013 Thiago Santos <thiago.sousa.santos@collabora.com>
+ *
+ * gst-qa-monitor-report.h - QA Element report structures and functions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_QA_REPORT_H__
+#define __GST_QA_REPORT_H__
+
+#include <glib-object.h>
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+  GST_QA_ERROR_AREA_EVENT=0,
+  GST_QA_ERROR_AREA_BUFFER,
+  GST_QA_ERROR_AREA_QUERY,
+  GST_QA_ERROR_AREA_OTHER=100,
+} GstQaErrorArea;
+
+typedef struct {
+  GstQaErrorArea area;
+  gchar *message;
+  gchar *detail;
+
+  GstObject *source;
+} GstQaErrorReport;
+
+#define GST_QA_ERROR_REPORT_PRINT_FORMAT "%d - %s - %s) %s (%s)"
+#define GST_QA_REPORT_PRINT_ARGS(r) r->area, gst_qa_error_area_get_name(r->area), \
+                                    r->source ? GST_OBJECT_NAME(r->source) : "null", \
+                                    r->message, r->detail
+
+GstQaErrorReport * gst_qa_error_report_new (GstObject * source, GstQaErrorArea area, const gchar * message, const gchar * detail);
+void               gst_qa_error_report_free (GstQaErrorReport * report);
+
+void               gst_qa_error_report_printf (GstQaErrorReport * report);
+
+G_END_DECLS
+
+#endif /* __GST_QA_REPORT_H__ */
+
index b5d6fef..9784e78 100644 (file)
@@ -44,6 +44,9 @@ gst_qa_runner_dispose (GObject * object)
   if (runner->pipeline)
     gst_object_unref (runner->pipeline);
 
+  g_slist_free_full (runner->error_reports,
+      (GDestroyNotify) gst_qa_error_report_free);
+
   if (runner->monitor)
     g_object_unref (runner->monitor);
 
@@ -98,3 +101,21 @@ gst_qa_runner_setup (GstQaRunner * runner)
   GST_DEBUG_OBJECT (runner, "Setup successful");
   return TRUE;
 }
+
+void
+gst_qa_runner_add_error_report (GstQaRunner * runner, GstQaErrorReport * report)
+{
+  runner->error_reports = g_slist_prepend (runner->error_reports, report);
+}
+
+void
+gst_qa_runner_print_error_reports (GstQaRunner * runner)
+{
+  GSList *iter;
+
+  for (iter = runner->error_reports; iter; iter = g_slist_next (iter)) {
+    GstQaErrorReport *report = iter->data;
+
+    gst_qa_error_report_printf (report);
+  }
+}
index 4ee752b..de4dba0 100644 (file)
@@ -25,6 +25,8 @@
 #include <glib-object.h>
 #include <gst/gst.h>
 
+#include "gst-qa-report.h"
+
 G_BEGIN_DECLS
 
 /* forward declaration */
@@ -58,6 +60,8 @@ struct _GstQaRunner {
   /*< private >*/
   GstElement    *pipeline;
   GstQaElementMonitor *monitor;
+
+  GSList *error_reports;
 };
 
 /**
@@ -76,6 +80,9 @@ GType         gst_qa_runner_get_type          (void);
 GstQaRunner *   gst_qa_runner_new               (GstElement * pipeline);
 gboolean        gst_qa_runner_setup             (GstQaRunner * runner);
 
+void            gst_qa_runner_add_error_report  (GstQaRunner * runner, GstQaErrorReport * report);
+void            gst_qa_runner_print_error_reports (GstQaRunner * runner);
+
 G_END_DECLS
 
 #endif /* __GST_QA_RUNNER_H__ */
index 71c7918..ed78e59 100644 (file)
@@ -113,11 +113,13 @@ main (int argc, gchar ** argv)
     goto exit;
   g_main_loop_run (mainloop);
 
-  /* TODO get report from QA runner */
+  g_print ("Pipeline finished, printing issues found: \n");
+  gst_qa_runner_print_error_reports (runner);
 
 exit:
   gst_element_set_state (pipeline, GST_STATE_NULL);
   g_main_loop_unref (mainloop);
   g_object_unref (runner);
+  g_object_unref (pipeline);
   return 0;
 }