Video Pipeline
The video pipeline takes a camera feed, encodes it to H.264 (or H.265), serves it locally via RTSP, and optionally transmits it over WFB-ng for long-range HD video or relays it to the cloud for remote viewing. The pipeline runs as theados-video systemd service and is enabled on Tier 3+ boards.
Pipeline flow
Camera (V4L2 or CSI) feeds into ffmpeg which encodes H.264. The encoded stream is pushed to MediaMTX, a lightweight RTSP/WebRTC server. From there, the stream can go three ways: over WFB-ng for long-range, via WebRTC/WHEP for LAN browsers, or through the cloud relay for remote access.Camera detection
The camera manager (camera_mgr.py) scans for cameras at startup:
- Checks
/dev/video*devices (V4L2) - Queries each with
v4l2-ctlfor capabilities - Filters for actual video capture devices (skips metadata-only nodes)
- Sorts by priority: CSI first, then USB
idle state and retries on USB hot-plug events.
Set
source: "test" to generate a test pattern without a physical camera. Useful for testing the pipeline end-to-end on a bench.Encoding
The encoder (encoder.py) builds an ffmpeg command line optimized for low latency:
| Flag | Purpose |
|---|---|
-fflags nobuffer | No input buffering |
-flags low_delay | Minimize encoder latency |
-probesize 32 | Minimal stream probe (skip auto-detection delay) |
-preset ultrafast | Fastest encode (lowest quality per bit, but lowest latency) |
-tune zerolatency | Disable B-frames and lookahead |
-profile:v high -level 4.1 | H.264 High Profile for browser compatibility (avc1.640029) |
-g 60 | Keyframe every 2 seconds at 30fps |
hw_video_codecs field.
H.264 vs H.265
H.264 is the default because it works everywhere. Browser-based players (MSE and WebRTC) expect H.264. H.265 saves roughly 30-50% bandwidth at the same quality, but WebRTC H.265 support in browsers is still inconsistent.MediaMTX
MediaMTX is a lightweight RTSP/WebRTC server bundled with the agent. The agent manages its lifecycle: starts it on boot, monitors it with a health check, and restarts it if it crashes. MediaMTX serves two protocols from the same stream:- RTSP at
rtsp://drone-ip:8554/camfor local network players (VLC, ffplay, GStreamer) - WHEP (WebRTC) at
http://drone-ip:8889/cam/whepfor browser-based playback with sub-200ms latency
:8189 simplifies firewall configuration. Both UDP and TCP ICE candidates use the same port.
Recording
The recorder module can save the encoded stream to disk:max_duration_minutes is reached.
Snapshots
Capture a JPEG snapshot from the live feed:/var/ados/recordings/ with a snap- prefix.
OSD overlay
The OSD module (osd.py) can burn telemetry data into the video frame: altitude, speed, battery, GPS coordinates, and flight mode. The overlay uses ffmpeg’s drawtext filter and pulls data from the state IPC socket.
Pipeline health monitoring
The video service includes a watchdog that checks:- Is the ffmpeg process alive?
- Is MediaMTX responding on its REST API (
localhost:9997)? - Is the camera device still present?