PC based example GStreamer pipelines with GstQtOverlay
GStreamer Qt Overlay |
---|
Overview |
Getting Started |
Examples |
Performance |
Similar Solutions |
Troubleshooting |
FAQ |
Contact Us |
1. Display a text overlay
For this example, create a file named: "main.qml" with the following content:
import QtQuick 2.0 Item { id: root transform: Rotation { origin.x: root.width/2; origin.y: root.height/2; axis { x: 1; y: 0; z: 0 } angle: 180 } Text { text: "Way cool QT imaging with GStreamer!" font.pointSize: 30 color: "Black" objectName: "labelMain" } }
gst-launch-1.0 videotestsrc ! qtoverlay qml=main.qml ! videoconvert ! ximagesink
This will result on a window like on Figure 1.
2. Animated gif overlay
For this example, create a file named: "animation.qml" with the following content:
import QtQuick 2.0 Item { id: root transform: Rotation { origin.x: root.width/2; origin.y: root.height/2; axis { x: 1; y: 0; z: 0 } angle: 180 } Rectangle { width: animation.width; height: animation.height + 8 AnimatedImage { id: animation; source: "animation.gif" } Rectangle { property int frames: animation.frameCount width: 4; height: 8 x: (animation.width - width) * animation.currentFrame / frames y: animation.height color: "red" } } }
Then generate or download an animation ".gif" file and rename it as "animation.gif". This file will be used as the animation to be displayed from the QML file.
gst-launch-1.0 videotestsrc ! "video/x-raw, width=1280, height=720" ! qtoverlay qml=animation.qml ! videoconvert ! ximagesink
This is the result:
3. Using GstQtOverlay within a GStreamer application
This use case is applicable when using a pipeline within a GStreamer application, where the application should interact with the QML nodes to change them dynamically. For achieving it, please, take into account the qml-attribute.
1. Supposing you have the following QML file:
import QtQuick 2.0 Item { id: root transform: Rotation { origin.x: root.width/2; origin.y: root.height/2; axis { x: 1; y: 0; z: 0 } angle: 180 } Text { text: "Original!" font.pointSize: 30 color: "Black" objectName: "labelMain" } }
Please, notice that the objectName
is set to "labelMain"
. It works as an ID to identify the nodes within the QML file. These IDs should be unique within the file to avoid ambiguity.
2. You can create a QtOverlay element with the following instructions:
GstElement overlay; const gchar *factory = "qtoverlay"; overlay = gst_element_factory_make (factory, "overlay");
In the factory make, you need to pass the element name (findable by gst-inspect) and the name of the instance within the pipeline, respectively. After that, you can add it to a GstBin or a pipeline. This example can be easily applied to the NVIDIA Jetson platform. The differences will rely on the pipeline description within the application.
3. For dynamically changing the QML node "labelName"
, we can use the qml-attribute property. Reminding the syntax:
<item name>.<attribute name>:<value>
For changing the text of the node, it would be:
"labelMain.text:GStreamer with QT imaging is way cool!"
Programatically in the GStreamer application:
g_object_set (overlay, "qml-attribute", "labelMain.text:GStreamer with QT imaging is way cool!", NULL);
For example take this simple code segment:
import sys import gi import time import random from datetime import date from datetime import datetime gi.require_version('Gst', '1.0') from gi.repository import GLib, Gst Gst.init(sys.argv) class Pipeline: def __init__(self) -> None: self.overlay = None def pipeline_init(self): pipeline = "videotestsrc ! video/x-raw,height=500,width=600 ! qtoverlay qml=main.qml name=my_overlay ! videoconvert ! ximagesink" pipeline = Gst.parse_launch(pipeline) self.overlay = pipeline.get_by_name('my_overlay') pipeline.set_state(Gst.State.PLAYING) pipe = Pipeline() pipe.pipeline_init() stamp = date.today().strftime("%d/%m/%y") pipe.overlay.set_property("qml-attribute", "label_date.text:{}".format(stamp)) while True: input("Update?") now = datetime.now().strftime("%H:%M:%S") pipe.overlay.set_property("qml-attribute", "label_time.text:{}".format(now)) x_pos = random.random() y_pos = random.random() value = "{:.2f},{:.2f}".format(x_pos, y_pos) pipe.overlay.set_property("qml-attribute", "label_pos.text:{}".format(value))
Using the previous main.qml file, we get something like this:
4. From file with extra animations
For this example the same previous overall logic is used but with two major changes.
- Pipeline:
filesrc location=bbb_sunflower_1080p_60fps_normal.mp4 ! qtdemux name=demux demux.video_0 ! h264parse ! avdec_h264 ! videoconvert ! videoscale method=0 add-borders=false ! video/x-raw,height=500,width=600 ! qtoverlay qml=main.qml name=my_overlay ! videoconvert ! ximagesink
- Control code:
toggle = True counter = 9 while True: time.sleep(1) now = datetime.now().strftime("%H:%M:%S") pipe.overlay.set_property("qml-attribute", "label_time.text:{}".format(now)) x_pos = random.random() y_pos = random.random() value = "{:.2f},{:.2f}".format(x_pos, y_pos) pipe.overlay.set_property("qml-attribute", "label_pos.text:{}".format(value)) pipe.overlay.set_property("qml-attribute", "dot.color:{}".format("red" if toggle else "transparent")) toggle = not toggle if counter == 6: pipe.overlay.set_property("qml-attribute", "b3.color:{}".format("transparent")) elif counter == 2: pipe.overlay.set_property("qml-attribute", "b2.color:{}".format("transparent")) elif counter == 0: pipe.overlay.set_property("qml-attribute", "b1.color:{}".format("transparent")) elif counter < 0: pipe.overlay.set_property("qml-attribute", "b0.color:{}".format("red" if toggle else "white")) counter = counter - 1
5. Stream video over network from RSTP source
Let's assume:
SOURCE_ADRESS=rtsp://10.251.101.176:5004/test: origin rtsp video
DEST_ADRESS=10.251.101.57: destination computer/board
PORT=5004: source/dest port
On destination computer/board:
gst-launch-1.0 udpsrc buffer-size=57600 caps="application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)JPEG\,\ a-framerate\=\(string\)9.000000\,\ payload\=\(int\)26\,\ ssrc\=\(uint\)1563094421\,\ timestamp-offset\=\(uint\)3492706426\,\ seqnum-offset\=\(uint\)11616" ! rtpjpegdepay ! jpegparse ! avdec_mjpeg ! videoconvert ! xvimagesink -v sync=false async=false