[rygel] core: Allow plugins to provide thumbnails



commit 4d9b1428e8df65da170b895f3bd981f65caf09e7
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Sun Sep 6 02:44:11 2009 +0300

    core: Allow plugins to provide thumbnails
    
    Plugins can now provide thumnails using a new easy-to-use API.

 src/rygel/Makefile.am                      |    1 +
 src/rygel/rygel-http-identity-handler.vala |   40 +++++++++++---
 src/rygel/rygel-http-request.vala          |   12 ++++
 src/rygel/rygel-http-server.vala           |   29 ++++++++++-
 src/rygel/rygel-media-item.vala            |   12 ++++
 src/rygel/rygel-thumbnail.vala             |   76 ++++++++++++++++++++++++++++
 src/rygel/rygel-transcode-manager.vala     |    1 +
 src/rygel/rygel-transcoder.vala            |    1 +
 8 files changed, 160 insertions(+), 12 deletions(-)
---
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index e9e289e..85d42a3 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -66,6 +66,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
 		    rygel-media-container.vala \
 		    rygel-simple-async-result.vala \
 		    rygel-media-item.vala \
+		    rygel-thumbnail.vala \
 		    rygel-browse.vala \
 		    rygel-didl-lite-writer.vala \
 		    rygel-transcoder.vala \
