tools/: Fix up includes: need to include stdlib.h in tools.h for exit().
[platform/upstream/gstreamer.git] / tools / gst-inspect.c
index b9a7853..32fbe7d 100644 (file)
-#include <gst/gst.h>
-#include <gst/control/control.h>
-#include <string.h>
-
-static void 
-print_prop (GstPropsEntry *prop, gboolean showname, const gchar *pfx) 
-{
-  GstPropsType type;
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000 Wim Taymans <wtay@chello.be>
+ *               2004 Thomas Vander Stichele <thomas@apestaart.org>
+ *
+ * gst-inspect.c: tool to inspect the GStreamer registry
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
 
-  if (showname)
-    g_print("%s%-20.20s: ", pfx, gst_props_entry_get_name (prop));
-  else
-    g_print(pfx);
+#include <gst/controller/gstcontroller.h>
 
-  type = gst_props_entry_get_type (prop);
+#include "tools.h"
 
-  switch (type) {
-    case GST_PROPS_INT_TYPE:
-    {
-      gint val;
-      gst_props_entry_get_int (prop, &val);
-      g_print("Integer: %d\n", val);
-      break;
-    }
-    case GST_PROPS_INT_RANGE_TYPE:
-    {
-      gint min, max;
-      gst_props_entry_get_int_range (prop, &min, &max);
-      g_print("Integer range: %d - %d\n", min, max);
-      break;
-    }
-    case GST_PROPS_FLOAT_TYPE:
-    {
-      gfloat val;
-      gst_props_entry_get_float (prop, &val);
-      g_print("Float: %f\n", val);
-      break;
-    }
-    case GST_PROPS_FLOAT_RANGE_TYPE:
-    {
-      gfloat min, max;
-      gst_props_entry_get_float_range (prop, &min, &max);
-      g_print("Float range: %f - %f\n", min, max);
-      break;
-    }
-    case GST_PROPS_BOOLEAN_TYPE:
-    {
-      gboolean val;
-      gst_props_entry_get_boolean (prop, &val);
-      g_print("Boolean: %s\n", val ? "TRUE" : "FALSE");
-      break;
-    }
-    case GST_PROPS_STRING_TYPE:
-    {
-      const gchar *val;
-      gst_props_entry_get_string (prop, &val);
-      g_print("String: \"%s\"\n", val);
-      break;
-    }
-    case GST_PROPS_FOURCC_TYPE:
-    {
-      guint32 val;
-      gst_props_entry_get_fourcc_int (prop, &val);
-      g_print("FourCC: '%c%c%c%c'\n",
-             (gchar)( val        & 0xff), 
-            (gchar)((val >> 8)  & 0xff),
-             (gchar)((val >> 16) & 0xff), 
-            (gchar)((val >> 24) & 0xff));
-      break;
-    }
-    case GST_PROPS_LIST_TYPE:
-    {
-      const GList *list;
-      gchar *longprefix;
-
-      gst_props_entry_get_list (prop, &list);
-      g_print ("List:\n");
-      longprefix = g_strdup_printf ("%s ", pfx);
-      while (list) {
-        GstPropsEntry *listentry;
+#include <string.h>
+#include <locale.h>
+#include <glib/gprintf.h>
 
-        listentry = (GstPropsEntry*) (list->data);
-        print_prop (listentry, FALSE, longprefix);
+static char *_name;
 
-        list = g_list_next (list);
-      }
-      g_free (longprefix);
-      break;
-    }
-    default:
-      g_print("unknown props %d\n", type);
-  }
-}
+static int print_element_info (GstElementFactory * factory,
+    gboolean print_names);
 
-static void 
-print_props (GstProps *properties, const gchar *pfx) 
+void
+n_print (const char *format, ...)
 {
-  GList *props;
-  GstPropsEntry *prop;
+  va_list args;
+  gint retval;
 
-  props = properties->properties;
-  while (props) {
-    prop = (GstPropsEntry*)(props->data);
-    props = g_list_next(props);
+  if (_name)
+    g_print (_name);
 
-    print_prop(prop,TRUE,pfx);
-  }
+  va_start (args, format);
+  retval = g_vprintf (format, args);
+  va_end (args);
 }
 
