Documentation Index
Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt
Use this file to discover all available pages before exploring further.
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.
Transport modes
The same encoded stream out of MediaMTX can ride four transport modes. The agent exposes them as an interactive switcher so the GCS can pick the right one for the current operating environment without restarting the pipeline.| Mode | Path | Best for |
|---|---|---|
| RTSP local | Direct RTSP from the agent’s port 8554 | Bench, lab, anything on the same LAN as the drone. |
| WFB-ng long-range | Encoded H.264 piped to wfb_tx over the RTL8812EU air interface | Field flight, multi-kilometer range, line-of-sight. |
| WebRTC remote | WHEP from MediaMTX over WebRTC, one-port ICE on :8189 | Browser-based viewing on the local network with sub-200ms latency. |
| Cloud relay | RTSP push to the cloud relay, WebRTC out to authenticated browsers | Off-LAN viewing without exposing the drone’s IP, plus fleet aggregation. |
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?