Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / tools / gst-inspect.c
index 58aff3b..9f54961 100644 (file)
@@ -172,33 +172,57 @@ print_event_masks (const GstEventMask * masks)
 #endif
 
 static const char *
-get_rank_name (gint rank)
+get_rank_name (char *s, 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 const int ranks[4] = {
+    GST_RANK_NONE, GST_RANK_MARGINAL, GST_RANK_SECONDARY, GST_RANK_PRIMARY
+  };
+  static const char *rank_names[4] = { "none", "marginal", "secondary",
+    "primary"
+  };
+  int i;
+  int best_i;
+
+  best_i = 0;
+  for (i = 0; i < 4; i++) {
+    if (rank == ranks[i])
+      return rank_names[i];
+    if (abs (rank - ranks[i]) < abs (rank - ranks[best_i])) {
+      best_i = i;
+    }
   }
+
+  sprintf (s, "%s %c %d", rank_names[best_i],
+      (rank - ranks[best_i] > 0) ? '+' : '-', abs (ranks[best_i] - rank));
+
+  return s;
+}
+
+static gboolean
+print_factory_details_metadata (GQuark field_id, const GValue * value,
+    gpointer user_data)
+{
+  gchar *val = g_strdup_value_contents (value);
+  gchar *key = g_strdup (g_quark_to_string (field_id));
+
+  key[0] = g_ascii_toupper (key[0]);
+  n_print ("  %s:\t\t%s\n", key, val);
+  g_free (val);
+  g_free (key);
+  return TRUE;
 }
 
 static void
 print_factory_details_info (GstElementFactory * factory)
 {
+  char s[20];
+
   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),
+      get_rank_name (s, GST_PLUGIN_FEATURE (factory)->rank),
       GST_PLUGIN_FEATURE (factory)->rank);
+  gst_structure_foreach ((GstStructure *) factory->metadata,
+      print_factory_details_metadata, NULL);
   n_print ("\n");
 }
 
@@ -276,7 +300,7 @@ flags_to_string (GFlagsValue * vals, guint flags)
     --i;
     if (vals[i].value != 0 && (flags_left & vals[i].value) == vals[i].value) {
       if (s->len > 0)
-        g_string_append (s, " | ");
+        g_string_append_c (s, '+');
       g_string_append (s, vals[i].value_nick);
       flags_left -= vals[i].value;
       if (flags_left == 0)
@@ -290,6 +314,13 @@ flags_to_string (GFlagsValue * vals, guint flags)
   return g_string_free (s, FALSE);
 }
 
+#define KNOWN_PARAM_FLAGS \
+  (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY | \
+  G_PARAM_LAX_VALIDATION |  G_PARAM_STATIC_STRINGS | \
+  G_PARAM_READABLE | G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE | \
+  GST_PARAM_MUTABLE_PLAYING | GST_PARAM_MUTABLE_PAUSED | \
+  GST_PARAM_MUTABLE_READY)
+
 static void
 print_element_properties_info (GstElement * element)
 {
@@ -319,23 +350,27 @@ print_element_properties_info (GstElement * element)
     if (param->flags & G_PARAM_READABLE) {
       g_object_get_property (G_OBJECT (element), param->name, &value);
       readable = TRUE;
-      if (!first_flag)
-        g_print (", ");
-      else
-        first_flag = FALSE;
-      g_print (_("readable"));
+      g_print ("%s%s", (first_flag) ? "" : ", ", _("readable"));
+      first_flag = FALSE;
     }
     if (param->flags & G_PARAM_WRITABLE) {
-      if (!first_flag)
-        g_print (", ");
-      else
-        first_flag = FALSE;
-      g_print (_("writable"));
+      g_print ("%s%s", (first_flag) ? "" : ", ", _("writable"));
+      first_flag = FALSE;
     }
     if (param->flags & GST_PARAM_CONTROLLABLE) {
-      if (!first_flag)
-        g_print (", ");
-      g_print (_("controllable"));
+      g_print (", %s", _("controllable"));
+      first_flag = FALSE;
+    }
+    if (param->flags & GST_PARAM_MUTABLE_PLAYING) {
+      g_print (", %s", _("changeable in NULL, READY, PAUSED or PLAYING state"));
+    } else if (param->flags & GST_PARAM_MUTABLE_PAUSED) {
+      g_print (", %s", _("changeable only in NULL, READY or PAUSED state"));
+    } else if (param->flags & GST_PARAM_MUTABLE_READY) {
+      g_print (", %s", _("changeable only in NULL or READY state"));
+    }
+    if (param->flags & ~KNOWN_PARAM_FLAGS) {
+      g_print ("%s0x%0x", (first_flag) ? "" : ", ",
+          param->flags & ~KNOWN_PARAM_FLAGS);
     }
     n_print ("\n");
 
@@ -566,9 +601,6 @@ print_element_properties_info (GstElement * element)
                 gst_value_get_fraction_numerator (&value),
                 gst_value_get_fraction_denominator (&value));
 
