OUTPUT_MPLANE sizeimage hardcap of 65484 too small for real H.264 slices; libva resize gets clamped back #19
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
On higgs (Pi CM5, libva-v4l2-request-fourier driver tracing enabled), Firefox YouTube avc1 emits a stream of:
The libva driver detects a slice larger than the current OUTPUT-MPLANE buffer (72921 B > 65484 B), asks the kernel to grow the buffer to 147456 B via
VIDIOC_S_FMT, and the kernel returns the same fixed 65484 — the format setterdaedalus_fill_output_fmtignores userspace's requestedsizeimageand unconditionally pins it toDAEDALUS_MAX_BITSTREAM.Same cap is what
ffmpeg-fourier -hwaccel v4l2requestran into on the morning of 2026-05-22 (Failed to append 197516 bytes data to OUTPUT buffer N (3 of 65484 used)).Root cause
From
include/daedalus_v4l2_proto.h:74:From
kernel/daedalus_v4l2_main.c:120:The wire-protocol cap is the binding constraint: a payload > 64 KiB cannot fit in a chardev REQ_DECODE message, so the kernel cannot accept a larger OUTPUT bitstream even if vb2 allocated room for it.
Real-world H.264 slice sizes
64 KiB is below typical 720p I-frame size; the failure is structural, not a corner case.
Fix (proposed)
Bump
DAEDALUS_PROTO_MAX_PAYLOADto 1 MiB ininclude/daedalus_v4l2_proto.h. All existing allocations (kmemdup,kmalloc, daemonmallocof the read buffer) are sized to the actual payload at runtime; the only growth is the daemon's startup read buffer (one buffer per daemon process) and the V4L2 OUTPUT_MPLANE per-buffer size (kmalloc-able on aarch64 kernels; KMALLOC_MAX_SIZE is ~4 MiB on SLUB).Other V4L2 stateless decoders (cedrus, rkvdec, hantro) report 1-4 MiB OUTPUT_MPLANE sizeimage — 1 MiB is the conservative end of normal.
Wire protocol
Value change of a
#defineonly; no struct layout change. But the practical effect is bidirectional: a kernel running stale 64 KiB cap with a new 1 MiB-aware daemon (or vice versa) will reject the larger payloads. Lock-step install ofdaedalus-v4l2+daedalus-v4l2-dkmsis required, same shape as the PR-#7/#8 era.Reproduce
LIBVA_TRACE_BUFDATA=1(or any verbose libva-v4l2-request-fourier trace path)codec_store_buffer_ensure_capacity: kernel returned sizeimage 65484 < required Nlog lines once a slice exceeds ~64 KiB.Refs
include/daedalus_v4l2_proto.h:74— wire capkernel/daedalus_v4l2_main.c:120+:398— kernel cap + format-setter