[banshee/stable-2.6] PlayerEngine: workaround dupe about-to-finish signals (bgo#679938)
- From: Andrés Aragoneses <aaragoneses src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee/stable-2.6] PlayerEngine: workaround dupe about-to-finish signals (bgo#679938)
- Date: Sat, 1 Feb 2014 16:48:49 +0000 (UTC)
commit 30b411237db480bb08b9e011a6a0953240d9861f
Author: Andrés G. Aragoneses <knocte gmail com>
Date: Sat Feb 1 15:00:50 2014 +0100
PlayerEngine: workaround dupe about-to-finish signals (bgo#679938)
Banshee codebase was making the reasonable assumption that
GStreamer was sending one (and only one) about-to-finish
signal for each play of each track, however this is not the
case, and this issue has been reported as bug BGO#722769.
Gapless feature was relying certainly on this assumption, and
therefore it was causing subtle unintended behaviours, such as:
- bgo#679938: Repeat always ON (tested by Ismael Olea)
- bgo#674293: Stop when finished is ignored (very likely)
- and possibly more...
To fix this we need to prevent the event RequestNextTrack to
be fired twice, so we put a timestamp every time current_track
is assigned, store that timestamp in the native and managed
PlayerEngines, and compare it, to prevent the OnAboutToFinish()
method to run twice for the same play.
Conflicts:
src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs
.../Banshee.GStreamer/PlayerEngine.cs | 11 +++++
.../Banshee.GStreamerSharp/PlayerEngine.cs | 11 +++++
.../Banshee.MediaEngine/PlayerEngine.cs | 8 ++++
.../Banshee.Services/Banshee.MediaEngine/Tests.cs | 40 ++++++++++++++++++++
4 files changed, 70 insertions(+), 0 deletions(-)
---
diff --git a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
index 475fa6c..806093a 100644
--- a/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
+++ b/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
@@ -425,8 +425,19 @@ namespace Banshee.GStreamer
}
}
+ private System.DateTime about_to_finish_time_stamp;
+
private void OnAboutToFinish (IntPtr player)
{
+ // HACK: ugly workaround for GStreamer's bug http://bugzilla.gnome.org/722769
+ // long story short, AboutToFinish signal firing twice for the same play of the same track
+ // causes problems when Gapless Enabled because of RequestNextTrack event being fired twice
+ if (about_to_finish_time_stamp == CurrentTrackTimeStamp) {
+ return;
+ }
+ about_to_finish_time_stamp = CurrentTrackTimeStamp;
+
+
// This is needed to make Shuffle-by-* work.
// Shuffle-by-* uses the LastPlayed field to determine what track in the grouping to play next.
// Therefore, we need to update this before requesting the next track.
diff --git a/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs
b/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs
index 1bb31e2..07004bb 100644
--- a/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs
+++ b/src/Backends/Banshee.GStreamerSharp/Banshee.GStreamerSharp/PlayerEngine.cs
@@ -413,8 +413,19 @@ namespace Banshee.GStreamerSharp
OnEventChanged (PlayerEvent.PrepareVideoWindow);
}
+ private System.DateTime about_to_finish_time_stamp;
+
void OnAboutToFinish (object o, Gst.GLib.SignalArgs args)
{
+ // HACK: ugly workaround for GStreamer's bug http://bugzilla.gnome.org/722769
+ // long story short, AboutToFinish signal firing twice for the same play of the same track
+ // causes problems when Gapless Enabled because of RequestNextTrack event being fired twice
+ if (about_to_finish_time_stamp == CurrentTrackTimeStamp) {
+ return;
+ }
+ about_to_finish_time_stamp = CurrentTrackTimeStamp;
+
+
// This is needed to make Shuffle-by-* work.
// Shuffle-by-* uses the LastPlayed field to determine what track in the grouping to play next.
// Therefore, we need to update this before requesting the next track.
diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
index c3059f6..c8357b5 100644
--- a/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
+++ b/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngine.cs
@@ -50,6 +50,11 @@ namespace Banshee.MediaEngine
private PlayerState current_state = PlayerState.NotReady;
private PlayerState last_state = PlayerState.NotReady;
+ public DateTime CurrentTrackTimeStamp {
+ get;
+ private set;
+ }
+
// will be changed to PlayerState.Idle after going to PlayerState.Ready
private PlayerState idle_state = PlayerState.NotReady;
@@ -67,6 +72,7 @@ namespace Banshee.MediaEngine
public void Reset ()
{
+ CurrentTrackTimeStamp = DateTime.Now;
current_track = null;
OnStateChanged (idle_state);
}
@@ -136,6 +142,7 @@ namespace Banshee.MediaEngine
}
try {
+ CurrentTrackTimeStamp = DateTime.Now;
current_track = track;
OnStateChanged (PlayerState.Loading);
OpenUri (uri, track.HasAttribute (TrackMediaAttributes.VideoStream) || track is
UnknownTrackInfo);
@@ -210,6 +217,7 @@ namespace Banshee.MediaEngine
if (args.Event == PlayerEvent.StartOfStream && pending_track != null) {
Log.DebugFormat ("OnEventChanged called with StartOfStream. Replacing current_track with
pending_track: \"{0}\"",
pending_track.DisplayTrackTitle);
+ CurrentTrackTimeStamp = DateTime.Now;
current_track = pending_track;
pending_track = null;
}
diff --git a/src/Core/Banshee.Services/Banshee.MediaEngine/Tests.cs
b/src/Core/Banshee.Services/Banshee.MediaEngine/Tests.cs
index c048121..91c0ee2 100644
--- a/src/Core/Banshee.Services/Banshee.MediaEngine/Tests.cs
+++ b/src/Core/Banshee.Services/Banshee.MediaEngine/Tests.cs
@@ -128,6 +128,42 @@ namespace Banshee.MediaEngine
Assert.AreEqual (a_valid_track, actual_filename);
}
+ private void StopEngine ()
+ {
+ service.SetNextTrack ((TrackInfo)null);
+ service.Play ();
+ }
+
+ [Test]
+ // make sure https://bugzilla.gnome.org/show_bug.cgi?id=722769 doesn't happen, or that our
workaround works
+ public void TestThatRequestNextTrackEventsAreNotDuplicated ()
+ {
+ WaitUntil (PlayerState.Idle, StopEngine);
+
+ var a_valid_track1 = "A_boy.ogg";
+ var a_valid_uri1 = new SafeUri (Paths.Combine (TestsDir, "data", a_valid_track1));
+
+ var a_valid_track2 = "A_girl.ogg";
+ var a_valid_uri2 = new SafeUri (Paths.Combine (TestsDir, "data", a_valid_track2));
+
+ var ignore_events_func = new Func<PlayerState?, PlayerEvent?, bool> ((s, e) =>
+ e != null && (e.Value == PlayerEvent.Volume));
+
+ WaitFor (ignore_events_func,
+ () => {
+ service.Open (a_valid_uri1);
+ service.Play ();
+ },
+ PlayerState.Loading,
+ PlayerState.Loaded,
+ PlayerEvent.StartOfStream,
+ PlayerState.Playing);
+
+ WaitFor (ignore_events_func,
+ PlayerEvent.RequestNextTrack, // <- this is the key, notice that we expect only one, not two
+ PlayerState.Idle);
+ }
+
private void LoadAndPlay (string filename)
{
track_intercepts = 0;
@@ -371,7 +407,11 @@ namespace Banshee.MediaEngine
});
service.ConnectEvent (handler);
+ bool return_early = (state != null && service.CurrentState.Equals (state.Value));
action ();
+ if (return_early) {
+ return;
+ }
const int seconds = 3;
int count = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]