core: encodebin-based MP3 transcoder
authorLuis de Bethencourt <luis@debethencourt.com>
Mon, 14 Mar 2011 17:02:42 +0000 (18:02 +0100)
committerZeeshan Ali (Khattak) <zeeshanak@gnome.org>
Sun, 10 Apr 2011 15:20:08 +0000 (18:20 +0300)
Co-author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>

po/POTFILES.in
po/POTFILES.skip
src/rygel/Makefile.am
src/rygel/rygel-mp3-transcoder-bin.vala [deleted file]
src/rygel/rygel-mp3-transcoder.vala
src/rygel/rygel-transcode-manager.vala

index 75ee862..99a4487 100644 (file)
@@ -115,7 +115,6 @@ src/rygel/rygel-media-object.vala
 src/rygel/rygel-media-receiver-registrar.vala
 src/rygel/rygel-meta-config.vala
 src/rygel/rygel-mp2ts-transcoder.vala
-src/rygel/rygel-mp3-transcoder-bin.vala
 src/rygel/rygel-mp3-transcoder.vala
 src/rygel/rygel-plugin-loader.vala
 src/rygel/rygel-plugin.vala
index b781977..0aad253 100644 (file)
@@ -72,7 +72,6 @@ src/rygel/rygel-video-item.c
 src/rygel/rygel-visual-item.c
 src/rygel/rygel-meta-config.c
 src/rygel/rygel-metadata-extractor.c
-src/rygel/rygel-mp3-transcoder-bin.c
 src/rygel/rygel-plugin-loader.c
 src/rygel/rygel-root-device-factory.c
 src/rygel/rygel-search.c
index c0fb6b7..0b11356 100644 (file)
@@ -95,7 +95,6 @@ VAPI_SOURCE_FILES = \
        rygel-mp2ts-transcoder.vala \
        rygel-mp3-transcoder.vala \
        rygel-l16-transcoder.vala \
-       rygel-mp3-transcoder-bin.vala \
        rygel-l16-transcoder-bin.vala \
        rygel-wma-transcoder.vala \
        rygel-wma-transcoder-bin.vala \
