Dynamic data overlays

Hi

Because of a very tight garage door entrance I want to put 2 webcams (new C920) , a Raspberry Pi and 2 lidar tof (I2C) modules for distance. On my Android phone I want to display low latency split screen video with distance data overlaid. Eventually hopefully broadcasting this data to the car Android Auto screen if I can satisfy the requirements. I looked at fdsrc otherwise I am looking for pointers to the best solution. I am an embedded C programmer so I could delve into the source.

Thank you

developerR

Hello. I’m a hobbyist gstreamer user with a long reply for you lol.

tl;dr: Yes, you can do dynamic data overlays.

That is kind of a broad question but the project is totally doable. Especially if you are willing to write C-code and maybe use other software/frameworks alongside gstreamer.

Cameras:
Logitech C920 cameras can provide YUYV and MJPG and some variants even h264. If you want to draw the overlay on the raspberry pi you’ll have to decode the MJPG or H264. YUYV is limited to lower resolutions and/or framerates due to bandwidth limits on the USB connection.

Gstreamer pipeline and overlay:
Here’s a pipeline to get you started:
Server/pi

gst-launch-1.0 -v v4l2src device=/dev/video0 ! image/jpeg,width=1024,height=576,framerate=15/1 ! queue ! jpegparse ! v4l2jpegdec ! v4l2convert ! textoverlay text=HelloWorld halignment=center valignment=center ! v4l2h264enc ! 'video/x-h264,level=(string)5' ! queue ! h264parse config-interval=-1 ! tcpserversink host=0.0.0.0 port=4953

Client (computer running gstreamer):

gst-launch-1.0.exe tcpclientsrc host=<pi IP-address> port=4953 ! queue ! decodebin3 ! autovideosink

It runs on a pi4 with GStreamer 1.18.4 and uses a c920 camera. It takes the mjpg stream, decodes it in hardware. draws the text “helloworld” and then encodes it to h264, again in hardware, before making it available to the network with the tcpserversink.

If you were to write a gstreamer application in python or C you could change the text property in the textoverlay with g_object_set(). If you want graphics there is a plugin called cairooverlay. Alternatively you could write your own plugin and run it with gst-launch. Again there are many ways to do this. You could write a bin plugin that contains either the textoverlay element, or perhaps the cairooverlay element.

You would have to add a compositor to combine the video streams from your two cameras. If you want graphics you could do that in the compositor instead, as you can change pad properties much like the text property in textoverlay. And change the encoder and tcpserversink depending on how you choose to broadcast the video.

Broadcasting:
As for the client side. You could write a gstreamer app for android, I guess. But i would personally chose a way were you can just watch it in a browser on the client side. Like webrtc or mjpg. Here’s some external software that could help with that part. But Gstreamer does have webrtc plugins that you could look into.

Media MTX
go2rtc
ustreamer
mjpg-streamer (old and obsolete)
python + OpenCV w/ gstreamer support. (for easy drawing/textoverlay in openCV)

Sadly there is no mjpg http server plugin for gstreamer. Imo a mjpg stream is the best way to “stream video to a browser” on a local network were bandwidth usage doesn’t matter.

Raspberry Pi removed all hardware encoders and all but a h265 decoder on the Pi 5. But the Pi5 might be fast enough to do it all in software, just something to keep in mind.

If I were to do this project I would choose to write a gstreamer app in python. The app would do the compositing and overlay and convert to mjpg. Then feed that into a virtual v4l2 device (v4l2loopback via v4l2sink) and then let ustreamer host that video.

Good luck.

I’m doing similar right now although on a bit more complex hw… (xilinx zynqmp)

I think same approach should be working on RPi as well though and it is not that complicated.

Use kmssink for video and have it on the lower plane, this would be driven by one process.

Next, in another process, use some gfx lib (I’m using raylib with DRM backend but sdl, qt or so would work too I’m quite sure) and put it into a plane higher than the plane for video. Usually the gpu/display is merging higher layers ontop of the lower ones, and by having pixel alpha value set for transparency we get the gpu/display hw do the merge and things can run showing realtime video with overlays. On the poor ZynqMP the cpu is loaded like 2% perhaps and rest is done by hw.

Hi wilderness / saxofon
Thank you so much for your reply I missed your initial email and have been seriously distracted for the last several weeks but fortunately I am back on track with this project.
I bought new C920s so unfortunately they lack the onboard decoder.
I also bought 2 Pi4s after realising Pi5 lack the hardware encoder.
I was able can bring up the 2 cameras via udp etc with the latency being just acceptable. And bringing up static text was okay.
I looked at writing a I2C plugin but the compilation times are horrendous. The plugin would mimic the way the date and time gets passed to gstreamer. I got both meson / ninja and regular cmake setupup and compiling. I even setup a netbook with a lightweight Linux but again the compile times were unwieldy.

I have looked at both rtsp and WebRTC and in fact I have both gstreamer tutorial examples compiled and working on an android tablet.