[rygel] server,engines: Make transcoders special resources



commit af2c32f1211b9970a66ce1f939fc182ec3e71d9e
Author: Jens Georg <mail jensge org>
Date:   Sun Feb 8 15:16:07 2015 +0100

    server,engines: Make transcoders special resources
    
    Move the knowledge of transcoders to the media engine which will add the
    transcoders as special resources.
    
    Code based on CVP-2 implementation from Cablelabs.
    
    Signed-off-by: Jens Georg <mail jensge org>

 src/librygel-server/filelist.am                    |    3 -
 src/librygel-server/rygel-http-get.vala            |    7 -
 src/librygel-server/rygel-http-item-uri.vala       |   19 +---
 src/librygel-server/rygel-http-server.vala         |   26 +---
 src/librygel-server/rygel-http-time-seek.vala      |   10 ++-
 .../rygel-http-transcode-handler.vala              |   91 -------------
 src/librygel-server/rygel-media-engine.vala        |    7 -
 src/librygel-server/rygel-media-file-item.vala     |   17 ---
 src/librygel-server/rygel-media-object.vala        |    1 -
 src/librygel-server/rygel-music-item.vala          |   17 ---
 src/librygel-server/rygel-samsung-tv-hacks.vala    |    1 -
 src/librygel-server/rygel-transcode-manager.vala   |  105 ---------------
 src/librygel-server/rygel-transcoder.vala          |  140 --------------------
 src/librygel-server/rygel-video-item.vala          |    1 -
 src/librygel-server/rygel-visual-item.vala         |    1 -
 .../gstreamer/rygel-aac-transcoder.vala            |    5 +-
 .../gstreamer/rygel-audio-transcoder.vala          |   43 +++---
 .../gstreamer/rygel-avc-transcoder.vala            |   24 +---
 .../gstreamer/rygel-gst-media-engine.vala          |   45 +++++--
 .../gstreamer/rygel-gst-transcoder.vala            |   64 ++++++++-
 .../gstreamer/rygel-l16-transcoder.vala            |   49 ++++----
 .../gstreamer/rygel-mp2ts-transcoder.vala          |   37 +++---
 .../gstreamer/rygel-mp3-transcoder.vala            |   10 +-
 .../gstreamer/rygel-video-transcoder.vala          |   46 ++++---
 .../gstreamer/rygel-wmv-transcoder.vala            |   10 +-
 .../simple/rygel-simple-media-engine.vala          |    4 -
 26 files changed, 226 insertions(+), 557 deletions(-)
---
diff --git a/src/librygel-server/filelist.am b/src/librygel-server/filelist.am
index 395f826..9d85d41 100644
--- a/src/librygel-server/filelist.am
+++ b/src/librygel-server/filelist.am
@@ -22,8 +22,6 @@ LIBRYGEL_SERVER_VAPI_SOURCE_FILES = \
        rygel-searchable-container.vala \
        rygel-trackable-container.vala \
        rygel-trackable-item.vala \
-       rygel-transcode-manager.vala \
-       rygel-transcoder.vala \
        rygel-visual-item.vala \
        rygel-writable-container.vala \
        rygel-media-server.vala \
@@ -52,7 +50,6 @@ LIBRYGEL_SERVER_NONVAPI_SOURCE_FILES = \
        rygel-http-response.vala \
        rygel-http-server.vala \
        rygel-http-time-seek.vala \
-       rygel-http-transcode-handler.vala \
        rygel-http-resource-handler.vala \
        rygel-import-resource.vala \
        rygel-object-creator.vala \
diff --git a/src/librygel-server/rygel-http-get.vala b/src/librygel-server/rygel-http-get.vala
index 60a2c74..a4bf8db 100644
--- a/src/librygel-server/rygel-http-get.vala
+++ b/src/librygel-server/rygel-http-get.vala
@@ -59,13 +59,6 @@ internal class Rygel.HTTPGet : HTTPRequest {
             throw new HTTPRequestError.BAD_REQUEST (_("Invalid Request"));
         }
 
