[totem/gnome-2-32] Add support for accurate seek



commit feb2eb92cf8345ce1d6619c00e56e24a7877e753
Author: Alexander Saprykin <xelfium gmail com>
Date:   Mon May 17 16:14:26 2010 +0400

    Add support for accurate seek
    
    Add "accurate" argument to seek functions, and
    use GST_SEEK_FLAG_ACCURATE instead of GST_SEEK_FLAG_KEY_UNIT
    when an accurate seek is requested.
    
    All the users of the seek functions will request "inaccurate" seeks
    except the video thumbnailer and the skipto plugin.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=618746

 bindings/python/totem.defs                |    6 ++-
 bindings/vala/totem.vapi                  |    4 +-
 browser-plugin/totem-plugin-viewer.c      |    3 +-
 src/backend/bacon-video-widget-gst-0.10.c |   29 ++++++++++++-----
 src/backend/bacon-video-widget.h          |    1 +
 src/plugins/bemused/totem-bemused.c       |    2 +-
 src/plugins/skipto/totem-skipto-plugin.c  |    3 +-
 src/totem-menu.c                          |    4 +-
 src/totem-object.c                        |   48 +++++++++++++++--------------
 src/totem-video-thumbnailer.c             |    2 +-
 src/totem.h                               |    4 +-
 11 files changed, 62 insertions(+), 44 deletions(-)
---
diff --git a/bindings/python/totem.defs b/bindings/python/totem.defs
index 4203052..ade52e5 100644
--- a/bindings/python/totem.defs
+++ b/bindings/python/totem.defs
@@ -266,7 +266,8 @@
   (c-name "totem_action_seek_time")
   (return-type "none")
   (parameters
-    '("gint64" "sec")
+    '("gint64" "msec")
+    '("gboolean" "accurate")
   )
 )
 
@@ -275,7 +276,8 @@
   (c-name "totem_action_seek_relative")
   (return-type "none")
   (parameters
-    '("int" "off_sec")
+    '("int" "off_msec")
+    '("gboolean" "accurate")
   )
 )
 
diff --git a/bindings/vala/totem.vapi b/bindings/vala/totem.vapi
index 4c6de91..d67f393 100644
--- a/bindings/vala/totem.vapi
+++ b/bindings/vala/totem.vapi
@@ -33,9 +33,9 @@ namespace Totem {
 		[CCode (cname = "totem_action_previous")]
 		public void action_previous ();
 		[CCode (cname = "totem_action_seek_time")]
-		public void action_seek_time (int64 sec);
+		public void action_seek_time (int64 msec, bool accurate);
 		[CCode (cname = "totem_action_seek_relative")]
-		public void action_seek_relative (int64 offset);
+		public void action_seek_relative (int64 offset, bool accurate);
 
 		[CCode (cname = "totem_get_volume")]
 		public double get_volume ();
diff --git a/browser-plugin/totem-plugin-viewer.c b/browser-plugin/totem-plugin-viewer.c
index 28bf309..938dc57 100644
--- a/browser-plugin/totem-plugin-viewer.c
+++ b/browser-plugin/totem-plugin-viewer.c
@@ -802,7 +802,7 @@ totem_embedded_set_time (TotemEmbedded *emb,
 {
 	g_message ("totem_embedded_set_time: %"G_GUINT64_FORMAT, time);
 
-	bacon_video_widget_seek_time (emb->bvw, time, NULL);
+	bacon_video_widget_seek_time (emb->bvw, time, FALSE, NULL);
 
 	return TRUE;
 }
@@ -913,6 +913,7 @@ totem_embedded_open_playlist_item (TotemEmbedded *emb,
 			g_message ("Seeking to %d seconds for starttime", plitem->starttime);
 			retval = bacon_video_widget_seek_time (emb->bvw,
 							       plitem->starttime * 1000,
+							       FALSE,
 							       NULL /* FIXME */);
 			if (!retval)
 				return TRUE;
diff --git a/src/backend/bacon-video-widget-gst-0.10.c b/src/backend/bacon-video-widget-gst-0.10.c
index 84facb2..a00a3d5 100644
--- a/src/backend/bacon-video-widget-gst-0.10.c
+++ b/src/backend/bacon-video-widget-gst-0.10.c
@@ -305,7 +305,7 @@ static GError* bvw_error_from_gst_error (BaconVideoWidget *bvw, GstMessage *m);
 static gboolean bvw_check_for_cover_pixbuf (BaconVideoWidget * bvw);
 static const GdkPixbuf * bvw_get_logo_pixbuf (BaconVideoWidget * bvw);
 static gboolean bvw_set_playback_direction (BaconVideoWidget *bvw, gboolean forward);
-static gboolean bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw, gint64 _time, GError **error);
+static gboolean bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw, gint64 _time, GstSeekFlags flag, GError **error);
 
 static GtkWidgetClass *parent_class = NULL;
 
@@ -2205,7 +2205,7 @@ bvw_bus_message_cb (GstBus * bus, GstMessage * message, gpointer data)
 
 	if (_time >= 0) {
 	  GST_DEBUG ("Have an old seek to schedule, doing it now");
-	  bacon_video_widget_seek_time_no_lock (bvw, _time, NULL);
+	  bacon_video_widget_seek_time_no_lock (bvw, _time, 0, NULL);
 	}
       break;
     }
