Skip to content
Tzu Huan Tai edited this page Sep 20, 2024 · 16 revisions

This wiki provides comprehensive information on configuring and using the pi_webrtc for video streaming, along with detailed technical insights on encoders, signaling protocols, and recording options.

Outline

Flags

Available flags for pi_webrtc:

Option Default Description
-h, --help Display help information about the available options.
--fps 30 Set the camera frame rate (frames per second) via V4L2.
--width 640 Set the camera frame width (in pixels) via V4L2.
--height 480 Set the camera frame height (in pixels) via V4L2.
--rotation_angle 0 Set the rotation angle of the frame (0, 90, 180, 270) via V4L2.
--device /dev/video0 Set the specific camera device file.
--uid Set the unique identifier string for the device.
--stun_url stun:stun.l.google.com:19302 Set the STUN server URL for WebRTC. Example: stun:xxx.xxx.xxx.
--turn_url Set the TURN server URL for WebRTC. Example: turn:xxx.xxx.xxx:3478?transport=tcp.
--turn_username Set the TURN server username for WebRTC authentication.
--turn_password Set the TURN server password for WebRTC authentication.
--mqtt_port 1883 Set the MQTT server port.
--mqtt_host localhost Set the MQTT server host.
--mqtt_username Set the MQTT server username.
--mqtt_password Set the MQTT server password.
--record_path Set the path where recording video files will be saved. If the value is empty or unavailable, the recorder will not start.
--hw_accel Enable hardware acceleration by sharing DMA buffers between the decoder, scaler, and encoder to reduce CPU usage.
--v4l2_format mjpeg Set the V4L2 input format (i420, mjpeg, h264) if supported by the camera.

Note

The fps, width, and height settings might be reduced in the live stream due to network or device performance issues if detected by WebRTC. However, the recording will always maintain the same width and height.

Encoding Mode

The encoder used in WebRTC depends on whether the --hw_accel flag is set and the SDP context offered by the client. I recommend running v4l2-ctl -d /dev/video0 --list-formats-ext to check which formats your camera supports before specifying the V4L2 source format, allowing you to choose the most suitable encoding mode.

Tip

pi_webrtc delivers the best performance if your camera provides h264 streams.

Hardware (V4L2 H264)

Run with --hw_accel.

pi_webrtc will list only H264 in the SDP context. Hardware H264 encoding is only available on the Raspberry Pi 3, 4, and Zero 2. The Raspberry Pi 5 no longer supports the hardware encoder. For other single-board computers, such as Radxa, Odroid, etc., H264 hardware encoding may be supported according to their specifications. However, if their codecs do not implement the V4L2 driver, it is recommended to use Software encoding instead. The Raspberry Pi codec device files are located at:

Codec Location
decoder /dev/video10
encoder /dev/video11
scaler /dev/video12
  • For h264 camera source

    /path/to/pi_webrtc --device=/dev/video0 --fps=30 --width=1280 --height=960 --v4l2_format=h264 --hw_accel ...
    graph LR
    A(Camera) -- h264 --> B(hw decoder) -- yuv420 --> C(hw scaler) --yuv420--> D(hw encoder) --h264-->E(webrtc client)
    A --h264--> F(mp4)
    
    Loading

    This approach provides optimal performance.

    This command grabs the h264 stream directly from the camera and uses the hardware decoder to convert it to yuv420. If WebRTC detects network or device performance issues, the hardware scaler will automatically adjust by scaling down the decoded yuv420 frame resolution, and vice versa when conditions improve. When the resolution changes, the hardware encoder will be reset to match the new resolution. All frame data is transferred via DMA (zero-copy) between hardware codecs. Furthermore, if the --record_path flag is set (enabling recording), the h264 packets from the camera are directly copied into MP4 files.

  • For mjpeg camera source

    /path/to/pi_webrtc --device=/dev/video0 --fps=30 --width=1280 --height=960 --v4l2_format=mjpeg --hw_accel ...
    graph LR
    A(camera) -- mjpeg --> B(hw decoder) -- yuv420 --> C(hw scaler) --yuv420--> D(hw encoder) --h264-->E(webrtc client)
    B --yuv420--> F(openh264) -- h264--> G(mp4)
    
    Loading

    All processes are similar to the h264 source camera in hardware mode. The main difference is OpenH264 software encoder will be used in video recording.

  • For i420 camera source

    /path/to/pi_webrtc --device=/dev/video0 --fps=30 --width=640 --height=480 --v4l2_format=i420 --hw_accel ...
    graph LR
    A(camera) -- yuv420 --> C(hw scaler) --yuv420--> D(hw encoder) --h264-->E(webrtc client)
    A --yuv420--> F(openh264) -- h264--> G(mp4)
    
    Loading

    This command captures uncompressed yuv420 from the camera. Since it is uncompressed, the CSI/USB bandwidth may not support high resolution and fps. i420 is rarely used unless running on a Pi Zero 1 or if CPU usage is excessively high due to many background services. The OpenH264 software encoder will be used for video recording, but this method is typically chosen because of limited system resources, and the recorder is usually not enabled.

