Split out documentation into subfolders.
[platform/upstream/gstreamer.git] / examples / tutorials / playback-tutorial-1.c
similarity index 96%
rename from tutorials/playback-tutorial-1.c
rename to examples/tutorials/playback-tutorial-1.c
index b142fa7..f1987f3 100644 (file)
-#include <stdio.h>\r
-#include <gst/gst.h>\r
-  \r
-/* Structure to contain all our information, so we can pass it around */\r
-typedef struct _CustomData {\r
-  GstElement *playbin;  /* Our one and only element */\r
-  \r
-  gint n_video;          /* Number of embedded video streams */\r
-  gint n_audio;          /* Number of embedded audio streams */\r
-  gint n_text;           /* Number of embedded subtitle streams */\r
-  \r
-  gint current_video;    /* Currently playing video stream */\r
-  gint current_audio;    /* Currently playing audio stream */\r
-  gint current_text;     /* Currently playing subtitle stream */\r
-  \r
-  GMainLoop *main_loop;  /* GLib's Main Loop */\r
-} CustomData;\r
-  \r
-/* playbin flags */\r
-typedef enum {\r
-  GST_PLAY_FLAG_VIDEO         = (1 << 0), /* We want video output */\r
-  GST_PLAY_FLAG_AUDIO         = (1 << 1), /* We want audio output */\r
-  GST_PLAY_FLAG_TEXT          = (1 << 2)  /* We want subtitle output */\r
-} GstPlayFlags;\r
-  \r
-/* Forward definition for the message and keyboard processing functions */\r
-static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data);\r
-static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data);\r
-  \r
-int main(int argc, char *argv[]) {\r
-  CustomData data;\r
-  GstBus *bus;\r
-  GstStateChangeReturn ret;\r
-  gint flags;\r
-  GIOChannel *io_stdin;\r
-  \r
-  /* Initialize GStreamer */\r
-  gst_init (&argc, &argv);\r
-   \r
-  /* Create the elements */\r
-  data.playbin = gst_element_factory_make ("playbin", "playbin");\r
-  \r
-  if (!data.playbin) {\r
-    g_printerr ("Not all elements could be created.\n");\r
-    return -1;\r
-  }\r
-  \r
-  /* Set the URI to play */\r
-  g_object_set (data.playbin, "uri", "https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_cropped_multilingual.webm", NULL);\r
-  \r
-  /* Set flags to show Audio and Video but ignore Subtitles */\r
-  g_object_get (data.playbin, "flags", &flags, NULL);\r
-  flags |= GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO;\r
-  flags &= ~GST_PLAY_FLAG_TEXT;\r
-  g_object_set (data.playbin, "flags", flags, NULL);\r
-  \r
-  /* Set connection speed. This will affect some internal decisions of playbin */\r
-  g_object_set (data.playbin, "connection-speed", 56, NULL);\r
-  \r
-  /* Add a bus watch, so we get notified when a message arrives */\r
-  bus = gst_element_get_bus (data.playbin);\r
-  gst_bus_add_watch (bus, (GstBusFunc)handle_message, &data);\r
-  \r
-  /* Add a keyboard watch so we get notified of keystrokes */\r
-#ifdef G_OS_WIN32\r
-  io_stdin = g_io_channel_win32_new_fd (fileno (stdin));\r
-#else\r
-  io_stdin = g_io_channel_unix_new (fileno (stdin));\r
-#endif\r
-  g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data);\r
-  \r
-  /* Start playing */\r
-  ret = gst_element_set_state (data.playbin, GST_STATE_PLAYING);\r
-  if (ret == GST_STATE_CHANGE_FAILURE) {\r
-    g_printerr ("Unable to set the pipeline to the playing state.\n");\r
-    gst_object_unref (data.playbin);\r
-    return -1;\r
-  }\r
-  \r
-  /* Create a GLib Main Loop and set it to run */\r
-  data.main_loop = g_main_loop_new (NULL, FALSE);\r
-  g_main_loop_run (data.main_loop);\r
-  \r
-  /* Free resources */\r
-  g_main_loop_unref (data.main_loop);\r
-  g_io_channel_unref (io_stdin);\r
-  gst_object_unref (bus);\r
-  gst_element_set_state (data.playbin, GST_STATE_NULL);\r
-  gst_object_unref (data.playbin);\r
-  return 0;\r
-}\r
-  \r
-/* Extract some metadata from the streams and print it on the screen */\r
-static void analyze_streams (CustomData *data) {\r
-  gint i;\r
-  GstTagList *tags;\r
-  gchar *str;\r
-  guint rate;\r
-  \r
-  /* Read some properties */\r
-  g_object_get (data->playbin, "n-video", &data->n_video, NULL);\r
-  g_object_get (data->playbin, "n-audio", &data->n_audio, NULL);\r
-  g_object_get (data->playbin, "n-text", &data->n_text, NULL);\r
-  \r
-  g_print ("%d video stream(s), %d audio stream(s), %d text stream(s)\n",\r
-    data->n_video, data->n_audio, data->n_text);\r
-  \r
-  g_print ("\n");\r
-  for (i = 0; i < data->n_video; i++) {\r
-    tags = NULL;\r
-    /* Retrieve the stream's video tags */\r
-    g_signal_emit_by_name (data->playbin, "get-video-tags", i, &tags);\r
-    if (tags) {\r
-      g_print ("video stream %d:\n", i);\r
-      gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str);\r
-      g_print ("  codec: %s\n", str ? str : "unknown");\r
-      g_free (str);\r
-      gst_tag_list_unref (tags);\r
-    }\r
-  }\r
-  \r
-  g_print ("\n");\r
-  for (i = 0; i < data->n_audio; i++) {\r
-    tags = NULL;\r
-    /* Retrieve the stream's audio tags */\r
-    g_signal_emit_by_name (data->playbin, "get-audio-tags", i, &tags);\r
-    if (tags) {\r
-      g_print ("audio stream %d:\n", i);\r
-      if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str)) {\r
-        g_print ("  codec: %s\n", str);\r
-        g_free (str);\r
-      }\r
-      if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) {\r
-        g_print ("  language: %s\n", str);\r
-        g_free (str);\r
-      }\r
-      if (gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate)) {\r
-        g_print ("  bitrate: %d\n", rate);\r
-      }\r
-      gst_tag_list_unref (tags);\r
-    }\r
-  }\r
-  \r
-  g_print ("\n");\r
-  for (i = 0; i < data->n_text; i++) {\r
-    tags = NULL;\r
-    /* Retrieve the stream's subtitle tags */\r
-    g_signal_emit_by_name (data->playbin, "get-text-tags", i, &tags);\r
-    if (tags) {\r
-      g_print ("subtitle stream %d:\n", i);\r
-      if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) {\r
-        g_print ("  language: %s\n", str);\r
-        g_free (str);\r
-      }\r
-      gst_tag_list_unref (tags);\r
-    }\r
-  }\r
-  \r
-  g_object_get (data->playbin, "current-video", &data->current_video, NULL);\r
-  g_object_get (data->playbin, "current-audio", &data->current_audio, NULL);\r
-  g_object_get (data->playbin, "current-text", &data->current_text, NULL);\r
-  \r
-  g_print ("\n");\r
-  g_print ("Currently playing video stream %d, audio stream %d and text stream %d\n",\r
-    data->current_video, data->current_audio, data->current_text);\r
-  g_print ("Type any number and hit ENTER to select a different audio stream\n");\r
-}\r
-  \r
-/* Process messages from GStreamer */\r
-static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data) {\r
-  GError *err;\r
-  gchar *debug_info;\r
-  \r
-  switch (GST_MESSAGE_TYPE (msg)) {\r
-    case GST_MESSAGE_ERROR:\r
-      gst_message_parse_error (msg, &err, &debug_info);\r
-      g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);\r
-      g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");\r
-      g_clear_error (&err);\r
-      g_free (debug_info);\r
-      g_main_loop_quit (data->main_loop);\r
-      break;\r
-    case GST_MESSAGE_EOS:\r
-      g_print ("End-Of-Stream reached.\n");\r
-      g_main_loop_quit (data->main_loop);\r
-      break;\r
-    case GST_MESSAGE_STATE_CHANGED: {\r
-      GstState old_state, new_state, pending_state;\r
-      gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);\r
-      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin)) {\r
-        if (new_state == GST_STATE_PLAYING) {\r
-          /* Once we are in the playing state, analyze the streams */\r
-          analyze_streams (data);\r
-        }\r
-      }\r
-    } break;\r
-    default:\r
-      break;\r
-  }\r
-  \r
-  /* We want to keep receiving messages */\r
-  return TRUE;\r
-}\r
-  \r
-/* Process keyboard input */\r
-static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) {\r
-  gchar *str = NULL;\r
-  \r
-  if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) {\r
-    int index = g_ascii_strtoull (str, NULL, 0);\r
-    if (index < 0 || index >= data->n_audio) {\r
-      g_printerr ("Index out of bounds\n");\r
-    } else {\r
-      /* If the input was a valid audio stream index, set the current audio stream */\r
-      g_print ("Setting current audio stream to %d\n", index);\r
-      g_object_set (data->playbin, "current-audio", index, NULL);\r
-    }\r
-  }\r
-  g_free (str);\r
-  return TRUE;\r
-}\r
+#include <stdio.h>
+#include <gst/gst.h>
+
+/* Structure to contain all our information, so we can pass it around */
+typedef struct _CustomData {
+  GstElement *playbin;  /* Our one and only element */
+
+  gint n_video;          /* Number of embedded video streams */
+  gint n_audio;          /* Number of embedded audio streams */
+  gint n_text;           /* Number of embedded subtitle streams */
+
+  gint current_video;    /* Currently playing video stream */
+  gint current_audio;    /* Currently playing audio stream */
+  gint current_text;     /* Currently playing subtitle stream */
+
+  GMainLoop *main_loop;  /* GLib's Main Loop */
+} CustomData;
+
+/* playbin flags */
+typedef enum {
+  GST_PLAY_FLAG_VIDEO         = (1 << 0), /* We want video output */
+  GST_PLAY_FLAG_AUDIO         = (1 << 1), /* We want audio output */
+  GST_PLAY_FLAG_TEXT          = (1 << 2)  /* We want subtitle output */
+} GstPlayFlags;
+
+/* Forward definition for the message and keyboard processing functions */
+static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data);
+static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data);
+
+int main(int argc, char *argv[]) {
+  CustomData data;
+  GstBus *bus;
+  GstStateChangeReturn ret;
+  gint flags;
+  GIOChannel *io_stdin;
+
+  /* Initialize GStreamer */
+  gst_init (&argc, &argv);
+
+  /* Create the elements */
+  data.playbin = gst_element_factory_make ("playbin", "playbin");
+
+  if (!data.playbin) {
+    g_printerr ("Not all elements could be created.\n");
+    return -1;
+  }
+
+  /* Set the URI to play */
+  g_object_set (data.playbin, "uri", "https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_cropped_multilingual.webm", NULL);
+
+  /* Set flags to show Audio and Video but ignore Subtitles */
+  g_object_get (data.playbin, "flags", &flags, NULL);
+  flags |= GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO;
+  flags &= ~GST_PLAY_FLAG_TEXT;
+  g_object_set (data.playbin, "flags", flags, NULL);
+
+  /* Set connection speed. This will affect some internal decisions of playbin */
+  g_object_set (data.playbin, "connection-speed", 56, NULL);
+
+  /* Add a bus watch, so we get notified when a message arrives */
+  bus = gst_element_get_bus (data.playbin);
+  gst_bus_add_watch (bus, (GstBusFunc)handle_message, &data);
+
+  /* Add a keyboard watch so we get notified of keystrokes */
+#ifdef G_OS_WIN32
+  io_stdin = g_io_channel_win32_new_fd (fileno (stdin));
+#else
+  io_stdin = g_io_channel_unix_new (fileno (stdin));
+#endif
+  g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc)handle_keyboard, &data);
+
+  /* Start playing */
+  ret = gst_element_set_state (data.playbin, GST_STATE_PLAYING);
+  if (ret == GST_STATE_CHANGE_FAILURE) {
+    g_printerr ("Unable to set the pipeline to the playing state.\n");
+    gst_object_unref (data.playbin);
+    return -1;
+  }
+
+  /* Create a GLib Main Loop and set it to run */
+  data.main_loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (data.main_loop);
+
+  /* Free resources */
+  g_main_loop_unref (data.main_loop);
+  g_io_channel_unref (io_stdin);
+  gst_object_unref (bus);
+  gst_element_set_state (data.playbin, GST_STATE_NULL);
+  gst_object_unref (data.playbin);
+  return 0;
+}
+
+/* Extract some metadata from the streams and print it on the screen */
+static void analyze_streams (CustomData *data) {
+  gint i;
+  GstTagList *tags;
+  gchar *str;
+  guint rate;
+
+  /* Read some properties */
+  g_object_get (data->playbin, "n-video", &data->n_video, NULL);
+  g_object_get (data->playbin, "n-audio", &data->n_audio, NULL);
+  g_object_get (data->playbin, "n-text", &data->n_text, NULL);
+
+  g_print ("%d video stream(s), %d audio stream(s), %d text stream(s)\n",
+    data->n_video, data->n_audio, data->n_text);
+
+  g_print ("\n");
+  for (i = 0; i < data->n_video; i++) {
+    tags = NULL;
+    /* Retrieve the stream's video tags */
+    g_signal_emit_by_name (data->playbin, "get-video-tags", i, &tags);
+    if (tags) {
+      g_print ("video stream %d:\n", i);
+      gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str);
+      g_print ("  codec: %s\n", str ? str : "unknown");
+      g_free (str);
+      gst_tag_list_unref (tags);
+    }
+  }
+
+  g_print ("\n");
+  for (i = 0; i < data->n_audio; i++) {
+    tags = NULL;
+    /* Retrieve the stream's audio tags */
+    g_signal_emit_by_name (data->playbin, "get-audio-tags", i, &tags);
+    if (tags) {
+      g_print ("audio stream %d:\n", i);
+      if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str)) {
+        g_print ("  codec: %s\n", str);
+        g_free (str);
+      }
+      if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) {
+        g_print ("  language: %s\n", str);
+        g_free (str);
+      }
+      if (gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate)) {
+        g_print ("  bitrate: %d\n", rate);
+      }
+      gst_tag_list_unref (tags);
+    }
+  }
+
+  g_print ("\n");
+  for (i = 0; i < data->n_text; i++) {
+    tags = NULL;
+    /* Retrieve the stream's subtitle tags */
+    g_signal_emit_by_name (data->playbin, "get-text-tags", i, &tags);
+    if (tags) {
+      g_print ("subtitle stream %d:\n", i);
+      if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) {
+        g_print ("  language: %s\n", str);
+        g_free (str);
+      }
+      gst_tag_list_unref (tags);
+    }
+  }
+
+  g_object_get (data->playbin, "current-video", &data->current_video, NULL);
+  g_object_get (data->playbin, "current-audio", &data->current_audio, NULL);
+  g_object_get (data->playbin, "current-text", &data->current_text, NULL);
+
+  g_print ("\n");
+  g_print ("Currently playing video stream %d, audio stream %d and text stream %d\n",
+    data->current_video, data->current_audio, data->current_text);
+  g_print ("Type any number and hit ENTER to select a different audio stream\n");
+}
+
+/* Process messages from GStreamer */
+static gboolean handle_message (GstBus *bus, GstMessage *msg, CustomData *data) {
+  GError *err;
+  gchar *debug_info;
+
+  switch (GST_MESSAGE_TYPE (msg)) {
+    case GST_MESSAGE_ERROR:
+      gst_message_parse_error (msg, &err, &debug_info);
+      g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
+      g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
+      g_clear_error (&err);
+      g_free (debug_info);
+      g_main_loop_quit (data->main_loop);
+      break;
+    case GST_MESSAGE_EOS:
+      g_print ("End-Of-Stream reached.\n");
+      g_main_loop_quit (data->main_loop);
+      break;
+    case GST_MESSAGE_STATE_CHANGED: {
+      GstState old_state, new_state, pending_state;
+      gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
+      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->playbin)) {
+        if (new_state == GST_STATE_PLAYING) {
+          /* Once we are in the playing state, analyze the streams */
+          analyze_streams (data);
+        }
+      }
+    } break;
+    default:
+      break;
+  }
+
+  /* We want to keep receiving messages */
+  return TRUE;
+}
+
+/* Process keyboard input */
+static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data) {
+  gchar *str = NULL;
+
+  if (g_io_channel_read_line (source, &str, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) {
+    int index = g_ascii_strtoull (str, NULL, 0);
+    if (index < 0 || index >= data->n_audio) {
+      g_printerr ("Index out of bounds\n");
+    } else {
+      /* If the input was a valid audio stream index, set the current audio stream */
+      g_print ("Setting current audio stream to %d\n", index);
+      g_object_set (data->playbin, "current-audio", index, NULL);
+    }
+  }
+  g_free (str);
+  return TRUE;
+}