@@ -3921,7 +3921,10 @@ bacon_video_widget_can_direct_seek (BaconVideoWidget *bvw)
 }
 
 static gboolean
-bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw, gint64 _time, GError **error)
+bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw,
+				      gint64 _time,
+				      GstSeekFlags flag,
+				      GError **error)
 {
   if (bvw_set_playback_direction (bvw, TRUE) == FALSE)
     return FALSE;
@@ -3930,7 +3933,7 @@ bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw, gint64 _time, GErro
   bvw->priv->rate = FORWARD_RATE;
 
   gst_element_seek (bvw->priv->play, FORWARD_RATE,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
+      GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | flag,
       GST_SEEK_TYPE_SET, _time * GST_MSECOND,
       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
 
@@ -3941,6 +3944,7 @@ bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw, gint64 _time, GErro
  * bacon_video_widget_seek_time:
  * @bvw: a #BaconVideoWidget
  * @_time: the time to which to seek, in milliseconds
+ * @accurate: whether to use accurate seek, an accurate seek might be slower for some formats (see GStreamer docs)
  * @error: a #GError, or %NULL
  *
  * Seeks the currently-playing stream to the absolute position @time, in milliseconds.
@@ -3948,9 +3952,10 @@ bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw, gint64 _time, GErro
  * Return value: %TRUE on success, %FALSE otherwise
  **/
 gboolean
-bacon_video_widget_seek_time (BaconVideoWidget *bvw, gint64 _time, GError **error)
+bacon_video_widget_seek_time (BaconVideoWidget *bvw, gint64 _time, gboolean accurate, GError **error)
 {
   GstClockTime cur_time;
+  GstSeekFlags  flag;
 
   g_return_val_if_fail (bvw != NULL, FALSE);
   g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);
@@ -3973,10 +3978,12 @@ bacon_video_widget_seek_time (BaconVideoWidget *bvw, gint64 _time, GError **erro
   /* Is there a pending seek? */
   g_mutex_lock (bvw->priv->seek_mutex);
   /* If there's no pending seek, or
-   * it's been too long since the seek */
+   * it's been too long since the seek,
+   * or we don't have an accurate seek requested */
   cur_time = gst_clock_get_internal_time (bvw->priv->clock);
   if (bvw->priv->seek_req_time == GST_CLOCK_TIME_NONE ||
-      cur_time > bvw->priv->seek_req_time + SEEK_TIMEOUT) {
+      cur_time > bvw->priv->seek_req_time + SEEK_TIMEOUT ||
+      accurate) {
     bvw->priv->seek_time = -1;
     bvw->priv->seek_req_time = cur_time;
     g_mutex_unlock (bvw->priv->seek_mutex);
@@ -3987,7 +3994,11 @@ bacon_video_widget_seek_time (BaconVideoWidget *bvw, gint64 _time, GError **erro
     return TRUE;
   }
 
-  bacon_video_widget_seek_time_no_lock (bvw, _time, error);
+  if (bvw_set_playback_direction (bvw, TRUE) == FALSE)
+    return FALSE;
+
+  flag = (accurate ? GST_SEEK_FLAG_ACCURATE : GST_SEEK_FLAG_KEY_UNIT);
+  bacon_video_widget_seek_time_no_lock (bvw, _time, flag, error);
 
   return TRUE;
 }
@@ -4018,7 +4029,7 @@ bacon_video_widget_seek (BaconVideoWidget *bvw, double position, GError **error)
   GST_LOG ("Seeking to %3.2f%% %" GST_TIME_FORMAT, position,
       GST_TIME_ARGS (seek_time));
 
-  return bacon_video_widget_seek_time (bvw, seek_time / GST_MSECOND, error);
+  return bacon_video_widget_seek_time (bvw, seek_time / GST_MSECOND, FALSE, error);
 }
 
 /**
diff --git a/src/backend/bacon-video-widget.h b/src/backend/bacon-video-widget.h
index 2c5c1dc..65e34b1 100644
--- a/src/backend/bacon-video-widget.h
+++ b/src/backend/bacon-video-widget.h
@@ -183,6 +183,7 @@ gboolean bacon_video_widget_seek		 (BaconVideoWidget *bvw,
 						  GError **error);
 gboolean bacon_video_widget_seek_time		 (BaconVideoWidget *bvw,
 						  gint64 _time,
+						  gboolean accurate,
 						  GError **error);
 gboolean bacon_video_widget_step		 (BaconVideoWidget *bvw,
 						  gboolean forward,
diff --git a/src/plugins/bemused/totem-bemused.c b/src/plugins/bemused/totem-bemused.c
index 43210c0..5ec2363 100644
--- a/src/plugins/bemused/totem-bemused.c
+++ b/src/plugins/bemused/totem-bemused.c
@@ -251,7 +251,7 @@ seek_to_pos (TotemBemusedPlugin *tp, GIOChannel *source)
 	time += buf[2] << 8;
 	time += buf[3];
 
-	totem_action_seek_time (tp->totem, (gint64) time * 1000);
+	totem_action_seek_time (tp->totem, (gint64) time * 1000, FALSE);
 }
 
 static void
diff --git a/src/plugins/skipto/totem-skipto-plugin.c b/src/plugins/skipto/totem-skipto-plugin.c
index c16e5eb..175da86 100644
--- a/src/plugins/skipto/totem-skipto-plugin.c
+++ b/src/plugins/skipto/totem-skipto-plugin.c
@@ -144,7 +144,8 @@ skip_to_response_callback (GtkDialog *dialog, gint response, TotemSkiptoPlugin *
 	gtk_widget_hide (GTK_WIDGET (dialog));
 
 	totem_action_seek_time (plugin->totem,
-				totem_skipto_get_range (plugin->priv->st));
+				totem_skipto_get_range (plugin->priv->st),
+				TRUE);
 	destroy_dialog (plugin);
 }
 
diff --git a/src/totem-menu.c b/src/totem-menu.c
index 51bf97f..5a9cca7 100644
--- a/src/totem-menu.c
+++ b/src/totem-menu.c
@@ -1119,13 +1119,13 @@ previous_chapter_action_callback (GtkAction *action, Totem *totem)
 void
 skip_forward_action_callback (GtkAction *action, Totem *totem)
 {
-	totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000);
+	totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000, FALSE);
 }
 
 void
 skip_backwards_action_callback (GtkAction *action, Totem *totem)
 {
-	totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000);
+	totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000, FALSE);
 }
 
 void
diff --git a/src/totem-object.c b/src/totem-object.c
index 3274d70..263151a 100644
--- a/src/totem-object.c
+++ b/src/totem-object.c
@@ -1871,7 +1871,7 @@ totem_action_next (Totem *totem)
 }
 
 static void
-totem_seek_time_rel (Totem *totem, gint64 _time, gboolean relative)
+totem_seek_time_rel (Totem *totem, gint64 _time, gboolean relative, gboolean accurate)
 {
 	GError *err = NULL;
 	gint64 sec;
@@ -1892,7 +1892,7 @@ totem_seek_time_rel (Totem *totem, gint64 _time, gboolean relative)
 		sec = _time;
 	}
 
-	bacon_video_widget_seek_time (totem->bvw, sec, &err);
+	bacon_video_widget_seek_time (totem->bvw, sec, accurate, &err);
 
 	totem_statusbar_set_seeking (TOTEM_STATUSBAR (totem->statusbar), FALSE);
 	totem_time_label_set_seeking (TOTEM_TIME_LABEL (totem->fs->time_label), FALSE);
@@ -1916,28 +1916,30 @@ totem_seek_time_rel (Totem *totem, gint64 _time, gboolean relative)
  * totem_action_seek_relative:
  * @totem: a #TotemObject
  * @offset: the time offset to seek to
+ * @accurate: whether to use accurate seek, an accurate seek might be slower for some formats (see GStreamer docs)
  *
  * Seeks to an @offset from the current position in the stream,
  * or displays an error dialog if that's not possible.
  **/
 void
-totem_action_seek_relative (Totem *totem, gint64 offset)
+totem_action_seek_relative (Totem *totem, gint64 offset, gboolean accurate)
 {
-	totem_seek_time_rel (totem, offset, TRUE);
+	totem_seek_time_rel (totem, offset, TRUE, accurate);
 }
 
 /**
  * totem_action_seek_time:
  * @totem: a #TotemObject
- * @sec: the time to seek to
+ * @msec: the time to seek to
+ * @accurate: whether to use accurate seek, an accurate seek might be slower for some formats (see GStreamer docs)
  *
  * Seeks to an absolute time in the stream, or displays an
  * error dialog if that's not possible.
  **/
 void
-totem_action_seek_time (Totem *totem, gint64 sec)
+totem_action_seek_time (Totem *totem, gint64 msec, gboolean accurate)
 {
-	totem_seek_time_rel (totem, sec, FALSE);
+	totem_seek_time_rel (totem, msec, FALSE, accurate);
 }
 
 static void
@@ -2554,11 +2556,11 @@ update_seekable (Totem *totem)
 	if (seekable != FALSE) {
 		if (totem->seek_to_start != 0) {
 			bacon_video_widget_seek_time (totem->bvw,
-						      totem->seek_to_start, NULL);
+						      totem->seek_to_start, FALSE, NULL);
 			totem_action_pause (totem);
 		} else if (totem->seek_to != 0) {
 			bacon_video_widget_seek_time (totem->bvw,
-						      totem->seek_to, NULL);
+						      totem->seek_to, FALSE, NULL);
 		}
 	}
 	totem->seek_to = 0;
