Skip to content

Codec Matrix

The release binary bundles every video encoder + decoder backend the edge knows about — libx264, libx265, NVIDIA NVENC + NVDEC, Intel QSV (x86_64 only), and VAAPI. At startup the hardware probe walks the active set, opens a minimal session against each, and advertises capability bits on HealthPayload.capabilities for the ones that actually work on this host. The manager UI keys per-output codec dropdowns off those bits.

This page covers the static support matrix, the *_auto resolver that does the right thing without operator hand-holding, and the verification commands for confirming what activated on a given host.

Pick *_auto unless you have a reason not to

Section titled “Pick *_auto unless you have a reason not to”

For most operators the right answer on video_encode.codec is h264_auto or hevc_auto. The edge resolves Auto on flow start against the host’s probed capabilities and the requested chroma + bit-depth, picking the cheapest backend that handles the combination:

Family + chroma + bit-depthResolver chain (head → tail)
H.264 + 4:2:0 + 8-bit (the dominant distribution path)NVENC ≻ QSV ≻ VAAPI ≻ libx264
H.264 + anything elselibx264 (no HW H.264 backend supports 4:2:2 / 10-bit / 4:4:4)
HEVC + 4:2:0 + 8-bitNVENC ≻ QSV ≻ VAAPI ≻ libx265
HEVC + 4:2:0 + 10-bitNVENC ≻ VAAPI ≻ QSV ≻ libx265
HEVC + 4:2:2 + 8-bitVAAPI (Intel iHD) ≻ libx265
HEVC + 4:2:2 + 10-bitVAAPI (Intel iHD) ≻ libx265
HEVC + 4:4:4 (any)libx265 (HW backends reject NV24 today)

Operators who need wire-level reproducibility (compliance deployments, vendor-specific bitstream behaviour) pick an explicit backend — the manager UI cross-validates the chroma + bit-depth combo before flow start, so an invalid combination fails at save time, not at flow bring-up.

Video encode — pixel-format / bit-depth matrix

Section titled “Video encode — pixel-format / bit-depth matrix”
Backend4:2:0 / 84:2:2 / 84:2:0 / 104:2:2 / 104:4:4
libx264 (CPU, video-encoder-x264)
libx265 (CPU, video-encoder-x265)
h264_nvenc (NVIDIA, video-encoder-nvenc)
hevc_nvenc (NVIDIA, video-encoder-nvenc)
h264_qsv (Intel, video-encoder-qsv)
hevc_qsv (Intel, video-encoder-qsv)
h264_vaapi (Linux, video-encoder-vaapi)
hevc_vaapi (Intel iHD Tiger Lake+)✗ (NV24 deferred)
hevc_vaapi (AMD radeonsi)usually ✗usually ✗

Implication for broadcast 4:2:2 contribution: on NVIDIA-only and AMD-only hosts there is no GPU path for 4:2:2 10-bit; libx265 is the only option. Intel Tiger Lake+ iGPUs have the full broadcast HEVC matrix through VAAPI.

Static rejection happens at config validation and at encoder open, so an operator who bypasses the manager UI still gets a precise error before any frame is encoded.

BackendDisplay output (KMS)TS → TS transcodeNotes
libavcodec (CPU)✓ (fallback)✓ (universal)Every format, every bit-depth.
NVDEC (video-decoder-nvdec)✓ zero-copy scanoutx86_64; 4:2:0 only.
QSV decode (video-decoder-qsv)x86_64; 4:2:0 only.
VAAPI decode (video-decoder-vaapi)✓ zero-copy DMA-BUFLinux; Intel iHD does 4:2:2 + Main10.

Auto resolution priority — both the display path and the transcode input-decode path share the same priority:

VAAPI ≻ NVDEC ≻ QSV ≻ CPU

The display path also relies on KMS atomic-commit zero-copy via DRM PRIME (see Display Output); the transcode path doesn’t get the same fast scanout but still benefits from offloading decode to dedicated silicon.

CodecEncodeDecodeSample ratesChannelsNotes
AAC-LCFDK-AAC in-process (fdk-aac)FDK-AAC8 k – 48 k1 – 8Production AAC, lowest latency.
HE-AAC v1FDK-AACFDK-AAC8 k – 48 k1 – 2SBR adds chroma-bandwidth dependency.
HE-AAC v2FDK-AACFDK-AAC8 k – 48 k2 (stereo only)Parametric Stereo — manager UI hard-filters mono.
Opuslibopus via libavcodeclibopus via libavcodec48 k1 – 2Decode wired; transcode-from-Opus-on-TS works.
MP2libavcodeclibavcodec32 k / 48 k1 – 2DVB-T / SD broadcast.
AC-3libavcodeclibavcodec32 / 44.1 / 48 k1 – 6 (5.1)ATSC / Blu-ray.
E-AC-3(passthrough only)libavcodec1 – 7.1UHD ATSC 3.0.
PCM (ST 2110-30 / -31)passthroughpassthrough48 k / 96 k1 – 16Hardcoded sample-rate in config.
SMPTE 302Minline muxinline demuxmatches inputmatches inputtransport_mode: audio_302m on SRT / UDP / rtp_audio.

Capability strings on HealthPayload.capabilities

Section titled “Capability strings on HealthPayload.capabilities”

Edges advertise the following when the matching feature is compiled in and the runtime probe finds the underlying driver / GPU usable. Anything missing is disabled in the manager UI dropdowns with a tooltip.

