2 * Copyright (C) 2015 Mathieu Duponchelle <mathieu.duponchelle@opencreed.com>
4 * gst-completion-helper.c: tool to let other tools enjoy fast and powerful
5 * gstreamer-aware completion
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
33 get_pad_templates_info (GstElement * element, GstElementFactory * factory,
34 GstPadDirection direction)
37 GstStaticPadTemplate *padtemplate;
38 GList *caps_list = NULL;
40 if (gst_element_factory_get_num_pad_templates (factory) == 0) {
45 pads = gst_element_factory_get_static_pad_templates (factory);
47 padtemplate = (GstStaticPadTemplate *) (pads->data);
48 pads = g_list_next (pads);
50 if (padtemplate->direction != direction)
53 if (padtemplate->static_caps.string) {
55 g_list_append (caps_list,
56 gst_static_caps_get (&padtemplate->static_caps));
65 _get_pad_caps (const gchar * factory_name, GstPadDirection direction)
67 GstElementFactory *factory = gst_element_factory_find (factory_name);
68 GstElement *element = gst_element_factory_make (factory_name, NULL);
75 GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
79 return get_pad_templates_info (element, factory, direction);
83 _are_linkable (GstPluginFeature * feature, GList * caps_list)
85 gboolean print = FALSE;
86 GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
90 for (tmp = caps_list; tmp; tmp = tmp->next) {
91 if (gst_element_factory_can_sink_any_caps (factory, tmp->data)) {
101 _belongs_to_klass (GstElementFactory * factory, const gchar * klass)
103 const gchar *factory_klass;
107 gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
108 if (strstr (factory_klass, klass))
114 _list_features (const gchar * compatible_with, const gchar * klass,
117 GList *plugins, *orig_plugins;
118 GList *caps_list = NULL;
120 if (compatible_with) {
121 caps_list = _get_pad_caps (compatible_with, GST_PAD_SRC);
124 orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get ());
126 GList *features, *orig_features;
129 plugin = (GstPlugin *) (plugins->data);
130 plugins = g_list_next (plugins);
132 if (GST_OBJECT_FLAG_IS_SET (plugin, GST_PLUGIN_FLAG_BLACKLISTED)) {
136 orig_features = features =
137 gst_registry_get_feature_list_by_plugin (gst_registry_get (),
138 gst_plugin_get_name (plugin));
140 GstPluginFeature *feature;
142 if (G_UNLIKELY (features->data == NULL))
144 feature = GST_PLUGIN_FEATURE (features->data);
146 if (GST_IS_ELEMENT_FACTORY (feature)) {
147 gboolean print = TRUE;
149 print = _are_linkable (feature, caps_list);
151 print = _belongs_to_klass (GST_ELEMENT_FACTORY (feature), klass);
152 if (print && sinkcaps)
154 gst_element_factory_can_sink_any_caps (GST_ELEMENT_FACTORY
155 (feature), sinkcaps);
158 g_print ("%s ", gst_plugin_feature_get_name (feature));
162 features = g_list_next (features);
165 gst_plugin_feature_list_free (orig_features);
168 g_list_free (caps_list);
170 gst_plugin_list_free (orig_plugins);
174 _print_element_properties_info (GstElement * element)
176 GParamSpec **property_specs;
177 guint num_properties, i;
179 property_specs = g_object_class_list_properties
180 (G_OBJECT_GET_CLASS (element), &num_properties);
182 for (i = 0; i < num_properties; i++) {
183 GParamSpec *param = property_specs[i];
185 if (param->flags & G_PARAM_WRITABLE) {
186 g_print ("%s= ", g_param_spec_get_name (param));
190 g_free (property_specs);
194 _list_element_properties (const gchar * factory_name)
196 GstElement *element = gst_element_factory_make (factory_name, NULL);
198 _print_element_properties_info (element);
202 main (int argc, char *argv[])
204 gboolean list_features = FALSE;
205 gchar *compatible_with = NULL;
206 gchar *element = NULL;
208 gchar *caps_str = NULL;
209 GstCaps *sinkcaps = NULL;
210 gint exit_code = EXIT_SUCCESS;
212 GOptionEntry options[] = {
213 {"list-features", 'l', 0, G_OPTION_ARG_NONE, &list_features,
214 "list all the available features", NULL},
215 {"compatible-with", '\0', 0, G_OPTION_ARG_STRING, &compatible_with,
216 "Only print the elements that could be queued after this feature name",
218 {"element-properties", '\0', 0, G_OPTION_ARG_STRING, &element,
219 "The element to list properties on", NULL},
220 {"klass", '\0', 0, G_OPTION_ARG_STRING, &klass,
221 "Only print the elements belonging to that klass", NULL},
222 {"sinkcaps", '\0', 0, G_OPTION_ARG_STRING, &caps_str,
223 "Only print the elements that can sink these caps", NULL},
230 ctx = g_option_context_new ("PIPELINE-DESCRIPTION");
231 g_option_context_add_main_entries (ctx, options, NULL);
232 g_option_context_add_group (ctx, gst_init_get_option_group ());
233 if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
235 g_printerr ("Error initializing: %s\n", GST_STR_NULL (err->message));
237 g_printerr ("Error initializing: Unknown error!\n");
240 g_option_context_free (ctx);
243 sinkcaps = gst_caps_from_string (caps_str);
245 exit_code = EXIT_FAILURE;
250 if (compatible_with || klass || sinkcaps) {
251 _list_features (compatible_with, klass, sinkcaps);
256 _list_element_properties (element);
261 _list_features (NULL, NULL, NULL);
267 gst_caps_unref (sinkcaps);