@@ -3024,9 +3026,9 @@ totem_action_remote (Totem *totem, TotemRemoteCommand cmd, const char *url)
 		if (url != NULL)
 			offset = g_ascii_strtod (url, NULL);
 		if (offset == 0) {
-			totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000, FALSE);
 		} else {
-			totem_action_seek_relative (totem, offset * 1000);
+			totem_action_seek_relative (totem, offset * 1000, FALSE);
 		}
 		icon_name = "gtk-media-forward";
 		break;
@@ -3037,9 +3039,9 @@ totem_action_remote (Totem *totem, TotemRemoteCommand cmd, const char *url)
 		if (url != NULL)
 			offset = g_ascii_strtod (url, NULL);
 		if (offset == 0)
-			totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000, FALSE);
 		else
-			totem_action_seek_relative (totem,  - (offset * 1000));
+			totem_action_seek_relative (totem,  - (offset * 1000), FALSE);
 		icon_name = "gtk-media-rewind";
 		break;
 	}
@@ -3443,11 +3445,11 @@ on_eos_event (GtkWidget *widget, Totem *totem)
 		if (totem_playlist_get_last (totem->playlist) == 0 &&
 		    totem_is_seekable (totem)) {
 			if (totem_playlist_get_repeat (totem->playlist) != FALSE) {
-				totem_action_seek_time (totem, 0);
+				totem_action_seek_time (totem, 0, FALSE);
 				totem_action_play (totem);
 			} else {
 				totem_action_pause (totem);
-				totem_action_seek_time (totem, 0);
+				totem_action_seek_time (totem, 0, FALSE);
 			}
 		} else {
 			totem_action_next (totem);
@@ -3480,18 +3482,18 @@ totem_action_handle_seek (Totem *totem, GdkEventKey *event, gboolean is_forward)
 {
 	if (is_forward != FALSE) {
 		if (event->state & GDK_SHIFT_MASK)
-			totem_action_seek_relative (totem, SEEK_FORWARD_SHORT_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_FORWARD_SHORT_OFFSET * 1000, FALSE);
 		else if (event->state & GDK_CONTROL_MASK)
-			totem_action_seek_relative (totem, SEEK_FORWARD_LONG_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_FORWARD_LONG_OFFSET * 1000, FALSE);
 		else
-			totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000, FALSE);
 	} else {
 		if (event->state & GDK_SHIFT_MASK)
-			totem_action_seek_relative (totem, SEEK_BACKWARD_SHORT_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_BACKWARD_SHORT_OFFSET * 1000, FALSE);
 		else if (event->state & GDK_CONTROL_MASK)
-			totem_action_seek_relative (totem, SEEK_BACKWARD_LONG_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_BACKWARD_LONG_OFFSET * 1000, FALSE);
 		else
-			totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000);
+			totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000, FALSE);
 	}
 }
 
