aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaZderMind <github@mazdermind.de>2015-04-23 06:49:07 +0200
committerMaZderMind <github@mazdermind.de>2015-04-23 06:49:42 +0200
commitf4cd6ec1bfed02def8502bc8373b1fe0d35acca8 (patch)
tree0b6f79472d0d033a8fb9c852f079d15740132731
parent33ae6e1aac59b4d120ed3b8a319c6eb0ed5045cf (diff)
remove unsuccessful experiments, add intervideo-based working example
-rwxr-xr-xvoctocore/experiments/failovertest.py59
-rw-r--r--voctocore/experiments/gstreamer-shm-pipe.txt13
-rwxr-xr-xvoctocore/experiments/intervideo.py128
-rw-r--r--voctocore/experiments/shmsrc.py115
-rwxr-xr-xvoctocore/experiments/startuptest/startuptest.py59
-rw-r--r--voctocore/experiments/startuptest/testbin.py41
-rwxr-xr-xvoctocore/experiments/test-audio.sh2
-rwxr-xr-xvoctocore/experiments/test-av-sync.sh24
-rwxr-xr-xvoctocore/experiments/test-grabber-src1.sh11
-rwxr-xr-xvoctocore/experiments/test-grabber-src2.sh11
-rwxr-xr-xvoctocore/experiments/test-video.sh2
-rw-r--r--voctocore/experiments/testframes/dead-1024x576.rgbabin2359296 -> 0 bytes
-rw-r--r--voctocore/experiments/testframes/dead-1920x1080.rgbabin8294400 -> 0 bytes
-rwxr-xr-xvoctocore/experiments/testframes/make_frames4
-rwxr-xr-xvoctocore/experiments/video-grabber-src.sh29
-rw-r--r--voctocore/experiments/videodisplay.py50
16 files changed, 156 insertions, 392 deletions
diff --git a/voctocore/experiments/failovertest.py b/voctocore/experiments/failovertest.py
deleted file mode 100755
index deb665b..0000000
--- a/voctocore/experiments/failovertest.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/python3
-import gi, time
-
-# import GStreamer and GTK-Helper classes
-gi.require_version('Gst', '1.0')
-from gi.repository import GLib, Gst, GObject
-
-# init GObject before importing local classes
-GObject.threads_init()
-Gst.init(None)
-
-from videodisplay import VideomixerWithDisplay
-from shmsrc import ShmSrc
-
-class Example:
- def __init__(self):
- self.mainloop = GObject.MainLoop()
- self.pipeline = Gst.Pipeline()
-
- self.bus = self.pipeline.get_bus()
- self.bus.add_signal_watch()
- self.bus.connect('message::eos', self.on_eos)
- self.bus.connect('message::error', self.on_error)
-
- self.addTest('/tmp/v-cam2')
- self.addTest('/tmp/v-cam1')
-
- def addTest(self, socket):
- self.mixdisplay = VideomixerWithDisplay()
- self.videoconvert = Gst.ElementFactory.make('videoconvert', None)
- self.grabbersrc = ShmSrc(socket, Gst.Caps.from_string('video/x-raw,width=1280,height=720,framerate=25/1,format=RGBx'))
-
- # Add elements to pipeline
- self.pipeline.add(self.grabbersrc)
- self.pipeline.add(self.videoconvert)
- self.pipeline.add(self.mixdisplay)
- self.grabbersrc.link(self.videoconvert)
- self.videoconvert.link(self.mixdisplay)
-
- def run(self):
- self.pipeline.set_state(Gst.State.PAUSED)
- time.sleep(0.5)
- self.pipeline.set_state(Gst.State.PLAYING)
- self.mainloop.run()
-
- def kill(self):
- self.pipeline.set_state(Gst.State.NULL)
- self.mainloop.quit()
-
- def on_eos(self, bus, msg):
- print('on_eos()')
- #self.kill()
-
- def on_error(self, bus, msg):
- print('on_error():', msg.parse_error())
- #self.kill()
-
-example = Example()
-example.run()
diff --git a/voctocore/experiments/gstreamer-shm-pipe.txt b/voctocore/experiments/gstreamer-shm-pipe.txt
deleted file mode 100644
index d4a9767..0000000
--- a/voctocore/experiments/gstreamer-shm-pipe.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# works with gstreamer 1.4 - will probably not work with lower versions
-
-# video/audio-src
-gst-launch-1.0 -vm uridecodebin uri=file:///home/peter/avsync.mp4 name=src \
-src. ! video/x-raw,format=I420,width=1280,height=720,framerate=25/1 ! queue ! shmsink sync=true socket-path=/tmp/sock-v wait-for-connection=false shm-size=100000000 \
-src. ! audio/x-raw,format=S16LE,layout=interleaved,rate=44100,channels=2 ! queue ! shmsink sync=true socket-path=/tmp/sock-a wait-for-connection=false shm-size=10000000
-
-# video sink
-gst-launch-1.0 -vm shmsrc is-live=true do-timestamp=true socket-path=/tmp/sock-v ! video/x-raw,format=I420,width=1280,height=720,framerate=25/1 ! videomixer ! ximagesink
-
-# audio sink
-gst-launch-1.0 -vm shmsrc is-live=true do-timestamp=true socket-path=/tmp/sock-a ! audio/x-raw,format=S16LE,layout=interleaved,rate=44100,channels=2 ! alsasink
-
diff --git a/voctocore/experiments/intervideo.py b/voctocore/experiments/intervideo.py
new file mode 100755
index 0000000..ac5cac1
--- /dev/null
+++ b/voctocore/experiments/intervideo.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python3
+import gi, time
+import socket
+
+# import GStreamer and GTK-Helper classes
+gi.require_version('Gst', '1.0')
+from gi.repository import GLib, Gst, GObject
+
+# init GObject before importing local classes
+GObject.threads_init()
+Gst.init(None)
+
+class Example:
+ def __init__(self):
+ self.mainloop = GObject.MainLoop()
+ self.vsink = Gst.parse_launch('intervideosrc channel=video ! video/x-raw,height=600,width=800,format=I420,framerate=25/1 ! timeoverlay ! videoconvert ! ximagesink')
+ self.vsource = None
+
+ self.asink = Gst.parse_launch('interaudiosrc channel=audio ! audio/x-raw,format=S16LE,layout=interleaved,rate=48000,channels=2 ! autoaudiosink')
+ self.asource = None
+
+
+ # Create the server, binding to localhost on port 5000
+ vsock = socket.socket(socket.AF_INET6)
+ vsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ vsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
+ vsock.bind(('::', 5000))
+ vsock.listen(1)
+
+ # register socket for callback inside the GTK-Mainloop
+ GObject.io_add_watch(vsock, GObject.IO_IN, self.connection_handler_video)
+
+
+
+ # Create the server, binding to localhost on port 6000
+ asock = socket.socket(socket.AF_INET6)
+ asock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ asock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
+ asock.bind(('::', 6000))
+ asock.listen(1)
+
+ # register socket for callback inside the GTK-Mainloop
+ GObject.io_add_watch(asock, GObject.IO_IN, self.connection_handler_audio)
+
+
+
+ def connection_handler_video(self, sock, *args):
+ '''Asynchronous connection listener. Starts a handler for each connection.'''
+ if self.vsource:
+ return False
+
+ conn, addr = sock.accept()
+ print("Connection from", addr)
+
+ self.vsource = Gst.parse_launch('appsrc name=a ! gdpdepay ! video/x-raw,height=600,width=800,format=I420,framerate=25/1 ! timeoverlay halignment=right ! intervideosink channel=video')
+ self.vsource.set_state(Gst.State.PLAYING)
+
+ # register data-received handler inside the GTK-Mainloop
+ GObject.io_add_watch(conn, GObject.IO_IN, self.data_handler_video)
+ return True
+
+ def data_handler_video(self, conn, *args):
+ '''Asynchronous data handler. Processes data-blocks line from the socket.'''
+ blob = conn.recv(10000000) # >1920x1080x3
+ if not len(blob):
+ print("Connection closed.")
+ self.vsource.set_state(Gst.State.NULL)
+ self.vsource = None
+ return False
+
+ print("Video-Blob of %u bytes" % len(blob))
+ buf = Gst.Buffer.new_wrapped(blob)
+ self.vsource.get_by_name('a').emit('push-buffer', buf)
+ return True
+
+
+
+ def connection_handler_audio(self, sock, *args):
+ '''Asynchronous connection listener. Starts a handler for each connection.'''
+ if self.asource:
+ return False
+
+ conn, addr = sock.accept()
+ print("Connection from", addr)
+
+ self.asource = Gst.parse_launch('appsrc name=a ! gdpdepay ! audio/x-raw,format=S16LE,layout=interleaved,rate=48000,channels=2 ! interaudiosink channel=audio')
+ self.asource.set_state(Gst.State.PLAYING)
+
+ # register data-received handler inside the GTK-Mainloop
+ GObject.io_add_watch(conn, GObject.IO_IN, self.data_handler_audio)
+ return True
+
+ def data_handler_audio(self, conn, *args):
+ '''Asynchronous data handler. Processes data-blocks line from the socket.'''
+ blob = conn.recv(10000000) # >1920x1080x3
+ if not len(blob):
+ print("Connection closed.")
+ self.asource.set_state(Gst.State.NULL)
+ self.asource = None
+ return False
+
+ print("Audio-Blob of %u bytes" % len(blob))
+ buf = Gst.Buffer.new_wrapped(blob)
+ self.asource.get_by_name('a').emit('push-buffer', buf)
+ return True
+
+
+
+ def run(self):
+ self.vsink.set_state(Gst.State.PLAYING)
+ self.asink.set_state(Gst.State.PLAYING)
+ self.mainloop.run()
+
+ def kill(self):
+ self.vsink.set_state(Gst.State.NULL)
+ self.asink.set_state(Gst.State.NULL)
+ self.mainloop.quit()
+
+ def on_eos(self, bus, msg):
+ print('on_eos()')
+ #self.kill()
+
+ def on_error(self, bus, msg):
+ print('on_error():', msg.parse_error())
+ #self.kill()
+
+example = Example()
+example.run()
diff --git a/voctocore/experiments/shmsrc.py b/voctocore/experiments/shmsrc.py
deleted file mode 100644
index 742767b..0000000
--- a/voctocore/experiments/shmsrc.py
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/python3
-import time
-from gi.repository import GLib, Gst
-
-class ShmSrc(Gst.Bin):
- last_buffer_arrived = 0
- is_in_failstate = True
-
- def __init__(self, socket, caps):
- super().__init__()
-
- # Create elements
- self.shmsrc = Gst.ElementFactory.make('shmsrc', None)
- self.identity1 = Gst.ElementFactory.make('identity', None)
- self.identity2 = Gst.ElementFactory.make('identity', None)
- self.switch = Gst.ElementFactory.make('input-selector', None)
- self.failsrc = Gst.ElementFactory.make('videotestsrc', None)
-
- # Add elements to Bin
- self.add(self.shmsrc)
- self.add(self.identity1)
- self.add(self.identity2)
- self.add(self.switch)
- self.add(self.failsrc)
-
- # Get Switcher-Pads
- self.goodpad = self.switch.get_request_pad('sink_%u')
- self.failpad = self.switch.get_request_pad('sink_%u')
-
- # Set properties
- self.shmsrc.set_property('socket-path', socket)
- self.shmsrc.set_property('is-live', True)
- self.shmsrc.set_property('do-timestamp', True)
- #self.identity1.set_property('sync', True)
- self.identity2.set_property('sync', True)
- self.switch.set_property('active-pad', self.failpad)
- self.failsrc.set_property('pattern', 'snow')
-
- # Link elements
- self.shmsrc.link_filtered(self.identity1, caps)
- self.identity1.get_static_pad('src').link(self.goodpad)
-
- self.failsrc.link_filtered(self.identity2, caps)
- self.identity2.get_static_pad('src').link(self.failpad)
-
- # Install pad probes
- self.shmsrc.get_static_pad('src').add_probe(Gst.PadProbeType.BLOCK | Gst.PadProbeType.EVENT_DOWNSTREAM, self.event_probe, None)
- self.shmsrc.get_static_pad('src').add_probe(Gst.PadProbeType.BLOCK | Gst.PadProbeType.BUFFER, self.data_probe, None)
-
- # Install Watchdog
- GLib.timeout_add(500, self.watchdog)
-
- # Add Ghost Pads
- self.add_pad(
- Gst.GhostPad.new('sink', self.switch.get_static_pad('src'))
- )
-
- def do_handle_message(self, msg):
- if msg.type == Gst.MessageType.ERROR:
- print("do_handle_message(): dropping error")
- return
-
- print("do_handle_message()", msg.src, msg.type)
- Gst.Bin.do_handle_message(self, msg)
-
- def event_probe(self, pad, info, ud):
- e = info.get_event()
- if e.type == Gst.EventType.EOS:
- self.switch_to_failstate()
- return Gst.PadProbeReturn.DROP
-
- return Gst.PadProbeReturn.PASS
-
-
- def data_probe(self, pad, info, ud):
- self.last_buffer_arrived = time.time()
- self.switch_to_goodstate()
- return Gst.PadProbeReturn.PASS
-
- def watchdog(self):
- if self.last_buffer_arrived + 0.1 < time.time():
- print("watchdog()::timeout")
- self.switch_to_failstate()
-
- if self.last_buffer_arrived + 3 < time.time() and round(time.time() % 3) == 0:
- print("watchdog()::restart")
- self.restart()
-
- return True
-
- def restart(self):
- self.shmsrc.set_state(Gst.State.NULL)
-
- # this somehow solves parts of the multi-output-timestamping-issue
- # starting the 2nd src n seconds after the program started freezes it for n seconds
- self.shmsrc.set_start_time(0)
- self.shmsrc.set_base_time(self.get_parent().get_base_time())
-
- self.shmsrc.set_state(Gst.State.PLAYING)
-
- def switch_to_goodstate(self):
- if not self.is_in_failstate:
- return
-
- print("switch_to_goodstate()")
- self.is_in_failstate = False
- self.switch.set_property('active-pad', self.goodpad)
-
- def switch_to_failstate(self):
- if self.is_in_failstate:
- return
-
- print("switch_to_failstate()")
- self.is_in_failstate = True
- self.switch.set_property('active-pad', self.failpad)
diff --git a/voctocore/experiments/startuptest/startuptest.py b/voctocore/experiments/startuptest/startuptest.py
deleted file mode 100755
index 58e676a..0000000
--- a/voctocore/experiments/startuptest/startuptest.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/python3
-
-# Example for the startup-problem
-#
-# The Pipeline will start but the test-image will be still, as long as no
-# ShmSink at /tmp/grabber-v is present (run ../test-grabber-src.sh in another shell)
-#
-# Even though the ShmSrc is not linked to anything and logically not required for
-# the videotestsrc or the ximagesink, the whole pipeline won't startup when this element
-# fails to start.
-#
-# once the pipeline is running, it does not matter what happens to the ShmSink on the
-# other end, because the TestBin filters all EOS and ERROR Messages coming from the ShmSrc,
-# but somehow this is not enough to make the pipeline start in an error-condition..
-#
-
-import gi, time
-
-# import GStreamer and GTK-Helper classes
-gi.require_version('Gst', '1.0')
-from gi.repository import GLib, Gst, GObject
-
-# init GObject before importing local classes
-GObject.threads_init()
-Gst.init(None)
-
-from testbin import TestBin
-
-class Example:
- def __init__(self):
- self.mainloop = GObject.MainLoop()
- self.pipeline = Gst.Pipeline()
-
- self.src = Gst.ElementFactory.make('videotestsrc', None)
- self.sink = Gst.ElementFactory.make('ximagesink', None)
-
- self.testbin = TestBin()
-
- # Add elements to pipeline
- self.pipeline.add(self.testbin)
- self.pipeline.add(self.src)
- self.pipeline.add(self.sink)
-
- self.src.link(self.sink)
-
- def run(self):
- print("PAUSED")
- self.pipeline.set_state(Gst.State.PAUSED)
- time.sleep(0.1)
- print("PLAYING")
- self.pipeline.set_state(Gst.State.PLAYING)
- self.mainloop.run()
-
- def kill(self):
- self.pipeline.set_state(Gst.State.NULL)
- self.mainloop.quit()
-
-example = Example()
-example.run()
diff --git a/voctocore/experiments/startuptest/testbin.py b/voctocore/experiments/startuptest/testbin.py
deleted file mode 100644
index e234b55..0000000
--- a/voctocore/experiments/startuptest/testbin.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python3
-import time
-from gi.repository import GLib, Gst
-
-class TestBin(Gst.Bin):
- def __init__(self):
- super().__init__()
- self.set_name('testbin')
-
- # Create elements
- self.shmsrc = Gst.ElementFactory.make('shmsrc', None)
-
- # Add elements to Bin
- self.add(self.shmsrc)
-
- self.shmsrc.set_property('socket-path', '/tmp/grabber-v')
- self.shmsrc.set_property('is-live', True)
- self.shmsrc.set_property('do-timestamp', True)
-
- # Install pad probes
- self.shmsrc.get_static_pad('src').add_probe(Gst.PadProbeType.BLOCK | Gst.PadProbeType.EVENT_DOWNSTREAM, self.event_probe, None)
- self.shmsrc.get_static_pad('src').add_probe(Gst.PadProbeType.BLOCK | Gst.PadProbeType.BUFFER, self.data_probe, None)
-
- def do_handle_message(self, msg):
- if msg.type == Gst.MessageType.ERROR:
- print("do_handle_message(): dropping error")
- return
-
- print("do_handle_message()", msg.src, msg.type)
- Gst.Bin.do_handle_message(self, msg)
-
- def event_probe(self, pad, info, ud):
- e = info.get_event()
- if e.type == Gst.EventType.EOS:
- return Gst.PadProbeReturn.DROP
-
- return Gst.PadProbeReturn.PASS
-
- def data_probe(self, pad, info, ud):
- self.last_buffer_arrived = time.time()
- return Gst.PadProbeReturn.PASS
diff --git a/voctocore/experiments/test-audio.sh b/voctocore/experiments/test-audio.sh
new file mode 100755
index 0000000..bd51bb8
--- /dev/null
+++ b/voctocore/experiments/test-audio.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+gst-launch-1.0 audiotestsrc ! audio/x-raw,format=S16LE,layout=interleaved,rate=48000,channels=2 ! gdppay ! tcpclientsink host=localhost port=6000
diff --git a/voctocore/experiments/test-av-sync.sh b/voctocore/experiments/test-av-sync.sh
new file mode 100755
index 0000000..13851d7
--- /dev/null
+++ b/voctocore/experiments/test-av-sync.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+gst-launch-1.0 -vm \
+ uridecodebin \
+ uri=http://c3voc.mazdermind.de/avsync.mp4 \
+ name=src \
+ \
+ src. !\
+ queue !\
+ videoconvert !\
+ videorate !\
+ videoscale !\
+ video/x-raw,height=600,width=800,format=I420,framerate=25/1 ! \
+ timeoverlay valignment=bottom ! \
+ gdppay ! \
+ tcpclientsink host=localhost port=5000 \
+ \
+ src. !\
+ queue !\
+ audioconvert !\
+ audioresample !\
+ audiorate !\
+ audio/x-raw,format=S16LE,layout=interleaved,rate=48000,channels=2 !\
+ gdppay !\
+ tcpclientsink host=localhost port=6000
diff --git a/voctocore/experiments/test-grabber-src1.sh b/voctocore/experiments/test-grabber-src1.sh
deleted file mode 100755
index ea46328..0000000
--- a/voctocore/experiments/test-grabber-src1.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-gst-launch-1.0 -vm \
- videotestsrc pattern=ball background-color=0xff0000ff !\
- video/x-raw,width=1280,height=720,framerate=25/1,format=RGBx !\
- progressreport update-freq=1 !\
- queue !\
- shmsink \
- sync=true \
- socket-path=/tmp/v-cam1 \
- wait-for-connection=false \
- shm-size=100000000
diff --git a/voctocore/experiments/test-grabber-src2.sh b/voctocore/experiments/test-grabber-src2.sh
deleted file mode 100755
index 0315f46..0000000
--- a/voctocore/experiments/test-grabber-src2.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-gst-launch-1.0 -vm \
- videotestsrc pattern=ball background-color=0x00ff00ff !\
- video/x-raw,width=1280,height=720,framerate=25/1,format=RGBx !\
- progressreport update-freq=1 !\
- queue !\
- shmsink \
- sync=true \
- socket-path=/tmp/v-cam2 \
- wait-for-connection=false \
- shm-size=100000000
diff --git a/voctocore/experiments/test-video.sh b/voctocore/experiments/test-video.sh
new file mode 100755
index 0000000..b152b9f
--- /dev/null
+++ b/voctocore/experiments/test-video.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+gst-launch-1.0 videotestsrc ! video/x-raw,height=600,width=800 ! timeoverlay valignment=bottom ! gdppay ! tcpclientsink host=localhost port=5000
diff --git a/voctocore/experiments/testframes/dead-1024x576.rgba b/voctocore/experiments/testframes/dead-1024x576.rgba
deleted file mode 100644
index b23e073..0000000
--- a/voctocore/experiments/testframes/dead-1024x576.rgba
+++ /dev/null
Binary files differ
diff --git a/voctocore/experiments/testframes/dead-1920x1080.rgba b/voctocore/experiments/testframes/dead-1920x1080.rgba
deleted file mode 100644
index aa06442..0000000
--- a/voctocore/experiments/testframes/dead-1920x1080.rgba
+++ /dev/null
Binary files differ
diff --git a/voctocore/experiments/testframes/make_frames b/voctocore/experiments/testframes/make_frames
deleted file mode 100755
index 088e27e..0000000
--- a/voctocore/experiments/testframes/make_frames
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-
-gst-launch-1.0 -q videotestsrc num-buffers=1 pattern=smpte100 ! video/x-raw,format=RGBA,width=1024,height=576 ! filesink location = dead-1024x576.rgba
-gst-launch-1.0 -q videotestsrc num-buffers=1 pattern=smpte100 ! video/x-raw,format=RGBA,width=1920,height=1080 ! filesink location = dead-1920x1080.rgba
diff --git a/voctocore/experiments/video-grabber-src.sh b/voctocore/experiments/video-grabber-src.sh
deleted file mode 100755
index e592940..0000000
--- a/voctocore/experiments/video-grabber-src.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-gst-launch-1.0 \
- uridecodebin \
- uri=http://video.blendertestbuilds.de/download.blender.org/ED/ED_1280.avi \
- name=src \
- \
- src. !\
- queue !\
- progressreport !\
- videoconvert !\
- videorate !\
- videoscale !\
- video/x-raw,format=RGBx,width=1280,height=720,framerate=25/1 !\
- shmsink \
- sync=true \
- socket-path=/tmp/voctomix-sockets/v-cam1 \
- wait-for-connection=false \
- shm-size=100000000
- \
- src. !\
- queue !\
- audioconvert !\
- audiorate !\
- audio/x-raw,format=S16LE,layout=interleaved,rate=44100,channels=2 !\
- shmsink \
- sync=true \
- socket-path=/tmp/voctomix-sockets/a-cam1 \
- wait-for-connection=false \
- shm-size=10000000
diff --git a/voctocore/experiments/videodisplay.py b/voctocore/experiments/videodisplay.py
deleted file mode 100644
index 17ef653..0000000
--- a/voctocore/experiments/videodisplay.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/python3
-from gi.repository import GObject, Gst
-
-class VideomixerWithDisplay(Gst.Bin):
- def __init__(self):
- super().__init__()
-
- # Create elements
- self.secondsrc = Gst.ElementFactory.make('videotestsrc', None)
- self.mixer = Gst.ElementFactory.make('compositor', None)
- self.ident = Gst.ElementFactory.make('identity', None)
- self.q1 = Gst.ElementFactory.make('queue', None)
- self.q2 = Gst.ElementFactory.make('queue', None)
- self.display = Gst.ElementFactory.make('ximagesink', None)
-
- # Add elements to Bin
- self.add(self.secondsrc)
- self.add(self.mixer)
- self.add(self.ident)
- self.add(self.display)
- self.add(self.q1)
- self.add(self.q2)
-
- # Set properties
- self.secondsrc.set_property('pattern', 'ball')
- self.ident.set_property('sync', True)
- self.display.set_property('sync', False)
-
- # Request Pads
- self.firstpad = self.mixer.get_request_pad('sink_%u')
- self.secondpad = self.mixer.get_request_pad('sink_%u')
-
- # Set pad-properties
- self.secondpad.set_property('alpha', 0.75)
- self.secondpad.set_property('xpos', 50)
- self.secondpad.set_property('ypos', 50)
-
- # Link elements
- self.q1.get_static_pad('src').link(self.firstpad)
-
- self.q2.get_static_pad('src').link(self.secondpad)
- self.secondsrc.link_filtered(self.ident, Gst.Caps.from_string('video/x-raw,width=400,height=400,framerate=25/1,format=RGBx'))
- self.ident.link(self.q2)
-
- self.mixer.link(self.display)
-
- # Add Ghost Pads
- self.add_pad(
- Gst.GhostPad.new('sink', self.q1.get_static_pad('sink'))
- )