summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Georg <mail@jensge.org>2014-11-29 14:51:04 +0100
committerJens Georg <mail@jensge.org>2015-02-08 13:19:26 +0100
commit5c7579defe3d55de71f5328c2dde4f7586952b14 (patch)
treef6c3f3824ce846ee01d309ac8c7dbaa9201d3a0b
parentd0c9a4e5c2389b25c2c811e6fa666fed3626e644 (diff)
downloadrygel-5c7579defe3d55de71f5328c2dde4f7586952b14.tar.gz
server: Refactor subtitle handling
Code based on Cablelabs's CVP-2 implementation.
-rw-r--r--src/librygel-server/filelist.am1
-rw-r--r--src/librygel-server/rygel-http-byte-seek.vala3
-rw-r--r--src/librygel-server/rygel-http-get.vala6
-rw-r--r--src/librygel-server/rygel-http-identity-handler.vala16
-rw-r--r--src/librygel-server/rygel-http-thumbnail-handler.vala103
-rw-r--r--src/librygel-server/rygel-http-time-seek.vala2
-rw-r--r--src/librygel-server/rygel-image-item.vala26
-rw-r--r--src/librygel-server/rygel-thumbnail.vala51
-rw-r--r--src/librygel-server/rygel-video-item.vala11
-rw-r--r--src/librygel-server/rygel-visual-item.vala56
10 files changed, 171 insertions, 104 deletions
diff --git a/src/librygel-server/filelist.am b/src/librygel-server/filelist.am
index 86c8bc33..29ce50a7 100644
--- a/src/librygel-server/filelist.am
+++ b/src/librygel-server/filelist.am
@@ -43,6 +43,7 @@ LIBRYGEL_SERVER_NONVAPI_SOURCE_FILES = \
rygel-http-byte-seek.vala \
rygel-http-get-handler.vala \
rygel-http-get.vala \
+ rygel-http-thumbnail-handler.vala \
rygel-http-identity-handler.vala \
rygel-http-item-uri.vala \
rygel-http-post.vala \
diff --git a/src/librygel-server/rygel-http-byte-seek.vala b/src/librygel-server/rygel-http-byte-seek.vala
index 5742e06d..76cb3614 100644
--- a/src/librygel-server/rygel-http-byte-seek.vala
+++ b/src/librygel-server/rygel-http-byte-seek.vala
@@ -71,8 +71,7 @@ internal class Rygel.HTTPByteSeek : Rygel.HTTPSeek {
return force_seek || (!(request.object is MediaContainer) &&
((request.object as MediaFileItem).size > 0 &&
request.handler is HTTPIdentityHandler) ||
- (request.thumbnail != null &&
- request.thumbnail.size > 0) ||
+ (request.handler is HTTPThumbnailHandler) ||
(request.subtitle != null && request.subtitle.size > 0));
}
diff --git a/src/librygel-server/rygel-http-get.vala b/src/librygel-server/rygel-http-get.vala
index 3a4e229b..b3fd5b9e 100644
--- a/src/librygel-server/rygel-http-get.vala
+++ b/src/librygel-server/rygel-http-get.vala
@@ -72,6 +72,12 @@ internal class Rygel.HTTPGet : HTTPRequest {
this.cancellable);
}
+ if (uri.thumbnail_index >= 0) {
+ this.handler = new HTTPThumbnailHandler (this.object as MediaFileItem,
+ uri.thumbnail_index,
+ this.cancellable);
+ }
+
if (this.handler == null) {
this.handler = new HTTPIdentityHandler (this.cancellable);
}
diff --git a/src/librygel-server/rygel-http-identity-handler.vala b/src/librygel-server/rygel-http-identity-handler.vala
index f39e3612..6c8b126d 100644
--- a/src/librygel-server/rygel-http-identity-handler.vala
+++ b/src/librygel-server/rygel-http-identity-handler.vala
@@ -37,9 +37,6 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
if (request.subtitle != null) {
request.msg.response_headers.append ("Content-Type",
request.subtitle.mime_type);
- } else if (request.thumbnail != null) {
- request.msg.response_headers.append ("Content-Type",
- request.thumbnail.mime_type);
} else {
request.msg.response_headers.append ("Content-Type",
(request.object as MediaFileItem).mime_type);
@@ -85,12 +82,7 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
throws Error {
var protocol = request.http_server.get_protocol ();
- if (request.thumbnail != null) {
- return request.thumbnail.add_resource (didl_object as DIDLLiteItem,
- protocol);
- } else {
- return request.object.add_resource (didl_object, null, protocol);
- }
+ return request.object.add_resource (didl_object, null, protocol);
}
private HTTPResponse render_body_real (HTTPGet request) throws Error {
@@ -99,8 +91,6 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
if (request.subtitle != null) {
src = engine.create_data_source (request.subtitle.uri);
- } else if (request.thumbnail != null) {
- src = engine.create_data_source (request.thumbnail.uri);
} else {
src = (request.object as MediaFileItem).create_stream_source
(request.http_server.context.host_ip);
@@ -118,10 +108,6 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
return request.subtitle.size;
}
- if (request.thumbnail != null) {
- return request.thumbnail.size;
- }
-
return (request.object as MediaFileItem).size;
}
}
diff --git a/src/librygel-server/rygel-http-thumbnail-handler.vala b/src/librygel-server/rygel-http-thumbnail-handler.vala
new file mode 100644
index 00000000..364d1278
--- /dev/null
+++ b/src/librygel-server/rygel-http-thumbnail-handler.vala
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008, 2009 Nokia Corporation.
+ * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+ * <zeeshan.ali@nokia.com>
+ * Jens Georg <jensg@openismus.com>
+ * Craig Pratt <craig@ecaspia.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;
+
+internal class Rygel.HTTPThumbnailHandler : Rygel.HTTPGetHandler {
+ private MediaFileItem media_item;
+ private int thumbnail_index;
+ private Thumbnail thumbnail;
+
+ public HTTPThumbnailHandler (MediaFileItem media_item,
+ int thumbnail_index,
+ Cancellable? cancellable) throws HTTPRequestError
+ {
+
+ this.media_item = media_item;
+ this.thumbnail_index = thumbnail_index;
+ this.cancellable = cancellable;
+
+ if (media_item is MusicItem) {
+ var music_item = media_item as MusicItem;
+ this.thumbnail = music_item.album_art;
+ } else if (media_item is VisualItem) {
+ var visual_item = media_item as VisualItem;
+ if (thumbnail_index < visual_item.thumbnails.size) {
+ this.thumbnail = visual_item.thumbnails.get (thumbnail_index);
+ }
+ }
+ if (this.thumbnail == null) {
+ throw new HTTPRequestError.NOT_FOUND ("Thumbnail index %d not found for item '%s",
+ thumbnail_index, media_item.id);
+ }
+ }
+
+ public override bool supports_transfer_mode (string mode) {
+ // Support interactive and background transfers only
+ return (mode != TRANSFER_MODE_STREAMING);
+ }
+
+ public override void add_response_headers (HTTPGet request)
+ throws HTTPRequestError {
+ // Add Content-Type
+ request.msg.response_headers.append ("Content-Type", thumbnail.mime_type);
+
+ // Add contentFeatures.dlna.org
+ MediaResource res = this.thumbnail.get_resource
+ (request.http_server.get_protocol (), this.thumbnail_index);
+ string protocol_info = res.get_protocol_info ().to_string ();
+ var pi_fields = protocol_info.split (":", 4);
+ request.msg.response_headers.append ("contentFeatures.dlna.org", pi_fields[3]);
+
+ // Chain-up
+ base.add_response_headers (request);
+ }
+
+ public override HTTPResponse render_body (HTTPGet request)
+ throws HTTPRequestError {
+ DataSource src;
+ try {
+ var engine = MediaEngine.get_default ();
+ src = engine.create_data_source (this.thumbnail.uri);
+
+ return new HTTPResponse (request, this, src);
+ } catch (Error err) {
+ throw new HTTPRequestError.NOT_FOUND (err.message);
+ }
+ }
+
+ public override int64 get_resource_size () {
+ return thumbnail.size;
+ }
+
+ protected override DIDLLiteResource add_resource
+ (DIDLLiteObject didl_object,
+ HTTPGet request)
+ throws Error {
+ return null as DIDLLiteResource;
+ }
+}
diff --git a/src/librygel-server/rygel-http-time-seek.vala b/src/librygel-server/rygel-http-time-seek.vala
index 7b248a9a..a8290795 100644
--- a/src/librygel-server/rygel-http-time-seek.vala
+++ b/src/librygel-server/rygel-http-time-seek.vala
@@ -100,7 +100,7 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
return force_seek || (request.object is AudioItem &&
(request.object as AudioItem).duration > 0 &&
(request.handler is HTTPTranscodeHandler ||
- (request.thumbnail == null &&
+ (!(request.handler is HTTPThumbnailHandler) &&
request.subtitle == null &&
(request.object as MediaFileItem).is_live_stream ())));
}
diff --git a/src/librygel-server/rygel-image-item.vala b/src/librygel-server/rygel-image-item.vala
index d81aca4d..83e136b2 100644
--- a/src/librygel-server/rygel-image-item.vala
+++ b/src/librygel-server/rygel-image-item.vala
@@ -97,25 +97,6 @@ public class Rygel.ImageItem : MediaFileItem, VisualItem {
return res;
}
- internal override void add_resources (DIDLLiteItem didl_item,
- bool allow_internal)
- throws Error {
- base.add_resources (didl_item, allow_internal);
-
- this.add_thumbnail_resources (didl_item, allow_internal);
- }
-
- internal override void add_proxy_resources (HTTPServer server,
- DIDLLiteItem didl_item)
- throws Error {
- base.add_proxy_resources (server, didl_item);
-
- if (!this.place_holder) {
- // Thumbnails comes in the end
- this.add_thumbnail_proxy_resources (server, didl_item);
- }
- }
-
protected override ProtocolInfo get_protocol_info (string? uri,
string protocol) {
var protocol_info = base.get_protocol_info (uri, protocol);
@@ -124,4 +105,11 @@ public class Rygel.ImageItem : MediaFileItem, VisualItem {
return protocol_info;
}
+
+ internal override void add_additional_resources (HTTPServer server) {
+ base.add_additional_resources (server);
+
+ this.add_thumbnail_resources (server);
+ }
+
}
diff --git a/src/librygel-server/rygel-thumbnail.vala b/src/librygel-server/rygel-thumbnail.vala
index 42ed9201..9b38f314 100644
--- a/src/librygel-server/rygel-thumbnail.vala
+++ b/src/librygel-server/rygel-thumbnail.vala
@@ -36,45 +36,28 @@ public class Rygel.Thumbnail : Rygel.IconInfo {
this.dlna_profile = dlna_profile;
}
- internal virtual DIDLLiteResource? add_resource (DIDLLiteItem didl_item,
- string protocol) {
- var res = didl_item.add_resource ();
-
- /* We check for NULL because
- * gupnp_didl_lite_resource_set_uri(),
- * used by the generated code,
- * complains, with a critical warning, if the URI is NULL.
- * It's already the default.
- */
- if (this.uri != null) {
- res.uri = this.uri;
- }
-
- res.size64 = this.size;
+ internal virtual MediaResource get_resource (string protocol, int index) {
+ var name = "%s_thumbnail_%02d".printf (protocol, index);
+ MediaResource res = new MediaResource (name);
+ res.size = this.size;
res.width = this.width;
res.height = this.height;
res.color_depth = this.depth;
-
- /* Protocol info */
- res.protocol_info = this.get_protocol_info (protocol);
+ res.mime_type = this.mime_type;
+ res.dlna_profile = this.dlna_profile;
+ res.protocol = protocol;
+ // Note: These represent best-case. The MediaServer/HTTPServer can dial these back
+ res.dlna_flags |= DLNAFlags.INTERACTIVE_TRANSFER_MODE |
+ DLNAFlags.BACKGROUND_TRANSFER_MODE |
+ DLNAFlags.CONNECTION_STALL |
+ DLNAFlags.DLNA_V15;
+ res.dlna_operation = DLNAOperation.RANGE;
+ res.dlna_conversion = DLNAConversion.TRANSCODED;
+ res.extension = this.file_extension;
+
+ res.uri = this.uri;
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 |
- DLNAFlags.CONNECTION_STALL |
- DLNAFlags.DLNA_V15;
- protocol_info.dlna_operation = DLNAOperation.RANGE;
- protocol_info.dlna_conversion = DLNAConversion.TRANSCODED;
-
- return protocol_info;
- }
}
diff --git a/src/librygel-server/rygel-video-item.vala b/src/librygel-server/rygel-video-item.vala
index 6dc44a48..d0ca515c 100644
--- a/src/librygel-server/rygel-video-item.vala
+++ b/src/librygel-server/rygel-video-item.vala
@@ -113,8 +113,6 @@ public class Rygel.VideoItem : AudioItem, VisualItem {
}
base.add_resources (didl_item, allow_internal);
-
- this.add_thumbnail_resources (didl_item, allow_internal);
}
internal override MediaResource get_primary_resource () {
@@ -214,10 +212,11 @@ public class Rygel.VideoItem : AudioItem, VisualItem {
resource.subtitle_file_uri = main_subtitle.uri;
}
}
+ }
- if (!this.place_holder) {
- // Thumbnails comes in the end
- this.add_thumbnail_proxy_resources (server, didl_item);
- }
+ internal override void add_additional_resources (HTTPServer server) {
+ base.add_additional_resources (server);
+
+ this.add_thumbnail_resources (server);
}
}
diff --git a/src/librygel-server/rygel-visual-item.vala b/src/librygel-server/rygel-visual-item.vala
index 85068e53..0c623762 100644
--- a/src/librygel-server/rygel-visual-item.vala
+++ b/src/librygel-server/rygel-visual-item.vala
@@ -71,41 +71,43 @@ public interface Rygel.VisualItem : MediaFileItem {
}
}
- internal void add_thumbnail_resources (DIDLLiteItem didl_item,
- bool allow_internal)
- throws Error {
- 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 void set_visual_resource_properties (MediaResource res) {
res.width = this.width;
res.height = this.height;
res.color_depth = this.color_depth;
}
- internal void add_thumbnail_proxy_resources (HTTPServer server,
- DIDLLiteItem didl_item)
- throws Error {
- foreach (var thumbnail in this.thumbnails) {
- if (server.need_proxy (thumbnail.uri)) {
- var uri = thumbnail.uri; // Save the original URI
- var index = this.thumbnails.index_of (thumbnail);
+ internal void add_thumbnail_resources (HTTPServer http_server) {
+ for (var i = 0; i < this.thumbnails.size; i++) {
+ if (!this.place_holder) {
+ var thumbnail = this.thumbnails.get (i);
+ // Add the defined thumbnail uri unconditionally
+ // (it will be filtered out if the request is remote)
+ string protocol;
+ try {
+ protocol = this.get_protocol_for_uri (thumbnail.uri);
+ } catch (Error e) {
+ message ("Could not determine protocol for " + thumbnail.uri);
+ continue;
+ }
- thumbnail.uri = server.create_uri_for_object (this,
- index,
- -1,
- null,
- null);
- thumbnail.add_resource (didl_item, server.get_protocol ());
+ var thumb_res = thumbnail.get_resource (protocol, i);
+ thumb_res.uri = thumbnail.uri;
+ this.get_resource_list ().add (thumb_res);
+ if (http_server.need_proxy (thumbnail.uri)) {
+ var http_thumb_res = thumbnail.get_resource
+ (http_server.get_protocol (), i);
- // Now restore the original URI
- thumbnail.uri = uri;
+ var index = this.thumbnails.index_of (thumbnail);
+ // Make a http uri for the thumbnail
+ http_thumb_res.uri = http_server.create_uri_for_object
+ (this,
+ index,
+ -1,
+ null,
+ null);
+ this.get_resource_list ().add (http_thumb_res);
+ }
}
}
}