diff --git a/validate/gst/qa/Makefile.am b/validate/gst/qa/Makefile.am index d3bb1a77b6..3e54fd299a 100644 --- a/validate/gst/qa/Makefile.am +++ b/validate/gst/qa/Makefile.am @@ -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 = diff --git a/validate/gst/qa/gst-qa-monitor.c b/validate/gst/qa/gst-qa-monitor.c index 6b6d80ac23..6cee777996 100644 --- a/validate/gst/qa/gst-qa-monitor.c +++ b/validate/gst/qa/gst-qa-monitor.c @@ -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); + } +} diff --git a/validate/gst/qa/gst-qa-monitor.h b/validate/gst/qa/gst-qa-monitor.h index 4913644eaa..64f0f661bb 100644 --- a/validate/gst/qa/gst-qa-monitor.h +++ b/validate/gst/qa/gst-qa-monitor.h @@ -24,6 +24,7 @@ #include #include +#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__ */ diff --git a/validate/gst/qa/gst-qa-pad-monitor.c b/validate/gst/qa/gst-qa-pad-monitor.c index 8545d4926a..d42f2796b7 100644 --- a/validate/gst/qa/gst-qa-pad-monitor.c +++ b/validate/gst/qa/gst-qa-pad-monitor.c @@ -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 index 0000000000..10bbb76df4 --- /dev/null +++ b/validate/gst/qa/gst-qa-report.c @@ -0,0 +1,72 @@ +/* GStreamer + * Copyright (C) 2013 Thiago Santos + * + * 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 + +#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 index 0000000000..dec0134ba7 --- /dev/null +++ b/validate/gst/qa/gst-qa-report.h @@ -0,0 +1,58 @@ +/* GStreamer + * Copyright (C) 2013 Thiago Santos + * + * 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 +#include + +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__ */ + diff --git a/validate/gst/qa/gst-qa-runner.c b/validate/gst/qa/gst-qa-runner.c index b5d6fef540..9784e78677 100644 --- a/validate/gst/qa/gst-qa-runner.c +++ b/validate/gst/qa/gst-qa-runner.c @@ -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); + } +} diff --git a/validate/gst/qa/gst-qa-runner.h b/validate/gst/qa/gst-qa-runner.h index 4ee752b62d..de4dba07fb 100644 --- a/validate/gst/qa/gst-qa-runner.h +++ b/validate/gst/qa/gst-qa-runner.h @@ -25,6 +25,8 @@ #include #include +#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__ */ diff --git a/validate/gst/qa/gst-qa.c b/validate/gst/qa/gst-qa.c index 71c79187cc..ed78e59cc5 100644 --- a/validate/gst/qa/gst-qa.c +++ b/validate/gst/qa/gst-qa.c @@ -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; }