examples/seeking/: Added some more examples, update others.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 25 Oct 2004 17:43:51 +0000 (17:43 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 25 Oct 2004 17:43:51 +0000 (17:43 +0000)
Original commit message from CVS:
* examples/seeking/Makefile.am:
* examples/seeking/cdplayer.c: (update_scale):
* examples/seeking/chained.c: (unlinked), (new_pad), (main):
* examples/seeking/playbin.c: (make_playerbin_pipeline),
(format_value), (update_scale), (iterate), (start_seek),
(stop_seek), (print_media_info), (play_cb), (pause_cb), (stop_cb),
(print_usage), (main):
Added some more examples, update others.

ChangeLog
examples/seeking/Makefile.am
examples/seeking/cdplayer.c
examples/seeking/chained.c [new file with mode: 0644]
examples/seeking/playbin.c [new file with mode: 0644]

index 683be3b..dbcc3f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-10-25  Wim Taymans  <wim@fluendo.com>
+
+       * examples/seeking/Makefile.am:
+       * examples/seeking/cdplayer.c: (update_scale):
+       * examples/seeking/chained.c: (unlinked), (new_pad), (main):
+       * examples/seeking/playbin.c: (make_playerbin_pipeline),
+       (format_value), (update_scale), (iterate), (start_seek),
+       (stop_seek), (print_media_info), (play_cb), (pause_cb), (stop_cb),
+       (print_usage), (main):
+       Added some more examples, update others.
+
 2004-10-25  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * ext/flac/gstflacdec.c: (gst_flacdec_update_metadata):
index 3d99ee2..582306a 100644 (file)
@@ -1,4 +1,4 @@
-examples = seek spider_seek cdplayer cdparanoia vorbisfile
+examples = seek spider_seek cdplayer cdparanoia vorbisfile playbin chained
 
 noinst_PROGRAMS = $(examples)
 
index afccaa8..73ab9cf 100644 (file)
@@ -131,9 +131,8 @@ update_scale (gpointer data)
     GstElement *element = GST_ELEMENT (seekable_elements->data);
 
     gst_element_query (element, GST_QUERY_TOTAL, &format, &duration);
+    gst_element_query (element, GST_QUERY_POSITION, &format, &position);
   }
