diff options
author | Hans Oesterholt <hans@oesterholt.net> | 2013-01-08 17:27:18 +0100 |
---|---|---|
committer | Bertrand Lorentz <bertrand.lorentz@gmail.com> | 2013-01-20 19:13:47 +0100 |
commit | fbbfb6487e138ade499faaa7b6a3b98db0f03e7a (patch) | |
tree | dacf2815ea8a77859f599b56b9a04f1523e0429a | |
parent | 7b210ef83bce8e08847ad130ca4701ce254855ee (diff) |
PlayerEngine: Add support for accurate seek
GStreamer can do accurate seeks, but it can be slower, even requiring a
complete scan of the file being seeked. So we add a new method in
PlayerEngineService, Seek(uint position, bool accurate_seek), that
allows to request an accurate seek. The accurate_seek parameter defaults
to false, because most use cases don't require accurate seeks.
Setting the Position property keeps its current behavior (no accurate
seek).
Accurate seeks are useful to be able to playback (mp3) files
that contain multiple songs, and will be used by the new CueSheets
community extensions.
Signed-off-by: Bertrand Lorentz <bertrand.lorentz@gmail.com>
6 files changed, 40 insertions, 11 deletions
diff --git a/libbanshee/banshee-player.c b/libbanshee/banshee-player.c index c655a72fd..673a81d2e 100644 --- a/libbanshee/banshee-player.c +++ b/libbanshee/banshee-player.c @@ -232,12 +232,17 @@ bp_set_next_track (BansheePlayer *player, const gchar *uri, gboolean maybe_video } P_INVOKE gboolean -bp_set_position (BansheePlayer *player, guint64 time_ms) +bp_set_position (BansheePlayer *player, guint64 time_ms, gboolean accurate_seek) { g_return_val_if_fail (IS_BANSHEE_PLAYER (player), FALSE); - + + GstSeekFlags seek_flag = GST_SEEK_FLAG_FLUSH; + if (accurate_seek) { + seek_flag |= GST_SEEK_FLAG_ACCURATE; + } + if (player->playbin == NULL || !gst_element_seek (player->playbin, 1.0, - GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, + GST_FORMAT_TIME, seek_flag, GST_SEEK_TYPE_SET, time_ms * GST_MSECOND, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { g_warning ("Could not seek in stream"); diff --git a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs index 278ff518b..1fbfcaf93 100644 --- a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs +++ b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs @@ -278,6 +278,12 @@ namespace Banshee.GStreamer } } + public override void Seek (uint position, bool accurate_seek = false) + { + bp_set_position (handle, (ulong)position, accurate_seek); + OnEventChanged (PlayerEvent.Seek); + } + public override void VideoExpose (IntPtr window, bool direct) { bp_video_window_expose (handle, window, direct); @@ -647,10 +653,7 @@ namespace Banshee.GStreamer public override uint Position { get { return (uint)bp_get_position(handle); } - set { - bp_set_position (handle, (ulong)value); - OnEventChanged (PlayerEvent.Seek); - } + set { Seek (value); } } public override bool CanSeek { @@ -1003,7 +1006,7 @@ namespace Banshee.GStreamer private static extern bool bp_audiosink_has_volume (HandleRef player); [DllImport ("libbanshee.dll")] - private static extern bool bp_set_position (HandleRef player, ulong time_ms); + private static extern bool bp_set_position (HandleRef player, ulong time_ms, bool accurate_seek); [DllImport ("libbanshee.dll")] private static extern ulong bp_get_position (HandleRef player); diff --git a/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs b/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs index 1bb31e210..f18b1e55a 100644 --- a/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs +++ b/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs @@ -449,6 +449,17 @@ namespace Banshee.GStreamerSharp next_track_set.Set (); } + public override void Seek (uint position, bool accurate_seek = false) + { + SeekFlags seek_flags = SeekFlags.Flush; + if (accurate_seek) { + seek_flags |= SeekFlags.Accurate; + } + + playbin.Seek (Format.Time, seek_flags, (long)(position * Gst.Clock.MSecond)); + OnEventChanged (PlayerEvent.Seek); + } + private bool OnBusMessage (Bus bus, Message msg) { switch (msg.Type) { @@ -771,9 +782,7 @@ namespace Banshee.GStreamerSharp playbin.QueryPosition (ref query_format, out pos); return (uint) ((ulong)pos / Gst.Clock.MSecond); } - set { - playbin.Seek (Format.Time, SeekFlags.Accurate, (long)(value * Gst.Clock.MSecond)); - } + set { Seek (value); } } public override uint Length { diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs b/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs index 780fe0732..fb92252a7 100644 --- a/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs +++ b/src/Core/Banshee.Services/Banshee.MediaEngine/NullPlayerEngine.cs @@ -49,6 +49,10 @@ namespace Banshee.MediaEngine OnStateChanged (PlayerState.Paused); } + public override void Seek (uint position, bool accurate_seek = false) + { + } + private ushort volume; public override ushort Volume { get { return volume; } diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs index 81a587960..692004838 100644 --- a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs +++ b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs @@ -148,6 +148,9 @@ namespace Banshee.MediaEngine public abstract void Pause (); + public abstract void Seek (uint position, bool accurate_seek = false); + + public virtual void SetNextTrackUri (SafeUri uri, bool maybeVideo) { // Opening files on SetNextTrack is a sane default behaviour. diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs index 793b9cdef..23115954e 100644 --- a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs +++ b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs @@ -538,6 +538,11 @@ namespace Banshee.MediaEngine } } + public void Seek (uint position, bool accurate_seek = false) + { + active_engine.Seek (position, accurate_seek); + } + public void VideoExpose (IntPtr displayContext, bool direct) { active_engine.VideoExpose (displayContext, direct); |