tools: avoid unportable vararg macro construct in gst-discoverer
[platform/upstream/gstreamer.git] / tools / gst-discoverer.c
index 0dbca30..5a168d6 100644 (file)
@@ -37,15 +37,28 @@ typedef struct
   char **argv;
 } PrivStruct;
 
-#define my_g_string_append_printf(str, format, ...) \
-  g_string_append_printf (str, "%*s" format, 2*depth, " ", ##__VA_ARGS__)
+static void
+my_g_string_append_printf (GString * str, int depth, const gchar * format, ...)
+{
+  va_list args;
+
+  while (depth-- > 0) {
+    g_string_append (str, "  ");
+  }
+
+  va_start (args, format);
+  g_string_append_vprintf (str, format, args);
+  va_end (args);
+}
 
 static gchar *
 gst_stream_audio_information_to_string (GstDiscovererStreamInfo * info,
     gint depth)
 {
+  GstDiscovererAudioInfo *audio_info;
   GString *s;
   gchar *tmp;
+  const gchar *ctmp;
   int len = 400;
   const GstTagList *tags;
   GstCaps *caps;
@@ -54,45 +67,49 @@ gst_stream_audio_information_to_string (GstDiscovererStreamInfo * info,
 
   s = g_string_sized_new (len);
 
-  my_g_string_append_printf (s, "Codec:\n");
+  my_g_string_append_printf (s, depth, "Codec:\n");
   caps = gst_discoverer_stream_info_get_caps (info);
   tmp = gst_caps_to_string (caps);
   gst_caps_unref (caps);
-  my_g_string_append_printf (s, "  %s\n", tmp);
+  my_g_string_append_printf (s, depth, "  %s\n", tmp);
   g_free (tmp);
 
-  my_g_string_append_printf (s, "Additional info:\n");
+  my_g_string_append_printf (s, depth, "Additional info:\n");
   if (gst_discoverer_stream_info_get_misc (info)) {
     tmp = gst_structure_to_string (gst_discoverer_stream_info_get_misc (info));
-    my_g_string_append_printf (s, "  %s\n", tmp);
+    my_g_string_append_printf (s, depth, "  %s\n", tmp);
     g_free (tmp);
   } else {
-    my_g_string_append_printf (s, "  None\n");
+    my_g_string_append_printf (s, depth, "  None\n");
   }
 
-  my_g_string_append_printf (s, "Channels: %u\n",
-      gst_discoverer_audio_info_get_channels (info));
-  my_g_string_append_printf (s, "Sample rate: %u\n",
-      gst_discoverer_audio_info_get_sample_rate (info));
-  my_g_string_append_printf (s, "Depth: %u\n",
-      gst_discoverer_audio_info_get_depth (info));
-
-  my_g_string_append_printf (s, "Bitrate: %u\n",
-      gst_discoverer_audio_info_get_bitrate (info));
-  my_g_string_append_printf (s, "Max bitrate: %u\n",
-      gst_discoverer_audio_info_get_max_bitrate (info));
-
-  my_g_string_append_printf (s, "Tags:\n");
+  audio_info = (GstDiscovererAudioInfo *) info;
+  ctmp = gst_discoverer_audio_info_get_language (audio_info);
+  my_g_string_append_printf (s, depth, "Language: %s\n",
+      ctmp ? ctmp : "<unknown>");
+  my_g_string_append_printf (s, depth, "Channels: %u\n",
+      gst_discoverer_audio_info_get_channels (audio_info));
+  my_g_string_append_printf (s, depth, "Sample rate: %u\n",
+      gst_discoverer_audio_info_get_sample_rate (audio_info));
+  my_g_string_append_printf (s, depth, "Depth: %u\n",
+      gst_discoverer_audio_info_get_depth (audio_info));
+
+  my_g_string_append_printf (s, depth, "Bitrate: %u\n",
+      gst_discoverer_audio_info_get_bitrate (audio_info));
+  my_g_string_append_printf (s, depth, "Max bitrate: %u\n",
+      gst_discoverer_audio_info_get_max_bitrate (audio_info));
+
+  my_g_string_append_printf (s, depth, "Tags:\n");
   tags = gst_discoverer_stream_info_get_tags (info);
   if (tags) {
     tmp = gst_structure_to_string ((GstStructure *) tags);
-    my_g_string_append_printf (s, "  %s\n", tmp);
+    my_g_string_append_printf (s, depth, "  %s\n", tmp);
     g_free (tmp);
   } else {
-    my_g_string_append_printf (s, "  None\n");
+    my_g_string_append_printf (s, depth, "  None\n");
   }
   if (verbose)
-    my_g_string_append_printf (s, "\n");
+    my_g_string_append_printf (s, depth, "\n");
 
   return g_string_free (s, FALSE);
 }
@@ -101,6 +118,7 @@ static gchar *
 gst_stream_video_information_to_string (GstDiscovererStreamInfo * info,
     gint depth)
 {
+  GstDiscovererVideoInfo *video_info;
   GString *s;
   gchar *tmp;
   int len = 500;
@@ -112,57 +130,110 @@ gst_stream_video_information_to_string (GstDiscovererStreamInfo * info,
 
   s = g_string_sized_new (len);
 
-  my_g_string_append_printf (s, "Codec:\n");
+  my_g_string_append_printf (s, depth, "Codec:\n");
   caps = gst_discoverer_stream_info_get_caps (info);
   tmp = gst_caps_to_string (caps);
   gst_caps_unref (caps);
-  my_g_string_append_printf (s, "  %s\n", tmp);
+  my_g_string_append_printf (s, depth, "  %s\n", tmp);
   g_free (tmp);
 
-  my_g_string_append_printf (s, "Additional info:\n");
+  my_g_string_append_printf (s, depth, "Additional info:\n");
   misc = gst_discoverer_stream_info_get_misc (info);
   if (misc) {
     tmp = gst_structure_to_string (misc);
-    my_g_string_append_printf (s, "  %s\n", tmp);
+    my_g_string_append_printf (s, depth, "  %s\n", tmp);
     g_free (tmp);
   } else {
-    my_g_string_append_printf (s, "  None\n");
+    my_g_string_append_printf (s, depth, "  None\n");
   }
 
-  my_g_string_append_printf (s, "Width: %u\n",
-      gst_discoverer_video_info_get_width (info));
-  my_g_string_append_printf (s, "Height: %u\n",
-      gst_discoverer_video_info_get_height (info));
-  my_g_string_append_printf (s, "Depth: %u\n",
-      gst_discoverer_video_info_get_depth (info));
+  video_info = (GstDiscovererVideoInfo *) info;
+  my_g_string_append_printf (s, depth, "Width: %u\n",
+      gst_discoverer_video_info_get_width (video_info));
+  my_g_string_append_printf (s, depth, "Height: %u\n",
+      gst_discoverer_video_info_get_height (video_info));
+  my_g_string_append_printf (s, depth, "Depth: %u\n",
+      gst_discoverer_video_info_get_depth (video_info));
 
-  my_g_string_append_printf (s, "Frame rate: %u/%u\n",
-      gst_discoverer_video_info_get_framerate_num (info),
-      gst_discoverer_video_info_get_framerate_denom (info));
+  my_g_string_append_printf (s, depth, "Frame rate: %u/%u\n",
+      gst_discoverer_video_info_get_framerate_num (video_info),
+      gst_discoverer_video_info_get_framerate_denom (video_info));
 
-  my_g_string_append_printf (s, "Pixel aspect ratio: %u/%u\n",
-      gst_discoverer_video_info_get_par_num (info),
-      gst_discoverer_video_info_get_par_denom (info));
+  my_g_string_append_printf (s, depth, "Pixel aspect ratio: %u/%u\n",
+      gst_discoverer_video_info_get_par_num (video_info),
+      gst_discoverer_video_info_get_par_denom (video_info));
 
-  my_g_string_append_printf (s, "Interlaced: %s\n",
-      gst_discoverer_video_info_get_interlaced (info) ? "true" : "false");
+  my_g_string_append_printf (s, depth, "Interlaced: %s\n",
+      gst_discoverer_video_info_is_interlaced (video_info) ? "true" : "false");
 
-  my_g_string_append_printf (s, "Bitrate: %u\n",
-      gst_discoverer_video_info_get_bitrate (info));
-  my_g_string_append_printf (s, "Max bitrate: %u\n",
-      gst_discoverer_video_info_get_max_bitrate (info));
+  my_g_string_append_printf (s, depth, "Bitrate: %u\n",
+      gst_discoverer_video_info_get_bitrate (video_info));
+  my_g_string_append_printf (s, depth, "Max bitrate: %u\n",
+      gst_discoverer_video_info_get_max_bitrate (video_info));
 
-  my_g_string_append_printf (s, "Tags:\n");
+  my_g_string_append_printf (s, depth, "Tags:\n");
   tags = gst_discoverer_stream_info_get_tags (info);
   if (tags) {
     tmp = gst_structure_to_string ((GstStructure *) tags);
-    my_g_string_append_printf (s, "  %s\n", tmp);
+    my_g_string_append_printf (s, depth, "  %s\n", tmp);
     g_free (tmp);
   } else {
-    my_g_string_append_printf (s, "  None\n");
+    my_g_string_append_printf (s, depth, "  None\n");
   }
   if (verbose)
-    my_g_string_append_printf (s, "\n");
+    my_g_string_append_printf (s, depth, "\n");
+
+  return g_string_free (s, FALSE);
+}
+
+static gchar *
+gst_stream_subtitle_information_to_string (GstDiscovererStreamInfo * info,
+    gint depth)
+{
+  GstDiscovererSubtitleInfo *subtitle_info;
+  GString *s;
+  gchar *tmp;
+  const gchar *ctmp;
+  int len = 400;
+  const GstTagList *tags;
+  GstCaps *caps;
+
+  g_return_val_if_fail (info != NULL, NULL);
+
+  s = g_string_sized_new (len);
+
+  my_g_string_append_printf (s, depth, "Codec:\n");
+  caps = gst_discoverer_stream_info_get_caps (info);
+  tmp = gst_caps_to_string (caps);
+  gst_caps_unref (caps);
+  my_g_string_append_printf (s, depth, "  %s\n", tmp);
+  g_free (tmp);
+
+  my_g_string_append_printf (s, depth, "Additional info:\n");
+  if (gst_discoverer_stream_info_get_misc (info)) {
+    tmp = gst_structure_to_string (gst_discoverer_stream_info_get_misc (info));
+    my_g_string_append_printf (s, depth, "  %s\n", tmp);
+    g_free (tmp);
+  } else {
+    my_g_string_append_printf (s, depth, "  None\n");
+  }
+
+  subtitle_info = (GstDiscovererSubtitleInfo *) info;
+  ctmp = gst_discoverer_subtitle_info_get_language (subtitle_info);
+  my_g_string_append_printf (s, depth, "Language: %s\n",
+      ctmp ? ctmp : "<unknown>");
+
+  my_g_string_append_printf (s, depth, "Tags:\n");
+  tags = gst_discoverer_stream_info_get_tags (info);
+  if (tags) {
+    tmp = gst_structure_to_string ((GstStructure *) tags);
+    my_g_string_append_printf (s, depth, "  %s\n", tmp);
+    g_free (tmp);
+  } else {
+    my_g_string_append_printf (s, depth, "  None\n");
+  }
+  if (verbose)
+    my_g_string_append_printf (s, depth, "\n");
 
   return g_string_free (s, FALSE);
 }
@@ -200,11 +271,14 @@ print_stream_info (GstDiscovererStreamInfo * info, void *depth)
       desc =
           gst_stream_video_information_to_string (info,
           GPOINTER_TO_INT (depth) + 1);
-  }
-
-  if (desc) {
-    g_print ("%s", desc);
-    g_free (desc);
+    else if (GST_IS_DISCOVERER_SUBTITLE_INFO (info))
+      desc =
+          gst_stream_subtitle_information_to_string (info,
+          GPOINTER_TO_INT (depth) + 1);
+    if (desc) {
+      g_print ("%s", desc);
+      g_free (desc);
+    }
   }
 }
 
@@ -225,7 +299,9 @@ print_topology (GstDiscovererStreamInfo * info, gint depth)
   } else if (GST_IS_DISCOVERER_CONTAINER_INFO (info)) {
     GList *tmp, *streams;
 
-    streams = gst_discoverer_container_info_get_streams (info);
+    streams =
+        gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
+        (info));
     for (tmp = streams; tmp; tmp = tmp->next) {
       GstDiscovererStreamInfo *tmpinf = (GstDiscovererStreamInfo *) tmp->data;
       print_topology (tmpinf, depth + 1);
@@ -234,11 +310,41 @@ print_topology (GstDiscovererStreamInfo * info, gint depth)
   }
 }
 
+static gboolean
+print_tag_each (GQuark field_id, const GValue * value, gpointer user_data)
+{
+  gint tab = GPOINTER_TO_INT (user_data);
+  gchar *ser;
+
+  if (G_VALUE_HOLDS_STRING (value))
+    ser = g_value_dup_string (value);
+  else if (GST_VALUE_HOLDS_BUFFER (value)) {
+    GstBuffer *buf = gst_value_get_buffer (value);
+    ser = g_strdup_printf ("<GstBuffer [%d bytes]>", GST_BUFFER_SIZE (buf));
+  } else
+    ser = gst_value_serialize (value);
+
+  g_print ("%*s%s: %s\n", tab, " ",
+      gst_tag_get_nick (g_quark_to_string (field_id)), ser);
+  g_free (ser);
+
+  return TRUE;
+}
+
 static void
-print_duration (GstDiscovererInfo * info, gint tab)
+print_properties (GstDiscovererInfo * info, gint tab)
 {
-  g_print ("%*s%" GST_TIME_FORMAT "\n", tab + 1, " ",
+  const GstTagList *tags;
+
+  g_print ("%*sDuration: %" GST_TIME_FORMAT "\n", tab + 1, " ",
       GST_TIME_ARGS (gst_discoverer_info_get_duration (info)));
+  g_print ("%*sSeekable: %s\n", tab + 1, " ",
+      (gst_discoverer_info_get_seekable (info) ? "yes" : "no"));
+  if ((tags = gst_discoverer_info_get_tags (info))) {
+    g_print ("%*sTags: \n", tab + 1, " ");
+    gst_structure_foreach ((const GstStructure *) tags, print_tag_each,
+        GINT_TO_POINTER (tab + 5));
+  }
 }
 
 static void
@@ -251,12 +357,6 @@ print_info (GstDiscovererInfo * info, GError * err)
   switch (result) {
     case GST_DISCOVERER_OK:
     {
-      sinfo = gst_discoverer_info_get_stream_info (info);
-      g_print ("\nTopology:\n");
-      print_topology (sinfo, 1);
-      g_print ("\nDuration:\n");
-      print_duration (info, 1);
-      gst_discoverer_stream_info_unref (sinfo);
       break;
     }
     case GST_DISCOVERER_URI_INVALID:
@@ -293,6 +393,14 @@ print_info (GstDiscovererInfo * info, GError * err)
     }
   }
 
