Extended any_fd_supports_output_format() with vpu981 fd as 4th probe
target. Added V4L2_PIX_FMT_AV1_FRAME advertisement in
RequestQueryConfigProfiles. VAProfileAV1Profile0 in entrypoints +
GetConfigAttributes switches.
V4L2_REQUEST_MAX_PROFILES=11 now exactly full; comment added warning
about future profile additions needing the constant bumped.
Verified via vainfo:
VAProfileMPEG2Simple/Main, H264×5, HEVC, VP8, AV1 — all advertised
(VP9 absent because rkvdec module is on sibling-campaign-close
state, not the broken vp9-iter1; restoring VP9 needs the
ampere-vp9-enablement campaign reopened or the fail-state module
reloaded.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Latent bug surfaced by iter38 multi-device probe. profiles[] array
in RequestQueryConfigProfiles is sized by V4L2_REQUEST_MAX_PROFILES
(set as context->max_profiles=11 in VA_DRIVER_INIT), but the bounds
checks used V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES (10). Pre-iter38 only
a single device's profiles were enumerated, total ≤9, so the off-by-
one never bit. With iter38's rkvdec+hantro union (10 profiles total
across MPEG2/H264/HEVC/VP8/VP9), the last enumerator (VP9) hit
index=9 with the check 'index < 10-1 = 9' → skipped.
Probe BOTH rkvdec and hantro-vpu at VA_DRIVER_INIT and keep their
{video,media}_fd pairs in driver_data. RequestQueryConfigProfiles
enumerates the union of supported profiles from all open fds.
RequestCreateConfig retargets driver_data->{video,media}_fd to the
device that serves the requested profile; if a switch is needed
(active fd is wrong), tears down output_pool, capture_pool, video_format
cache, and fmt_valid so the next RequestCreateContext rebuilds them
on the new device.
Profile→device map (RK3399-shaped):
H264 / HEVC / VP9 → rkvdec
MPEG-2 / VP8 → hantro-vpu
Honours LIBVA_V4L2_REQUEST_VIDEO_PATH / MEDIA_PATH explicit overrides
(skips alt-probe when those are set).
Closes the 'libva multi-device probe' open item from iter36/iter37
campaign-close.
Populate the previously-dead pixelformat field at config.h:46 from
pixelformat_for_profile(profile). The switch at lines 54-88 already
rejects unsupported profiles, so by the time we reach the assignment
at line 98, pixelformat_for_profile returns non-zero.
Commit C reads this field at CreateContext to set the V4L2 OUTPUT
format correctly per profile (the β architectural fix for Bug 2 —
HEVC/VP9/VP8 currently dispatch through the pre-iter5b H264_SLICE
hardcode at surface.c:173 because surface.c has no config_id to look
up the profile).
Signed-off-by: claude-noether <claude-noether@reauktion.de>
request.h: add last_output_pixelformat to struct request_data, alongside
the existing last_output_{width,height} V4L2 device state cache. Gates
re-S_FMT on codec change in addition to resolution change.
config.c::RequestCreateConfig: wire up object_config->pixelformat
(previously dead field at config.h:46) by calling pixelformat_for_profile
on the active profile. The pixelformat field becomes the source of truth
that surface.c reads in commit C.
Signed-off-by: claude-noether <claude-noether@reauktion.de>
3 sites:
1. RequestQueryConfigProfiles: probe V4L2_PIX_FMT_VP9_FRAME against
single + MPLANE OUTPUT formats; advertise VAProfileVP9Profile0.
2. RequestCreateConfig: VAProfileVP9Profile0 case (no profile-specific
validation; defer to vaCreateContext / control submission time).
3. RequestQueryConfigEntrypoints: add VAProfileVP9Profile0 to the
VAEntrypointVLD fall-through.
Verified on fresnel: vainfo (auto-detect rkvdec) now shows
VAProfileVP9Profile0 alongside H.264x5 + HEVCMain.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three sites enabling VP8 profile recognition through the libva config
path:
1. RequestQueryConfigProfiles: NEW enumeration block probing
V4L2_PIX_FMT_VP8_FRAME against single + MPLANE OUTPUT formats.
Mirrors iter2 HEVC enumeration block. Surfaces VAProfileVP8
Version0_3 in vainfo on hantro env binding.
2. RequestCreateConfig: NEW case VAProfileVP8Version0_3 with
break — same shape as iter1 MPEG-2 + iter2 HEVCMain (no
profile-specific config validation in the libva backend;
validation deferred to vaCreateContext / control submission).
3. RequestQueryConfigEntrypoints: VAProfileVP8Version0_3 added to
the existing fall-through case list — surfaces VAEntrypointVLD.
After this commit alone, vainfo lists VP8Version0_3 (Phase 1
criterion 1) but vaCreateContext / runtime decode would fail at
later stages because no codec dispatcher exists yet (added in
commit B + C).
Refs:
../fresnel-fourier/phase4_iter3_plan.md (Commit A site list)
../fresnel-fourier/phase2_iter3_situation.md (B1, B2, B3
bug enumeration)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
RequestCreateConfig dispatches H.264 + MPEG-2 cases via break.
HEVCMain previously fell through to default returning
VA_STATUS_ERROR_UNSUPPORTED_PROFILE (= 12). Same fall-through
pattern iter1 fixed for MPEG-2; iter2 closes the loop for HEVC.
Add break for VAProfileHEVCMain. Same shape as iter1 Commit A
pattern — no profile-specific config validation in
RequestCreateConfig (validation happens at vaCreateContext /
control submission time).
This is the substrate fix only. After this commit:
- vaCreateConfig(VAProfileHEVCMain) returns SUCCESS
- mpv-vaapi HEVC ATTEMPTS to set up the hwaccel path
- codec_set_controls at picture.c:204-206 still has the
explicit case VAProfileHEVCMain: return UNSUPPORTED_PROFILE
reject in place
- decode fails downstream with -5 (Input/output error)
Bug 2 (picture.c reject removal) + Bug 3-7 (h265.c rewrite +
meson re-enable + slice_params accumulation + device-init
extension) land together in commit B, where h265_set_controls
exists to dispatch to.
Verified empirically Phase 3 Baseline D (scratch test on
throwaway branch): with this break alone, vaCreateConfig
SUCCESS for HEVCMain, V4L2 setup proceeds, decode fails at
the picture.c reject — confirms Phase 2 prediction. T4 H.264
+ iter1 MPEG-2 reference hashes hold (no collateral
regression).
Refs:
../fresnel-fourier/phase0_findings_iter2.md (Phase 1 lock)
../fresnel-fourier/phase2_iter2_situation.md Bug 1
../fresnel-fourier/phase3_iter2_baseline.md Baseline D
../fresnel-fourier/phase4_iter2_plan.md Clause 8, File 1
../fresnel-fourier/phase5_iter2_review.md (no Critical findings
touch this commit)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrites src/mpeg2.c to submit MPEG-2 control payload via the new
split V4L2_CID_STATELESS_MPEG2_{SEQUENCE,PICTURE,QUANTISATION}
controls (mainline kernel <linux/v4l2-controls.h>:1985-2105),
replacing the staging-era V4L2_CID_MPEG_VIDEO_MPEG2_{SLICE_PARAMS,
QUANTIZATION} combined-struct API that the kernel removed.
Per-frame submission: one batched VIDIOC_S_EXT_CTRLS, count=3,
ctrl_class=V4L2_CTRL_CLASS_CODEC_STATELESS (0xf010000), with the
three controls in order:
- id=0xa409dc (SEQUENCE) size=12 bytes
- id=0xa409dd (PICTURE) size=32 bytes
- id=0xa409de (QUANTISATION) size=256 bytes
Matches FFmpeg libavcodec/v4l2_request_mpeg2.c:130-155 reference
implementation. Verified empirically against fresnel-fourier
Phase 0 cross-validator anchor (bit-for-bit byte equivalence on
SEQUENCE first-row + QUANTISATION 256 bytes).
Six structural changes from old to new API:
1. Slice header parsing moved to kernel: bit_size,
data_bit_offset, quantiser_scale_code GONE from new structs.
2. Reference timestamps moved from slice to picture:
forward_ref_ts/backward_ref_ts now in
v4l2_ctrl_mpeg2_picture (offsets 0/8).
3. Boolean fields collapsed into picture.flags bitmask
(TOP_FIELD_FIRST 0x01 .. PROGRESSIVE 0x80, 8 bits total).
4. progressive_sequence collapsed into sequence.flags &
V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE.
5. PICTURE_CODING_TYPE renamed to PIC_CODING_TYPE (values same).
6. Quantisation load_* flags removed; matrices always present;
British spelling — quantiSation not quantiZation.
Behavioral correction (from old code, was a latent bug):
Old src/mpeg2.c:104-118 self-referenced surface_object timestamp
when the VAAPI ref picture was VA_INVALID_ID. New code sets the
ref_ts to 0, matching kernel doc 0-as-sentinel convention
(verified Phase 3 Baseline C: I-frame has both ts == 0; FFmpeg
v4l2_request_mpeg2.c:98-108 same convention).
Quantisation matrix order: zigzag scanning order per kernel doc
v4l2-controls.h:2076. VAAPI VAIQMatrixBufferMPEG2 stores in
zigzag order (per VAAPI spec). Direct memcpy works; no
permutation in libva backend. Kernel hantro_mpeg2.c::
hantro_mpeg2_dec_copy_qtable applies zigzag-to-raster permutation
when copying to the hardware quantisation table.
Default matrices (when iqmatrix_set==false): MPEG-2 spec defaults
per ISO/IEC 13818-2 Table 7-3. The mpeg2_default_intra_matrix
constant was transcribed from fresnel-fourier Phase 3 Baseline C
QUANTISATION verbatim payload bytes 0..63 (256-byte capture from
ffmpeg-v4l2request decode of bbb_720p10s_mpeg2.ts), per
phase5_iter1_review.md S3 amendment that flagged spec-recall as
unreliable. non_intra and chroma_non_intra are 16s per spec
(verified Baseline C bytes 64..127, 192..255). chroma_intra is
copy of intra (Baseline C bytes 128..191, verified identical).
Submission shape: one batched v4l2_set_controls call with all
three v4l2_ext_control entries, matching iter6/7/8 H.264 pattern
at src/h264.c:986. Bound to surface_object->request_fd (the
per-OUTPUT-slot permanent request_fd from iter6 binding).
Behavioral details:
- sequence.vbv_buffer_size = surface_object->source_size, where
source_size is set in picture.c:276 from request_pool slot->size,
which is the V4L2-negotiated sizeimage from VIDIOC_QUERYBUF.
Matches FFmpeg controls->pic.output->size.
- sequence.profile_and_level_indication = 0; not exposed by
VAAPI VAPictureParameterBufferMPEG2.
- sequence.chroma_format = 1 (4:2:0) hardcoded; campaign codec
scope is 4:2:0.
- progressive_frame proxies for progressive_sequence; same bit
for typical streams.
Phase 6 smoke test (post Commit A + Commit B):
- vainfo enumerates VAProfileMPEG2Simple + VAProfileMPEG2Main
on hantro bind. (Phase 1 criterion 1)
- libva trace: vaCreateConfig(VAProfileMPEG2Main) =
VA_STATUS_SUCCESS. (Phase 1 criterion 2)
- ffmpeg -hwaccel vaapi exits 0 with no Failed-to-create-
decode-configuration. (Phase 1 criterion 3 adjusted)
- mpv --hwdec=vaapi --vo=image at +02s seek: 2 distinct
frames with hashes byte-identical to SW reference:
HW frame 1: 6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092
SW frame 1: 6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092
HW frame 2: ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de
SW frame 2: ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de
(Phase 1 criterion 4 — DMA-BUF GL import path; cache-coherency-safe)
- T4 H.264 reference hashes still match (criterion 5; verified
Phase 3 Baseline D earlier).
Cache-stale class observation (out-of-scope iter1 work item):
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi + hwdownload
pipeline produces all-zero NV12 for MPEG-2 (same iter1 patch-0011
cache-coherency bug class observed for H.264 in fresnel-fourier
T4). Kernel + HW decode is correct (verified via ffmpeg
-hwaccel v4l2request -hwaccel_output_format drm_prime + hwdownload
which produces correct non-zero pixels matching SW reference).
Bug is in libva backend vaDeriveImage path; Phase 4 cross-
cutting work to add VIDIOC_EXPBUF + DMA_BUF_IOCTL_SYNC support.
Not blocking iter1 — DMA-BUF GL import path (mpv --vo=image) is
cache-coherency-safe and gives bit-exact pixels.
Auxiliary EINVAL noise (out-of-scope iter1 work item):
src/context.c:142-155 unconditionally sets H.264 device-wide
controls (V4L2_CID_STATELESS_H264_DECODE_MODE,
_START_CODE) on every CreateContext, regardless of profile.
EINVALs on hantro-vpu-dec (no H.264 controls there). Intentional
best-effort behavior — return value cast to (void) and discarded
at line 153. The error message "Unable to set control(s):
Invalid argument" is logged from src/v4l2.c:484 but doesn't
propagate as a backend error. Stays as documented auxiliary
noise.
Drop #include <mpeg2-ctrls.h> from src/config.c:37 and src/mpeg2.c
(formerly line 38). The kernel UAPI for MPEG-2 stateless control
IDs comes from <linux/v4l2-controls.h>, pulled transitively via
<linux/videodev2.h> (and explicitly from src/mpeg2.c after this
rewrite). The fork local include/mpeg2-ctrls.h header is deleted
in commit C; this commit removes the last includes of it.
src/config.c:38 still includes <hevc-ctrls.h> — left untouched per
phase5_iter1_review.md Nit 6 (lower-risk path; HEVC iteration
deletes its header).
Refs:
../fresnel-fourier/phase4_iter1_plan.md (contract clauses 1-6,
File 2 patch shape)
../fresnel-fourier/phase5_iter1_review.md (S3, Q4, Q5 amendments)
../fresnel-fourier/phase0_evidence/2026-05-07/iter1_phase3/
baseline_C_xvalidator/ffmpeg.stdout (cross-validator anchor)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
RequestCreateConfig dispatches H.264 cases via // FIXME + break;
MPEG-2 + HEVC cases fell through to default: which returns
VA_STATUS_ERROR_UNSUPPORTED_PROFILE (= 12). For MPEG-2, fall-through
was a leftover from libva-multiplanar iter1-iter5 H.264 focus —
nobody on that campaign tested MPEG-2 end-to-end, so the missing
break never surfaced as a bug there.
Add break for VAProfileMPEG2Simple + VAProfileMPEG2Main cases.
HEVC stays in fall-through (h265.c excluded from build per
fresnel-fourier campaign Phase 0 finding F-C; honest
UNSUPPORTED_PROFILE is correct until h265.c is reinstated in a
later iteration).
This is the substrate fix only. After this commit, vaCreateConfig
returns SUCCESS for MPEG-2, but actual decode still fails at
VIDIOC_S_EXT_CTRLS time because src/mpeg2.c uses staging-era
control IDs that mainline kernel removed. That fix lands in
commit B (mpeg2.c rewrite against the new V4L2_CID_STATELESS_MPEG2_*
split API).
Verified empirically in Phase 3 baseline B (scratch fix on
throwaway branch): with this break in place, vaCreateConfig
ret = SUCCESS, V4L2 setup proceeds (CREATE_BUFS, REQBUFS,
QUERYBUF, STREAMON, REQUEST_ALLOC, QBUF/DQBUF), then
VIDIOC_S_EXT_CTRLS id=V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS
(0x9909fa) returns -1 EINVAL — exactly the next failure mode
predicted by phase2_iter1_situation.md.
H.264 regression check (T4 reference hashes): with scratch fix
in place, mpv --hwdec=vaapi at +30s into bbb_1080p30_h264.mp4
produces JPEG hashes f623d5f7... (frame 1) and 7d7bc6f2...
(frame 2), exactly matching SW reference and T4 baseline.
No H.264 regression.
Refs:
../fresnel-fourier/phase0_findings_iter1.md (Phase 1 lock)
../fresnel-fourier/phase2_iter1_situation.md Bug 1
../fresnel-fourier/phase3_iter1_baseline.md Baseline A + B
../fresnel-fourier/phase4_iter1_plan.md Clause 6, File 1
../fresnel-fourier/phase5_iter1_review.md (Nit 6, kept smaller)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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>
Drop the per-codec options while at it, since we'll soon include a copy
of the associated headers.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
H.264 and H.265 support is still not supported upstream,
so it makes sense to autodetect each codec and only
enable those that are supported.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
void * can be assigned from and stored to any pointer type without any
warning. Remove the explicit casts.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
The cedrus_data structure carries the old name. In order to migrate to the
new name, let's rename it to request_data.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
The sunxi_cedrus.h header contains a bunch of defines prefixed with
SUNXI_CEDRUS.
As part as the ongoing migration to a more generic name, change that prefix
for V4L2_REQUEST, and the header file to request.h
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
As part of our renaming effort, Rename the libva hooks names to mention
request instead of SunxiCedrus
Signed-off-by: Maxime Ripard <maxime.ripard@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>
This long structure name makes it quite difficult to fit within the 80
characters limit. Shorten it.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>