qa-report: adds qa-report for reporting errors to GstQaRunner

The errors are printed directly to stdout and are accumulated at
GstQaRunner for being printed at the end if requested
This commit is contained in:
Thiago Santos 2013-07-12 02:10:06 -03:00
parent 5250ed4331
commit 3476fffd54
9 changed files with 220 additions and 9 deletions

View 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 =

View 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);
}
}

View 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__ */

View 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;

View file

@ -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));
}

View file

@ -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__ */

View 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);
}
}

View 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__ */

View 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;
}