vector-calls
The half of Vector's voice and video calls that runs anywhere: the wire format, the jitter buffer, bitrate control, and the small signal-processing pieces that need no device.
Everything that touches a microphone, a speaker, a codec library or a socket lives in the client that embeds this crate. vector-core runs the call itself (signalling, the Iroh connection, the call's state) on top of it with its calls feature, and each Vector client brings the devices.
There is no clock in here. Every function that reasons about time takes milliseconds from the caller, so the same code runs under tokio, on a plain thread, or in a browser, and the crate builds for wasm32-unknown-unknown.
What's inside
| Module | What it does |
|---|---|
wire |
The call's wire format over one QUIC connection: a reliable control stream (length-prefixed JSON Control messages), unreliable datagrams for audio (pack / unpack), and one stream per video frame (VideoHeader). |
jitter |
The adaptive jitter buffer: holds a few audio frames to smooth the network's unevenness, grows on late arrivals, and gives the latency back when the path settles. |
rate |
Bitrate control fed by QUIC's own loss accounting: RateControl walks the audio ladder (12 to 64 kbps, with FEC), VideoRate the camera and screen rungs. |
link |
The binary messages between the media engine and whatever captures, encodes, decodes and paints video. |
ring |
A lock-free, allocation-free sample ring for audio callbacks. |
resample |
A streaming linear resampler with no seam between blocks. |
declick |
Removes the click a microphone makes when its cable is pulled or pushed in. |
share |
A shared screen's sound on its way to the mixer. |
stats |
The per-call counters the media threads share. |
Audio runs at 48 kHz in 20 ms frames (ENGINE_RATE, FRAME_MS, FRAME).
The audio path
The sender packs each encoded 20 ms frame into a datagram. The receiver unpacks it into the jitter buffer and pulls one frame every 20 ms, and once a second it feeds QUIC's packet counts to the rate control, which tells the encoder when to change.
use ;
use RateControl;
use MediaStats;
use wire;
const MUTED: u16 = 1; // a flag your sender sets on silent frames
let stats = default;
let mut jitter = default;
let mut rate = new;
// Sender: one encoded frame per datagram.
let datagram = pack;
// Receiver: every datagram goes into the buffer...
if let Some = unpack
// ...and the playout clock takes one frame every 20 ms.
match jitter.pop
// Once a second, with the connection's cumulative packet counts.
if let Some = rate.observe
License
MIT