This is a megapatch with the following changes:
[platform/upstream/gstreamer.git] / tools / gstreamer-inspect.c
1 #include <gst/gst.h>
2 #include <string.h>
3
4 // this must be built within the gstreamer dir, else this will fail
5 #include <gst/gstpropsprivate.h>
6
7 void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) {
8   GList *list;
9   GstPropsEntry *listentry;
10   gchar *longprefix;
11
12   if (showname)
13     printf("%s%s: ",pfx,g_quark_to_string(prop->propid));
14   else
15     printf(pfx);
16
17   switch (prop->propstype) {
18     case GST_PROPS_INT_ID_NUM:
19       printf("Integer: %d\n",prop->data.int_data);
20       break;
21     case GST_PROPS_INT_RANGE_ID_NUM:
22       printf("Integer range: %d - %d\n",prop->data.int_range_data.min,
23              prop->data.int_range_data.max);
24       break;
25     case GST_PROPS_BOOL_ID_NUM:
26       printf("Boolean: %s\n",prop->data.bool_data ? "TRUE" : "FALSE");
27       break;
28     case GST_PROPS_FOURCC_ID_NUM:
29       printf("FourCC: %c%c%c%c\n",
30              prop->data.fourcc_data & 0xff,prop->data.fourcc_data>>8 & 0xff,
31              prop->data.fourcc_data>>16 & 0xff,prop->data.fourcc_data>>24 & 0xff);
32       break;
33     case GST_PROPS_LIST_ID_NUM:
34       printf("List:\n");
35       longprefix = g_strdup_printf("%s  ",pfx);
36       list = prop->data.list_data.entries;
37       while (list) {
38         listentry = (GstPropsEntry*)(list->data);
39         list = g_list_next(list);
40         print_prop(listentry,FALSE,longprefix);
41       }
42       g_free(longprefix);
43       break;
44     default:
45       printf("\n");
46   }
47 }
48
49 void print_props(GstProps *properties,gchar *pfx) {
50   GList *props;
51   GstPropsEntry *prop;
52
53   props = properties->properties;
54   while (props) {
55     prop = (GstPropsEntry*)(props->data);
56     props = g_list_next(props);
57
58     print_prop(prop,TRUE,pfx);
59   }
60 }
61
62 /*
63 struct _GstPropsEntry {
64   GQuark    propid;
65   GstPropsId propstype;
66
67   union {
68     // flat values
69     gboolean bool_data;
70     guint32  fourcc_data;
71     gint     int_data;
72
73     // structured values
74     struct {
75       GList *entries;
76     } list_data;
77     struct {
78       gint min;
79       gint max;
80     } int_range_data;
81   } data;
82 };
83 */
84
85 gint print_element_info(GstElementFactory *factory) {
86   GstElement *element;
87   GstObjectClass *gstobject_class;
88   GstElementClass *gstelement_class;
89   GList *pads, *caps;
90   GstPad *pad;
91   GstRealPad *realpad;
92   GstPadTemplate *padtemplate;
93   GstCaps *cap;
94   GtkArg *args;
95   guint32 *flags;
96   gint num_args,i;
97
98   element = gst_elementfactory_create(factory,"element");
99   if (!element) {
100     g_print ("couldn't construct element for some reason\n");
101     return -1;
102   }
103
104   gstobject_class = GST_OBJECT_CLASS (GTK_OBJECT (element)->klass);
105   gstelement_class = GST_ELEMENT_CLASS (GTK_OBJECT (element)->klass);
106
107   printf("Factory Details:\n");
108   printf("  Long name:\t%s\n",factory->details->longname);
109   printf("  Class:\t%s\n",factory->details->klass);
110   printf("  Description:\t%s\n",factory->details->description);
111   printf("  Version:\t%s\n",factory->details->version);
112   printf("  Author(s):\t%s\n",factory->details->author);
113   printf("  Copyright:\t%s\n",factory->details->copyright);
114   printf("\n");
115
116   printf("Pad Templates:\n");
117   if (factory->numpadtemplates) {
118     pads = factory->padtemplates;
119     while (pads) {
120       padtemplate = (GstPadTemplate*)(pads->data);
121       pads = g_list_next(pads);
122
123       if (padtemplate->direction == GST_PAD_SRC)
124         printf("  SRC template: '%s'\n",padtemplate->name_template);
125       else if (padtemplate->direction == GST_PAD_SINK)
126         printf("  SINK template: '%s'\n",padtemplate->name_template);
127       else
128         printf("  UNKNOWN!!! template: '%s'\n",padtemplate->name_template);
129
130       if (padtemplate->presence == GST_PAD_ALWAYS)
131         printf("    Exists: Always\n");
132       else if (padtemplate->presence == GST_PAD_SOMETIMES)
133         printf("    Exists: Sometimes\n");
134       else if (padtemplate->presence == GST_PAD_REQUEST)
135         printf("    Exists: Request\n");
136       else
137         printf("    Exists: UNKNOWN!!!\n");
138
139       if (padtemplate->caps) {
140         printf("    Capabilities:\n");
141         caps = padtemplate->caps;
142         while (caps) {
143           GstType *type;
144
145           cap = (GstCaps*)(caps->data);
146           caps = g_list_next(caps);
147
148           printf("      '%s':\n",cap->name);
149
150           type = gst_type_find_by_id (cap->id);
151           if (type) 
152             printf("        MIME type: '%s':\n",type->mime);
153           else
154             printf("        MIME type: 'unknown/unknown':\n");
155
156           if (cap->properties)
157             print_props(cap->properties,"        ");
158         }
159       }
160
161       printf("\n");
162     }
163   } else
164     printf("  none\n\n");
165
166   printf("Element Flags:\n");
167   if (GST_FLAG_IS_SET(element,GST_ELEMENT_COMPLEX))
168     printf("  GST_ELEMENT_COMPLEX\n");
169   if (GST_FLAG_IS_SET(element,GST_ELEMENT_DECOUPLED))
170     printf("  GST_ELEMENT_DECOUPLED\n");
171   if (GST_FLAG_IS_SET(element,GST_ELEMENT_THREAD_SUGGESTED))
172     printf("  GST_ELEMENT_THREADSUGGESTED\n");
173   if (GST_FLAG_IS_SET(element,GST_ELEMENT_NO_SEEK))
174     printf("  GST_ELEMENT_NO_SEEK\n");
175   if (! GST_FLAG_IS_SET(element, GST_ELEMENT_COMPLEX | GST_ELEMENT_DECOUPLED |
176                                  GST_ELEMENT_THREAD_SUGGESTED | GST_ELEMENT_NO_SEEK))
177     printf("  no flags set\n");
178   printf("\n");
179
180
181   printf("Element Implementation:\n");
182   if (element->loopfunc)
183     printf("  loopfunc()-based element\n");
184   else
185     printf("  No loopfunc(), must be chain-based or not configured yet\n");
186   if (gstelement_class->change_state)
187     printf("  Has change_state() function\n");
188   else
189     printf("  No change_state() class function\n");
190   if (gstobject_class->save_thyself)
191     printf("  Has custom save_thyself() class function\n");
192   if (gstobject_class->restore_thyself)
193     printf("  Has custom restore_thyself() class function\n");
194   printf("\n");
195
196
197   printf("Pads:\n");
198   if (element->numpads) {
199     pads = gst_element_get_pad_list(element);
200     while (pads) {
201       pad = GST_PAD(pads->data);
202       pads = g_list_next(pads);
203       realpad = GST_REAL_PAD(pad);
204
205       if (gst_pad_get_direction(pad) == GST_PAD_SRC)
206         printf("  SRC: '%s'\n",gst_pad_get_name(pad));
207       else if (gst_pad_get_direction(pad) == GST_PAD_SINK)
208         printf("  SINK: '%s'\n",gst_pad_get_name(pad));
209       else
210         printf("  UNKNOWN!!!: '%s'\n",gst_pad_get_name(pad));
211
212       printf("    Implementation:\n");
213       if (realpad->chainfunc)
214         printf("      Has chainfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->chainfunc));
215       if (realpad->getfunc)
216         printf("      Has getfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getfunc));
217       if (realpad->getregionfunc)
218         printf("      Has getregionfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getregionfunc));
219       if (realpad->qosfunc)
220         printf("      Has qosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->qosfunc));
221       if (realpad->eosfunc) {
222         printf("      Has eosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->eosfunc));
223       }
224
225       if (pad->padtemplate)
226         printf("    Pad Template: '%s'\n",pad->padtemplate->name_template);
227
228       if (realpad->caps) {
229         printf("    Capabilities:\n");
230         caps = realpad->caps;
231         while (caps) {
232           GstType *type;
233
234           cap = (GstCaps*)(caps->data);
235           caps = g_list_next(caps);
236
237           printf("      '%s':\n",cap->name);
238
239           type = gst_type_find_by_id (cap->id);
240           if (type) 
241             printf("        MIME type: '%s':\n",type->mime);
242           else
243             printf("        MIME type: 'unknown/unknown':\n");
244
245           if (cap->properties)
246             print_props(cap->properties,"        ");
247         }
248       }
249
250       printf("\n");
251     }
252   } else
253     printf("  none\n\n");
254
255   printf("Element Arguments:\n");
256   args = gtk_object_query_args(GTK_OBJECT_TYPE(element), &flags, &num_args);
257   for (i=0;i<num_args;i++) {
258     gtk_object_getv(GTK_OBJECT(element), 1, &args[i]);
259
260 // FIXME should say whether it's read-only or not
261
262     printf("  %s: ",args[i].name);
263     switch (args[i].type) {
264       case GTK_TYPE_STRING: printf("String");break;
265       case GTK_TYPE_BOOL: printf("Boolean");break;
266       case GTK_TYPE_ULONG:
267       case GTK_TYPE_LONG:
268       case GTK_TYPE_UINT:
269       case GTK_TYPE_INT: printf("Integer");break;
270       case GTK_TYPE_FLOAT:
271       case GTK_TYPE_DOUBLE: printf("Float");break;
272       default:
273         if (args[i].type == GST_TYPE_FILENAME)
274           printf("Filename");
275         else if (GTK_FUNDAMENTAL_TYPE (args[i].type) == GTK_TYPE_ENUM) {
276           GtkEnumValue *values;
277           guint j = 0;
278
279           printf("Enum (default %d)", GTK_VALUE_ENUM (args[i]));
280           values = gtk_type_enum_get_values (args[i].type);
281           while (values[j].value_name) {
282             printf("\n    (%d): \t%s", values[j].value, values[j].value_nick);
283             j++; 
284           }
285         }
286         else if (args[i].type == GTK_TYPE_WIDGET)
287           printf("GtkWidget");
288         else
289           printf("unknown");
290         break;
291     }
292     printf("\n");
293   }
294   g_free (args);
295   if (num_args == 0) g_print ("  none");
296   printf("\n");
297
298   return 0;
299 }
300
301 void print_element_list() {
302   GList *plugins, *factories;
303   GstPlugin *plugin;
304   GstElementFactory *factory;
305
306   plugins = gst_plugin_get_list();
307   while (plugins) {
308     plugin = (GstPlugin*)(plugins->data);
309     plugins = g_list_next (plugins);
310
311 //    printf("%s:\n",plugin->name);
312
313     factories = gst_plugin_get_factory_list(plugin);
314     while (factories) {
315       factory = (GstElementFactory*)(factories->data);
316       factories = g_list_next (factories);
317
318       printf("%s: %s: %s\n",plugin->name,factory->name,factory->details->longname);
319     }
320
321 //    printf("\n");
322   }
323 }
324
325
326 void print_plugin_info(GstPlugin *plugin) {
327   GList *factories;
328   GstElementFactory *factory;
329
330   printf("Plugin Details:\n");
331   printf("  Name:\t\t%s\n",plugin->name);
332   printf("  Long Name:\t%s\n",plugin->longname);
333   printf("  Filename:\t%s\n",plugin->filename);
334   printf("\n");
335
336   if (plugin->numelements) {
337     printf("Element Factories:\n");
338
339     factories = gst_plugin_get_factory_list(plugin);
340     while (factories) {
341       factory = (GstElementFactory*)(factories->data);
342       factories = g_list_next(factories);
343
344       printf("  %s: %s\n",factory->name,factory->details->longname);
345     }
346   }
347   printf("\n");
348 }
349
350
351 int main(int argc,char *argv[]) {
352   GstElementFactory *factory;
353   GstPlugin *plugin;
354   gchar *so;
355
356   gst_init(&argc,&argv);
357
358   // if no arguments, print out list of elements
359   if (argc == 1) {
360     print_element_list(); 
361
362   // else we try to get a factory
363   } else {
364     // first check for help
365     if (strstr(argv[1],"-help")) {
366       printf("Usage: %s\t\t\tList all registered elements\n",argv[0]);
367       printf("       %s element-name\tShow element details\n",argv[0]);
368       printf("       %s plugin-name[.so]\tShow information about plugin\n",argv[0]);
369       return 0;
370     }
371
372     // only search for a factory if there's not a '.so'
373     if (! strstr(argv[1],".so")) {
374       factory = gst_elementfactory_find (argv[1]);
375
376       // if there's a factory, print out the info
377       if (factory)
378         return print_element_info(factory);
379     } else {
380       // strip the .so
381       so = strstr(argv[1],".so");
382       so[0] = '\0';
383     }
384
385     // otherwise assume it's a plugin
386     plugin = gst_plugin_find (argv[1]);
387
388     // if there is such a plugin, print out info
389     if (plugin) {
390       print_plugin_info(plugin);
391
392     } else {
393       printf("no such element or plugin '%s'\n",argv[1]);
394       return -1;
395     }
396   }
397
398   return 0;
399 }