[totem/gnome-2-32] Add support for accurate seek
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem/gnome-2-32] Add support for accurate seek
- Date: Thu, 5 Aug 2010 09:26:50 +0000 (UTC)
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]