fix(host/serverinfo): don't advertise an empty codec mask when the VAAPI probe finds nothing
apple / swift (push) Successful in 54s
windows-host / package (push) Successful in 2m21s
android / android (push) Successful in 3m30s
ci / web (push) Successful in 26s
ci / docs-site (push) Successful in 27s
ci / rust (push) Successful in 5m56s
deb / build-publish (push) Successful in 3m9s
ci / bench (push) Successful in 4m40s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 6s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 4s
decky / build-publish (push) Successful in 11s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 3s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m47s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m51s
docker / deploy-docs (push) Successful in 17s

The Phase 3 GPU-aware codec mask (6922e1c) probes VAAPI on any non-NVIDIA host.
On a GPU-less box (CI container: no /dev/nvidia* -> `auto` picks VAAPI, but there's
no VA display) the probe returns all-false, so the mask was 0 -- the host
advertised NO codecs, and the serverinfo unit test failed.

Fall back to the static superset when the probe yields nothing (VAAPI wasn't
usable, not "the GPU encodes nothing"); quiet ffmpeg's expected "No VA display"
error during the probe; and assert the test against codec_mode_support() rather
than a hardcoded 65793 so it's deterministic regardless of the build host's GPU.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 11:52:17 +00:00
parent 6922e1c467
commit 333f66b45b
2 changed files with 27 additions and 6 deletions
+12 -4
View File
@@ -134,11 +134,19 @@ pub fn probe_can_encode(codec: Codec) -> bool {
return false; return false;
} }
unsafe { unsafe {
let hw = match VaapiHw::new(ffi::AVPixelFormat::AV_PIX_FMT_NV12, 640, 480, 2) { // A missing VA device (non-VAAPI host, GPU-less CI) is an expected probe outcome — quiet
Ok(hw) => hw, // ffmpeg's "No VA display found" error for the probe, then restore the level.
Err(_) => return false, let prev = ffi::av_log_get_level();
ffi::av_log_set_level(ffi::AV_LOG_FATAL);
let ok = match VaapiHw::new(ffi::AVPixelFormat::AV_PIX_FMT_NV12, 640, 480, 2) {
Ok(hw) => {
open_vaapi_encoder(codec, 640, 480, 30, 2_000_000, hw.device_ref, hw.frames_ref)
.is_ok()
}
Err(_) => false,
}; };
open_vaapi_encoder(codec, 640, 480, 30, 2_000_000, hw.device_ref, hw.frames_ref).is_ok() ffi::av_log_set_level(prev);
ok
} }
} }
@@ -61,7 +61,13 @@ fn codec_mode_support() -> u32 {
if caps.av1 { if caps.av1 {
m |= SCM_AV1_MAIN8; m |= SCM_AV1_MAIN8;
} }
return m; // Only trust a probe that actually found an encoder. An empty result means VAAPI wasn't
// usable at probe time (no VA display — a GPU-less CI box, or a misconfigured host), NOT
// that the GPU encodes nothing; advertise the static superset (pre-probe behaviour) rather
// than claiming zero codecs.
if m != 0 {
return m;
}
} }
SERVER_CODEC_MODE_SUPPORT SERVER_CODEC_MODE_SUPPORT
} }
@@ -99,6 +105,13 @@ mod tests {
https_port: 47984, https_port: 47984,
}; };
let xml = serverinfo_xml(&host, false); let xml = serverinfo_xml(&host, false);
assert!(xml.contains("<ServerCodecModeSupport>65793</ServerCodecModeSupport>")); // The mask is the GPU-aware value (NVENC/no-GPU → the static 65793; a VAAPI host →
// whatever it probes). Assert the XML embeds exactly what `codec_mode_support()` returns,
// so the test is deterministic regardless of the build host's GPU.
let mask = codec_mode_support();
assert!(mask != 0, "must advertise at least one codec");
assert!(xml.contains(&format!(
"<ServerCodecModeSupport>{mask}</ServerCodecModeSupport>"
)));
} }
} }