Blame tests/examples/seek/scrubby.c

Packit 971217
/* GStreamer
Packit 971217
 *
Packit 971217
 * scrubby.c: sample application to change the playback speed dynamically
Packit 971217
 *
Packit 971217
 * Copyright (C) 2005 Wim Taymans <wim.taymans@gmail.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
Packit 971217
#ifdef HAVE_CONFIG_H
Packit 971217
#include "config.h"
Packit 971217
#endif
Packit 971217
#include <stdlib.h>
Packit 971217
#include <glib.h>
Packit 971217
#include <gtk/gtk.h>
Packit 971217
#include <gst/gst.h>
Packit 971217
#include <string.h>
Packit 971217
Packit 971217
GST_DEBUG_CATEGORY_STATIC (scrubby_debug);
Packit 971217
#define GST_CAT_DEFAULT (scrubby_debug)
Packit 971217
Packit 971217
static GstElement *pipeline;
Packit 971217
static gint64 position;
Packit 971217
static gint64 duration;
Packit 971217
static GtkAdjustment *adjustment;
Packit 971217
static GtkWidget *hscale;
Packit 971217
static GtkAdjustment *sadjustment;
Packit 971217
static GtkWidget *shscale;
Packit 971217
static gboolean verbose = FALSE;
Packit 971217
Packit 971217
static guint bus_watch = 0;
Packit 971217
static guint update_id = 0;
Packit 971217
static guint changed_id = 0;
Packit 971217
static guint schanged_id = 0;
Packit 971217
Packit 971217
#define SOURCE "filesrc"
Packit 971217
#define ASINK   "autoaudiosink"
Packit 971217
//#define ASINK "alsasink"
Packit 971217
//#define ASINK "osssink"
Packit 971217
#define VSINK   "autovideosink"
Packit 971217
//#define VSINK "xvimagesink"
Packit 971217
//#define VSINK "ximagesink"
Packit 971217
//#define VSINK "aasink"
Packit 971217
//#define VSINK "cacasink"
Packit 971217
Packit 971217
#define RANGE_PREC 10000
Packit 971217
#define SEGMENT_LEN 100
Packit 971217
#define UPDATE_INTERVAL 500
Packit 971217
Packit 971217
static gdouble prev_range = -1.0;
Packit 971217
static GstClockTime prev_time = GST_CLOCK_TIME_NONE;
Packit 971217
static gdouble cur_range;
Packit 971217
static GstClockTime cur_time;
Packit 971217
static GstClockTimeDiff diff;
Packit 971217
static gdouble cur_speed = 1.0;
Packit 971217
Packit 971217
typedef struct
Packit 971217
{
Packit 971217
  const gchar *padname;
Packit 971217
  GstPad *target;
Packit 971217
  GstElement *bin;
Packit 971217
}
Packit 971217
dyn_link;
Packit 971217
Packit 971217
static GstElement *
Packit 971217
gst_element_factory_make_or_warn (const gchar * type, const gchar * name)
Packit 971217
{
Packit 971217
  GstElement *element = gst_element_factory_make (type, name);
Packit 971217
Packit 971217
  if (!element) {
Packit 971217
    g_warning ("Failed to create element %s of type %s", name, type);
Packit 971217
  }
Packit 971217
Packit 971217
  return element;
Packit 971217
}
Packit 971217
Packit 971217
static GstElement *
Packit 971217
make_wav_pipeline (const gchar * location)
Packit 971217
{
Packit 971217
  GstElement *pipeline;
Packit 971217
  GstElement *src, *decoder, *audiosink;
Packit 971217
Packit 971217
  pipeline = gst_pipeline_new ("app");
Packit 971217
Packit 971217
  src = gst_element_factory_make_or_warn (SOURCE, "src");
Packit 971217
  decoder = gst_element_factory_make_or_warn ("wavparse", "decoder");
Packit 971217
  audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
Packit 971217
Packit 971217
  g_object_set (G_OBJECT (src), "location", location, NULL);
Packit 971217
Packit 971217
  gst_bin_add_many (GST_BIN (pipeline), src, decoder, audiosink, NULL);
Packit 971217
  gst_element_link_many (src, decoder, audiosink, NULL);
Packit 971217
Packit 971217
  return pipeline;
Packit 971217
}
Packit 971217
Packit 971217
static GstElement *
Packit 971217
make_playerbin_pipeline (const gchar * location)
Packit 971217
{
Packit 971217
  GstElement *player;
Packit 971217
  const gchar *uri = g_filename_to_uri (location, NULL, NULL);
Packit 971217
Packit 971217
  player = gst_element_factory_make ("playbin", "player");
Packit 971217
  g_assert (player);
Packit 971217
Packit 971217
  g_object_set (G_OBJECT (player), "uri", uri, NULL);
Packit 971217
Packit 971217
  return player;
Packit 971217
}
Packit 971217
Packit 971217
static gchar *
Packit 971217
format_value (GtkScale * scale, gdouble value)
Packit 971217
{
Packit 971217
  gint64 real;
Packit 971217
  gint64 seconds;
Packit 971217
  gint64 subseconds;
Packit 971217
Packit 971217
  real = value * duration / RANGE_PREC;
Packit 971217
  seconds = (gint64) real / GST_SECOND;
Packit 971217
  subseconds = (gint64) real / (GST_SECOND / RANGE_PREC);
Packit 971217
Packit 971217
  return g_strdup_printf ("%02" G_GINT64_FORMAT ":%02" G_GINT64_FORMAT ":%02"
Packit 971217
      G_GINT64_FORMAT, seconds / 60, seconds % 60, subseconds % 100);
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
update_scale (gpointer data)
Packit 971217
{
Packit 971217
  position = 0;
Packit 971217
  duration = 0;
Packit 971217
Packit 971217
  gst_element_query_position (pipeline, GST_FORMAT_TIME, &position);
Packit 971217
  gst_element_query_duration (pipeline, GST_FORMAT_TIME, &duration);
Packit 971217
Packit 971217
  if (position >= duration)
Packit 971217
    duration = position;
Packit 971217
Packit 971217
  if (duration > 0) {
Packit 971217
    gtk_adjustment_set_value (adjustment,
Packit 971217
        position * (gdouble) RANGE_PREC / duration);
Packit 971217
    gtk_widget_queue_draw (hscale);
Packit 971217
  }
Packit 971217
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
speed_cb (GtkWidget * widget)
Packit 971217
{
Packit 971217
  GstEvent *s_event;
Packit 971217
  gboolean res;
Packit 971217
Packit 971217
  GST_DEBUG ("speed change");
Packit 971217
  cur_speed = gtk_range_get_value (GTK_RANGE (widget));
Packit 971217
Packit 971217
  if (cur_speed == 0.0)
Packit 971217
    return;
Packit 971217
Packit 971217
  s_event = gst_event_new_seek (cur_speed,
Packit 971217
      GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
Packit 971217
Packit 971217
  res = gst_element_send_event (pipeline, s_event);
Packit 971217
  if (!res)
Packit 971217
    g_print ("speed change failed\n");
Packit 971217
}
Packit 971217
Packit 971217
static gboolean do_seek (GtkWidget * widget, gboolean flush, gboolean segment);
Packit 971217
Packit 971217
static void
Packit 971217
seek_cb (GtkWidget * widget)
Packit 971217
{
Packit 971217
  if (changed_id) {
Packit 971217
    GST_DEBUG ("seek because of slider move");
Packit 971217
Packit 971217
    if (do_seek (widget, TRUE, TRUE)) {
Packit 971217
      g_signal_handler_disconnect (hscale, changed_id);
Packit 971217
      changed_id = 0;
Packit 971217
    }
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
do_seek (GtkWidget * widget, gboolean flush, gboolean segment)
Packit 971217
{
Packit 971217
  gint64 start, stop;
Packit 971217
  gboolean res = FALSE;
Packit 971217
  GstEvent *s_event;
Packit 971217
  gdouble rate;
Packit 971217
  GTimeVal tv;
Packit 971217
  gboolean valid;
Packit 971217
  gdouble new_range;
Packit 971217
Packit 971217
  if (segment)
Packit 971217
    new_range = gtk_range_get_value (GTK_RANGE (widget));
Packit 971217
  else {
Packit 971217
    new_range = (gdouble) RANGE_PREC;
Packit 971217
    cur_time = -1;
Packit 971217
  }
Packit 971217
Packit 971217
  valid = prev_time != -1;
Packit 971217
Packit 971217
  GST_DEBUG ("flush %d, segment %d, valid %d", flush, segment, valid);
Packit 971217
Packit 971217
  if (new_range == cur_range)
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  prev_time = cur_time;
Packit 971217
  prev_range = cur_range;
Packit 971217
Packit 971217
  cur_range = new_range;
Packit 971217
Packit 971217
  g_get_current_time (&tv;;
Packit 971217
  cur_time = GST_TIMEVAL_TO_TIME (tv);
Packit 971217
Packit 971217
  if (!valid)
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  GST_DEBUG ("cur:  %lf, %" GST_TIME_FORMAT, cur_range,
Packit 971217
      GST_TIME_ARGS (cur_time));
Packit 971217
  GST_DEBUG ("prev: %lf, %" GST_TIME_FORMAT, prev_range,
Packit 971217
      GST_TIME_ARGS (prev_time));
Packit 971217
Packit 971217
  diff = cur_time - prev_time;
Packit 971217
Packit 971217
  GST_DEBUG ("diff: %" GST_STIME_FORMAT, GST_STIME_ARGS (diff));
Packit 971217
Packit 971217
  start = prev_range * duration / RANGE_PREC;
Packit 971217
  /* play 50 milliseconds */