-        } else if (GST_IS_PARAM_SPEC_MINI_OBJECT (param)) {
-          n_print ("%-23.23s MiniObject of type \"%s\"", "",
-              g_type_name (param->value_type));
         } else {
           n_print ("%-23.23s Unknown type %ld \"%s\"", "", param->value_type,
               g_type_name (param->value_type));
@@ -657,10 +689,8 @@ print_element_flag_info (GstElement * element)
 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));
 
   n_print ("\n");
@@ -668,12 +698,6 @@ print_implementation_info (GstElement * element)
 
   n_print ("  Has change_state() function: %s\n",
       GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state));
-#ifndef GST_DISABLE_LOADSAVE
-  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
 }
 
 static void
@@ -767,6 +791,7 @@ print_pad_info (GstElement * element)
   pads = element->pads;
   while (pads) {
     gchar *name;
+    GstCaps *caps;
 
     pad = GST_PAD (pads->data);
     pads = g_list_next (pads);
@@ -799,35 +824,54 @@ print_pad_info (GstElement * element)
       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));
+      const GstQueryType *query_types = gst_pad_get_query_types (pad);
+      if (query_types) {
+        n_print ("        Provides query types:\n");
+        print_query_types (query_types);
+      }
     }
 
     if (pad->iterintlinkfunc != gst_pad_iterate_internal_links_default)
       n_print ("      Has custom iterintlinkfunc(): %s\n",
           GST_DEBUG_FUNCPTR_NAME (pad->iterintlinkfunc));
 
-    if (pad->bufferallocfunc)
-      n_print ("      Has bufferallocfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc));
+    if (pad->getcapsfunc)
+      n_print ("      Has getcapsfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->getcapsfunc));
+    /* gst_pad_acceptcaps_default is static :/ */
+    if (pad->acceptcapsfunc)
+      n_print ("      Has acceptcapsfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->acceptcapsfunc));
+    if (pad->fixatecapsfunc)
+      n_print ("      Has fixatecapsfunc(): %s\n",
+          GST_DEBUG_FUNCPTR_NAME (pad->fixatecapsfunc));
+
 
     if (pad->padtemplate)
       n_print ("    Pad Template: '%s'\n", pad->padtemplate->name_template);
 
-    if (pad->caps) {
+    caps = gst_pad_get_current_caps (pad);
+    if (caps) {
       n_print ("    Capabilities:\n");
-      print_caps (pad->caps, "      ");
+      print_caps (caps, "      ");
+      gst_caps_unref (caps);
     }
   }
 }
 
-#if 0
-static gint
-compare_signal_names (GSignalQuery * a, GSignalQuery * b)
+static gboolean
+has_sometimes_template (GstElement * element)
 {
-  return strcmp (a->signal_name, b->signal_name);
+  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
+  GList *l;
+
+  for (l = klass->padtemplates; l != NULL; l = l->next) {
+    if (GST_PAD_TEMPLATE (l->data)->presence == GST_PAD_SOMETIMES)
+      return TRUE;
+  }
+
+  return FALSE;
 }
-#endif
 
 static void
 print_signal_info (GstElement * element)
@@ -842,6 +886,22 @@ print_signal_info (GstElement * element)
 
   for (k = 0; k < 2; k++) {
     found_signals = NULL;
+
+    /* For elements that have sometimes pads, also list a few useful GstElement
+     * signals. Put these first, so element-specific ones come later. */
+    if (k == 0 && has_sometimes_template (element)) {
+      query = g_new0 (GSignalQuery, 1);
+      g_signal_query (g_signal_lookup ("pad-added", GST_TYPE_ELEMENT), query);
+      found_signals = g_slist_append (found_signals, query);
+      query = g_new0 (GSignalQuery, 1);
+      g_signal_query (g_signal_lookup ("pad-removed", GST_TYPE_ELEMENT), query);
+      found_signals = g_slist_append (found_signals, query);
+      query = g_new0 (GSignalQuery, 1);
+      g_signal_query (g_signal_lookup ("no-more-pads", GST_TYPE_ELEMENT),
+          query);
+      found_signals = g_slist_append (found_signals, query);
+    }
+
     for (type = G_OBJECT_TYPE (element); type; type = g_type_parent (type)) {
       if (type == GST_TYPE_ELEMENT || type == GST_TYPE_OBJECT)
         break;
@@ -1005,7 +1065,7 @@ print_element_list (gboolean print_all)
           print_element_info (factory, TRUE);
         else
           g_print ("%s:  %s: %s\n", plugin->desc.name,
-              GST_PLUGIN_FEATURE_NAME (factory),
+              GST_OBJECT_NAME (factory),
               gst_element_factory_get_longname (factory));
       } else if (GST_IS_INDEX_FACTORY (feature)) {
         GstIndexFactory *factory;
@@ -1013,7 +1073,7 @@ print_element_list (gboolean print_all)
         factory = GST_INDEX_FACTORY (feature);
         if (!print_all)
           g_print ("%s:  %s: %s\n", plugin->desc.name,
-              GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
+              GST_OBJECT_NAME (factory), factory->longdesc);
       } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
         GstTypeFindFactory *factory;
 
@@ -1038,8 +1098,7 @@ print_element_list (gboolean print_all)
       } 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)));
