da1876c37fd14a370c97c7b90e14ce61d4869055
[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   GstElementClass *gstelement_class;
88   GList *pads, *caps;
89   GstPad *pad;
90   GstRealPad *realpad;
91   GstPadTemplate *padtemplate;
92   GstCaps *cap;
93   GtkArg *args;
94   guint32 *flags;
95   gint num_args,i;
96
97   element = gst_elementfactory_create(factory,"element");
98   if (!element) {
99     g_print ("couldn't construct element for some reason\n");
100     return -1;
101   }
102   gstelement_class = GST_ELEMENT_CLASS (GTK_OBJECT (element)->klass);
103
104   printf("Factory Details:\n");
105   printf("  Long name:\t%s\n",factory->details->longname);
106   printf("  Class:\t%s\n",factory->details->klass);
107   printf("  Description:\t%s\n",factory->details->description);
108   printf("  Version:\t%s\n",factory->details->version);
109   printf("  Author(s):\t%s\n",factory->details->author);
110   printf("  Copyright:\t%s\n",factory->details->copyright);
111   printf("\n");
112
113   printf("Pad Templates:\n");
114   if (factory->numpadtemplates) {
115     pads = factory->padtemplates;
116     while (pads) {
117       padtemplate = (GstPadTemplate*)(pads->data);
118       pads = g_list_next(pads);
119
120       if (padtemplate->direction == GST_PAD_SRC)
121         printf("  SRC template: '%s'\n",padtemplate->name_template);
122       else if (padtemplate->direction == GST_PAD_SINK)
123         printf("  SINK template: '%s'\n",padtemplate->name_template);
124       else
125         printf("  UNKNOWN!!! template: '%s'\n",padtemplate->name_template);
126
127       if (padtemplate->presence == GST_PAD_ALWAYS)
128         printf("    Exists: Always\n");
129       else if (padtemplate->presence == GST_PAD_SOMETIMES)
130         printf("    Exists: Sometimes\n");
131       else if (padtemplate->presence == GST_PAD_REQUEST)
132         printf("    Exists: Request\n");
133       else
134         printf("    Exists: UNKNOWN!!!\n");
135
136       if (padtemplate->caps) {
137         printf("    Capabilities:\n");
138         caps = padtemplate->caps;
139         while (caps) {
140           GstType *type;
141
142           cap = (GstCaps*)(caps->data);
143           caps = g_list_next(caps);
144
145           printf("      '%s':\n",cap->name);
146
147           type = gst_type_find_by_id (cap->id);
148           if (type) 
149             printf("        MIME type: '%s':\n",type->mime);
150           else
151             printf("        MIME type: 'unknown/unknown':\n");
152
153           if (cap->properties)
154             print_props(cap->properties,"        ");
155         }
156       }
157
158       printf("\n");
159     }
160   } else
161     printf("  none\n\n");
162
163   printf("Element Flags:\n");
164   if (GST_FLAG_IS_SET(element,GST_ELEMENT_COMPLEX))
165     printf("  GST_ELEMENT_COMPLEX\n");
166   if (GST_FLAG_IS_SET(element,GST_ELEMENT_DECOUPLED))
167     printf("  GST_ELEMENT_DECOUPLED\n");
168   if (GST_FLAG_IS_SET(element,GST_ELEMENT_THREAD_SUGGESTED))
169     printf("  GST_ELEMENT_THREADSUGGESTED\n");
170   if (GST_FLAG_IS_SET(element,GST_ELEMENT_NO_SEEK))
171     printf("  GST_ELEMENT_NO_SEEK\n");
172   if (! GST_FLAG_IS_SET(element, GST_ELEMENT_COMPLEX | GST_ELEMENT_DECOUPLED |
173                                  GST_ELEMENT_THREAD_SUGGESTED | GST_ELEMENT_NO_SEEK))
174     printf("  no flags set\n");
175   printf("\n");
176
177
178   printf("Element Implementation:\n");
179   if (element->loopfunc)
180     printf("  loopfunc()-based element\n");
181   else
182     printf("  No loopfunc(), must be chain-based or not configured yet\n");
183   if (gstelement_class->change_state)
184     printf("  Has change_state() function\n");
185   else
186     printf("  No change_state() class function\n");
187   if (gstelement_class->save_thyself)
188     printf("  Has custom save_thyself() class function\n");
189   if (gstelement_class->restore_thyself)
190     printf("  Has custom restore_thyself() class function\n");
191   printf("\n");
192
193
194   printf("Pads:\n");
195   if (element->numpads) {
196     pads = gst_element_get_pad_list(element);
197     while (pads) {
198       pad = GST_PAD(pads->data);
199       pads = g_list_next(pads);
200       realpad = GST_REAL_PAD(pad);
201
202       if (gst_pad_get_direction(pad) == GST_PAD_SRC)
203         printf("  SRC: '%s'\n",gst_pad_get_name(pad));
204       else if (gst_pad_get_direction(pad) == GST_PAD_SINK)
205         printf("  SINK: '%s'\n",gst_pad_get_name(pad));
206       else
207         printf("  UNKNOWN!!!: '%s'\n",gst_pad_get_name(pad));
208
209       printf("    Implementation:\n");
210       if (realpad->chainfunc)
211         printf("      Has chainfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->chainfunc));
212       if (realpad->getfunc)
213         printf("      Has getfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getfunc));
214       if (realpad->getregionfunc)
215         printf("      Has getregionfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getregionfunc));
216       if (realpad->qosfunc)
217         printf("      Has qosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->qosfunc));
218       if (realpad->eosfunc) {
219         printf("      Has eosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->eosfunc));
220       }
221
222       if (pad->padtemplate)
223         printf("    Pad Template: '%s'\n",pad->padtemplate->name_template);
224
225       if (realpad->caps) {
226         printf("    Capabilities:\n");
227         caps = realpad->caps;
228         while (caps) {
229           GstType *type;
230
231           cap = (GstCaps*)(caps->data);
232           caps = g_list_next(caps);
233
234           printf("      '%s':\n",cap->name);
235
236           type = gst_type_find_by_id (cap->id);
237           if (type) 
238             printf("        MIME type: '%s':\n",type->mime);
239           else
240             printf("        MIME type: 'unknown/unknown':\n");
241
242           if (cap->properties)
243             print_props(cap->properties,"        ");
244         }
245       }
246
247       printf("\n");
248     }
249   } else
250     printf("  none\n\n");
251
252   printf("Element Arguments:\n");
253   args = gtk_object_query_args(GTK_OBJECT_TYPE(element), &flags, &num_args);
254   for (i=0;i<num_args;i++) {
255     gtk_object_getv(GTK_OBJECT(element), 1, &args[i]);
256
257 // FIXME should say whether it's read-only or not
258
259     printf("  %s: ",args[i].name);
260     switch (args[i].type) {
261       case GTK_TYPE_STRING: printf("String");break;
262       case GTK_TYPE_BOOL: printf("Boolean");break;
263       case GTK_TYPE_ULONG:
264       case GTK_TYPE_LONG:
265       case GTK_TYPE_UINT:
266       case GTK_TYPE_INT: printf("Integer");break;
267       case GTK_TYPE_FLOAT:
268       case GTK_TYPE_DOUBLE: printf("Float");break;
269       default:
270         if (args[i].type == GST_TYPE_FILENAME)
271           printf("Filename");
272         else if (GTK_FUNDAMENTAL_TYPE (args[i].type) == GTK_TYPE_ENUM) {
273           GtkEnumValue *values;
274           guint j = 0;
275
276           printf("Enum (default %d)", GTK_VALUE_ENUM (args[i]));
277           values = gtk_type_enum_get_values (args[i].type);
278           while (values[j].value_name) {
279             printf("\n    (%d): \t%s", values[j].value, values[j].value_nick);
280             j++; 
281           }
282         }
283         else if (args[i].type == GTK_TYPE_WIDGET)
284           printf("GtkWidget");
285         else
286           printf("unknown");
287         break;
288     }
289     printf("\n");
290   }
291   g_free (args);
292   if (num_args == 0) g_print ("  none");
293   printf("\n");
294
295   return 0;
296 }
297
298 void print_element_list() {
299   GList *plugins, *factories;
300   GstPlugin *plugin;
301   GstElementFactory *factory;
302
303   plugins = gst_plugin_get_list();
304   while (plugins) {
305     plugin = (GstPlugin*)(plugins->data);
306     plugins = g_list_next (plugins);
307
308 //    printf("%s:\n",plugin->name);
309
310     factories = gst_plugin_get_factory_list(plugin);
311     while (factories) {
312       factory = (GstElementFactory*)(factories->data);
313       factories = g_list_next (factories);
314
315       printf("%s: %s: %s\n",plugin->name,factory->name,factory->details->longname);
316     }
317
318 //    printf("\n");
319   }
320 }
321
322
323 void print_plugin_info(GstPlugin *plugin) {
324   GList *factories;
325   GstElementFactory *factory;
326
327   printf("Plugin Details:\n");
328   printf("  Name:\t\t%s\n",plugin->name);
329   printf("  Long Name:\t%s\n",plugin->longname);
330   printf("  Filename:\t%s\n",plugin->filename);
331   printf("\n");
332
333   if (plugin->numelements) {
334     printf("Element Factories:\n");
335
336     factories = gst_plugin_get_factory_list(plugin);
337     while (factories) {
338       factory = (GstElementFactory*)(factories->data);
339       factories = g_list_next(factories);
340
341       printf("  %s: %s\n",factory->name,factory->details->longname);
342     }
343   }
344   printf("\n");
345 }
346
347
348 int main(int argc,char *argv[]) {
349   GstElementFactory *factory;
350   GstPlugin *plugin;
351   gchar *so;
352
353   gst_init(&argc,&argv);
354
355   // if no arguments, print out list of elements
356   if (argc == 1) {
357     print_element_list(); 
358
359   // else we try to get a factory
360   } else {
361     // first check for help
362     if (strstr(argv[1],"-help")) {
363       printf("Usage: %s\t\t\tList all registered elements\n",argv[0]);
364       printf("       %s element-name\tShow element details\n",argv[0]);
365       printf("       %s plugin-name[.so]\tShow information about plugin\n",argv[0]);
366       return 0;
367     }
368
369     // only search for a factory if there's not a '.so'
370     if (! strstr(argv[1],".so")) {
371       factory = gst_elementfactory_find (argv[1]);
372
373       // if there's a factory, print out the info
374       if (factory)
375         return print_element_info(factory);
376     } else {
377       // strip the .so
378       so = strstr(argv[1],".so");
379       so[0] = '\0';
380     }
381
382     // otherwise assume it's a plugin
383     plugin = gst_plugin_find (argv[1]);
384
385     // if there is such a plugin, print out info
386     if (plugin) {
387       print_plugin_info(plugin);
388
389     } else {
390       printf("no such element or plugin '%s'\n",argv[1]);
391       return -1;
392     }
393   }
394
395   return 0;
396 }