-static void 
-print_caps (const GstCaps *caps, const gchar *pfx) 
+static gboolean
+print_field (GQuark field, const GValue * value, gpointer pfx)
 {
-  while (caps) {
-    GstType *type;
+  gchar *str = gst_value_serialize (value);
 
-    g_print ("%s'%s': (%sfixed)\n", pfx, caps->name, (caps->fixed ? "" : "NOT "));
+  n_print ("%s  %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);
+  g_free (str);
+  return TRUE;
+}
 
-    type = gst_type_find_by_id (caps->id);
-    if (type) 
-      g_print ("%s  MIME type: '%s':\n", pfx, type->mime);
-    else
-      g_print ("%s  MIME type: 'unknown/unknown':\n", pfx);
+static void
+print_caps (const GstCaps * caps, const gchar * pfx)
+{
+  guint i;
 
-    if (caps->properties) {
-      gchar *prefix = g_strdup_printf ("%s  ", pfx);
+  g_return_if_fail (caps != NULL);
 
-      print_props(caps->properties, prefix);
+  if (gst_caps_is_any (caps)) {
+    n_print ("%sANY\n", pfx);
+    return;
+  }
+  if (gst_caps_is_empty (caps)) {
+    n_print ("%sEMPTY\n", pfx);
+    return;
+  }
 
-      g_free (prefix);
-    }
+  for (i = 0; i < gst_caps_get_size (caps); i++) {
+    GstStructure *structure = gst_caps_get_structure (caps, i);
 
-    caps = caps->next;
+    n_print ("%s%s\n", pfx, gst_structure_get_name (structure));
+    gst_structure_foreach (structure, print_field, (gpointer) pfx);
   }
 }
 
-static void 
-print_formats (const GstFormat *formats) 
+#if 0
+static void
+print_formats (const GstFormat * formats)
 {
   while (formats && *formats) {
     const GstFormatDefinition *definition;
 
     definition = gst_format_get_details (*formats);
     if (definition)
-      g_print ("\t\t(%d):\t%s (%s)\n", *formats,
-              definition->nick, definition->description);
+      n_print ("\t\t(%d):\t%s (%s)\n", *formats,
+          definition->nick, definition->description);
     else
-      g_print ("\t\t(%d):\tUnknown format\n", *formats);
+      n_print ("\t\t(%d):\tUnknown format\n", *formats);
 
     formats++;
   }
 }
+#endif
 
-static void 
-print_query_types (const GstQueryType *types) 
+static void
+print_query_types (const GstQueryType * types)
 {
   while (types && *types) {
     const GstQueryTypeDefinition *definition;
 
     definition = gst_query_type_get_details (*types);
     if (definition)
-      g_print ("\t\t(%d):\t%s (%s)\n", *types,
-              definition->nick, definition->description);
+      n_print ("\t\t(%d):\t%s (%s)\n", *types,
+          definition->nick, definition->description);
     else
-      g_print ("\t\t(%d):\tUnknown query format\n", *types);
+      n_print ("\t\t(%d):\tUnknown query format\n", *types);
 
     types++;
   }
 }
 
-static void 
-print_event_masks (const GstEventMask *masks) 
+#ifndef GST_DISABLE_ENUMTYPES
+#if 0
+static void
+print_event_masks (const GstEventMask * masks)
 {
   GType event_type;
   GEnumClass *klass;
   GType event_flags;
   GFlagsClass *flags_class = NULL;
 
-  event_type = gst_event_type_get_type();
+  event_type = gst_event_type_get_type ();
   klass = (GEnumClass *) g_type_class_ref (event_type);
 
   while (masks && masks->type) {
@@ -185,13 +142,13 @@ print_event_masks (const GstEventMask *masks)
     switch (masks->type) {
       case GST_EVENT_SEEK:
         flags = masks->flags;
-       event_flags = gst_seek_type_get_type ();
-       flags_class = (GFlagsClass *) g_type_class_ref (event_flags);
+        event_flags = gst_seek_type_get_type ();
+        flags_class = (GFlagsClass *) g_type_class_ref (event_flags);
         break;
       default:
         break;
     }
-    
+
     value = g_enum_get_value (klass, masks->type);
     g_print ("\t\t%s ", value->value_nick);
 
@@ -201,22 +158,60 @@ print_event_masks (const GstEventMask *masks)
       if (flags & 1) {
         value = g_flags_get_first_value (flags_class, 1 << index);
 
-       if (value)
+        if (value)
           g_print ("| %s ", value->value_nick);
-       else
+        else
           g_print ("| ? ");
       }
       flags >>= 1;
       index++;
     }
     g_print ("\n");
-    
+
     masks++;
   }
 }
+#endif
+#else
+static void
+print_event_masks (const GstEventMask * masks)
+{
+}
+#endif
+
+static char *
+get_rank_name (gint rank)
+{
+  switch (rank) {
+    case GST_RANK_NONE:
+      return "none";
+    case GST_RANK_MARGINAL:
+      return "marginal";
+    case GST_RANK_SECONDARY:
+      return "secondary";
+    case GST_RANK_PRIMARY:
+      return "primary";
+    default:
+      return "unknown";
+  }
+}
 
 static void
-output_hierarchy (GType type, gint level, gint *maxlevel)
+print_factory_details_info (GstElementFactory * factory)
+{
+  n_print ("Factory Details:\n");
+  n_print ("  Long name:\t%s\n", factory->details.longname);
+  n_print ("  Class:\t%s\n", factory->details.klass);
+  n_print ("  Description:\t%s\n", factory->details.description);
+  n_print ("  Author(s):\t%s\n", factory->details.author);
+  n_print ("  Rank:\t\t%s (%d)\n",
+      get_rank_name (GST_PLUGIN_FEATURE (factory)->rank),
+      GST_PLUGIN_FEATURE (factory)->rank);
+  n_print ("\n");
+}
+
+static void
+print_hierarchy (GType type, gint level, gint * maxlevel)
 {
   GType parent;
   gint i;
@@ -227,648 +222,731 @@ output_hierarchy (GType type, gint level, gint *maxlevel)
   level++;
 
   if (parent)
-    output_hierarchy (parent, level, maxlevel);
-  
-  for (i=1; i<*maxlevel-level; i++)
-   g_print ("      ");
-  if (*maxlevel-level)
+    print_hierarchy (parent, level, maxlevel);
+
+  if (_name)
+    g_print (_name);
+
+  for (i = 1; i < *maxlevel - level; i++)
+    g_print ("      ");
+  if (*maxlevel - level)
     g_print (" +----");
 
   g_print ("%s\n", g_type_name (type));
-         
+
   if (level == 1)
-    g_print ("\n");
+    n_print ("\n");
 }
 
 static void
-print_element_properties (GstElement *element) 
+print_interfaces (GType type)
+{
+  guint n_ifaces;
+  GType *iface, *ifaces = g_type_interfaces (type, &n_ifaces);
+
+  if (ifaces) {
+    if (n_ifaces) {
+      g_print ("%sImplemented Interfaces:\n", _name);
+      iface = ifaces;
+      while (*iface) {
+        g_print ("%s  %s\n", _name, g_type_name (*iface));
+        iface++;
+      }
+      g_print ("%s\n", _name);
+      g_free (ifaces);
+    }
+  }
+}
+
+static void
+print_element_properties_info (GstElement * element)
 {
   GParamSpec **property_specs;
-  gint num_properties,i;
+  guint num_properties, i;
   gboolean readable;
-  
+  gboolean first_flag;
 
-  property_specs = g_object_class_list_properties 
-                    (G_OBJECT_GET_CLASS (element), &num_properties);
-  g_print("\nElement Arguments:\n");
+  property_specs = g_object_class_list_properties
+      (G_OBJECT_GET_CLASS (element), &num_properties);
+  n_print ("\n");
+  n_print ("Element Properties:\n");
 
   for (i = 0; i < num_properties; i++) {
     GValue value = { 0, };
     GParamSpec *param = property_specs[i];
+
     readable = FALSE;
 
     g_value_init (&value, param->value_type);
+
+    n_print ("  %-20s: %s\n", g_param_spec_get_name (param),
+        g_param_spec_get_blurb (param));
+
+    first_flag = TRUE;
+    n_print ("%-23.23s flags: ", "");
     if (param->flags & G_PARAM_READABLE) {
       g_object_get_property (G_OBJECT (element), param->name, &value);
       readable = TRUE;
+      g_print ((first_flag ? "readable" : ", readable"));
+      first_flag = FALSE;
     }
-
-    g_print("  %-20s: %s\n", g_param_spec_get_name (param),
-                              g_param_spec_get_blurb (param));
+    if (param->flags & G_PARAM_WRITABLE) {
+      g_print ((first_flag ? "writable" : ", writable"));
+      first_flag = FALSE;
+    }
+    if (param->flags & GST_PARAM_CONTROLLABLE) {
+      g_print ((first_flag ? "controllable" : ", controllable"));
+      first_flag = FALSE;
+    }
+    n_print ("\n");
 
     switch (G_VALUE_TYPE (&value)) {
-      case G_TYPE_STRING: 
-       g_print ("%-23.23s String. ", "");
-       if (readable) g_print ("(Default \"%s\")", g_value_get_string (&value));
-       break;
-      case G_TYPE_BOOLEAN: 
-       g_print ("%-23.23s Boolean. ", "");
-       if (readable) g_print ("(Default %s)", (g_value_get_boolean (&value) ? "true" : "false"));
-       break;
-      case G_TYPE_ULONG: 
+      case G_TYPE_STRING:
+      {
+        GParamSpecString *pstring = G_PARAM_SPEC_STRING (param);
+
+        n_print ("%-23.23s String. ", "");
+
+        if (pstring->default_value == NULL)
+          g_print ("Default: null ");
+        else
+          g_print ("Default: \"%s\" ", pstring->default_value);
+
+        if (readable) {
+          const char *string_val = g_value_get_string (&value);
+
+          if (string_val == NULL)
+            g_print ("Current: null");
+          else
+            g_print ("Current: \"%s\"", string_val);
+        }
+        break;
+      }
+      case G_TYPE_BOOLEAN:
+      {
+        GParamSpecBoolean *pboolean = G_PARAM_SPEC_BOOLEAN (param);
+
+        n_print ("%-23.23s Boolean. ", "");
+        g_print ("Default: %s ", (pboolean->default_value ? "true" : "false"));
+        if (readable)
+          g_print ("Current: %s",
+              (g_value_get_boolean (&value) ? "true" : "false"));
+        break;
+      }
+      case G_TYPE_ULONG:
       {
-       GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
-       g_print("%-23.23s Unsigned Long. ", ""); 
-       if (readable) g_print("Range: %lu - %lu (Default %lu)",  
-                       pulong->minimum, pulong->maximum, g_value_get_ulong (&value));
-       break;
+        GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
+
+        n_print ("%-23.23s Unsigned Long. ", "");
+        g_print ("Range: %lu - %lu Default: %lu ",
+            pulong->minimum, pulong->maximum, pulong->default_value);
+        if (readable)
+          g_print ("Current: %lu", g_value_get_ulong (&value));
+        break;
       }
-      case G_TYPE_LONG: 
+      case G_TYPE_LONG:
       {
-       GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
-       g_print("%-23.23s Long. ", ""); 
-       if (readable) g_print("Range: %ld - %ld (Default %ld)",  
-                       plong->minimum, plong->maximum, g_value_get_long (&value));
-       break;
+        GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
+
+        n_print ("%-23.23s Long. ", "");
+        g_print ("Range: %ld - %ld Default: %ld ",
+            plong->minimum, plong->maximum, plong->default_value);
+        if (readable)
+          g_print ("Current: %ld", g_value_get_long (&value));
+        break;
       }
-      case G_TYPE_UINT: 
+      case G_TYPE_UINT:
       {
-       GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
-       g_print("%-23.23s Unsigned Integer. ", "");
-       if (readable) g_print("Range: %u - %u (Default %u)",  
-                       puint->minimum, puint->maximum, g_value_get_uint (&value));
-       break;
+        GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
+
+        n_print ("%-23.23s Unsigned Integer. ", "");
+        g_print ("Range: %u - %u Default: %u ",
+            puint->minimum, puint->maximum, puint->default_value);
+        if (readable)
+          g_print ("Current: %u", g_value_get_uint (&value));
+        break;
       }
-      case G_TYPE_INT: 
+      case G_TYPE_INT:
       {
-       GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
-       g_print("%-23.23s Integer. ", ""); 
-       if (readable) g_print("Range: %d - %d (Default %d)", 
-                       pint->minimum, pint->maximum, g_value_get_int (&value));
-       break;
+        GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
+
+        n_print ("%-23.23s Integer. ", "");
+        g_print ("Range: %d - %d Default: %d ",
+            pint->minimum, pint->maximum, pint->default_value);
+        if (readable)
+          g_print ("Current: %d", g_value_get_int (&value));
+        break;
       }
-      case G_TYPE_UINT64: 
+      case G_TYPE_UINT64:
       {
-       GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);
-       g_print("%-23.23s Unsigned Integer64. ", ""); 
-       if (readable) g_print("Range: %llu - %llu (Default %llu)", 
-                       puint64->minimum, puint64->maximum, g_value_get_uint64 (&value));
-       break;
+        GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);
+
+        n_print ("%-23.23s Unsigned Integer64. ", "");
+        g_print ("Range: %" G_GUINT64_FORMAT " - %" G_GUINT64_FORMAT
+            " Default: %" G_GUINT64_FORMAT " ",
+            puint64->minimum, puint64->maximum, puint64->default_value);
+        if (readable)
+          g_print ("Current: %" G_GUINT64_FORMAT, g_value_get_uint64 (&value));
+        break;
       }
-      case G_TYPE_INT64: 
+      case G_TYPE_INT64:
       {
-       GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);
-       g_print("%-23.23s Integer64. ", ""); 
-       if (readable) g_print("Range: %lld - %lld (Default %lld)", 
-                       pint64->minimum, pint64->maximum, g_value_get_int64 (&value));
-       break;
+        GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);
+
+        n_print ("%-23.23s Integer64. ", "");
+        g_print ("Range: %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
+            " Default: %" G_GINT64_FORMAT " ",
+            pint64->minimum, pint64->maximum, pint64->default_value);
+        if (readable)
+          g_print ("Current: %" G_GINT64_FORMAT, g_value_get_int64 (&value));
+        break;
       }
