Files
punktfunk/crates
enricobuehler abc6d790bd feat(client): make concealed decodes visible instead of silently erasing them
libavcodec reports reference damage by LOGGING and then concealing: HEVC's `Error
constructing the frame RPS`, `First slice in a frame missing`, `Previous slice
segment missing` (hevcdec.c) and H.264's reference-list equivalents all emit at
AV_LOG_ERROR and then hand back a frame and a success code. Every one of them means
the picture on screen was built from references the decoder could not resolve.

We threw all of it away. `quiet_ffmpeg_log()` set libavcodec's level to fatal-only,
which silences its stderr sink, and we installed no callback — so the messages went
nowhere. Worse, `decode_frame`'s Ok arm then RESET the failure streak, so a decoder
concealing every other frame looked healthier than one erroring occasionally: it
never asked for an IDR, and under the infinite GOP nothing else would, so the damage
stayed for the life of the session.

Now: a real av_log callback routes libavcodec into tracing (these lines are decode
evidence and belong in the log a field report ships us) and counts ERROR-and-worse.
`decode_frame` brackets each AU; a backend that returns a frame while that counter
moved decoded something libavcodec itself called broken, and we ask for a keyframe.

Concealment gets its OWN counter, deliberately not the hardware-demotion streak. An
ordinary packet loss conceals every AU until the requested IDR lands — at 120 fps a
100-300 ms round trip is 12-36 frames, well past VAAPI_DEMOTE_AFTER and past
HW_DEMOTE_MIN_STREAK too if that IDR is itself lost. Feeding it there would demote a
healthy decoder for surviving a lossy second.

Scope, stated plainly: this catches the class libavcodec KNOWS about. It does not
catch a driver that returns wrong pixels without complaint, which is what the
Windows FFmpeg-Vulkan reports look like — and that class has no in-band signal at
all today. Verified against FFmpeg n8.1 source: vulkan_decode.c calls
ff_vk_exec_pool_init(..., nb_queries=0, ...), so VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR
— the only channel a Vulkan driver has to report a failed decode — is never read;
and neither h264dec.c nor hevcdec.c ever sets AV_FRAME_FLAG_CORRUPT. Closing that
needs an upstream patch, not a client change.

Verified on BOTH platforms, because the callback's va_list parameter is the one part
whose ABI differs and a wrong one faults inside libavcodec at call time rather than
failing to build: Linux 117/117 (linux/amd64 container) + clippy --all-targets
-D warnings clean; Windows 109/109 against FFmpeg n8.1.2 on the CI runner, where
`installing_the_log_callback_is_safe_and_idempotent` drives a real av_log through
libavcodec's dispatcher into our callback.
2026-08-05 09:03:07 +02:00
..