29
29
* The base Transcoder class. Each implementation derives from it and must
30
* implement get_distance and get_encoding_profile methods.
30
* at least implement create_source method.
32
32
internal abstract class Rygel.Transcoder : GLib.Object {
33
33
public string mime_type { get; protected set; }
34
34
public string dlna_profile { get; protected set; }
35
public Gst.Caps decoder_caps;
37
private const string DECODE_BIN = "decodebin2";
38
private const string ENCODE_BIN = "encodebin";
40
36
// Primary UPnP item class that this transcoder is meant for, doesn't
41
37
// necessarily mean it cant be used for other classes.
58
54
* @return the new transcoding source
60
public virtual Element create_source (MediaItem item,
61
Element src) throws Error {
62
dynamic Element decoder = GstUtils.create_element (DECODE_BIN,
64
dynamic Element encoder = GstUtils.create_element (ENCODE_BIN,
67
encoder.profile = this.get_encoding_profile ();
69
var bin = new Bin ("transcoder-source");
70
bin.add_many (src, decoder, encoder);
74
decoder.pad_added.connect (this.on_decoder_pad_added);
75
decoder.autoplug_continue.connect (this.on_autoplug_continue);
77
var pad = encoder.get_static_pad ("src");
78
var ghost = new GhostPad (null, pad);
56
public abstract Element create_source (MediaItem item,
57
Element src) throws Error;
84
59
public virtual DIDLLiteResource? add_resource (DIDLLiteItem didl_item,
132
107
public abstract uint get_distance (MediaItem item);
135
* Gets the Gst.EncodingProfile for this transcoder.
137
* @return the Gst.EncodingProfile for this transcoder.
139
protected abstract EncodingProfile get_encoding_profile ();
141
109
protected bool mime_type_is_a (string mime_type1, string mime_type2) {
142
110
string content_type1 = ContentType.get_mime_type (mime_type1);
143
111
string content_type2 = ContentType.get_mime_type (mime_type2);
145
113
return ContentType.is_a (content_type1, content_type2);
148
private bool on_autoplug_continue (Element decodebin,
151
this.decoder_caps = caps;
152
return !this.connect_decoder_pad (decodebin, new_pad);
155
private void on_decoder_pad_added (Element decodebin, Pad new_pad) {
156
this.connect_decoder_pad (decodebin, new_pad);
159
private bool connect_decoder_pad (Element decodebin, Pad new_pad) {
160
var bin = decodebin.get_parent () as Bin;
161
assert (bin != null);
163
var encoder = bin.get_by_name (ENCODE_BIN);
164
assert (encoder != null);
166
Gst.Pad encoder_pad = null;
167
encoder_pad = encoder.get_compatible_pad (new_pad, null);
168
if (encoder_pad == null) {
169
Signal.emit_by_name (encoder,
175
if (encoder_pad == null) {
176
debug ("No compatible encodebin pad found for pad '%s', ignoring..",
181
debug ("pad '%s' with caps '%s' is compatible with '%s'",
183
this.decoder_caps.to_string (),
187
var pad_link_ok = (new_pad.link (encoder_pad) == PadLinkReturn.OK);
189
warning ("Failed to link pad '%s' to '%s'",