qa-report: rework qa-report API

Remove error from GstQaErrorReport, making it only GstQaReport. Add
 a level and use area and subarea code, with an extra string for message
 adding details.

Provide macros on qa-monitor to make it easy to create reports.
This commit is contained in:
Thiago Santos 2013-07-16 21:15:09 -03:00
parent d1fde6f4cf
commit 4e84ad6513
8 changed files with 220 additions and 71 deletions

View file

@ -203,22 +203,22 @@ gst_qa_monitor_get_property (GObject * object, guint prop_id,
} }
void void
gst_qa_monitor_post_error (GstQaMonitor * monitor, GstQaErrorArea area, gst_qa_monitor_do_report (GstQaMonitor * monitor,
const gchar * message, const gchar * detail) GstQaReportLevel level, GstQaReportArea area,
gint subarea, const gchar * message)
{ {
GstQaErrorReport *report; GstQaReport *report;
report = report =
gst_qa_error_report_new (GST_OBJECT_CAST (GST_QA_MONITOR_GET_OBJECT gst_qa_report_new (GST_OBJECT_CAST (GST_QA_MONITOR_GET_OBJECT
(monitor)), area, message, detail); (monitor)), level, area, subarea, message);
GST_WARNING_OBJECT (monitor, "Received error report %d : %s : %s", GST_INFO_OBJECT (monitor, "Received error report %d : %d : %d : %s",
area, message, detail); level, area, subarea, message);
gst_qa_error_report_printf (report); gst_qa_report_printf (report);
if (GST_QA_MONITOR_GET_RUNNER (monitor)) { if (GST_QA_MONITOR_GET_RUNNER (monitor)) {
gst_qa_runner_add_error_report (GST_QA_MONITOR_GET_RUNNER (monitor), gst_qa_runner_add_report (GST_QA_MONITOR_GET_RUNNER (monitor), report);
report);
} else { } else {
gst_qa_error_report_free (report); gst_qa_report_free (report);
} }
} }

View file

