Skip to content

moq-video: remaining work (codecs, platforms, decode, HW validation) #1837

Description

@kixelated

Tracking issue for the gaps in moq-video after the ffmpeg removal + native-codec rework on dev. Audit done against rs/moq-video on the dev branch.

Current state:

  • Encode: H.264 via openh264 (software, all platforms), VideoToolbox (macOS), Media Foundation (Windows), NVENC + VAAPI (Linux, feature-gated, unverified). H.265 via VideoToolbox (macOS), Media Foundation (Windows), and NVENC (Linux, feature-gated, unverified).
  • Decode: H.264 via VideoToolbox (macOS), Media Foundation/DXVA (Windows), openh264 (software). H.265 via Media Foundation/DXVA (Windows) and VideoToolbox (macOS, feat(moq-video): H.265 hardware decode on macOS (VideoToolbox) #1859); no software fallback. In [Unreleased].
  • Capture: camera on all three platforms (AVFoundation / V4L2 / Media Foundation); screen capture on macOS (ScreenCaptureKit) and Windows (DXGI Desktop Duplication).

Decode

  • H.264 hardware decode on Windows (Media Foundation) - done in code (DXVA: NVDEC / Intel / AMD; GPU-less host falls back to openh264). In [Unreleased]; HW-validation pending.
  • H.264 hardware decode on Linux (NVENC/NVDEC, VAAPI, or V4L2)
  • H.265 hardware decode on macOS (VideoToolbox) - done in feat(moq-video): H.265 hardware decode on macOS (VideoToolbox) #1859 (verified end-to-end on Apple M4).
  • H.265 hardware decode on Windows (Media Foundation) - done in code (DXVA). In [Unreleased]; HW-unverified (test box had no HEVC decoder MFT installed).
  • H.265 hardware decode on Linux (NVDEC / VAAPI)
  • H.265 software decode - only if a backend with acceptable real-time performance and no licensing concerns exists; otherwise skip (do NOT add software HEVC decode just to fill the matrix)

Encode

  • Linux NVENC H.265 - done in feat(moq-video): NVENC H.265 encode + refresh README #1840 (codec GUID selected from Codec; HW-unverified)
  • Linux VAAPI H.265 - VAAPI backend advertises H.264 only today. Update: moq-vaapi 0.0.2 vendors HEVC buffer types (src/buffer/hevc.rs) but its Encoder is hardcoded H.264 (VAProfileH264Main / VAEntrypointEncSlice), so exposing an HEVC encoder is a moq-dev/vaapi change, not just a moq-video flag.
  • Software H.265 encode - explicitly out of scope (no software HEVC encode)

Robustness

  • NVENC driver-probe (avoid abort on GPU-less box) - done in fix(moq-video): probe NVIDIA driver libs before NVENC init (avoid abort on GPU-less box) #1844. Auto aborted under panic = "abort" when libcuda was missing because cudarc/the SDK panic! on a failed dlopen instead of erroring; Nvenc::open now probes libcuda / libnvidia-encode first and falls back cleanly.
  • VAAPI: make moq-vaapi dlopen libva (not a driver-probe) - the original premise was wrong. moq-vaapi 0.0.2 links libva (binary carries NEEDED libva.so.2 / libva-drm.so.2, verified via readelf), it does not dlopen it, and its Encoder::new returns a Result rather than panicking. So unlike NVENC there is no panic-on-miss to guard: a libva-less box fails at process load (before any Rust probe could run), and the no-GPU case (libva present, no usable VA driver) already falls back cleanly via Encoder::newErrbackend::open → openh264. A probe in open() can't help. Mitigated in feat(moq-video): opt-out nvenc/vaapi features (default-on) + correct libva docs #1860 (merged): corrected the docs that wrongly claimed dlopen, and made nvenc/vaapi default-on opt-out features so a self-compiler can drop the libva/CUDA deps (cargo build -p moq-cli --no-default-features --features "iroh quinn websocket capture"). Still open: the real fix is restoring the documented vaapi_dlopen design (no cargo:rustc-link-lib, no DT_NEEDED) in the separate moq-dev/vaapi crate, then adding the NVENC-style probe — only then does an always-on VAAPI binary load on a libva-less host.

Hardware validation (written but never run on real HW)

  • NVENC encode on a Linux + NVIDIA box - confirm pitch alignment, forced-IDR, the chosen cudarc/dlopen feature set, and H.265 VPS/SPS/PPS landing inline ahead of each IDR
  • VAAPI encode on a Linux + Intel/AMD box - low-power vs full entrypoint, NV12 upload round-trip, cargo deny license resolution
  • VAAPI zero-copy dmabuf input path - currently uses an NV12 surface-upload; add the Frame::DmaBuf + V4L2 VIDIOC_EXPBUF path for NV12-capable sources
  • Windows Media Foundation capture on real HW - on-demand open/close (LED off when unwatched), NV12 delivery for MJPEG/YUY2 cameras
  • Live camera run per platform - capture needs device permission a headless/agent process can't get

Capture

  • Screen/display capture on Linux (PipeWire/portal, or X11/DRM)
  • Screen/display capture on Windows (Desktop Duplication) - done in code (DXGI Desktop Duplication, whole-monitor). In [Unreleased]; compile-verified, HW-validation pending.

Codecs (new)

  • AV1 - returns when a hardware backend lands (NVENC/VAAPI AV1 on Linux). No software AV1 encode (rav1e too slow for real-time). Software AV1 decode only if perf + licensing are acceptable. Codec enum is #[non_exhaustive] so this is additive.
  • VP8 / VP9 - the hang catalog models them but moq-video has no path either way; track here, low priority

Other platform coverage (noted in DESIGN, lower priority)

  • Intel QSV-specific encode path (Intel currently goes through VAAPI)
  • Raspberry Pi v4l2m2m stateful encoder
  • iOS (VideoToolbox is available; not wired)

Docs


Constraints captured from the request: do not add software H.265/AV1 encode at all; only add software H.265/AV1 decode if a backend has good enough real-time performance and no licensing concerns.

(Written by Claude)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions