# include <sys/wait.h>
#endif
+#ifdef G_OS_WIN32
+/* _isatty() */
+#include <io.h>
+#endif
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
/* "R" : support color
* "X" : do not clear the screen when leaving the pager
#define FEATURE_RANK_COLOR (colored_output? CYAN : "")
#define FEATURE_PROTO_COLOR (colored_output? BRYELLOW : "")
+#define GST_DOC_BASE_URL "https://gstreamer.freedesktop.org/documentation"
+
+static const gchar *gstreamer_modules[] = {
+ "gstreamer", "gst-plugins-base", "gst-plugins-good", "gst-plugins-ugly",
+ "gst-plugins-bad", "gst-editing-services", "gst-libav", "gst-rtsp-server",
+ "gstreamer-vaapi", NULL
+};
+
static char *_name = NULL;
static int indent = 0;
}
static void
-print_factory_details_info (GstElementFactory * factory)
+print_factory_details_info (GstElementFactory * factory, GstPlugin * plugin)
{
gchar **keys, **k;
+ gboolean seen_doc_uri = FALSE;
GstRank rank;
char s[40];
key[0] = g_ascii_toupper (key[0]);
n_print ("%s%-25s%s%s%s\n", PROP_NAME_COLOR, key, PROP_VALUE_COLOR, val,
RESET_COLOR);
+ seen_doc_uri =
+ seen_doc_uri || g_str_equal (key, GST_ELEMENT_METADATA_DOC_URI);
}
g_strfreev (keys);
}
+
+ if (!seen_doc_uri && plugin != NULL &&
+ !gst_element_factory_get_skip_documentation (factory)) {
+ const gchar *module = gst_plugin_get_source (plugin);
+ const gchar *origin = gst_plugin_get_origin (plugin);
+
+ /* gst-plugins-rs has per-plugin module names so need to check origin there */
+ if (g_strv_contains (gstreamer_modules, module)
+ || (origin != NULL && g_str_has_suffix (origin, "/gst-plugins-rs"))) {
+ GList *features;
+
+ features =
+ gst_registry_get_feature_list_by_plugin (gst_registry_get (),
+ gst_plugin_get_name (plugin));
+
+ /* if the plugin only has a single feature, plugin page == feature page */
+ if (features != NULL && features->next == NULL) {
+ n_print ("%s%-25s%s%s%s/%s/#%s-page%s\n", PROP_NAME_COLOR,
+ "Documentation", RESET_COLOR, PROP_VALUE_COLOR, GST_DOC_BASE_URL,
+ gst_plugin_get_name (plugin), GST_OBJECT_NAME (factory),
+ RESET_COLOR);
+ } else {
+ n_print ("%s%-25s%s%s%s/%s/%s.html%s\n", PROP_NAME_COLOR,
+ "Documentation", RESET_COLOR, PROP_VALUE_COLOR, GST_DOC_BASE_URL,
+ gst_plugin_get_name (plugin), GST_OBJECT_NAME (factory),
+ RESET_COLOR);
+ }
+ gst_plugin_feature_list_free (features);
+ }
+ }
+
pop_indent ();
n_print ("\n");
}
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_DEPRECATED | \
GST_PARAM_CONTROLLABLE | GST_PARAM_MUTABLE_PLAYING | \
GST_PARAM_MUTABLE_PAUSED | GST_PARAM_MUTABLE_READY | \
- GST_PARAM_CONDITIONALLY_AVAILABLE)
+ GST_PARAM_CONDITIONALLY_AVAILABLE | GST_PARAM_DOC_SHOW_DEFAULT)
static int
sort_gparamspecs (GParamSpec ** a, GParamSpec ** b)
(GCompareDataFunc) sort_gparamspecs, NULL);
n_print ("%s%s%s:\n", HEADING_COLOR, desc, RESET_COLOR);
+ n_print ("\n");
push_indent ();
} else if (param->value_type == GST_TYPE_ARRAY) {
GstParamSpecArray *parray = GST_PARAM_SPEC_ARRAY_LIST (param);
+ if (GST_VALUE_HOLDS_ARRAY (&value)) {
+ gchar *def = gst_value_serialize (&value);
+
+ n_print ("%sDefault%s: \"%s\"\n", PROP_ATTR_VALUE_COLOR,
+ RESET_COLOR, def);
+
+ g_free (def);
+ }
+
if (parray->element_spec) {
n_print ("%sGstValueArray of GValues of type%s %s\"%s\"%s",
PROP_VALUE_COLOR, RESET_COLOR, DATATYPE_COLOR,
pop_indent_n (11);
g_value_reset (&value);
+
+ n_print ("\n");
}
if (num_properties == 0)
n_print ("%snone%s\n", PROP_VALUE_COLOR, RESET_COLOR);
static void
print_pad_templates_info (GstElement * element, GstElementFactory * factory)
{
- GList *pads;
+ GList *pads, *tmp;
GstStaticPadTemplate *padtemplate;
GstPadTemplate *tmpl;
pads = g_list_copy ((GList *)
gst_element_factory_get_static_pad_templates (factory));
pads = g_list_sort (pads, gst_static_pad_compare_func);
- while (pads) {
- padtemplate = (GstStaticPadTemplate *) (pads->data);
- pads = g_list_next (pads);
+
+ for (tmp = pads; tmp; tmp = tmp->next) {
+ padtemplate = (GstStaticPadTemplate *) (tmp->data);
if (padtemplate->direction == GST_PAD_SRC)
n_print ("%sSRC template%s: %s'%s'%s\n", PROP_NAME_COLOR, RESET_COLOR,
pop_indent ();
- if (pads != NULL)
+ if (tmp->next)
n_print ("\n");
}
g_list_free (pads);
return FALSE;
}
+static const gchar *
+pretty_type_name (GType type, const gchar ** p_pmark)
+{
+ if (type == G_TYPE_STRING) {
+ *p_pmark = " * ";
+ return "gchar";
+ } else if (type == G_TYPE_STRV) {
+ *p_pmark = " ** ";
+ return "gchar";
+ } else {
+ *p_pmark = gtype_needs_ptr_marker (type) ? " * " : " ";
+ return g_type_name (type);
+ }
+}
+
static void
print_signal_info (GstElement * element)
{
n_print ("%sElement Signals%s:\n", HEADING_COLOR, RESET_COLOR);
else
n_print ("%sElement Actions%s:\n", HEADING_COLOR, RESET_COLOR);
+ n_print ("\n");
} else {
continue;
}
for (l = found_signals; l; l = l->next) {
gchar *indent;
const gchar *pmark;
+ const gchar *retval_type_name;
int indent_len;
query = (GSignalQuery *) l->data;
- indent_len = strlen (query->signal_name) +
- strlen (g_type_name (query->return_type)) + 24;
-
- if (gtype_needs_ptr_marker (query->return_type)) {
- pmark = "* ";
- indent_len += 2;
- } else {
- pmark = " ";
- }
+ retval_type_name = pretty_type_name (query->return_type, &pmark);
+ indent_len =
+ strlen (query->signal_name) + strlen (retval_type_name) + 24 +
+ strlen (pmark) - 1;
indent = g_new0 (gchar, indent_len + 1);
memset (indent, ' ', indent_len);
- n_print (" %s\"%s\"%s : %s%s%s%suser_function%s (%s%s%s* object%s",
+ n_print (" %s\"%s\"%s : %s%s%s%suser_function%s (%s%s%s * object%s",
PROP_NAME_COLOR, query->signal_name, RESET_COLOR,
- DATATYPE_COLOR, g_type_name (query->return_type), PROP_VALUE_COLOR,
+ DATATYPE_COLOR, retval_type_name, PROP_VALUE_COLOR,
pmark, RESET_COLOR, DATATYPE_COLOR, g_type_name (type),
PROP_VALUE_COLOR, RESET_COLOR);
for (j = 0; j < query->n_params; j++) {
- const gchar *type_name, *asterisk;
+ const gchar *type_name, *asterisk, *const_prefix;
+
+ type_name = pretty_type_name (query->param_types[j], &asterisk);
- type_name = g_type_name (query->param_types[j]);
- asterisk = gtype_needs_ptr_marker (query->param_types[j]) ? "*" : "";
+ /* Add const prefix for string and string array arguments */
+ if (g_str_equal (type_name, "gchar") && strchr (asterisk, '*')) {
+ const_prefix = "const ";
+ } else {
+ const_prefix = "";
+ }
g_print (",\n");
- n_print ("%s%s%s%s%s arg%d%s", indent, DATATYPE_COLOR, type_name,
- PROP_VALUE_COLOR, asterisk, j, RESET_COLOR);
+ n_print ("%s%s%s%s%s%sarg%d%s", indent, DATATYPE_COLOR, const_prefix,
+ type_name, PROP_VALUE_COLOR, asterisk, j, RESET_COLOR);
}
if (k == 0) {
g_print (");\n");
g_free (indent);
+ g_print ("\n");
}
if (found_signals) {
static void
print_plugin_info (GstPlugin * plugin)
{
+ const gchar *plugin_name = gst_plugin_get_name (plugin);
const gchar *release_date = gst_plugin_get_release_date_string (plugin);
const gchar *filename = gst_plugin_get_filename (plugin);
+ const gchar *module = gst_plugin_get_source (plugin);
+ const gchar *origin = gst_plugin_get_origin (plugin);
n_print ("%sPlugin Details%s:\n", HEADING_COLOR, RESET_COLOR);
push_indent ();
n_print ("%s%-25s%s%s%s%s\n", PROP_NAME_COLOR, "Name", RESET_COLOR,
- PROP_VALUE_COLOR, gst_plugin_get_name (plugin), RESET_COLOR);
+ PROP_VALUE_COLOR, plugin_name, RESET_COLOR);
n_print ("%s%-25s%s%s%s%s\n", PROP_NAME_COLOR, "Description", RESET_COLOR,
PROP_VALUE_COLOR, gst_plugin_get_description (plugin), RESET_COLOR);
n_print ("%s%-25s%s%s%s%s\n", PROP_NAME_COLOR, "Filename", RESET_COLOR,
n_print ("%s%-25s%s%s%s%s\n", PROP_NAME_COLOR, "License", RESET_COLOR,
PROP_VALUE_COLOR, gst_plugin_get_license (plugin), RESET_COLOR);
n_print ("%s%-25s%s%s%s%s\n", PROP_NAME_COLOR, "Source module", RESET_COLOR,
- PROP_VALUE_COLOR, gst_plugin_get_source (plugin), RESET_COLOR);
+ PROP_VALUE_COLOR, module, RESET_COLOR);
+
+ /* gst-plugins-rs has per-plugin module names so need to check origin there */
+ if (g_strv_contains (gstreamer_modules, module)
+ || (origin != NULL && g_str_has_suffix (origin, "/gst-plugins-rs"))) {
+ n_print ("%s%-25s%s%s%s/%s/%s\n", PROP_NAME_COLOR, "Documentation",
+ RESET_COLOR, PROP_VALUE_COLOR, GST_DOC_BASE_URL, plugin_name,
+ RESET_COLOR);
+ }
if (release_date != NULL) {
const gchar *tz = "(UTC)";
else
_name = NULL;
- print_factory_details_info (factory);
-
plugin = gst_plugin_feature_get_plugin (GST_PLUGIN_FEATURE (factory));
+
+ print_factory_details_info (factory, plugin);
+
if (plugin) {
print_plugin_info (plugin);
gst_object_unref (plugin);
return FALSE;
}
-int
-main (int argc, char *argv[])
+static int
+real_main (int argc, char *argv[])
{
gboolean print_all = FALSE;
gboolean do_print_blacklist = FALSE;
ctx = g_option_context_new ("[ELEMENT-NAME | PLUGIN-NAME]");
g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
g_option_context_add_group (ctx, gst_init_get_option_group ());
- if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
+#if defined(G_OS_WIN32) && !defined(GST_CHECK_MAIN)
+ if (!g_option_context_parse_strv (ctx, &argv, &err))
+#else
+ if (!g_option_context_parse (ctx, &argc, &argv, &err))
+#endif
+ {
g_printerr ("Error initializing: %s\n", err->message);
g_clear_error (&err);
g_option_context_free (ctx);
gst_init (&argc, &argv);
#endif
+#if defined(G_OS_WIN32) && !defined(GST_CHECK_MAIN)
+ argc = g_strv_length (argv);
+#endif
+
gst_tools_print_version ();
if (print_all && argc > 1) {
return exit_code;
}
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+
+ /* gstinspect.c calls this function */
+#if defined(G_OS_WIN32) && !defined(GST_CHECK_MAIN)
+ argv = g_win32_get_command_line ();
+#endif
+
+#if defined(__APPLE__) && TARGET_OS_MAC && !TARGET_OS_IPHONE
+ ret = gst_macos_main ((GstMainFunc) real_main, argc, argv, NULL);
+#else
+ ret = real_main (argc, argv);
+#endif
+
+#if defined(G_OS_WIN32) && !defined(GST_CHECK_MAIN)
+ g_strfreev (argv);
+#endif
+
+ return ret;
+}