-        if (uri.transcode_target != null) {
-            var transcoder = this.http_server.get_transcoder
-                                        (uri.transcode_target);
-            this.handler = new HTTPTranscodeHandler (transcoder,
-                                                     this.cancellable);
-        }
-
         if (uri.resource_name != null) {
             this.handler = new HTTPMediaResourceHandler (this.object,
                                                          uri.resource_name,
diff --git a/src/librygel-server/rygel-http-item-uri.vala b/src/librygel-server/rygel-http-item-uri.vala
index ae03c34..ec944a4 100644
--- a/src/librygel-server/rygel-http-item-uri.vala
+++ b/src/librygel-server/rygel-http-item-uri.vala
@@ -29,7 +29,6 @@ public class Rygel.HTTPItemURI : Object {
     public string item_id { get; set; }
     public int thumbnail_index { get; set; default = -1; }
     public int subtitle_index { get; set; default = -1; }
-    public string? transcode_target { get; set; default = null; }
     public string? resource_name { get; set; default = null; }
     public unowned HTTPServer http_server { get; set; }
 
@@ -52,12 +51,10 @@ public class Rygel.HTTPItemURI : Object {
                         HTTPServer http_server,
                         int        thumbnail_index = -1,
                         int        subtitle_index = -1,
-                        string?    transcode_target = null,
                         string?    resource_name = null) {
         this.item_id = object.id;
         this.thumbnail_index = thumbnail_index;
         this.subtitle_index = subtitle_index;
-        this.transcode_target = transcode_target;
         this.http_server = http_server;
         this.resource_name = resource_name;
         this.extension = "";
@@ -99,12 +96,6 @@ public class Rygel.HTTPItemURI : Object {
                     this.extension = subtitles[subtitle_index].caption_type;
                 }
             }
-        } else if (transcode_target != null) {
-            try {
-                var tc = this.http_server.get_transcoder (transcode_target);
-
-                this.extension = tc.extension;
-            } catch (Error error) {}
         }
 
         if (this.extension == "") {
@@ -151,7 +142,6 @@ public class Rygel.HTTPItemURI : Object {
         // do not decode the path here as it may contain encoded slashes
         this.thumbnail_index = -1;
         this.subtitle_index = -1;
-        this.transcode_target = null;
         this.http_server = http_server;
         this.extension = "";
 
@@ -181,10 +171,6 @@ public class Rygel.HTTPItemURI : Object {
                     this.item_id = builder.str;
 
                     break;
-                case "tr":
-                    this.transcode_target = Soup.URI.decode (parts[i + 1]);
-
-                    break;
                 case "th":
                     this.thumbnail_index = int.parse (parts[i + 1]);
 
@@ -216,10 +202,7 @@ public class Rygel.HTTPItemURI : Object {
         var escaped = Uri.escape_string (data, "", true);
         string path = "/i/" + escaped;
 
-        if (this.transcode_target != null) {
-            escaped = Uri.escape_string (this.transcode_target, "", true);
-            path += "/tr/" + escaped;
-        } else if (this.thumbnail_index >= 0) {
+        if (this.thumbnail_index >= 0) {
             path += "/th/" + this.thumbnail_index.to_string ();
         } else if (this.subtitle_index >= 0) {
             path += "/sub/" + this.subtitle_index.to_string ();
diff --git a/src/librygel-server/rygel-http-server.vala b/src/librygel-server/rygel-http-server.vala
index 7f60b0f..f72c4d8 100644
--- a/src/librygel-server/rygel-http-server.vala
+++ b/src/librygel-server/rygel-http-server.vala
@@ -28,7 +28,7 @@
 using GUPnP;
 using Gee;
 
-public class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
+public class Rygel.HTTPServer : GLib.Object, Rygel.StateMachine {
     public string path_root { get; private set; }
 
     // Reference to root container of associated ContentDirectory
@@ -90,35 +90,25 @@ public class Rygel.HTTPServer : Rygel.TranscodeManager, Rygel.StateMachine {
         this.completed ();
     }
 
-    internal override string create_uri_for_object (MediaObject object,
-                                                    int         thumbnail_index,
-                                                    int         subtitle_index,
-                                                    string?     transcode_target,
-                                                    string?     resource_name) {
+    internal string create_uri_for_object (MediaObject object,
+                                           int         thumbnail_index,
+                                           int         subtitle_index,
+                                           string?     resource_name) {
         var uri = new HTTPItemURI (object,
                                    this,
                                    thumbnail_index,
                                    subtitle_index,
-                                   transcode_target,
                                    resource_name);
 
         return uri.to_string ();
     }
 
-    internal override string get_protocol () {
+    internal virtual string get_protocol () {
         return "http-get";
     }
 
-    internal override ArrayList<ProtocolInfo> get_protocol_info () {
-        var protocol_infos = base.get_protocol_info ();
-
-        var protocol_info = new ProtocolInfo ();
-        protocol_info.protocol = this.get_protocol ();
-        protocol_info.mime_type = "*";
-
-        protocol_infos.add (protocol_info);
-
-        return protocol_infos;
+    internal virtual ArrayList<ProtocolInfo> get_protocol_info () {
+        return new ArrayList<ProtocolInfo>();
     }
 
     public bool is_local () {
diff --git a/src/librygel-server/rygel-http-time-seek.vala b/src/librygel-server/rygel-http-time-seek.vala
index 7967bf5..397d831 100644
--- a/src/librygel-server/rygel-http-time-seek.vala
+++ b/src/librygel-server/rygel-http-time-seek.vala
@@ -23,6 +23,8 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+using GUPnP;
+
 internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
     public HTTPTimeSeek (HTTPGet request) throws HTTPSeekError {
         string range;
@@ -89,6 +91,12 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
         this.seek_type = HTTPSeekType.TIME;
     }
 
+    private static bool is_transcoder (HTTPGetHandler handler) {
+        return (handler is HTTPMediaResourceHandler) &&
+            ((handler as HTTPMediaResourceHandler).media_resource.dlna_conversion ==
+                DLNAConversion.TRANSCODED);
+    }
+
     public static bool needed (HTTPGet request) {
         bool force_seek = false;
 
@@ -99,7 +107,7 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
 
         return force_seek || (request.object is AudioItem &&
                (request.object as AudioItem).duration > 0 &&
-               (request.handler is HTTPTranscodeHandler ||
+               (is_transcoder (request.handler) ||
                 (!(request.handler is HTTPThumbnailHandler) &&
                  !(request.handler is HTTPSubtitleHandler) &&
                  (request.object as MediaFileItem).is_live_stream ())));
diff --git a/src/librygel-server/rygel-media-engine.vala b/src/librygel-server/rygel-media-engine.vala
index 2314229..e152f26 100644
--- a/src/librygel-server/rygel-media-engine.vala
+++ b/src/librygel-server/rygel-media-engine.vala
@@ -121,13 +121,6 @@ public abstract class Rygel.MediaEngine : GLib.Object {
      */
     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.
-     */
-    public abstract unowned List<Transcoder>? get_transcoders ();
-
     public virtual DataSource? create_data_source_for_resource
                                         (MediaObject item,
                                          MediaResource resource)
diff --git a/src/librygel-server/rygel-media-file-item.vala b/src/librygel-server/rygel-media-file-item.vala
index ecf1d32..d0ab538 100644
--- a/src/librygel-server/rygel-media-file-item.vala
+++ b/src/librygel-server/rygel-media-file-item.vala
@@ -157,12 +157,6 @@ public abstract class Rygel.MediaFileItem : MediaItem {
 
     public abstract bool streamable ();
 
-    internal int compare_transcoders (Transcoder transcoder1,
-                                      Transcoder transcoder2) {
-        return (int) transcoder1.get_distance (this) -
-               (int) transcoder2.get_distance (this);
-    }
-
     internal override DIDLLiteResource add_resource
                                         (DIDLLiteObject didl_object,
                                          string?        uri,
@@ -213,8 +207,6 @@ public abstract class Rygel.MediaFileItem : 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);
 
@@ -311,15 +303,6 @@ public abstract class Rygel.MediaFileItem : MediaItem {
     }
 
 
-    internal virtual void add_proxy_resources (HTTPServer   server,
-                                               DIDLLiteItem didl_item)
-                                               throws Error {
-        if (!this.place_holder) {
-            // Transcoding resources
-            server.add_resources (didl_item, this);
-        }
-    }
-
     protected override ProtocolInfo get_protocol_info (string? uri,
                                                        string  protocol) {
         var protocol_info = base.get_protocol_info (uri, protocol);
diff --git a/src/librygel-server/rygel-media-object.vala b/src/librygel-server/rygel-media-object.vala
index a1d1e30..8dde001 100644
--- a/src/librygel-server/rygel-media-object.vala
+++ b/src/librygel-server/rygel-media-object.vala
@@ -257,7 +257,6 @@ public abstract class Rygel.MediaObject : GLib.Object {
                 var uri = http_server.create_uri_for_object (this,
                                                              -1,
                                                              -1,
-                                                             null,
                                                              res.get_name ());
                 if (this is MediaFileItem &&
                     (this as MediaFileItem).place_holder) {
diff --git a/src/librygel-server/rygel-music-item.vala b/src/librygel-server/rygel-music-item.vala
index 9c48f5d..2f9bcf3 100644
--- a/src/librygel-server/rygel-music-item.vala
+++ b/src/librygel-server/rygel-music-item.vala
@@ -121,21 +121,4 @@ public class Rygel.MusicItem : AudioItem {
 
         return didl_item;
     }
-
-    internal override void add_proxy_resources (HTTPServer   server,
-                                                DIDLLiteItem didl_item)
-                                                throws Error {
-        base.add_proxy_resources (server, didl_item);
-
-        // Album-art URI comes in the end
-        if (!this.place_holder &&
-            this.album_art != null &&
-            server.need_proxy (this.album_art.uri)) {
-            didl_item.album_art = server.create_uri_for_object (this,
-                                                                0,
-                                                                -1,
-                                                                null,
-                                                                null);
-        }
-    }
 }
diff --git a/src/librygel-server/rygel-samsung-tv-hacks.vala b/src/librygel-server/rygel-samsung-tv-hacks.vala
index 5a4c3df..7e16bc8 100644
--- a/src/librygel-server/rygel-samsung-tv-hacks.vala
+++ b/src/librygel-server/rygel-samsung-tv-hacks.vala
@@ -61,7 +61,6 @@ internal class Rygel.SamsungTVHacks : ClientHacks {
                                         (request.object as MediaItem,
                                          -1,
                                          0, // FIXME: offer first subtitle only?
-                                         null,
                                          null);
 
                 request.msg.response_headers.append ("CaptionInfo.sec",
diff --git a/src/librygel-server/rygel-video-item.vala b/src/librygel-server/rygel-video-item.vala
index ad625e5..f49df80 100644
--- a/src/librygel-server/rygel-video-item.vala
+++ b/src/librygel-server/rygel-video-item.vala
@@ -167,7 +167,6 @@ public class Rygel.VideoItem : AudioItem, VisualItem {
                     subtitle.uri = http_server.create_uri_for_object (this,
                                                                       -1,
                                                                       index,
-                                                                      null,
                                                                       null);
                     subtitle.add_didl_node (didl_item);
                     subtitle.uri = uri; // Now restore the original URI
diff --git a/src/librygel-server/rygel-visual-item.vala b/src/librygel-server/rygel-visual-item.vala
index 0c62376..d2fa2d2 100644
--- a/src/librygel-server/rygel-visual-item.vala
+++ b/src/librygel-server/rygel-visual-item.vala
@@ -104,7 +104,6 @@ public interface Rygel.VisualItem : MediaFileItem {
                                                  (this,
                                                   index,
                                                   -1,
-                                                  null,
                                                   null);
                     this.get_resource_list ().add (http_thumb_res);
                 }
diff --git a/src/media-engines/gstreamer/rygel-aac-transcoder.vala 
b/src/media-engines/gstreamer/rygel-aac-transcoder.vala
index bf5a36f..7a859b9 100644
--- a/src/media-engines/gstreamer/rygel-aac-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-aac-transcoder.vala
@@ -1,7 +1,9 @@
 /*
  * Copyright (C) 2011 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Luis de Bethencourt <luis debethencourt collabora com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -31,8 +33,9 @@ internal class Rygel.AACTranscoder : Rygel.AudioTranscoder {
     private const string CODEC = "audio/mpeg,mpegversion=4," +
                                  "stream-format=adts,rate=44100,base-profile=lc";
 
+    private const string NAME = "AAC_ADTS_320";
     public AACTranscoder () {
-        base ("audio/vnd.dlna.adts", "AAC_ADTS_320", BITRATE, null, CODEC, "adts");
+        base (NAME, "audio/vnd.dlna.adts", NAME, BITRATE, null, CODEC, "adts");
         this.preset = "Rygel AAC_ADTS_320 preset";
     }
 }
diff --git a/src/media-engines/gstreamer/rygel-audio-transcoder.vala 
b/src/media-engines/gstreamer/rygel-audio-transcoder.vala
index 8694f54..6aca760 100644
--- a/src/media-engines/gstreamer/rygel-audio-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-audio-transcoder.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2011 Nokia Corporation.
  * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Jens Georg <jensg openismus com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -20,6 +22,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using Gst.PbUtils;
 using GUPnP;
@@ -27,20 +30,21 @@ using GUPnP;
 /**
  * Base class for all transcoders that handle audio.
  */
-internal class Rygel.AudioTranscoder : Rygel.GstTranscoder {
+internal abstract class Rygel.AudioTranscoder : Rygel.GstTranscoder {
     protected int audio_bitrate;
     protected Caps container_format = null;
     protected Caps audio_codec_format = null;
 
     public const string NO_CONTAINER = null;
 
-    public AudioTranscoder (string  content_type,
+    public AudioTranscoder (string  name,
+                            string  content_type,
                             string  dlna_profile,
                             int     audio_bitrate,
                             string? container_caps,
                             string  audio_codec_caps,
                             string  extension) {
-        base (content_type, dlna_profile, extension);
+        base (name, content_type, dlna_profile, extension);
 
         this.audio_bitrate = audio_bitrate;
         if (container_caps != null) {
@@ -50,13 +54,14 @@ internal class Rygel.AudioTranscoder : Rygel.GstTranscoder {
         this.audio_codec_format = Caps.from_string (audio_codec_caps);
     }
 
-    public AudioTranscoder.with_class (string  content_type,
+    public AudioTranscoder.with_class (string  name,
+                                       string  content_type,
                                        string  dlna_profile,
                                        int     audio_bitrate,
                                        string? container_caps,
                                        string  audio_codec_caps,
                                        string  extension) {
-        base (content_type, dlna_profile, extension);
+        base (name, content_type, dlna_profile, extension);
 
         this.audio_bitrate = audio_bitrate;
         if (container_caps != null) {
@@ -66,22 +71,7 @@ internal class Rygel.AudioTranscoder : Rygel.GstTranscoder {
         this.audio_codec_format = Caps.from_string (audio_codec_caps);
     }
 
-
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaFileItem    item,
-                                                    TranscodeManager manager)
-                                                    throws Error {
-        var resource = base.add_resource (didl_item, item, manager);
-        if (resource == null) {
-            return null;
-        }
-
-        resource.bitrate = (this.audio_bitrate * 1000) / 8;
-
-        return resource;
-    }
-
-    public override uint get_distance (MediaItem item) {
+    public override uint get_distance (MediaFileItem item) {
         if (!(item is AudioItem) || item is VideoItem) {
             return uint.MAX;
         }
@@ -115,4 +105,15 @@ internal class Rygel.AudioTranscoder : Rygel.GstTranscoder {
 
         return enc_audio_profile;
     }
+
+    public override MediaResource? get_resource_for_item (MediaFileItem item) {
+        var resource = base.get_resource_for_item (item);
+        if (resource == null) {
+            return null;
+        }
+
+        resource.sample_freq = this.audio_bitrate;
+
+        return resource;
+    }
 }
diff --git a/src/media-engines/gstreamer/rygel-avc-transcoder.vala 
b/src/media-engines/gstreamer/rygel-avc-transcoder.vala
index 7d49d8e..e47882e 100644
--- a/src/media-engines/gstreamer/rygel-avc-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-avc-transcoder.vala
@@ -1,7 +1,9 @@
 /*
  * Copyright (C) 2011 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Luis de Bethencourt <luis debethencourt collabora com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -19,6 +21,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using GUPnP;
 
@@ -37,9 +40,11 @@ internal class Rygel.AVCTranscoder : Rygel.VideoTranscoder {
     private const string RESTRICTIONS =
         "video/x-raw,framerate=(fraction)15/1,width=352,height=288";
 
+    private const string NAME = "AVC_MP4_BL_CIF15_AAC_520";
     public AVCTranscoder () {
-        base ("video/mp4",
-              "AVC_MP4_BL_CIF15_AAC_520",
+        base (NAME,
+              "video/mp4",
+              NAME,
               AUDIO_BITRATE,
               VIDEO_BITRATE,
               CONTAINER,
@@ -49,19 +54,4 @@ internal class Rygel.AVCTranscoder : Rygel.VideoTranscoder {
               RESTRICTIONS);
         this.preset = "Rygel AVC_MP4_BL_CIF15_AAC_520 preset";
     }
-
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaFileItem    item,
-                                                    TranscodeManager manager)
-                                                    throws Error {
-        var resource = base.add_resource (didl_item, item, manager);
-        if (resource == null) {
-            return null;
-        }
-
-        resource.width = 352;
-        resource.height = 288;
-
-        return resource;
-    }
 }
diff --git a/src/media-engines/gstreamer/rygel-gst-media-engine.vala 
b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
index f2b4f81..f1ca163 100644
--- a/src/media-engines/gstreamer/rygel-gst-media-engine.vala
+++ b/src/media-engines/gstreamer/rygel-gst-media-engine.vala
@@ -1,7 +1,10 @@
 /*
  * Copyright (C) 2012 Intel Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Jens Georg <jensg openismus com>
+ *         Prasanna Modem <prasanna ecaspia com>
+ *         Craig Pratt <craig ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -33,7 +36,7 @@ extern bool gst_preset_set_app_dir (string app_dir);
 
 public class Rygel.GstMediaEngine : Rygel.MediaEngine {
     private GLib.List<DLNAProfile> dlna_profiles = null;
-    private GLib.List<Transcoder> transcoders = null;
+    private GLib.List<GstTranscoder> transcoders = null;
 
     public GstMediaEngine () {
         unowned string[] args = null;
@@ -113,10 +116,6 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
         return this.dlna_profiles;
     }
 
-    public override unowned GLib.List<Transcoder>? get_transcoders () {
-        return this.transcoders;
-    }
-
     public override DataSource? create_data_source (string uri) {
         try {
             return new GstDataSource (uri);
@@ -129,8 +128,7 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
         }
     }
 
-    public override async Gee.List<MediaResource>? get_resources_for_item (MediaObject
-            object) {
+    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;
@@ -164,6 +162,23 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
         http_res.uri = ""; // The URI needs to be assigned by the MediaServer
         resources.add (http_res);
 
+        var list = new GLib.List<GstTranscoder> ();
+        foreach (var transcoder in transcoders) {
+            if (transcoder.get_distance (item) != uint.MAX) {
+                list.append (transcoder);
+            }
+        }
+        list.sort_with_data( (transcoder_1, transcoder_2) => {
+                                 return (int) ( transcoder_1.get_distance (item)
+                                                - transcoder_2.get_distance (item) );
+                             } );
+
+        // Put all Transcoders in the list according to their sorted rank
+        foreach (var transcoder in list) {
+            MediaResource res = transcoder.get_resource_for_item (item);
+            if (res != null)
+                resources.add (res);
+        }
         // Put the primary resource as most-preferred (front of the list)
         resources.add (primary_res);
 
@@ -172,7 +187,7 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
 
     public override DataSource? create_data_source_for_resource
                                         (MediaObject object,
-                                         MediaResource res) throws Error {
+                                         MediaResource resource) throws Error {
         if (!(object is MediaFileItem)) {
             warning ("Can only process file-based MediaObjects (MediaFileItem)");
             return null;
@@ -180,11 +195,23 @@ public class Rygel.GstMediaEngine : Rygel.MediaEngine {
 
         var item = object as MediaFileItem;
 
+        // For MediaFileItems, the primary URI refers directly to the content
         string source_uri = item.get_primary_uri ();
         debug ("creating data source for %s", source_uri);
 
         DataSource ds = new GstDataSource (source_uri);
-
+        debug ("MediaResource %s, profile %s, mime_type %s", resource.get_name (),
+               resource.dlna_profile, resource.mime_type);
+        if (resource.dlna_conversion == DLNAConversion.TRANSCODED) {
+            foreach (var transcoder in transcoders) {
+                if (transcoder.name == resource.get_name()) {
+                    debug ("creating data source from transcoder %s (profile %s)",
+                            transcoder.name, transcoder.dlna_profile );
+                    ds = transcoder.create_source (item, ds);
+                    break;
+                }
+            }
+        }
         return ds;
     }
 
diff --git a/src/media-engines/gstreamer/rygel-gst-transcoder.vala 
b/src/media-engines/gstreamer/rygel-gst-transcoder.vala
index 649785e..dd0bc02 100644
--- a/src/media-engines/gstreamer/rygel-gst-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-gst-transcoder.vala
@@ -1,10 +1,12 @@
 /*
  * Copyright (C) 2009-2012 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>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -32,10 +34,16 @@ public errordomain Rygel.GstTranscoderError {
 }
 
 /**
- * The base Transcoder class. Each implementation derives from it and must
- * implement get_distance and get_encoding_profile methods.
+ * The base Transcoder class used by gstreamer media engine.
+ * Each implementation derives from it and must
+ * implement get_resources_for_item and get_encoding_profile methods.
  */
-internal abstract class Rygel.GstTranscoder : Rygel.Transcoder {
+public abstract class Rygel.GstTranscoder : GLib.Object {
+    public string name { get; construct; }
+    public string mime_type { get; construct; }
+    public string dlna_profile { get; construct; }
+    public string extension { get; construct; }
+
     public string preset { get;
                            protected set;
                            default =  DEFAULT_ENCODING_PRESET; }
@@ -49,10 +57,12 @@ internal abstract class Rygel.GstTranscoder : Rygel.Transcoder {
 
     private bool link_failed;
 
-    public GstTranscoder (string mime_type,
+    public GstTranscoder (string name,
+                          string mime_type,
                           string dlna_profile,
                           string extension) {
-        GLib.Object (mime_type : mime_type,
+        GLib.Object (name : name,
+                     mime_type : mime_type,
                      dlna_profile : dlna_profile,
                      extension : extension);
     }
@@ -64,6 +74,47 @@ internal abstract class Rygel.GstTranscoder : Rygel.Transcoder {
     }
 
     /**
+     * Get the supported (transcoded) MediaResource for the given content item
+     *
+     * @return A MediaResources or null if the transcoder cannot
+     * transcode this media item
+     */
+    public virtual MediaResource? get_resource_for_item (MediaFileItem item) {
+        MediaResource res = new MediaResource(this.name);
+
+        res.mime_type = this.mime_type;
+        res.dlna_profile = this.dlna_profile;
+        res.extension = this.extension;
+        res.dlna_conversion = DLNAConversion.TRANSCODED;
+        res.dlna_flags = DLNAFlags.DLNA_V15
+                         | DLNAFlags.STREAMING_TRANSFER_MODE
+                         | DLNAFlags.BACKGROUND_TRANSFER_MODE
+                         | DLNAFlags.CONNECTION_STALL;
+        // For transcoded content only support time seek
+        res.dlna_operation = DLNAOperation.TIMESEEK;
+
+        // Retrieve the duration from primary media resource
+        if (item is AudioItem) {
+            res.duration = (item as AudioItem).duration;
+        }
+
+        return res;
+    }
+
+    /**
+     * Gets a numeric value that gives an gives an estimate of how hard
+     * it would be for this transcoder to trancode @item to the target profile of
+     * this transcoder.
+     *
+     * @param item the media item to calculate the distance for
+     *
+     * @return      the distance from the @item, uint.MIN if providing such a
+     *              value is impossible or uint.MAX if it doesn't make any
+     *              sense to use this transcoder for @item
+     */
+    public abstract uint get_distance (MediaFileItem item);
+
+    /**
      * Creates a transcoding source.
      *
      * @param src the media item to create the transcoding source for
@@ -71,8 +122,7 @@ internal abstract class Rygel.GstTranscoder : Rygel.Transcoder {
      *
      * @return      the new transcoding source
      */
-    public override DataSource create_source (MediaItem  item,
-                                              DataSource src) throws Error {
+    public DataSource create_source (MediaFileItem item, DataSource src) throws Error {
         // We can only link GStreamer data sources together
         assert (src is GstDataSource);
 
diff --git a/src/media-engines/gstreamer/rygel-l16-transcoder.vala 
b/src/media-engines/gstreamer/rygel-l16-transcoder.vala
index a9e0044..063d749 100644
--- a/src/media-engines/gstreamer/rygel-l16-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-l16-transcoder.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *                               <zeeshan ali nokia com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -20,6 +22,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using GUPnP;
 using Gee;
@@ -34,7 +37,7 @@ internal class Rygel.L16Transcoder : Rygel.AudioTranscoder {
     private const int DEPTH = 16;
     private const bool SIGNED = true;
     private const int ENDIANNESS = ByteOrder.BIG_ENDIAN;
-
+    private const string NAME = "LPCM";
     public L16Transcoder () {
         var mime_type = "audio/L" + L16Transcoder.WIDTH.to_string () +
                         ";rate=" + L16Transcoder.FREQUENCY.to_string () +
@@ -44,35 +47,16 @@ internal class Rygel.L16Transcoder : Rygel.AudioTranscoder {
                        ",channels=" + CHANNELS.to_string () +
                        ",rate=" +  FREQUENCY.to_string ();
 
-        base (mime_type,
-              "LPCM",
+        base (NAME,
+              mime_type,
+              NAME,
               0,
               AudioTranscoder.NO_CONTAINER,
               caps_str,
               "lpcm");
     }
 
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaFileItem    item,
-                                                    TranscodeManager manager)
-                                                    throws Error {
-        var resource = base.add_resource (didl_item, item, manager);
-        if (resource == null) {
-            return null;
-        }
-
-        resource.sample_freq = L16Transcoder.FREQUENCY;
-        resource.audio_channels = L16Transcoder.CHANNELS;
-        resource.bits_per_sample = L16Transcoder.WIDTH;
-        // Set bitrate in bytes/second
-        resource.bitrate = L16Transcoder.FREQUENCY *
-                           L16Transcoder.CHANNELS *
-                           L16Transcoder.WIDTH / 8;
-
-        return resource;
-    }
-
-    public override uint get_distance (MediaItem item) {
+    public override uint get_distance (MediaFileItem item) {
         if (!(item is AudioItem) || item is VideoItem) {
             return uint.MAX;
         }
@@ -94,4 +78,21 @@ internal class Rygel.L16Transcoder : Rygel.AudioTranscoder {
 
         return distance;
     }
+
+    public override MediaResource? get_resource_for_item (MediaFileItem item) {
+        var resource = base.get_resource_for_item (item);
+        if (resource == null) {
+            return null;
+        }
+
+        resource.sample_freq = L16Transcoder.FREQUENCY;
+        resource.audio_channels = L16Transcoder.CHANNELS;
+        resource.bits_per_sample = L16Transcoder.WIDTH;
+        // Set bitrate in bytes/second
+        resource.bitrate = L16Transcoder.FREQUENCY *
+                           L16Transcoder.CHANNELS *
+                           L16Transcoder.WIDTH / 8;
+
+        return resource;
+    }
 }
diff --git a/src/media-engines/gstreamer/rygel-mp2ts-transcoder.vala 
b/src/media-engines/gstreamer/rygel-mp2ts-transcoder.vala
index 04334b3..763a329 100644
--- a/src/media-engines/gstreamer/rygel-mp2ts-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-mp2ts-transcoder.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *                               <zeeshan ali nokia com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -20,6 +22,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using GUPnP;
 
@@ -59,7 +62,8 @@ internal class Rygel.MP2TSTranscoder : Rygel.VideoTranscoder {
     private MP2TSProfile profile;
 
     public MP2TSTranscoder (MP2TSProfile profile) {
-        base ("video/mpeg",
+        base (PROFILES[profile],
+              "video/mpeg",
               PROFILES[profile],
               AUDIO_BITRATE,
               VIDEO_BITRATE,
@@ -74,23 +78,7 @@ internal class Rygel.MP2TSTranscoder : Rygel.VideoTranscoder {
         this.profile = profile;
     }
 
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaFileItem    item,
-                                                    TranscodeManager manager)
-                                                    throws Error {
-        var resource = base.add_resource (didl_item, item, manager);
-        if (resource == null) {
-            return null;
-        }
-
-        resource.width = WIDTH[this.profile];
-        resource.height = HEIGHT[this.profile];
-        resource.bitrate = (VIDEO_BITRATE + AUDIO_BITRATE) * 1000 / 8;
-
-        return resource;
-    }
-
-    public override uint get_distance (MediaItem item) {
+    public override uint get_distance (MediaFileItem item) {
         if (!(item is VideoItem)) {
             return uint.MAX;
         }
@@ -112,4 +100,17 @@ internal class Rygel.MP2TSTranscoder : Rygel.VideoTranscoder {
 
         return distance;
     }
+
+    public override MediaResource? get_resource_for_item (MediaFileItem item) {
+        var resource = base.get_resource_for_item(item);
+        if (resource == null) {
+            return null;
+        }
+
+        resource.width = WIDTH[this.profile];
+        resource.height = HEIGHT[this.profile];
+        resource.bitrate = (VIDEO_BITRATE + AUDIO_BITRATE) * 1000 / 8;
+
+        return resource;
+    }
 }
diff --git a/src/media-engines/gstreamer/rygel-mp3-transcoder.vala 
b/src/media-engines/gstreamer/rygel-mp3-transcoder.vala
index ecbdd45..d2a327d 100644
--- a/src/media-engines/gstreamer/rygel-mp3-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-mp3-transcoder.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *                               <zeeshan ali nokia com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -20,6 +22,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using GUPnP;
 using Gee;
@@ -30,10 +33,11 @@ using Gee;
 internal class Rygel.MP3Transcoder : Rygel.AudioTranscoder {
     public const int BITRATE = 128;
     private const string FORMAT = "audio/mpeg,mpegversion=1,layer=3";
-
+    private const string NAME = "MP3";
     public MP3Transcoder () {
-        base ("audio/mpeg",
-              "MP3",
+        base (NAME,
+              "audio/mpeg",
+              NAME,
               BITRATE,
               AudioTranscoder.NO_CONTAINER,
               FORMAT,
diff --git a/src/media-engines/gstreamer/rygel-video-transcoder.vala 
b/src/media-engines/gstreamer/rygel-video-transcoder.vala
index 4cd3c68..309c546 100644
--- a/src/media-engines/gstreamer/rygel-video-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-video-transcoder.vala
@@ -1,7 +1,9 @@
 /*
  * Copyright (C) 2011 Nokia Corporation.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Jens Georg <jensg openismus com>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -19,6 +21,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using Gst.PbUtils;
 using GUPnP;
@@ -26,12 +29,13 @@ using GUPnP;
 /**
  * Base class for all transcoders that handle video.
  */
-internal class Rygel.VideoTranscoder : Rygel.AudioTranscoder {
+internal abstract class Rygel.VideoTranscoder : Rygel.AudioTranscoder {
     private int video_bitrate;
     private Caps video_codec_format;
     private Caps video_restrictions = null;
 
-    public VideoTranscoder (string  content_type,
+    public VideoTranscoder (string  name,
+                            string  content_type,
                             string  dlna_profile,
                             int     audio_bitrate,
                             int     video_bitrate,
@@ -41,7 +45,8 @@ internal class Rygel.VideoTranscoder : Rygel.AudioTranscoder {
                             string  extension,
                             string? restrictions = null) {
 
-        base.with_class (content_type,
+        base.with_class (name,
+                         content_type,
                          dlna_profile,
                          audio_bitrate,
                          container_caps,
@@ -56,25 +61,7 @@ internal class Rygel.VideoTranscoder : Rygel.AudioTranscoder {
         }
     }
 
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaFileItem        item,
-                                                    TranscodeManager manager)
-                                                    throws Error {
-        var resource = base.add_resource (didl_item, item, manager);
-        if (resource == null) {
-            return null;
-        }
-
-        var video_item = item as VideoItem;
-
-        resource.width = video_item.width;
-        resource.height = video_item.height;
-        resource.bitrate = (this.video_bitrate + this.audio_bitrate) * 1000 / 8;
-
-        return resource;
-    }
-
-    public override uint get_distance (MediaItem item) {
+    public override uint get_distance (MediaFileItem item) {
         if (!(item is VideoItem)) {
             return uint.MAX;
         }
@@ -104,4 +91,19 @@ internal class Rygel.VideoTranscoder : Rygel.AudioTranscoder {
 
         return enc_container_profile;
     }
+
+    public override MediaResource? get_resource_for_item (MediaFileItem item) {
+        var resource = base.get_resource_for_item (item);
+        if (resource == null) {
+            return null;
+        }
+
+        var video_item = item as VideoItem;
+
+        resource.width = video_item.width;
+        resource.height = video_item.height;
+        resource.bitrate = (this.video_bitrate + this.audio_bitrate) * 1000 / 8;
+
+        return resource;
+    }
 }
diff --git a/src/media-engines/gstreamer/rygel-wmv-transcoder.vala 
b/src/media-engines/gstreamer/rygel-wmv-transcoder.vala
index 947ee04..0b3519b 100644
--- a/src/media-engines/gstreamer/rygel-wmv-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-wmv-transcoder.vala
@@ -1,7 +1,9 @@
 /*
  * Copyright (C) 2009 Jens Georg <mail jensge org>.
+ * Copyright (C) 2013 Cable Television Laboratories, Inc.
  *
  * Author: Jens Georg <mail jensge org>
+ *         Prasanna Modem <prasanna ecaspia com>
  *
  * This file is part of Rygel.
  *
@@ -19,16 +21,18 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
+
 using Gst;
 using GUPnP;
 
 internal class Rygel.WMVTranscoder : Rygel.VideoTranscoder {
     private const int VIDEO_BITRATE = 1200;
     private const int AUDIO_BITRATE = 64;
-
+    private const string NAME = "WMVHIGH_FULL";
     public WMVTranscoder () {
-        base ("video/x-ms-wmv",
-              "WMVHIGH_FULL",
+        base (NAME,
+              "video/x-ms-wmv",
+              NAME,
               AUDIO_BITRATE,
               VIDEO_BITRATE,
               "video/x-ms-asf,parsed=true",
diff --git a/src/media-engines/simple/rygel-simple-media-engine.vala 
b/src/media-engines/simple/rygel-simple-media-engine.vala
index 42253c6..4580432 100644
--- a/src/media-engines/simple/rygel-simple-media-engine.vala
+++ b/src/media-engines/simple/rygel-simple-media-engine.vala
@@ -38,10 +38,6 @@ internal class Rygel.SimpleMediaEngine : MediaEngine {
         return this.profiles;
     }
 
-    public override unowned List<Transcoder>? get_transcoders () {
-        return null;
-    }
-
     public override async Gee.List<MediaResource>? get_resources_for_item (MediaObject
             object) {
         if (! (object is MediaFileItem)) {



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