[rygel] renderer: Add playback speeds support



commit 41478b32810d3d0a8410a9b729314b29cc273647
Author: Christophe Guiraud <christophe guiraud intel com>
Date:   Tue Dec 11 16:43:13 2012 +0100

    renderer: Add playback speeds support
    
    - allow to specify value other than 1.0 for playback speed.
    - allowed playback speed values are specified by the renderer
     player plugins.
    - add the X_DLNA_PS to the result of GetCurrentTransportAction
     invoked from a renderer.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=690056

 .../renderer-plugins/vala/example-player-vala.vala |   18 ++++++
 .../rygel-playbin-player.vala                      |   18 ++++++
 src/librygel-renderer/rygel-av-transport.vala      |   16 +++---
 src/librygel-renderer/rygel-media-player.vala      |    6 ++
 src/librygel-renderer/rygel-player-controller.vala |   12 ++++
 src/plugins/mpris/rygel-mpris-interfaces.vala      |    4 +
 src/plugins/mpris/rygel-mpris-player.vala          |   61 ++++++++++++++++++++
 7 files changed, 127 insertions(+), 8 deletions(-)
---
diff --git a/examples/renderer-plugins/vala/example-player-vala.vala b/examples/renderer-plugins/vala/example-player-vala.vala
index a79817b..4768c67 100644
--- a/examples/renderer-plugins/vala/example-player-vala.vala
+++ b/examples/renderer-plugins/vala/example-player-vala.vala
@@ -57,6 +57,24 @@ public class Rygel.Example.PlayerVala : GLib.Object, Rygel.MediaPlayer {
         }
     }
 
+    private string[] _allowed_playback_speeds = {"1/2","1","2"};
+    public string[] allowed_playback_speeds {
+        owned get {
+            return this._allowed_playback_speeds;
+        }
+    }
+
+    private string _playback_speed = "1";
+    public string playback_speed {
+        owned get {
+            return this._playback_speed;
+        }
+
+        set {
+            this._playback_speed = value;
+        }
+    }
+
     private string _uri = "";
     public string? uri {
         owned get {
diff --git a/src/librygel-renderer-gst/rygel-playbin-player.vala b/src/librygel-renderer-gst/rygel-playbin-player.vala
index 2616699..275477b 100644
--- a/src/librygel-renderer-gst/rygel-playbin-player.vala
+++ b/src/librygel-renderer-gst/rygel-playbin-player.vala
@@ -140,6 +140,24 @@ public class Rygel.Playbin.Player : GLib.Object, Rygel.MediaPlayer {
         }
     }
 
+    private string[] _allowed_playback_speeds = {"1"};
+    public string[] allowed_playback_speeds {
+        owned get {
+            return this._allowed_playback_speeds;
+        }
+    }
+
+    private string _playback_speed = "1";
+    public string playback_speed {
+        owned get {
+            return this._playback_speed;
+        }
+
+        set {
+            this._playback_speed = value;
+        }
+    }
+
     private string transfer_mode = null;
 
     private bool uri_update_hint = false;
diff --git a/src/librygel-renderer/rygel-av-transport.vala b/src/librygel-renderer/rygel-av-transport.vala
index 0a59cab..833cb7d 100644
--- a/src/librygel-renderer/rygel-av-transport.vala
+++ b/src/librygel-renderer/rygel-av-transport.vala
@@ -76,16 +76,15 @@ internal class Rygel.AVTransport : Service {
         }
     }
 
-    private string _speed = "1";
     public string speed {
-        get {
-            return this._speed;
+        owned get {
+            return this.player.playback_speed;
         }
 
         set {
-            this._speed = value;
+            this.player.playback_speed = value;
 
-            this.changelog.log ("TransportPlaySpeed", this._speed);
+            this.changelog.log ("TransportPlaySpeed", this.player.playback_speed);
         }
     }
 
@@ -169,7 +168,7 @@ internal class Rygel.AVTransport : Service {
         log.log ("PossiblePlaybackStorageMedia", "NOT_IMPLEMENTED");
         log.log ("PossibleRecordStorageMedia",   "NOT_IMPLEMENTED");
         log.log ("CurrentPlayMode",              this.mode);
-        log.log ("TransportPlaySpeed",           this.speed);
+        log.log ("TransportPlaySpeed",           this.player.playback_speed);
         log.log ("RecordMediumWriteStatus",      "NOT_IMPLEMENTED");
         log.log ("CurrentRecordQualityMode",     "NOT_IMPLEMENTED");
         log.log ("PossibleRecordQualityModes",   "NOT_IMPLEMENTED");
@@ -406,7 +405,7 @@ internal class Rygel.AVTransport : Service {
                         this.status,
                     "CurrentSpeed",
                         typeof (string),
-                        this.speed);
+                        this.player.playback_speed);
 
         action.return ();
     }
@@ -511,13 +510,14 @@ internal class Rygel.AVTransport : Service {
         string speed;
 
         action.get ("Speed", typeof (string), out speed);
-        if (speed != "1") {
+        if (!(speed in this.player.allowed_playback_speeds)) {
             action.return_error (717, _("Play speed not supported"));
 
             return;
         }
 
         this.player.playback_state = "PLAYING";
+        this.player.playback_speed = speed;
 
         action.return ();
     }
diff --git a/src/librygel-renderer/rygel-media-player.vala b/src/librygel-renderer/rygel-media-player.vala
index 68ecd0a..68d54a2 100644
--- a/src/librygel-renderer/rygel-media-player.vala
+++ b/src/librygel-renderer/rygel-media-player.vala
@@ -35,6 +35,12 @@ public interface Rygel.MediaPlayer : GLib.Object {
     /// The state as a UPnP playback state string such as PAUSED_PLAYBACK, "STOPPED" or "PLAYING"
     public abstract string playback_state { owned get; set; }
 
+    /// The allowed playback speeds as UPnP playback speeds such as "-4","-2","-1","-1/2","1/2","1","2","4"
+    public abstract string[] allowed_playback_speeds { owned get; }
+
+    /// The current media playback speed as UPnP playback speed
+    public abstract string playback_speed { owned get; set; }
+
     /// The URI of the current media.
     public abstract string? uri { owned get; set; }
 
diff --git a/src/librygel-renderer/rygel-player-controller.vala b/src/librygel-renderer/rygel-player-controller.vala
index 4f4be7c..f453d7a 100644
--- a/src/librygel-renderer/rygel-player-controller.vala
+++ b/src/librygel-renderer/rygel-player-controller.vala
@@ -92,6 +92,18 @@ internal class Rygel.PlayerController : Object {
             }
             if (actions != null && this.player.can_seek) {
                 actions += ",X_DLNA_SeekTime";
+
+                string play_speeds = "";
+                foreach (var speed in this.player.allowed_playback_speeds) {
+                    if (speed != "1") {
+                        if (play_speeds == "") {
+                            play_speeds = ",X_DLNA_PS=" + speed;
+                        } else {
+                            play_speeds += "\\," + speed;
+                        }
+                    }
+                }
+                actions += play_speeds;
             }
 
             if (actions == null) {
diff --git a/src/plugins/mpris/rygel-mpris-interfaces.vala b/src/plugins/mpris/rygel-mpris-interfaces.vala
index f41d2a8..42ea269 100644
--- a/src/plugins/mpris/rygel-mpris-interfaces.vala
+++ b/src/plugins/mpris/rygel-mpris-interfaces.vala
@@ -36,6 +36,10 @@ public interface Rygel.MPRIS.MediaPlayer.PlayerProxy : DBusProxy,
     public const string IFACE = "org.mpris.MediaPlayer2.Player";
 
     public abstract string playback_status { owned get; }
+    public abstract double rate { get; set; }
+    public abstract double minimum_rate { get; }
+    public abstract double maximum_rate { get; }
+
     public abstract double volume { get; set; }
     public abstract int64 position { get; }
     public abstract HashTable<string,Variant> metadata { owned get; }
diff --git a/src/plugins/mpris/rygel-mpris-player.vala b/src/plugins/mpris/rygel-mpris-player.vala
index df12c1e..39c5b07 100644
--- a/src/plugins/mpris/rygel-mpris-player.vala
+++ b/src/plugins/mpris/rygel-mpris-player.vala
@@ -65,6 +65,39 @@ public class Rygel.MPRIS.Player : GLib.Object, Rygel.MediaPlayer {
         }
     }
 
+    private string[] _allowed_playback_speeds = {"1"};
+    public string[] allowed_playback_speeds {
+        owned get {
+            return this._allowed_playback_speeds;
+        }
+    }
+
+    public string playback_speed {
+        owned get {
+            return this.double_to_rational (this.actual_player.rate);
+        }
+
+        set {
+            this.actual_player.rate = this.rational_to_double (value);
+        }
+    }
+
+    public double minimum_rate {
+        get {
+            return this.rational_to_double (_allowed_playback_speeds[0]);
+        }
+    }
+
+    public double maximum_rate {
+        get {
+            int i = _allowed_playback_speeds.length;
+
+            assert (i > 0);
+
+            return this.rational_to_double (_allowed_playback_speeds[i-1]);
+        }
+    }
+
     public string? uri {
         owned get {
             var val = this.actual_player.metadata.lookup ("xesam:url");
@@ -158,6 +191,34 @@ public class Rygel.MPRIS.Player : GLib.Object, Rygel.MediaPlayer {
         }
     }
 
+    private double rational_to_double (string r)
+    {
+         string[] rational;
+
+         rational = r.split("/", 2);
+
+         assert (rational[0] != "0");
+
+         if (rational[1] != null) {
+             assert (rational[1] != "0");
+         } else {
+             return double.parse (rational[0]);
+         }
+
+         return double.parse (rational[0]) / double.parse (rational[1]);
+    }
+
+    private string double_to_rational (double d)
+    {
+         foreach (var r in _allowed_playback_speeds) {
+             if (Math.fabs (rational_to_double (r) - d) < 0.1) {
+                 return r;
+             }
+         }
+
+         return "";
+    }
+
     private void on_properties_changed (DBusProxy actual_player,
                                         Variant   changed,
                                         string[]  invalidated) {



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