-      case G_TYPE_FLOAT: 
+      case G_TYPE_FLOAT:
       {
-       GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
-       g_print("%-23.23s Float. Default: %-8.8s %15.7g\n", "", "", 
-               g_value_get_float (&value));
-       g_print("%-23.23s Range: %15.7g - %15.7g", "", 
-              pfloat->minimum, pfloat->maximum);
-       break;
+        GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
+
+        n_print ("%-23.23s Float. ", "");
+        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
+            pfloat->minimum, pfloat->maximum, pfloat->default_value);
+        if (readable)
+          g_print ("Current: %15.7g", g_value_get_float (&value));
+        break;
       }
-      case G_TYPE_DOUBLE: 
+      case G_TYPE_DOUBLE:
       {
-       GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
-       g_print("%-23.23s Double. Default: %-8.8s %15.7g\n", "", "", 
-               g_value_get_double (&value));
-       g_print("%-23.23s Range: %15.7g - %15.7g", "", 
-              pdouble->minimum, pdouble->maximum);
-       break;
+        GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
+
+        n_print ("%-23.23s Double. ", "");
+        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
+            pdouble->minimum, pdouble->maximum, pdouble->default_value);
+        if (readable)
+          g_print ("Current: %15.7g", g_value_get_double (&value));
+        break;
       }
       default:
-        if (param->value_type == GST_TYPE_FILENAME) {
-          g_print("%-23.23s Filename", "");
-       }
         if (param->value_type == GST_TYPE_CAPS) {
-          GstCaps *caps = g_value_peek_pointer (&value);
+          const GstCaps *caps = gst_value_get_caps (&value);
 
-         if (!caps) 
-            g_print("%-23.23s Caps (NULL)", "");
-         else {
+          if (!caps)
+            n_print ("%-23.23s Caps (NULL)", "");
+          else {
             print_caps (caps, "                           ");
-         }
-       }
-        else if (G_IS_PARAM_SPEC_ENUM (param)) {
+          }
+        } else if (G_IS_PARAM_SPEC_ENUM (param)) {
           GEnumValue *values;
-         guint j = 0;
-         gint enum_value;
-
-         values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
-         enum_value = g_value_get_enum (&value);
-
-         while (values[j].value_name) {
-           if (values[j].value == enum_value)
-             break;
-           j++; 
-         }
-
-          g_print ("%-23.23s Enum \"%s\" (default %d, \"%s\")", "", 
-                         g_type_name (G_VALUE_TYPE (&value)),
-                         enum_value, values[j].value_nick);
-
-         j = 0;
-         while (values[j].value_name) {
-            g_print("\n%-23.23s    (%d): \t%s", "", 
-                           values[j].value, values[j].value_nick);
-           j++; 
-         }
-         /* g_type_class_unref (ec); */
-       }
-        else if (G_IS_PARAM_SPEC_FLAGS (param)) {
+          guint j = 0;
+          gint enum_value;
+
+          values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
+          enum_value = g_value_get_enum (&value);
+
+          while (values[j].value_name) {
+            if (values[j].value == enum_value)
+              break;
+            j++;
+          }
+
+          n_print ("%-23.23s Enum \"%s\" Current: %d, \"%s\"", "",
+              g_type_name (G_VALUE_TYPE (&value)),
+              enum_value, values[j].value_nick);
+
+          j = 0;
+          while (values[j].value_name) {
+            g_print ("\n%s%-23.23s    %d) %-16s - %s", "",
+                _name, values[j].value, values[j].value_nick,
+                values[j].value_name);
+            j++;
+          }
+          /* g_type_class_unref (ec); */
+        else if (G_IS_PARAM_SPEC_FLAGS (param)) {
           GFlagsValue *values;
-         guint j = 0;
-         gint flags_value;
-         GString *flags = NULL;
-
-         values = G_FLAGS_CLASS (g_type_class_ref (param->value_type))->values;
-         flags_value = g_value_get_flags (&value);
-
-         while (values[j].value_name) {
-           if (values[j].value & flags_value) {
-             if (flags) {
-               g_string_append_printf (flags, " | %s", values[j].value_nick);
-             }
-             else {
-               flags = g_string_new (values[j].value_nick);
-             }
-           }
-           j++;
-         }
-
-          g_print ("%-23.23s Flags \"%s\" (default %d, \"%s\")", "", 
-                         g_type_name (G_VALUE_TYPE (&value)),
-                         flags_value, (flags ? flags->str : "(none)"));
-
-         j = 0;
-         while (values[j].value_name) {
-            g_print("\n%-23.23s    (%d): \t%s", "", 
-                           values[j].value, values[j].value_nick);
-           j++; 
-         }
-
-         if (flags)
-           g_string_free (flags, TRUE);
-       }
-       else if (G_IS_PARAM_SPEC_OBJECT (param)) {
-         g_print("%-23.23s Object of type \"%s\"", "",
-                         g_type_name(param->value_type));
+          guint j = 0;
+          gint flags_value;
+          GString *flags = NULL;
+
+          values = G_FLAGS_CLASS (g_type_class_ref (param->value_type))->values;
+          flags_value = g_value_get_flags (&value);
+
+          while (values[j].value_name) {
+            if (values[j].value & flags_value) {
+              if (flags) {
+                g_string_append_printf (flags, " | %s", values[j].value_nick);
+              } else {
+                flags = g_string_new (values[j].value_nick);
+              }
+            }
+            j++;
+          }
+
+          n_print ("%-23.23s Flags \"%s\" Current: %d, \"%s\"", "",
+              g_type_name (G_VALUE_TYPE (&value)),
+              flags_value, (flags ? flags->str : "(none)"));
+
+          j = 0;
+          while (values[j].value_name) {
+            g_print ("\n%s%-23.23s    (%d): \t%s", "",
+                _name, values[j].value, values[j].value_nick);
+            j++;
+          }
+
+          if (flags)
+            g_string_free (flags, TRUE);
+        } else if (G_IS_PARAM_SPEC_OBJECT (param)) {
+          n_print ("%-23.23s Object of type \"%s\"", "",
+              g_type_name (param->value_type));
+        } else if (G_IS_PARAM_SPEC_BOXED (param)) {
+          n_print ("%-23.23s Boxed pointer of type \"%s\"", "",
+              g_type_name (param->value_type));
+        } else if (G_IS_PARAM_SPEC_POINTER (param)) {
+          if (param->value_type != G_TYPE_POINTER) {
+            n_print ("%-23.23s Pointer of type \"%s\".", "",
+                g_type_name (param->value_type));
+          } else {
+            n_print ("%-23.23s Pointer.", "");
+          }
+        } else {
+          n_print ("%-23.23s Unknown type %ld \"%s\"", "", param->value_type,
+              g_type_name (param->value_type));
         }
-       else {
-          g_print ("%-23.23s Unknown type %ld \"%s\"", "",param->value_type, 
-                       g_type_name(param->value_type));
-       }
         break;
     }
