A collection of tools for low-latency transmission of compressed images over wired and wireless networks using GStreamer and ROS 2.
This repository provides two solutions to efficiently transmit images between two computing units (PCs, servers, robots, etc.) using either a wired or wireless connection.
The two proposed approaches are:
- GStreamer-based video streaming
- ROS 2 image transport using FFmpeg compression
This repository provides a Docker environment to easily reproduce the image transmission experiments.
The Docker image contains all required dependencies, including ROS 2 Humble, FFmpeg image transport, GStreamer, and Cyclone DDS support.
To build the Docker image, run:
make buildAn interactive shell can be started with:
make shellStart a GStreamer sender:
make gstreamer_sender HOST=127.0.0.1Start a GStreamer receiver:
make gstreamer_receiverStart the H.264 encoder:
make ffmpeg_encoderStart the H.264 decoder:
make ffmpeg_decoderGStreamer is used to capture, compress, transmit, and decode video streams with low latency.
Before using GStreamer, identify the available video devices:
ls -l /dev/video*This command captures a local camera stream and displays it locally. It is only used to verify that the camera and GStreamer pipeline are working correctly:
gst-launch-1.0 v4l2src device=/dev/video6 ! \
video/x-raw,format=YUY2,width=1280,height=720,framerate=30/1 ! \
queue leaky=downstream max-size-buffers=1 ! \
videoconvert ! \
autovideosink sync=falseFor local testing, use:
host=127.0.0.1For communication between two computers, replace it with the receiver IP address:
udpsink host=<RECEIVER_PC_IP> port=5000gst-launch-1.0 -v \
v4l2src device=/dev/video6 ! \
video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1 ! \
videoconvert ! \
queue leaky=downstream max-size-buffers=1 ! \
x264enc tune=zerolatency speed-preset=ultrafast bitrate=4000 key-int-max=15 ! \
rtph264pay config-interval=1 pt=96 ! \
udpsink host=127.0.0.1 port=5000Main parameters:
tune=zerolatency: reduces encoding latencyspeed-preset=ultrafast: prioritizes speed over compression efficiencybitrate=4000: H.264 bitrate in kbpskey-int-max=15: controls keyframe interval
gst-launch-1.0 -v \
udpsrc port=5000 \
caps="application/x-rtp,media=video,encoding-name=H264,payload=96" ! \
rtpjitterbuffer latency=0 ! \
rtph264depay ! \
queue leaky=downstream max-size-buffers=1 ! \
avdec_h264 ! \
videoconvert ! \
fpsdisplaysink video-sink=autovideosink sync=false text-overlay=trueThe second approach uses ROS 2 image_transport with FFmpeg compression.
Install the required package:
sudo apt install ros-humble-ffmpeg-image-transportExample: compress a raw ROS 2 image topic using H.264:
ros2 run image_transport republish raw ffmpeg \
--ros-args \
--remap in:=/camera/camera/color/image_raw \
--remap out/ffmpeg:=/camera/color_ffmpeg \
-p out.ffmpeg.bit_rate:=400000 \
-p out.ffmpeg.encoder:=libx264 \
-p out.ffmpeg.qmax:=20 \
-p out.ffmpeg.gop_size:=10 \
-p out.ffmpeg.max_b_frames:=0 \
-p out.ffmpeg.encoder_av_options:="preset:ultrafast,tune:zerolatency"Decode the compressed stream back to a raw ROS 2 image:
ros2 run image_transport republish ffmpeg raw \
--ros-args \
--remap __node:=ffmpeg_decoder \
--remap in/ffmpeg:=/camera/color_ffmpeg \
--remap out:=/camera/color_raw \
-p in.ffmpeg.decoders.h264:=h264- Ubuntu 22.04
- ROS 2 Humble (for the FFmpeg ROS 2 option)
- GStreamer
- H.264 encoder/decoder support
Amaury Saint-Jore