+  if ((sinfo = gst_discoverer_info_get_stream_info (info))) {
+    g_print ("\nTopology:\n");
+    print_topology (sinfo, 1);
+    g_print ("\nProperties:\n");
+    print_properties (info, 1);
+    gst_discoverer_stream_info_unref (sinfo);
+  }
+
   g_print ("\n");
 }
 
@@ -376,7 +484,7 @@ _run_async (PrivStruct * ps)
 }
 
 static void
-_discoverer_ready (GstDiscoverer * dc, GMainLoop * ml)
+_discoverer_finished (GstDiscoverer * dc, GMainLoop * ml)
 {
   g_main_loop_quit (ml);
 }
@@ -402,8 +510,10 @@ main (int argc, char **argv)
   };
   GOptionContext *ctx;
 
+#if !GLIB_CHECK_VERSION (2, 31, 0)
   if (!g_thread_supported ())
     g_thread_init (NULL);
+#endif
 
   ctx =
       g_option_context_new
@@ -446,7 +556,7 @@ main (int argc, char **argv)
 
     /* connect signals */
     g_signal_connect (dc, "discovered", G_CALLBACK (_new_discovered_uri), NULL);
-    g_signal_connect (dc, "ready", G_CALLBACK (_discoverer_ready), ml);
+    g_signal_connect (dc, "finished", G_CALLBACK (_discoverer_finished), ml);
 
     gst_discoverer_start (dc);
     /* run mainloop */
@@ -454,6 +564,7 @@ main (int argc, char **argv)
 
     gst_discoverer_stop (dc);
     g_free (ps);
+    g_main_loop_unref (ml);
   }
   g_object_unref (dc);