-  if (clock)
-    position = gst_clock_get_time (clock);
 
   if (stats) {
     if (clock)
diff --git a/examples/seeking/chained.c b/examples/seeking/chained.c
new file mode 100644 (file)
index 0000000..5bd0e12
--- /dev/null
@@ -0,0 +1,104 @@
+#include <stdlib.h>
+#include <gst/gst.h>
+#include <string.h>
+
+static GstElement *bin;
+
+static void
+unlinked (GstPad * pad, GstPad * peerpad, GstElement * pipeline)
+{
+  gst_element_set_state (pipeline, GST_STATE_PAUSED);
+  gst_bin_remove (GST_BIN (pipeline), bin);
+  gst_element_set_state (bin, GST_STATE_READY);
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+}
+
+static void
+new_pad (GstElement * elem, GstPad * newpad, GstElement * pipeline)
+{
+  GstScheduler *sched;
+  GstClock *clock;
+
+  g_print ("new pad %s\n", gst_pad_get_name (newpad));
+
+  gst_element_set_state (pipeline, GST_STATE_PAUSED);
+  gst_bin_add (GST_BIN (pipeline), bin);
+
+  sched = gst_element_get_scheduler (GST_ELEMENT (pipeline));
+  clock = gst_scheduler_get_clock (sched);
+  gst_scheduler_set_clock (sched, clock);
+
+  gst_pad_link (newpad, gst_element_get_pad (bin, "sink"));
+
+  g_signal_connect (G_OBJECT (newpad), "unlinked", G_CALLBACK (unlinked),
+      pipeline);
+
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+}
+
+int
+main (int argc, char **argv)
+{
+  GstElement *pipeline;
+  GstElement *filesrc;
+  GstElement *oggdemux;
+  GstElement *vorbisdec;
+  GstElement *audioconvert;
+  GstElement *osssink;
+
+  gst_init (&argc, &argv);
+
+  if (argc < 2) {
+    g_print ("usage: %s <oggfile>\n", argv[0]);
+    return (-1);
+  }
+
+  pipeline = gst_pipeline_new ("pipeline");
+
+  filesrc = gst_element_factory_make ("filesrc", "filesrc");
+  g_assert (filesrc);
+  g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
+
+  oggdemux = gst_element_factory_make ("oggdemux", "oggdemux");
+  g_assert (oggdemux);
+
+  gst_bin_add (GST_BIN (pipeline), filesrc);
+  gst_bin_add (GST_BIN (pipeline), oggdemux);
+
+  gst_element_link_pads (filesrc, "src", oggdemux, "sink");
+
+  g_signal_connect (G_OBJECT (oggdemux), "new_pad", G_CALLBACK (new_pad),
+      pipeline);
+
+  bin = gst_bin_new ("bin");
+  vorbisdec = gst_element_factory_make ("vorbisdec", "vorbisdec");
+  g_assert (vorbisdec);
+  audioconvert = gst_element_factory_make ("audioconvert", "audioconvert");
+  g_assert (audioconvert);
+  osssink = gst_element_factory_make ("osssink", "osssink");
+  g_assert (osssink);
+  gst_bin_add (GST_BIN (bin), vorbisdec);
+  gst_bin_add (GST_BIN (bin), audioconvert);
+  gst_bin_add (GST_BIN (bin), osssink);
+
+  gst_element_link_pads (vorbisdec, "src", audioconvert, "sink");
+  gst_element_link_pads (audioconvert, "src", osssink, "sink");
+
+  gst_element_add_ghost_pad (bin, gst_element_get_pad (vorbisdec, "sink"),
+      "sink");
+
+  g_object_ref (G_OBJECT (bin));
+
+  g_signal_connect (pipeline, "deep_notify",
+      G_CALLBACK (gst_element_default_deep_notify), NULL);
+
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  while (gst_bin_iterate (GST_BIN (pipeline)))
+    /* nop */ ;
+
+  /* stop probe */
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+
+  return 0;
+}
diff --git a/examples/seeking/playbin.c b/examples/seeking/playbin.c
new file mode 100644 (file)
index 0000000..b6ff35b
--- /dev/null
@@ -0,0 +1,270 @@
+#include <stdlib.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gst/gst.h>
+#include <string.h>
+
+static GstElement *playbin = NULL;
+static GstElement *pipeline;
+static guint64 duration;
+static GtkAdjustment *adjustment;
+static GtkWidget *hscale;
+static gboolean verbose = FALSE;
+
+static guint update_id;
+
+#define UPDATE_INTERVAL 500
+
+static GstElement *
+make_playerbin_pipeline (const gchar * location)
+{
+  playbin = gst_element_factory_make ("playbin", "player");
+  g_assert (playbin);
+
+  g_object_set (G_OBJECT (playbin), "uri", location, NULL);
+
+  return playbin;
+}
+
+static gchar *
+format_value (GtkScale * scale, gdouble value)
+{
+  gint64 real;
+  gint64 seconds;
+  gint64 subseconds;
+
+  real = value * duration / 100;
+  seconds = (gint64) real / GST_SECOND;
+  subseconds = (gint64) real / (GST_SECOND / 100);
+
+  return g_strdup_printf ("%02" G_GINT64_FORMAT ":%02" G_GINT64_FORMAT ":%02"
+      G_GINT64_FORMAT, seconds / 60, seconds % 60, subseconds % 100);
+}
+
+static gboolean
+update_scale (gpointer data)
+{
+  GstClock *clock;
+  guint64 position;
+  GstFormat format = GST_FORMAT_TIME;
+  gboolean res;
+
+  duration = 0;
+  clock = gst_bin_get_clock (GST_BIN (pipeline));
+
+  res = gst_element_query (playbin, GST_QUERY_TOTAL, &format, &duration);
+  if (!res)
+    duration = 0;
+  res = gst_element_query (playbin, GST_QUERY_POSITION, &format, &position);
+  if (!res)
+    position = 0;
+
+  if (position >= duration)
+    duration = position;
+
+  if (duration > 0) {
+    gtk_adjustment_set_value (adjustment, position * 100.0 / duration);
+    gtk_widget_queue_draw (hscale);
+  }
+
+  return TRUE;
+}
+
+static gboolean
+iterate (gpointer data)
+{
+  gboolean res;
+
+  if (!GST_FLAG_IS_SET (GST_OBJECT (data), GST_BIN_SELF_SCHEDULABLE)) {
+    res = gst_bin_iterate (GST_BIN (data));
+  } else {
+    g_usleep (UPDATE_INTERVAL);
+    res = gst_element_get_state (GST_ELEMENT (data)) == GST_STATE_PLAYING;
+  }
+
+  if (!res) {
+    gtk_timeout_remove (update_id);
+    g_print ("stopping iterations\n");
+  }
+  return res;
+}
+
+static gboolean
+start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
+{
+  gst_element_set_state (pipeline, GST_STATE_PAUSED);
+  gtk_timeout_remove (update_id);
+
+  return FALSE;
+}
+
+static gboolean
+stop_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
+{
+  gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100;
+  gboolean res;
+  GstEvent *s_event;
+
+  g_print ("seek to %" G_GINT64_FORMAT " on element %s\n", real,
+      gst_element_get_name (playbin));
+  s_event =
+      gst_event_new_seek (GST_FORMAT_TIME | GST_SEEK_METHOD_SET |
+      GST_SEEK_FLAG_FLUSH, real);
+
+  res = gst_element_send_event (playbin, s_event);
+
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+  gtk_idle_add ((GtkFunction) iterate, pipeline);
+  update_id =
+      gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
+
+  return FALSE;
+}
+
+static void
+print_media_info (GstElement * playbin)
+{
+  GList *streaminfo;
+  GList *s;
+
+  g_print ("have media info now\n");
+
+  /* get info about the stream */
+  g_object_get (G_OBJECT (playbin), "stream-info", &streaminfo, NULL);
+
+  for (s = streaminfo; s; s = g_list_next (s)) {
+    GObject *obj = G_OBJECT (s->data);
+    gint type;
+    gboolean mute;
+
+    g_object_get (obj, "type", &type, NULL);
+    g_object_get (obj, "mute", &mute, NULL);
+
+    g_print ("%d %d\n", type, mute);
+  }
+}
+
+static void
+play_cb (GtkButton * button, gpointer data)
+{
+  if (gst_element_get_state (pipeline) != GST_STATE_PLAYING) {
+    GstElementStateReturn res;
+
+    res = gst_element_set_state (pipeline, GST_STATE_PAUSED);
+    if (res == GST_STATE_SUCCESS) {
+      print_media_info (playbin);
+
+      res = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+      gtk_idle_add ((GtkFunction) iterate, pipeline);
+      update_id =
+          gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale,
+          pipeline);
+    } else {
+      g_print ("failed playing\n");
+    }
+  }
+}
+
+static void
+pause_cb (GtkButton * button, gpointer data)
+{
+  if (gst_element_get_state (pipeline) != GST_STATE_PAUSED) {
+    gst_element_set_state (pipeline, GST_STATE_PAUSED);
+    gtk_timeout_remove (update_id);
+  }
+}
+
+static void
+stop_cb (GtkButton * button, gpointer data)
+{
+  if (gst_element_get_state (pipeline) != GST_STATE_READY) {
+    gst_element_set_state (pipeline, GST_STATE_READY);
+    gtk_adjustment_set_value (adjustment, 0.0);
+    gtk_timeout_remove (update_id);
+  }
+}
+
+static void
+print_usage (int argc, char **argv)
+{
+  g_print ("usage: %s <uri>\n", argv[0]);
+}
+
+int
+main (int argc, char **argv)
+{
+  GtkWidget *window, *hbox, *vbox, *play_button, *pause_button, *stop_button;
+  struct poptOption options[] = {
+    {"verbose", 'v', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &verbose, 0,
+        "Verbose properties", NULL},
+    POPT_TABLEEND
+  };
+
+  gst_init_with_popt_table (&argc, &argv, options);
+  gtk_init (&argc, &argv);
+
+  if (argc != 2) {
+    print_usage (argc, argv);
+    exit (-1);
+  }
+
+  pipeline = make_playerbin_pipeline (argv[1]);
+  g_assert (pipeline);
+
+  /* initialize gui elements ... */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  hbox = gtk_hbox_new (FALSE, 0);
+  vbox = gtk_vbox_new (FALSE, 0);
+  play_button = gtk_button_new_with_label ("play");
+  pause_button = gtk_button_new_with_label ("pause");
+  stop_button = gtk_button_new_with_label ("stop");
+
+  adjustment =
+      GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.00, 100.0, 0.1, 1.0, 1.0));
+  hscale = gtk_hscale_new (adjustment);
+  gtk_scale_set_digits (GTK_SCALE (hscale), 2);
+  gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_CONTINUOUS);
+
+  gtk_signal_connect (GTK_OBJECT (hscale),
+      "button_press_event", G_CALLBACK (start_seek), pipeline);
+  gtk_signal_connect (GTK_OBJECT (hscale),
+      "button_release_event", G_CALLBACK (stop_seek), pipeline);
+  gtk_signal_connect (GTK_OBJECT (hscale),
+      "format_value", G_CALLBACK (format_value), pipeline);
+
+  /* do the packing stuff ... */
+  gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_container_add (GTK_CONTAINER (vbox), hbox);
+  gtk_box_pack_start (GTK_BOX (hbox), play_button, FALSE, FALSE, 2);
+  gtk_box_pack_start (GTK_BOX (hbox), pause_button, FALSE, FALSE, 2);
+  gtk_box_pack_start (GTK_BOX (hbox), stop_button, FALSE, FALSE, 2);
+  gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
+
+  /* connect things ... */
+  g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
+      pipeline);
+  g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
+      pipeline);
+  g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
+      pipeline);
+  g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
+
+  /* show the gui. */
+  gtk_widget_show_all (window);
+
+  if (verbose) {
+    g_signal_connect (pipeline, "deep_notify",
+        G_CALLBACK (gst_element_default_deep_notify), NULL);
+  }
+  g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error),
+      NULL);
+
+  gtk_main ();
+
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+
+  gst_object_unref (GST_OBJECT (pipeline));
+
+  return 0;
+}