-    if (!readable) 
-      g_print ("Write only\n");
-    else 
+    if (!readable)
+      g_print (" Write only\n");
+    else
       g_print ("\n");
   }
-  if (num_properties == 0) 
-    g_print ("  none\n");
+  if (num_properties == 0)
+    n_print ("  none\n");
+
+  g_free (property_specs);
 }
 
-static gint
-print_element_info (GstElementFactory *factory)
+static void
+print_pad_templates_info (GstElement * element, GstElementFactory * factory)
 {
-  GstElement *element;
-  GstObjectClass *gstobject_class;
   GstElementClass *gstelement_class;
-  GList *pads;
-  GstPad *pad;
-  GstRealPad *realpad;
-  GstPadTemplate *padtemplate;
-  GList *children;
-  GstElement *child;
-  gboolean have_flags;
-  gint maxlevel = 0;
+  const GList *pads;
+  GstStaticPadTemplate *padtemplate;
 
-  element = gst_element_factory_create (factory, "element");
-  if (!element) {
-    g_print ("couldn't construct element for some reason\n");
-    return -1;
+  n_print ("Pad Templates:\n");
+  if (!factory->numpadtemplates) {
+    n_print ("  none\n");
+    return;
   }
 
-  gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element));
   gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
 
-  g_print ("Factory Details:\n");
-  g_print ("  Long name:\t%s\n",   factory->details->longname);
-  g_print ("  Class:\t%s\n",       factory->details->klass);
-  g_print ("  License:\t%s\n",     factory->details->license);
-  g_print ("  Description:\t%s\n", factory->details->description);
-  g_print ("  Version:\t%s\n",     factory->details->version);
-  g_print ("  Author(s):\t%s\n",   factory->details->author);
-  g_print ("  Copyright:\t%s\n",   factory->details->copyright);
-  g_print ("\n");
-
-  output_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel);
-
-  g_print ("Pad Templates:\n");
-  if (factory->numpadtemplates) {
-    pads = factory->padtemplates;
-    while (pads) {
-      padtemplate = (GstPadTemplate*)(pads->data);
-      pads = g_list_next(pads);
-
-      if (padtemplate->direction == GST_PAD_SRC)
-        g_print ("  SRC template: '%s'\n", padtemplate->name_template);
-      else if (padtemplate->direction == GST_PAD_SINK)
-        g_print ("  SINK template: '%s'\n", padtemplate->name_template);
-      else
-        g_print ("  UNKNOWN!!! template: '%s'\n", padtemplate->name_template);
-
-      if (padtemplate->presence == GST_PAD_ALWAYS)
-        g_print ("    Availability: Always\n");
-      else if (padtemplate->presence == GST_PAD_SOMETIMES)
-        g_print ("    Availability: Sometimes\n");
-      else if (padtemplate->presence == GST_PAD_REQUEST) {
-        g_print ("    Availability: On request\n");
-        g_print ("      Has request_new_pad() function: %s\n",
-                GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad));
-      }
-      else
-        g_print ("    Availability: UNKNOWN!!!\n");
-
-      if (padtemplate->caps) {
-        g_print ("    Capabilities:\n");
-       print_caps (padtemplate->caps, "      ");
-      }
+  pads = factory->staticpadtemplates;
+  while (pads) {
+    padtemplate = (GstStaticPadTemplate *) (pads->data);
+    pads = g_list_next (pads);
 
-      g_print ("\n");
+    if (padtemplate->direction == GST_PAD_SRC)
+      n_print ("  SRC template: '%s'\n", padtemplate->name_template);
+    else if (padtemplate->direction == GST_PAD_SINK)
+      n_print ("  SINK template: '%s'\n", padtemplate->name_template);
+    else
+      n_print ("  UNKNOWN!!! template: '%s'\n", padtemplate->name_template);
+
+    if (padtemplate->presence == GST_PAD_ALWAYS)
+      n_print ("    Availability: Always\n");
+    else if (padtemplate->presence == GST_PAD_SOMETIMES)
+      n_print ("    Availability: Sometimes\n");
+    else if (padtemplate->presence == GST_PAD_REQUEST) {
+      n_print ("    Availability: On request\n");
+      n_print ("      Has request_new_pad() function: %s\n",
+          GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad));
+    } else
+      n_print ("    Availability: UNKNOWN!!!\n");
+
+    if (padtemplate->static_caps.string) {
+      n_print ("    Capabilities:\n");
+      print_caps (gst_static_caps_get (&padtemplate->static_caps), "      ");
     }
-  } else
-    g_print ("  none\n");
 
-  have_flags = FALSE;
-
-  g_print ("\nElement Flags:\n");
-  if (GST_FLAG_IS_SET (element, GST_ELEMENT_COMPLEX)) {
-    g_print ("  GST_ELEMENT_COMPLEX\n");
-    have_flags = TRUE;
-  }
-  if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) {
-    g_print ("  GST_ELEMENT_DECOUPLED\n");
-    have_flags = TRUE;
-  }
-  if (GST_FLAG_IS_SET (element, GST_ELEMENT_THREAD_SUGGESTED)) {
-    g_print ("  GST_ELEMENT_THREADSUGGESTED\n");
-    have_flags = TRUE;
-  }
-  if (GST_FLAG_IS_SET (element, GST_ELEMENT_EVENT_AWARE)) {
-    g_print("  GST_ELEMENT_EVENT_AWARE\n");
-    have_flags = TRUE;
+    n_print ("\n");
   }
+}
+
+static void
+print_element_flag_info (GstElement * element)
+{
+  gboolean have_flags = FALSE;
+
+  n_print ("\n");
+  n_print ("Element Flags:\n");
+
   if (!have_flags)
-    g_print("  no flags set\n");
+    n_print ("  no flags set\n");
 
   if (GST_IS_BIN (element)) {
-    g_print ("\nBin Flags:\n");
-    if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
-      g_print ("  GST_BIN_FLAG_MANAGER\n");
-      have_flags = TRUE;
-    }
-    if (GST_FLAG_IS_SET (element, GST_BIN_SELF_SCHEDULABLE)) {
-      g_print ("  GST_BIN_SELF_SCHEDULABLE\n");
-      have_flags = TRUE;
-    }
-    if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_PREFER_COTHREADS)) {
-      g_print ("  GST_BIN_FLAG_PREFER_COTHREADS\n");
-      have_flags = TRUE;
-    }
+    n_print ("\n");
+    n_print ("Bin Flags:\n");
     if (!have_flags)
-      g_print ("  no flags set\n");
+      n_print ("  no flags set\n");
   }
+}
 
+static void
+print_implementation_info (GstElement * element)
+{
+  GstObjectClass *gstobject_class;
+  GstElementClass *gstelement_class;
 
+  gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element));
+  gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
 
-  g_print ("\nElement Implementation:\n");
+  n_print ("\n");
+  n_print ("Element Implementation:\n");
 
-  if (element->loopfunc)
-    g_print ("  loopfunc()-based element: %s\n",
-           GST_DEBUG_FUNCPTR_NAME (element->loopfunc));
-  else
-    g_print ("  No loopfunc(), must be chain-based or not configured yet\n");
+  n_print ("  No loopfunc(), must be chain-based or not configured yet\n");
 
-  g_print ("  Has change_state() function: %s\n",
-          GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state));
+  n_print ("  Has change_state() function: %s\n",
+      GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state));
 #ifndef GST_DISABLE_LOADSAVE
-  g_print ("  Has custom save_thyself() function: %s\n",
-          GST_DEBUG_FUNCPTR_NAME (gstobject_class->save_thyself));
-  g_print ("  Has custom restore_thyself() function: %s\n",
-          GST_DEBUG_FUNCPTR_NAME (gstobject_class->restore_thyself));
+  n_print ("  Has custom save_thyself() function: %s\n",
+      GST_DEBUG_FUNCPTR_NAME (gstobject_class->save_thyself));
+  n_print ("  Has custom restore_thyself() function: %s\n",
+      GST_DEBUG_FUNCPTR_NAME (gstobject_class->restore_thyself));
 #endif
+}
 
-  have_flags = FALSE;
+static void
+print_clocking_info (GstElement * element)
+{
+  if (!gst_element_requires_clock (element) &&
+      !(gst_element_provides_clock (element) &&
+          gst_element_get_clock (element))) {
+    n_print ("\n");
+    n_print ("Element has no clocking capabilities.");
+    return;
+  }
 
-  g_print ("\nClocking Interaction:\n");
+  n_print ("\n");
+  n_print ("Clocking Interaction:\n");
   if (gst_element_requires_clock (element)) {
-    g_print ("  element requires a clock\n");
-    have_flags = TRUE;
+    n_print ("  element requires a clock\n");
   }
+
   if (gst_element_provides_clock (element)) {
     GstClock *clock;
 
     clock = gst_element_get_clock (element);
     if (clock)
-      g_print ("  element provides a clock: %s\n", GST_OBJECT_NAME(clock));
+      n_print ("  element provides a clock: %s\n", GST_OBJECT_NAME (clock));
     else
-      g_print ("  element is supposed to provide a clock but returned NULL\n");
-    have_flags = TRUE;
-  }
-  if (!have_flags) {
-    g_print ("  none\n");
+      n_print ("  element is supposed to provide a clock but returned NULL\n");
   }
+}
 
-  g_print ("\nIndexing capabilities:\n");
+#ifndef GST_DISABLE_INDEX
+static void
+print_index_info (GstElement * element)
+{
   if (gst_element_is_indexable (element)) {
-    g_print ("  element can do indexing\n");
-  }
-  else {
-    g_print ("  none\n");
+    n_print ("\n");
+    n_print ("Indexing capabilities:\n");
+    n_print ("  element can do indexing\n");
+  } else {
+    n_print ("\n");
+    n_print ("Element has no indexing capabilities.\n");
   }
+}
+#else
+static void
+print_index_info (GstElement * element)
+{
+}
+#endif
 
