feat(moq-video)!: make hardware encoders always-on (openh264 stays the software fallback)#1819
Merged
Conversation
Co-authored-by: moq-bot[bot] <186640430+moq-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Luke Curley <kixelated@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…7.3 (#1790) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…1792) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: moq-bot[bot] <186640430+moq-bot[bot]@users.noreply.github.com>
… aarch64-linux (#1793) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
#1806) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Bring main's recent fixes onto dev. Most of main's commits since the last sync were already present on dev (latency-range playback, relay credential-expiry close, moq_json command routing, peer_identity), so the net new content is: - CI: adopt main's crane-based Rust checks (clippy/doc/test via `nix flake check`), replacing dev's per-runner CARGO_TARGET_DIR scheme (#1801). - moq-native: combine main's session-flap backoff (#1806) with dev's reconnect session-state tracking. Conflicts resolved in favor of dev's newer moq-net API and input/output signal structure; main's overlapping changes were the same features in the older shape. Removed a duplicate PeerIdentity block that auto-merge concatenated in tls.rs. Regenerated Cargo.lock. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hardware encoders are now always-on and the only ones in a default build: VideoToolbox (macOS), Media Foundation (Windows), and NVENC + VAAPI (Linux, previously behind opt-in `nvenc`/`vaapi` features). The openh264 software encoder moves behind a new opt-in `software` feature (off by default), so a GPU-less box without it gets `NoEncoder` rather than silently falling back to software. - moq-video: drop the `nvenc`/`vaapi` features and cfg-gate NVENC/VAAPI on Linux; add `software = ["dep:openh264"]`; `Kind::Auto` no longer falls back to software unless the feature is on. Remove `publish = false`. - NVENC: consume nvidia-video-codec-sdk with default-features off so the crate's `cuda-version-from-build-system` default stays off; we pin the CUDA version via cudarc's `cuda-12020`. Repin the patched fork to the reviewed dynamic-loading commit. - moq-boy: enable the `software` feature (its 160x144 frames are too small for some hardware encoders). - moq-cli: drop the `--software` flag; capture builds are hardware-only. - Docs/comments updated (lib, frame, captures, DESIGN, cli.md, flake/overlay). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-32ccb0 # Conflicts: # nix/overlay.nix
`cargo sort --check` (just ci) requires alphabetical order within each dependency table; the new Linux target deps weren't sorted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ting Making hardware encoders always-on means Kind::Auto (the default) tries NVENC on every Linux build. cudarc and the NVENC SDK dlopen their driver libraries lazily and panic (which aborts the process under release's `panic = "abort"`) when a library is absent, so a GPU-less Linux box would crash in CudaContext::new instead of falling back to the next encoder, contrary to this PR's own claim. Probe libcuda and libnvidia-encode with libloading before touching either crate and return Error::Codec when missing, so backend::open moves on. Adds a Linux test asserting open() errors rather than panics when the driver is absent. Verified GPU-less in podman (cargo test -p moq-video --all-features). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 tasks
Making hardware encoders always-on is the right call, but gating openh264 behind an opt-in `software` feature meant a GPU-less box got NoEncoder by default, and Kind::Software / `--software` stopped working without it. Keep hardware always-on but restore openh264 as the always-compiled fallback. - Drop the `software` feature; openh264 is a non-optional dependency again. - backend::open always registers the openh264 SOFTWARE candidate, so Kind::Auto falls back to it and Kind::Software always opens. - Remove the now-unnecessary `feature = "software"` cfgs (the surface-download path in frame.rs is live again; the software encoder tests run again). - moq-cli regains `--software`; moq-boy drops the (now nonexistent) feature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-32ccb0 Brings the branch up to date with dev (HEVC #1802, native H.264 decode #1796, async device capture #1807, srt/rtmp/rtc egress) and keeps this PR's deltas: NVENC/VAAPI always-on for Linux, openh264 always-on (no `software` feature), publish=false removed, the nvidia-video-codec-sdk fork repinned to the hardened dynamic-loading commit (default-features off), and the NVIDIA-probe fallback. Note: restores dev's H.265/HEVC codec-aware encode path (Codec enum, codec-aware backend selection, hev1 producer) that the previous branch merge had dropped by taking "ours" wholesale. Verified: clippy -D clean, 19 moq-video tests pass (incl. H.265 roundtrips), sort/taplo/fmt clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kixelated
pushed a commit
that referenced
this pull request
Jun 21, 2026
dev advanced 3 commits while this PR was open (#1845 PTS-exposing TS Export + PCR-paced SRT egress, #1847 moq-lite-05 wire sync, #1819 always-on hardware encoders). Re-merged dev and reconciled two conflicts: - nix/overlay.nix: kept this PR's cargo+sccache CI direction (dev's tip still carries the crane `moqChecks`; the cargo switch lives on main, #1821). - rs/moq-mux/src/container/ts/export.rs: combined dev's #1845 Frame-returning `Export::next` (PTS/keyframe-stamped) with this PR's generic `catalog::Catalog` trait (main's #1815 mpegts rename). Updated the moq-cli drain helper to read `frame.payload` and refreshed two stale `scte35::Ext` comments. Verified: moq-mux (279), moq-cli, moq-srt tests pass; workspace clippy -D warnings and fmt clean (excluding the crates that need libva/gstreamer system libs unavailable in this sandbox: moq-video/libmoq/moq-boy/moq-gst); JS type-checks and biome clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BQ9o9paZnRLpYRgbyjUwFV
Merged
kixelated
added a commit
that referenced
this pull request
Jun 21, 2026
#1819 made the NVENC/VAAPI hardware encoders always-on for Linux, which also made libva a hard runtime dependency of every Linux moq-video binary (moq-vaapi 0.0.2 links libva: NEEDED libva.so.2 / libva-drm.so.2). Give self-compilers a way to drop the CUDA / libva deps without changing the default. moq-video: reintroduce `nvenc` and `vaapi` features (the Linux deps become optional), both in `default`, gating the backend modules + candidates with `#[cfg(all(target_os = "linux", feature = ...))]`. Default builds are unchanged; `--no-default-features` (or dropping one feature) builds without the corresponding dep. openh264 stays the always-compiled software fallback and V4L2 capture is unaffected. Consumers: the workspace moq-video dep is now `default-features = false` (mirroring moq-native), so each binary opts in. libmoq and moq-boy enable both encoders; moq-cli exposes default-on `nvenc`/`vaapi` passthroughs so a `capture` build can drop them: cargo build -p moq-cli --no-default-features --features "iroh quinn websocket capture" Verified: macOS builds all affected crates (features are no-ops off Linux); a Linux container compiles `moq-video --no-default-features` WITHOUT libva-dev and the default (nvenc+vaapi) WITH it; `cargo tree` confirms the feature resolution for every consumer scenario. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hardware encoders become always-on across all platforms, while openh264 remains the always-compiled software fallback so a GPU-less box still encodes.
nvenc/vaapifeatures), matching how VideoToolbox (macOS) and Media Foundation (Windows) already worked. Both still dlopen their drivers at runtime, so a binary links on a GPU-less builder and runs on a machine with no GPU.Kind::Autoprefers a hardware encoder and falls back to openh264 when none is usable;Kind::Software/Kind::Named("openh264")always work. (Nosoftwarefeature: I don't want a build that can't encode at all.)panic = "abort") when their library can't be dlopen'd, so always-on NVENC would crashKind::Autoon every GPU-less Linux box.Nvenc::opennow probes libcuda + libnvidia-encode withlibloadingfirst and returnsErr, sobackend::openfalls back to openh264. Verified GPU-less in a Linux container.publish = falseremoved frommoq-video(the remaining functional publish blocker is the nvidia fork, see below).Consumers
Kind::Softwaredirectly (its 160x144 Game Boy frames are small enough that hardware encoders may reject them); openh264 being always-on means no special feature wiring.--hardware(force hardware, error if none) and--software(force openh264).NVENC plumbing
NVENC's always-on build depends on the
dynamic-loadingfeature ofnvidia-video-codec-sdk, consumed via the existing[patch.crates-io]fork branch (reviewed/hardened: per-OS library resolution, no default-build cudarc regression, MSRV-safelibloading0.8). Consumed withdefault-features = falsesocuda-version-from-build-systemstays off and the CUDA version is pinned via cudarc'scuda-12020(no CUDA toolkit needed to build).Public API changes (breaking)
moq-videofeaturesnvencandvaapiare removed; those backends are unconditional on Linux now.moq_video::encode::Kind::Autonow tries the platform hardware encoders before openh264 (on Linux it previously needed thenvenc/vaapifeatures to try them at all).Kind::Software/ moq-cli--softwarevs the pre-PR baseline (openh264 stays always-on).Per the branch-targeting rules this is a breaking change to a library crate, hence targeting
dev.Test plan
cargo check/clippy/fmtclean for moq-video, moq-cli--features capture, moq-boy;cargo test -p moq-video(10 tests, incl. the openh264 software paths).cargo clippy -p moq-video --all-targets -- -D warningsclean andcargo test -p moq-video --locked(8 tests) pass — includingsoftware_encoder_emits_annexb(openh264 always compiled) andmissing_driver_errors_instead_of_panicking(NVENC falls back, no abort).Cross-package sync
Docs updated:
doc/bin/cli.md,rs/moq-video/DESIGN-native-codecs.md, and in-crate doc comments (lib, frame, captures, encoder).(Written by Claude)