+              GST_OBJECT_NAME (feature), g_type_name (G_OBJECT_TYPE (feature)));
       }
 
     next:
@@ -1120,12 +1179,12 @@ print_all_uri_handlers (void)
               gst_uri_handler_get_protocols (GST_URI_HANDLER (element));
           joined = g_strjoinv (", ", uri_protocols);
 
-          g_print ("%s (%s, rank %u): %s\n", GST_OBJECT_NAME (factory), dir,
+          g_print ("%s (%s, rank %u): %s\n",
+              gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)), dir,
               gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE (factory)),
               joined);
 
           g_free (joined);
-          //g_strfreev (uri_protocols);
         }
 
         gst_object_unref (element);
@@ -1150,6 +1209,25 @@ print_plugin_info (GstPlugin * plugin)
   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);
+  if (plugin->desc.release_datetime != NULL) {
+    const gchar *tz = "(UTC)";
+    gchar *str, *sep;
+
+    /* may be: YYYY-MM-DD or YYYY-MM-DDTHH:MMZ */
+    /* YYYY-MM-DDTHH:MMZ => YYYY-MM-DD HH:MM (UTC) */
+    str = g_strdup (plugin->desc.release_datetime);
+    sep = strstr (str, "T");
+    if (sep != NULL) {
+      *sep = ' ';
+      sep = strstr (sep + 1, "Z");
+      if (sep != NULL)
+        *sep = ' ';
+    } else {
+      tz = "";
+    }
+    n_print ("  Source release date:\t%s%s\n", str, tz);
+    g_free (str);
+  }
   n_print ("  Binary package:\t%s\n", plugin->desc.package);
   n_print ("  Origin URL:\t\t%s\n", plugin->desc.origin);
   n_print ("\n");
@@ -1158,14 +1236,14 @@ print_plugin_info (GstPlugin * plugin)
 static void
 print_plugin_features (GstPlugin * plugin)
 {
-  GList *features;
+  GList *features, *origlist;
   gint num_features = 0;
   gint num_elements = 0;
   gint num_typefinders = 0;
   gint num_indexes = 0;
   gint num_other = 0;
 
-  features =
+  origlist = features =
       gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
       plugin->desc.name);
 
@@ -1178,7 +1256,7 @@ print_plugin_features (GstPlugin * plugin)
       GstElementFactory *factory;
 
       factory = GST_ELEMENT_FACTORY (feature);
-      n_print ("  %s: %s\n", GST_PLUGIN_FEATURE_NAME (factory),
+      n_print ("  %s: %s\n", GST_OBJECT_NAME (factory),
           gst_element_factory_get_longname (factory));
       num_elements++;
     } else if (GST_IS_INDEX_FACTORY (feature)) {
@@ -1214,6 +1292,9 @@ print_plugin_features (GstPlugin * plugin)
     num_features++;
     features = g_list_next (features);
   }
+
+  gst_plugin_feature_list_free (origlist);
+
   n_print ("\n");
   n_print ("  %d features:\n", num_features);
   if (num_elements > 0)
@@ -1272,7 +1353,7 @@ print_element_info (GstElementFactory * factory, gboolean print_names)
   }
 
   if (print_names)
-    _name = g_strdup_printf ("%s: ", GST_PLUGIN_FEATURE (factory)->name);
+    _name = g_strdup_printf ("%s: ", GST_OBJECT_NAME (factory));
   else
     _name = NULL;
 
@@ -1350,7 +1431,7 @@ print_plugin_automatic_install_info_codecs (GstElementFactory * factory)
 
   if (caps == NULL) {
     g_printerr ("Couldn't find static pad template for %s '%s'\n",
-        type_name, GST_PLUGIN_FEATURE_NAME (factory));
+        type_name, GST_OBJECT_NAME (factory));
     return;
   }