Add gst-decoupled-pipelines.py
authorAntonio Ospite <ao2@ao2.it>
Tue, 16 Oct 2018 10:10:26 +0000 (12:10 +0200)
committerAntonio Ospite <ao2@ao2.it>
Tue, 16 Oct 2018 10:22:30 +0000 (12:22 +0200)
Add an example with intervideosink and intervideosrc.

python/gst-decoupled-pipelines.py [new file with mode: 0755]

diff --git a/python/gst-decoupled-pipelines.py b/python/gst-decoupled-pipelines.py
new file mode 100755 (executable)
index 0000000..25a95b7
--- /dev/null
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+
+import sys
+
+from math import pi
+
+import gi
+gi.require_version('Gst', '1.0')
+from gi.repository import Gst
+Gst.init(None)
+
+from gi.repository import GObject
+GObject.threads_init()
+
+
+PIPELINE_SRC = """
+videotestsrc pattern=18 background-color=4294901760 ! intervideosink
+"""
+
+#PIPELINE_SRC = """
+#v4l2src ! video/x-raw,width=320,height=240 ! intervideosink
+#"""
+
+PIPELINE_SINK = """
+intervideosrc timeout=-1 ! videoconvert ! rotate name=rotate ! videoconvert ! autovideosink
+"""
+
+
+class Player:
+    def __init__(self):
+        self.loop = GObject.MainLoop()
+        self.pipeline_src = Gst.parse_launch(PIPELINE_SRC)
+        self.pipeline_sink = Gst.parse_launch(PIPELINE_SINK)
+
+        self.rotate = self.pipeline_sink.get_by_name('rotate')
+        self.paused = 0
+        self.angle = 0
+
+        bus = self.pipeline_src.get_bus()
+        bus.add_signal_watch()
+        bus.connect('message::eos', self.on_eos)
+        bus.connect('message::error', self.on_error)
+        bus.connect('message::state-changed', self .on_state_changed)
+
+    def run(self):
+        self.pipeline_src.set_state(Gst.State.PLAYING)
+        self.pipeline_sink.set_state(Gst.State.PLAYING)
+        self.loop.run()
+
+    def quit(self):
+        self.pipeline_sink.set_state(Gst.State.NULL)
+        self.pipeline_src.set_state(Gst.State.NULL)
+        self.loop.quit()
+
+    def on_rotate(self):
+        self.angle -= pi / 100
+        self.angle %= 2 * pi
+        self.rotate.set_property("angle", self.angle)
+
+    def on_input(self):
+        print(self.paused)
+        if self.paused:
+            self.pipeline_src.set_state(Gst.State.PLAYING)
+        else:
+            self.pipeline_src.set_state(Gst.State.PAUSED)
+
+        self.paused ^= 1
+
+    def on_eos(self, bus, msg):
+        self.quit()
+
+    def on_error(self, bus, msg):
+        (err, debug) = msg.parse_error()
+        print("Error: %s" % err)
+        self.quit()
+
+    def on_state_changed(self, bus, msg):
+        if msg.src != self.pipeline_src:
+            return
+
+        old_state, new_state, pending = msg.parse_state_changed()
+        print("%s from %s to %s" % (msg.src.get_name(), old_state, new_state))
+
+
+def main():
+    player = Player()
+
+    def stdin_cb(source, condition):
+        source.readline()
+        player.on_input()
+        return True
+
+    def timeout_cb():
+        player.on_rotate()
+        return True
+
+    GObject.io_add_watch(sys.stdin, GObject.IO_IN, stdin_cb)
+    GObject.timeout_add(100, timeout_cb)
+
+    print("\nPress Enter to freeze the video\n")
+    player.run()
+
+
+if __name__ == '__main__':
+    sys.exit(main())