fix(stream): functional libplacebo probe + benchmark hardening
Review (critico) caught a regression: the prod agent image ships a BtbN GPL ffmpeg with libplacebo COMPILED IN but no Vulkan runtime (debian-slim, no libvulkan1/mesa-vulkan-drivers/nvidia ICD). The presence probe (ffmpeg -filters) would flip HasLibplacebo on, the filter's Vulkan device creation would fail at runtime, and HDR sources that previously tonemapped via zscale would break. - FFmpegSupportsLibplacebo now RUNS the filter on one synthetic frame and requires a clean exit (forces Vulkan device init + filtergraph negotiation), so it is honest about THIS host: works on Vulkan-capable hosts, falls back to zscale where Vulkan is absent. Logs the real ffmpeg error on failure. - Warm the libplacebo (Vulkan init ~1.7s) + zscale caches in a background goroutine at startup so the first stream session doesn't pay the probe and risk its setup timeout. - Benchmark: margin 1.5x -> 2.0x (the probe measures encode only; real decode of HEVC/10-bit + busier content needs more headroom), per-probe timeout 12s -> 6s + overall 45s -> 20s (it blocks registration on software hosts), and a 'no rung measured' case (missing lavfi/wedged ffmpeg) now keeps the 1080 default instead of flooring at 480 — an infra failure isn't a slow host. Verified e2e on the fixed binary: LOTR Two Towers (HEVC 3840x1608 10-bit HDR10/PQ, 12GB) on desktop-Chrome caps -> hls, ffmpeg runs h264_nvenc with -vf ...,libplacebo=...:format=yuv420p:tonemapping=bt.2390 (zscale chain replaced), 45 fMP4 segments, ffprobe confirms output h264 yuv420p bt709 (tonemapped from bt2020/smpte2084), no ffmpeg errors.
This commit is contained in:
parent
ef3b190e0b
commit
cfaedb7f3b
4 changed files with 102 additions and 21 deletions
|
|
@ -160,12 +160,27 @@ func runDaemonStart() error {
|
|||
// HW encoders return 2160 instantly; a software-only host runs a bounded
|
||||
// encode benchmark so a weak NAS/CPU reports the rung it can actually
|
||||
// sustain (720/480) and the web side routes oversized sources to an
|
||||
// external player instead of a stuttering transcode. Own timeout — the 10 s
|
||||
// probeCtx above is sized for the quick diagnostic, not three encode rungs.
|
||||
benchCtx, benchCancel := context.WithTimeout(context.Background(), 45*time.Second)
|
||||
// external player instead of a stuttering transcode. This blocks
|
||||
// registration on a software host, so it's bounded tight (3 rungs × 6 s =
|
||||
// 18 s worst case; <1 s on a capable box that passes the first rung). Own
|
||||
// timeout — the 10 s probeCtx above is sized for the quick diagnostic.
|
||||
benchCtx, benchCancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
maxTranscodeHeight := engine.BenchmarkMaxTranscodeHeight(benchCtx, ffmpegResolved, hwAccelPick)
|
||||
benchCancel()
|
||||
|
||||
// Warm the tonemap capability caches off the hot path. The libplacebo probe
|
||||
// actually RUNS the filter (Vulkan device init ~1.7 s), so doing it lazily
|
||||
// in buildTranscodeRuntime would tax the FIRST stream session and risk its
|
||||
// setup timeout. A real session arrives seconds-to-minutes after startup, so
|
||||
// a background warm has finished by then; if one races in first, the cache's
|
||||
// own mutex makes the concurrent cold call safe (both compute the same bool).
|
||||
if cfg.Download.Transcode.Enabled && ffmpegResolved != "" {
|
||||
go func() {
|
||||
engine.FFmpegSupportsLibplacebo(ffmpegResolved)
|
||||
engine.FFmpegSupportsZscale(ffmpegResolved)
|
||||
}()
|
||||
}
|
||||
|
||||
// Create daemon config
|
||||
daemonCfg := agent.DaemonConfig{
|
||||
AgentID: cfg.Agent.ID,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue