summaryrefslogtreecommitdiff
path: root/tests/examples/seek/scrubby.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/examples/seek/scrubby.c')
-rw-r--r--tests/examples/seek/scrubby.c570
1 files changed, 0 insertions, 570 deletions
diff --git a/tests/examples/seek/scrubby.c b/tests/examples/seek/scrubby.c
deleted file mode 100644
index 7517ec2a..00000000
--- a/tests/examples/seek/scrubby.c
+++ /dev/null
@@ -1,570 +0,0 @@
-#include <stdlib.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <gst/gst.h>
-#include <string.h>
-
-GST_DEBUG_CATEGORY_STATIC (scrubby_debug);
-#define GST_CAT_DEFAULT (scrubby_debug)
-
-static GstElement *pipeline;
-static gint64 position;
-static gint64 duration;
-static GtkAdjustment *adjustment;
-static GtkWidget *hscale;
-static GtkAdjustment *sadjustment;
-static GtkWidget *shscale;
-static gboolean verbose = FALSE;
-
-static guint bus_watch = 0;
-static guint update_id = 0;
-static guint changed_id = 0;
-static guint schanged_id = 0;
-
-//#define SOURCE "filesrc"
-#define SOURCE "gnomevfssrc"
-#define ASINK "alsasink"
-//#define ASINK "osssink"
-#define VSINK "xvimagesink"
-//#define VSINK "ximagesink"
-//#define VSINK "aasink"
-//#define VSINK "cacasink"
-
-#define RANGE_PREC 10000
-#define SEGMENT_LEN 100
-#define UPDATE_INTERVAL 500
-
-static gdouble prev_range = -1.0;
-static GstClockTime prev_time = GST_CLOCK_TIME_NONE;
-static gdouble cur_range;
-static GstClockTime cur_time;
-static GstClockTimeDiff diff;
-static gdouble cur_speed = 1.0;
-
-typedef struct
-{
- const gchar *padname;
- GstPad *target;
- GstElement *bin;
-}
-dyn_link;
-
-static GstElement *
-gst_element_factory_make_or_warn (gchar * type, gchar * name)
-{
- GstElement *element = gst_element_factory_make (type, name);
-
- if (!element) {
- g_warning ("Failed to create element %s of type %s", name, type);
- }
-
- return element;
-}
-
-static void
-dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer data)
-{
- dyn_link *connect = (dyn_link *) data;
-
- if (connect->padname == NULL ||
- !strcmp (gst_pad_get_name (newpad), connect->padname)) {
- if (connect->bin)
- gst_bin_add (GST_BIN (pipeline), connect->bin);
- gst_pad_link (newpad, connect->target);
- }
-}
-
-static void
-setup_dynamic_link (GstElement * element, const gchar * padname,
- GstPad * target, GstElement * bin)
-{
- dyn_link *connect;
-
- connect = g_new0 (dyn_link, 1);
- connect->padname = g_strdup (padname);
- connect->target = target;
- connect->bin = bin;
-
- g_signal_connect (G_OBJECT (element), "pad-added", G_CALLBACK (dynamic_link),
- connect);
-}
-
-static GstElement *
-make_wav_pipeline (const gchar * location)
-{
- GstElement *pipeline;
- GstElement *src, *decoder, *audiosink;
-
- pipeline = gst_pipeline_new ("app");
-
- src = gst_element_factory_make_or_warn (SOURCE, "src");
- decoder = gst_element_factory_make_or_warn ("wavparse", "decoder");
- audiosink = gst_element_factory_make_or_warn (ASINK, "sink");
-
- g_object_set (G_OBJECT (src), "location", location, NULL);
-
- gst_bin_add (GST_BIN (pipeline), src);
- gst_bin_add (GST_BIN (pipeline), decoder);
- gst_bin_add (GST_BIN (pipeline), audiosink);
-
- gst_element_link (src, decoder);
-
- setup_dynamic_link (decoder, "src", gst_element_get_static_pad (audiosink,
- "sink"), NULL);
-
- return pipeline;
-}
-
-static GstElement *
-make_playerbin_pipeline (const gchar * location)
-{
- GstElement *player;
-
- player = gst_element_factory_make ("playbin", "player");
- g_assert (player);
-
- g_object_set (G_OBJECT (player), "uri", location, NULL);
-
- return player;
-}
-
-static gchar *
-format_value (GtkScale * scale, gdouble value)
-{
- gint64 real;
- gint64 seconds;
- gint64 subseconds;
-
- real = value * duration / RANGE_PREC;
- seconds = (gint64) real / GST_SECOND;
- subseconds = (gint64) real / (GST_SECOND / RANGE_PREC);
-
- 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)
-{
- GstFormat format;
-
- position = 0;
- duration = 0;
-
- format = GST_FORMAT_TIME;
-
- gst_element_query_position (pipeline, &format, &position);
- gst_element_query_duration (pipeline, &format, &duration);
-
- if (position >= duration)
- duration = position;
-
- if (duration > 0) {
- gtk_adjustment_set_value (adjustment,
- position * (gdouble) RANGE_PREC / duration);
- gtk_widget_queue_draw (hscale);
- }
-
- return TRUE;
-}
-
-static void
-speed_cb (GtkWidget * widget)
-{
- GstEvent *s_event;
- gboolean res;
-
- GST_DEBUG ("speed change");
- cur_speed = gtk_range_get_value (GTK_RANGE (widget));
-
- if (cur_speed == 0.0)
- return;
-
- s_event = gst_event_new_seek (cur_speed,
- GST_FORMAT_TIME, 0, GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1);
-
- res = gst_element_send_event (pipeline, s_event);
- if (!res)
- g_print ("speed change failed\n");
-}
-
-static gboolean do_seek (GtkWidget * widget, gboolean flush, gboolean segment);
-
-static void
-seek_cb (GtkWidget * widget)
-{
- if (changed_id) {
- GST_DEBUG ("seek because of slider move");
-
- if (do_seek (widget, TRUE, TRUE)) {
- g_source_remove (changed_id);
- changed_id = 0;
- }
- }
-}
-
-static gboolean
-do_seek (GtkWidget * widget, gboolean flush, gboolean segment)
-{
- gint64 start, stop;
- gboolean res = FALSE;
- GstEvent *s_event;
- gdouble rate;
- GTimeVal tv;
- gboolean valid;
- gdouble new_range;
-
- if (segment)
- new_range = gtk_range_get_value (GTK_RANGE (widget));
- else {
- new_range = (gdouble) RANGE_PREC;
- cur_time = -1;
- }
-
- valid = prev_time != -1;
-
- GST_DEBUG ("flush %d, segment %d, valid %d", flush, segment, valid);
-
- if (new_range == cur_range)
- return FALSE;
-
- prev_time = cur_time;
- prev_range = cur_range;
-
- cur_range = new_range;
-
- g_get_current_time (&tv);
- cur_time = GST_TIMEVAL_TO_TIME (tv);
-
- if (!valid)
- return FALSE;
-
- GST_DEBUG ("cur: %lf, %" GST_TIME_FORMAT, cur_range,
- GST_TIME_ARGS (cur_time));
- GST_DEBUG ("prev: %lf, %" GST_TIME_FORMAT, prev_range,
- GST_TIME_ARGS (prev_time));
-
- diff = cur_time - prev_time;
-
- GST_DEBUG ("diff: %" GST_TIME_FORMAT, GST_TIME_ARGS (diff));
-
- start = prev_range * duration / RANGE_PREC;
- /* play 50 milliseconds */
- stop = segment ? cur_range * duration / RANGE_PREC : duration;
-
- if (start == stop)
- return FALSE;
-
- if (segment)
- rate = (stop - start) / (gdouble) diff;
- else
- rate = cur_speed;
-
- if (start > stop) {
- gint64 tmp;
-
- tmp = start;
- start = stop;
- stop = tmp;
- }
-
- if (rate == 0.0)
- return TRUE;
-
- GST_DEBUG ("seek to %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT ", rate %lf"
- " on element %s",
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop), rate,
- GST_ELEMENT_NAME (pipeline));
-
- s_event = gst_event_new_seek (rate,
- GST_FORMAT_TIME,
- (flush ? GST_SEEK_FLAG_FLUSH : 0) |
- (segment ? GST_SEEK_FLAG_SEGMENT : 0),
- GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_SET, stop);
-
- res = gst_element_send_event (pipeline, s_event);
- if (!res)
- g_print ("seek failed\n");
-
- gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
-
- return TRUE;
-}
-
-static gboolean
-start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
-{
- if (update_id) {
- g_source_remove (update_id);
- update_id = 0;
- }
-
- if (changed_id == 0) {
- changed_id =
- g_signal_connect (hscale, "value_changed", G_CALLBACK (seek_cb),
- pipeline);
- }
-
- GST_DEBUG ("start seek");
-
- return FALSE;
-}
-
-static gboolean
-stop_seek (GtkWidget * widget, gpointer user_data)
-{
- update_id =
- g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
-
- GST_DEBUG ("stop seek");
-
- if (changed_id) {
- g_source_remove (changed_id);
- changed_id = 0;
- }
-
- do_seek (hscale, FALSE, FALSE);
-
- return FALSE;
-}
-
-static void
-play_cb (GtkButton * button, gpointer data)
-{
- GstState state;
-
- gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
- if (state != GST_STATE_PLAYING) {
- g_print ("PLAY pipeline\n");
- gst_element_set_state (pipeline, GST_STATE_PAUSED);
- gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
- gst_element_set_state (pipeline, GST_STATE_PLAYING);
- update_id =
- g_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline);
- }
-}
-
-static void
-pause_cb (GtkButton * button, gpointer data)
-{
- GstState state;
-
- gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
- if (state != GST_STATE_PAUSED) {
- g_print ("PAUSE pipeline\n");
- gst_element_set_state (pipeline, GST_STATE_PAUSED);
- g_source_remove (update_id);
- }
-}
-
-static void
-stop_cb (GtkButton * button, gpointer data)
-{
- GstState state;
-
- gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
- if (state != GST_STATE_READY) {
- g_print ("READY pipeline\n");
- gst_element_set_state (pipeline, GST_STATE_READY);
- /* position and speed return to their default values */
- gtk_adjustment_set_value (adjustment, 0.0);
- gtk_adjustment_set_value (sadjustment, 1.0);
- g_source_remove (update_id);
- }
-}
-
-static void
-print_message (GstMessage * message)
-{
- const GstStructure *s;
-
- s = gst_message_get_structure (message);
- g_print ("Got Message from element \"%s\"\n",
- GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message))));
-
- if (s) {
- gchar *sstr;
-
- sstr = gst_structure_to_string (s);
- g_print ("%s\n", sstr);
- g_free (sstr);
- }
-}
-
-static gboolean
-bus_message (GstBus * bus, GstMessage * message, gpointer data)
-{
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_EOS:
- g_print ("EOS\n");
- break;
- case GST_MESSAGE_ERROR:
- case GST_MESSAGE_WARNING:
- print_message (message);
- break;
- case GST_MESSAGE_SEGMENT_START:
- break;
- case GST_MESSAGE_SEGMENT_DONE:
- GST_DEBUG ("segment_done, doing next seek");
- if (!do_seek (hscale, FALSE, update_id == 0)) {
- if (changed_id == 0) {
- changed_id =
- g_signal_connect (hscale, "value_changed", G_CALLBACK (seek_cb),
- pipeline);
- }
- }
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-typedef struct
-{
- gchar *name;
- GstElement *(*func) (const gchar * location);
-}
-Pipeline;
-
-static Pipeline pipelines[] = {
- {"wav", make_wav_pipeline},
- {"playerbin", make_playerbin_pipeline},
- {NULL, NULL},
-};
-
-#define NUM_TYPES ((sizeof (pipelines) / sizeof (Pipeline)) - 1)
-
-static void
-print_usage (int argc, char **argv)
-{
- gint i;
-
- g_print ("usage: %s <type> <filename>\n", argv[0]);
- g_print (" possible types:\n");
-
- for (i = 0; i < NUM_TYPES; i++) {
- g_print (" %d = %s\n", i, pipelines[i].name);
- }
-}
-
-int
-main (int argc, char **argv)
-{
- GtkWidget *window, *hbox, *vbox, *play_button, *pause_button, *stop_button;
- GstBus *bus;
- GOptionEntry options[] = {
- {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
- "Verbose properties", NULL},
- {NULL}
- };
- gint type;
- GOptionContext *ctx;
- GError *err = NULL;
-
- if (!g_thread_supported ())
- g_thread_init (NULL);
-
- ctx = g_option_context_new ("seek");
- g_option_context_add_main_entries (ctx, options, NULL);
- g_option_context_add_group (ctx, gst_init_get_option_group ());
-
- if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
- g_print ("Error initializing: %s\n", err->message);
- exit (1);
- }
-
- GST_DEBUG_CATEGORY_INIT (scrubby_debug, "scrubby", 0, "scrubby example");
-
- gtk_init (&argc, &argv);
-
- if (argc != 3) {
- print_usage (argc, argv);
- exit (-1);
- }
-
- type = atoi (argv[1]);
-
- if (type < 0 || type >= NUM_TYPES) {
- print_usage (argc, argv);
- exit (-1);
- }
-
- pipeline = pipelines[type].func (argv[2]);
- 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.0, (gdouble) RANGE_PREC, 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);
-
- sadjustment =
- GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 0.0, 5.0, 0.1, 1.0, 0.0));
- shscale = gtk_hscale_new (sadjustment);
- gtk_scale_set_digits (GTK_SCALE (shscale), 2);
- gtk_range_set_update_policy (GTK_RANGE (shscale), GTK_UPDATE_CONTINUOUS);
-
- schanged_id =
- g_signal_connect (shscale, "value_changed", G_CALLBACK (speed_cb),
- pipeline);
-
- g_signal_connect (hscale, "button_press_event", G_CALLBACK (start_seek),
- pipeline);
- g_signal_connect (hscale, "button_release_event", G_CALLBACK (stop_seek),
- pipeline);
- g_signal_connect (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);
- gtk_box_pack_start (GTK_BOX (vbox), shscale, 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_object_default_deep_notify), NULL);
- }
- bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
- g_assert (bus);
-
- bus_watch = gst_bus_add_watch_full (bus,
- G_PRIORITY_HIGH, bus_message, pipeline, NULL);
-
- gtk_main ();
-
- g_print ("NULL pipeline\n");
- gst_element_set_state (pipeline, GST_STATE_NULL);
-
- g_print ("free pipeline\n");
- gst_object_unref (pipeline);
-
- return 0;
-}