[rygel] engine-gst: Refactor transcoding into data source



commit 5bae8f87aa621de83737daae90d56419a2747283
Author: Jens Georg <mail jensge org>
Date:   Sat May 2 12:50:11 2020 +0200

    engine-gst: Refactor transcoding into data source

 src/media-engines/gstreamer/meson.build            |   1 +
 .../gstreamer/rygel-gst-transcoder.vala            | 108 +-------------------
 .../rygel-gst-transcoding-data-source.vala         | 109 +++++++++++++++++++++
 3 files changed, 113 insertions(+), 105 deletions(-)
---
diff --git a/src/media-engines/gstreamer/meson.build b/src/media-engines/gstreamer/meson.build
index 04cb2077..f3bc2814 100644
--- a/src/media-engines/gstreamer/meson.build
+++ b/src/media-engines/gstreamer/meson.build
@@ -8,6 +8,7 @@ media_engine_gst_sources = [
     'rygel-audio-transcoder.vala',
     'rygel-avc-transcoder.vala',
     'rygel-gst-data-source.vala',
+    'rygel-gst-transcoding-data-source.vala',
     'rygel-gst-media-engine.vala',
     'rygel-gst-sink.vala',
     'rygel-gst-transcoder.vala',
diff --git a/src/media-engines/gstreamer/rygel-gst-transcoder.vala 
b/src/media-engines/gstreamer/rygel-gst-transcoder.vala
index 2747e9fd..5c56e4ec 100644
--- a/src/media-engines/gstreamer/rygel-gst-transcoder.vala
+++ b/src/media-engines/gstreamer/rygel-gst-transcoder.vala
@@ -39,6 +39,8 @@ public errordomain Rygel.GstTranscoderError {
  * implement get_resources_for_item and get_encoding_profile methods.
  */
 internal abstract class Rygel.GstTranscoder : GLib.Object {
+    private const string DEFAULT_ENCODING_PRESET = "Rygel DLNA preset";
+
     public string name { get; construct; }
     public string mime_type { get; construct; }
     public string dlna_profile { get; construct; }
@@ -48,14 +50,6 @@ internal abstract class Rygel.GstTranscoder : GLib.Object {
                            protected set;
                            default =  DEFAULT_ENCODING_PRESET; }
 
-    private const string DECODE_BIN = "decodebin";
-    private const string ENCODE_BIN = "encodebin";
-    private const string DEFAULT_ENCODING_PRESET = "Rygel DLNA preset";
-
-    dynamic Element decoder;
-    dynamic Element encoder;
-
-    private bool link_failed;
 
     protected GstTranscoder (string name,
                              string mime_type,
@@ -69,8 +63,6 @@ internal abstract class Rygel.GstTranscoder : GLib.Object {
 
     public override void constructed () {
         base.constructed ();
-
-        this.link_failed = true;
     }
 
     /**
@@ -126,42 +118,7 @@ internal abstract class Rygel.GstTranscoder : GLib.Object {
         // We can only link GStreamer data sources together
         assert (src is GstDataSource);
 
-        var orig_source = src as GstDataSource;
-
-        this.decoder = GstUtils.create_element (DECODE_BIN,
-                                                DECODE_BIN);
-        this.encoder = GstUtils.create_element (ENCODE_BIN,
-                                                ENCODE_BIN);
-
-        encoder.profile = this.get_encoding_profile (item);
-        if (encoder.profile == null) {
-            var message = _("Could not create a transcoder configuration. Your GStreamer installation might 
be missing a plug-in");
-
-            throw new GstTranscoderError.CANT_TRANSCODE (message);
-        }
-
-        debug ("%s using the following encoding profile:",
-               this.get_class ().get_type ().name ());
-        GstUtils.dump_encoding_profile (encoder.profile);
-
-        var bin = new Bin ("transcoder-source");
-        bin.add_many (orig_source.src, decoder, encoder);
-
-        orig_source.src.link (decoder);
-
-        decoder.autoplug_continue.connect (this.on_decode_autoplug_continue);
-        decoder.pad_added.connect (this.on_decoder_pad_added);
-        decoder.no_more_pads.connect (this.on_no_more_pads);
-
-        var pad = encoder.get_static_pad ("src");
-        var ghost = new GhostPad (null, pad);
-        bin.add_pad (ghost);
-
-        // Hook up resource from original resource
-        var new_source = new GstDataSource.from_element (bin);
-        new_source.res = orig_source.res;
-
-        return new_source;
+        return new TranscodingGstDataSource (src, this.get_encoding_profile (item));
     }
 
     /**
@@ -172,65 +129,6 @@ internal abstract class Rygel.GstTranscoder : GLib.Object {
     protected abstract EncodingProfile get_encoding_profile
                                         (MediaFileItem item);
 
-    private Gst.Pad? get_compatible_sink_pad (Pad pad, Caps caps) {
-        var sinkpad = this.encoder.get_compatible_pad (pad, null);
-
-        if (sinkpad == null) {
-            Signal.emit_by_name (this.encoder, "request-pad", caps, out sinkpad);
-        }
-
-        if (sinkpad == null) {
-            debug ("No compatible encodebin pad found for pad '%s', ignoring...",
-                   pad.name);
-        }
-
-        return sinkpad;
-    }
-
-    private bool on_decode_autoplug_continue (Element decodebin,
-                                              Pad     new_pad,
-                                              Caps    caps) {
-        return this.get_compatible_sink_pad (new_pad, caps) == null;
-    }
-
-    private void on_decoder_pad_added (Element decodebin, Pad new_pad) {
-        var sinkpad = this.get_compatible_sink_pad (new_pad, new_pad.query_caps (null));
-
-        if (sinkpad == null) {
-            debug ("No compatible encodebin pad found for pad '%s', ignoring...",
-                   new_pad.name);
-            return;
-        }
-
-        var pad_link_ok = (new_pad.link (sinkpad) == PadLinkReturn.OK);
-        if (!pad_link_ok) {
-            warning ("Failed to link pad '%s' to '%s'",
-                     new_pad.name,
-                     sinkpad.name);
-        } else {
-            this.link_failed = false;
-        }
-    }
-
-    private const string DESCRIPTION = "Encoder and decoder are not " +
-                                       "compatible";
-
-    private void on_no_more_pads (Element decodebin) {
-        // We haven't found any pads we could link
-        if (this.link_failed) {
-            // Signalize that error
-            var bin = this.encoder.get_parent () as Bin;
-            var error = new IOError.FAILED ("Could not link");
-            var message = new Message.error (bin,
-                                             error,
-                                             DESCRIPTION);
-
-
-            var bus = bin.get_bus ();
-            bus.post (message);
-        }
-    }
-
     public bool transcoding_necessary (MediaFileItem item) {
         return !(this.mime_type_is_a (this.mime_type, item.mime_type) &&
                  this.dlna_profile == item.dlna_profile);
diff --git a/src/media-engines/gstreamer/rygel-gst-transcoding-data-source.vala 
b/src/media-engines/gstreamer/rygel-gst-transcoding-data-source.vala
new file mode 100644
index 00000000..16f2e77e
--- /dev/null
+++ b/src/media-engines/gstreamer/rygel-gst-transcoding-data-source.vala
@@ -0,0 +1,109 @@
+/*
+ * This file is part of Rygel.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+using Gst;
+using Gst.PbUtils;
+
+internal class Rygel.TranscodingGstDataSource : Rygel.GstDataSource {
+    private const string DECODE_BIN = "decodebin";
+    private const string ENCODE_BIN = "encodebin";
+
+    dynamic Element decoder;
+    dynamic Element encoder;
+    private bool link_failed = true;
+
+    public TranscodingGstDataSource(DataSource src, EncodingProfile profile) throws Error {
+        var bin = new Bin ("transcoder-source");
+        base.from_element (bin);
+
+        var orig_source = (GstDataSource) src;
+
+        this.decoder = GstUtils.create_element (DECODE_BIN, DECODE_BIN);
+        this.encoder = GstUtils.create_element (ENCODE_BIN, ENCODE_BIN);
+
+        this.encoder.profile = profile;
+        if (encoder.profile == null) {
+            var message = _("Could not create a transcoder configuration. Your GStreamer installation might 
be missing a plug-in");
+
+            throw new GstTranscoderError.CANT_TRANSCODE (message);
+        }
+
+        debug ("%s using the following encoding profile:",
+               this.get_class ().get_type ().name ());
+               GstUtils.dump_encoding_profile (encoder.profile);
+
+        bin.add_many (orig_source.src, decoder, encoder);
+
+        orig_source.src.link (decoder);
+
+        decoder.autoplug_continue.connect (this.on_decode_autoplug_continue);
+        decoder.pad_added.connect (this.on_decoder_pad_added);
+        decoder.no_more_pads.connect (this.on_no_more_pads);
+
+        var pad = encoder.get_static_pad ("src");
+        var ghost = new GhostPad (null, pad);
+        bin.add_pad (ghost);
+    }
+
+    private Gst.Pad? get_compatible_sink_pad (Pad pad, Caps caps) {
+        var sinkpad = this.encoder.get_compatible_pad (pad, null);
+
+        if (sinkpad == null) {
+            Signal.emit_by_name (this.encoder, "request-pad", caps, out sinkpad);
+        }
+
+        if (sinkpad == null) {
+            debug ("No compatible encodebin pad found for pad '%s', ignoring...",
+                   pad.name);
+        }
+
+        return sinkpad;
+    }
+
+    private bool on_decode_autoplug_continue (Element decodebin,
+                                              Pad     new_pad,
+                                              Caps    caps) {
+        return this.get_compatible_sink_pad (new_pad, caps) == null;
+    }
+
+    private void on_decoder_pad_added (Element decodebin, Pad new_pad) {
+        var sinkpad = this.get_compatible_sink_pad (new_pad, new_pad.query_caps (null));
+
+        if (sinkpad == null) {
+            debug ("No compatible encodebin pad found for pad '%s', ignoring...",
+                   new_pad.name);
+            return;
+        }
+
+        var pad_link_ok = (new_pad.link (sinkpad) == PadLinkReturn.OK);
+        if (!pad_link_ok) {
+            warning ("Failed to link pad '%s' to '%s'",
+                     new_pad.name,
+                     sinkpad.name);
+        } else {
+            this.link_failed = false;
+        }
+    }
+
+    private const string DESCRIPTION = "Encoder and decoder are not " +
+                                       "compatible";
+
+    private void on_no_more_pads (Element decodebin) {
+        // We haven't found any pads we could link
+        if (this.link_failed) {
+            // Signalize that error
+            var bin = this.encoder.get_parent () as Bin;
+            var error = new IOError.FAILED ("Could not link");
+            var message = new Message.error (bin,
+                                             error,
+                                             DESCRIPTION);
+
+
+            var bus = bin.get_bus ();
+            bus.post (message);
+        }
+    }
+}


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