[rygel] renderer: Fix image playlist "slide show"



commit 3b7589562493fd86f4deebee41a3e166c646b1b8
Author: Jussi Kukkonen <jku goto fi>
Date:   Fri Jul 11 15:35:02 2014 +0300

    renderer: Fix image playlist "slide show"
    
    The image playlist timer wasn't working: start the timer from both
    apply_track() and when playback state changes to PLAYING. This
    required some refactoring.
    
    Also, include "Pause" TransportAction for image playlists. Make sure
    Pause() method call returns "701 Transition not available" for
    individual images, but not for image playlists.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=731467

 src/librygel-renderer/rygel-av-transport.vala      |    2 +-
 .../rygel-default-player-controller.vala           |   73 ++++++++++++++------
 src/librygel-renderer/rygel-player-controller.vala |    3 +
 3 files changed, 55 insertions(+), 23 deletions(-)
---
diff --git a/src/librygel-renderer/rygel-av-transport.vala b/src/librygel-renderer/rygel-av-transport.vala
index c4448bd..da95bb4 100644
--- a/src/librygel-renderer/rygel-av-transport.vala
+++ b/src/librygel-renderer/rygel-av-transport.vala
@@ -487,7 +487,7 @@ internal class Rygel.AVTransport : Service {
             return;
         }
 
-        if (this.controller.playback_state != "PLAYING") {
+        if (!this.controller.can_pause) {
             action.return_error (701, _("Transition not available"));
 
             return;
diff --git a/src/librygel-renderer/rygel-default-player-controller.vala 
b/src/librygel-renderer/rygel-default-player-controller.vala
index 346d722..ca45e02 100644
--- a/src/librygel-renderer/rygel-default-player-controller.vala
+++ b/src/librygel-renderer/rygel-default-player-controller.vala
@@ -120,6 +120,19 @@ internal class Rygel.DefaultPlayerController : Rygel.PlayerController, Object {
     public string next_uri { owned get; protected set; default = ""; }
     public string next_metadata { owned get; protected set; default = ""; }
 
+    public bool can_pause {
+        get {
+            if (this.playback_state != "PLAYING" &&
+                this.playback_state != "TRANSITIONING") {
+                return false;
+            }
+
+            /* Pause is valid for images only in playlist */
+            return (!this.player.mime_type.has_prefix ("image/") ||
+                    this.playlist != null);
+        }
+    }
+
     public string current_transport_actions {
         owned get {
             string actions = null;
@@ -127,7 +140,9 @@ internal class Rygel.DefaultPlayerController : Rygel.PlayerController, Object {
                 case "PLAYING":
                 case "TRANSITIONING":
                     actions = "Stop";
-                    if (!this.player.mime_type.has_prefix ("image/")) {
+                    /* Pause is valid for images only in playlist */
+                    if (!this.player.mime_type.has_prefix ("image/") ||
+                        this.playlist != null) {
                         actions += ",Pause";
                     }
                     break;
@@ -349,7 +364,7 @@ internal class Rygel.DefaultPlayerController : Rygel.PlayerController, Object {
             // Play next item in playlist, play next_uri, or move to STOPPED
             Idle.add (() => {
                 if (!this.next ()) {
-                    this.reset ();
+                    this.playback_state = "STOPPED";
                 }
 
                 return false;
@@ -357,6 +372,24 @@ internal class Rygel.DefaultPlayerController : Rygel.PlayerController, Object {
         } else if (this._playback_state != state) {
             // mirror player value in _playback_state and notify
             this._playback_state = state;
+
+            if (this.timeout_id != 0) {
+                Source.remove (this.timeout_id);
+                this.timeout_id = 0;
+            }
+
+            /* start image playlist timeout and update track */
+            switch (this._playback_state) {
+                case "PLAYING":
+                    this.setup_image_timeout ();
+                    break;
+                case "STOPPED":
+                    this.track = 1;
+                    break;
+                default:
+                    break;
+            }
+
             this.notify_property ("playback-state");
         }
     }
@@ -383,37 +416,33 @@ internal class Rygel.DefaultPlayerController : Rygel.PlayerController, Object {
                                         (item.get_xml_string ());
             this.track_uri = res.get_uri ();
 
-            if (item.upnp_class.has_prefix ("object.item.image") &&
-                this.playback_state != "STOPPED") {
-                this.setup_image_timeouts (item.lifetime);
+            if (this.playback_state == "PLAYING") {
+                setup_image_timeout ();
             }
         }
     }
 
-    private void reset () {
-        this.playback_state = "STOPPED";
-        this.track = 1;
-    }
-
-    private void setup_image_timeouts (long lifetime) {
-        // For images, we handle the timeout here. Either the item carries a
-        // dlna:lifetime tag, then we use that or we use a default timeout of
-        // 5 minutes.
-        var timeout = this.default_image_timeout;
-        if (lifetime > 0) {
-            timeout = (uint) lifetime;
+    private void setup_image_timeout () {
+        if (this.playlist == null) {
+             return;
         }
 
-        debug ("Item is image, setup timer: %ld", timeout);
+        var item = this.playlist.nth (this.track - 1).data;
+        if (!item.upnp_class.has_prefix ("object.item.image")) {
+            return;
+        }
 
-        if (this.timeout_id != 0) {
-            Source.remove (this.timeout_id);
+        // If image does not have dlna:lifetime tag, then use a default timeout
+        var lifetime = item.lifetime;
+        if (lifetime <= 0) {
+            lifetime = this.default_image_timeout;
         }
+        debug ("Item is image, setup timer: %ld", lifetime);
 
-        this.timeout_id = Timeout.add_seconds ((uint) timeout, () => {
+        this.timeout_id = Timeout.add_seconds ((uint) lifetime, () => {
             this.timeout_id = 0;
             if (!this.next ()) {
-                this.reset ();
+                this.playback_state = "STOPPED";
             }
 
             return false;
diff --git a/src/librygel-renderer/rygel-player-controller.vala 
b/src/librygel-renderer/rygel-player-controller.vala
index 8b7044a..1b9ab8a 100644
--- a/src/librygel-renderer/rygel-player-controller.vala
+++ b/src/librygel-renderer/rygel-player-controller.vala
@@ -62,6 +62,9 @@ public interface Rygel.PlayerController : GLib.Object {
 
     public abstract string play_mode { get; set; }
 
+    /// Return true if the current controller can go into PAUSE playback state
+    public abstract bool can_pause { get; }
+
     public abstract bool next ();
 
     public abstract bool previous ();


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