Packit 971217
  stop = segment ? cur_range * duration / RANGE_PREC : duration;
Packit 971217
Packit 971217
  if (start == stop)
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  if (segment)
Packit 971217
    rate = (stop - start) / (gdouble) diff;
Packit 971217
  else
Packit 971217
    rate = cur_speed;
Packit 971217
Packit 971217
  if (start > stop) {
Packit 971217
    gint64 tmp;
Packit 971217
Packit 971217
    tmp = start;
Packit 971217
    start = stop;
Packit 971217
    stop = tmp;
Packit 971217
  }
Packit 971217
Packit 971217
  if (rate == 0.0)
Packit 971217
    return TRUE;
Packit 971217
Packit 971217
  GST_DEBUG ("seek to %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT ", rate %lf"
Packit 971217
      " on element %s",
Packit 971217
      GST_TIME_ARGS (start), GST_TIME_ARGS (stop), rate,
Packit 971217
      GST_ELEMENT_NAME (pipeline));
Packit 971217
Packit 971217
  s_event = gst_event_new_seek (rate,
Packit 971217
      GST_FORMAT_TIME,
Packit 971217
      (flush ? GST_SEEK_FLAG_FLUSH : 0) |
Packit 971217
      (segment ? GST_SEEK_FLAG_SEGMENT : 0),
Packit 971217
      GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_SET, stop);
