It is used to separate plugins in a pipeline. It may further be used for setting caps between plugins.
First, check that you can read images from both camera and sound from microphone. Assuming you locally connected to Nano with X running and sound working, you would try (use Ctrl-C for stopping):
# Cam1
gst-launch-1.0 -v v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! xvimagesink
# Cam2
gst-launch-1.0 -v v4l2src device=/dev/video1 ! image/jpeg,width=800,height=448,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! xvimagesink
# Audio
gst-launch-1.0 -v alsasrc device=hw:2 ! autoaudiosink
If all 3 work, you would first try to compose both videos, adding textoverlay on both and videobox on cam2. It has been succesfully tested on AGX Orin, not sure it works on Nano. So you would first boost Nano:
# Switch to MAXN mode
sudo nvpmodel -m0
# Boost clocks
sudo jeston_clocks
and measure the achieved framerate with fpsdisplaysink:
gst-launch -v \
v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! textoverlay text=\"cam1\" valignment=top halignment=right font-desc="Monospace, 5" name=overlay1 ! queue ! nvvidconv interpolation-method=5 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! queue ! comp.sink_0 \
v4l2src device=/dev/video1 ! image/jpeg,width=800,height=448,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! videobox left=-4 right=-4 top=-4 bottom=-4 ! textoverlay text="cam2" valignment=top halignment=right font-desc="Monospace, 10" name=overlay2 ! queue ! nvvidconv interpolation-method=5 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! queue ! comp.sink_1 \
nvcompositor name=comp sink_0::width=1920 sink_0::height=1080 sink_1::width=640 sink_1::height=360 sink_1::xpos=1266 sink_1::ypos=706 sink_1::zorder=2 ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! nvvidconv ! fpsdisplaysink text-overlay=0 video-sink=xvimagesink
If not working, you may try to decrease framerate to 30/1 (or less) if both your cameras support this.
Assuming it is working, you would encode video as H265 and add sound and mux both into mpegts. In order to check the stream, we will locally stream it using RTP/MP2T so that you’ll be able to check:
gst-launch -v \
v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! textoverlay text=\"cam1\" valignment=top halignment=right font-desc="Monospace, 5" name=overlay1 ! queue ! nvvidconv interpolation-method=5 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! queue ! comp.sink_0 \
v4l2src device=/dev/video1 ! image/jpeg,width=800,height=448,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! videobox left=-4 right=-4 top=-4 bottom=-4 ! textoverlay text="cam2" valignment=top halignment=right font-desc="Monospace, 10" name=overlay2 ! queue ! nvvidconv interpolation-method=5 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! queue ! comp.sink_1 \
nvcompositor name=comp sink_0::width=1920 sink_0::height=1080 sink_1::width=640 sink_1::height=360 sink_1::xpos=1266 sink_1::ypos=706 sink_1::zorder=2 ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! nvvidconv ! nvv4l2h265enc control-rate=1 qp-range="28,50:0,38:0,50" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! mux. \
alsasrc ! identity name=a_delay signal-handoffs=TRUE ! volume volume=1.0 ! audioconvert ! opusenc bitrate=320000 ! opusparse ! queue max-size-time=10000000000 max-size-buffers=1000 ! mux. \
mpegtsmux name=mux ! rtpmp2tpay ! udpsink host=127.0.0.1 port=5004
You would receive with:
gst-launch-1.0 -v udpsrc port=5004 ! application/x-rtp,encoding-name=MP2T,payload=33,clock-rate=90000 ! rtpjitterbuffer latency=200 ! rtpmp2tdepay ! tsparse ! tsdemux name=demux ! queue ! audio/x-opus ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux. ! queue ! video/x-h265 ! h265parse ! nvv4l2decoder ! nvvidconv ! xvimagesink
# or
ffmplay rtp://127.0.0.1:5004
# vlc may also work but may have worse performance
cvlc rtp://127.0.0.1:5004
If that works, you have most of the pipeline. What you may have to do is adapting the syntax from gst-launch to code pipeline. You would remove single quotes (these were used for preventing shell from interpreting the parenthesis), remove ‘\’ , and add a ‘\’ before double quotes inside the pipeline, and replace with appsink at the tail:
pipeline_str = "v4l2src device=/dev/video0 ! image/jpeg,width=1920,height=1080,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! textoverlay text=\"cam1\" valignment=top halignment=right font-desc=\"Monospace, 5\" name=overlay1 ! queue ! nvvidconv interpolation-method=5 ! nvvidconv ! video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1 ! queue ! comp.sink_0 v4l2src device=/dev/video1 ! image/jpeg,width=800,height=448,framerate=60/1 ! nvv4l2decoder mjpeg=1 ! nvvidconv ! videobox left=-4 right=-4 top=-4 bottom=-4 ! textoverlay text=\"cam2\" valignment=top halignment=right font-desc=\"Monospace, 10\" name=overlay2 ! queue ! nvvidconv interpolation-method=5 ! nvvidconv ! video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1 ! queue ! comp.sink_1 nvcompositor name=comp sink_0::width=1920 sink_0::height=1080 sink_1::width=640 sink_1::height=360 sink_1::xpos=1266 sink_1::ypos=706 sink_1::zorder=2 ! video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1 ! nvvidconv ! nvv4l2h265enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! mux. alsasrc ! identity name=a_delay signal-handoffs=TRUE ! volume volume=1.0 ! audioconvert ! opusenc bitrate=320000 ! opusparse ! queue max-size-time=10000000000 max-size-buffers=1000 ! mux. mpegtsmux name=mux ! appsink"