[rygel/wip/cablelabs-integration: 27/27] WIP



commit 2d18e45f369bf05938455ed66de02fbdaa02890e
Author: Jens Georg <mail jensge org>
Date:   Wed Dec 3 09:10:59 2014 +0100

    WIP

 src/librygel-server/rygel-image-item.vala          |   11 +++-
 src/librygel-server/rygel-media-engine.vala        |   23 ++++++++
 .../gstreamer/rygel-gst-media-engine.vala          |   60 ++++++++++++++++++++
 .../simple/rygel-simple-media-engine.vala          |   51 +++++++++++++++++
 .../rygel-media-export-media-cache.vala            |   17 +++++-
 5 files changed, 160 insertions(+), 2 deletions(-)
---
diff --git a/src/librygel-server/rygel-image-item.vala b/src/librygel-server/rygel-image-item.vala
index 4f7e8a4..f491f5f 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 {
@@ -128,5 +138,4 @@ public class Rygel.ImageItem : MediaFileItem, VisualItem {
 
         this.add_thumbnail_resources (server);
     }
-
 }
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/media-engines/gstreamer/rygel-gst-media-engine.vala 
b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
index 1486737..5a6c7b6 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")]
@@ -116,6 +117,24 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
         return this.transcoders;
     }
 
+    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 override DataSource? create_data_source (string uri) {
         try {
             return new GstDataSource (uri);
@@ -128,6 +147,47 @@ 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 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..ab30aea 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,17 @@ internal class Rygel.SimpleMediaEngine : MediaEngine {
         return null;
     }
 
+    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;
@@ -47,6 +60,44 @@ internal class Rygel.SimpleMediaEngine : MediaEngine {
 
         return new SimpleDataSource (uri);
     }
+
+    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 static Rygel.MediaEngine module_get_instance () {
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]