-#include <string.h>\r
-#include <gst/gst.h>\r
-#include <gst/pbutils/pbutils.h>\r
- \r
-/* Structure to contain all our information, so we can pass it around */\r
-typedef struct _CustomData {\r
- GstDiscoverer *discoverer;\r
- GMainLoop *loop;\r
-} CustomData;\r
- \r
-/* Print a tag in a human-readable format (name: value) */\r
-static void print_tag_foreach (const GstTagList *tags, const gchar *tag, gpointer user_data) {\r
- GValue val = { 0, };\r
- gchar *str;\r
- gint depth = GPOINTER_TO_INT (user_data);\r
- \r
- gst_tag_list_copy_value (&val, tags, tag);\r
- \r
- if (G_VALUE_HOLDS_STRING (&val))\r
- str = g_value_dup_string (&val);\r
- else\r
- str = gst_value_serialize (&val);\r
- \r
- g_print ("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick (tag), str);\r
- g_free (str);\r
- \r
- g_value_unset (&val);\r
-}\r
- \r
-/* Print information regarding a stream */\r
-static void print_stream_info (GstDiscovererStreamInfo *info, gint depth) {\r
- gchar *desc = NULL;\r
- GstCaps *caps;\r
- const GstTagList *tags;\r
- \r
- caps = gst_discoverer_stream_info_get_caps (info);\r
- \r
- if (caps) {\r
- if (gst_caps_is_fixed (caps))\r
- desc = gst_pb_utils_get_codec_description (caps);\r
- else\r
- desc = gst_caps_to_string (caps);\r
- gst_caps_unref (caps);\r
- }\r
- \r
- g_print ("%*s%s: %s\n", 2 * depth, " ", gst_discoverer_stream_info_get_stream_type_nick (info), (desc ? desc : ""));\r
- \r
- if (desc) {\r
- g_free (desc);\r
- desc = NULL;\r
- }\r
- \r
- tags = gst_discoverer_stream_info_get_tags (info);\r
- if (tags) {\r
- g_print ("%*sTags:\n", 2 * (depth + 1), " ");\r
- gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (depth + 2));\r
- }\r
-}\r
- \r
-/* Print information regarding a stream and its substreams, if any */\r
-static void print_topology (GstDiscovererStreamInfo *info, gint depth) {\r
- GstDiscovererStreamInfo *next;\r
- \r
- if (!info)\r
- return;\r
- \r
- print_stream_info (info, depth);\r
- \r
- next = gst_discoverer_stream_info_get_next (info);\r
- if (next) {\r
- print_topology (next, depth + 1);\r
- gst_discoverer_stream_info_unref (next);\r
- } else if (GST_IS_DISCOVERER_CONTAINER_INFO (info)) {\r
- GList *tmp, *streams;\r
- \r
- streams = gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO (info));\r
- for (tmp = streams; tmp; tmp = tmp->next) {\r
- GstDiscovererStreamInfo *tmpinf = (GstDiscovererStreamInfo *) tmp->data;\r
- print_topology (tmpinf, depth + 1);\r
- }\r
- gst_discoverer_stream_info_list_free (streams);\r
- }\r
-}\r
- \r
-/* This function is called every time the discoverer has information regarding\r
- * one of the URIs we provided.*/\r
-static void on_discovered_cb (GstDiscoverer *discoverer, GstDiscovererInfo *info, GError *err, CustomData *data) {\r
- GstDiscovererResult result;\r
- const gchar *uri;\r
- const GstTagList *tags;\r
- GstDiscovererStreamInfo *sinfo;\r
- \r
- uri = gst_discoverer_info_get_uri (info);\r
- result = gst_discoverer_info_get_result (info);\r
- switch (result) {\r
- case GST_DISCOVERER_URI_INVALID:\r
- g_print ("Invalid URI '%s'\n", uri);\r
- break;\r
- case GST_DISCOVERER_ERROR:\r
- g_print ("Discoverer error: %s\n", err->message);\r
- break;\r
- case GST_DISCOVERER_TIMEOUT:\r
- g_print ("Timeout\n");\r
- break;\r
- case GST_DISCOVERER_BUSY:\r
- g_print ("Busy\n");\r
- break;\r
- case GST_DISCOVERER_MISSING_PLUGINS:{\r
- const GstStructure *s;\r
- gchar *str;\r
- \r
- s = gst_discoverer_info_get_misc (info);\r
- str = gst_structure_to_string (s);\r
- \r
- g_print ("Missing plugins: %s\n", str);\r
- g_free (str);\r
- break;\r
- }\r
- case GST_DISCOVERER_OK:\r
- g_print ("Discovered '%s'\n", uri);\r
- break;\r
- }\r
- \r
- if (result != GST_DISCOVERER_OK) {\r
- g_printerr ("This URI cannot be played\n");\r
- return;\r
- }\r
- \r
- /* If we got no error, show the retrieved information */\r
- \r
- g_print ("\nDuration: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (gst_discoverer_info_get_duration (info)));\r
- \r
- tags = gst_discoverer_info_get_tags (info);\r
- if (tags) {\r
- g_print ("Tags:\n");\r
- gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (1));\r
- }\r
- \r
- g_print ("Seekable: %s\n", (gst_discoverer_info_get_seekable (info) ? "yes" : "no"));\r
- \r
- g_print ("\n");\r
- \r
- sinfo = gst_discoverer_info_get_stream_info (info);\r
- if (!sinfo)\r
- return;\r
- \r
- g_print ("Stream information:\n");\r
- \r
- print_topology (sinfo, 1);\r
- \r
- gst_discoverer_stream_info_unref (sinfo);\r
- \r
- g_print ("\n");\r
-}\r
- \r
-/* This function is called when the discoverer has finished examining\r
- * all the URIs we provided.*/\r
-static void on_finished_cb (GstDiscoverer *discoverer, CustomData *data) {\r
- g_print ("Finished discovering\n");\r
- \r
- g_main_loop_quit (data->loop);\r
-}\r
- \r
-int main (int argc, char **argv) {\r
- CustomData data;\r
- GError *err = NULL;\r
- gchar *uri = "http://docs.gstreamer.com/media/sintel_trailer-480p.webm";\r
- \r
- /* if a URI was provided, use it instead of the default one */\r
- if (argc > 1) {\r
- uri = argv[1];\r
- }\r
-
- /* Initialize cumstom data structure */\r
- memset (&data, 0, sizeof (data));\r
-
- /* Initialize GStreamer */\r
- gst_init (&argc, &argv);\r
- \r
- g_print ("Discovering '%s'\n", uri);\r
-
- /* Instantiate the Discoverer */\r
- data.discoverer = gst_discoverer_new (5 * GST_SECOND, &err);\r
- if (!data.discoverer) {\r
- g_print ("Error creating discoverer instance: %s\n", err->message);\r
- g_clear_error (&err);\r
- return -1;\r
- }\r
- \r
- /* Connect to the interesting signals */\r
- g_signal_connect (data.discoverer, "discovered", G_CALLBACK (on_discovered_cb), &data);\r
- g_signal_connect (data.discoverer, "finished", G_CALLBACK (on_finished_cb), &data);\r
- \r
- /* Start the discoverer process (nothing to do yet) */\r
- gst_discoverer_start (data.discoverer);\r
- \r
- /* Add a request to process asynchronously the URI passed through the command line */\r
- if (!gst_discoverer_discover_uri_async (data.discoverer, uri)) {\r
- g_print ("Failed to start discovering URI '%s'\n", uri);\r
- g_object_unref (data.discoverer);\r
- g_main_loop_unref (data.loop);\r
- return -1;\r
- }\r
-
- /* Create a GLib Main Loop and set it to run, so we can wait for the signals */\r
- data.loop = g_main_loop_new (NULL, FALSE);\r
- g_main_loop_run (data.loop);\r
- \r
- /* Stop the discoverer process */\r
- gst_discoverer_stop (data.discoverer);\r
-
- /* Free resources */\r
- g_object_unref (data.discoverer);\r
- g_main_loop_unref (data.loop);\r
- \r
- return 0;\r
+#include <string.h>
+#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
+
+/* Structure to contain all our information, so we can pass it around */
+typedef struct _CustomData {
+ GstDiscoverer *discoverer;
+ GMainLoop *loop;
+} CustomData;
+
+/* Print a tag in a human-readable format (name: value) */
+static void print_tag_foreach (const GstTagList *tags, const gchar *tag, gpointer user_data) {
+ GValue val = { 0, };
+ gchar *str;
+ gint depth = GPOINTER_TO_INT (user_data);
+
+ gst_tag_list_copy_value (&val, tags, tag);
+
+ if (G_VALUE_HOLDS_STRING (&val))
+ str = g_value_dup_string (&val);
+ else
+ str = gst_value_serialize (&val);
+
+ g_print ("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick (tag), str);
+ g_free (str);
+
+ g_value_unset (&val);
+}
+
+/* Print information regarding a stream */
+static void print_stream_info (GstDiscovererStreamInfo *info, gint depth) {
+ gchar *desc = NULL;
+ GstCaps *caps;
+ const GstTagList *tags;
+
+ caps = gst_discoverer_stream_info_get_caps (info);
+
+ if (caps) {
+ if (gst_caps_is_fixed (caps))
+ desc = gst_pb_utils_get_codec_description (caps);
+ else
+ desc = gst_caps_to_string (caps);
+ gst_caps_unref (caps);
+ }
+
+ g_print ("%*s%s: %s\n", 2 * depth, " ", gst_discoverer_stream_info_get_stream_type_nick (info), (desc ? desc : ""));
+
+ if (desc) {
+ g_free (desc);
+ desc = NULL;
+ }
+
+ tags = gst_discoverer_stream_info_get_tags (info);
+ if (tags) {
+ g_print ("%*sTags:\n", 2 * (depth + 1), " ");
+ gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (depth + 2));
+ }
+}
+
+/* Print information regarding a stream and its substreams, if any */
+static void print_topology (GstDiscovererStreamInfo *info, gint depth) {
+ GstDiscovererStreamInfo *next;
+
+ if (!info)
+ return;
+
+ print_stream_info (info, depth);
+
+ next = gst_discoverer_stream_info_get_next (info);
+ if (next) {
+ print_topology (next, depth + 1);
+ gst_discoverer_stream_info_unref (next);
+ } else if (GST_IS_DISCOVERER_CONTAINER_INFO (info)) {
+ GList *tmp, *streams;
+
+ 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);
+ }
+ gst_discoverer_stream_info_list_free (streams);
+ }
+}
+
+/* This function is called every time the discoverer has information regarding
+ * one of the URIs we provided.*/
+static void on_discovered_cb (GstDiscoverer *discoverer, GstDiscovererInfo *info, GError *err, CustomData *data) {
+ GstDiscovererResult result;
+ const gchar *uri;
+ const GstTagList *tags;
+ GstDiscovererStreamInfo *sinfo;
+
+ uri = gst_discoverer_info_get_uri (info);
+ result = gst_discoverer_info_get_result (info);
+ switch (result) {
+ case GST_DISCOVERER_URI_INVALID:
+ g_print ("Invalid URI '%s'\n", uri);
+ break;
+ case GST_DISCOVERER_ERROR:
+ g_print ("Discoverer error: %s\n", err->message);
+ break;
+ case GST_DISCOVERER_TIMEOUT:
+ g_print ("Timeout\n");
+ break;
+ case GST_DISCOVERER_BUSY:
+ g_print ("Busy\n");
+ break;
+ case GST_DISCOVERER_MISSING_PLUGINS:{
+ const GstStructure *s;
+ gchar *str;
+
+ s = gst_discoverer_info_get_misc (info);
+ str = gst_structure_to_string (s);
+
+ g_print ("Missing plugins: %s\n", str);
+ g_free (str);
+ break;
+ }
+ case GST_DISCOVERER_OK:
+ g_print ("Discovered '%s'\n", uri);
+ break;
+ }
+
+ if (result != GST_DISCOVERER_OK) {
+ g_printerr ("This URI cannot be played\n");
+ return;
+ }
+
+ /* If we got no error, show the retrieved information */
+
+ g_print ("\nDuration: %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (gst_discoverer_info_get_duration (info)));
+
+ tags = gst_discoverer_info_get_tags (info);
+ if (tags) {
+ g_print ("Tags:\n");
+ gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (1));
+ }
+
+ g_print ("Seekable: %s\n", (gst_discoverer_info_get_seekable (info) ? "yes" : "no"));
+
+ g_print ("\n");
+
+ sinfo = gst_discoverer_info_get_stream_info (info);
+ if (!sinfo)
+ return;
+
+ g_print ("Stream information:\n");
+
+ print_topology (sinfo, 1);
+
+ gst_discoverer_stream_info_unref (sinfo);
+
+ g_print ("\n");
+}
+
+/* This function is called when the discoverer has finished examining
+ * all the URIs we provided.*/
+static void on_finished_cb (GstDiscoverer *discoverer, CustomData *data) {
+ g_print ("Finished discovering\n");
+
+ g_main_loop_quit (data->loop);
+}
+
+int main (int argc, char **argv) {
+ CustomData data;
+ GError *err = NULL;
+ gchar *uri = "http://docs.gstreamer.com/media/sintel_trailer-480p.webm";
+
+ /* if a URI was provided, use it instead of the default one */
+ if (argc > 1) {
+ uri = argv[1];
+ }
+
+ /* Initialize cumstom data structure */
+ memset (&data, 0, sizeof (data));
+
+ /* Initialize GStreamer */
+ gst_init (&argc, &argv);
+
+ g_print ("Discovering '%s'\n", uri);
+
+ /* Instantiate the Discoverer */
+ data.discoverer = gst_discoverer_new (5 * GST_SECOND, &err);
+ if (!data.discoverer) {
+ g_print ("Error creating discoverer instance: %s\n", err->message);
+ g_clear_error (&err);
+ return -1;
+ }
+
+ /* Connect to the interesting signals */
+ g_signal_connect (data.discoverer, "discovered", G_CALLBACK (on_discovered_cb), &data);
+ g_signal_connect (data.discoverer, "finished", G_CALLBACK (on_finished_cb), &data);
+
+ /* Start the discoverer process (nothing to do yet) */
+ gst_discoverer_start (data.discoverer);
+
+ /* Add a request to process asynchronously the URI passed through the command line */
+ if (!gst_discoverer_discover_uri_async (data.discoverer, uri)) {
+ g_print ("Failed to start discovering URI '%s'\n", uri);
+ g_object_unref (data.discoverer);
+ return -1;
+ }
+
+ /* Create a GLib Main Loop and set it to run, so we can wait for the signals */
+ data.loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (data.loop);
+
+ /* Stop the discoverer process */
+ gst_discoverer_stop (data.discoverer);
+
+ /* Free resources */
+ g_object_unref (data.discoverer);
+ g_main_loop_unref (data.loop);
+
+ return 0;
}
\ No newline at end of file