diff options
author | Jan Schmidt <thaytan@mad.scientist.com> | 2005-02-20 14:16:38 +0000 |
---|---|---|
committer | Jan Schmidt <thaytan@mad.scientist.com> | 2005-02-20 14:16:38 +0000 |
commit | 593fb4a9fb808cd00274256a531cbe2d73ae3e1e (patch) | |
tree | 7fecbe35edf3e9de41a358e35e33e7344c7113d2 | |
parent | 002836cd1566890a9d5ba988a0fb684edd1cb9dc (diff) | |
download | gstreamer-plugins-base-593fb4a9fb808cd00274256a531cbe2d73ae3e1e.tar.gz |
examples/seeking/seek.c: Add realtime scrubbing to the seek example.
Original commit message from CVS:
* examples/seeking/seek.c: (end_scrub), (do_seek), (seek_cb),
(start_seek), (stop_seek):
Add realtime scrubbing to the seek example.
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_perform_seek):
Avoid overflowing 64-bits on large files when estimating
the new position during a seek.
-rw-r--r-- | examples/seeking/seek.c | 51 | ||||
-rw-r--r-- | ext/ogg/gstoggdemux.c | 10 | ||||
-rw-r--r-- | tests/examples/seek/seek.c | 51 |
3 files changed, 99 insertions, 13 deletions
diff --git a/examples/seeking/seek.c b/examples/seeking/seek.c index 4ba2f34c6..81ba7d8f4 100644 --- a/examples/seeking/seek.c +++ b/examples/seeking/seek.c @@ -17,6 +17,7 @@ static gboolean elem_seek = FALSE; static gboolean verbose = FALSE; static guint update_id; +static guint seek_timeout_id = 0; static gulong changed_id; //#define SOURCE "gnomevfssrc" @@ -24,6 +25,10 @@ static gulong changed_id; #define UPDATE_INTERVAL 500 +/* number of milliseconds to play for after a seek */ +#define SCRUB_TIME 250 +#undef SCRUB + #define THREAD #define PAD_SEEK @@ -982,8 +987,21 @@ update_scale (gpointer data) return TRUE; } +static void do_seek (GtkWidget * widget); + +#ifdef SCRUB static gboolean -do_seek (GtkWidget * widget, gpointer user_data) +end_scrub (GtkWidget * widget) +{ + gst_element_set_state (pipeline, GST_STATE_PAUSED); + seek_timeout_id = 0; + + return FALSE; +} +#endif + +static void +do_seek (GtkWidget * widget) { gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100; gboolean res; @@ -1024,8 +1042,28 @@ do_seek (GtkWidget * widget, gpointer user_data) } GST_PIPELINE (pipeline)->stream_time = real; +} - return FALSE; +static void +seek_cb (GtkWidget * widget) +{ +#ifdef SCRUB + /* If the timer hasn't expired yet, then the pipeline is running */ + if (seek_timeout_id != 0) { + gst_element_set_state (pipeline, GST_STATE_PAUSED); + } +#endif + + do_seek (widget); + +#ifdef SCRUB + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + if (seek_timeout_id == 0) { + seek_timeout_id = + gtk_timeout_add (SCRUB_TIME, (GSourceFunc) end_scrub, widget); + } +#endif } static gboolean @@ -1036,7 +1074,7 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data) if (changed_id == 0) { changed_id = gtk_signal_connect (GTK_OBJECT (hscale), - "value_changed", G_CALLBACK (do_seek), pipeline); + "value_changed", G_CALLBACK (seek_cb), pipeline); } return FALSE; @@ -1047,8 +1085,13 @@ stop_seek (GtkWidget * widget, gpointer user_data) { g_signal_handler_disconnect (GTK_OBJECT (hscale), changed_id); changed_id = 0; + if (seek_timeout_id != 0) { + gtk_timeout_remove (seek_timeout_id); + seek_timeout_id = 0; + /* Still scrubbing, so the pipeline is already playing */ + } else + gst_element_set_state (pipeline, GST_STATE_PLAYING); - gst_element_set_state (pipeline, GST_STATE_PLAYING); update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c index 9625d9281..02519b343 100644 --- a/ext/ogg/gstoggdemux.c +++ b/ext/ogg/gstoggdemux.c @@ -1275,13 +1275,13 @@ gst_ogg_demux_perform_seek (GstOggDemux * ogg, gint64 pos) while (begin < end) { gint64 bisect; - if (end - begin < CHUNKSIZE) { + if ((end - begin < CHUNKSIZE) || (endtime == begintime)) { bisect = begin; } else { - /* take a (pretty decent) guess. */ - bisect = begin + - (target - begintime) * (end - begin) / (endtime - begintime) - - CHUNKSIZE; + /* take a (pretty decent) guess, avoiding overflow */ + gint64 rate = (end - begin) * GST_MSECOND / (endtime - begintime); + + bisect = (target - begintime) / GST_MSECOND * rate + begin - CHUNKSIZE; if (bisect <= begin) bisect = begin + 1; diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c index 4ba2f34c6..81ba7d8f4 100644 --- a/tests/examples/seek/seek.c +++ b/tests/examples/seek/seek.c @@ -17,6 +17,7 @@ static gboolean elem_seek = FALSE; static gboolean verbose = FALSE; static guint update_id; +static guint seek_timeout_id = 0; static gulong changed_id; //#define SOURCE "gnomevfssrc" @@ -24,6 +25,10 @@ static gulong changed_id; #define UPDATE_INTERVAL 500 +/* number of milliseconds to play for after a seek */ +#define SCRUB_TIME 250 +#undef SCRUB + #define THREAD #define PAD_SEEK @@ -982,8 +987,21 @@ update_scale (gpointer data) return TRUE; } +static void do_seek (GtkWidget * widget); + +#ifdef SCRUB static gboolean -do_seek (GtkWidget * widget, gpointer user_data) +end_scrub (GtkWidget * widget) +{ + gst_element_set_state (pipeline, GST_STATE_PAUSED); + seek_timeout_id = 0; + + return FALSE; +} +#endif + +static void +do_seek (GtkWidget * widget) { gint64 real = gtk_range_get_value (GTK_RANGE (widget)) * duration / 100; gboolean res; @@ -1024,8 +1042,28 @@ do_seek (GtkWidget * widget, gpointer user_data) } GST_PIPELINE (pipeline)->stream_time = real; +} - return FALSE; +static void +seek_cb (GtkWidget * widget) +{ +#ifdef SCRUB + /* If the timer hasn't expired yet, then the pipeline is running */ + if (seek_timeout_id != 0) { + gst_element_set_state (pipeline, GST_STATE_PAUSED); + } +#endif + + do_seek (widget); + +#ifdef SCRUB + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + if (seek_timeout_id == 0) { + seek_timeout_id = + gtk_timeout_add (SCRUB_TIME, (GSourceFunc) end_scrub, widget); + } +#endif } static gboolean @@ -1036,7 +1074,7 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data) if (changed_id == 0) { changed_id = gtk_signal_connect (GTK_OBJECT (hscale), - "value_changed", G_CALLBACK (do_seek), pipeline); + "value_changed", G_CALLBACK (seek_cb), pipeline); } return FALSE; @@ -1047,8 +1085,13 @@ stop_seek (GtkWidget * widget, gpointer user_data) { g_signal_handler_disconnect (GTK_OBJECT (hscale), changed_id); changed_id = 0; + if (seek_timeout_id != 0) { + gtk_timeout_remove (seek_timeout_id); + seek_timeout_id = 0; + /* Still scrubbing, so the pipeline is already playing */ + } else + gst_element_set_state (pipeline, GST_STATE_PLAYING); - gst_element_set_state (pipeline, GST_STATE_PLAYING); update_id = gtk_timeout_add (UPDATE_INTERVAL, (GtkFunction) update_scale, pipeline); |