feat(stream): enable GPU libplacebo in prod image + gate to real GPU

Make libplacebo actually reachable in the shipped agent image, and refuse it
where it would be a regression.

Dockerfile (so a Vulkan-capable host can use the GPU tonemap path):
- install libvulkan1 (the Vulkan loader libplacebo links at runtime; ~150 KB)
- add 'graphics' to NVIDIA_DRIVER_CAPABILITIES so the nvidia container runtime
  mounts the Vulkan ICD (nvidia_icd.json + GLX libs) under --gpus all
Both are inert without a working Vulkan GPU — the functional probe gates use.

hls.go: gate libplacebo on a real HW encoder (HWAccel != none). A software-only
host with mesa would expose lavapipe (CPU Vulkan); the functional probe accepts
it but its tonemap is SLOWER than the zscale CPU chain, so libplacebo there is a
regression. No HW encoder -> stay on zscale.

Verified on the GPU dev box: nvenc session still picks libplacebo (-c:v
h264_nvenc -vf ...,libplacebo=...:tonemapping=bt.2390); new unit test locks the
software-encoder path onto zscale.
This commit is contained in:
Deivid Soto 2026-06-03 10:42:16 +02:00
parent cfaedb7f3b
commit 5e5a719f27
3 changed files with 47 additions and 9 deletions

View file

@ -1359,7 +1359,14 @@ func buildHLSFFmpegArgsAt(cfg HLSSessionConfig, probe *StreamProbe, tmpDir strin
// CPU chain; else play untonemapped (desaturated, last resort). Skip
// libplacebo on VAAPI: its Vulkan surface flow doesn't compose with our
// nv12+hwupload path, so VAAPI keeps the zscale-or-none behaviour.
useLibplacebo := probe.HDR != "" && cfg.Transcode.HasLibplacebo && codec != "h264_vaapi"
//
// Gate on a real HW encoder (HWAccel != none): only then is the Vulkan
// device a genuine GPU. A software-only host with mesa would expose lavapipe
// (CPU Vulkan), which the functional probe accepts but whose tonemap is
// SLOWER than the zscale CPU chain — so on those hosts libplacebo would be a
// regression. No HW encoder ⇒ stay on zscale.
useLibplacebo := probe.HDR != "" && cfg.Transcode.HasLibplacebo &&
codec != "h264_vaapi" && cfg.Transcode.HWAccel != HWAccelNone
tonemap := ""
if probe.HDR != "" && cfg.Transcode.TonemapHDR && !useLibplacebo {
tonemap = hdrTonemapChain