From: Einar Jørgen Haraldseid Date: Sat, 3 Jun 2017 20:52:00 +0000 (+0200) Subject: Faster example using videomixer X-Git-Url: https://git.slaskete.net/python-gstreamer-examples/commitdiff_plain/28384339c30c154d2e55e266d45f2dd52ad4861a?ds=inline;hp=f27d0d0705b7485c0bff2bfefe258199a5e81168 Faster example using videomixer --- diff --git a/example5.glade b/example5.glade new file mode 100644 index 0000000..9d3d36d --- /dev/null +++ b/example5.glade @@ -0,0 +1,177 @@ + + + + + + False + GStreamer video switcher test + + + True + False + vertical + + + True + False + + + viewport_main + 1280 + 720 + True + True + False + True + True + + + + + False + True + 0 + + + + + True + False + 1 + + + True + False + + + True + False + + + Input 1 + True + True + True + + + + + + False + True + 0 + + + + + True + False + + + Input 2 + True + True + True + + + + + + False + True + 1 + + + + + True + False + + + Input 3 + True + True + True + + + + + + False + True + 2 + + + + + True + False + + + Input 4 + True + True + True + + + + + + False + True + 3 + + + + + True + False + + + Input 5 + True + True + True + + + + + + False + True + 4 + + + + + True + False + + + Input 6 + True + True + True + + + + + + False + True + 5 + + + + + + + False + True + 1 + + + + + + diff --git a/example5.py b/example5.py new file mode 100755 index 0000000..44ace18 --- /dev/null +++ b/example5.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +# Attempting to dynamically switch between input sources + +# GdkX11 to get access to xid, GstVideo to get access to set_window_handle +import gi, signal +gi.require_version('Gtk', '3.0') +gi.require_version('Gst', '1.0') +gi.require_version('GstVideo', '1.0') +from gi.repository import Gtk, Gst, GdkX11, GstVideo + +class Main: + def __init__(self): + + # Create gui bits and bobs + + self.mainwindow = Gtk.Builder() + self.mainwindow.add_from_file("example5.glade") + + signals = { + "on_input1_clicked" : self.SetInput1, + "on_input2_clicked" : self.SetInput2, + "on_input3_clicked" : self.SetInput3, + "on_input4_clicked" : self.SetInput4, + "on_input5_clicked" : self.SetInput5, + "on_input6_clicked" : self.SetInput6, + "on_quit_clicked" : self.OnQuit, + } + + self.mainwindow.connect_signals(signals) + + # Create GStreamer bits and bobs + + # Initiate Gstreamer + Gst.init(None) + + # Some capabilities we want to share between different elements + jpegcaps = Gst.Caps.from_string("image/jpeg,width=1280,height=720,framerate=30/1") + + # Set up the pipeline + self.pipeline = Gst.Pipeline() + + # Add elements + + # src1 + self.src1 = Gst.ElementFactory.make("v4l2src", "src1") + self.src1.set_property("device", "/dev/video1") + + # src1 capsfilter + self.src1caps = Gst.ElementFactory.make("capsfilter", "src1caps") + self.src1caps.set_property("caps", jpegcaps) + + # src1jpegdec + self.src1jpegdec = Gst.ElementFactory.make("jpegdec", "src1jpegdec") + + # src1videoconvert + self.src1videoconvert = Gst.ElementFactory.make("videoconvert", "src1videoconvert") + + # src2 + self.src2 = Gst.ElementFactory.make("v4l2src", "src2") + self.src2.set_property("device", "/dev/video0") + + # src2 capsfilter + self.src2caps = Gst.ElementFactory.make("capsfilter", "src2caps") + self.src2caps.set_property("caps", jpegcaps) + + # src2jpegdec + self.src2jpegdec = Gst.ElementFactory.make("jpegdec", "src2jpegdec") + + # src2videoconvert + self.src2videoconvert = Gst.ElementFactory.make("videoconvert", "src2videoconvert") + + # Video mix + self.videomix = Gst.ElementFactory.make("videomixer", "videomix") + self.src1pad = self.videomix.get_request_pad("sink_1") + self.src1pad.set_property("zorder", 2) + self.src2pad = self.videomix.get_request_pad("sink_2") + self.src2pad.set_property("zorder", 1) + + # Add main videosink + self.videosink = Gst.ElementFactory.make("autovideosink", "videosink") + self.videosink.set_property("sync", False) + + # Add initial elements to the pipeline + self.pipeline.add(self.src1) + self.pipeline.add(self.src1caps) + self.pipeline.add(self.src1jpegdec) + self.pipeline.add(self.src1videoconvert) + + self.pipeline.add(self.src2) + self.pipeline.add(self.src2caps) + self.pipeline.add(self.src2jpegdec) + self.pipeline.add(self.src2videoconvert) + + self.pipeline.add(self.videomix) + self.pipeline.add(self.videosink) + + # Link the initial pipeline + self.src1.link(self.src1caps) + self.src1caps.link(self.src1jpegdec) + self.src1jpegdec.link(self.src1videoconvert) + self.src1videoconvert.link(self.videomix) + + self.src2.link(self.src2caps) + self.src2caps.link(self.src2jpegdec) + self.src2jpegdec.link(self.src2videoconvert) + self.src2videoconvert.link(self.videomix) + + self.videomix.link(self.videosink) + + # Set up a bus to our pipeline to get notified when the video is ready + self.bus = self.pipeline.get_bus() + self.bus.enable_sync_message_emission() + self.bus.connect("sync-message::element", self.OnSyncElement) + + # Summon the window and connect the window's close button to quit + self.window = self.mainwindow.get_object("mainwindow") + self.window.connect("delete-event", Gtk.main_quit) + self.window.show_all() + + # Get window ID of the viewport widget from the GUI + self.win_id = self.mainwindow.get_object("viewport_main").get_window().get_xid() + + # Play! + self.pipeline.set_state(Gst.State.PLAYING) + + + # When we get a message that video is ready to display, set the + # correct window id to hook it to our viewport + def OnSyncElement(self, bus, message): + if message.get_structure().get_name() == "prepare-window-handle": + print("prepare-window-handle") + message.src.set_window_handle(self.win_id) + + def SetInput1(self, widget): + print("Switch to input 1") + self.src1pad.set_property("zorder", 2) + self.src2pad.set_property("zorder", 1) + + def SetInput2(self, widget): + print("Switch to input 2") + self.src1pad.set_property("zorder", 1) + self.src2pad.set_property("zorder", 2) + + def SetInput3(self, widget): + print("Switch to input 3") + + def SetInput4(self, widget): + print("Switch to input 4") + + def SetInput5(self, widget): + print("Switch to input 5") + + def SetInput6(self, widget): + print("Switch to input 6") + + def OnQuit(self, widget): + print("quit") + Gtk.main_quit() + + # Workaround to get Ctrl+C to terminate from command line + # ref: https://bugzilla.gnome.org/show_bug.cgi?id=622084#c12 + signal.signal(signal.SIGINT, signal.SIG_DFL) + +start = Main() +Gtk.main()