ampere-av1 Phase 2.1 + 3 diagnostic: log which control failed validation
on S_EXT_CTRLS rejection so debug iterations can identify the offending
CID without strace. Pre-validation failures (error_idx >= count) log as
"<pre-validation>" with the syscall errno surfacing the root reason.
Already informative on ampere — surfaces the pre-existing benign H264 +
HEVC device-init failures on the vpu981 AV1 fd as count=2 / failed_cid=0
(those go through (void)cast at context.c:450/473 by design).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tests mechanism 5 (silent partial failure). If error_idx != count after
S_EXT_CTRLS, one of the per-request controls was rejected by the kernel
even though the ioctl returned 0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sonnet review 7.3 / 9.6 from iter1 + carried iter2/3/4 substrate.
Two libva driver_data instances in the same process (e.g. Firefox
playing two tabs at different resolutions, or Firefox + mpv via the
same dlopened backend) would race on the static cache.
Move to struct request_data.last_output_width/height. The V4L2
device fd is already per-driver_data, so this is the correct binding
unit (one fd, one current OUTPUT format).
Verified: two concurrent mpv processes (2s stagger) both decode
300 frames cleanly with no cross-corruption. Same-instant init still
hits kernel-level fd contention on /dev/video1 (hantro is a
single-instance device); cross-process serialization is out of scope
for a libva backend.
Resolves the surface_reset_format_cache() callsite: now takes
driver_data parameter (was zero-arg).
Also drops the 'rc' unused-variable warning in v4l2_ioctl_controls
that the iter5 sweep left behind.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
h264.c:
- Remove the slice_header parse success log (the parse data is now
forwarded into decode_params directly without per-frame echo). Keep
the FAILED-rc log since it indicates a real decode-blocking error.
- Remove the iter1 patch-0014 VAPictureH264 byte-dump + field-read
log block. The TopFieldOrderCnt=65536 anomaly it diagnosed was
resolved by the POC sentinel strip (h264_strip_ffmpeg_poc_sentinel)
that stays in the codebase.
surface.c:
- Remove the per-call "RequestSyncSurface RETURN status=" trace.
- Remove the per-call "RequestSyncSurface early-exit" trace.
v4l2.c:
- Suppress the per-frame "Unable to get control(s): Permission denied"
log when errno == EACCES (the expected case on this hantro rig
per iter1 patch-0014's findings). The one-time announcement in
h264.c stays. Real EACCES-on-non-request-fd or other errno values
still log normally.
Per-frame v4l2-request log noise drops from ~30+ lines/frame to
init-time + once-per-resolution-change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes iter3 Y2 v1 (S_EXT_CTRLS rejected logging) + iter4 Y2 v3
(TRY_EXT_CTRLS retry) + iter4 per-control TRY isolation. With the
frame-11 EINVAL fix landed in iter4 (385dee1), these diagnostics no
longer fire under expected workloads, and they're noise for any
upstream submission.
If a future EINVAL re-introduces, the per-control TRY isolation
pattern is documented in feedback_kernel_obfuscation_compound.md and
can be re-applied surgically.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Iterates each control individually through VIDIOC_TRY_EXT_CTRLS on
S_EXT_CTRLS EINVAL. Used in iter4 Phase 4 to diagnose the carryover
frame-11 EINVAL: discovered all four H.264 controls fail individually
on the same request_fd → diagnosis pivot from "bad control content"
to "bad request_fd state," which led to the fresh-request_fd-per-frame
fix in 385dee1.
Stays in for the iter5 DEBUG sweep alongside iter1 ENTER traces +
iter3 Y2 + iter4 Y2v3 + iter4 DPB census.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per kernel comment in v4l2-ctrls-api.c:222-224, S_EXT_CTRLS deliberately
obfuscates by setting error_idx = count, while TRY_EXT_CTRLS reports
the actual failing index. Adds TRY retry inside the EINVAL diagnostic
path.
Empirical finding (iter4 Phase 4): TRY also returned error_idx == count
on the frame-11 EINVAL on bbb_1080p30. Conclusion: failure is in the
post-validate cluster commit (hantro driver's try_ctrl op or similar
state-coherence check), NOT in any individual control's std_validate.
The kernel comment may be outdated for compound controls, or the
H.264 stateless cluster is committed atomically post-validate where
error_idx is intentionally not updated for either S or TRY.
Path forward (Phase 4 next): switch from "read kernel source" to
"diff our DECODE_PARAMS construction vs FFmpeg's libavcodec/v4l2_request_h264.c"
to identify field-by-field divergence at frame 11.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When VIDIOC_S_EXT_CTRLS returns -EINVAL, log num_controls, error_idx,
and per-control id+size. Lets iter3+ debug "Unable to set control(s):
Invalid argument" failures by naming exactly which control set was
rejected — previously the request_log line in v4l2_set_controls just
printed strerror(errno) with no specificity.
Used in iter3 Phase 7 to confirm the frame-11 EINVAL is request-level
("error_idx == num_controls" sentinel = kernel rejected but couldn't
pinpoint a single field) rather than a single-control size mismatch.
To remove at iter4 DEBUG sweep alongside iter1 ENTER/CAPTURE-dump
instrumentation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pure utility additions, no behaviour change. Three helpers in
src/v4l2.{c,h}:
- v4l2_query_ext_ctrl(): wraps VIDIOC_QUERY_EXT_CTRL by CID.
Returns 0 if the control exists, -1 if not. Caller passes NULL
qec to test existence only.
- v4l2_query_menu(): wraps VIDIOC_QUERYMENU at a given index.
Returns 0 if a menu item exists at that index, -1 otherwise.
- v4l2_ctrl_menu_has_value(): convenience layered on the above.
For a menu/intmenu-type control, walks all menu items between
minimum and maximum and returns true iff `value` is a valid
entry. Used by callers that ask "does this driver accept menu
value X for this CID?" without caring about iteration details.
These unblock commit 3 (request_pool — needs ext-ctrl probing for
codec-ops dispatch) and commit 4 (probe-then-set DECODE_MODE/
START_CODE — replaces 0002's unconditional set with a real probe)
of the upstreamable design's six-commit series.
Forward-declarations in v4l2.h keep the header lean: existing
prototypes already use opaque struct v4l2_ext_control * pointers
without including <linux/videodev2.h>; we follow the same
convention for struct v4l2_query_ext_ctrl and struct v4l2_querymenu.
No call sites added in this commit. Compile-only verification:
the .so links cleanly with three new exports.
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
Compound patch carrying the fork's pre-Step-1 substrate, originally
authored by Jernej Škrabec / fourier on top of bootlin's a3c2476:
- src/h264.c + src/picture.c: V4L2_CID_MPEG_VIDEO_H264_* renamed to
V4L2_CID_STATELESS_H264_*, struct shapes tracked to mainline
(V4L2_CID_STATELESS_H264_DECODE_MODE/_START_CODE added to the
passthrough shim).
- include/hevc-ctrls.h: redirect shim to <linux/v4l2-controls.h>
(kernel-side HEVC controls now live in the canonical UAPI header).
- src/meson.build: src/h265.c / src/h265.h commented out — HEVC
build path is excluded from this fork (RK3568 hantro G1/G2 has
no HEVC, and the kernel-side HEVC controls have a separate
rework in flight upstream).
- src/tiled_yuv.S: aarch64 stub for tiled_to_planar (assembly
source was sunxi-cedrus armv7-only; aarch64 needs a stub to keep
the build linking).
- include/h264-ctrls.h: removed (dead post-fourier — no source
includes it; the passthrough shim's CID aliases live in the
kernel header now).
Functionally equivalent to the prior fork master commits:
c1f5108 V4L2_PIX_FMT_H264_SLICE rename
4ccbfe9 Strip HEVC build path
da9f2a5 include/h264-ctrls.h passthrough + CID aliases
fc4bb10 src/h264.c track upstream UAPI shape
13e9b64 src/h264.c drop num_slices field
4d14ffb src/tiled_yuv.S aarch64 stub
1b02c9b src/h264.c include utils.h
Folded into one commit during 2026-05-04 Step 1 reconciliation
(see ../phase0_evidence/2026-05-04/findings.md). Per-patch history
of the early fork commits preserved on the pre-step1 branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reference frames are now identified using their timestamp:
set the timestamp when queuing the output buffer and use it to identify
the frame later on.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Commit 7ff2543e64 ("Add support for the single-planar V4L2 API")
missed the VIDIOC_QBUF bytesused parameter. The kernel will
warn loudly if bytesused is not properly defined for an OUTPUT buffer.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
This adds a helper function to query v4l2 capabilities, returning
either the device caps when available or the general device caps
otherwise.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Because there might be more than a single call to CreateSurfaces,
we cannot assume that the index relative to the number of surfaces
requested in a single call matches the v4l2 index.
Grab the base index (as returned by the kernel) when allocating
buffers and use it for memory mapping and addressing them in v4l2.
This avoids memory-mapping the first (index 0) buffer multiple times
in that scenario instead of the n-th allocated buffer (in the n-th
call in the sequence).
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Although this is not needed when using the combination of CREATE_BUFS and
QUERYBUF V4L2 ioctls (as currently done) to allocate and prepare buffers,
the REQBUF ioctl is useful to liberate the buffers after use.
This introduces a helper for this purpose.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Since the V4L2 ioctl is called QUERYBUF, it makes more sense to
call the associated function with the same name.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
The coding style has been a bit erratic. Enforce the linux kernel coding
style by reusing their .clang-format file, running clang-format on the
source, and ignoring the few shortcomings that clang-format has at the
moment (especially on aligning the define values).
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>