Edge Overview
bilbycast-edge is a media transport gateway that bridges multiple protocols for professional broadcast workflows. Each node runs one or more flows, where a flow connects one or more inputs (one active at a time) to any number of outputs by reference. Inputs, outputs, and flows are independently managed entities — outputs can be reused across flows, and a flow with multiple inputs supports zero-gap hot switching between them.
Supported Protocols
Section titled “Supported Protocols”| Protocol | Input | Output | Notes |
|---|---|---|---|
| SRT | Yes | Yes | Caller, listener, rendezvous; AES encryption; Stream ID; 2022-7 redundancy; optional audio_encode + video_encode on TS; optional output delay |
| RIST | Yes | Yes | VSF TR-06-1 Simple Profile — NACK-driven retransmit, 2022-7 bonding, optional audio_encode + video_encode on TS, optional output delay |
| RTP | Yes | Yes | SMPTE 2022-1 FEC; unicast/multicast; DSCP QoS; optional audio_encode + video_encode on TS; optional output delay |
| UDP | Yes | Yes | Raw MPEG-TS; unicast/multicast; SMPTE 302M audio mode; optional audio_encode + video_encode on TS; optional output delay |
| RTMP/RTMPS | Yes | Yes | H.264 (FLV) and Enhanced-RTMP HEVC, AAC audio; publish to Twitch/YouTube/Facebook or ingest from OBS/ffmpeg; TLS; optional audio_encode + video_encode |
| RTSP | Yes | — | Pull H.264/H.265 from IP cameras; TCP/UDP transport |
| HLS | — | Yes | Segment-based egress; HEVC/HDR; MPTS filtering; optional audio_encode (AAC / HE-AAC v1/v2 / MP2 / AC-3) |
| CMAF / CMAF-LL | — | Yes | Fragmented-MP4 push with parallel HLS + MPEG-DASH manifests, chunked-transfer low-latency mode, ClearKey CENC (cenc / cbcs), optional audio_encode + video_encode |
| WebRTC | Yes | Yes | WHIP/WHEP via str0m; H.264 + Opus (H.264-only on egress — HEVC sources auto-transcoded); AAC→Opus via audio_encode |
| SMPTE ST 2110-20 | Yes | Yes | Uncompressed video, RFC 4175 YCbCr 4:2:2 8/10-bit, PTP, 2022-7 Red/Blue. Inputs need a compiled-in video encoder feature; outputs need only the default media-codecs feature |
| SMPTE ST 2110-23 | Yes | Yes | ST 2110-20 with 2SI and sample-row partition modes for higher resolutions/framerates |
| SMPTE ST 2110-30 | Yes | Yes | Linear PCM (L16/L24), 48k/96k, 1–16 channels, PM/AM packet times, SMPTE 2022-7 Red/Blue |
| SMPTE ST 2110-31 | Yes | Yes | AES3 transparent (Dolby E, etc.) — same wire framing as -30, preserves user/status/parity bits |
| SMPTE ST 2110-40 | Yes | Yes | RFC 8331 ancillary data (SCTE-104, SMPTE 12M timecode, CEA-608/708 captions) |
rtp_audio |
Yes | Yes | Generic RFC 3551 PCM over RTP — wire-identical to ST 2110-30 but no PTP requirement; transport_mode: "audio_302m" option on output for RTP/MP2T delivery |
| Bonded | Yes | Yes | Carrier-grade multi-path aggregation — N heterogeneous UDP / QUIC legs (cellular, Starlink, fibre); the default capacity-aware adaptive scheduler tracks each leg’s measured bandwidth and duplicates H.264/HEVC IDR frames across the two best legs for frame-accurate failover. Any inner protocol (SRT/RTMP/RTSP/ST 2110) can ride a bonded hop. See Multi-Path Bonding |
| SDI | Yes | Yes | Blackmagic DeckLink capture + playout (video + embedded audio, VANC SCTE-104/35, ATC timecode, CEA-608/708) via bilbycast-decklink-rs; ships in the *-full release (sdi-decklink feature, media-codecs required) |
| MXL | Yes | Yes | EBU / Linux Foundation Media eXchange Layer same-host shared-memory bus (mxl_video / mxl_audio / mxl_anc), PTP-required; off-by-default mxl feature. See MXL |
| Local display | — | Yes | HDMI / DisplayPort (KMS) + ALSA confidence-monitor playout — zero-copy VAAPI scanout, audio-master A/V sync; Linux-only display feature (on by default) |
test_pattern / media_player / replay |
Yes | — | Synthetic + local input types: colour-bar/tone generator, local-file playlist player (TS / MP4 / image), and recorded-clip replay. media_player/replay are default-on |
The default build includes the fdk-aac feature (Fraunhofer FDK AAC — AAC-LC, HE-AAC v1/v2, multichannel up to 7.1) and the media-codecs feature (FFmpeg libavcodec/libswscale for thumbnails, video decode, Opus/MP2/AC-3 in-process audio encode, and uncompressed ST 2110-20/-23 video decode). H.264/HEVC encoding requires opting into a video-encoder feature — video-encoder-x264 / video-encoder-x265 (GPL), video-encoder-nvenc, video-encoder-qsv, or video-encoder-vaapi. The *-full release channel bundles all five encoders (plus the matching HW decoders); the runtime probe auto-detects which the host can actually open.
Key Features
Section titled “Key Features”- Independent inputs / outputs / flows (config v2) — Each is a first-class entity with its own ID. Flows reference inputs and outputs by ID (
input_ids,output_ids). Outputs can be reused across flows; inputs can be pre-staged and attached on demand - Seamless input switching — Flows with multiple
input_idssupport zero-gap cutover viaPOST /api/v1/flows/{id}/activate-input. A sharedTsContinuityFixer(per flow) with per-input PSI caching creates a clean CC jump for receiver resync, injects the new input’s cached PAT/PMT stamped with a per-fixer monotonic version counter (so consecutive switches always produce a strictly-differentversion_numberand receivers always re-parse), and forwards immediately. NULL-PID keepalive padding goes out every 250 ms when the active input has no live packets, so downstream UDP sockets stay alive across switches to inputs whose source isn’t currently transmitting. Fully format-agnostic — inputs can use different codecs, containers, and transports (e.g., H.264 on one input, HEVC on another, JPEG XS on a third, uncompressed ST 2110 on a fourth) - Video transcoding — SRT, RIST, UDP, RTP, RTMP, and WebRTC outputs accept an optional
video_encodeblock. TS-carrying outputs run a streamingTsVideoReplacer(source →VideoDecoder→VideoEncoder→ re-muxed into TS, non-video PIDs untouched). RTMP H.264 uses classic FLV; RTMP HEVC uses Enhanced RTMP v2 (hvc1). WebRTC is H.264-only (browsers don’t decode HEVC) — HEVC sources are auto-transcoded. Encoders: libx264, libx265, NVIDIA NVENC, Intel QSV, or VAAPI, opt-in via Cargo features. Full matrix, per-codec defaults, and licence implications are documented inbilbycast-edge/docs/transcoding.mdin the repo - Output delay / path sync — SRT, RIST, RTP, and UDP outputs accept an optional
delayblock for synchronising parallel paths with different processing latencies. Three modes:fixed(constant ms delay),target_ms(target end-to-end latency — self-adjusting),target_frames(target latency in video frames using auto-detected frame rate, with optional ms fallback) - Audio gateway — Per-output PCM transcode (sample-rate / bit-depth / channel routing via rubato), IS-08 channel-map hot reload without restarting flows (matrix routing, 5.1→stereo BS.775 downmix, stereo→mono sum, mono→stereo split presets), SMPTE 302M LPCM-in-MPEG-TS on SRT / UDP /
rtp_audiooutputs for byte-identical interop withffmpeg -c:a s302mand broadcast hardware decoders — see Audio Gateway - Compressed-audio bridge — In-process AAC decoder (Fraunhofer FDK AAC by default — AAC-LC, HE-AAC v1/v2, multichannel up to 7.1;
symphoniafallback for AAC-LC mono/stereo) lands AAC contribution from RTMP / RTSP / SRT / UDP / RTP-TS as PCM on the ST 2110-30/-31,rtp_audio, and SMPTE 302M outputs (Phase A). Optionalaudio_encodeblock re-encodes audio to AAC-LC, HE-AAC v1/v2 (in-process FDK AAC), or Opus, MP2, AC-3 (in-process libavcodec on the defaultmedia-codecsbuild; ffmpeg subprocess fallback) on RTMP, HLS, WebRTC, SRT, UDP, RTP, and RIST outputs. Marquee chain: AAC RTMP contribution → Opus WebRTC distribution in one edge process - SMPTE ST 2110 — Phase 1: audio essences (-30 PCM, -31 AES3) and ancillary data (-40). Phase 2: uncompressed video (-20 RFC 4175, -23 with 2SI and sample-row partition modes). Best-effort PTP integration via external
ptp4lmanagement socket. SMPTE 2022-7 Red/Blue dual-network support everywhere - SMPTE 2022-1 FEC — Forward Error Correction for RTP (encode + decode) and SRT (wire-compatible with libsrt 1.5.5 row/staircase/2D modes)
- SMPTE 2022-7 hitless redundancy — Dual-leg input merging for seamless failover; also available inside the RIST protocol layer as native bonding
- Multi-path bonding — A third bonding option for N ≥ 2 heterogeneous UDP / QUIC legs (5G + Starlink + fibre), distinct from SRT socket groups and RIST 2022-7. The default capacity-aware
adaptivescheduler discovers each leg’s usable bandwidth and splits the stream to track it while duplicating H.264/HEVC IDR frames across the two best legs; the bond layer itself is transport-agnostic and can carry SRT, RTMP, RTSP, ST 2110, or any other inner protocol — see Multi-Path Bonding - Flow groups —
start_flow_group/stop_flow_groupmanager commands bring up multi-essence broadcast bundles (audio + ANC + video) all-or-nothing in parallel; failures roll back every started member - NMOS IS-04 / IS-05 / IS-08 + BCP-004 — Broadcast control system integration with multi-essence audio/data/video resources, audio channel mapping, and BCP-004 receiver capability constraint sets
- mDNS-SD discovery — Best-effort
_nmos-node._tcpregistration for automatic NMOS controller discovery - TR-101290 analysis — Transport stream quality monitoring
- RP 2129 trust boundary — Inter-arrival time, PDV, source filtering metrics
- WebRTC via str0m — WHIP/WHEP support, HEVC→H.264 auto-transcode on egress
- Media analysis — Per-program PID breakdown for MPTS inputs (codec, resolution, frame rate, audio format) surfaced in the manager UI
- MPTS ↔ SPTS — Full multi-program transport stream passthrough on UDP/RTP/SRT/RIST/HLS, with per-output
program_numberdown-selection to extract any single program as a rewritten SPTS. RTMP/WebRTC outputs and thumbnails lock onto a chosen program deterministically - Flow Assembly (PID bus) — Build a fresh MPEG-TS (SPTS or MPTS) from elementary streams pulled off any of a flow’s inputs: mix video from input A with audio from input B, compose a multi-program feed from N different sources, or stand up a pre-bus hitless merger between two ingress legs. Every output type consumes the assembled TS unchanged. PCM / AES3 inputs (ST 2110-30/-31,
rtp_audio) become TS carriers via input-levelaudio_encode(AAC-LC / HE-AAC v1/v2 / SMPTE 302M). The plan is hot-swappable at runtime viaUpdateFlowAssembly— unchanged slots keep running, PMT version bumps mod 32, PAT only when the program set changes. See Flow Assembly (PID Bus) - Node Bus — cross-flow ES routing — The PID bus is node-wide: any flow’s assembly can pull elementary streams from inputs owned by sibling flows on the same edge, with a master-clock identity preflight that refuses cross-PTP-domain / cross-PCR-PLL combinations before the WS round-trip. One edge becomes a full distribution matrix — fan one input’s program out to N flows, change source per-output without dropping any other flow. The manager UI surfaces this as the Node Bus Matrix — a three-pane crosspoint authoring surface (Sources / Matrix / Inspector) with click-to-wire + drag-and-drop, pending-state diffing, and salvo export to a Switcher preset
- PES Switch — access-unit-aligned splice —
SlotSource::Switchslots acceptsplice_mode = "pes_aligned"(defaultpmt_bump). Audio splices hold the outbound stream at the from-leg’s last fully-emitted PES boundary then concatenate the to-leg’s first PES whose PTS is monotonically past — glitchless on real receivers when both sources are coherent content. Video splices wait for the next H.264 / HEVC IDR. AAC ADTS, AAC LATM, H.264 SPS, and HEVC SPS sentinels refuse the splice on codec-parameter mismatch and fall back to PmtBump with a structured Warning event. Per-switchsplice_mode_overrideonActivateInputlets operators force one strategy for a single take without changing the assembly - Thumbnail generation — Per-flow 320×180 JPEG thumbnails generated in-process via libavcodec on the default
media-codecsbuild. Flow-levelthumbnail_program_numberpicks which MPTS program the preview shows - Cross-node egress alignment — Two edges forwarding the same contribution feed can be placed on one shared timeline, so they emit the same content at the same wall instant and a downstream switcher can cut between them without a timing discontinuity. Configured per UDP/RTP output as an
epoch_lockblock; the shared timeline is minted by the manager, since no single node can derive one that does not carry its own ingest latency. Scope is deliberately narrow — single-input, single-program, non-transcoded forwarding with the source clock passed through. See Aligned Output - Egress + ingress de-jitter — Per-output
egress_pacing(forward/pcr/servo) chooses when datagrams hit the wire, with an optional servo cushion; per-inputingress_dejitter_msrecovers the source rate from inter-PCR observations and releases packets at that rate, so analysers, the PCR PLL, the PID bus and every downstream output see a smooth cadence regardless of network jitter. Both are ordinary manager-configurable fields — see Configuration
Deployment Options
Section titled “Deployment Options”- Standalone — No external dependencies, run with a local config file
- With API auth — OAuth 2.0 client credentials for Prometheus and external monitoring
- Managed — Connected to bilbycast-manager for remote configuration and monitoring
- Browser setup — Field deployment via web-based setup wizard at
/setup
Architecture
Section titled “Architecture”The system is organized into three planes:
| Plane | Purpose |
|---|---|
| Control | REST API, authentication, configuration, manager commands |
| Data | Packet processing, protocol I/O, FEC, redundancy, tunnels |
| Monitor | Lock-free metrics, dashboard, Prometheus endpoint |
Each flow has an input task connected to N output tasks via a broadcast::channel. Outputs are independent — a slow output drops packets rather than blocking the input or other outputs.
Quick Start
Section titled “Quick Start”cargo build --release./target/release/bilbycast-edge --config config.jsonSee Configuration for the full config reference and Your First Flow for a walkthrough.