Raspberry Pi 5 Video Capture: Camera Module V3 Video Stream Latencies. Comparing UDP, TCP, RTSP, and WebRTC

by gektor650 in Circuits > Raspberry Pi

2037 Views, 0 Favorites, 0 Comments

Raspberry Pi 5 Video Capture: Camera Module V3 Video Stream Latencies. Comparing UDP, TCP, RTSP, and WebRTC

Screenshot 2024-04-14 at 19.23.11.png

Testing the best live-streaming options for the Raspberry Pi 5. I will compare a video live-stream latency and pick the best from the list.


We will use raspi-vid and MediaMTX to capture a video from Camera Module V3.


A video version of this instruction:


Supplies

IMG.jpg

Rasbperry PI and Camera Setup and Connect

imager.png

As an operating system, I have the latest official port of Debian Bookworm. I have zero custom setup; everything can be found in the official Raspberry Stores and Raspberry PI Imager.

Let’s start with the official Raspberry Camera Documentation and try some network stream recommendations.


https://www.raspberrypi.com/documentation/computers/camera_software.html

The left menu has an rpicam-vid item. Press it, and the page will scroll down to the necessary information. We can scroll a bit down to Network Streaming, and let’s try UDP stream.

I have two terminals. One will be connected to the Raspberry PI via SSH, and the other will run commands on a local machine.

Capture TCP Video Stream With a Default Codec

tcp-native.jpg

https://www.raspberrypi.com/documentation/computers/camera_software.html#tcp

The command to stream on Raspberry PI:

rpicam-vid -t 0 --width 1280 --height 720 --framerate 30 --inline --listen -o tcp://0.0.0.0:5556

The Raspberry PI will make a stream to its own port (I set 5556); any client can connect to it and receive a stream

As you can see, it sends some frames, and it stops and waits for a listener to receive the stream.

To show a stream on a laptop, we can use:

ffplay tcp://RASPBERRY_PI_IP_HERE:5556 -vf "setpts=N/30" -fflags nobuffer -flags low_delay -framedrop


The delay for TCP with a native codec is 0.5 seconds. (500 milliseconds)

Capture UDP Video StreamWith a Default Codec

UPD-native.png

https://www.raspberrypi.com/documentation/computers/camera_software.html#udp

The command to start a stream on a Raspberry PI is:

rpicam-vid -t 0 --width 1280 --height 720 --framerate 30 --inline -o udp://LAPTOP_IP_HERE:5555

We must replace LAPTOP_IP_HERE with a laptop IP address (not the Raspberry PI).

A port could be arbitrary. I used 5555.

As we can see, the Raspberry PI sends some frames to the laptop.

To play the video, we can run the ffplay command on the laptop:

ffplay udp://RASPBERRY_PI_IP_HERE:5555 -fflags nobuffer -flags low_delay -framedrop

Now, it’s time to see the performance.

I have a real-time camera that records the timer and sends a stream through the local network.

The UDP video delivery method has a 3.4-second delay. (3400 milliseconds)

Capture TCP Video Steam With a Libav Codec (mpegts)

tcp-libav.jpg

https://www.raspberrypi.com/documentation/computers/camera_software.html#network-streaming-with-libav

It’s a different video codec, and it could affect delays.

The command to run on a Raspberry PI:

rpicam-vid -t 0 --width 1280 --height 720 --framerate 30 --codec libav --libav-format mpegts --libav-audio -o "tcp://0.0.0.0:1234?listen=1"

The command to play it on a laptop:

ffplay tcp://RASPBERRY_PI_IP_HERE:1234 -vf "setpts=N/30" -fflags nobuffer -flags low_delay -framedrop


Surprisingly, LibAv has a huge delay—approximately 10.5 seconds. (10500 milliseconds)

We had half a second with a default codec and TCP, but now it is ten and a half.

Capture UDP Video Steam With a Libav Codec (Mpegts)

UDP-libav-delay.jpg

https://www.raspberrypi.com/documentation/computers/camera_software.html#network-streaming-with-libav

The command to run on a Raspberry PI:

rpicam-vid -t 0 --width 1280 --height 720 --framerate 30 --codec libav --libav-format mpegts --libav-audio  -o "udp://REPLACE_WITH_LAPTOP_IP:5555"

And player for a laptop:

ffplay tcp://RASPBERRY_PI_IP_HERE:1234 -vf "setpts=N/30" -fflags nobuffer -flags low_delay -framedrop

And now we have only half a second delay for UDP. (500 milliseconds)


These results are pretty strange. With the native codec, we had a huge delay in UDP and a small delay in TCP; with LibAV, we have the opposite.


Raspberry PI MediaMTX Setup

mediamtx.png

Finally, we are getting closer to our Raspberry PI winner of the stream latency: MediaMTX. This software can send a stream through all the protocols mentioned previously in the video and a few more. Let’s start with the set-up.

To install it, I need to do really simple steps:

  • First, open the release page on the GitHub.
  • Second, copy a link to an ARM64 archive. It’s essential to choose a proper version here.

  • Third, create a folder for it on the Raspberry PI.
mkdir mediamtx && cd mediamtx
  • Fourth, download it using the WGET command (find the latest link on GitHub).
wget https://github.com/bluenviron/mediamtx/releases/download/v1.7.0/mediamtx_v1.7.0_linux_arm64v8.tar.gz
  • Fifth, unarchive it to the same folder.
tar -xvzf mediamtx_v1.7.0_linux_arm64v8.tar.gz
  • Sixth, open the YML configuration file for editing.
nano mediamtx.yml
  • Seventh, scroll down and paste these configurations.
cam1:
runOnInit: bash -c 'rpicam-vid -t 0 --camera 0 --nopreview --codec yuv420 --width 1280 --height 720 --inline --listen -o - | ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1280x720 -i /dev/stdin -c:v libx264 -preset ultrafast -tune zerolatency -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH'
runOnInitRestart: yes

In a nutshell, the MediaMTX software will run this command in a bash.

Next, it asks the RPICAM-VID command (the same as we dealt with before) to send a stream to the FFMPEG.

And FFMPEG will send it to the MediaMTX via RTSP protocol, but locally.

We can save the configuration and run MediaMTX.

./mediamtx

The very first prints of it will have helpful information about protocol and ports that we can use.


Capture RTSP Stream Using MediaMTX

mediamtx-rtsp.jpg

Run MediaMTX from the previous step:

./mediamtx

Open a video player:

vlc rtsp://RASPBERRY_PI_IP_ADDRESS_HERE:8554/cam1

We have a delay of 1.3-1.4 seconds with this video stream. (~1300 milliseconds)

Capture WebRTC Stream Using MediaMTX

mediamtx-webrtc.jpg

Finally, we are closer to our winner. Let’s go back to the console and grab a port for WebRTC. In my case, it’s 8889.

To play it, I'll open this stream in the browser:

http://RASPBERRY_PI_IP_HERE:8889/cam1

In a moment, we have a stream.

Zoom out, and let’s review the delay.

It has an awesome 0.2 delay, which is a winner across all tests. (~200 milliseconds)