diff --git a/src/rygel/rygel-mp3-transcoder-bin.vala b/src/rygel/rygel-mp3-transcoder-bin.vala
deleted file mode 100644 (file)
index f3d5401..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2009 Nokia Corporation.
- *
- * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
- *                               <zeeshan.ali@nokia.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;
-
-internal enum Rygel.MP3Layer {
-    TWO = 1,
-    THREE = 2
-}
-
-/**
- * A Gst.Bin derivative that implements transcoding of any type of media (using
- * decodebin2) to mpeg 1 layer 2 and 3 format.
- */
-internal class Rygel.MP3TranscoderBin : Gst.Bin {
-    private const string DECODEBIN = "decodebin2";
-
-    private const string AUDIO_SRC_PAD = "audio-src-pad";
-    private const string AUDIO_SINK_PAD = "audio-sink-pad";
-
-    private dynamic Element audio_enc;
-
-    public MP3TranscoderBin (MediaItem     item,
-                             Element       src,
-                             MP3Transcoder transcoder) throws Error {
-        Element decodebin = GstUtils.create_element (DECODEBIN, DECODEBIN);
-
-        this.audio_enc = transcoder.create_encoder (item,
-                                                    AUDIO_SRC_PAD,
-                                                    AUDIO_SINK_PAD);
-
-        this.add_many (src, decodebin, this.audio_enc);
-        src.link (decodebin);
-
-        var src_pad = this.audio_enc.get_static_pad (AUDIO_SRC_PAD);
-        var ghost = new GhostPad (null, src_pad);
-        this.add_pad (ghost);
-
-        decodebin.pad_added.connect (this.decodebin_pad_added);
-    }
-
-    private void decodebin_pad_added (Element decodebin, Pad new_pad) {
-        Pad enc_pad = this.audio_enc.get_pad (AUDIO_SINK_PAD);
-        if (!new_pad.can_link (enc_pad)) {
-            return;
-        }
-
-        if (new_pad.link (enc_pad) != PadLinkReturn.OK) {
-            var error = new GstError.LINK (_("Failed to link pad %s to %s"),
-                                           new_pad.name,
-                                           enc_pad.name);
-            GstUtils.post_error (this, error);
-
-            return;
-        }
-    }
-}
index 96ace8c..39490f4 100644 (file)
@@ -25,29 +25,40 @@ using GUPnP;
 using Gee;
 
 /**
- * Transcoder for mpeg 1 layer 2 and 3 audio. This element uses MP3TrancoderBin
- * for actual transcoding.
+ * Transcoder for mpeg 1 layer 3 audio.
  */
 internal class Rygel.MP3Transcoder : Rygel.Transcoder {
     public const int BITRATE = 256;
 
-    private const string[] AUDIO_ENCODER = {null, "twolame", "lame"};
-    private const string AUDIO_PARSER = "mp3parse";
+    private const string DECODE_BIN = "decodebin2";
+    private const string ENCODE_BIN = "encodebin";
 
-    private const string CONVERT_SINK_PAD = "convert-sink-pad";
-
-    private MP3Layer layer;
-
-    public MP3Transcoder (MP3Layer layer) {
+    public MP3Transcoder () {
         base ("audio/mpeg", "MP3", AudioItem.UPNP_CLASS);
-
-        this.layer = layer;
     }
 
     public override Element create_source (MediaItem item,
                                            Element   src)
                                            throws Error {
-        return new MP3TranscoderBin (item, src, this);
+        dynamic Element decoder = GstUtils.create_element (DECODE_BIN,
+                                                           DECODE_BIN);
+        dynamic Element encoder = GstUtils.create_element (ENCODE_BIN,
+                                                           ENCODE_BIN);
+
+        encoder.profile = this.get_encoding_profile ();
+
+        var bin = new Bin ("mp3-transcoder-bin");
+        bin.add_many (src, decoder, encoder);
+
+        src.link (decoder);
+
+        decoder.pad_added.connect (this.on_decoder_pad_added);
+
+        var pad = encoder.get_static_pad ("src");
+        var ghost = new GhostPad (null, pad);
+        bin.add_pad (ghost);
+
+        return bin;
     }
 
     public override DIDLLiteResource? add_resource (DIDLLiteItem     didl_item,
@@ -79,39 +90,39 @@ internal class Rygel.MP3Transcoder : Rygel.Transcoder {
         return distance;
     }
 
-    public Element create_encoder (MediaItem item,
-                                   string?   src_pad_name,
-                                   string?   sink_pad_name)
-                                   throws Error {
-        var l16_transcoder = new L16Transcoder (Endianness.LITTLE);
-        dynamic Element convert = l16_transcoder.create_encoder
-                                        (item, null, CONVERT_SINK_PAD);
-        dynamic Element encoder = GstUtils.create_element
-                                        (AUDIO_ENCODER[this.layer],
-                                         AUDIO_ENCODER[this.layer]);
-        dynamic Element parser = GstUtils.create_element (AUDIO_PARSER,
-                                                          AUDIO_PARSER);
-
-        if (this.layer == MP3Layer.THREE) {
-            // Best quality
-            encoder.quality = 0;
-        }
+    private void on_decoder_pad_added (Element decodebin, Pad new_pad) {
+        var bin = decodebin.get_parent () as Bin;
+        assert (bin != null);
 
-        encoder.bitrate = BITRATE;
+        var encoder = bin.get_by_name (ENCODE_BIN);
+        assert (encoder != null);
 
-        var bin = new Bin ("mp3-encoder-bin");
-        bin.add_many (convert, encoder, parser);
+        var encoder_pad = encoder.get_compatible_pad (new_pad, null);
+        if (encoder_pad == null) {
+            debug ("No compatible encodebin pad found for pad '%s', ignoring..",
+                   new_pad.name);
 
-        convert.link_many (encoder, parser);
+            return;
+        } else {
+            debug ("pad '%s' with caps '%s' is compatible with '%s'",
+                   new_pad.name,
+                   new_pad.get_caps ().to_string (),
+                   encoder_pad.name);
+        }
 
-        var pad = convert.get_static_pad (CONVERT_SINK_PAD);
-        var ghost = new GhostPad (sink_pad_name, pad);
-        bin.add_pad (ghost);
+        if (new_pad.link (encoder_pad) != PadLinkReturn.OK) {
+            var error = new GstError.LINK (_("Failed to link pad %s to %s"),
+                                           new_pad.name,
+                                           encoder_pad.name);
+            GstUtils.post_error (bin, error);
+        }
+    }
 
-        pad = parser.get_static_pad ("src");
-        ghost = new GhostPad (src_pad_name, pad);
-        bin.add_pad (ghost);
+    private EncodingProfile get_encoding_profile () {
+        var format = Caps.from_string ("audio/mpeg,mpegversion=1,layer=3");
+        // FIXME: We should use the preset to set bitrate
+        var encoding_profile = new EncodingAudioProfile (format, null, null, 1);
 
-        return bin;
+        return encoding_profile;
     }
 }
index f6dff1e..08ab9b9 100644 (file)
@@ -69,7 +69,7 @@ internal abstract class Rygel.TranscodeManager : GLib.Object {
             }
 
             if (mp3_transcoder) {
-                transcoders.add (new MP3Transcoder (MP3Layer.THREE));
+                transcoders.add (new MP3Transcoder ());
             }
 
             if (mp2ts_transcoder) {