@ -44,6 +44,34 @@ G_BEGIN_DECLS
#define GST_QA_MONITOR_LOCK(m) (g_mutex_lock (&GST_QA_MONITOR_CAST(m)->mutex)) #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)) #define GST_QA_MONITOR_UNLOCK(m) (g_mutex_unlock (&GST_QA_MONITOR_CAST(m)->mutex))
#define GST_QA_MONITOR_REPORT(m, status, area, subarea, detail) \
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, detail); \
} G_STMT_END
#define GST_QA_MONITOR_REPORT_CRITICAL(m, area, subarea, detail) \
G_STMT_START { \
GST_ERROR_OBJECT (m, "Critical report: %s: %s: %s", \
"## area", "subarea ##", detail); \
GST_QA_MONITOR_REPORT(m, CRITICAL, area, subarea, detail); \
} G_STMT_END
#define GST_QA_MONITOR_REPORT_WARNING(m, area, subarea, detail) \
G_STMT_START { \
GST_WARNING_OBJECT (m, "Warning report: %s: %s: %s", \
"## area ##", "## subarea ##", detail); \
GST_QA_MONITOR_REPORT(m, WARNING, area, subarea, detail); \
} G_STMT_END
#define GST_QA_MONITOR_REPORT_ISSUE(m, area, subarea, detail) \
G_STMT_START { \
GST_WARNING_OBJECT (m, "Issue report: %s: %s: %s", \
"## area ##", "## subarea ##", detail); \
GST_QA_MONITOR_REPORT(m, ISSUE, area, subarea, detail); \
} G_STMT_END
typedef struct _GstQaMonitor GstQaMonitor; typedef struct _GstQaMonitor GstQaMonitor;
typedef struct _GstQaMonitorClass GstQaMonitorClass; typedef struct _GstQaMonitorClass GstQaMonitorClass;
@ -82,7 +110,8 @@ struct _GstQaMonitorClass {
/* normal GObject stuff */ /* normal GObject stuff */
GType gst_qa_monitor_get_type (void); GType gst_qa_monitor_get_type (void);
void gst_qa_monitor_post_error (GstQaMonitor * monitor, GstQaErrorArea area, const gchar * message, const gchar * detail); void gst_qa_monitor_do_report (GstQaMonitor * monitor, GstQaReportLevel level, GstQaReportArea area,
gint subarea, const gchar * detail);
G_END_DECLS G_END_DECLS

View file

@ -160,17 +160,15 @@ gst_qa_pad_monitor_sink_event_check (GstQaPadMonitor * pad_monitor,
if (seqnum == pad_monitor->pending_flush_start_seqnum) { if (seqnum == pad_monitor->pending_flush_start_seqnum) {
pad_monitor->pending_flush_start_seqnum = 0; pad_monitor->pending_flush_start_seqnum = 0;
} else { } else {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, SEQNUM,
GST_QA_ERROR_AREA_EVENT, "Wrong flush-start seqnum",
"The expected flush-start seqnum should be the same as the " "The expected flush-start seqnum should be the same as the "
"one from the event that caused it (probably a seek)"); "one from the event that caused it (probably a seek)");
} }
} }
if (pad_monitor->pending_flush_stop) { if (pad_monitor->pending_flush_stop) {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, UNEXPECTED,
GST_QA_ERROR_AREA_EVENT, "Received flush-start when flush-stop was " "Received flush-start when flush-stop was expected");
"expected", NULL);
} }
} }
break; break;
@ -180,16 +178,15 @@ gst_qa_pad_monitor_sink_event_check (GstQaPadMonitor * pad_monitor,
if (seqnum == pad_monitor->pending_flush_stop_seqnum) { if (seqnum == pad_monitor->pending_flush_stop_seqnum) {
pad_monitor->pending_flush_stop_seqnum = 0; pad_monitor->pending_flush_stop_seqnum = 0;
} else { } else {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, SEQNUM,
GST_QA_ERROR_AREA_EVENT, "Wrong flush-stop seqnum",
"The expected flush-stop seqnum should be the same as the " "The expected flush-stop seqnum should be the same as the "
"one from the event that caused it (probably a seek)"); "one from the event that caused it (probably a seek)");
} }
} }
if (!pad_monitor->pending_flush_stop) { if (!pad_monitor->pending_flush_stop) {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, UNEXPECTED,
GST_QA_ERROR_AREA_EVENT, "Unexpected flush-stop", NULL); "Unexpected flush-stop");
} }
} }
break; break;
@ -276,17 +273,15 @@ gst_qa_pad_monitor_src_event_check (GstQaPadMonitor * pad_monitor,
if (seqnum == pad_monitor->pending_flush_start_seqnum) { if (seqnum == pad_monitor->pending_flush_start_seqnum) {
pad_monitor->pending_flush_start_seqnum = 0; pad_monitor->pending_flush_start_seqnum = 0;
} else { } else {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, SEQNUM,
GST_QA_ERROR_AREA_EVENT, "Wrong flush-start seqnum",
"The expected flush-start seqnum should be the same as the " "The expected flush-start seqnum should be the same as the "
"one from the event that caused it (probably a seek)"); "one from the event that caused it (probably a seek)");
} }
} }
if (pad_monitor->pending_flush_stop) { if (pad_monitor->pending_flush_stop) {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, UNEXPECTED,
GST_QA_ERROR_AREA_EVENT, "Received flush-start when flush-stop was " "Received flush-start when flush-stop was expected");
"expected", NULL);
} }
} }
break; break;
@ -296,16 +291,15 @@ gst_qa_pad_monitor_src_event_check (GstQaPadMonitor * pad_monitor,
if (seqnum == pad_monitor->pending_flush_stop_seqnum) { if (seqnum == pad_monitor->pending_flush_stop_seqnum) {
pad_monitor->pending_flush_stop_seqnum = 0; pad_monitor->pending_flush_stop_seqnum = 0;
} else { } else {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, SEQNUM,
GST_QA_ERROR_AREA_EVENT, "Wrong flush-stop seqnum",
"The expected flush-stop seqnum should be the same as the " "The expected flush-stop seqnum should be the same as the "
"one from the event that caused it (probably a seek)"); "one from the event that caused it (probably a seek)");
} }
} }
if (!pad_monitor->pending_flush_stop) { if (!pad_monitor->pending_flush_stop) {
gst_qa_monitor_post_error (GST_QA_MONITOR_CAST (pad_monitor), GST_QA_MONITOR_REPORT_ISSUE (pad_monitor, EVENT, UNEXPECTED,
GST_QA_ERROR_AREA_EVENT, "Unexpected flush-stop", NULL); "Unexpected flush-stop");
} }
} }
break; break;