Packit 971217
Packit 971217
  res = gst_element_send_event (pipeline, s_event);
Packit 971217
  if (!res)
Packit 971217
    g_print ("seek failed\n");
Packit 971217
Packit 971217
  gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
Packit 971217
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
Packit 971217
{
Packit 971217
  if (update_id) {
Packit 971217
    g_source_remove (update_id);
Packit 971217
    update_id = 0;
Packit 971217
  }
Packit 971217
Packit 971217
  if (changed_id == 0) {
Packit 971217
    changed_id =
Packit 971217
        g_signal_connect (hscale, "value_changed", G_CALLBACK (seek_cb),
Packit 971217
        pipeline);
Packit 971217
  }
Packit 971217
Packit 971217
  GST_DEBUG ("start seek");
Packit 971217
Packit 971217
  return FALSE;
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
stop_seek (GtkWidget * widget, gpointer user_data)
Packit 971217
{
Packit 971217
  update_id =
Packit 971217
      g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, pipeline);
Packit 971217
Packit 971217
  GST_DEBUG ("stop seek");
Packit 971217
Packit 971217
  if (changed_id) {
Packit 971217
    g_signal_handler_disconnect (hscale, changed_id);
Packit 971217
    changed_id = 0;
Packit 971217
  }
Packit 971217
Packit 971217
  do_seek (hscale, FALSE, FALSE);
Packit 971217
Packit 971217
  return FALSE;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
play_cb (GtkButton * button, gpointer data)
Packit 971217
{
Packit 971217
  GstState state;
Packit 971217
Packit 971217
  gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
Packit 971217
  if (state != GST_STATE_PLAYING) {
Packit 971217
    g_print ("PLAY pipeline\n");
Packit 971217
    gst_element_set_state (pipeline, GST_STATE_PLAYING);
Packit 971217
    update_id =
Packit 971217
        g_timeout_add (UPDATE_INTERVAL, (GSourceFunc) update_scale, pipeline);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
pause_cb (GtkButton * button, gpointer data)
Packit 971217
{
Packit 971217
  GstState state;
Packit 971217
Packit 971217
  gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
Packit 971217
  if (state != GST_STATE_PAUSED) {
Packit 971217
    g_print ("PAUSE pipeline\n");
Packit 971217
    gst_element_set_state (pipeline, GST_STATE_PAUSED);
Packit 971217
    g_source_remove (update_id);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
stop_cb (GtkButton * button, gpointer data)
Packit 971217
{
Packit 971217
  GstState state;
Packit 971217
Packit 971217
  gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
Packit 971217
  if (state != GST_STATE_READY) {
Packit 971217
    g_print ("READY pipeline\n");
Packit 971217
    gst_element_set_state (pipeline, GST_STATE_READY);
Packit 971217
    /* position and speed return to their default values */
Packit 971217
    gtk_adjustment_set_value (adjustment, 0.0);
Packit 971217
    gtk_adjustment_set_value (sadjustment, 1.0);
Packit 971217
    g_source_remove (update_id);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
print_message (GstMessage * message)
Packit 971217
{
Packit 971217
  const GstStructure *s;
Packit 971217
Packit 971217
  s = gst_message_get_structure (message);
Packit 971217
  g_print ("Got Message from element \"%s\"\n",
Packit 971217
      GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))));
Packit 971217
Packit 971217
  if (s) {
Packit 971217
    gchar *sstr;
Packit 971217
Packit 971217
    sstr = gst_structure_to_string (s);
Packit 971217
    g_print ("%s\n", sstr);
Packit 971217
    g_free (sstr);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static gboolean
Packit 971217
bus_message (GstBus * bus, GstMessage * message, gpointer data)
Packit 971217
{
Packit 971217
  switch (GST_MESSAGE_TYPE (message)) {
Packit 971217
    case GST_MESSAGE_EOS:
Packit 971217
      g_print ("EOS\n");
Packit 971217
      break;
Packit 971217
    case GST_MESSAGE_ERROR:
Packit 971217
    case GST_MESSAGE_WARNING:
Packit 971217
      print_message (message);
Packit 971217
      break;
Packit 971217
    case GST_MESSAGE_SEGMENT_START:
Packit 971217
      break;
Packit 971217
    case GST_MESSAGE_SEGMENT_DONE:
Packit 971217
      GST_DEBUG ("segment_done, doing next seek");
Packit 971217
      if (!do_seek (hscale, FALSE, update_id == 0)) {
Packit 971217
        if (changed_id == 0) {
Packit 971217
          changed_id =
Packit 971217
              g_signal_connect (hscale, "value_changed", G_CALLBACK (seek_cb),
Packit 971217
              pipeline);
Packit 971217
        }
Packit 971217
      }
Packit 971217
      break;
Packit 971217
    default:
Packit 971217
      break;
Packit 971217
  }
Packit 971217
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
typedef struct
Packit 971217
{
Packit 971217
  const gchar *name;
Packit 971217
  GstElement *(*func) (const gchar * location);
Packit 971217
}
Packit 971217
Pipeline;
Packit 971217
Packit 971217
static Pipeline pipelines[] = {
Packit 971217
  {"wav", make_wav_pipeline},
Packit 971217
  {"playerbin", make_playerbin_pipeline},
Packit 971217
  {NULL, NULL},
Packit 971217
};
Packit 971217
Packit 971217
#define NUM_TYPES       ((sizeof (pipelines) / sizeof (Pipeline)) - 1)
Packit 971217
Packit 971217
static void
Packit 971217
print_usage (int argc, char **argv)
Packit 971217
{
Packit 971217
  gint i;
Packit 971217
Packit 971217
  g_print ("usage: %s <type> <filename>\n", argv[0]);
Packit 971217
  g_print ("   possible types:\n");
Packit 971217
Packit 971217
  for (i = 0; i < NUM_TYPES; i++) {
Packit 971217
    g_print ("     %d = %s\n", i, pipelines[i].name);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
int
Packit 971217
main (int argc, char **argv)
Packit 971217
{
Packit 971217
  GtkWidget *window, *hbox, *vbox, *play_button, *pause_button, *stop_button;
Packit 971217
  GstBus *bus;
Packit 971217
  GOptionEntry options[] = {
Packit 971217
    {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
Packit 971217
        "Verbose properties", NULL},
Packit 971217
    {NULL}
Packit 971217
  };
Packit 971217
  gint type;
Packit 971217
  GOptionContext *ctx;
Packit 971217
  GError *err = NULL;
Packit 971217
Packit 971217
  ctx = g_option_context_new ("seek");
Packit 971217
  g_option_context_add_main_entries (ctx, options, NULL);
Packit 971217
  g_option_context_add_group (ctx, gst_init_get_option_group ());
Packit 971217
Packit 971217
  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
Packit 971217
    g_print ("Error initializing: %s\n", err->message);
Packit 971217
    g_option_context_free (ctx);
Packit 971217
    g_clear_error (&err;;
Packit 971217
    exit (1);
Packit 971217
  }
Packit 971217
Packit 971217
  GST_DEBUG_CATEGORY_INIT (scrubby_debug, "scrubby", 0, "scrubby example");
Packit 971217
Packit 971217
  gtk_init (&argc, &argv);
Packit 971217
Packit 971217
  if (argc != 3) {
Packit 971217
    print_usage (argc, argv);
Packit 971217
    exit (-1);
Packit 971217
  }
Packit 971217
Packit 971217
  type = atoi (argv[1]);
Packit 971217
Packit 971217
  if (type < 0 || type >= NUM_TYPES) {
Packit 971217
    print_usage (argc, argv);
Packit 971217
    exit (-1);
Packit 971217
  }
Packit 971217
Packit 971217
  pipeline = pipelines[type].func (argv[2]);
Packit 971217
  g_assert (pipeline);
Packit 971217
Packit 971217
  /* initialize gui elements ... */
Packit 971217
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Packit 971217
  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
Packit 971217
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Packit 971217
  play_button = gtk_button_new_with_label ("play");
Packit 971217
  pause_button = gtk_button_new_with_label ("pause");
Packit 971217
  stop_button = gtk_button_new_with_label ("stop");
Packit 971217
Packit 971217
  adjustment =
Packit 971217
      GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, (gdouble) RANGE_PREC, 0.1,
Packit 971217
          1.0, 1.0));
Packit 971217
  hscale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
Packit 971217
  gtk_scale_set_digits (GTK_SCALE (hscale), 2);
Packit 971217
Packit 971217
  sadjustment =
Packit 971217
      GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 0.0, 5.0, 0.1, 1.0, 0.0));
Packit 971217
  shscale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, sadjustment);
Packit 971217
  gtk_scale_set_digits (GTK_SCALE (shscale), 2);
Packit 971217
Packit 971217
  schanged_id =
Packit 971217
      g_signal_connect (shscale, "value_changed", G_CALLBACK (speed_cb),
Packit 971217
      pipeline);
Packit 971217
Packit 971217
  g_signal_connect (hscale, "button_press_event", G_CALLBACK (start_seek),
Packit 971217
      pipeline);
Packit 971217
  g_signal_connect (hscale, "button_release_event", G_CALLBACK (stop_seek),
Packit 971217
      pipeline);
Packit 971217
  g_signal_connect (hscale, "format_value", G_CALLBACK (format_value),
Packit 971217
      pipeline);
Packit 971217
Packit 971217
  /* do the packing stuff ... */
Packit 971217
  gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
Packit 971217
  gtk_container_add (GTK_CONTAINER (window), vbox);
Packit 971217
  gtk_container_add (GTK_CONTAINER (vbox), hbox);
Packit 971217
  gtk_box_pack_start (GTK_BOX (hbox), play_button, FALSE, FALSE, 2);
Packit 971217
  gtk_box_pack_start (GTK_BOX (hbox), pause_button, FALSE, FALSE, 2);
Packit 971217
  gtk_box_pack_start (GTK_BOX (hbox), stop_button, FALSE, FALSE, 2);
Packit 971217
  gtk_box_pack_start (GTK_BOX (vbox), hscale, TRUE, TRUE, 2);
Packit 971217
  gtk_box_pack_start (GTK_BOX (vbox), shscale, TRUE, TRUE, 2);
Packit 971217
Packit 971217
  /* connect things ... */
Packit 971217
  g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb),
Packit 971217
      pipeline);
Packit 971217
  g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb),
Packit 971217
      pipeline);
Packit 971217
  g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb),
Packit 971217
      pipeline);
Packit 971217
  g_signal_connect (G_OBJECT (window), "delete_event", gtk_main_quit, NULL);
Packit 971217
Packit 971217
  /* show the gui. */
Packit 971217
  gtk_widget_show_all (window);
Packit 971217
Packit 971217
  if (verbose) {
Packit 971217
    g_signal_connect (pipeline, "deep_notify",
Packit 971217
        G_CALLBACK (gst_object_default_deep_notify), NULL);
Packit 971217
  }
Packit 971217
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
Packit 971217
  g_assert (bus);
Packit 971217
Packit 971217
  bus_watch = gst_bus_add_watch_full (bus,
Packit 971217
      G_PRIORITY_HIGH, bus_message, pipeline, NULL);
Packit 971217
Packit 971217
  gtk_main ();
Packit 971217
Packit 971217
  g_print ("NULL pipeline\n");
Packit 971217
  gst_element_set_state (pipeline, GST_STATE_NULL);
Packit 971217
Packit 971217
  gst_object_unref (bus);
Packit 971217
Packit 971217
  g_print ("free pipeline\n");
Packit 971217
  gst_object_unref (pipeline);
Packit 971217
Packit 971217
  return 0;
Packit 971217
}