CapabilitySourceMeaning
video-encodeany of x264 / x265 / nvenc / qsv / vaapiEdge can re-encode video at all.
video-encoder-x264video-encoder-x264libx264 available.
video-encoder-x265video-encoder-x265libx265 available.
video-encoder-nvencvideo-encoder-nvenc + probeh264_nvenc / hevc_nvenc available.
video-encoder-qsvvideo-encoder-qsv + probeh264_qsv / hevc_qsv available.
video-encoder-vaapivideo-encoder-vaapi + probeh264_vaapi / hevc_vaapi available.
video-decoder-nvdecvideo-decoder-nvdec + probeNVDEC available (transcode + display).
video-decoder-qsvvideo-decoder-qsv + probeQSV decode available.
video-decoder-vaapivideo-decoder-vaapi + probeVAAPI decode available.
displaydisplay + ≥ 1 KMS connector enumeratedLocal-display output usable.
fdk-aacfdk-aacIn-process AAC family.
media-codecsmedia-codecs (default on)libavcodec video decode + Opus / MP2 / AC-3.
webrtcwebrtc (default on)WHIP / WHEP supported.
tlstls (default on)HTTPS + RTMPS.
replayreplay (default on)Recording + clip playback.

The resource_budget.hw_encoder_chroma block on the same payload carries the per-(codec, chroma, bit-depth) matrix with one boolean per cell — that’s the source of truth the manager UI reads when graying out 4:2:2 chroma against NVENC.

Static support is one thing; what your host actually opens at runtime is another. Common combinations:

Host classAuto resolves to (H.264 4:2:0 8-bit)Auto resolves to (HEVC 4:2:2 10-bit)
x86_64 NVIDIANVENClibx265 (NVENC rejects 4:2:2)
x86_64 Intel Tiger Lake+ iGPUQSV (or VAAPI if explicitly preferred)VAAPI (iHD does 4:2:2 + Main10)
x86_64 AMDVAAPIlibx265 (AMD radeonsi rejects 4:2:2)
aarch64 NVIDIA JetsonNVENClibx265
aarch64 AMD APU SBCVAAPIlibx265
Headless / no GPUlibx264libx265

Verification — confirm Auto activates the right backend

Section titled “Verification — confirm Auto activates the right backend”
  1. Inspect the host capability matrix. Start the edge and curl /api/v1/stats/health (or open the manager Node detail → Resources card):

    Terminal window
    curl https://edge:8443/api/v1/stats/health \
    -H "Authorization: Bearer $TOKEN" | \
    jq '.resource_budget.hw_encoder_chroma'

    On Tiger Lake+ Intel iHD: hevc_vaapi_yuv422_10bit = true. On AMD radeonsi: hevc_vaapi_yuv422_10bit = false. On any host with NVENC: every hevc_nvenc_yuv422_* cell is false.

  2. Confirm Auto resolution lands on the expected backend. Create a flow with video_encode.codec = "h264_auto", chroma yuv420p, 8-bit. Watch the edge logs for:

    video_encode auto-resolved 'h264_auto' → <backend>

    On an NVIDIA host this prints → nvenc_h264; on Intel Tiger Lake+ → qsv_h264 (or → vaapi_h264 with explicit preference); on AMD → vaapi_h264; on a host without any compiled-in HW backend that the probe could open → libx264.

  3. Confirm an invalid combination is rejected up front. Create a flow with video_encode.codec = "h264_nvenc", chroma yuv422p. The manager preflight returns HTTP 422 + error_code: encoder_chroma_not_supported before the WS round-trip — the flow never reaches the edge.

  4. Confirm HW transcode decode activates. Set video_encode.hw_decode = "auto" (the default) on a flow that decodes a source video. Edge logs:

    ts_video_replace: opened HW decoder (backend=Vaapi)

    (or Nvdec / Qsv). Running perf top against the edge process should show av_hwframe_transfer_data in the hot path (sysmem download) but no libavcodec_decode_h264 — the decode itself ran on the GPU.

Per-flow cost units scale with pixel rate. The HW vs SW base is the dominant axis: HW backends start at base 100, software at base 500.

units = base × (width × height × fps) / (1920 × 1080 × 30)
× 1.5 if bit_depth == 10
× 1.33 if chroma == yuv422p
× 2.0 if chroma == yuv444p

Examples:

ProfileApproximate units
1080p25 H.264 4:2:0 8-bit on NVENC~83
1080p50 H.264 4:2:0 8-bit on NVENC (3G-SDI tier-1)167
1080p59.94 H.264 4:2:0 8-bit on NVENC200
1080p50 HEVC 4:2:2 10-bit on NVENC (broadcast contribution)313
4K30 H.264 4:2:0 8-bit on NVENC400
1080p50 H.264 4:2:0 8-bit on libx264833
4K50 HEVC 4:2:2 10-bit on libx265 (broadcast contribution)~6 650
4K59.94 HEVC 4:2:2 10-bit on libx265 (broadcast contribution)~7 980
4K59.94 HEVC 4:2:0 8-bit on libx265~4 800

The per-host budget is 1000 + 200 × physical_cores, so a 4-core edge gets 1 800 units, a 32-core EPYC gets 7 400. See Resources & Capacity for the per-family HW session caps and how oversubscription is surfaced.