View file

@ -32,17 +32,36 @@ gst_qa_report_init (void)
_gst_qa_report_start_time = gst_util_get_timestamp (); _gst_qa_report_start_time = gst_util_get_timestamp ();
} }
/* TODO how are these functions going to work with extensions */
const gchar * const gchar *
gst_qa_error_area_get_name (GstQaErrorArea area) gst_qa_report_level_get_name (GstQaReportLevel level)
{
switch (level) {
case GST_QA_REPORT_LEVEL_CRITICAL:
return "critical";
case GST_QA_REPORT_LEVEL_WARNING:
return "warning";
case GST_QA_REPORT_LEVEL_ISSUE:
return "issue";
default:
return "unknown";
}
}
const gchar *
gst_qa_report_area_get_name (GstQaReportArea area)
{ {
switch (area) { switch (area) {
case GST_QA_ERROR_AREA_EVENT: case GST_QA_AREA_EVENT:
return "event"; return "event";
case GST_QA_ERROR_AREA_BUFFER: case GST_QA_AREA_BUFFER:
return "buffer"; return "buffer";
case GST_QA_ERROR_AREA_QUERY: case GST_QA_AREA_QUERY:
return "query"; return "query";
case GST_QA_ERROR_AREA_OTHER: case GST_QA_AREA_CAPS_NEGOTIATION:
return "caps";
case GST_QA_AREA_OTHER:
return "other"; return "other";
default: default:
g_assert_not_reached (); g_assert_not_reached ();
@ -50,32 +69,105 @@ gst_qa_error_area_get_name (GstQaErrorArea area)
} }
} }
GstQaErrorReport * const gchar *
gst_qa_error_report_new (GstObject * source, GstQaErrorArea area, gst_qa_area_event_get_subarea_name (GstQaReportAreaEvent subarea)
const gchar * message, const gchar * detail)
{ {
GstQaErrorReport *report = g_slice_new0 (GstQaErrorReport); switch (subarea) {
case GST_QA_AREA_EVENT_SEQNUM:
return "seqnum";
case GST_QA_AREA_EVENT_UNEXPECTED:
return "unexpected";
case GST_QA_AREA_EVENT_EXPECTED:
return "expected";
default:
return "unknown";
}
}
report->source = g_object_ref (source); const gchar *
gst_qa_area_buffer_get_subarea_name (GstQaReportAreaEvent subarea)
{
switch (subarea) {
case GST_QA_AREA_BUFFER_TIMESTAMP:
return "timestamp";
case GST_QA_AREA_BUFFER_DURATION:
return "duration";
case GST_QA_AREA_BUFFER_FLAGS:
return "flags";
case GST_QA_AREA_BUFFER_UNEXPECTED:
return "unexpected";
default:
return "unknown";
}
}
const gchar *
gst_qa_area_query_get_subarea_name (GstQaReportAreaEvent subarea)
{
switch (subarea) {
case GST_QA_AREA_QUERY_UNEXPECTED:
return "unexpected";
default:
return "unknown";
}
}
const gchar *
gst_qa_area_caps_get_subarea_name (GstQaReportAreaEvent subarea)
{
switch (subarea) {
case GST_QA_AREA_CAPS_NEGOTIATION:
return "negotiation";
default:
return "unknown";
}
}
const gchar *
gst_qa_report_subarea_get_name (GstQaReportArea area, gint subarea)
{
switch (area) {
case GST_QA_AREA_EVENT:
return gst_qa_area_event_get_subarea_name (subarea);
case GST_QA_AREA_BUFFER:
return gst_qa_area_buffer_get_subarea_name (subarea);
case GST_QA_AREA_QUERY:
return gst_qa_area_query_get_subarea_name (subarea);
case GST_QA_AREA_CAPS_NEGOTIATION:
return gst_qa_area_caps_get_subarea_name (subarea);
default:
g_assert_not_reached ();
case GST_QA_AREA_OTHER:
return "unknown";
}
}
GstQaReport *
gst_qa_report_new (GstObject * source, GstQaReportLevel level,
GstQaReportArea area, gint subarea, const gchar * message)
{
GstQaReport *report = g_slice_new0 (GstQaReport);
report->level = level;
report->area = area; report->area = area;
report->subarea = subarea;
report->source = g_object_ref (source);
report->message = g_strdup (message); report->message = g_strdup (message);
report->detail = g_strdup (detail);
report->timestamp = gst_util_get_timestamp () - _gst_qa_report_start_time; report->timestamp = gst_util_get_timestamp () - _gst_qa_report_start_time;
return report; return report;
} }
void void
gst_qa_error_report_free (GstQaErrorReport * report) gst_qa_report_free (GstQaReport * report)
{ {
g_free (report->message); g_free (report->message);
g_free (report->detail);
g_object_unref (report->source); g_object_unref (report->source);
g_slice_free (GstQaErrorReport, report); g_slice_free (GstQaReport, report);
} }
void void
gst_qa_error_report_printf (GstQaErrorReport * report) gst_qa_report_printf (GstQaReport * report)
{ {
g_print ("%" GST_QA_ERROR_REPORT_PRINT_FORMAT "\n", g_print ("%" GST_QA_ERROR_REPORT_PRINT_FORMAT "\n",
GST_QA_REPORT_PRINT_ARGS (report)); GST_QA_REPORT_PRINT_ARGS (report));

View file

@ -28,32 +28,67 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum { typedef enum {
GST_QA_ERROR_AREA_EVENT=0, GST_QA_REPORT_LEVEL_CRITICAL,
GST_QA_ERROR_AREA_BUFFER, GST_QA_REPORT_LEVEL_WARNING,
GST_QA_ERROR_AREA_QUERY, GST_QA_REPORT_LEVEL_ISSUE,
GST_QA_ERROR_AREA_OTHER=100, GST_QA_REPORT_LEVEL_NUM_ENTRIES,
} GstQaErrorArea; } GstQaReportLevel;
typedef enum {
GST_QA_AREA_EVENT=0,
GST_QA_AREA_BUFFER,
GST_QA_AREA_QUERY,
GST_QA_AREA_CAPS_NEGOTIATION,
GST_QA_AREA_OTHER=100,
} GstQaReportArea;
typedef enum {
GST_QA_AREA_EVENT_SEQNUM,
GST_QA_AREA_EVENT_UNEXPECTED,
GST_QA_AREA_EVENT_EXPECTED,
GST_QA_AREA_EVENT_NUM_ENTRIES
} GstQaReportAreaEvent;
typedef enum {
GST_QA_AREA_BUFFER_TIMESTAMP,
GST_QA_AREA_BUFFER_DURATION,
GST_QA_AREA_BUFFER_FLAGS,
GST_QA_AREA_BUFFER_UNEXPECTED,
GST_QA_AREA_BUFFER_NUM_ENTRIES
} GstQaReportAreaBuffer;
typedef enum {
GST_QA_AREA_QUERY_UNEXPECTED,
GST_QA_AREA_QUERY_NUM_ENTRIES
} GstQaReportAreaQuery;
typedef struct { typedef struct {
GstQaErrorArea area; GstQaReportLevel level;
GstQaReportArea area;
gint subarea;
gchar *message; gchar *message;
gchar *detail;
GstObject *source; GstObject *source;
guint64 timestamp; guint64 timestamp;
} GstQaErrorReport; } GstQaReport;
#define GST_QA_ERROR_REPORT_PRINT_FORMAT GST_TIME_FORMAT ": %s, %s(%d)) %s (%s)" #define GST_QA_ERROR_REPORT_PRINT_FORMAT GST_TIME_FORMAT " (%s): %s, %s(%d)) %s(%d): %s"
#define GST_QA_REPORT_PRINT_ARGS(r) GST_TIME_ARGS (r->timestamp), \ #define GST_QA_REPORT_PRINT_ARGS(r) GST_TIME_ARGS (r->timestamp), \
gst_qa_report_level_get_name (r->level), \
r->source ? GST_OBJECT_NAME(r->source) : "null", \ r->source ? GST_OBJECT_NAME(r->source) : "null", \
gst_qa_error_area_get_name(r->area), r->area, \ gst_qa_report_area_get_name(r->area), r->area, \
r->message, r->detail gst_qa_report_subarea_get_name(r->area, r->subarea), r->subarea, \
r->message
void gst_qa_report_init (void); void gst_qa_report_init (void);
GstQaErrorReport * gst_qa_error_report_new (GstObject * source, GstQaErrorArea area, const gchar * message, const gchar * detail); GstQaReport * gst_qa_report_new (GstObject * source, GstQaReportLevel level, GstQaReportArea area,
void gst_qa_error_report_free (GstQaErrorReport * report); gint subarea, const gchar * message);
void gst_qa_report_free (GstQaReport * report);
void gst_qa_error_report_printf (GstQaErrorReport * report); void gst_qa_report_printf (GstQaReport * report);
G_END_DECLS G_END_DECLS

View file

@ -44,8 +44,7 @@ gst_qa_runner_dispose (GObject * object)
if (runner->pipeline) if (runner->pipeline)
gst_object_unref (runner->pipeline); gst_object_unref (runner->pipeline);
g_slist_free_full (runner->error_reports, g_slist_free_full (runner->reports, (GDestroyNotify) gst_qa_report_free);
(GDestroyNotify) gst_qa_error_report_free);
if (runner->monitor) if (runner->monitor)
g_object_unref (runner->monitor); g_object_unref (runner->monitor);
@ -107,19 +106,19 @@ gst_qa_runner_setup (GstQaRunner * runner)
} }
void void
gst_qa_runner_add_error_report (GstQaRunner * runner, GstQaErrorReport * report) gst_qa_runner_add_report (GstQaRunner * runner, GstQaReport * report)
{ {
runner->error_reports = g_slist_prepend (runner->error_reports, report); runner->reports = g_slist_prepend (runner->reports, report);
} }
void void
gst_qa_runner_print_error_reports (GstQaRunner * runner) gst_qa_runner_print_reports (GstQaRunner * runner)
{ {
GSList *iter; GSList *iter;
for (iter = runner->error_reports; iter; iter = g_slist_next (iter)) { for (iter = runner->reports; iter; iter = g_slist_next (iter)) {
GstQaErrorReport *report = iter->data; GstQaReport *report = iter->data;
gst_qa_error_report_printf (report); gst_qa_report_printf (report);
} }
} }

