fix(encode/nvenc): the host advertises what the driver lists, not a superset
Every NVIDIA host advertised a static H.264|HEVC|AV1 superset, so a 1st-gen Maxwell (GTX 960M, no HEVC/AV1 encode) offered HEVC — a client that believed it got ~15 s of blank video and a disconnect instead of a stream. Both OSes now ask the driver itself (nvEncGetEncodeGUIDs) on one throwaway direct-SDK session: Linux on the shared CUDA context, Windows on the selected render adapter, wired into host_wire_caps AND the GameStream serverinfo mask (which had been left on the superset for NVIDIA on both OSes). Fails open — an unanswerable probe keeps the historical superset, so it can only ever narrow the advertisement to codecs the GPU really encodes. The HEVC 4:4:4 answer rides the same session on Linux instead of opening a libav hevc_nvenc FREXT probe: that open is the prime suspect for the field bug where one probe wedges NVENC process-wide (NV_ENC_ERR_INVALID_VERSION on every later session until a host restart), and the direct backend re-checks the same caps bit at session open anyway. The ffmpeg probe remains only for hosts that really stream over libav (PUNKTFUNK_NVENC_DIRECT=0 or a build without the nvenc feature), where ffmpeg's NVENC client runs regardless. The 10-bit probe deliberately stays libav — Linux HDR rides the libav P010 path. On-hardware: .136 (RTX 5070 Ti) 14/14 nvenc tests in one process incl. the probe followed by real sessions and dirty teardown; .173 (Windows RTX) probe + 47 release lib tests. The Windows probe test documents the pre-existing MSVC debug-link failure (LNK2019 via the sdk crate's unused lazy loader) — run it with --release, the same reason windows-host.yml gates with clippy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 0346ec8090568eb499e8cb7d735305b28471185e)
This commit is contained in:
@@ -94,9 +94,20 @@ fn base_codec_mode_support() -> u32 {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
// Windows AMD/Intel (AMF/QSV): advertise only what the GPU actually encodes (AV1 is narrow, an
|
||||
// old iGPU might lack HEVC). AMF probes natively (no build feature needed); QSV needs the
|
||||
// libavcodec build. NVENC and the GPU-less software path keep the static superset.
|
||||
// Linux NVIDIA: the driver's own encode-GUID list (`nvenc_codec_support`, one throwaway
|
||||
// direct-SDK session, cached) — the same probe `host_wire_caps` consults, so both planes
|
||||
// stop advertising HEVC/AV1 on a chip without them (the GM107 dead-session field bug).
|
||||
// Fail-open like every arm here: an unanswerable probe → `probed_mask` = None → superset.
|
||||
#[cfg(all(target_os = "linux", feature = "nvenc"))]
|
||||
if !crate::encode::linux_zero_copy_is_vaapi() {
|
||||
if let Some(m) = probed_mask(crate::encode::nvenc_codec_support()) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
// Windows: advertise only what the GPU actually encodes (AV1 is narrow, an old iGPU might
|
||||
// lack HEVC, a 1st-gen-Maxwell NVENC is H.264-only). AMF probes natively (no build feature
|
||||
// needed); QSV needs the libavcodec or VPL build, NVENC the `nvenc` build. The GPU-less
|
||||
// software path keeps the static superset.
|
||||
#[cfg(target_os = "windows")]
|
||||
if crate::encode::windows_backend_is_probed() {
|
||||
if let Some(m) = probed_mask(crate::encode::windows_codec_support()) {
|
||||
|
||||
Reference in New Issue
Block a user