[rygel] core: Refactor video transcoders



commit 195f309c915c376aba13b191c1dd989c14279bf9
Author: Jens Georg <mail jensge org>
Date:   Fri Jul 22 14:12:18 2011 +0200

    core: Refactor video transcoders
    
    https://bugzilla.gnome.org/show_bug.cgi?id=661891

 src/rygel/Makefile.am                 |    1 +
 src/rygel/rygel-avc-transcoder.vala   |   88 ++++++----------------------
 src/rygel/rygel-mp2ts-transcoder.vala |   80 +++++++++----------------
 src/rygel/rygel-video-transcoder.vala |  104 +++++++++++++++++++++++++++++++++
 src/rygel/rygel-wmv-transcoder.vala   |   69 +++-------------------
 5 files changed, 161 insertions(+), 181 deletions(-)
---
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 05872f7..2518aa3 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -96,6 +96,7 @@ VAPI_SOURCE_FILES = \
 	rygel-search-criteria-parser.vala \
 	rygel-transcoder.vala \
 	rygel-audio-transcoder.vala \
+	rygel-video-transcoder.vala \
 	rygel-mp2ts-transcoder.vala \
 	rygel-mp3-transcoder.vala \
 	rygel-l16-transcoder.vala \
diff --git a/src/rygel/rygel-avc-transcoder.vala b/src/rygel/rygel-avc-transcoder.vala
index 0211a90..17a325f 100644
--- a/src/rygel/rygel-avc-transcoder.vala
+++ b/src/rygel/rygel-avc-transcoder.vala
@@ -22,79 +22,29 @@
 using Gst;
 using GUPnP;
 
-internal class Rygel.AVCTranscoder : Rygel.Transcoder {
-    private const int BITRATE = 1200000;
+/**
+ * Transcoder for H.264 in MP4 conforming to DLNA profile
+ * AVC_MP4_BL_CIF15_AAC_520 (15 fps, CIF resolution)
+ */
+internal class Rygel.AVCTranscoder : Rygel.VideoTranscoder {
     private const int VIDEO_BITRATE = 1200;
     private const int AUDIO_BITRATE = 64;
+    private const string CONTAINER = "video/quicktime,variant=iso";
+    private const string AUDIO_CAPS = "audio/mpeg,mpegversion=4";
+    private const string VIDEO_CAPS =
+        "video/x-h264,stream-format=avc,framerate=(fraction)15/1";
 
-    private const string RESTRICTIONS = "framerate=(fraction)15/1," +
-                                        "width=352,height=288";
+    private const string RESTRICTIONS =
+        "framerate=(fraction)15/1,width=352,height=288";
 
     public AVCTranscoder () {
-        base ("video/mp4", "AVC_MP4_BL_CIF15_AAC_520", VideoItem.UPNP_CLASS);
-    }
-
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaItem        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 = (VIDEO_BITRATE + AUDIO_BITRATE) * 1000 / 8;
-
-        return resource;
-    }
-
-    public override uint get_distance (MediaItem item) {
-        if (!(item is VideoItem)) {
-            return uint.MAX;
-        }
-
-        var video_item = item as VideoItem;
-        var distance = uint.MIN;
-
-        if (video_item.bitrate > 0) {
-            distance += (video_item.bitrate - BITRATE).abs ();
-        }
-
-        return distance;
-    }
-
-    protected override EncodingProfile get_encoding_profile () {
-        var container_format = Caps.from_string ("video/quicktime,variant=iso");
-
-        var video_format = Caps.from_string ("video/x-h264," +
-                                             "stream-format=avc," +
-                                             "framerate=(fraction)15/1");
-        var audio_format = Caps.from_string ("audio/mpeg,mpegversion=4");
-
-        var enc_container_profile = new EncodingContainerProfile("container",
-                                                                 null,
-                                                                 container_format,
-                                                                 null);
-
-        var video_restriction = Caps.from_string (RESTRICTIONS);
-
-        var enc_video_profile = new EncodingVideoProfile (video_format,
-                                                          null,
-                                                          video_restriction,
-                                                          1);
-        var enc_audio_profile = new EncodingAudioProfile (audio_format,
-                                                          null,
-                                                          null,
-                                                          1);
-
-        // FIXME: We should use the preset to set bitrate
-        enc_container_profile.add_profile (enc_video_profile);
-        enc_container_profile.add_profile (enc_audio_profile);
-
-        return enc_container_profile;
+        base ("video/mp4",
+              "AVC_MP4_BL_CIF15_AAC_520",
+              AUDIO_BITRATE,
+              VIDEO_BITRATE,
+              CONTAINER,
+              AUDIO_CAPS,
+              VIDEO_CAPS,
+              RESTRICTIONS);
     }
 }