View file

@ -61,7 +61,7 @@ struct _GstQaRunner {
GstElement *pipeline; GstElement *pipeline;
GstQaElementMonitor *monitor; GstQaElementMonitor *monitor;
GSList *error_reports; GSList *reports;
}; };
/** /**
@ -80,8 +80,8 @@ GType gst_qa_runner_get_type (void);
GstQaRunner * gst_qa_runner_new (GstElement * pipeline); GstQaRunner * gst_qa_runner_new (GstElement * pipeline);
gboolean gst_qa_runner_setup (GstQaRunner * runner); gboolean gst_qa_runner_setup (GstQaRunner * runner);
void gst_qa_runner_add_error_report (GstQaRunner * runner, GstQaErrorReport * report); void gst_qa_runner_add_report (GstQaRunner * runner, GstQaReport * report);
void gst_qa_runner_print_error_reports (GstQaRunner * runner); void gst_qa_runner_print_reports (GstQaRunner * runner);
G_END_DECLS G_END_DECLS

View file

@ -114,7 +114,7 @@ main (int argc, gchar ** argv)
g_main_loop_run (mainloop); g_main_loop_run (mainloop);
g_print ("Pipeline finished, printing issues found: \n"); g_print ("Pipeline finished, printing issues found: \n");
gst_qa_runner_print_error_reports (runner); gst_qa_runner_print_reports (runner);
exit: exit:
gst_element_set_state (pipeline, GST_STATE_NULL); gst_element_set_state (pipeline, GST_STATE_NULL);