Hi there,
I have a 4Gb Jetson Nano and am trying to combine 4 webcams to stream using python / gstreamer to a more powerful machine with an RTX 2060 graphics card for processing using a Pytorch model.
The 4 webcams are identical. The video from each of them needs to be at 1920x1080 and 30fps. The webcams are only capable of serving at that rate using MJPEG.
My aim is to use the GPU in the Nano to take the load of merging the streams and encoding them in H264/5 to reduce the network traffic.
I am therefore attempting to use nvcompositor to merge the webcams, nvv4l2h264enc for encoding and rtph264pay to stream the video, but I can’t get it to work.
My python script is as follows:
import gi
import os
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
from gi.repository import Gst, GLib, GstRtspServer
os.environ['GST_DEBUG'] = '3'
Gst.init(None)
port = "8554"
mount_point = "/test"
server = GstRtspServer.RTSPServer.new()
server.set_service(port)
mounts = server.get_mount_points()
factory = GstRtspServer.RTSPMediaFactory.new()
width=1920
height=1080
factory.set_launch(f'nvcompositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_0::width={width} sink_0::height={height} '
f' sink_1::xpos={width} sink_1::ypos=0 sink_1::width={width} sink_1::height={height} '
f' sink_2::xpos=0 sink_2::ypos={height} sink_2::width={width} sink_2::height={height} '
f' sink_3::xpos={width} sink_3::ypos={height} sink_3::width={width} sink_3::height={height} '
f'! queue '
f'! nvvidconv '
f'! video/x-raw(memory:NVMM), format=NV12, width={width * 2}, height={height * 2}, framerate=30/1 '
f'! nvv4l2h264enc '
f'! rtph264pay '
f'v4l2src device=/dev/video0 io-mode=2 ! image/jpeg,width=1920,height=1080 ! nvv4l2decoder mjpeg=1 ! comp.sink_0 '
f'v4l2src device=/dev/video1 io-mode=2 ! image/jpeg,width=1920,height=1080 ! nvv4l2decoder mjpeg=1 ! comp.sink_1 '
f'v4l2src device=/dev/video2 io-mode=2 ! image/jpeg,width=1920,height=1080 ! nvv4l2decoder mjpeg=1 ! comp.sink_2 '
f'v4l2src device=/dev/video3 io-mode=2 ! image/jpeg,width=1920,height=1080 ! nvv4l2decoder mjpeg=1 ! comp.sink_3 ')
mounts.add_factory(mount_point, factory)
server.attach()
print ("stream ready at rtsp://127.0.0.1:" + port + "/test")
loop = GLib.MainLoop()
loop.run()
My problem is that when I run the script and try to connect to it using VLC all I get for output is the following:
stream ready at rtsp://127.0.0.1:8554/test
0:00:02.781204229 238 0x55816bfa30 FIXME rtspmedia rtsp-media.c:3841:gst_rtsp_media_suspend: suspend for dynamic pipelines needs fixing
0:00:02.827036565 238 0x7fa80d0f20 FIXME rtspmedia rtsp-media.c:3841:gst_rtsp_media_suspend: suspend for dynamic pipelines needs fixing
0:00:02.827096202 238 0x7fa80d0f20 ERROR rtspclient rtsp-client.c:2651:handle_setup_request: client 0x55816c8260: no control in path '/test'
I’ve seen a couple of other threads that relate to the ‘no control in path’ message, but I haven’t been able to use them to solve my issue.
The machine is running R32 (release), REVISION: 4.4, GCID: 23942405, BOARD: t210ref, EABI: aarch64, DATE: Fri Oct 16 19:44:43 UTC 2020
The python script is running in a docker container based on nvcr.io/nvidia/l4t-base:r32.5.0
The dockerfile is as follows:
FROM nvcr.io/nvidia/l4t-base:r32.5.0
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -y -qq update && apt-get install -y -qq xz-utils build-essential zlib1g-dev
RUN apt-get install -y -qq libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev
WORKDIR "/tmp"
RUN wget --quiet --no-check-certificate https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tar.xz && \
tar xf Python-3.8.10.tar.xz && \
cd Python-3.8.10 && ls -l && \
./configure --enable-optimizations && \
make && make install
WORKDIR /opt/venv
RUN python3 -m venv /opt/venv && \
. /opt/venv/bin/activate && \
python3 -m pip install --upgrade pip
RUN apt-get update && \
apt-get install -y libgirepository1.0-dev libcairo2-dev gir1.2-gstreamer-1.0 pkg-config python3-dev gir1.2-gtk-3.0 gir1.2-gst-rtsp-server-1.0 v4l-utils
WORKDIR /opt/CamStreamer
COPY ./ .
ENTRYPOINT [ "/opt/CamStreamer/entrypoint.sh" ]
RUN . /opt/venv/bin/activate && pip install -r requirements.txt
To run the docker container I use:
docker run --rm -it -p 8554:8554 -v "${THIS_DIR}/../app":/opt/CamStreamer \
--device /dev/video0 \
--device /dev/video1 \
--device /dev/video2 \
--device /dev/video3 \
cam-streamer "$@"
Any help would be very much appreciated.
Archie