summaryrefslogtreecommitdiff
path: root/libs/gst/helpers/gst-completion-helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gst/helpers/gst-completion-helper.c')
-rw-r--r--libs/gst/helpers/gst-completion-helper.c226
1 files changed, 226 insertions, 0 deletions
diff --git a/libs/gst/helpers/gst-completion-helper.c b/libs/gst/helpers/gst-completion-helper.c
new file mode 100644
index 000000000..2e83dd592
--- /dev/null
+++ b/libs/gst/helpers/gst-completion-helper.c
@@ -0,0 +1,226 @@
+/* GStreamer
+ * Copyright (C) 2015 Mathieu Duponchelle <mathieu.duponchelle@opencreed.com>
+ *
+ * gst-completion-helper.c: tool to let other tools enjoy fast and powerful
+ * gstreamer-aware completion
+ *
+ * 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 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <glib.h>
+#include <stdlib.h>
+
+static GList *
+get_pad_templates_info (GstElement * element, GstElementFactory * factory,
+ GstPadDirection direction)
+{
+ const GList *pads;
+ GstStaticPadTemplate *padtemplate;
+ GList *caps_list = NULL;
+
+ if (gst_element_factory_get_num_pad_templates (factory) == 0) {
+ g_print (" none\n");
+ return NULL;
+ }
+
+ pads = gst_element_factory_get_static_pad_templates (factory);
+ while (pads) {
+ padtemplate = (GstStaticPadTemplate *) (pads->data);
+ pads = g_list_next (pads);
+
+ if (padtemplate->direction != direction)
+ continue;
+
+ if (padtemplate->static_caps.string) {
+ caps_list =
+ g_list_append (caps_list,
+ gst_static_caps_get (&padtemplate->static_caps));
+ }
+
+ }
+
+ return caps_list;
+}
+
+static GList *
+_get_pad_caps (const gchar * factory_name, GstPadDirection direction)
+{
+ GstElementFactory *factory = gst_element_factory_find (factory_name);
+ GstElement *element = gst_element_factory_make (factory_name, NULL);
+
+ if (!element)
+ return NULL;
+ if (!factory)
+ return NULL;
+ factory =
+ GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
+ (factory)));
+ if (!factory)
+ return NULL;
+ return get_pad_templates_info (element, factory, direction);
+}
+
+static gboolean
+_are_linkable (GstPluginFeature * feature, GList * caps_list)
+{
+ gboolean print = FALSE;
+ GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
+
+ GList *tmp;
+ print = FALSE;
+ for (tmp = caps_list; tmp; tmp = tmp->next) {
+ if (gst_element_factory_can_sink_any_caps (factory, tmp->data)) {
+ print = TRUE;
+ break;
+ }
+ }
+
+ return print;
+}
+
+static void
+_list_features (const gchar * compatible_with)
+{
+ GList *plugins, *orig_plugins;
+ GList *caps_list = NULL;
+
+ if (compatible_with) {
+ caps_list = _get_pad_caps (compatible_with, GST_PAD_SRC);
+ }
+
+ orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get ());
+ while (plugins) {
+ GList *features, *orig_features;
+ GstPlugin *plugin;
+
+ plugin = (GstPlugin *) (plugins->data);
+ plugins = g_list_next (plugins);
+
+ if (GST_OBJECT_FLAG_IS_SET (plugin, GST_PLUGIN_FLAG_BLACKLISTED)) {
+ continue;
+ }
+
+ orig_features = features =
+ gst_registry_get_feature_list_by_plugin (gst_registry_get (),
+ gst_plugin_get_name (plugin));
+ while (features) {
+ GstPluginFeature *feature;
+
+ if (G_UNLIKELY (features->data == NULL))
+ goto next;
+ feature = GST_PLUGIN_FEATURE (features->data);
+
+ if (GST_IS_ELEMENT_FACTORY (feature)) {
+ gboolean print = TRUE;
+ if (caps_list)
+ print = _are_linkable (feature, caps_list);
+ if (print)
+ g_print ("%s ", gst_plugin_feature_get_name (feature));
+ }
+
+ next:
+ features = g_list_next (features);
+ }
+
+ gst_plugin_feature_list_free (orig_features);
+ }
+
+ g_list_free (caps_list);
+ g_print ("\n");
+ gst_plugin_list_free (orig_plugins);
+}
+
+static void
+_print_element_properties_info (GstElement * element)
+{
+ GParamSpec **property_specs;
+ guint num_properties, i;
+
+ property_specs = g_object_class_list_properties
+ (G_OBJECT_GET_CLASS (element), &num_properties);
+
+ for (i = 0; i < num_properties; i++) {
+ GParamSpec *param = property_specs[i];
+
+ if (param->flags & G_PARAM_WRITABLE) {
+ g_print ("%s= ", g_param_spec_get_name (param));
+ }
+ }
+
+ g_free (property_specs);
+}
+
+static void
+_list_element_properties (const gchar * factory_name)
+{
+ GstElement *element = gst_element_factory_make (factory_name, NULL);
+
+ _print_element_properties_info (element);
+}
+
+int
+main (int argc, char *argv[])
+{
+ gboolean list_features = FALSE;
+ gchar *compatible_with = NULL;
+ gchar *element = NULL;
+
+ GOptionEntry options[] = {
+ {"list-features", 'l', 0, G_OPTION_ARG_NONE, &list_features,
+ "list all the available features", NULL},
+ {"compatible-with", '\0', 0, G_OPTION_ARG_STRING, &compatible_with,
+ "Only print the elements that could be queued after this feature name",
+ NULL},
+ {"element-properties", '\0', 0, G_OPTION_ARG_STRING, &element,
+ "The element to list properties on", NULL},
+ {NULL}
+ };
+
+ GOptionContext *ctx;
+ GError *err = NULL;
+
+ ctx = g_option_context_new ("PIPELINE-DESCRIPTION");
+ g_option_context_add_main_entries (ctx, options, NULL);
+ g_option_context_add_group (ctx, gst_init_get_option_group ());
+ if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
+ if (err)
+ g_printerr ("Error initializing: %s\n", GST_STR_NULL (err->message));
+ else
+ g_printerr ("Error initializing: Unknown error!\n");
+ exit (1);
+ }
+ g_option_context_free (ctx);
+
+ if (compatible_with) {
+ _list_features (compatible_with);
+ exit (EXIT_SUCCESS);
+ }
+
+ if (element) {
+ _list_element_properties (element);
+ exit (EXIT_SUCCESS);
+ }
+
+ if (list_features) {
+ _list_features (NULL);
+ exit (EXIT_SUCCESS);
+ }
+}