mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 21:16:24 +00:00
validate: Add a way to print information about pipeline status
Similare to what is done with gst-launch. And finally generate GTypes for our flags and enums.
This commit is contained in:
parent
40eb48d21f
commit
b9d6f9df9e
12 changed files with 246 additions and 4 deletions
|
@ -64,6 +64,10 @@ static void
|
|||
_validate_bin_element_added (GstBin * bin, GstElement * pad,
|
||||
GstValidateBinMonitor * monitor);
|
||||
|
||||
static void
|
||||
_validate_bin_element_removed (GstBin * bin, GstElement * element,
|
||||
GstValidateBinMonitor * monitor);
|
||||
|
||||
static void
|
||||
gst_validate_bin_set_media_descriptor (GstValidateMonitor * monitor,
|
||||
GstValidateMediaDescriptor * media_descriptor)
|
||||
|
@ -138,6 +142,8 @@ gst_validate_bin_monitor_dispose (GObject * object)
|
|||
if (bin) {
|
||||
if (monitor->element_added_id)
|
||||
g_signal_handler_disconnect (bin, monitor->element_added_id);
|
||||
if (monitor->element_removed_id)
|
||||
g_signal_handler_disconnect (bin, monitor->element_removed_id);
|
||||
gst_object_unref (bin);
|
||||
}
|
||||
|
||||
|
@ -249,6 +255,10 @@ gst_validate_bin_monitor_setup (GstValidateMonitor * monitor)
|
|||
g_signal_connect (bin, "element-added",
|
||||
G_CALLBACK (_validate_bin_element_added), monitor);
|
||||
|
||||
bin_monitor->element_removed_id =
|
||||
g_signal_connect (bin, "element-removed",
|
||||
G_CALLBACK (_validate_bin_element_removed), monitor);
|
||||
|
||||
iterator = gst_bin_iterate_elements (bin);
|
||||
done = FALSE;
|
||||
while (!done) {
|
||||
|
@ -297,9 +307,18 @@ gst_validate_bin_monitor_wrap_element (GstValidateBinMonitor * monitor,
|
|||
GST_VALIDATE_ELEMENT_MONITOR_CAST (gst_validate_monitor_factory_create
|
||||
(GST_OBJECT_CAST (element), runner, GST_VALIDATE_MONITOR_CAST (monitor)));
|
||||
g_return_if_fail (element_monitor != NULL);
|
||||
|
||||
GST_VALIDATE_MONITOR_CAST (element_monitor)->verbosity =
|
||||
GST_VALIDATE_MONITOR_CAST (monitor)->verbosity;
|
||||
gst_validate_bin_child_added_overrides (GST_VALIDATE_MONITOR (monitor),
|
||||
element);
|
||||
|
||||
if (GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
|
||||
GST_VALIDATE_VERBOSITY_NEW_ELEMENTS)
|
||||
gst_validate_printf (NULL, "(element-added) %s added to %s\n",
|
||||
GST_ELEMENT_NAME (element),
|
||||
gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)));
|
||||
|
||||
GST_VALIDATE_MONITOR_LOCK (monitor);
|
||||
monitor->element_monitors = g_list_prepend (monitor->element_monitors,
|
||||
element_monitor);
|
||||
|
@ -320,3 +339,14 @@ _validate_bin_element_added (GstBin * bin, GstElement * element,
|
|||
gst_object_unref (target);
|
||||
gst_validate_bin_monitor_wrap_element (monitor, element);
|
||||
}
|
||||
|
||||
static void
|
||||
_validate_bin_element_removed (GstBin * bin, GstElement * element,
|
||||
GstValidateBinMonitor * monitor)
|
||||
{
|
||||
if (GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
|
||||
GST_VALIDATE_VERBOSITY_NEW_ELEMENTS)
|
||||
gst_validate_printf (NULL, "(element-removed) %s removed from %s\n",
|
||||
GST_ELEMENT_NAME (element),
|
||||
gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)));
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ struct _GstValidateBinMonitor {
|
|||
|
||||
/*< private >*/
|
||||
gulong element_added_id;
|
||||
gulong element_removed_id;
|
||||
gboolean stateless;
|
||||
};
|
||||
|
||||
|
|
40
validate/gst/validate/gst-validate-enum-types.c.template
Normal file
40
validate/gst/validate/gst-validate-enum-types.c.template
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*** BEGIN file-header ***/
|
||||
#include <gst/validate/validate.h>
|
||||
#define C_ENUM(v) ((gint) v)
|
||||
#define C_FLAGS(v) ((guint) v)
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type (void)
|
||||
{
|
||||
static gsize id = 0;
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ C_@TYPE@(@VALUENAME@), "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
if (g_once_init_enter (&id)) {
|
||||
GType tmp = g_@type@_register_static ("@EnumName@", values);
|
||||
g_once_init_leave (&id, tmp);
|
||||
}
|
||||
|
||||
return (GType) id;
|
||||
}
|
||||
|
||||
/*** END value-tail ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
|
||||
/*** END file-tail ***/
|
25
validate/gst/validate/gst-validate-enum-types.h.template
Normal file
25
validate/gst/validate/gst-validate-enum-types.h.template
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*** BEGIN file-header ***/
|
||||
#ifndef __GST_ENUM_TYPES_H__
|
||||
#define __GST_ENUM_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gst/validate/validate.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
|
||||
/* enumerations from "@basename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GST_EXPORT GType @enum_name@_get_type (void);
|
||||
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
|
@ -81,4 +81,19 @@ typedef enum {
|
|||
#define GST_VALIDATE_SHOW_DEFAULT GST_VALIDATE_SHOW_SMART
|
||||
#endif
|
||||
|
||||
/**
|
||||
* GstValidateVerbosityFlags:
|
||||
*
|
||||
* Defines the level of verbosity of -validate (ie, printing on stdout).
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_VALIDATE_VERBOSITY_NONE = 0,
|
||||
GST_VALIDATE_VERBOSITY_POSITION = 1 << 1,
|
||||
GST_VALIDATE_VERBOSITY_MESSAGES = 1 << 2,
|
||||
GST_VALIDATE_VERBOSITY_PROPS_CHANGES = 1 << 3,
|
||||
GST_VALIDATE_VERBOSITY_NEW_ELEMENTS = 1 << 4,
|
||||
GST_VALIDATE_VERBOSITY_ALL = GST_VALIDATE_VERBOSITY_POSITION | GST_VALIDATE_VERBOSITY_MESSAGES | GST_VALIDATE_VERBOSITY_PROPS_CHANGES | GST_VALIDATE_VERBOSITY_NEW_ELEMENTS
|
||||
} GstValidateVerbosityFlags;
|
||||
|
||||
#endif /* __GST_VALIDATE_RUNNER_H__ */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gst-validate-enum-types.h"
|
||||
#include "gst-validate-internal.h"
|
||||
#include "gst-validate-monitor.h"
|
||||
#include "gst-validate-override-registry.h"
|
||||
|
@ -43,6 +44,7 @@ enum
|
|||
PROP_PIPELINE,
|
||||
PROP_RUNNER,
|
||||
PROP_VALIDATE_PARENT,
|
||||
PROP_VERBOSITY,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
|
@ -175,6 +177,12 @@ gst_validate_monitor_class_init (GstValidateMonitorClass * klass)
|
|||
"The Validate monitor that is the parent of this one",
|
||||
GST_TYPE_VALIDATE_MONITOR,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_VERBOSITY,
|
||||
g_param_spec_flags ("verbosity", "Verbosity",
|
||||
"The verbosity of GstValidate on the monitor",
|
||||
GST_TYPE_VALIDATE_VERBOSITY_FLAGS,
|
||||
GST_VALIDATE_VERBOSITY_POSITION, G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static GObject *
|
||||
|
@ -219,6 +227,8 @@ gst_validate_monitor_init (GstValidateMonitor * monitor)
|
|||
|
||||
g_mutex_init (&monitor->overrides_mutex);
|
||||
g_queue_init (&monitor->overrides);
|
||||
|
||||
monitor->verbosity = GST_VALIDATE_VERBOSITY_POSITION;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -288,8 +298,20 @@ _determine_reporting_level (GstValidateMonitor * monitor)
|
|||
gboolean
|
||||
gst_validate_monitor_setup (GstValidateMonitor * monitor)
|
||||
{
|
||||
GList *config;
|
||||
|
||||
GST_DEBUG_OBJECT (monitor, "Starting monitor setup");
|
||||
|
||||
for (config = gst_validate_plugin_get_config (NULL); config;
|
||||
config = config->next) {
|
||||
const gchar *verbosity =
|
||||
gst_structure_get_string (GST_STRUCTURE (config->data),
|
||||
"verbosity");
|
||||
|
||||
if (verbosity)
|
||||
gst_util_set_object_arg (G_OBJECT (monitor), "verbosity", verbosity);
|
||||
}
|
||||
|
||||
/* For now we just need to do this at setup time */
|
||||
_determine_reporting_level (monitor);
|
||||
return GST_VALIDATE_MONITOR_GET_CLASS (monitor)->setup (monitor);
|
||||
|
@ -412,6 +434,9 @@ gst_validate_monitor_set_property (GObject * object, guint prop_id,
|
|||
case PROP_VALIDATE_PARENT:
|
||||
monitor->parent = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_VERBOSITY:
|
||||
monitor->verbosity = g_value_get_flags (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -440,6 +465,9 @@ gst_validate_monitor_get_property (GObject * object, guint prop_id,
|
|||
case PROP_VALIDATE_PARENT:
|
||||
g_value_set_object (value, GST_VALIDATE_MONITOR_GET_PARENT (monitor));
|
||||
break;
|
||||
case PROP_VERBOSITY:
|
||||
g_value_set_flags (value, monitor->verbosity);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
@ -96,6 +96,8 @@ struct _GstValidateMonitor {
|
|||
|
||||
/*< private >*/
|
||||
GHashTable *reports;
|
||||
|
||||
GstValidateVerbosityFlags verbosity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -108,6 +108,10 @@ print_position (GstValidateMonitor * monitor)
|
|||
gdouble rate = 1.0;
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
|
||||
if (!(GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
|
||||
GST_VALIDATE_VERBOSITY_POSITION))
|
||||
goto done;
|
||||
|
||||
if (!gst_element_query_position (pipeline, format, &position)) {
|
||||
GST_DEBUG_OBJECT (monitor, "Could not query position");
|
||||
|
||||
|
@ -481,6 +485,46 @@ _bus_handler (GstBus * bus, GstMessage * message,
|
|||
const GstStructure *details = NULL;
|
||||
gint error_flow = GST_FLOW_OK;
|
||||
|
||||
if (GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
|
||||
GST_VALIDATE_VERBOSITY_MESSAGES
|
||||
&& GST_MESSAGE_TYPE (message) != GST_MESSAGE_PROPERTY_NOTIFY) {
|
||||
GstObject *src_obj;
|
||||
const GstStructure *s;
|
||||
guint32 seqnum;
|
||||
GString *str = g_string_new (NULL);
|
||||
|
||||
seqnum = gst_message_get_seqnum (message);
|
||||
s = gst_message_get_structure (message);
|
||||
src_obj = GST_MESSAGE_SRC (message);
|
||||
|
||||
if (GST_IS_ELEMENT (src_obj)) {
|
||||
g_string_append_printf (str, "Got message #%u from element \"%s\" (%s): ",
|
||||
(guint) seqnum, GST_ELEMENT_NAME (src_obj),
|
||||
GST_MESSAGE_TYPE_NAME (message));
|
||||
} else if (GST_IS_PAD (src_obj)) {
|
||||
g_string_append_printf (str, "Got message #%u from pad \"%s:%s\" (%s): ",
|
||||
(guint) seqnum, GST_DEBUG_PAD_NAME (src_obj),
|
||||
GST_MESSAGE_TYPE_NAME (message));
|
||||
} else if (GST_IS_OBJECT (src_obj)) {
|
||||
g_string_append_printf (str, "Got message #%u from object \"%s\" (%s): ",
|
||||
(guint) seqnum, GST_OBJECT_NAME (src_obj),
|
||||
GST_MESSAGE_TYPE_NAME (message));
|
||||
} else {
|
||||
g_string_append_printf (str, "Got message #%u (%s): ", (guint) seqnum,
|
||||
GST_MESSAGE_TYPE_NAME (message));
|
||||
}
|
||||
if (s) {
|
||||
gchar *sstr;
|
||||
|
||||
sstr = gst_structure_to_string (s);
|
||||
g_string_append_printf (str, "%s\n", sstr);
|
||||
g_free (sstr);
|
||||
} else {
|
||||
g_string_append (str, "no message details\n");
|
||||
}
|
||||
gst_validate_printf (NULL, str->str);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
switch (GST_MESSAGE_TYPE (message)) {
|
||||
case GST_MESSAGE_ERROR:
|
||||
gst_message_parse_error (message, &err, &debug);
|
||||
|
@ -616,6 +660,43 @@ _bus_handler (GstBus * bus, GstMessage * message,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case GST_MESSAGE_PROPERTY_NOTIFY:
|
||||
{
|
||||
const GValue *val;
|
||||
const gchar *name;
|
||||
GstObject *obj;
|
||||
gchar *val_str = NULL;
|
||||
gchar *obj_name;
|
||||
|
||||
if (!(GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
|
||||
GST_VALIDATE_VERBOSITY_PROPS_CHANGES))
|
||||
return;
|
||||
|
||||
gst_message_parse_property_notify (message, &obj, &name, &val);
|
||||
|
||||
obj_name = gst_object_get_path_string (GST_OBJECT (obj));
|
||||
if (val != NULL) {
|
||||
if (G_VALUE_HOLDS_STRING (val))
|
||||
val_str = g_value_dup_string (val);
|
||||
else if (G_VALUE_TYPE (val) == GST_TYPE_CAPS)
|
||||
val_str = gst_caps_to_string (g_value_get_boxed (val));
|
||||
else if (G_VALUE_TYPE (val) == GST_TYPE_TAG_LIST)
|
||||
val_str = gst_tag_list_to_string (g_value_get_boxed (val));
|
||||
else if (G_VALUE_TYPE (val) == GST_TYPE_STRUCTURE)
|
||||
val_str = gst_structure_to_string (g_value_get_boxed (val));
|
||||
else
|
||||
val_str = gst_value_serialize (val);
|
||||
} else {
|
||||
val_str = g_strdup ("(no value)");
|
||||
}
|
||||
|
||||
gst_validate_printf (NULL, "%s: %s = %s\n", obj_name, name, val_str);
|
||||
g_free (obj_name);
|
||||
g_free (val_str);
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -694,6 +775,10 @@ gst_validate_pipeline_monitor_new (GstPipeline * pipeline,
|
|||
gst_bus_enable_sync_message_emission (bus);
|
||||
g_signal_connect (bus, "sync-message", (GCallback) _bus_handler, monitor);
|
||||
|
||||
monitor->deep_notify_id =
|
||||
gst_element_add_property_deep_notify_watch ((GstElement *) pipeline, NULL,
|
||||
TRUE);
|
||||
|
||||
gst_object_unref (bus);
|
||||
|
||||
if (g_strcmp0 (G_OBJECT_TYPE_NAME (pipeline), "GstPlayBin") == 0)
|
||||
|
|
|
@ -68,6 +68,8 @@ struct _GstValidatePipelineMonitor {
|
|||
GstStreamCollection *stream_collection;
|
||||
/* Latest GstStream received from GST_MESSAGE_STREAMS_SELECTED */
|
||||
GList *streams_selected;
|
||||
|
||||
gulong deep_notify_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,8 +44,15 @@ gstvalidate_headers = [
|
|||
|
||||
install_headers(gstvalidate_headers, subdir : 'gstreamer-1.0/gst/validate')
|
||||
|
||||
gst_validate_enums = gnome.mkenums('gstvalidateenumtypes',
|
||||
sources : gstvalidate_headers,
|
||||
h_template : 'gst-validate-enum-types.h.template',
|
||||
c_template : 'gst-validate-enum-types.c.template',
|
||||
install_header : true,
|
||||
install_dir : join_paths(get_option('includedir'), 'gstreamer-1.0/gst/validate'))
|
||||
|
||||
gstvalidate = shared_library('gstvalidate-1.0',
|
||||
sources: gstvalidate_sources,
|
||||
sources: gstvalidate_sources + gst_validate_enums,
|
||||
version : libversion,
|
||||
soversion : soversion,
|
||||
include_directories : [inc_dirs],
|
||||
|
@ -56,7 +63,7 @@ gstvalidate = shared_library('gstvalidate-1.0',
|
|||
gst_pbutils_dep, mathlib, json_dep])
|
||||
|
||||
gstvalidatetracer = shared_library('gstvalidatetracer',
|
||||
sources: gstvalidate_sources,
|
||||
sources: gstvalidate_sources + gst_validate_enums,
|
||||
include_directories : [inc_dirs],
|
||||
install: true,
|
||||
c_args : [gst_c_args] + ['-D__GST_VALIDATE_PLUGIN', '-D_GNU_SOURCE'],
|
||||
|
@ -76,7 +83,7 @@ if build_gir
|
|||
'--cflags-end']
|
||||
endif
|
||||
validate_gen_sources = [gnome.generate_gir(gstvalidate,
|
||||
sources : gstvalidate_sources + gstvalidate_headers,
|
||||
sources : gstvalidate_sources + gstvalidate_headers + gst_validate_enums,
|
||||
nsversion : '1.0',
|
||||
namespace : 'GstValidate',
|
||||
symbol_prefix : 'gst_validate',
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <gst/validate/gst-validate-types.h>
|
||||
#include <gst/validate/gst-validate-enums.h>
|
||||
#include <gst/validate/gst-validate-scenario.h>
|
||||
|
||||
#include <gst/validate/gst-validate-runner.h>
|
||||
#include <gst/validate/gst-validate-monitor-factory.h>
|
||||
|
|
|
@ -305,7 +305,8 @@ int
|
|||
main (int argc, gchar ** argv)
|
||||
{
|
||||
GError *err = NULL;
|
||||
gchar *scenario = NULL, *configs = NULL, *media_info = NULL;
|
||||
gchar *scenario = NULL, *configs = NULL, *media_info = NULL,
|
||||
*verbosity = NULL;
|
||||
gboolean list_scenarios = FALSE, monitor_handles_state,
|
||||
inspect_action_type = FALSE;
|
||||
GstStateChangeReturn sret;
|
||||
|
@ -324,6 +325,9 @@ main (int argc, gchar ** argv)
|
|||
" '.scenario' extension).", NULL},
|
||||
{"list-scenarios", 'l', 0, G_OPTION_ARG_NONE, &list_scenarios,
|
||||
"List the available scenarios that can be run", NULL},
|
||||
{"verbosity", 'v', 0, G_OPTION_ARG_STRING, &verbosity,
|
||||
"Set overall verbosity as defined by GstValidateVerbosityFlags"
|
||||
" as a string", NULL},
|
||||
{"scenarios-defs-output-file", '\0', 0, G_OPTION_ARG_FILENAME,
|
||||
&output_file, "The output file to store scenarios details. "
|
||||
"Implies --list-scenarios",
|
||||
|
@ -453,6 +457,8 @@ main (int argc, gchar ** argv)
|
|||
|
||||
monitor = gst_validate_monitor_factory_create (GST_OBJECT_CAST (pipeline),
|
||||
runner, NULL);
|
||||
if (verbosity)
|
||||
gst_util_set_object_arg (G_OBJECT (monitor), "verbosity", verbosity);
|
||||
gst_validate_reporter_set_handle_g_logs (GST_VALIDATE_REPORTER (monitor));
|
||||
|
||||
if (media_info) {
|
||||
|
|
Loading…
Reference in a new issue