-  g_print ("\nPads:\n");
-  if (element->numpads) {
-    const GList *pads;
-    pads = gst_element_get_pad_list (element);
-    while (pads) {
-      pad = GST_PAD (pads->data);
-      pads = g_list_next (pads);
-      realpad = GST_PAD_REALIZE (pad);
-
-      if (gst_pad_get_direction (pad) == GST_PAD_SRC)
-        g_print ("  SRC: '%s'", gst_pad_get_name (pad));
-      else if (gst_pad_get_direction (pad) == GST_PAD_SINK)
-        g_print ("  SINK: '%s'", gst_pad_get_name (pad));
-      else
-        g_print ("  UNKNOWN!!!: '%s'\n", gst_pad_get_name (pad));
+static void
+print_pad_info (GstElement * element)
+{
+  const GList *pads;
+  GstPad *pad;
 
-      if (GST_IS_GHOST_PAD (pad))
-        g_print (", ghost of real pad %s:%s\n", GST_DEBUG_PAD_NAME (realpad));
-      else
-        g_print ("\n");
+  n_print ("\n");
+  n_print ("Pads:\n");
 
-      g_print ("    Implementation:\n");
-      if (realpad->chainfunc)
-        g_print ("      Has chainfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc));
-      if (realpad->getfunc)
-        g_print ("      Has getfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME (realpad->getfunc));
-      if (realpad->formatsfunc != gst_pad_get_formats_default) {
-        g_print ("      Supports seeking/conversion/query formats:\n");
-       print_formats (gst_pad_get_formats (GST_PAD (realpad)));
-      }
-      if (realpad->convertfunc != gst_pad_convert_default)
-        g_print ("      Has custom convertfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME (realpad->convertfunc));
-      if (realpad->eventfunc != gst_pad_event_default)
-        g_print ("      Has custom eventfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc));
-      if (realpad->eventmaskfunc != gst_pad_get_event_masks_default) {
-        g_print ("        Provides event masks:\n");
-       print_event_masks (gst_pad_get_event_masks (GST_PAD (realpad)));
-      }
-      if (realpad->queryfunc != gst_pad_query_default)
-        g_print ("      Has custom queryfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc));
-      if (realpad->querytypefunc != gst_pad_get_query_types_default) {
-        g_print ("        Provides query types:\n");
-       print_query_types (gst_pad_get_query_types (GST_PAD (realpad)));
-      }
+  if (!element->numpads) {
+    n_print ("  none\n");
+    return;
+  }
 
-      if (realpad->intconnfunc != gst_pad_get_internal_links_default)
-        g_print ("      Has custom intconnfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME(realpad->intconnfunc));
+  pads = element->pads;
+  while (pads) {
+    pad = GST_PAD (pads->data);
+    pads = g_list_next (pads);
 
-      if (realpad->bufferpoolfunc)
-        g_print ("      Has bufferpoolfunc(): %s\n",
-               GST_DEBUG_FUNCPTR_NAME(realpad->bufferpoolfunc));
+    n_print ("");
 
-      if (pad->padtemplate)
-        g_print ("    Pad Template: '%s'\n",
-               pad->padtemplate->name_template);
+    if (gst_pad_get_direction (pad) == GST_PAD_SRC)
+      g_print ("  SRC: '%s'", gst_pad_get_name (pad));
+    else if (gst_pad_get_direction (pad) == GST_PAD_SINK)
+      g_print ("  SINK: '%s'", gst_pad_get_name (pad));
+    else
+      g_print ("  UNKNOWN!!!: '%s'", gst_pad_get_name (pad));
 
-      if (realpad->caps) {
-        g_print ("    Capabilities:\n");
-       print_caps (realpad->caps, "      ");
-      }
-    }
-  } else
-    g_print ("  none\n");
-
-  print_element_properties (element);
-
-  /* Dynamic Parameters block */
-  {
-    GstDParamManager* dpman;
-    GParamSpec** specs;
-    gint x;
-    
-    g_print ("\nDynamic Parameters:\n");
-    if((dpman = gst_dpman_get_manager (element))) {
-      specs = gst_dpman_list_dparam_specs (dpman);
-      for (x = 0; specs[x] != NULL; x++) {
-        g_print ("  %-20.20s: ", g_param_spec_get_name (specs[x]));
-
-        switch (G_PARAM_SPEC_VALUE_TYPE (specs[x])) {
-          case G_TYPE_INT64: 
-            g_print ("64 Bit Integer (Default %lld, Range %lld -> %lld)", 
-            ((GParamSpecInt64 *) specs[x])->default_value,
-            ((GParamSpecInt64 *) specs[x])->minimum, 
-            ((GParamSpecInt64 *) specs[x])->maximum);
-            break;
-          case G_TYPE_INT: 
-            g_print ("Integer (Default %d, Range %d -> %d)", 
-            ((GParamSpecInt *) specs[x])->default_value,
-            ((GParamSpecInt *) specs[x])->minimum, 
-            ((GParamSpecInt *) specs[x])->maximum);
-            break;
-          case G_TYPE_FLOAT: 
-           g_print ("Float. Default: %-8.8s %15.7g\n", "",
-              ((GParamSpecFloat *) specs[x])->default_value);
-           g_print ("%-23.23s Range: %15.7g - %15.7g", "", 
-              ((GParamSpecFloat *) specs[x])->minimum, 
-              ((GParamSpecFloat *) specs[x])->maximum);
-            break;
-        default: g_print ("unknown %ld", G_PARAM_SPEC_VALUE_TYPE (specs[x]));
-        }
-        g_print ("\n");
-      }
-      g_free (specs);
+    g_print ("\n");
+
+    n_print ("    Implementation:\n");
+    if (pad->chainfunc)
+      n_print ("      Has chainfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->chainfunc));
+    if (pad->getrangefunc)
+      n_print ("      Has getrangefunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->getrangefunc));
+    if (pad->eventfunc != gst_pad_event_default)
+      n_print ("      Has custom eventfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->eventfunc));
+    if (pad->queryfunc != gst_pad_query_default)
+      n_print ("      Has custom queryfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->queryfunc));
+    if (pad->querytypefunc != gst_pad_get_query_types_default) {
+      n_print ("        Provides query types:\n");
+      print_query_types (gst_pad_get_query_types (pad));
     }
-    else {
-      g_print ("  none\n");
+
+    if (pad->intlinkfunc != gst_pad_get_internal_links_default)
+      n_print ("      Has custom intconnfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->intlinkfunc));
+
+    if (pad->bufferallocfunc)
+      n_print ("      Has bufferallocfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc));
+
+    if (pad->padtemplate)
+      n_print ("    Pad Template: '%s'\n", pad->padtemplate->name_template);
+
+    if (pad->caps) {
+      n_print ("    Capabilities:\n");
+      print_caps (pad->caps, "      ");
     }
   }
+}
 
-  /* Signals/Actions Block */  
-  {
-    guint *signals;
-    guint nsignals;
-    gint i, k;
-    GSignalQuery *query;
-    
-    signals = g_signal_list_ids (G_OBJECT_TYPE (element), &nsignals);
-    for (k = 0; k < 2; k++) {
-      gint counted = 0;
+#if 0
+static gint
+compare_signal_names (GSignalQuery * a, GSignalQuery * b)
+{
+  return strcmp (a->signal_name, b->signal_name);
+}
+#endif
 
-      if (k == 0)
-        g_print ("\nElement Signals:\n");
-      else
-        g_print ("\nElement Actions:\n");
+static void
+print_signal_info (GstElement * element)
+{
+  /* Signals/Actions Block */
+  guint *signals;
+  guint nsignals;
+  gint i = 0, j, k;
+  GSignalQuery *query = NULL;
+  GType type;
+  GSList *found_signals, *l;
+
+  for (k = 0; k < 2; k++) {
+    found_signals = NULL;
+    for (type = G_OBJECT_TYPE (element); type; type = g_type_parent (type)) {
+      if (type == GST_TYPE_ELEMENT || type == GST_TYPE_OBJECT)
+        break;
+
+      if (type == GST_TYPE_BIN && G_OBJECT_TYPE (element) != GST_TYPE_BIN)
+        continue;
 
+      signals = g_signal_list_ids (type, &nsignals);
       for (i = 0; i < nsignals; i++) {
-        gint n_params;
-        GType return_type;
-        const GType *param_types;
-        gint j;
-      
-        query = g_new0 (GSignalQuery,1);
+        query = g_new0 (GSignalQuery, 1);
         g_signal_query (signals[i], query);
 
-       if ((k == 0 && !(query->signal_flags & G_SIGNAL_ACTION)) ||
-           (k == 1 &&  (query->signal_flags & G_SIGNAL_ACTION))) {
-          n_params = query->n_params;
-          return_type = query->return_type;
-          param_types = query->param_types;
+        if ((k == 0 && !(query->signal_flags & G_SIGNAL_ACTION)) ||
+            (k == 1 && (query->signal_flags & G_SIGNAL_ACTION)))
+          found_signals = g_slist_append (found_signals, query);
+      }
+    }
 
-          g_print ("  \"%s\" :\t %s user_function (%s* object", 
-                 query->signal_name, g_type_name (return_type),
-                 g_type_name (G_OBJECT_TYPE (element)));
+    if (found_signals) {
+      n_print ("\n");
+      if (k == 0)
+        n_print ("Element Signals:\n");
+      else
+        n_print ("Element Actions:\n");
+    } else {
+      continue;
+    }
 
-          for (j = 0; j < n_params; j++) {
-            g_print (",\n    \t\t\t\t%s arg%d", g_type_name (param_types[j]), j);
-          }
-         if (k == 0)
-            g_print (",\n    \t\t\t\tgpointer user_data);\n");
-         else
-            g_print (");\n");
+    for (l = found_signals; l; l = l->next) {
+      gchar *indent;
+      int indent_len;
+
+      query = (GSignalQuery *) l->data;
+      indent_len = strlen (query->signal_name) +
+          strlen (g_type_name (query->return_type)) + 24;
 
-         counted++;
-       }
+      indent = g_new0 (gchar, indent_len + 1);
+      memset (indent, ' ', indent_len);
 
-        g_free (query);
+      n_print ("  \"%s\" :  %s user_function (%s* object",
+          query->signal_name,
+          g_type_name (query->return_type), g_type_name (type));
+
+      for (j = 0; j < query->n_params; j++) {
+        if (G_TYPE_IS_FUNDAMENTAL (query->param_types[j])) {
+          g_print (",\n%s%s%s arg%d", _name, indent,
+              g_type_name (query->param_types[j]), j);
+        } else {
+          g_print (",\n%s%s%s* arg%d", _name, indent,
+              g_type_name (query->param_types[j]), j);
+        }
       }
-      if (counted == 0) g_print ("  none\n");
+
+      if (k == 0)
+        g_print (",\n%s%sgpointer user_data);\n", _name, indent);
+      else
+        g_print (");\n");
+
+      g_free (indent);
     }
-  }
-  
 
-  /* for compound elements */
-  if (GST_IS_BIN (element)) {
-    g_print ("\nChildren:\n");
-    children = (GList *) gst_bin_get_list (GST_BIN (element));
-    if (!children) 
-      g_print ("  none\n");
-    else {
-      while (children) {
-        child = GST_ELEMENT (children->data);
-        children = g_list_next (children);
-
-        g_print ("  %s\n", GST_ELEMENT_NAME (child));
-      }
+    if (found_signals) {
+      g_slist_foreach (found_signals, (GFunc) g_free, NULL);
+      g_slist_free (found_signals);
     }
   }
+}
 
-  return 0;
+static void
+print_children_info (GstElement * element)
+{
+  GList *children;
+
+  if (!GST_IS_BIN (element))
+    return;
+
+  children = (GList *) GST_BIN (element)->children;
+  if (children) {
+    n_print ("\n");
+    g_print ("Children:\n");
+  }
+
+  while (children) {
+    n_print ("  %s\n", GST_ELEMENT_NAME (GST_ELEMENT (children->data)));
+    children = g_list_next (children);
+  }
 }
 
-static void 
-print_element_list (void) 
+static void
+print_element_list (gboolean print_all)
 {
-  GList *plugins;
+  int plugincount = 0, featurecount = 0;
+  GList *plugins, *orig_plugins;
 
-  plugins = gst_registry_pool_plugin_list();
+  orig_plugins = plugins = gst_default_registry_get_plugin_list ();
   while (plugins) {
-    GList *features;
+    GList *features, *orig_features;
     GstPlugin *plugin;
-    
-    plugin = (GstPlugin*)(plugins->data);
+
+    plugin = (GstPlugin *) (plugins->data);
     plugins = g_list_next (plugins);
+    plugincount++;
 
-    features = gst_plugin_get_feature_list (plugin);
+    orig_features = features =
+        gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
+        plugin->desc.name);
     while (features) {
       GstPluginFeature *feature;
 
       feature = GST_PLUGIN_FEATURE (features->data);
+      featurecount++;
 
       if (GST_IS_ELEMENT_FACTORY (feature)) {
         GstElementFactory *factory;
 
         factory = GST_ELEMENT_FACTORY (feature);
-        g_print ("%s:  %s: %s\n", plugin->name, 
-               GST_PLUGIN_FEATURE_NAME (factory) ,factory->details->longname);
-      }
-      else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
-        GstAutoplugFactory *factory;
-
-        factory = GST_AUTOPLUG_FACTORY (feature);
-        g_print ("%s:  %s: %s\n", plugin->name, 
-               GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
+        if (print_all)
+          print_element_info (factory, TRUE);
+        else
+          g_print ("%s:  %s: %s\n", plugin->desc.name,
+              GST_PLUGIN_FEATURE_NAME (factory), factory->details.longname);
       }
+#ifndef GST_DISABLE_INDEX
       else if (GST_IS_INDEX_FACTORY (feature)) {
         GstIndexFactory *factory;
 
         factory = GST_INDEX_FACTORY (feature);
-        g_print ("%s:  %s: %s\n", plugin->name, 
-               GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
+        if (!print_all)
+          g_print ("%s:  %s: %s\n", plugin->desc.name,
+              GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
       }
-      else if (GST_IS_TYPE_FACTORY (feature)) {
-        GstTypeFactory *factory;
-
-        factory = GST_TYPE_FACTORY (feature);
-        g_print ("%s type:  %s: %s\n", plugin->name, 
-               factory->mime, factory->exts);
-
-        if (factory->typefindfunc)
-          g_print ("      Has typefind function: %s\n",
-                 GST_DEBUG_FUNCPTR_NAME (factory->typefindfunc));
-      }
-      else if (GST_IS_SCHEDULER_FACTORY (feature)) {
-        GstSchedulerFactory *factory;
-
-        factory = GST_SCHEDULER_FACTORY (feature);
-        g_print ("%s:  %s: %s\n", plugin->name, 
-               GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
-      }
-      else {
-        g_print ("%s:  %s (%s)\n", plugin->name, 
-               GST_PLUGIN_FEATURE_NAME (feature), 
-               g_type_name (G_OBJECT_TYPE (feature)));
+#endif
+      else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
+        GstTypeFindFactory *factory;
+
+        factory = GST_TYPE_FIND_FACTORY (feature);
+        if (!print_all)
+          g_print ("%s: %s: ", plugin->desc.name,
+              gst_plugin_feature_get_name (feature));
+        if (factory->extensions) {
+          guint i = 0;
+
+          while (factory->extensions[i]) {
+            if (!print_all)
+              g_print ("%s%s", i > 0 ? ", " : "", factory->extensions[i]);
+            i++;
+          }
+          if (!print_all)
+            g_print ("\n");
+        } else {
+          if (!print_all)
+            g_print ("no extensions\n");
+        }
+      } else {
+        if (!print_all)
+          n_print ("%s:  %s (%s)\n", plugin->desc.name,
+              GST_PLUGIN_FEATURE_NAME (feature),
+              g_type_name (G_OBJECT_TYPE (feature)));
       }
 
       features = g_list_next (features);
     }
+
+    gst_plugin_feature_list_free (orig_features);
   }
+
+  gst_plugin_list_free (orig_plugins);
+
+  g_print ("\nTotal plugins: %d\nTotal features: %d\n",
+      plugincount, featurecount);
 }
 
 static void
-print_plugin_info (GstPlugin *plugin)
+print_plugin_info (GstPlugin * plugin)
+{
+  n_print ("Plugin Details:\n");
+  n_print ("  Name:\t\t\t%s\n", plugin->desc.name);
+  n_print ("  Description:\t\t%s\n", plugin->desc.description);
+  n_print ("  Filename:\t\t%s\n",
+      plugin->filename ? plugin->filename : "(null)");
+  n_print ("  Version:\t\t%s\n", plugin->desc.version);
+  n_print ("  License:\t\t%s\n", plugin->desc.license);
+  n_print ("  Source module:\t%s\n", plugin->desc.source);
+  n_print ("  Binary package:\t%s\n", plugin->desc.package);
+  n_print ("  Origin URL:\t\t%s\n", plugin->desc.origin);
+  n_print ("\n");
+}
+
+static void
+print_plugin_features (GstPlugin * plugin)
 {
   GList *features;
   gint num_features = 0;
   gint num_elements = 0;
-  gint num_autoplug = 0;
   gint num_types = 0;
-  gint num_schedulers = 0;
   gint num_indexes = 0;
   gint num_other = 0;
-  
-  g_print ("Plugin Details:\n");
-  g_print ("  Name:\t\t%s\n",    plugin->name);
-  g_print ("  Long Name:\t%s\n", plugin->longname);
-  g_print ("  Filename:\t%s\n",  plugin->filename);
-  g_print ("\n");
 
-  features = gst_plugin_get_feature_list (plugin);
+  features =
+      gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
+      plugin->desc.name);
 
   while (features) {
     GstPluginFeature *feature;
@@ -879,124 +957,219 @@ print_plugin_info (GstPlugin *plugin)
       GstElementFactory *factory;
 
       factory = GST_ELEMENT_FACTORY (feature);
-      g_print ("  %s: %s\n", GST_OBJECT_NAME (factory),
-             factory->details->longname);
+      n_print ("  %s: %s\n", GST_PLUGIN_FEATURE_NAME (factory),
+          factory->details.longname);
       num_elements++;
     }
-    else if (GST_IS_AUTOPLUG_FACTORY (feature)) {
-      GstAutoplugFactory *factory;
-
-      factory = GST_AUTOPLUG_FACTORY (feature);
-      g_print ("  %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
-      num_autoplug++;
-    }
+#ifndef GST_DISABLE_INDEX
     else if (GST_IS_INDEX_FACTORY (feature)) {
       GstIndexFactory *factory;
 
       factory = GST_INDEX_FACTORY (feature);
-      g_print ("  %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
+      n_print ("  %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
       num_indexes++;
     }
-    else if (GST_IS_TYPE_FACTORY (feature)) {
-      GstTypeFactory *factory;
+#endif
+    else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
+      GstTypeFindFactory *factory;
 
-      factory = GST_TYPE_FACTORY (feature);
-      g_print ("  %s: %s\n", factory->mime, factory->exts);
+      factory = GST_TYPE_FIND_FACTORY (feature);
+      if (factory->extensions) {
+        guint i = 0;
 
-      if (factory->typefindfunc)
-        g_print ("      Has typefind function: %s\n", 
-               GST_DEBUG_FUNCPTR_NAME (factory->typefindfunc));
-      num_types++;
-    }
-    else if (GST_IS_SCHEDULER_FACTORY (feature)) {
-      GstSchedulerFactory *factory;
+        g_print ("%s type: ", plugin->desc.name);
+        while (factory->extensions[i]) {
+          g_print ("%s%s", i > 0 ? ", " : "", factory->extensions[i]);
+          i++;
+        }
+        g_print ("\n");
+      } else
+        g_print ("%s type: N/A\n", plugin->desc.name);
 
-      factory = GST_SCHEDULER_FACTORY (feature);
-      g_print ("  %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
-      num_schedulers++;
-    }
-    else {
-      g_print ("  %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)), 
-                            g_type_name (G_OBJECT_TYPE (feature)));
+      num_types++;
+    } else {
+      n_print ("  %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)),
+          g_type_name (G_OBJECT_TYPE (feature)));
       num_other++;
     }
     num_features++;
     features = g_list_next (features);
   }
-  g_print ("\n  %d features:\n", num_features);
+  n_print ("\n");
+  n_print ("  %d features:\n", num_features);
   if (num_elements > 0)
-    g_print ("  +-- %d elements\n", num_elements);
-  if (num_autoplug > 0)
-    g_print ("  +-- %d autopluggers\n", num_autoplug);
+    n_print ("  +-- %d elements\n", num_elements);
   if (num_types > 0)
-    g_print ("  +-- %d types\n", num_types);
-  if (num_schedulers > 0)
-    g_print ("  +-- %d schedulers\n", num_schedulers);
+    n_print ("  +-- %d types\n", num_types);
   if (num_indexes > 0)
-    g_print ("  +-- %d indexes\n", num_indexes);
+    n_print ("  +-- %d indexes\n", num_indexes);
   if (num_other > 0)
-    g_print ("  +-- %d other objects\n", num_other);
-  
-  g_print ("\n");
-}
+    n_print ("  +-- %d other objects\n", num_other);
 
+  n_print ("\n");
+}
 
-int 
-main (int argc, char *argv[]) 
+static int
+print_element_features (const gchar * element_name)
 {
-  GstElementFactory *factory;
-  GstPlugin *plugin;
-  gchar *so;
-  struct poptOption options[] = {
-    {"gst-inspect-plugin",  'p',  POPT_ARG_STRING|POPT_ARGFLAG_STRIP,   NULL,   0,
-                  "Show plugin details", NULL},
-    {"gst-inspect-scheduler",  's',  POPT_ARG_STRING|POPT_ARGFLAG_STRIP,   NULL,   0,
-                  "Show scheduler details", NULL},
-    POPT_TABLEEND
-  };
+  GstPluginFeature *feature;
+
+  /* FIXME implement other pretty print function for these */
+#ifndef GST_DISABLE_INDEX
+  feature = gst_default_registry_find_feature (element_name,
+      GST_TYPE_INDEX_FACTORY);
+  if (feature) {
+    n_print ("%s: an index\n", element_name);
+    return 0;
+  }
+#endif
+  feature = gst_default_registry_find_feature (element_name,
+      GST_TYPE_TYPE_FIND_FACTORY);
+  if (feature) {
+    n_print ("%s: a typefind function\n", element_name);
+    return 0;
+  }
 
-  gst_init_with_popt_table (&argc, &argv, options);
-  gst_control_init (&argc, &argv);
-  
-  /* if no arguments, print out list of elements */
-  if (argc == 1) {
-    print_element_list();
+  return -1;
+}
 
-  /* else we try to get a factory */
-  } else {
-    /* first check for help */
-    if (strstr (argv[1], "-help")) {
-      g_print ("Usage: %s\t\t\tList all registered elements\n",argv[0]);
-      g_print ("       %s element-name\tShow element details\n",argv[0]);
-      g_print ("       %s plugin-name[.so]\tShow information about plugin\n",
-             argv[0]);
-      return 0;
-    }
+static int
+print_element_info (GstElementFactory * factory, gboolean print_names)
+{
+  GstElement *element;
+  gint maxlevel = 0;
 
-    /* only search for a factory if there's not a '.so' */
-    if (! strstr (argv[1], ".so")) {
-      factory = gst_element_factory_find (argv[1]);
+  factory =
+      GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
+          (factory)));
 
-      /* if there's a factory, print out the info */
-      if (factory)
-        return print_element_info (factory);
-    } else {
-      /* strip the .so */
-      so = strstr(argv[1],".so");
-      so[0] = '\0';
-    }
+  if (!factory) {
+    g_print ("element plugin couldn't be loaded\n");
+    return -1;
+  }
 
-    /* otherwise assume it's a plugin */
-    plugin = gst_registry_pool_find_plugin (argv[1]);
+  element = gst_element_factory_create (factory, NULL);
+  if (!element) {
+    g_print ("couldn't construct element for some reason\n");
+    return -1;
+  }
 
-    /* if there is such a plugin, print out info */
+  if (print_names)
+    _name = g_strdup_printf ("%s: ", GST_PLUGIN_FEATURE (factory)->name);
+  else
+    _name = "";
 
+  print_factory_details_info (factory);
+  if (GST_PLUGIN_FEATURE (factory)->plugin_name) {
+    GstPlugin *plugin;
+
+    plugin = gst_registry_find_plugin (gst_registry_get_default (),
+        GST_PLUGIN_FEATURE (factory)->plugin_name);
     if (plugin) {
       print_plugin_info (plugin);
+    }
+  }
+
+  print_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel);
+  print_interfaces (G_OBJECT_TYPE (element));
+
+  print_pad_templates_info (element, factory);
+  print_element_flag_info (element);
+  print_implementation_info (element);
+  print_clocking_info (element);
+  print_index_info (element);
+  print_pad_info (element);
+  print_element_properties_info (element);
+  print_signal_info (element);
+  print_children_info (element);
+
+  if (_name[0] != '\0')
+    g_free (_name);
+
+  return 0;
+}
 
+int
+main (int argc, char *argv[])
+{
+  gboolean print_all = FALSE;
+  GOptionEntry options[] = {
+    {"print-all", 'a', 0, G_OPTION_ARG_NONE, &print_all,
+        N_("Print all elements"), NULL},
+    GST_TOOLS_GOPTION_VERSION,
+    {NULL}
+  };
+  GOptionContext *ctx;
+  GError *err = NULL;
+
+#ifdef ENABLE_NLS
+  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+  textdomain (GETTEXT_PACKAGE);
+#endif
+
+  ctx = g_option_context_new ("[ELEMENT-NAME | PLUGIN-NAME]");
+  g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
+  g_option_context_add_group (ctx, gst_init_get_option_group ());
+  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
+    g_print ("Error initializing: %s\n", err->message);
+    exit (1);
+  }
+  g_option_context_free (ctx);
+
+  gst_tools_print_version ("gst-inspect");
+
+  if (print_all && argc > 2) {
+    g_print ("-a requires no extra arguments\n");
+    return 1;
+  }
+
+  /* if no arguments, print out list of elements */
+  if (argc == 1 || print_all) {
+    print_element_list (print_all);
+    /* else we try to get a factory */
+  } else {
+    GstElementFactory *factory;
+    GstPlugin *plugin;
+    const char *arg = argv[argc - 1];
+    int retval;
+
+    factory = gst_element_factory_find (arg);
+    /* if there's a factory, print out the info */
+    if (factory) {
+      retval = print_element_info (factory, print_all);
+      gst_object_unref (factory);
     } else {
-      g_print("no such element or plugin '%s'\n", argv[1]);
-      return -1;
+      retval = print_element_features (arg);
+    }
+
+    /* otherwise check if it's a plugin */
+    if (retval) {
+      plugin = gst_default_registry_find_plugin (arg);
+
+      /* if there is such a plugin, print out info */
+      if (plugin) {
+        print_plugin_info (plugin);
+        print_plugin_features (plugin);
+      } else {
+        GError *error = NULL;
+
+        if (g_file_test (arg, G_FILE_TEST_EXISTS)) {
+          plugin = gst_plugin_load_file (arg, &error);
+
+          if (plugin) {
+            print_plugin_info (plugin);
+            print_plugin_features (plugin);
+          } else {
+            g_print ("Error loading plugin file: %s\n", error->message);
+            g_error_free (error);
+            return -1;
+          }
+        } else {
+          g_print ("No such element or plugin '%s'\n", arg);
+          return -1;
+        }
+      }
     }
   }