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.
Figure 1. Simple example with label
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:
Figure 2. Simple example with animated gif
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:
Figure 3. Simple example with property change on runtime
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
Figure 4. Example with property change on runtime over more elements
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