diff options
author | Marvin W <git@larma.de> | 2021-03-21 12:41:38 +0100 |
---|---|---|
committer | Marvin W <git@larma.de> | 2021-03-21 12:41:38 +0100 |
commit | ef2e3c774cab82a94a5e34399f2013d64c3cf03b (patch) | |
tree | dee0b7184eb2e225593508d74b25a8228e35144f /plugins/rtp/src/video_widget.vala | |
parent | e6a933ad307116952d3202c36d0a8d6e7f4b0946 (diff) | |
download | dino-ef2e3c774cab82a94a5e34399f2013d64c3cf03b.tar.gz dino-ef2e3c774cab82a94a5e34399f2013d64c3cf03b.zip |
Add RTP implementation as plugin
Diffstat (limited to 'plugins/rtp/src/video_widget.vala')
-rw-r--r-- | plugins/rtp/src/video_widget.vala | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/plugins/rtp/src/video_widget.vala b/plugins/rtp/src/video_widget.vala new file mode 100644 index 00000000..fa5ba138 --- /dev/null +++ b/plugins/rtp/src/video_widget.vala @@ -0,0 +1,110 @@ +public class Dino.Plugins.Rtp.VideoWidget : Gtk.Bin, Dino.Plugins.VideoCallWidget { + private static uint last_id = 0; + + public uint id { get; private set; } + public Gst.Element element { get; private set; } + public Gtk.Widget widget { get; private set; } + + public Plugin plugin { get; private set; } + public Gst.Pipeline pipe { get { + return plugin.pipe; + }} + + private bool attached; + private Device? connected_device; + private Stream? connected_stream; + private Gst.Element convert; + + public VideoWidget(Plugin plugin) { + this.plugin = plugin; + + id = last_id++; + element = Gst.ElementFactory.make("gtksink", @"video-widget-$id"); + if (element != null) { + Gtk.Widget widget; + element.@get("widget", out widget); + element.@set("async", false); + element.@set("sync", false); + this.widget = widget; + add(widget); + widget.visible = true; + + // Listen for resolution changes + element.get_static_pad("sink").notify["caps"].connect(() => { + if (element.get_static_pad("sink").caps == null) return; + + int width, height; + element.get_static_pad("sink").caps.get_structure(0).get_int("width", out width); + element.get_static_pad("sink").caps.get_structure(0).get_int("height", out height); + resolution_changed(width, height); + }); + } else { + warning("Could not create GTK video sink. Won't display videos."); + } + } + + public void display_stream(Xmpp.Xep.JingleRtp.Stream stream) { + if (element == null) return; + detach(); + if (stream.media != "video") return; + connected_stream = stream as Stream; + if (connected_stream == null) return; + plugin.pause(); + pipe.add(element); + convert = Gst.parse_bin_from_description(@"videoconvert name=video-widget-$id-convert", true); + convert.name = @"video-widget-$id-prepare"; + pipe.add(convert); + convert.link(element); + connected_stream.add_output(convert); + element.set_locked_state(false); + plugin.unpause(); + attached = true; + } + + public void display_device(MediaDevice media_device) { + if (element == null) return; + detach(); + connected_device = media_device as Device; + if (connected_device == null) return; + plugin.pause(); + pipe.add(element); + convert = Gst.parse_bin_from_description(@"videoflip method=horizontal-flip name=video-widget-$id-flip ! videoconvert name=video-widget-$id-convert", true); + convert.name = @"video-widget-$id-prepare"; + pipe.add(convert); + convert.link(element); + connected_device.link_source().link(convert); + element.set_locked_state(false); + plugin.unpause(); + attached = true; + } + + public void detach() { + if (element == null) return; + if (attached) { + if (connected_stream != null) { + connected_stream.remove_output(convert); + connected_stream = null; + } + if (connected_device != null) { + connected_device.link_source().unlink(element); + connected_device.unlink(); // We get a new ref to recover the element, so unlink twice + connected_device.unlink(); + connected_device = null; + } + convert.set_locked_state(true); + convert.set_state(Gst.State.NULL); + pipe.remove(convert); + convert = null; + element.set_locked_state(true); + element.set_state(Gst.State.NULL); + pipe.remove(element); + attached = false; + } + } + + public override void dispose() { + detach(); + widget = null; + element = null; + } +}
\ No newline at end of file |