fix(playback): stop random black frames on software GL in frame-copy

mpv's LUT scalers (the default lanczos/spline family) build their weight
texture from an uninitialized talloc_array: mp_compute_lut fills only
kernel->size of every stride floats, so each row's padding is heap
garbage (reinit_scaler in video/out/gpu/video.c, mpv 0.41 and master).
The LUT is an rgba16f texture sampled with linear filtering. When the
padding holds NaN, or a value large enough to become Inf as half-float,
Mesa's llvmpipe carries it through the zero-weight neighbour texel, the
weights become NaN and the frame clamps to pure black. Whether it happens
depends on heap contents, so the packaged smoke's paused frame was black
in most attempts on the CI runner.

Evidence from CI (8 repeats each, no retries): baseline 2/8 passed;
LUT-free bilinear scalers 8/8; gpu-dumb-mode 8/8; LP_NUM_THREADS=1 6/8.
A synchronous glReadPixels right after mpv_render_context_render()
showed the black frame already in the helper's FBO. The readback, the
shared-memory ring and the preload pump were correct.

On a CPU rasterizer the helper now selects mpv's LUT-free bilinear
scalers and disables sigmoid upscaling. Software GL cannot afford the
LUT scalers anyway. A session option for the same key still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-09-29 19:39:52 +02:00
1 parent 136c62915a
commit 893c9d62a6
6 files changed
+74 -19

No files matched your search

+6 -1
View File
@@ -91,7 +91,12 @@ exit. The retained handle still provides the actual exit code and signal.
The Linux portable build uploads `packaged-frame-copy-smoke` reports and traces
even when the smoke fails. Check the paused-frame screenshot and trace before
classifying a zero rendered-frame signal as an infrastructure flake.
classifying a zero rendered-frame signal as an infrastructure flake. A zero
signal also attaches `frame-copy-diagnostics` (the session's stream stats,
including mpv's drop counter, and each helper ring read from `/dev/shm`) and
`mpv-log`, the session's verbose mpv log. A `latestSeq` of 0 means the helper
never published; a `latestFrameSignal` of 0 means mpv rendered black; a
visible ring frame behind a black canvas points at the preload pump.
The Snap and Flatpak `--embedded-mpv-runtime-probe` launches in
`build-and-make.yaml` run under GNU `timeout --verbose -k 10 300` with
`ELECTRON_ENABLE_LOGGING=1`, so a main process that throws before app ready