diff --git a/tools/gst-device-monitor.c b/tools/gst-device-monitor.c index 43a127f184..3005343c4f 100644 --- a/tools/gst-device-monitor.c +++ b/tools/gst-device-monitor.c @@ -42,6 +42,99 @@ typedef struct static gboolean bus_msg_handler (GstBus * bus, GstMessage * msg, gpointer data); +static gchar * +get_launch_line (GstDevice * device) +{ + static const char *const ignored_propnames[] = + { "name", "parent", "direction", "template", "caps", NULL }; + GString *launch_line; + GstElement *element; + GstElement *pureelement; + GParamSpec **properties, *property; + GValue value = G_VALUE_INIT; + GValue pvalue = G_VALUE_INIT; + guint i, number_of_properties; + GstElementFactory *factory; + + element = gst_device_create_element (device, NULL); + + if (!element) + return NULL; + + factory = gst_element_get_factory (element); + if (!factory) { + gst_object_unref (element); + return NULL; + } + + if (!gst_plugin_feature_get_name (factory)) { + gst_object_unref (element); + return NULL; + } + + launch_line = g_string_new (gst_plugin_feature_get_name (factory)); + + pureelement = gst_element_factory_create (factory, NULL); + + /* get paramspecs and show non-default properties */ + properties = + g_object_class_list_properties (G_OBJECT_GET_CLASS (element), + &number_of_properties); + if (properties) { + for (i = 0; i < number_of_properties; i++) { + gint j; + gboolean ignore = FALSE; + property = properties[i]; + + /* skip some properties */ + if ((property->flags & G_PARAM_READWRITE) != G_PARAM_READWRITE) + continue; + + for (j = 0; ignored_propnames[j]; j++) + if (!g_strcmp0 (ignored_propnames[j], property->name)) + ignore = TRUE; + + if (ignore) + continue; + + /* Can't use _param_value_defaults () because sub-classes modify the + * values already. + */ + + g_value_init (&value, property->value_type); + g_value_init (&pvalue, property->value_type); + g_object_get_property (G_OBJECT (element), property->name, &value); + g_object_get_property (G_OBJECT (pureelement), property->name, &pvalue); + if (gst_value_compare (&value, &pvalue) != GST_VALUE_EQUAL) { + gchar *valuestr = gst_value_serialize (&value); + + if (!valuestr) { + GST_WARNING ("Could not serialize property %s:%s", + GST_OBJECT_NAME (element), property->name); + g_free (valuestr); + goto next; + } + + g_string_append_printf (launch_line, " %s=%s", + property->name, valuestr); + g_free (valuestr); + + } + + next: + g_value_unset (&value); + g_value_unset (&pvalue); + } + g_free (properties); + } + + gst_object_unref (element); + gst_object_unref (pureelement); + + return g_string_free (launch_line, FALSE); +} + + static gboolean print_structure_field (GQuark field_id, const GValue * value, gpointer user_data) @@ -97,6 +190,12 @@ device_added (GstDevice * device) gst_structure_free (props); g_print ("\n"); } + str = get_launch_line (device); + if (gst_device_has_classes (device, "Source")) + g_print ("\tgst-launch-1.0 %s ! ...\n", str); + if (gst_device_has_classes (device, "Sink")) + g_print ("\tgst-launch-1.0 ... ! %s\n", str); + g_free (str); g_print ("\n"); g_free (name);