diff --git a/src/rygel/rygel-http-identity-handler.vala b/src/rygel/rygel-http-identity-handler.vala
index e473927..ec46794 100644
--- a/src/rygel/rygel-http-identity-handler.vala
+++ b/src/rygel/rygel-http-identity-handler.vala
@@ -30,20 +30,30 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPRequestHandler {
 
     public override void add_response_headers (HTTPRequest request)
                                                throws HTTPRequestError {
-        var item = request.item;
+        long size;
+        string mime_type;
 
-        request.msg.response_headers.append ("Content-Type", item.mime_type);
-        if (item.size >= 0) {
-            request.msg.response_headers.set_content_length (item.size);
+        if (request.thumbnail != null) {
+            size = request.thumbnail.size;
+            mime_type= request.thumbnail.mime_type;
+        } else {
+            size = request.item.size;
+            mime_type= request.item.mime_type;
         }
-        if (item.should_stream ()) {
+
+        request.msg.response_headers.append ("Content-Type", mime_type);
+        if (size >= 0) {
+            request.msg.response_headers.set_content_length (size);
+        }
+
+        if (request.thumbnail == null && request.item.should_stream ()) {
             if (request.time_range != null) {
                 request.time_range.add_response_header (request.msg);
             }
         } else {
             request.msg.response_headers.append ("Accept-Ranges", "bytes");
             if (request.byte_range != null) {
-                request.byte_range.add_response_header (request.msg, item.size);
+                request.byte_range.add_response_header (request.msg, size);
             }
         }
 
@@ -53,6 +63,14 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPRequestHandler {
 
     public override HTTPResponse render_body (HTTPRequest request)
                                               throws HTTPRequestError {
+        if (request.thumbnail != null) {
+            return new SeekableResponse (request.server,
+                                         request.msg,
+                                         request.thumbnail.uri,
+                                         request.byte_range,
+                                         request.thumbnail.size);
+        }
+
         var item = request.item;
 
         if (item.should_stream ()) {
@@ -84,8 +102,12 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPRequestHandler {
     protected override DIDLLiteResource add_resource (DIDLLiteItem didl_item,
                                                       HTTPRequest  request)
                                                       throws HTTPRequestError {
-        return request.item.add_resource (didl_item,
-                                          null,
-                                          request.http_server.get_protocol ());
+        var protocol = request.http_server.get_protocol ();
+
+        if (request.thumbnail != null) {
+            return request.thumbnail.add_resource (didl_item, protocol);
+        } else {
+            return request.item.add_resource (didl_item, null, protocol);
+        }
     }
 }
diff --git a/src/rygel/rygel-http-request.vala b/src/rygel/rygel-http-request.vala
index 580d11c..2299d7f 100644
--- a/src/rygel/rygel-http-request.vala
+++ b/src/rygel/rygel-http-request.vala
@@ -44,7 +44,9 @@ internal class Rygel.HTTPRequest : GLib.Object, Rygel.StateMachine {
     private HTTPResponse response;
 
     private string item_id;
+    private int thumbnail_index;
     public MediaItem item;
+    public Thumbnail thumbnail;
     public HTTPSeek byte_range;
     public HTTPSeek time_range;
 
@@ -61,6 +63,7 @@ internal class Rygel.HTTPRequest : GLib.Object, Rygel.StateMachine {
         this.server = server;
         this.msg = msg;
         this.query = query;
+        this.thumbnail_index = -1;
     }
 
     public void run (Cancellable? cancellable) {
@@ -86,6 +89,11 @@ internal class Rygel.HTTPRequest : GLib.Object, Rygel.StateMachine {
                 var transcoder = this.http_server.get_transcoder (target);
                 this.request_handler = new HTTPTranscodeHandler (transcoder);
             }
+
+            var index = this.query.lookup ("thumbnail");
+            if (index != null) {
+                this.thumbnail_index = index.to_int ();
+            }
         }
 
         if (this.item_id == null) {
@@ -151,6 +159,10 @@ internal class Rygel.HTTPRequest : GLib.Object, Rygel.StateMachine {
 
         this.item = (MediaItem) media_object;
 
+        if (this.thumbnail_index >= 0) {
+            this.thumbnail = this.item.thumbnails.get (this.thumbnail_index);
+        }
+
         this.handle_item_request ();
     }
 
diff --git a/src/rygel/rygel-http-server.vala b/src/rygel/rygel-http-server.vala
index d583aac..0d06b7e 100644
--- a/src/rygel/rygel-http-server.vala
+++ b/src/rygel/rygel-http-server.vala
@@ -67,11 +67,29 @@ internal class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
         if (!this.http_uri_present (item)) {
             // Create the HTTP proxy URI
             string protocol;
-            var uri = this.create_uri_for_item (item, null, out protocol);
+            var uri = this.create_uri_for_item (item, -1, null, out protocol);
             item.add_resource (didl_item, uri, protocol);
         }
 
         base.add_resources (didl_item, item);
+
+        // Thumbnails comes in the end
+        foreach (var thumbnail in item.thumbnails) {
+            if (!is_http_uri (thumbnail.uri)) {
+                var uri = thumbnail.uri; // Save the original URI
+                var index = item.thumbnails.index_of (thumbnail);
+                string protocol;
+
+                thumbnail.uri = this.create_uri_for_item (item,
+                                                          index,
+                                                          null,
+                                                          out protocol);
+                thumbnail.add_resource (didl_item, protocol);
+
+                // Now restore the original URI
+                thumbnail.uri = uri;
+            }
+        }
     }
 
     private bool http_uri_present (MediaItem item) {
@@ -104,11 +122,16 @@ internal class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
                                           path);
     }
 
-    internal override string create_uri_for_item (MediaItem  item,
-                                                  string?    transcode_target,
+    internal override string create_uri_for_item (MediaItem item,
+                                                  int       thumbnail_index,
+                                                  string?   transcode_target,
                                                   out string protocol) {
         string escaped = Uri.escape_string (item.id, "", true);
         string query = "?itemid=" + escaped;
+        if (thumbnail_index >= 0) {
+            query += "&thumbnail=" + thumbnail_index.to_string ();
+        }
+
         if (transcode_target != null) {
             escaped = Uri.escape_string (transcode_target, "", true);
             query += "&transcode=" + escaped;
diff --git a/src/rygel/rygel-media-item.vala b/src/rygel/rygel-media-item.vala
index 1e2e2d1..40dcca7 100644
--- a/src/rygel/rygel-media-item.vala
+++ b/src/rygel/rygel-media-item.vala
@@ -63,6 +63,8 @@ public class Rygel.MediaItem : MediaObject {
     public int pixel_height = -1;
     public int color_depth = -1;
 
+    public ArrayList<Thumbnail> thumbnails;
+
     public MediaItem (string         id,
                       MediaContainer parent,
                       string         title,
@@ -71,6 +73,8 @@ public class Rygel.MediaItem : MediaObject {
         this.parent = parent;
         this.title = title;
         this.upnp_class = upnp_class;
+
+        this.thumbnails = new ArrayList<Thumbnail> ();
     }
 
     // Live media items need to provide a nice working implementation of this
@@ -117,6 +121,14 @@ public class Rygel.MediaItem : MediaObject {
                 this.add_resource (didl_item, uri, protocol);
             }
         }
+
+        foreach (var thumbnail in this.thumbnails) {
+            var protocol = this.get_protocol_for_uri (thumbnail.uri);
+
+            if (allow_internal || protocol != "internal") {
+                thumbnail.add_resource (didl_item, protocol);
+            }
+        }
     }
 
     internal DIDLLiteResource add_resource (DIDLLiteItem didl_item,
diff --git a/src/rygel/rygel-thumbnail.vala b/src/rygel/rygel-thumbnail.vala
new file mode 100644
index 0000000..63f5e7d
--- /dev/null
+++ b/src/rygel/rygel-thumbnail.vala
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ *
+ * Author: Zeeshan Ali <zeenix gmail com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using GUPnP;
+
+private errordomain Rygel.ThumbnailError {
+    BAD_URI
+}
+
+/**
+ * Represents a picture or video thumbnail.
+ */
+public class Rygel.Thumbnail : GLib.Object {
+    public string uri;
+    public string mime_type;
+    public string dlna_profile;
+
+    public long size = -1;       // Size in bytes
+    public int width = -1;       // Width in pixels
+    public int height = -1;      // Height in pixels
+    public int color_depth = -1; // depth of pixels in bytes
+
+    public Thumbnail (string mime_type = "image/jpeg",
+                      string dlna_profile = "JPEG_TN") {
+        this.mime_type = mime_type;
+        this.dlna_profile = dlna_profile;
+    }
+
+    internal DIDLLiteResource add_resource (DIDLLiteItem didl_item,
+                                            string       protocol) {
+        var res = didl_item.add_resource ();
+
+        res.uri = this.uri;
+        res.size = this.size;
+
+        res.width = this.width;
+        res.height = this.height;
+        res.color_depth = this.color_depth;
+
+        /* Protocol info */
+        res.protocol_info = this.get_protocol_info (protocol);
+
+        return res;
+    }
+
+    private ProtocolInfo get_protocol_info (string protocol) {
+        var protocol_info = new ProtocolInfo ();
+
+        protocol_info.mime_type = this.mime_type;
+        protocol_info.dlna_profile = this.dlna_profile;
+        protocol_info.protocol = protocol;
+        protocol_info.dlna_flags |= DLNAFlags.INTERACTIVE_TRANSFER_MODE |
+                                    DLNAFlags.BACKGROUND_TRANSFER_MODE;
+
+        return protocol_info;
+    }
+}
diff --git a/src/rygel/rygel-transcode-manager.vala b/src/rygel/rygel-transcode-manager.vala
index fe15db8..5bb002e 100644
--- a/src/rygel/rygel-transcode-manager.vala
+++ b/src/rygel/rygel-transcode-manager.vala
@@ -53,6 +53,7 @@ internal abstract class Rygel.TranscodeManager : GLib.Object {
     }
 
     public abstract string create_uri_for_item (MediaItem  item,
+                                                int        thumbnail_index,
                                                 string?    transcode_target,
                                                 out string protocol);
 
diff --git a/src/rygel/rygel-transcoder.vala b/src/rygel/rygel-transcoder.vala
index f13a313..d16d4ca 100644
--- a/src/rygel/rygel-transcoder.vala
+++ b/src/rygel/rygel-transcoder.vala
@@ -66,6 +66,7 @@ internal abstract class Rygel.Transcoder : GLib.Object {
 
         string protocol;
         var uri = manager.create_uri_for_item (item,
+                                               -1,
                                                this.dlna_profile,
                                                out protocol);
         var res = item.add_resource (didl_item, uri, protocol);



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