ulong type fix add 64b types add printing name of unknown type
[platform/upstream/gstreamer.git] / tools / gst-inspect.c
1 #include <gst/gst.h>
2 #include <gst/control/control.h>
3 #include <string.h>
4
5 static void 
6 print_prop (GstPropsEntry *prop, gboolean showname, gchar *pfx) 
7 {
8   GstPropsType type;
9
10   if (showname)
11     printf("%s%s: ", pfx, gst_props_entry_get_name (prop));
12   else
13     printf(pfx);
14
15   type = gst_props_entry_get_type (prop);
16
17   switch (type) {
18     case GST_PROPS_INT_TYPE:
19     {
20       gint val;
21       gst_props_entry_get_int (prop, &val);
22       printf("Integer: %d\n", val);
23       break;
24     }
25     case GST_PROPS_INT_RANGE_TYPE:
26     {
27       gint min, max;
28       gst_props_entry_get_int_range (prop, &min, &max);
29       printf("Integer range: %d - %d\n", min, max);
30       break;
31     }
32     case GST_PROPS_FLOAT_TYPE:
33     {
34       gfloat val;
35       gst_props_entry_get_float (prop, &val);
36       printf("Float: %f\n", val);
37       break;
38     }
39     case GST_PROPS_FLOAT_RANGE_TYPE:
40     {
41       gfloat min, max;
42       gst_props_entry_get_float_range (prop, &min, &max);
43       printf("Float range: %f - %f\n", min, max);
44       break;
45     }
46     case GST_PROPS_BOOL_TYPE:
47     {
48       gboolean val;
49       gst_props_entry_get_boolean (prop, &val);
50       printf("Boolean: %s\n", val ? "TRUE" : "FALSE");
51       break;
52     }
53     case GST_PROPS_STRING_TYPE:
54     {
55       const gchar *val;
56       gst_props_entry_get_string (prop, &val);
57       printf("String: %s\n", val);
58       break;
59     }
60     case GST_PROPS_FOURCC_TYPE:
61     {
62       guint32 val;
63       gst_props_entry_get_fourcc_int (prop, &val);
64       printf("FourCC: '%c%c%c%c'\n",
65              (gchar)( val        & 0xff), 
66              (gchar)((val >> 8)  & 0xff),
67              (gchar)((val >> 16) & 0xff), 
68              (gchar)((val >> 24) & 0xff));
69       break;
70     }
71     case GST_PROPS_LIST_TYPE:
72     {
73       const GList *list;
74       gchar *longprefix;
75
76       gst_props_entry_get_list (prop, &list);
77       printf ("List:\n");
78       longprefix = g_strdup_printf ("%s  ", pfx);
79       while (list) {
80         GstPropsEntry *listentry;
81
82         listentry = (GstPropsEntry*) (list->data);
83         print_prop (listentry, FALSE, longprefix);
84
85         list = g_list_next (list);
86       }
87       g_free (longprefix);
88       break;
89     }
90     default:
91       printf("unknown props %d\n", type);
92   }
93 }
94
95 static void 
96 print_props (GstProps *properties, gchar *pfx) 
97 {
98   GList *props;
99   GstPropsEntry *prop;
100
101   props = properties->properties;
102   while (props) {
103     prop = (GstPropsEntry*)(props->data);
104     props = g_list_next(props);
105
106     print_prop(prop,TRUE,pfx);
107   }
108 }
109
110 static void
111 output_hierarchy (GType type, gint level, gint *maxlevel)
112 {
113   GType parent;
114   gint i;
115
116   parent = g_type_parent (type);
117
118   *maxlevel = *maxlevel + 1;
119   level++;
120
121   if (parent)
122     output_hierarchy (parent, level, maxlevel);
123   
124   for (i=1; i<*maxlevel-level; i++)
125    g_print ("      ");
126   if (*maxlevel-level)
127     g_print (" +----");
128
129   g_print ("%s\n", g_type_name (type));
130           
131   if (level == 1)
132     g_print ("\n");
133 }
134
135 static void
136 print_element_properties (GstElement *element) 
137 {
138   GParamSpec **property_specs;
139   gint num_properties,i;
140
141   property_specs = g_object_class_list_properties 
142                      (G_OBJECT_GET_CLASS (element), &num_properties);
143   printf("\nElement Arguments:\n");
144
145   for (i = 0; i < num_properties; i++) {
146     GValue value = { 0, };
147     GParamSpec *param = property_specs[i];
148
149     if (param->flags & G_PARAM_READABLE) {
150       g_value_init (&value, param->value_type);
151       g_object_get_property (G_OBJECT (element), param->name, &value);
152     }
153
154     printf("  %-40.40s: %s\n", g_param_spec_get_name (param),
155                                g_param_spec_get_blurb (param));
156
157     switch (G_VALUE_TYPE (&value)) {
158       case G_TYPE_STRING: 
159         printf ("%-43.43s String (Default \"%s\")", "", g_value_get_string (&value));
160         break;
161       case G_TYPE_BOOLEAN: 
162         printf ("%-43.43s Boolean (Default %s)", "", (g_value_get_boolean (&value) ? "true" : "false"));
163         break;
164       case G_TYPE_ULONG: 
165       {
166         GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
167         printf("%-43.43s Unsigned Long. Range: %lu - %lu (Default %lu)", "", 
168                         pulong->minimum, pulong->maximum, g_value_get_ulong (&value));
169         break;
170       }
171       case G_TYPE_LONG: 
172       {
173         GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
174         printf("%-43.43s Long. Range: %ld - %ld (Default %ld)", "", 
175                         plong->minimum, plong->maximum, g_value_get_long (&value));
176         break;
177       }
178       case G_TYPE_UINT: 
179       {
180         GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
181         printf("%-43.43s Unsigned Integer. Range: %u - %u (Default %u)", "", 
182                         puint->minimum, puint->maximum, g_value_get_uint (&value));
183         break;
184       }
185       case G_TYPE_INT: 
186       {
187         GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
188         printf("%-43.43s Integer. Range: %d - %d (Default %d)", "", 
189                         pint->minimum, pint->maximum, g_value_get_int (&value));
190         break;
191       }
192       case G_TYPE_UINT64: 
193       {
194         GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);
195         printf("%-43.43s Unsigned Integer64. Range: %llu - %llu (Default %llu)", "", 
196                         puint64->minimum, puint64->maximum, g_value_get_uint64 (&value));
197         break;
198       }
199       case G_TYPE_INT64: 
200       {
201         GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);
202         printf("%-43.43s Integer64. Range: %lld - %lld (Default %lld)", "", 
203                         pint64->minimum, pint64->maximum, g_value_get_int64 (&value));
204         break;
205       }
206       case G_TYPE_FLOAT: 
207       {
208         GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
209         printf("%-43.43s Float. Range: %f - %f (Default %f)", "", 
210                         pfloat->minimum, pfloat->maximum, g_value_get_float (&value));
211         break;
212       }
213       case G_TYPE_DOUBLE: 
214       {
215         GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
216         printf("%-43.43s Double. Range: %f - %f (Default %f)", "", 
217                         pdouble->minimum, pdouble->maximum, g_value_get_double (&value));
218         break;
219       }
220       default:
221         if (param->value_type == GST_TYPE_FILENAME)
222           printf("Filename");
223         else if (G_IS_PARAM_SPEC_ENUM (param)) {
224           GEnumValue *values;
225           guint j = 0;
226
227           printf("%-43.43s Enum \"%s\" (default %d)", "", 
228                           g_type_name (G_VALUE_TYPE (&value)),
229                           g_value_get_enum (&value));
230           values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
231
232           while (values[j].value_name) {
233             printf("\n%-43.43s    (%d): \t%s", "", values[j].value, values[j].value_nick);
234             j++; 
235           }
236           /* g_type_class_unref (ec); */
237         }
238         else
239           printf("unknown type %ld \"%s\"", param->value_type, g_type_name(param->value_type));
240         break;
241     }
242     printf("\n");
243   }
244   if (num_properties == 0) 
245     g_print ("  none\n");
246 }
247
248 static gint
249 print_element_info (GstElementFactory *factory)
250 {
251   GstElement *element;
252   GstObjectClass *gstobject_class;
253   GstElementClass *gstelement_class;
254   GList *pads;
255   GstCaps *caps;
256   GstPad *pad;
257   GstRealPad *realpad;
258   GstPadTemplate *padtemplate;
259   GList *children;
260   GstElement *child;
261   gboolean have_flags;
262   gint maxlevel = 0;
263
264   element = gst_element_factory_create(factory,"element");
265   if (!element) {
266     g_print ("couldn't construct element for some reason\n");
267     return -1;
268   }
269
270   gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element));
271   gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
272
273   printf("Factory Details:\n");
274   printf("  Long name:\t%s\n",factory->details->longname);
275   printf("  Class:\t%s\n",factory->details->klass);
276   printf("  Description:\t%s\n",factory->details->description);
277   printf("  Version:\t%s\n",factory->details->version);
278   printf("  Author(s):\t%s\n",factory->details->author);
279   printf("  Copyright:\t%s\n",factory->details->copyright);
280   printf("\n");
281
282   output_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel);
283
284   printf("Pad Templates:\n");
285   if (factory->numpadtemplates) {
286     pads = factory->padtemplates;
287     while (pads) {
288       padtemplate = (GstPadTemplate*)(pads->data);
289       pads = g_list_next(pads);
290
291       if (padtemplate->direction == GST_PAD_SRC)
292         printf("  SRC template: '%s'\n",padtemplate->name_template);
293       else if (padtemplate->direction == GST_PAD_SINK)
294         printf("  SINK template: '%s'\n",padtemplate->name_template);
295       else
296         printf("  UNKNOWN!!! template: '%s'\n",padtemplate->name_template);
297
298       if (padtemplate->presence == GST_PAD_ALWAYS)
299         printf("    Availability: Always\n");
300       else if (padtemplate->presence == GST_PAD_SOMETIMES)
301         printf("    Availability: Sometimes\n");
302       else if (padtemplate->presence == GST_PAD_REQUEST) {
303         printf("    Availability: On request\n");
304         printf("      Has request_new_pad() function: %s\n",
305              GST_DEBUG_FUNCPTR_NAME(gstelement_class->request_new_pad));
306       }
307       else
308         printf("    Availability: UNKNOWN!!!\n");
309
310       if (padtemplate->caps) {
311         printf("    Capabilities:\n");
312         caps = padtemplate->caps;
313         while (caps) {
314           GstType *type;
315
316           printf("      '%s':\n",caps->name);
317
318           type = gst_type_find_by_id (caps->id);
319           if (type) 
320             printf("        MIME type: '%s':\n",type->mime);
321           else
322             printf("        MIME type: 'unknown/unknown':\n");
323
324           if (caps->properties)
325             print_props(caps->properties,"        ");
326
327           caps = caps->next;
328         }
329       }
330
331       printf("\n");
332     }
333   } else
334     printf("  none\n");
335
336   have_flags = FALSE;
337
338   printf("\nElement Flags:\n");
339   if (GST_FLAG_IS_SET(element,GST_ELEMENT_COMPLEX)) {
340     printf("  GST_ELEMENT_COMPLEX\n");
341     have_flags = TRUE;
342   }
343   if (GST_FLAG_IS_SET(element,GST_ELEMENT_DECOUPLED)) {
344     printf("  GST_ELEMENT_DECOUPLED\n");
345     have_flags = TRUE;
346   }
347   if (GST_FLAG_IS_SET(element,GST_ELEMENT_THREAD_SUGGESTED)) {
348     printf("  GST_ELEMENT_THREADSUGGESTED\n");
349     have_flags = TRUE;
350   }
351   if (GST_FLAG_IS_SET(element,GST_ELEMENT_NO_SEEK)) {
352     printf("  GST_ELEMENT_NO_SEEK\n");
353     have_flags = TRUE;
354   }
355   if (!have_flags)
356     printf("  no flags set\n");
357
358   if (GST_IS_BIN (element)) {
359     printf("\nBin Flags:\n");
360     if (GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) {
361       printf("  GST_BIN_FLAG_MANAGER\n");
362       have_flags = TRUE;
363     }
364     if (GST_FLAG_IS_SET(element,GST_BIN_SELF_SCHEDULABLE)) {
365       printf("  GST_BIN_SELF_SCHEDULABLE\n");
366       have_flags = TRUE;
367     }
368     if (GST_FLAG_IS_SET(element,GST_BIN_FLAG_PREFER_COTHREADS)) {
369       printf("  GST_BIN_FLAG_PREFER_COTHREADS\n");
370       have_flags = TRUE;
371     }
372     if (!have_flags)
373       printf("  no flags set\n");
374   }
375
376
377
378   printf("\nElement Implementation:\n");
379
380   if (element->loopfunc)
381     printf("  loopfunc()-based element: %s\n",GST_DEBUG_FUNCPTR_NAME(element->loopfunc));
382   else
383     printf("  No loopfunc(), must be chain-based or not configured yet\n");
384
385   printf("  Has change_state() function: %s\n",
386          GST_DEBUG_FUNCPTR_NAME(gstelement_class->change_state));
387 #ifndef GST_DISABLE_LOADSAVE
388   printf("  Has custom save_thyself() function: %s\n",
389          GST_DEBUG_FUNCPTR_NAME(gstobject_class->save_thyself));
390   printf("  Has custom restore_thyself() function: %s\n",
391          GST_DEBUG_FUNCPTR_NAME(gstobject_class->restore_thyself));
392 #endif
393
394   have_flags = FALSE;
395
396   printf("\nClocking Interaction:\n");
397   if (element->setclockfunc) {
398     printf("  element requires a clock\n");
399     have_flags = TRUE;
400   }
401   if (element->getclockfunc) {
402     GstClock *clock;
403
404     clock = gst_element_get_clock (element);
405     printf("  element provides a clock: %s\n", GST_OBJECT_NAME(clock));
406     have_flags = TRUE;
407   }
408   if (!have_flags) {
409     printf("  none\n");
410   }
411
412
413   printf("\nPads:\n");
414   if (element->numpads) {
415     pads = gst_element_get_pad_list(element);
416     while (pads) {
417       pad = GST_PAD(pads->data);
418       pads = g_list_next(pads);
419       realpad = GST_PAD_REALIZE(pad);
420
421       if (gst_pad_get_direction(pad) == GST_PAD_SRC)
422         printf("  SRC: '%s'",gst_pad_get_name(pad));
423       else if (gst_pad_get_direction(pad) == GST_PAD_SINK)
424         printf("  SINK: '%s'",gst_pad_get_name(pad));
425       else
426         printf("  UNKNOWN!!!: '%s'\n",gst_pad_get_name(pad));
427
428       if (GST_IS_GHOST_PAD(pad))
429         printf(", ghost of real pad %s:%s\n",GST_DEBUG_PAD_NAME(realpad));
430       else
431         printf("\n");
432
433       printf("    Implementation:\n");
434       if (realpad->chainfunc)
435         printf("      Has chainfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->chainfunc));
436       if (realpad->getfunc)
437         printf("      Has getfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getfunc));
438       if (realpad->getregionfunc)
439         printf("      Has getregionfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(realpad->getregionfunc));
440
441       if (pad->padtemplate)
442         printf("    Pad Template: '%s'\n",pad->padtemplate->name_template);
443
444       if (realpad->caps) {
445         printf("    Capabilities:\n");
446         caps = realpad->caps;
447         while (caps) {
448           GstType *type;
449
450           printf("      '%s':\n",caps->name);
451
452           type = gst_type_find_by_id (caps->id);
453           if (type) 
454             printf("        MIME type: '%s':\n",type->mime);
455           else
456             printf("        MIME type: 'unknown/unknown':\n");
457
458           if (caps->properties)
459             print_props(caps->properties,"        ");
460
461           caps = caps->next;
462         }
463       }
464     }
465   } else
466     printf("  none\n");
467
468   print_element_properties (element);
469
470   /* Dynamic Parameters block */
471   {
472     GstDParamManager* dpman;
473     GParamSpec** specs;
474     gint x;
475     
476     printf("\nDynamic Parameters:\n");
477     if((dpman = gst_dpman_get_manager (element))){
478       specs = gst_dpman_list_dparam_specs(dpman);
479       for (x=0; specs[x] != NULL; x++){
480         printf("  %-40.40s: ",g_param_spec_get_name(specs[x]));
481         
482         switch (G_PARAM_SPEC_VALUE_TYPE (specs[x])) {
483           case G_TYPE_INT64: 
484             printf("64 Bit Integer (Default %lld, Range %lld -> %lld)", 
485             ((GParamSpecInt64*)specs[x])->default_value,
486             ((GParamSpecInt64*)specs[x])->minimum, 
487             ((GParamSpecInt64*)specs[x])->maximum);
488             break;
489           case G_TYPE_INT: 
490             printf("Integer (Default %d, Range %d -> %d)", 
491             ((GParamSpecInt*)specs[x])->default_value,
492             ((GParamSpecInt*)specs[x])->minimum, 
493             ((GParamSpecInt*)specs[x])->maximum);
494             break;
495           case G_TYPE_FLOAT: 
496             printf("Float (Default %f, Range %f -> %f)", 
497             ((GParamSpecFloat*)specs[x])->default_value,
498             ((GParamSpecFloat*)specs[x])->minimum, 
499             ((GParamSpecFloat*)specs[x])->maximum);
500             break;
501           default: printf("unknown %ld", G_PARAM_SPEC_VALUE_TYPE (specs[x]));
502         }
503         printf("\n");
504       }
505       g_free(specs);
506     }
507     else {
508       g_print ("  none\n");
509     }
510   }
511
512   /* Signals Block */  
513   {
514     guint *signals;
515     guint nsignals;
516     gint i;
517     GSignalQuery *query;
518
519     printf("\nElement Signals:\n");
520     
521     signals = g_signal_list_ids (G_OBJECT_TYPE (element), &nsignals);
522
523     for (i=0; i<nsignals; i++) {
524       gint n_params;
525       GType return_type;
526       const GType *param_types;
527       gint j;
528       
529       query = g_new0(GSignalQuery,1);
530       g_signal_query (signals[i], query);
531       n_params = query->n_params;
532       return_type = query->return_type;
533       param_types = query->param_types;
534
535       printf ("  \"%s\" :\t %s user_function (%s* object, \n", query->signal_name, g_type_name (return_type),
536                       g_type_name (G_OBJECT_TYPE (element)));
537
538       for (j=0; j<n_params; j++) {
539         printf ("    \t\t\t\t%s arg%d,\n", g_type_name (param_types[j]), j);
540       }
541       printf ("    \t\t\t\tgpointer user_data);\n");
542
543       g_free (query);
544     }
545     if (nsignals == 0) g_print ("  none\n");
546   }
547   
548
549   /* for compound elements */
550   if (GST_IS_BIN(element)) {
551     printf("\nChildren:\n");
552     children = (GList *) gst_bin_get_list(GST_BIN(element));
553     if (!children) 
554       g_print ("  none\n");
555     else {
556       while (children) {
557         child = GST_ELEMENT (children->data);
558         children = g_list_next (children);
559
560         g_print("  %s\n",GST_ELEMENT_NAME(child));
561       }
562     }
563   }
564
565   return 0;
566 }
567
568 static void 
569 print_element_list (void) 
570 {
571   GList *plugins;
572
573   plugins = gst_registry_pool_plugin_list();
574   while (plugins) {
575     GList *features;
576     GstPlugin *plugin;
577     
578     plugin = (GstPlugin*)(plugins->data);
579     plugins = g_list_next (plugins);
580
581     features = gst_plugin_get_feature_list (plugin);
582     while (features) {
583       GstPluginFeature *feature;
584
585       feature = GST_PLUGIN_FEATURE (features->data);
586
587       if (GST_IS_ELEMENT_FACTORY (feature)) {
588         GstElementFactory *factory;
589
590         factory = GST_ELEMENT_FACTORY (feature);
591         printf("%s:  %s: %s\n",plugin->name, GST_PLUGIN_FEATURE_NAME (factory) ,factory->details->longname);
592       }
593       else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
594         GstAutoplugFactory *factory;
595
596         factory = GST_AUTOPLUG_FACTORY (feature);
597         printf("%s:  %s: %s\n", plugin->name, GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
598       }
599       else if (GST_IS_TYPE_FACTORY (feature)) {
600         GstTypeFactory *factory;
601
602         factory = GST_TYPE_FACTORY (feature);
603         printf("%s type:  %s: %s\n", plugin->name, factory->mime, factory->exts);
604
605         if (factory->typefindfunc)
606           printf("      Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc));
607       }
608       else if (GST_IS_SCHEDULER_FACTORY (feature)) {
609         GstSchedulerFactory *factory;
610
611         factory = GST_SCHEDULER_FACTORY (feature);
612         printf("%s:  %s: %s\n", plugin->name, GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
613       }
614       else {
615         printf("%s:  %s (%s)\n", plugin->name, GST_PLUGIN_FEATURE_NAME (feature), 
616                       g_type_name (G_OBJECT_TYPE (feature)));
617       }
618
619       features = g_list_next (features);
620     }
621   }
622 }
623
624 static void
625 print_plugin_info (GstPlugin *plugin)
626 {
627   GList *features;
628   
629   printf("Plugin Details:\n");
630   printf("  Name:\t\t%s\n",plugin->name);
631   printf("  Long Name:\t%s\n",plugin->longname);
632   printf("  Filename:\t%s\n",plugin->filename);
633   printf("\n");
634
635   features = gst_plugin_get_feature_list (plugin);
636
637   while (features) {
638     GstPluginFeature *feature;
639
640     feature = GST_PLUGIN_FEATURE (features->data);
641
642     if (GST_IS_ELEMENT_FACTORY (feature)) {
643       GstElementFactory *factory;
644
645       factory = GST_ELEMENT_FACTORY (feature);
646       printf("  %s: %s\n", GST_OBJECT_NAME (factory) ,factory->details->longname);
647     }
648     else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
649       GstAutoplugFactory *factory;
650
651       factory = GST_AUTOPLUG_FACTORY (feature);
652       printf("  %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
653     }
654     else if (GST_IS_TYPE_FACTORY (feature)) {
655       GstTypeFactory *factory;
656
657       factory = GST_TYPE_FACTORY (feature);
658       printf("  %s: %s\n", factory->mime, factory->exts);
659
660       if (factory->typefindfunc)
661         printf("      Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc));
662     }
663     else if (GST_IS_SCHEDULER_FACTORY (feature)) {
664       GstSchedulerFactory *factory;
665
666       factory = GST_SCHEDULER_FACTORY (feature);
667       printf("  %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
668     }
669     else {
670       printf("  %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)), 
671                       g_type_name (G_OBJECT_TYPE (feature)));
672     }
673
674
675     features = g_list_next (features);
676   }
677   printf("\n");
678 }
679
680
681 int 
682 main (int argc, char *argv[]) 
683 {
684   GstElementFactory *factory;
685   GstPlugin *plugin;
686   gchar *so;
687
688   gst_init(&argc,&argv);
689   gst_control_init(&argc,&argv);
690   
691   /* if no arguments, print out list of elements */
692   if (argc == 1) {
693     print_element_list();
694
695   /* else we try to get a factory */
696   } else {
697     /* first check for help */
698     if (strstr(argv[1],"-help")) {
699       printf("Usage: %s\t\t\tList all registered elements\n",argv[0]);
700       printf("       %s element-name\tShow element details\n",argv[0]);
701       printf("       %s plugin-name[.so]\tShow information about plugin\n",argv[0]);
702       return 0;
703     }
704
705     /* only search for a factory if there's not a '.so' */
706     if (! strstr(argv[1],".so")) {
707       factory = gst_element_factory_find (argv[1]);
708
709       /* if there's a factory, print out the info */
710       if (factory)
711         return print_element_info(factory);
712     } else {
713       /* strip the .so */
714       so = strstr(argv[1],".so");
715       so[0] = '\0';
716     }
717
718     /* otherwise assume it's a plugin */
719     plugin = gst_registry_pool_find_plugin (argv[1]);
720
721     /* if there is such a plugin, print out info */
722
723     if (plugin) {
724       print_plugin_info(plugin);
725
726     } else {
727       printf("no such element or plugin '%s'\n",argv[1]);
728       return -1;
729     }
730   }
731
732   return 0;
733 }