Software (H264/VP8/VP9/AV1)

Run without --hw_accel.

pi_webrtc will list all H264, VP8, VP9 and AV1 codecs in the SDP context. The encoder used depends on the SDP provided by the client. For example, if the client's SDP only includes H264, WebRTC will use the H264 encoder for live streaming. Make sure the client's SDP contains the only codec you want to use."

  • For h264 camera source
    /path/to/pi_webrtc --device=/dev/video0 --fps=30 --width=1280 --height=960 --v4l2_format=h264 ...
    It's not available in pi_webrtc. I didn't implement H264 software decoding.
  • For mjpeg camera source
    /path/to/pi_webrtc --device=/dev/video0 --fps=30 --width=1280 --height=960 --v4l2_format=mjpeg ...
    graph LR
    A(camera) -- mjpeg --> B(libyuv) -- yuv420 --> C(libyuv scaler) --yuv420--> D(openh264) --h264-->E(webrtc client)
    B --yuv420--> F(openh264) -- h264--> G(mp4)
    
    Loading
    It's suitable for most devices that do not support the V4L2 hardware encoder. The mjpeg frames will be decoded into yuv420 by libyuv. If WebRTC requires a lower resolution for live streaming, the scaling will also be handled by libyuv. The recording will use separate instances of the OpenH264 encoder.
  • For i420 camera source
    /path/to/pi_webrtc --device=/dev/video0 --fps=30 --width=640 --height=480 --v4l2_format=i420 ...
    graph LR
    A(camera) -- yuv420 --> C(libyuv scaler) --yuv420--> D(openh264) --h264-->E(webrtc client)
    A --yuv420--> F(openh264) -- h264--> G(mp4)
    
    Loading
    It's suitable only for devices with limited performance that do not support the V4L2 hardware encoder.

Signaling

MQTT

The diagram below shows how the connection process operates between the app client, MQTT server, and pi_webrtc when pi_webrtc is set with --uid=home-pi-5. The ${clientId} from the client side is another generated uid to identify each connection.

sequenceDiagram
Note over pi_webrtc, mqtt server: sub: home-pi-5/sdp/+/offer<br>sub: home-pi-5/ice/+/offer

client--> pi_webrtc: start connecting

Note over client, mqtt server: sub: home-pi-5/sdp/${clientId}<br>sub: home-pi-5/ice/${clientId}

client ->> mqtt server: client's SDP
Note over client, mqtt server: pub: home-pi-5/sdp/${clientId}/offer

mqtt server ->> pi_webrtc: client's SDP

pi_webrtc ->> mqtt server : pi's SDP
Note over pi_webrtc, mqtt server: pub: home-pi-5/sdp/${clientId}

mqtt server ->> client: pi's SDP

client ->> mqtt server: client's ICE
Note over client, mqtt server: pub: home-pi-5/ice/${clientId}/offer

mqtt server ->> pi_webrtc: client's ICE

pi_webrtc ->> mqtt server : pi's ICE
Note over pi_webrtc, mqtt server: pub: home-pi-5/ice/${clientId}

mqtt server ->> client: pi's ICE
client ->pi_webrtc: connected
Loading

Recording

The video files will be recorded every minute, and each video file will generate a snapshot image for preview. If the disk space falls below 400MB, it will start rotation.

Format
Video H264
Audio AAC

Misc

Other useful tools, commands, or information are not included in this project but are potentially useful.

Useful Commands

Command Description
v4l2-ctl --list-devices Show available devices in V4L2.
v4l2-ctl -d /dev/video0 --list-formats-ext Show supported formats for the camera /dev/video0.
sudo fdisk -l List partition tables to help set up USB disks.