[rygel] server: Serve file items using resources



commit d0c9a4e5c2389b25c2c811e6fa666fed3626e644
Author: Jens Georg <mail jensge org>
Date:   Thu Nov 20 17:45:54 2014 +0100

    server: Serve file items using resources
    
    Based on Cablelabs's CVP-2 implementation.
    
    Signed-off-by: Jens Georg <mail jensge org>

 src/librygel-server/rygel-audio-item.vala          |    9 +-
 src/librygel-server/rygel-http-get-handler.vala    |    7 +-
 src/librygel-server/rygel-http-get.vala            |   22 +++
 .../rygel-http-identity-handler.vala               |    4 +
 .../rygel-http-resource-handler.vala               |    4 +
 src/librygel-server/rygel-http-server.vala         |   26 ----
 .../rygel-http-transcode-handler.vala              |    4 +
 src/librygel-server/rygel-image-item.vala          |   23 ++--
 src/librygel-server/rygel-media-engine.vala        |   23 +++
 src/librygel-server/rygel-media-file-item.vala     |  142 ++++++++++++++++----
 src/librygel-server/rygel-media-object.vala        |    2 +-
 src/librygel-server/rygel-video-item.vala          |   13 +--
 src/librygel-server/rygel-visual-item.vala         |    2 +-
 .../gstreamer/rygel-gst-media-engine.vala          |   61 +++++++++
 .../simple/rygel-simple-media-engine.vala          |   51 +++++++
 .../rygel-media-export-media-cache.vala            |   17 +++-
 16 files changed, 325 insertions(+), 85 deletions(-)
---
diff --git a/src/librygel-server/rygel-audio-item.vala b/src/librygel-server/rygel-audio-item.vala
index b6cd7ba..ec9b4c7 100644
--- a/src/librygel-server/rygel-audio-item.vala
+++ b/src/librygel-server/rygel-audio-item.vala
@@ -112,13 +112,8 @@ public class Rygel.AudioItem : MediaFileItem {
         return didl_item;
     }
 