@@ -3746,10 +3748,10 @@ totem_action_handle_scroll (Totem *totem, GdkScrollDirection direction)
 
 	switch (direction) {
 	case GDK_SCROLL_UP:
-		totem_action_seek_relative (totem, SEEK_FORWARD_SHORT_OFFSET * 1000);
+		totem_action_seek_relative (totem, SEEK_FORWARD_SHORT_OFFSET * 1000, FALSE);
 		break;
 	case GDK_SCROLL_DOWN:
-		totem_action_seek_relative (totem, SEEK_BACKWARD_SHORT_OFFSET * 1000);
+		totem_action_seek_relative (totem, SEEK_BACKWARD_SHORT_OFFSET * 1000, FALSE);
 		break;
 	default:
 		retval = FALSE;
diff --git a/src/totem-video-thumbnailer.c b/src/totem-video-thumbnailer.c
index d39636e..f72700c 100644
--- a/src/totem-video-thumbnailer.c
+++ b/src/totem-video-thumbnailer.c
@@ -429,7 +429,7 @@ capture_frame_at_time(BaconVideoWidget *bvw,
 {
 	GError *err = NULL;
 
-	if (bacon_video_widget_seek_time (bvw, seconds * 1000, &err) == FALSE) {
+	if (bacon_video_widget_seek_time (bvw, seconds * 1000, TRUE, &err) == FALSE) {
 		g_print ("totem-video-thumbnailer: could not seek to %d seconds in '%s'\n"
 			 "Reason: %s\n",
 			 (int) seconds, input, err ? err->message : "programming error");
diff --git a/src/totem.h b/src/totem.h
index 22a1dec..8f7486f 100644
--- a/src/totem.h
+++ b/src/totem.h
@@ -195,8 +195,8 @@ void	totem_action_fullscreen_toggle		(Totem *totem);
 void	totem_action_fullscreen			(Totem *totem, gboolean state);
 void	totem_action_next			(Totem *totem);
 void	totem_action_previous			(Totem *totem);
-void	totem_action_seek_time			(Totem *totem, gint64 sec);
-void	totem_action_seek_relative		(Totem *totem, gint64 offset);
+void	totem_action_seek_time			(Totem *totem, gint64 msec, gboolean accurate);
+void	totem_action_seek_relative		(Totem *totem, gint64 offset, gboolean accurate);
 double	totem_get_volume			(Totem *totem);
 void	totem_action_volume			(Totem *totem, double volume);
 void	totem_action_volume_relative		(Totem *totem, double off_pct);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]