diff --git a/src/rygel/rygel-mp2ts-transcoder.vala b/src/rygel/rygel-mp2ts-transcoder.vala
index 93bc793..677f651 100644
--- a/src/rygel/rygel-mp2ts-transcoder.vala
+++ b/src/rygel/rygel-mp2ts-transcoder.vala
@@ -22,7 +22,6 @@
  */
 using Gst;
 using GUPnP;
-using Gee;
 
 internal enum Rygel.MP2TSProfile {
     SD = 0,
@@ -32,7 +31,7 @@ internal enum Rygel.MP2TSProfile {
 /**
  * Transcoder for mpeg transport stream containing mpeg 2 video and mp2 audio.
  */
-internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
+internal class Rygel.MP2TSTranscoder : Rygel.VideoTranscoder {
     private const int VIDEO_BITRATE = 3000;
     private const int AUDIO_BITRATE = 256;
 
@@ -41,12 +40,32 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
     private const int[] HEIGHT = {576, 720};
     private const int[] FRAME_RATE = {25, 30};
     private const string[] PROFILES = {"MPEG_TS_SD_EU_ISO", "MPEG_TS_HD_NA_ISO"};
-    private const int BITRATE = 3000000;
+
+    private const string CONTAINER =
+        "video/mpegts,systemstream=true,paketsize=188";
+
+    private const string AUDIO_FORMAT =
+        "audio/mpeg,mpegversion=1,layer=2";
+
+    private const string BASE_VIDEO_FORMAT =
+        "video/mpeg,mpegversion=2,systemstream=false,framerate=(fraction)%d/1";
+
+    private const string RESTRICTION_TEMPLATE =
+        "video/x-raw-yuv,framerate=(fraction)%d/1,width=%d,height=%d";
 
     private MP2TSProfile profile;
 
     public MP2TSTranscoder (MP2TSProfile profile) {
-        base ("video/mpeg", PROFILES[profile], VideoItem.UPNP_CLASS);
+        base ("video/mpeg",
+              PROFILES[profile],
+              AUDIO_BITRATE,
+              VIDEO_BITRATE,
+              CONTAINER,
+              AUDIO_FORMAT,
+              BASE_VIDEO_FORMAT.printf (FRAME_RATE[profile]),
+              RESTRICTION_TEMPLATE.printf (FRAME_RATE[profile],
+                                           WIDTH[profile],
+                                           HEIGHT[profile]));
 
         this.profile = profile;
     }
@@ -56,11 +75,12 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
                                                     TranscodeManager manager)
                                                     throws Error {
         var resource = base.add_resource (didl_item, item, manager);
-        if (resource == null)
+        if (resource == null) {
             return null;
+        }
 
-        resource.width = WIDTH[profile];
-        resource.height = HEIGHT[profile];
+        resource.width = WIDTH[this.profile];
+        resource.height = HEIGHT[this.profile];
         resource.bitrate = (VIDEO_BITRATE + AUDIO_BITRATE) * 1000 / 8;
 
         return resource;
@@ -72,10 +92,10 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
         }
 
         var video_item = item as VideoItem;
-        var distance = uint.MIN;
+        var distance = base.get_distance (item);
 
         if (video_item.bitrate > 0) {
-            distance += (video_item.bitrate - BITRATE).abs ();
+            distance += (video_item.bitrate - VIDEO_BITRATE).abs ();
         }
 
         if (video_item.width > 0) {
@@ -88,46 +108,4 @@ internal class Rygel.MP2TSTranscoder : Rygel.Transcoder {
 
         return distance;
     }
-
-    protected override EncodingProfile get_encoding_profile () {
-        var cont_format = Caps.from_string ("video/mpegts," +
-                                            "systemstream=true," +
-                                            "packetsize=188");
-        var framerate = "framerate=(fraction)%d/1".printf
-                                        (FRAME_RATE[this.profile]);
-
-        var video_format = Caps.from_string ("video/mpeg," +
-                                             "mpegversion=2," +
-                                             "systemstream=false," +
-                                             framerate);
-        var restriction = "video/x-raw-yuv," +
-                          framerate + "," +
-                          "width=%d,".printf (WIDTH[this.profile]) +
-                          "height=%d".printf (HEIGHT[this.profile]);
-
-        var video_restriction = Caps.from_string (restriction);
-
-        var audio_format = Caps.from_string ("audio/mpeg," +
-                                             "mpegversion=1," +
-                                             "layer=2");
-
-        var enc_container_profile = new EncodingContainerProfile ("container",
-                                                                  null,
-                                                                  cont_format,
-                                                                  null);
-        var enc_video_profile = new EncodingVideoProfile (video_format,
-                                                          null,
-                                                          video_restriction,
-                                                          1);
-        var enc_audio_profile = new EncodingAudioProfile (audio_format,
-                                                          null,
-                                                          null,
-                                                          1);
-
-        // FIXME: We should use the preset to set bitrate
-        enc_container_profile.add_profile (enc_video_profile);
-        enc_container_profile.add_profile (enc_audio_profile);
-
-        return enc_container_profile;
-    }
 }
diff --git a/src/rygel/rygel-video-transcoder.vala b/src/rygel/rygel-video-transcoder.vala
new file mode 100644
index 0000000..0b33bab
--- /dev/null
+++ b/src/rygel/rygel-video-transcoder.vala
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 Nokia Corporation.
+ *
+ * Author: Jens Georg <jensg openismus 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 Gst;
+using GUPnP;
+
+/**
+ * Base class for all transcoders that handle video.
+ */
+internal class Rygel.VideoTranscoder : Rygel.AudioTranscoder {
+    private int video_bitrate;
+    private Caps video_codec_format;
+    private Caps video_restrictions = null;
+
+    public VideoTranscoder (string  content_type,
+                            string  dlna_profile,
+                            int     audio_bitrate,
+                            int     video_bitrate,
+                            string  container_caps,
+                            string  audio_codec_caps,
+                            string  video_codec_caps,
+                            string? restrictions = null) {
+
+        base.with_class (content_type,
+                         dlna_profile,
+                         VideoItem.UPNP_CLASS,
+                         audio_bitrate,
+                         container_caps,
+                         audio_codec_caps);
+
+        this.video_bitrate = video_bitrate;
+        this.video_codec_format = Caps.from_string (video_codec_caps);
+
+        if (restrictions != null) {
+            this.video_restrictions = Caps.from_string (restrictions);
+        }
+    }
+
+    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
+                                                    MediaItem        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) {
+        if (!(item is VideoItem)) {
+            return uint.MAX;
+        }
+
+        var video_item = item as VideoItem;
+        var distance = uint.MIN;
+
+        if (video_item.bitrate > 0) {
+            distance += (video_item.bitrate - this.video_bitrate).abs ();
+        }
+
+        return distance;
+    }
+
+    protected override EncodingProfile get_encoding_profile () {
+        var enc_container_profile = base.get_encoding_profile () as
+                                        EncodingContainerProfile;
+
+        var enc_video_profile = new EncodingVideoProfile
+                                        (this.video_codec_format,
+                                         null,
+                                         this.video_restrictions,
+                                         1);
+
+        enc_container_profile.add_profile (enc_video_profile);
+
+        return enc_container_profile;
+    }
+}
diff --git a/src/rygel/rygel-wmv-transcoder.vala b/src/rygel/rygel-wmv-transcoder.vala
index 9f93a99..a601ddc 100644
--- a/src/rygel/rygel-wmv-transcoder.vala
+++ b/src/rygel/rygel-wmv-transcoder.vala
@@ -22,70 +22,17 @@
 using Gst;
 using GUPnP;
 
-internal class Rygel.WMVTranscoder : Rygel.Transcoder {
-    private const int BITRATE = 1200000;
+internal class Rygel.WMVTranscoder : Rygel.VideoTranscoder {
     private const int VIDEO_BITRATE = 1200;
     private const int AUDIO_BITRATE = 64;
 
     public WMVTranscoder () {
-        base ("video/x-ms-wmv", "WMVHIGH_FULL", VideoItem.UPNP_CLASS);
-    }
-
-    public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
-                                                    MediaItem        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 = (VIDEO_BITRATE + AUDIO_BITRATE) * 1000 / 8;
-
-        return resource;
-    }
-
-    public override uint get_distance (MediaItem item) {
-        if (!(item is VideoItem)) {
-            return uint.MAX;
-        }
-
-        var video_item = item as VideoItem;
-        var distance = uint.MIN;
-
-        if (video_item.bitrate > 0) {
-            distance += (video_item.bitrate - BITRATE).abs ();
-        }
-
-        return distance;
-    }
-
-    protected override EncodingProfile get_encoding_profile () {
-        var container_format = Caps.from_string ("video/x-ms-asf,parsed=true");
-
-        var video_format = Caps.from_string ("video/x-wmv,wmvversion=1");
-        var audio_format = Caps.from_string ("audio/x-wma,channels=2,wmaversion=1");
-
-        var enc_container_profile = new EncodingContainerProfile("container",
-                                                                 null,
-                                                                 container_format,
-                                                                 null);
-        var enc_video_profile = new EncodingVideoProfile (video_format,
-                                                          null,
-                                                          null,
-                                                          1);
-        var enc_audio_profile = new EncodingAudioProfile (audio_format,
-                                                          null,
-                                                          null,
-                                                          1);
-
-        // FIXME: We should use the preset to set bitrate
-        enc_container_profile.add_profile (enc_video_profile);
-        enc_container_profile.add_profile (enc_audio_profile);
-
-        return enc_container_profile;
+        base ("video/x-ms-wmv",
+              "WMVHIGH_FULL",
+              AUDIO_BITRATE,
+              VIDEO_BITRATE,
+              "video/x-ms-asf,parsed=true",
+              "audio/x-wma,channels=2,wmaversion=1",
+              "video/x-wmv,wmvversion=1");
     }
 }



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