-    internal override DIDLLiteResource add_resource
-                                        (DIDLLiteObject didl_object,
-                                         string?        uri,
-                                         string         protocol,
-                                         string?        import_uri = null)
-                                         throws Error {
-        var res = base.add_resource (didl_object, uri, protocol, import_uri);
+    internal override MediaResource get_primary_resource () {
+        var res = base.get_primary_resource ();
 
         res.duration = this.duration;
         res.bitrate = this.bitrate;
diff --git a/src/librygel-server/rygel-http-get-handler.vala b/src/librygel-server/rygel-http-get-handler.vala
index 48638ec..2d88881 100644
--- a/src/librygel-server/rygel-http-get-handler.vala
+++ b/src/librygel-server/rygel-http-get-handler.vala
@@ -71,8 +71,13 @@ internal abstract class Rygel.HTTPGetHandler: GLib.Object {
         request.msg.response_headers.append ("Connection", "close");
     }
 
+    /**
+     * Returns the resource size or -1 if not known.
+     */
+    public abstract int64 get_resource_size ();
+
     public virtual bool knows_size (HTTPGet request) {
-        return false;
+        return this.get_resource_size () >= 0;
     }
 
     // Create an HTTPResponse object that will render the body.
diff --git a/src/librygel-server/rygel-http-get.vala b/src/librygel-server/rygel-http-get.vala
index ede92a9..3a4e229 100644
--- a/src/librygel-server/rygel-http-get.vala
+++ b/src/librygel-server/rygel-http-get.vala
@@ -169,6 +169,28 @@ internal class Rygel.HTTPGet : HTTPRequest {
         // Add headers
         this.handler.add_response_headers (this);
 
+        int64 response_size;
+        {
+            // Response size might have already been set by one of the response elements
+            response_size = this.msg.response_headers.get_content_length ();
+
+            if (response_size > 0) {
+                this.msg.response_headers.set_content_length (response_size);
+                debug ("Response size set via response element: size "
+                       + response_size.to_string());
+            } else {
+                // If not already set by a response element, try to set it to the resource size
+                if ((response_size = this.handler.get_resource_size ()) > 0) {
+                    this.msg.response_headers.set_content_length (response_size);
+                    debug ("Response size set via response element: size "
+                           + response_size.to_string());
+                } else {
+                    debug ("Response size unknown");
+                }
+            }
+            // size will factor into other logic below...
+        }
+
         // Add general headers
         if (this.msg.request_headers.get_one ("Range") != null) {
             this.msg.set_status (Soup.Status.PARTIAL_CONTENT);
diff --git a/src/librygel-server/rygel-http-identity-handler.vala 
b/src/librygel-server/rygel-http-identity-handler.vala
index 54f03c0..f39e361 100644
--- a/src/librygel-server/rygel-http-identity-handler.vala
+++ b/src/librygel-server/rygel-http-identity-handler.vala
@@ -68,6 +68,10 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
         }
     }
 
+    public override int64 get_resource_size () {
+        return -1;
+    }
+
     public override bool knows_size (HTTPGet request) {
         var size = this.get_size (request);
 
diff --git a/src/librygel-server/rygel-http-resource-handler.vala 
b/src/librygel-server/rygel-http-resource-handler.vala
index 4dcf575..b1ed7ab 100644
--- a/src/librygel-server/rygel-http-resource-handler.vala
+++ b/src/librygel-server/rygel-http-resource-handler.vala
@@ -80,6 +80,10 @@ internal class Rygel.HTTPMediaResourceHandler : HTTPGetHandler {
         }
     }
 
+    public override int64 get_resource_size () {
+        return media_resource.size;
+    }
+
     protected override DIDLLiteResource add_resource (DIDLLiteObject didl_object,
                                                       HTTPGet      request)
                                                       throws Error {
diff --git a/src/librygel-server/rygel-http-server.vala b/src/librygel-server/rygel-http-server.vala
index daabf0b..7f60b0f 100644
--- a/src/librygel-server/rygel-http-server.vala
+++ b/src/librygel-server/rygel-http-server.vala
@@ -77,36 +77,10 @@ public class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
         // This server supports all DLNA delivery modes - so leave those flags alone
      }
 
-    internal void add_proxy_resource (DIDLLiteItem  didl_item,
-                                      MediaFileItem item)
-                                      throws Error {
-        if (this.http_uri_present (item)) {
-            return;
-        }
-
-        var uri = this.create_uri_for_object (item, -1, -1, null, null);
-
-        item.add_resource (didl_item, uri, this.get_protocol (), uri);
-    }
-
     public bool need_proxy (string uri) {
         return Uri.parse_scheme (uri) != "http";
     }
 
-    private bool http_uri_present (MediaItem item) {
-        bool present = false;
-
-        foreach (var uri in item.get_uris ()) {
-            if (!this.need_proxy (uri)) {
-                present = true;
-
-                break;
-            }
-        }
-
-        return present;
-    }
-
     private void on_cancelled (Cancellable cancellable) {
         // Cancel all state machines
         this.cancellable.cancel ();
diff --git a/src/librygel-server/rygel-http-transcode-handler.vala 
b/src/librygel-server/rygel-http-transcode-handler.vala
index f6486e4..94492da 100644
--- a/src/librygel-server/rygel-http-transcode-handler.vala
+++ b/src/librygel-server/rygel-http-transcode-handler.vala
@@ -67,6 +67,10 @@ internal class Rygel.HTTPTranscodeHandler : HTTPGetHandler {
         }
     }
 
+    public override int64 get_resource_size () {
+        return -1;
+    }
+
     protected override DIDLLiteResource add_resource
                                         (DIDLLiteObject didl_object,
                                          HTTPGet      request)
diff --git a/src/librygel-server/rygel-image-item.vala b/src/librygel-server/rygel-image-item.vala
index 219dac3..d81aca4 100644
--- a/src/librygel-server/rygel-image-item.vala
+++ b/src/librygel-server/rygel-image-item.vala
@@ -87,6 +87,16 @@ public class Rygel.ImageItem : MediaFileItem, VisualItem {
         this.add_thumbnail_for_uri (uri);
     }
 
+    internal override MediaResource get_primary_resource () {
+        var res = base.get_primary_resource ();
+
+        this.set_visual_resource_properties (res);
+
+        res.dlna_flags |= DLNAFlags.INTERACTIVE_TRANSFER_MODE;
+
+        return res;
+    }
+
     internal override void add_resources (DIDLLiteItem didl_item,
                                           bool         allow_internal)
                                           throws Error {
@@ -95,19 +105,6 @@ public class Rygel.ImageItem : MediaFileItem, VisualItem {
         this.add_thumbnail_resources (didl_item, allow_internal);
     }
 
-    internal override DIDLLiteResource add_resource
-                                        (DIDLLiteObject didl_object,
-                                         string?      uri,
-                                         string       protocol,
-                                         string?      import_uri = null)
-                                         throws Error {
-        var res = base.add_resource (didl_object, uri, protocol, import_uri);
-
-        this.add_visual_props (res);
-
-        return res;
-    }
-
     internal override void add_proxy_resources (HTTPServer   server,
                                                 DIDLLiteItem didl_item)
                                                 throws Error {
diff --git a/src/librygel-server/rygel-media-engine.vala b/src/librygel-server/rygel-media-engine.vala
index 247475b..2314229 100644
--- a/src/librygel-server/rygel-media-engine.vala
+++ b/src/librygel-server/rygel-media-engine.vala
@@ -99,6 +99,29 @@ public abstract class Rygel.MediaEngine : GLib.Object {
     public abstract unowned List<DLNAProfile> get_dlna_profiles ();
 
     /**
+     * Retrieve engine-provided resources for the given MediaObject
+     *
+     * The MediaResources returned may include formats/profiles that do not
+     * match the source content byte-for-byte (e.g. transcodes, encrypted
+     * formats, etc). The MediaEngine must return a MediaResource for the raw
+     * MediaObject content if it can support streaming the content directly.
+     *
+     * The order of MediaResources in the returned List should be from
+     * most-preferred to least-preferred and each must have a unique
+     * alphanumeric "name" field.
+     *
+     * Note: The engine should set all delivery-related flags assuming all
+     * delivery forms are supported (e.g. the protocol fields and delivery
+     * flags of the ProtocolInfo). And the resource uri should be set to the
+     * empty string for http-delivered resources. The effective delivery
+     * options and uri will be established by the HTTP server.
+     *
+     * @return A list of #MediaResources<!-- -->s or null if no representations
+     *         are provided by the engine for the item.
+     */
+    public abstract async Gee.List<MediaResource> ? get_resources_for_item (MediaObject item);
+
+   /**
      * Get a list of the transcoders that are provided by this media engine.
      *
      * @return A list of #RygelTranscoder<!-- -->s or null if not supported.
diff --git a/src/librygel-server/rygel-media-file-item.vala b/src/librygel-server/rygel-media-file-item.vala
index 249d285..d915c5a 100644
--- a/src/librygel-server/rygel-media-file-item.vala
+++ b/src/librygel-server/rygel-media-file-item.vala
@@ -113,6 +113,8 @@ public abstract class Rygel.MediaFileItem : MediaItem {
                 upnp_class : upnp_class);
     }
 
+    public static Gee.HashMap<string, string> mime_to_ext;
+
     static construct {
         try {
             address_regex = new Regex (Regex.escape_string ("@ADDRESS@"));
@@ -203,42 +205,116 @@ public abstract class Rygel.MediaFileItem : MediaItem {
     internal override DIDLLiteObject? serialize (Serializer serializer,
                                                  HTTPServer http_server)
                                                  throws Error {
-        var didl_item = base.serialize (serializer, http_server)
-                                        as DIDLLiteItem;
-
-        /* We list proxy/transcoding resources first instead of original URIs
-         * because some crappy MediaRenderer/ControlPoint implemenation out
-         * there just choose the first one in the list instead of the one they
-         * can handle.
-         */
-        this.add_proxy_resources (http_server, didl_item);
+        var didl_item = base.serialize (serializer, http_server) as DIDLLiteItem;
 
         if (!this.place_holder) {
-            var host_ip = http_server.context.host_ip;
-
-            // then original URIs
-            bool internal_allowed;
-            internal_allowed = http_server.context.interface == "lo" ||
-                               host_ip == "127.0.0.1";
-            this.add_resources (didl_item, internal_allowed);
-
-            foreach (var res in didl_item.get_resources ()) {
-                res.uri = MediaFileItem.address_regex.replace_literal (res.uri,
-                                                                       -1,
-                                                                       0,
-                                                                       host_ip);
-            }
+            // Subclasses can override add_resources and augment the media resource list (which
+            //  should contain the primary resource representations for the MediaItem
+            //  at this point) with any secondary representations or alternate delivery
+            //  mechanisms they can provide
+            this.add_additional_resources (http_server);
+
+            this.add_proxy_resources (http_server, didl_item);
+
+            this.serialize_resource_list (didl_item, http_server);
         }
 
         return didl_item;
     }
 
+    /**
+     * Subclasses override this method to create the type-specific primary MediaResource.
+     *
+     * The resource returned is presumed to represent the "internal" file resource and
+     * a uri referring to the source file. Transport-specific variants can be created
+     * by the caller.
+     */
+    public virtual MediaResource get_primary_resource () {
+        var res = new MediaResource ("primary");
+
+        res.mime_type = this.mime_type;
+        res.dlna_profile = this.dlna_profile;
+        res.dlna_flags = DLNAFlags.BACKGROUND_TRANSFER_MODE;
+
+        // MediaFileItems refer directly to the source URI
+        res.uri = this.get_primary_uri ();
+        try {
+            res.protocol = this.get_protocol_for_uri (res.uri);
+        } catch (Error e) {
+            warning ("Could not determine protocol for " + res.uri);
+        }
+        res.extension = get_extension ();
+        res.size = this.size;
+        return res;
+    }
+
+    /**
+     * Return the file/uri extension that best represents the item's primary resource.
+     */
+    public virtual string get_extension () {
+        string uri_extension = null;
+        // Use the extension from the source content filename, if it has an extension
+        string basename = Path.get_basename (this.get_primary_uri ());
+        int dot_index = -1;
+        if (basename != null) {
+            dot_index = basename.last_index_of (".");
+            if (dot_index > -1) {
+               uri_extension = basename.substring (dot_index + 1);
+            }
+        }
+
+        if (uri_extension == null) {
+            uri_extension = ext_from_mime_type (this.mime_type);
+        }
+        return uri_extension;
+    }
+
+    protected string ext_from_mime_type (string mime_type) {
+        if (mime_to_ext == null) {
+            // Lazy initialization of the static hashmap
+            mime_to_ext = new Gee.HashMap<string, string> ();
+            // videos
+            string[] videos = {"mpeg", "webm", "ogg", "mp4"};
+
+            foreach (string video in videos) {
+                mime_to_ext.set ("video/" + video, video);
+            }
+            mime_to_ext.set ("video/x-matroska", "mkv");
+
+            // audios
+            mime_to_ext.set ("audio/x-wav", "wav");
+            mime_to_ext.set ("audio/x-matroska", "mka");
+            mime_to_ext.set ("audio/L16","pcm");
+            mime_to_ext.set ("audio/vnd.dlna.adts","adts");
+            mime_to_ext.set ("audio/mpeg","mp3");
+            mime_to_ext.set ("audio/3gpp","3gp");
+
+            // images
+            string[] images = {"jpeg", "png"};
+
+            foreach (string image in images) {
+                mime_to_ext.set ("image/" + image, image);
+            }
+
+            // texts
+            mime_to_ext.set ("text/srt", "srt");
+            mime_to_ext.set ("text/xml", "xml");
+
+            // applications? (can be either video or audio?);
+            mime_to_ext.set ("application/ogg", "ogg");
+        }
+
+        if (MediaFileItem.mime_to_ext.has_key (mime_type)) {
+            return mime_to_ext.get (mime_type);
+        }
+
+        return "";
+    }
+
+
     internal virtual void add_proxy_resources (HTTPServer   server,
                                                DIDLLiteItem didl_item)
                                                throws Error {
-        // Proxy resource for the original resources
-        server.add_proxy_resource (didl_item, this);
-
         if (!this.place_holder) {
             // Transcoding resources
             server.add_resources (didl_item, this);
@@ -274,4 +350,18 @@ public abstract class Rygel.MediaFileItem : MediaItem {
             }
         }
     }
+
+    /**
+     * Subclasses can override this method to augment the MediaObject MediaResource
+     * list with secondary MediaResource objects representing derivative resources.
+     *
+     * Note: Implementations should add both internal/file-based resources and HTTP-accessible
+     *       resources to the MediaResource list.
+     * FIXME: Will be renamed once we can safely remove old add_resources
+     */
+    internal virtual void add_additional_resources (HTTPServer server) {
+        /* Do nothing - provide default implementation to avoid unnecessary
+           empty code blocks.
+         */
+    }
 }
diff --git a/src/librygel-server/rygel-media-object.vala b/src/librygel-server/rygel-media-object.vala
index 179ee06..e05d467 100644
--- a/src/librygel-server/rygel-media-object.vala
+++ b/src/librygel-server/rygel-media-object.vala
@@ -266,7 +266,7 @@ public abstract class Rygel.MediaObject : GLib.Object {
             } else {
                 try {
                     var protocol = this.get_protocol_for_uri (res.uri);
-                    if (protocol != "internal") {
+                    if (protocol != "internal" || http_server.is_local ()) {
                         // Exclude internal resources when request is non-local
                         var didl_resource = didl_object.add_resource ();
                         res.serialize (didl_resource);
diff --git a/src/librygel-server/rygel-video-item.vala b/src/librygel-server/rygel-video-item.vala
index c9d3a16..6dc44a4 100644
--- a/src/librygel-server/rygel-video-item.vala
+++ b/src/librygel-server/rygel-video-item.vala
@@ -117,15 +117,10 @@ public class Rygel.VideoItem : AudioItem, VisualItem {
         this.add_thumbnail_resources (didl_item, allow_internal);
     }
 
-    internal override DIDLLiteResource add_resource
-                                        (DIDLLiteObject didl_object,
-                                         string?        uri,
-                                         string         protocol,
-                                         string?        import_uri = null)
-                                         throws Error {
-        var res = base.add_resource (didl_object, uri, protocol, import_uri);
-
-        this.add_visual_props (res);
+    internal override MediaResource get_primary_resource () {
+        var res = base.get_primary_resource ();
+
+        this.set_visual_resource_properties (res);
 
         return res;
     }
diff --git a/src/librygel-server/rygel-visual-item.vala b/src/librygel-server/rygel-visual-item.vala
index 2ab8897..85068e5 100644
--- a/src/librygel-server/rygel-visual-item.vala
+++ b/src/librygel-server/rygel-visual-item.vala
@@ -83,7 +83,7 @@ public interface Rygel.VisualItem : MediaFileItem {
         }
     }
 
-    internal void add_visual_props (DIDLLiteResource res) {
+    internal void set_visual_resource_properties (MediaResource res) {
         res.width = this.width;
         res.height = this.height;
         res.color_depth = this.color_depth;
diff --git a/src/media-engines/gstreamer/rygel-gst-media-engine.vala 
b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
index 1486737..f2b4f81 100644
--- a/src/media-engines/gstreamer/rygel-gst-media-engine.vala
+++ b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
@@ -22,6 +22,7 @@
 
 using Gst;
 using Gee;
+using GUPnP;
 
 // Remove for GStreamer 1.0
 [CCode (cname = "PRESET_DIR")]
@@ -128,6 +129,66 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
         }
     }
 
+    public override async Gee.List<MediaResource>? get_resources_for_item (MediaObject
+            object) {
+        if (! (object is MediaFileItem)) {
+            warning ("Can only process file-based MediaObjects (MediaFileItems)");
+            return null;
+        }
+
+        var item = object as MediaFileItem;
+
+        // For MediaFileItems, the primary URI refers directly to the content
+        string source_uri = item.get_primary_uri ();
+
+        debug ("get_resources_for_item(%s)", source_uri);
+
+        if (!source_uri.has_prefix ("file://")) {
+            warning ("Can't process non-file uri " + source_uri);
+            return null;
+        }
+
+        Gee.List<MediaResource> resources = new Gee.ArrayList<MediaResource> ();
+
+        var primary_res = item.get_primary_resource ();
+
+        // The GstMediaEngine only supports byte-based seek on the primary resource currently
+        primary_res.dlna_operation = DLNAOperation.RANGE;
+
+        // The GstMediaEngine supports connection stalling on the primary resource
+        primary_res.dlna_flags |= DLNAFlags.CONNECTION_STALL;
+
+        // Add a resource for http consumption
+        MediaResource http_res = new MediaResource.from_resource ("primary_http",
+                                                                  primary_res);
+        http_res.uri = ""; // The URI needs to be assigned by the MediaServer
+        resources.add (http_res);
+
+        // Put the primary resource as most-preferred (front of the list)
+        resources.add (primary_res);
+
+        return resources;
+    }
+
+    public override DataSource? create_data_source_for_resource
+                                        (MediaObject object,
+                                         MediaResource res) throws Error {
+        if (!(object is MediaFileItem)) {
+            warning ("Can only process file-based MediaObjects (MediaFileItem)");
+            return null;
+        }
+
+        var item = object as MediaFileItem;
+
+        string source_uri = item.get_primary_uri ();
+        debug ("creating data source for %s", source_uri);
+
+        DataSource ds = new GstDataSource (source_uri);
+
+        return ds;
+    }
+
+
     public DataSource create_data_source_from_element (Element element) {
         return new GstDataSource.from_element (element);
     }
diff --git a/src/media-engines/simple/rygel-simple-media-engine.vala 
b/src/media-engines/simple/rygel-simple-media-engine.vala
index 512a9f2..42253c6 100644
--- a/src/media-engines/simple/rygel-simple-media-engine.vala
+++ b/src/media-engines/simple/rygel-simple-media-engine.vala
@@ -20,6 +20,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+using GUPnP;
+
 /**
  * The simple media engine does not use GStreamer or any other
  * multimedia framework. Therefore its capabilities are limited.
@@ -40,6 +42,55 @@ internal class Rygel.SimpleMediaEngine : MediaEngine {
         return null;
     }
 
+    public override async Gee.List<MediaResource>? get_resources_for_item (MediaObject
+            object) {
+        if (! (object is MediaFileItem)) {
+            warning ("Can only process file-based MediaObjects (MediaFileItems)");
+            return null;
+        }
+
+        var item = object as MediaFileItem;
+
+        // For MediaFileItems, uri 0 is the file URI referring directly to the content
+        string source_uri = item.get_primary_uri ();
+        if (!source_uri.has_prefix ("file://")) {
+            warning ("Can't process non-file uri " + source_uri);
+        }
+
+        debug ("get_resources_for_item (%s)", source_uri);
+
+        Gee.List<MediaResource> resources = new Gee.ArrayList<MediaResource> ();
+
+        var primary_res = item.get_primary_resource ();
+
+        // The SimpleMediaEngine supports only byte-based seek
+        primary_res.dlna_operation = GUPnP.DLNAOperation.RANGE;
+
+        // The SimpleMediaEngine supports connection stalling on
+        primary_res.dlna_flags |= DLNAFlags.CONNECTION_STALL;
+
+        // Add a resource for http consumption (as SimpleMediaEngine can handle http)
+        MediaResource http_res = new MediaResource.from_resource ("primary_http",
+                                                                  primary_res);
+        http_res.uri = ""; // The URI needs to be assigned by the MediaServer
+        resources.add (http_res);
+
+        resources.add (primary_res);
+
+        return resources;
+   }
+
+    public override DataSource? create_data_source_for_resource
+                                        (MediaObject object,
+                                         MediaResource res) throws Error {
+       if (!(object is MediaFileItem)) {
+            warning ("Can only process file-based MediaObjects (MediaFileItem)");
+            return null;
+       }
+
+       string source_uri = object.get_primary_uri ();
+       return new SimpleDataSource (source_uri);
+    }
     public override DataSource? create_data_source (string uri) {
         if (!uri.has_prefix ("file://")) {
             return null;
diff --git a/src/plugins/media-export/rygel-media-export-media-cache.vala 
b/src/plugins/media-export/rygel-media-export-media-cache.vala
index d24c81b..c4d95d9 100644
--- a/src/plugins/media-export/rygel-media-export-media-cache.vala
+++ b/src/plugins/media-export/rygel-media-export-media-cache.vala
@@ -910,7 +910,22 @@ public class Rygel.MediaExport.MediaCache : Object {
                 if (uri != null) {
                     item.add_uri (uri);
                 }
-                break;
+
+                // Call the MediaEngine to determine which item representations it can support
+                var media_engine = MediaEngine.get_default ( );
+                media_engine.get_resources_for_item.begin ( item,
+                                                            (obj, res) => {
+                    var added_resources = media_engine
+                                          .get_resources_for_item.end (res);
+                    debug ("Adding %d resources to item source %s",
+                           added_resources.size, item.get_primary_uri ());
+                    foreach (var resrc in added_resources) {
+                       debug ("Media-export item media resource %s",
+                              resrc.get_name ());
+                    }
+                    item.get_resource_list ().add_all (added_resources);
+                  });
+               break;
             default:
                 assert_not_reached ();
         }


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