From 4992249848a632a83103db5b0f05f4570f6dc016 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 22 Jul 2013 19:17:53 -0400 Subject: [PATCH] qa: Add a GstQaReporter interface that objects needing reporting can implement Various type of object should be able to do some reporting, so we have to make sure all the code to do that is in one place. Creating an interface makes it simple to share information and it avoid to have a baseclass for something that is not actually important enough to create a baseclass. Conflicts: gst/qa/gst-qa-pad-monitor.c --- validate/data/Makefile.am | 4 +- validate/gst/qa/Makefile.am | 1 + validate/gst/qa/gst-qa-monitor.c | 80 ++------------- validate/gst/qa/gst-qa-monitor.h | 72 -------------- validate/gst/qa/gst-qa-pad-monitor.c | 49 ++++----- validate/gst/qa/gst-qa-report.c | 4 +- validate/gst/qa/gst-qa-report.h | 3 +- validate/gst/qa/gst-qa-reporter.c | 142 +++++++++++++++++++++++++++ validate/gst/qa/gst-qa-reporter.h | 122 +++++++++++++++++++++++ 9 files changed, 304 insertions(+), 173 deletions(-) create mode 100644 validate/gst/qa/gst-qa-reporter.c create mode 100644 validate/gst/qa/gst-qa-reporter.h diff --git a/validate/data/Makefile.am b/validate/data/Makefile.am index 3a2fc92180..50ebe3715a 100644 --- a/validate/data/Makefile.am +++ b/validate/data/Makefile.am @@ -1,3 +1,3 @@ -confdir=${sysconfdir}/gstreamer -conf_DATA = simple_seeks.xml +scenariosdir=${datadir}/gstreamer-$(GST_API_VERSION)/qa-scenario +scenarios_DATA = simple_seeks.xml EXTRA_DIST = simple_seeks.xml diff --git a/validate/gst/qa/Makefile.am b/validate/gst/qa/Makefile.am index 979effa48a..5c0aee1812 100644 --- a/validate/gst/qa/Makefile.am +++ b/validate/gst/qa/Makefile.am @@ -3,6 +3,7 @@ public_headers = \ c_sources = \ gst-qa-runner.c \ + gst-qa-reporter.c \ gst-qa-monitor.c \ gst-qa-element-monitor.c \ gst-qa-bin-monitor.c \ diff --git a/validate/gst/qa/gst-qa-monitor.c b/validate/gst/qa/gst-qa-monitor.c index a7f4567e84..3259b32bc5 100644 --- a/validate/gst/qa/gst-qa-monitor.c +++ b/validate/gst/qa/gst-qa-monitor.c @@ -20,6 +20,7 @@ */ #include "gst-qa-monitor.h" +#include "gst-qa-reporter.h" /** * SECTION:gst-qa-monitor @@ -41,7 +42,10 @@ GST_DEBUG_CATEGORY_STATIC (gst_qa_monitor_debug); #define GST_CAT_DEFAULT gst_qa_monitor_debug #define _do_init \ - GST_DEBUG_CATEGORY_INIT (gst_qa_monitor_debug, "qa_monitor", 0, "QA Monitor"); + GST_DEBUG_CATEGORY_INIT (gst_qa_monitor_debug, "qa_monitor", 0, "QA Monitor");\ + G_IMPLEMENT_INTERFACE (GST_TYPE_QA_REPORTER, NULL) + + #define gst_qa_monitor_parent_class parent_class G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstQaMonitor, gst_qa_monitor, G_TYPE_OBJECT, _do_init); @@ -76,17 +80,13 @@ gst_qa_monitor_dispose (GObject * object) g_object_weak_unref (G_OBJECT (monitor->target), (GWeakNotify) _target_freed_cb, monitor); - g_hash_table_unref (monitor->reports); - G_OBJECT_CLASS (parent_class)->dispose (object); } static void gst_qa_monitor_finalize (GObject * object) { - GstQaMonitor *monitor = GST_QA_MONITOR_CAST (object); - - gst_qa_monitor_set_target_name (monitor, NULL); + gst_qa_reporter_set_name (GST_QA_REPORTER (object), NULL); G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -133,20 +133,11 @@ gst_qa_monitor_constructor (GType type, guint n_construct_params, return (GObject *) monitor; } -static inline gchar * -_qa_report_id (GstQaReport * report) -{ - return g_strdup_printf ("%i-%i-%i-%s", - report->level, report->area, report->subarea, report->id); -} - static void gst_qa_monitor_init (GstQaMonitor * monitor) { g_mutex_init (&monitor->mutex); - monitor->reports = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) gst_qa_report_unref); } /** @@ -198,7 +189,7 @@ gst_qa_monitor_set_property (GObject * object, guint prop_id, (GWeakNotify) _target_freed_cb, monitor); if (monitor->target) - gst_qa_monitor_set_target_name (monitor, g_strdup + gst_qa_reporter_set_name (GST_QA_REPORTER (monitor), g_strdup (GST_OBJECT_NAME (monitor->target))); break; case PROP_RUNNER: @@ -238,60 +229,3 @@ gst_qa_monitor_get_property (GObject * object, guint prop_id, break; } } - -void -gst_qa_monitor_do_report_valist (GstQaMonitor * monitor, gboolean repeat, - GstQaReportLevel level, GstQaReportArea area, - gint subarea, const gchar * format, va_list var_args) -{ - GstQaReport *report; - gchar *message, *report_id = NULL; - - message = g_strdup_vprintf (format, var_args); - report = gst_qa_report_new (monitor, level, area, subarea, format, message); - - if (repeat == FALSE) { - report_id = _qa_report_id (report); - - if (g_hash_table_lookup (monitor->reports, report_id)) { - GST_DEBUG ("Report %s already present", report_id); - g_free (report_id); - return; - } - - g_hash_table_insert (monitor->reports, report_id, report); - } - - GST_INFO_OBJECT (monitor, "Received error report %d : %d : %d : %s", - level, area, subarea, message); - gst_qa_report_printf (report); - if (GST_QA_MONITOR_GET_RUNNER (monitor)) { - gst_qa_runner_add_report (GST_QA_MONITOR_GET_RUNNER (monitor), report); - } else { - gst_qa_report_unref (report); - } - - g_free (message); -} - -void -gst_qa_monitor_do_report (GstQaMonitor * monitor, gboolean repeat, - GstQaReportLevel level, GstQaReportArea area, - gint subarea, const gchar * format, ...) -{ - va_list var_args; - - va_start (var_args, format); - gst_qa_monitor_do_report_valist (monitor, repeat, level, area, subarea, - format, var_args); - va_end (var_args); -} - -void -gst_qa_monitor_set_target_name (GstQaMonitor * monitor, gchar * target_name) -{ - if (monitor->target_name) - g_free (monitor->target_name); - - monitor->target_name = target_name; -} diff --git a/validate/gst/qa/gst-qa-monitor.h b/validate/gst/qa/gst-qa-monitor.h index 82c06f9399..d45ba10f61 100644 --- a/validate/gst/qa/gst-qa-monitor.h +++ b/validate/gst/qa/gst-qa-monitor.h @@ -44,66 +44,6 @@ G_BEGIN_DECLS #define GST_QA_MONITOR_LOCK(m) (g_mutex_lock (&GST_QA_MONITOR_CAST(m)->mutex)) #define GST_QA_MONITOR_UNLOCK(m) (g_mutex_unlock (&GST_QA_MONITOR_CAST(m)->mutex)) -#ifdef G_HAVE_ISO_VARARGS -#define GST_QA_MONITOR_REPORT(m, repeat, status, area, subarea, ...) \ -G_STMT_START { \ - gst_qa_monitor_do_report (GST_QA_MONITOR (m), repeat, \ - GST_QA_REPORT_LEVEL_ ## status, GST_QA_AREA_ ## area, \ - GST_QA_AREA_ ## area ## _ ## subarea, __VA_ARGS__ ); \ -} G_STMT_END - -#define GST_QA_MONITOR_REPORT_CRITICAL(m, repeat, area, subarea, ...) \ -G_STMT_START { \ - GST_ERROR_OBJECT (m, "Critical report: %s: %s: %s", \ - #area, #subarea, __VA_ARGS__); \ - GST_QA_MONITOR_REPORT(m, repeat, CRITICAL, area, subarea, __VA_ARGS__); \ -} G_STMT_END - -#define GST_QA_MONITOR_REPORT_WARNING(m, repeat, area, subarea, ...) \ -G_STMT_START { \ - GST_WARNING_OBJECT (m, "Warning report: %s: %s: %s", \ - #area, #subarea, __VA_ARGS__); \ - GST_QA_MONITOR_REPORT(m, repeat, WARNING, area, subarea, __VA_ARGS__); \ -} G_STMT_END - -#define GST_QA_MONITOR_REPORT_ISSUE(m, repeat, area, subarea, ...) \ -G_STMT_START { \ - GST_WARNING_OBJECT (m, "Issue report: %s: %s: %s", \ - #area, #subarea, __VA_ARGS__); \ - GST_QA_MONITOR_REPORT(m, repeat, ISSUE, area, subarea, __VA_ARGS__); \ -} G_STMT_END -#else /* G_HAVE_GNUC_VARARGS */ -#ifdef G_HAVE_GNUC_VARARGS -#define GST_QA_MONITOR_REPORT(m, repeat, status, area, subarea, args...) \ -G_STMT_START { \ - gst_qa_monitor_do_report (GST_QA_MONITOR (m), \ - GST_QA_REPORT_LEVEL_ ## status, GST_QA_AREA_ ## area, \ - GST_QA_AREA_ ## area ## _ ## subarea, ##args ); \ -} G_STMT_END - -#define GST_QA_MONITOR_REPORT_CRITICAL(m, repeat, area, subarea, args...) \ -G_STMT_START { \ - GST_ERROR_OBJECT (m, "Critical report: %s: %s: %s", \ - #area, #subarea, ##args); \ - GST_QA_MONITOR_REPORT(m, repeat, CRITICAL, area, subarea, ##args); \ -} G_STMT_END - -#define GST_QA_MONITOR_REPORT_WARNING(m, repeat, area, subarea, args...) \ -G_STMT_START { \ - GST_WARNING_OBJECT (m, "Warning report: %s: %s: %s", \ - #area, #subarea, ##args); \ - GST_QA_MONITOR_REPORT(m, repeat, WARNING, area, subarea, ##args); \ -} G_STMT_END - -#define GST_QA_MONITOR_REPORT_ISSUE(m, repeat, area, subarea, args...) \ -G_STMT_START { \ - GST_WARNING_OBJECT (m, "Issue report: %s: %s: %s", \ - #area, #subarea, ##args); \ - GST_QA_MONITOR_REPORT(m, repeat, ISSUE, area, subarea, ##args); \ -} G_STMT_END -#endif /* G_HAVE_ISO_VARARGS */ -#endif /* G_HAVE_GNUC_VARARGS */ - /* #else TODO Implemen no variadic macros, use inline, * Problem being: * GST_QA_REPORT_LEVEL_ ## status @@ -150,18 +90,6 @@ struct _GstQaMonitorClass { /* normal GObject stuff */ GType gst_qa_monitor_get_type (void); -void gst_qa_monitor_do_report (GstQaMonitor * monitor, gboolean repeat, - GstQaReportLevel level, GstQaReportArea area, - gint subarea, const gchar * format, ...); - -void gst_qa_monitor_do_report_valist (GstQaMonitor * monitor, gboolean repeat, - GstQaReportLevel level, GstQaReportArea area, - gint subarea, const gchar *format, - va_list var_args); - -void gst_qa_monitor_set_target_name (GstQaMonitor *monitor, - gchar *target_name); - 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 18b029e078..9373d336bd 100644 --- a/validate/gst/qa/gst-qa-pad-monitor.c +++ b/validate/gst/qa/gst-qa-pad-monitor.c @@ -21,6 +21,7 @@ #include "gst-qa-pad-monitor.h" #include "gst-qa-element-monitor.h" +#include "gst-qa-reporter.h" #include #include #include @@ -156,7 +157,7 @@ _check_field_type (GstQaPadMonitor * monitor, GstStructure * structure, gint rejected_types_index = 0; if (!gst_structure_has_field (structure, field)) { - GST_QA_MONITOR_REPORT_WARNING (monitor, FALSE, CAPS_NEGOTIATION, + GST_QA_REPORT_WARNING (GST_QA_REPORTER (monitor), FALSE, CAPS_NEGOTIATION, MISSING_FIELD, "%s is missing from structure: %" GST_PTR_FORMAT, field, structure); return; @@ -174,7 +175,7 @@ _check_field_type (GstQaPadMonitor * monitor, GstStructure * structure, va_end (var_args); joined_types = g_strjoinv (" / ", (gchar **) rejected_types); - GST_QA_MONITOR_REPORT_CRITICAL (monitor, FALSE, CAPS_NEGOTIATION, + GST_QA_REPORT_CRITICAL (GST_QA_REPORTER (monitor), FALSE, CAPS_NEGOTIATION, BAD_FIELD_TYPE, "%s has wrong type %s in structure '%" GST_PTR_FORMAT "'. Expected: %s", field, g_type_name (gst_structure_get_field_type (structure, field)), @@ -444,7 +445,7 @@ gst_qa_pad_monitor_check_caps_fields_proxied (GstQaPadMonitor * monitor, } if (type_match && !found) { - GST_QA_MONITOR_REPORT_WARNING (monitor, FALSE, CAPS_NEGOTIATION, + GST_QA_REPORT_WARNING (monitor, FALSE, CAPS_NEGOTIATION, GET_CAPS, "Peer pad structure '%" GST_PTR_FORMAT "' has no similar version " "on pad's caps '%" GST_PTR_FORMAT "'", otherstructure, caps); @@ -464,7 +465,7 @@ gst_qa_pad_monitor_check_late_serialized_events (GstQaPadMonitor * monitor, SerializedEventData *data = g_ptr_array_index (monitor->serialized_events, i); if (data->timestamp < ts) { - GST_QA_MONITOR_REPORT_WARNING (monitor, FALSE, EVENT, EXPECTED, + GST_QA_REPORT_WARNING (monitor, FALSE, EVENT, EXPECTED, "Serialized event %" GST_PTR_FORMAT " wasn't pushed before expected " "timestamp %" GST_TIME_FORMAT " on pad %s:%s", data->event, GST_TIME_ARGS (data->timestamp), @@ -482,7 +483,7 @@ gst_qa_pad_monitor_check_late_serialized_events (GstQaPadMonitor * monitor, void _parent_set_cb (GstObject * object, GstObject * parent, GstQaMonitor * monitor) { - gst_qa_monitor_set_target_name (monitor, g_strdup_printf ("%s:%s", + gst_qa_reporter_set_name (GST_QA_REPORTER (monitor), g_strdup_printf ("%s:%s", GST_DEBUG_PAD_NAME (object))); } @@ -641,7 +642,7 @@ gst_qa_pad_monitor_check_buffer_timestamp_in_received_range (GstQaPadMonitor * return; } if (!found) { - GST_QA_MONITOR_REPORT_WARNING (monitor, FALSE, BUFFER, TIMESTAMP, + GST_QA_REPORT_WARNING (monitor, FALSE, BUFFER, TIMESTAMP, "Timestamp %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT " is out of range of received input", GST_TIME_ARGS (ts), GST_TIME_ARGS (ts_end)); @@ -657,14 +658,14 @@ gst_qa_pad_monitor_check_first_buffer (GstQaPadMonitor * pad_monitor, if (!pad_monitor->has_segment && PAD_IS_IN_PUSH_MODE (GST_QA_PAD_MONITOR_GET_PAD (pad_monitor))) { - GST_QA_MONITOR_REPORT_WARNING (pad_monitor, FALSE, EVENT, EXPECTED, - "Received buffer before Segment event"); + GST_QA_REPORT_WARNING (GST_QA_REPORTER (pad_monitor), FALSE, EVENT, + EXPECTED, "Received buffer before Segment event"); } if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer))) { gint64 running_time = gst_segment_to_running_time (&pad_monitor->segment, pad_monitor->segment.format, GST_BUFFER_TIMESTAMP (buffer)); if (running_time != 0) { - GST_QA_MONITOR_REPORT_WARNING (pad_monitor, FALSE, BUFFER, TIMESTAMP, + GST_QA_REPORT_WARNING (pad_monitor, FALSE, BUFFER, TIMESTAMP, "First buffer running time is not 0, it is: %" GST_TIME_FORMAT, GST_TIME_ARGS (running_time)); } @@ -773,7 +774,7 @@ gst_qa_pad_monitor_check_aggregated_return (GstQaPadMonitor * monitor, } if (aggregated != ret) { /* TODO review this error code */ - GST_QA_MONITOR_REPORT_CRITICAL (monitor, TRUE, BUFFER, UNEXPECTED, + GST_QA_REPORT_CRITICAL (monitor, TRUE, BUFFER, UNEXPECTED, "Wrong combined flow return %s(%d). Expected: %s(%d)", gst_flow_get_name (ret), ret, gst_flow_get_name (aggregated), aggregated); @@ -923,7 +924,7 @@ gst_qa_pad_monitor_add_expected_newsegment (GstQaPadMonitor * monitor, othermonitor = g_object_get_data ((GObject *) otherpad, "qa-monitor"); GST_QA_MONITOR_LOCK (othermonitor); if (othermonitor->expected_segment) { - GST_QA_MONITOR_REPORT_WARNING (othermonitor, FALSE, EVENT, EXPECTED, + GST_QA_REPORT_WARNING (othermonitor, FALSE, EVENT, EXPECTED, "expected newsegment event never pushed"); gst_event_unref (othermonitor->expected_segment); } @@ -960,7 +961,8 @@ gst_qa_pad_monitor_common_event_check (GstQaPadMonitor * pad_monitor, if (seqnum == pad_monitor->pending_flush_start_seqnum) { pad_monitor->pending_flush_start_seqnum = 0; } else { - GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, TRUE, EVENT, SEQNUM, + GST_QA_REPORT_ISSUE (GST_QA_REPORTER (pad_monitor), TRUE, EVENT, + SEQNUM, "The expected flush-start seqnum should be the same as the " "one from the event that caused it (probably a seek). Got: %u." " Expected: %u", seqnum, pad_monitor->pending_flush_start_seqnum); @@ -968,7 +970,8 @@ gst_qa_pad_monitor_common_event_check (GstQaPadMonitor * pad_monitor, } if (pad_monitor->pending_flush_stop) { - GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, TRUE, EVENT, UNEXPECTED, + GST_QA_REPORT_ISSUE (GST_QA_REPORTER (pad_monitor), TRUE, EVENT, + UNEXPECTED, "Received flush-start from %" GST_PTR_FORMAT " when flush-stop was expected", GST_EVENT_SRC (event)); } @@ -981,7 +984,8 @@ gst_qa_pad_monitor_common_event_check (GstQaPadMonitor * pad_monitor, if (seqnum == pad_monitor->pending_flush_stop_seqnum) { pad_monitor->pending_flush_stop_seqnum = 0; } else { - GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, TRUE, EVENT, SEQNUM, + GST_QA_REPORT_ISSUE (GST_QA_REPORTER (pad_monitor), TRUE, EVENT, + SEQNUM, "The expected flush-stop seqnum should be the same as the " "one from the event that caused it (probably a seek). Got: %u." " Expected: %u", seqnum, pad_monitor->pending_flush_stop_seqnum); @@ -989,8 +993,8 @@ gst_qa_pad_monitor_common_event_check (GstQaPadMonitor * pad_monitor, } if (!pad_monitor->pending_flush_stop) { - GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, TRUE, EVENT, UNEXPECTED, - "Unexpected flush-stop %p from %" GST_PTR_FORMAT, event, + GST_QA_REPORT_ISSUE (GST_QA_REPORTER (pad_monitor), TRUE, EVENT, + UNEXPECTED, "Unexpected flush-stop %p from %" GST_PTR_FORMAT, event, GST_EVENT_SRC (event)); } pad_monitor->pending_flush_stop = FALSE; @@ -1050,7 +1054,7 @@ gst_qa_pad_monitor_sink_event_check (GstQaPadMonitor * pad_monitor, || (exp_rate * exp_applied_rate != rate * applied_rate) || exp_start != start || exp_stop != stop || exp_position != position) { - GST_QA_MONITOR_REPORT_WARNING (pad_monitor, TRUE, EVENT, + GST_QA_REPORT_WARNING (pad_monitor, TRUE, EVENT, EXPECTED, "Expected segment didn't match received segment event"); } @@ -1147,7 +1151,6 @@ gst_qa_pad_monitor_src_event_check (GstQaPadMonitor * pad_monitor, pad_monitor->pending_newsegment_seqnum = seqnum; } break; - /* both flushes are handled by the common event handling function */ case GST_EVENT_FLUSH_START: case GST_EVENT_FLUSH_STOP: @@ -1317,7 +1320,7 @@ gst_qa_pad_monitor_buffer_probe (GstPad * pad, GstBuffer * buffer, GST_BUFFER_TIMESTAMP (buffer), GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer), NULL, NULL)) { /* TODO is this a timestamp issue? */ - GST_QA_MONITOR_REPORT_ISSUE (monitor, FALSE, BUFFER, TIMESTAMP, + GST_QA_REPORT_ISSUE (monitor, FALSE, BUFFER, TIMESTAMP, "buffer is out of segment and shouldn't be pushed. Timestamp: %" GST_TIME_FORMAT " - duration: %" GST_TIME_FORMAT ". Range: %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT, @@ -1361,7 +1364,7 @@ gst_qa_pad_monitor_event_probe (GstPad * pad, GstEvent * event, gpointer udata) if (event == stored_event->event || GST_EVENT_TYPE (event) == GST_EVENT_TYPE (stored_event->event)) { - GST_QA_MONITOR_REPORT_WARNING (monitor, FALSE, EVENT, UNEXPECTED, + GST_QA_REPORT_WARNING (monitor, FALSE, EVENT, UNEXPECTED, "Serialized event %" GST_PTR_FORMAT " was pushed out of original " "serialization order in pad %s:%s", event, GST_DEBUG_PAD_NAME (GST_QA_PAD_MONITOR_GET_PAD (monitor))); @@ -1432,12 +1435,12 @@ gst_qa_pad_monitor_setcaps_func (GstPad * pad, GstCaps * caps) gst_structure_get_value (pad_monitor->pending_setcaps_fields, name); if (v == NULL) { - GST_QA_MONITOR_REPORT_WARNING (pad_monitor, FALSE, CAPS_NEGOTIATION, + GST_QA_REPORT_WARNING (pad_monitor, FALSE, CAPS_NEGOTIATION, MISSING_FIELD, "Field %s is missing from setcaps caps '%" GST_PTR_FORMAT "'", name, caps); } else if (gst_value_compare (v, otherv) != GST_VALUE_EQUAL) { - GST_QA_MONITOR_REPORT_WARNING (pad_monitor, FALSE, CAPS_NEGOTIATION, + GST_QA_REPORT_WARNING (pad_monitor, FALSE, CAPS_NEGOTIATION, MISSING_FIELD, "Field %s from setcaps caps '%" GST_PTR_FORMAT "' is different " "from expected value in caps '%" GST_PTR_FORMAT "'", name, caps, @@ -1535,7 +1538,7 @@ gst_qa_pad_monitor_do_setup (GstQaMonitor * monitor) gst_pad_set_getcaps_function (pad, gst_qa_pad_monitor_getcaps_func); gst_pad_set_setcaps_function (pad, gst_qa_pad_monitor_setcaps_func); - gst_qa_monitor_set_target_name (monitor, g_strdup_printf ("%s:%s", + gst_qa_reporter_set_name (GST_QA_REPORTER (monitor), g_strdup_printf ("%s:%s", GST_DEBUG_PAD_NAME (pad))); g_signal_connect (pad, "parent-set", (GCallback) _parent_set_cb, monitor); diff --git a/validate/gst/qa/gst-qa-report.c b/validate/gst/qa/gst-qa-report.c index 55702a4554..2bdf1d87be 100644 --- a/validate/gst/qa/gst-qa-report.c +++ b/validate/gst/qa/gst-qa-report.c @@ -176,7 +176,7 @@ gst_qa_report_check_abort (GstQaReport * report) } GstQaReport * -gst_qa_report_new (GstQaMonitor * monitor, GstQaReportLevel level, +gst_qa_report_new (const gchar * source_name, GstQaReportLevel level, GstQaReportArea area, gint subarea, const gchar * id, const gchar * message) { GstQaReport *report = g_slice_new0 (GstQaReport); @@ -184,7 +184,7 @@ gst_qa_report_new (GstQaMonitor * monitor, GstQaReportLevel level, report->level = level; report->area = area; report->subarea = subarea; - report->source_name = g_strdup (monitor->target_name); + report->source_name = g_strdup (source_name); report->message = g_strdup (message); report->id = g_strdup (id); report->timestamp = gst_util_get_timestamp () - _gst_qa_report_start_time; diff --git a/validate/gst/qa/gst-qa-report.h b/validate/gst/qa/gst-qa-report.h index 3edc9f70cf..b3e4ada3a1 100644 --- a/validate/gst/qa/gst-qa-report.h +++ b/validate/gst/qa/gst-qa-report.h @@ -108,7 +108,8 @@ typedef struct { r->message void gst_qa_report_init (void); -GstQaReport * gst_qa_report_new (GstQaMonitor * monitor, GstQaReportLevel level, +GstQaReport * gst_qa_report_new (const gchar * source_name, + GstQaReportLevel level, GstQaReportArea area, gint subarea, const gchar *format, diff --git a/validate/gst/qa/gst-qa-reporter.c b/validate/gst/qa/gst-qa-reporter.c new file mode 100644 index 0000000000..06f1d5b9c7 --- /dev/null +++ b/validate/gst/qa/gst-qa-reporter.c @@ -0,0 +1,142 @@ +/* GStreamer + * + * Copyright (C) 2013 Thibault Saunier + * + * 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 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 "gst-qa-reporter.h" +#include "gst-qa-report.h" + +#define REPORTER_PRIVATE "gst-qa-reporter-private" + +typedef struct _GstQaReporterPrivate +{ + GstQaRunner *runner; + GHashTable *reports; + char *name; +} GstQaReporterPrivate; + +static void +gst_qa_reporter_default_init (GstQaReporterInterface * iface) +{ + g_object_interface_install_property (iface, + g_param_spec_object ("qa-runner", "QA Runner", "The QA runner to " + "report errors to", GST_TYPE_QA_RUNNER, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); +} + +G_DEFINE_INTERFACE (GstQaReporter, gst_qa_reporter, G_TYPE_OBJECT); + +static void +_free_priv (GstQaReporterPrivate * priv) +{ + g_hash_table_unref (priv->reports); + g_free (priv->name); +} + +static inline gchar * +_qa_report_id (GstQaReport * report) +{ + return g_strdup_printf ("%i-%i-%i-%s", + report->level, report->area, report->subarea, report->id); +} + +static GstQaReporterPrivate * +gst_qa_reporter_get_priv (GstQaReporter * reporter) +{ + GstQaReporterPrivate *priv = + g_object_get_data (G_OBJECT (reporter), REPORTER_PRIVATE); + + if (priv == NULL) { + priv = g_slice_new0 (GstQaReporterPrivate); + priv->reports = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) gst_qa_report_unref); + + g_object_set_data_full (G_OBJECT (reporter), REPORTER_PRIVATE, priv, + (GDestroyNotify) _free_priv); + } + + return priv; +} + +void +gst_qa_report_valist (GstQaReporter * reporter, gboolean repeat, + GstQaReportLevel level, GstQaReportArea area, + gint subarea, const gchar * format, va_list var_args) +{ + GstQaReport *report; + gchar *message, *report_id = NULL; + GstQaReporterPrivate *priv = gst_qa_reporter_get_priv (reporter); + + message = g_strdup_vprintf (format, var_args); + report = gst_qa_report_new (priv->name, level, area, subarea, + format, message); + + if (repeat == FALSE) { + report_id = _qa_report_id (report); + + if (g_hash_table_lookup (priv->reports, report_id)) { + GST_DEBUG ("Report %s already present", report_id); + g_free (report_id); + return; + } + + g_hash_table_insert (priv->reports, report_id, report); + } + + GST_INFO_OBJECT (reporter, "Received error report %d : %d : %d : %s", + level, area, subarea, message); + gst_qa_report_printf (report); + if (priv->runner) { + gst_qa_runner_add_report (priv->runner, report); + } else { + gst_qa_report_unref (report); + } + + g_free (message); +} + +void +gst_qa_report (GstQaReporter * reporter, gboolean repeat, + GstQaReportLevel level, GstQaReportArea area, + gint subarea, const gchar * format, ...) +{ + va_list var_args; + + va_start (var_args, format); + gst_qa_report_valist (reporter, repeat, level, area, subarea, + format, var_args); + va_end (var_args); +} + +void +gst_qa_reporter_set_name (GstQaReporter * reporter, const gchar * name) +{ + GstQaReporterPrivate *priv = gst_qa_reporter_get_priv (reporter); + + if (priv->name) + g_free (priv->name); + + priv->name = g_strdup (name); +} + +GstQaRunner * +gst_qa_reporter_get_runner (GstQaReporter * reporter) +{ + GstQaReporterPrivate *priv = gst_qa_reporter_get_priv (reporter); + + return priv->runner; +} diff --git a/validate/gst/qa/gst-qa-reporter.h b/validate/gst/qa/gst-qa-reporter.h new file mode 100644 index 0000000000..bdab066f7b --- /dev/null +++ b/validate/gst/qa/gst-qa-reporter.h @@ -0,0 +1,122 @@ +/* GStreamer + * + * Copyright (C) 2013 Thibault Saunier + * + * 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 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_REPORTER_ +#define _GST_QA_REPORTER_ + +#include +#include "gst-qa-runner.h" + +G_BEGIN_DECLS + +typedef struct _GstQaReporter GstQaReporter; +typedef struct _GstQaReporterInterface GstQaReporterInterface; + +/* GstQaReporter interface declarations */ +#define GST_TYPE_QA_REPORTER (gst_qa_reporter_get_type ()) +#define GST_QA_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_QA_REPORTER, GstQaReporter)) +#define GST_IS_QA_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_QA_REPORTER)) +#define GST_QA_REPORTER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_QA_REPORTER, GESExtractableInterface)) + +#ifdef G_HAVE_ISO_VARARGS +#define GST_QA_REPORT(m, repeat, status, area, subarea, ...) \ +G_STMT_START { \ + gst_qa_report (GST_QA_REPORTER (m), repeat, \ + GST_QA_REPORT_LEVEL_ ## status, GST_QA_AREA_ ## area, \ + GST_QA_AREA_ ## area ## _ ## subarea, __VA_ARGS__ ); \ +} G_STMT_END + +#define GST_QA_REPORT_CRITICAL(m, repeat, area, subarea, ...) \ +G_STMT_START { \ + GST_ERROR_OBJECT (m, "Critical report: %s: %s: %s", \ + #area, #subarea, __VA_ARGS__); \ + GST_QA_REPORT(m, repeat, CRITICAL, area, subarea, __VA_ARGS__); \ +} G_STMT_END + +#define GST_QA_REPORT_WARNING(m, repeat, area, subarea, ...) \ +G_STMT_START { \ + GST_WARNING_OBJECT (m, "Warning report: %s: %s: %s", \ + #area, #subarea, __VA_ARGS__); \ + GST_QA_REPORT(m, repeat, WARNING, area, subarea, __VA_ARGS__); \ +} G_STMT_END + +#define GST_QA_REPORT_ISSUE(m, repeat, area, subarea, ...) \ +G_STMT_START { \ + GST_WARNING_OBJECT (m, "Issue report: %s: %s: %s", \ + #area, #subarea, __VA_ARGS__); \ + GST_QA_REPORT(m, repeat, ISSUE, area, subarea, __VA_ARGS__); \ +} G_STMT_END +#else /* G_HAVE_GNUC_VARARGS */ +#ifdef G_HAVE_GNUC_VARARGS +#define GST_QA_REPORT(m, repeat, status, area, subarea, args...) \ +G_STMT_START { \ + gst_qa_reporter_do_report (GST_QA_REPORTER (m), \ + GST_QA_REPORT_LEVEL_ ## status, GST_QA_AREA_ ## area, \ + GST_QA_AREA_ ## area ## _ ## subarea, ##args ); \ +} G_STMT_END + +#define GST_QA_REPORT_CRITICAL(m, repeat, area, subarea, args...) \ +G_STMT_START { \ + GST_ERROR_OBJECT (m, "Critical report: %s: %s: %s", \ + #area, #subarea, ##args); \ + GST_QA_REPORT(m, repeat, CRITICAL, area, subarea, ##args); \ +} G_STMT_END + +#define GST_QA_REPORT_WARNING(m, repeat, area, subarea, args...) \ +G_STMT_START { \ + GST_WARNING_OBJECT (m, "Warning report: %s: %s: %s", \ + #area, #subarea, ##args); \ + GST_QA_REPORT(m, repeat, WARNING, area, subarea, ##args); \ +} G_STMT_END + +#define GST_QA_REPORT_ISSUE(m, repeat, area, subarea, args...) \ +G_STMT_START { \ + GST_WARNING_OBJECT (m, "Issue report: %s: %s: %s", \ + #area, #subarea, ##args); \ + GST_QA_REPORT(m, repeat, ISSUE, area, subarea, ##args); \ +} G_STMT_END +#endif /* G_HAVE_ISO_VARARGS */ +#endif /* G_HAVE_GNUC_VARARGS */ + +GType gst_qa_reporter_get_type (void); + +/** + * GstQaReporter: + */ +struct _GstQaReporterInterface +{ + GTypeInterface parent; +}; + +void gst_qa_reporter_set_name (GstQaReporter * reporter, + const gchar * name); +GstQaRunner * gst_qa_reporter_get_runner (GstQaReporter *reporter); +void gst_qa_reporter_init (GstQaReporter * reporter, const gchar *name); +void gst_qa_report (GstQaReporter * reporter, gboolean repeat, + GstQaReportLevel level, GstQaReportArea area, + gint subarea, const gchar * format, ...); +void gst_qa_report_valist (GstQaReporter * reporter, gboolean repeat, + GstQaReportLevel level, GstQaReportArea area, + gint subarea, const gchar * format, va_list var_args); + +G_END_DECLS +#endif /* _GST_QA_REPORTER_ */ + + +