111f8bac8f9f845f7ea55e36469a7bf00fe38fbf
318 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
111f8bac8f |
iter17 α-20 revert: pool size 11 inert; back to 24
Test discriminator: lowering MIN_CAP_POOL from 24 to 11 (matching kdirect) did not change any of the 5-codec hashes. Pool depth is not the cause of Bug 4/5/6. Revert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7ae85c54fc |
iter17 α-20 (test): MIN_CAP_POOL 24 -> 11 to match kdirect
Quick discriminator: if pool depth affects rkvdec's per-codec state machine, reducing libva's pool to kdirect's ~11 might change Bug 4/5/6 hashes. Reverts to 24 if test shows no change or regression. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
3760a70006 |
iter15 α-19: explicit VIDIOC_S_FMT on CAPTURE side for rkvdec correctness
Phase 3 ioctl-sequence diff: kdirect (ffmpeg-v4l2request) S_FMTs CAPTURE with NV12 + dimensions after S_FMT OUTPUT, BEFORE CREATE_BUFS. libva's old code only G_FMTs CAPTURE (per iter5b-β's hantro-targeted comment that explicit S_FMT puts hantro into an inconsistent state). For rkvdec on RK3399 the absence of explicit S_FMT CAPTURE doesn't commit the chosen NV12 format properly. rkvdec HEVC + H.264 silently produce zero / garbage CAPTURE output — Bug 4 + Bug 5 root cause. Now: S_FMT OUTPUT → S_FMT CAPTURE → G_FMT CAPTURE. Failure of S_FMT CAPTURE is non-fatal: fall back to G_FMT (preserves the iter5b-β hantro path). Future iter to gate this on driver_kind explicitly per feedback_per_driver_kludge_gating.md. For now, always-on is safe because kdirect proves S_FMT CAPTURE works on both rkvdec AND hantro. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
522fb6daa5 |
iter14 α-16: env-gated OUTPUT bitstream byte dump pre-QBUF
LIBVA_V4L2_DUMP_OUTPUT=<dir> writes source_data[0..slices_size] to <dir>/output_p<profile>_s<surface>_t<ts>.bin immediately before v4l2_queue_buffer OUTPUT. Discriminates whether libva writes the correct H.264/HEVC bitstream bytes (same as kdirect/input file). Off by default. Wrapped in static-cache env check. iter11+12+13 confirmed Bug 4/5 are not in S_EXT_CTRLS payload, not in kernel substrate (RFC v2), not in CPU cache visibility (α-17 sync ioctl works but inert). The remaining libva-side surface is the actual bitstream bytes the kernel reads. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
ca4dd88007 |
iter13 α-17: explicit DMA_BUF_IOCTL_SYNC around copy_surface_to_image
V4L2 CAPTURE buffers are V4L2_MEMORY_MMAP and mapped cached. Kernel DMA writes don't propagate to CPU cache observer; reading destination_data[] without DMA_BUF_IOCTL_SYNC(START|READ) returns stale data on RK3399 — observed as Bug 4 (H.264 partial-fill) and Bug 5 (HEVC all-zero) when libva goes through cached-mmap readback while kdirect ffmpeg-v4l2request + DRM_PRIME-mmap reads cleanly via implicit sync. Per Tomasz Figa's 2024 linaro-mm-sig discussion + feedback_rfc_v2_ vb2_dma_resv_scope.md: userspace responsibility for cache sync on cached-mmap'd V4L2 buffers. RFC v2 fence work doesn't engage this path; this ioctl pair does. Just-in-time EXPBUF + SYNC + close per copy. Per-call cost is one ioctl pair + one fd lifecycle per plane. Could cache the EXPBUF fd on cap_pool slot but doing it transient keeps lifecycle simple. Closing the EXPBUF fd is a no-op on V4L2 buffer memory. If EXPBUF or SYNC fails, fall through to existing memcpy path — preserves pre-iter13 behavior on the error branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
8e2c04f84b |
iter11 Phase 6 α-13 + α-14: HEVC SPS hygiene + IRAP/IDR flags fix Bug 5
Two fixes in one commit: α-13 (h265_fill_sps): sps_max_num_reorder_pics now derived from sps_max_dec_pic_buffering_minus1 (safe upper bound per H.265 §A.4.2) instead of hardcoded 0. Phase 5b empirically showed rkvdec ignores this field on RK3399, so this is wire-correctness hygiene only — matches kdirect's payload pattern without behavior change. α-14 (h265_set_controls): derive IRAP_PIC / IDR_PIC flags from the first slice's nal_unit_type (parsed by h265_fill_slice_params into slice_params_array[0].nal_unit_type). Without these flags rkvdec doesn't recognise the keyframe boundary, treats IDR as inter without references, and produces all-zero CAPTURE output — observed as Bug 5 on libva HEVC (06b2c5a0...). kdirect sets these from the bitstream parse and decodes correctly (9340b832...). Mapping: nal_unit_type 16..23 -> IRAP_PIC nal_unit_type 19 (IDR_W_RADL) or 20 (IDR_N_LP) -> IDR_PIC HEVC-only (no risk to other codecs). h265_set_controls already profile-gated via picture.c::codec_set_controls VAProfileHEVCMain dispatch. Per feedback_unconditional_codec_state.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
e0be4e6992 |
iter9 Phase 6 α-7: monotonic per-context timestamp counter
Replace gettimeofday in RequestEndPicture with object_context-scoped counter producing small us values (1, 2, 3, ...) so OUTPUT QBUF timestamp and DPB.reference_ts match ffmpeg-v4l2request's pattern. Phase 5 IMP-1: counter scoped to object_context (not driver_data) to avoid multi-context collisions. Empirical confirmation only — reviewer's CRIT-1 predicts this is inert (VP9/MPEG-2 use same path and PASS). If α-7 produces the same broken hash, the libva wire-byte search space is exhausted and iter10 must pivot to slice-data inspection or kernel investigation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
02266841c6 |
iter8 Phase 6c α-2: pass H.264 POC values through unchanged for rkvdec
Bug 4 root cause per Phase 7 γ + Phase 4c strace re-decode: libva strips FFmpeg's bit-16 POC sentinel; kdirect (ffmpeg-v4l2request) does NOT strip. rkvdec writes top/bottom_field_order_cnt directly to MMIO via writel_relaxed; with libva sending 0 instead of kdirect's 65536, hardware POC comparisons mismatch and motion compensation silently corrupts (16x32 patch + nothing else). The original h264_strip_ffmpeg_poc_sentinel was hantro-specific (hantro_h264.c prepare_table fed unmasked tbl->poc[]). Hantro+H.264 is not exercised on RK3399; deferring per-driver gating to iter9 if it surfaces. Preserve VA_PICTURE_H264_INVALID → return 0 (correct zero-init for empty DPB slots per Phase 5c amendment). 4 call sites unchanged (h264.c:309, 312, 462, 465 — for ref and current frame TopFieldOrderCnt / BottomFieldOrderCnt). Both reference and current-frame POCs now pass through unchanged so hardware compares agree. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
6f4e5833f0 |
iter8 Phase 7 fix-fwd: picture.c needs <stdlib.h> for getenv
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
66ecbef5c6 |
iter8 Phase 7 IMP-1 experiment: LIBVA_V4L2_ZERO_CAPTURE pre-zero gate
Env-gated CAPTURE pre-zero in BeginPicture after cap_pool_acquire. With LIBVA_V4L2_ZERO_CAPTURE=1, the slot mmap region is memset 0 before the kernel decode runs. Discriminates "kernel writes partial then aborts" from "kernel writes nothing, buffer carries stale residue from prior allocation." Per Phase 5 IMP-1: the 16x32 patch in libva H.264 frame 1 may be either real partial kernel write OR stale residue. This gate makes the next sweep run deterministically zero the buffer; if the patch still appears after, the kernel really writes it; if not, it was stale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7eae6eab46 |
iter8 Phase 6: γ env-gated CAPTURE buffer diagnostic dump
After RequestSyncSurface DQBUFs CAPTURE and marks slot DECODED, optionally dump first/last 32 bytes of each destination_data plane plus a non-zero count over a per-plane scan window (one MB row for plane 0, 1024 bytes for chroma). Gated behind LIBVA_V4L2_DUMP_CAPTURE=1; default off, no regression on existing flows. Diagnostic for Bug 4 (H.264 partial-fill): distinguishes "kernel didn't write" from "libva mis-reads" from "stale-residue" by inspecting the post-DQBUF buffer state directly. Phase 5 amendments applied: - Amendment 1 (CRIT-1): snprintf-buffered hex line, one request_log call. - Amendment 2 (CRIT-2): dump nested inside current_slot != NULL guard. - Amendment 4 (IMP-3): placed between cap_pool_mark_decoded and status=VASurfaceDisplaying on happy path only. - Amendment 5 (MIN-2): scan window = max(1024 chroma, bpl*16 luma). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
6df2159dd3 |
fresnel-fourier iter7 Phase 7 fix-forward: data links connect pads not entities directly
Empirical Phase 7 verification revealed the algorithm bug: data links in MEDIA_IOC_G_TOPOLOGY connect PAD IDs, not entity IDs directly. My iter7 Phase 6 commit compared link source_id/sink_id against the proc entity_id, never matched → io_entity_ids stayed empty → interface lookup never fired → returns -1 → falls back to legacy hardcoded path. Topology dump on fresnel /dev/media0 (rkvdec) confirmed: - Entity 3 (rkvdec-proc) has function=0x4008 (DECODER) ✓ - Data link src=16777218 sink=16777220 — these are PAD ids (0x01000002, 0x01000004), NOT entity 3. - Interface link src=50331660 (interface) sink=1 (entity) — for interface links source/sink ARE entity IDs. Fix: resolve pads → entities via the topo.pads[] array. 1. Collect pads belonging to proc entity (via pads[].entity_id). 2. For each data link touching those pads, the OTHER pad's entity_id is an IO neighbor. 3. Find interface link to those IO entities (unchanged from prev). Also allocate topo.pads[] in the 2-call ioctl pattern. Signed-off-by: claude-noether <claude-noether@reauktion.de> |
||
|
|
c106d95869 |
fresnel-fourier iter7 Phase 6: auto-detect with decoder-entity discrimination (B1a)
Refactor request.c::find_video_node_via_topology to find_decoder_video_node_via_topology — walks media-topology entities looking for MEDIA_ENT_F_PROC_VIDEO_DECODER function, then follows the kernel's link graph (data link from proc to IO entity, interface link from IO entity to V4L_VIDEO interface) to the correct /dev/videoN. Two-pass find_codec_device: pass 1 accepts only "rkvdec" (multi-codec decoder, 3 of 5 codecs); pass 2 accepts any known_decoder_drivers entry. Pre-iter7 the walk picked whichever media device matched the hantro-vpu driver name first — which on RK3399 could be the encoder half of the same media device, surfacing as an empty profile list. Phase 5 amendments incorporated: - CRIT-1: use MEDIA_LNK_FL_INTERFACE_LINK (1U<<28) to discriminate interface vs data links. - CRIT-2: check both source_id and sink_id of each link. - IMP-3: 2-call MEDIA_IOC_G_TOPOLOGY pattern (allocate all 3 arrays before second call); pre-iter7 had a spurious memset + third call. iter4-B1b (multi-decoder routing — open BOTH rkvdec AND hantro from one backend instance) still deferred. Post-iter7 MPEG-2/VP8 (hantro) still need LIBVA_V4L2_REQUEST_VIDEO_PATH override. Signed-off-by: claude-noether <claude-noether@reauktion.de> |
||
|
|
70196f8065 |
fresnel-fourier iter5b-β Phase 7 fix-forward commit D: destination_* for vaapi-copy late-surface flow
Phase 7 empirical: all 5 libva codecs returned all-zero because CreateContext's surfaces_ids[] walk was a no-op for ffmpeg-vaapi-copy which passes surfaces_count=0 to vaCreateContext (per the iter6 comment at context.c:262). Surfaces existed in driver_data's surface_heap but weren't in the param array → destination_* stayed at the zero initialization from CreateSurfaces2 β → BeginPicture's surface_bind_slot saw destination_planes_count=0 → no data assignment → copy_surface_to_image read all-zero. Fix: cache the format-uniform CAPTURE geometry in driver_data (fmt_valid, fmt_planes_count, fmt_buffers_count, fmt_format_height, fmt_sizes[], fmt_bytesperlines[]). Populate at CreateContext after v4l2_get_format(CAPTURE). Walk surface_heap (not just surfaces_ids[]) to fill every existing surface. Add lazy-fill in CreateSurfaces2 for surfaces created AFTER CreateContext. Invalidate cache in DestroyContext. New helper: surface_fill_format_uniform(driver_data, surface_object). Idempotent on destination_planes_count != 0. Signed-off-by: claude-noether <claude-noether@reauktion.de> |
||
|
|
7055b14f5e |
fresnel-fourier iter5b-β Phase 6 commit C: β refactor — OUTPUT lifecycle to CreateContext + CRIT-1 + CRIT-2
Strip OUTPUT-side V4L2 device-format lifecycle out of
RequestCreateSurfaces2 entirely. Move S_FMT(OUTPUT), CAPTURE-format
probe, cap_pool_init, per-surface destination_* fill into
RequestCreateContext where config_id (and therefore the bound
VAProfile) is known via config_object->pixelformat (wired by
commit B). The α' multi-CreateSurfaces2-mid-stream failure mode
disappears because β has no in-CreateSurfaces2 teardown branch;
each context cycle does its own setup, DestroyContext handles
teardown.
Phase 5 v2 review amendments:
- CRIT-1: removed video_format==NULL early-return at context.c:64-66
(would have rejected every first β CreateContext).
- CRIT-2: added request_pool_destroy() to DestroyContext before
REQBUFS(0). Pre-β only surface.c's resolution-change branch
called request_pool_destroy; β strips that, so DestroyContext
becomes the sole per-session teardown site.
- IMP-1: probe CAPTURE format first to derive output_type from
video_format->v4l2_mplane (eliminates the hardcoded mplane=true
hack from the Phase 4 v2 plan).
- IMP-2: surface_reset_format_cache() deleted (function + declaration
in surface.h + call in DestroyContext + last_output_{width,height}
fields in request.h). All dead under β.
CreateSurfaces2 now ~50 LOC (was ~250). Pure surface ID allocation
+ per-surface lifecycle bookkeeping; no V4L2 device state touched.
Signed-off-by: claude-noether <claude-noether@reauktion.de>
|
||
|
|
cc077a0c06 |
fresnel-fourier iter5b-β Phase 6 commit B: config.c — wire object_config->pixelformat
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> |
||
|
|
1c548b136a |
fresnel-fourier iter5b-β Phase 6 commit A: NEW src/codec.{h,c} — pixelformat_for_profile helper
Re-introduce after the iter5b-α' revert. Helper maps VAProfile to V4L2 OUTPUT-side FOURCC, used at CreateConfig in commit B to populate the previously-dead object_config->pixelformat field. β reads from there at CreateContext (commit C). Single source of truth for the profile→pixelformat mapping; mirrors the per-profile probes in config.c::RequestQueryConfigProfiles (lines 138-188). Register codec.c in meson.build sources, codec.h in headers. Signed-off-by: claude-noether <claude-noether@reauktion.de> |
||
|
|
6bc29ec582 |
Revert "fresnel-fourier iter5b Phase 6 commit A: NEW src/codec.{h,c} — pixelformat_for_profile helper"
This reverts commit
|
||
|
|
9a7f888f1b |
Revert "fresnel-fourier iter5b Phase 6 commit B: state-tracking — request.h field + config.c wire-up"
This reverts commit
|
||
|
|
709ab34624 |
Revert "fresnel-fourier iter5b Phase 6 commit C: surface.c — profile-derived OUTPUT pixel format"
This reverts commit
|
||
|
|
4b2288fa9a |
fresnel-fourier iter5b Phase 6 commit C: surface.c — profile-derived OUTPUT pixel format
Replace the hardcoded `V4L2_PIX_FMT_H264_SLICE` at surface.c:173 with a profile-derived lookup via find_sole_active_pixelformat(). The helper walks the config_heap; with one active config (universal across mpv, ffmpeg, Firefox, Chromium) it returns the cached pixelformat populated at CreateConfig in commit B. Falls back to the pre-iter5b H264_SLICE for the pathological "zero or multiple configs" case (probe surfaces before CreateConfig; multi-config-then-surfaces). Extend the existing resolution-change gate to also fire on pixelformat (codec) change. The teardown branch handles both cases identically — REQBUFS(0) on both queues before re-S_FMT. The kernel behavior pre-iter5b on RK3399: - hantro: hantro_find_format(H264_SLICE) returns NULL on the RK3399 decoder block (no H.264 support); hantro_try_fmt silently substitutes the first format in rk3399_vpu_dec_fmts = MPEG2_SLICE → codec_mode = MPEG2_DECODER. VP8 bitstream dispatched to MPEG2 ops → all-zero CAPTURE. MPEG-2 worked by accident (bitstream matched the substituted codec_mode). - rkvdec: format/control mismatch; decoder silently drops the request → all-zero CAPTURE. Same bug class as iter4 commit `692eaa0` (h264_start_code unconditional set). Both fixes thread the active VAProfile into codec-specific kernel state. Signed-off-by: claude-noether <claude-noether@reauktion.de> |
||
|
|
f8256e6c2d |
fresnel-fourier iter5b Phase 6 commit B: state-tracking — request.h field + config.c wire-up
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>
|
||
|
|
ce304ef5af |
fresnel-fourier iter5b Phase 6 commit A: NEW src/codec.{h,c} — pixelformat_for_profile helper
Add a small helper that maps a VAProfile to its V4L2 OUTPUT-side pixel format FOURCC. Single source of truth, mirrors the per-profile probes in config.c::RequestQueryConfigProfiles (lines 138-188). Used by commits B + C in this series: - commit B: populate object_config->pixelformat at CreateConfig - commit C: surface.c reads the populated field to set OUTPUT format per-profile instead of hardcoded H264_SLICE Register in meson.build sources + headers. Signed-off-by: claude-noether <claude-noether@reauktion.de> |
||
|
|
692eaa0053 |
fresnel-fourier iter4 Phase 7 fix-forward: gate ANNEX-B start-code prepend on H.264/HEVC profiles
Root cause for VP9 criterion-4 failure traced via runtime instrumentation: context.c:194 unconditionally set context_object->h264_start_code = true for every CreateContext, regardless of codec profile. picture.c:70 then prepends 0x00 0x00 0x01 (ANNEX-B start code) to ALL slice data including VP9 frames. VP9 has no start codes — its uncompressed_header begins with the raw frame_marker byte (0x10 in the high 2 bits). The 3-byte prefix shifted the rkvdec driver's bitstream-read by 24 bits, producing a silent decode failure (frame_marker mismatch -> driver fails to locate a valid frame -> CAPTURE slot stays at cap_pool init pattern, the dim 0x4c green visible in Phase 7 hwdownload PNGs). iter4 fix: switch on config_object->profile in RequestCreateContext. Set h264_start_code = true only for VAProfileH264* and VAProfileHEVCMain. False for MPEG2/VP8/VP9. iter1 (MPEG-2) and iter3 (VP8) had this same bug latent — they passed because their criterion-4 verification used different paths (iter1 direct readback was small enough to mask, iter3 used transitive proof not pixel comparison). The Phase 7 byte-level pixel comparison is what exposed it. Empirical proof of the fix on fresnel: - pre-fix submission FRAME control bytes 0-23: lf.flags=0x01 (only DELTA_ENABLED), base_q_idx=0x41 — bit-misaligned because parser was reading the prefix bytes. - post-fix submission FRAME control bytes 0-23 byte-match Phase 3 kernel-direct anchor: lf.flags=0x03 (ENABLED|UPDATE), base_q_idx=0x2e (46). Transitive-proof leg 1 (backend-payload == kernel-direct-payload) satisfied for the keyframe. - s(6) bit-width fix in vp9.c (4 mag + 1 sign -> 6 mag + 1 sign per VP9 spec) was a real bug too, latent because Bug 1 (this commit's fix) prevented its code path from running. Both fixes ship together. Pixels still produce 0x4c constant pattern post-fix — that is Bug 2 (substrate-wide cap_pool readback regression on linux-fresnel-fourier 7.0-1) per phase7_iter4_verification.md. Bug 2 is out of iter4 scope per Option-A choice; transitive proof remains the criterion-4 verification path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
beaa914680 |
fresnel-fourier iter4 Phase 6 commit C: picture.c VP9 dispatch + 2 buffer-type cases
5 sites: 1. include block: add #include "vp9.h". 2. codec_set_controls: add VP9 case calling vp9_set_controls(). 3. codec_store_buffer VAPictureParameterBufferType: VP9 inner case memcpy'ing into surface_object->params.vp9.picture. 4. codec_store_buffer VASliceParameterBufferType: VP9 inner case memcpy'ing into surface_object->params.vp9.slice. 5. (No reset in RequestBeginPicture — VP9 has no iqmatrix_set/ probability_set-style flag, Picture/Slice are unconditionally populated by VAAPI consumer per frame.) Per Phase 2 B12: NO buffer.c changes — VP9 uses Picture+Slice+Data which are already in the iter3 allow-list. Per memory feedback_runtime_enumerates_allowlists.md plan for Commit D fix-forward if a runtime miss surfaces; predicted clean. Verified end-to-end on fresnel: - vainfo enumerates VAProfileVP9Profile0 alongside H.264 + HEVC. - LIBVA_DRIVER_NAME=v4l2_request ffmpeg -hwaccel vaapi VP9 decode exits 0 (criterion 3 PASS): 5 frames decoded at 0.307x speed, cap_pool_init OK, no kernel ioctl errors. - mpv vp9-vaapi engagement still SW-fallback (iter4-B2 backlog — mpv-DRM device-create path doesn't honor LIBVA_DRIVER_NAME the way ffmpeg-vaapi does; investigation deferred). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
406d08e122 |
fresnel-fourier iter4 Phase 6 commit B: NEW src/vp9.c + src/vp9.h + meson.build + context.h (vp9_lf) + surface.h (params.vp9)
VP9 codec dispatcher implementing 12 contract clauses against
V4L2_CID_STATELESS_VP9_FRAME (0xa40a2c) +
V4L2_CID_STATELESS_VP9_COMPRESSED_HDR (0xa40a2d). 2 batched
controls per frame; rkvdec on RK3399 mandatorily requires both
per drivers/staging/media/rkvdec/rkvdec-vp9.c::rkvdec_vp9_run_preamble:752.
Implementation:
- ~80 LOC VPX range coder (vp9_rac_*) — minimal port of FFmpeg
vpx_rac.[ch] + vp89_rac.h. Stateless static helpers.
- inv_map_table[255] + read_prob_delta — verbatim copy from
v4l2_request_vp9.c:44-97.
- vp9_parse_uncompressed_header_lf_quant — partial parse for the
fields VAAPI doesn't expose: lf_delta_enabled / lf_delta_update /
lf_ref_delta[4] / lf_mode_delta[2] / base_q_idx /
delta_q_y_dc / delta_q_uv_dc / delta_q_uv_ac. ~120 LOC.
- vp9_fill_compressed_hdr — port of FFmpeg fill_compressed_hdr
with Phase 5 C3 out_reference_mode parameter. ~140 LOC.
- vp9_set_controls — orchestrates Clauses 1+2+4+5+7+10+11+12.
~120 LOC.
Phase 5 amendments incorporated in code:
- C1: frame.interpolation_filter = direct from VAAPI's
mcomp_filter_type (NO XOR; vaapi_vp9.c:62 already applied it
before storing into VAAPI's mcomp_filter_type).
- C2: persistent vp9_lf state added to object_context (in
context.h). Initialized to VP9 spec defaults
{1,0,-1,-1,0,0} on keyframe / intra_only / error_resilient.
Updated only when parser sees lf_delta.update=1. Always
copied to kernel control.
- C3: vp9_fill_compressed_hdr takes uint8_t *out_reference_mode;
threaded through call site. allowcompinter derived from VAAPI
sign-bias bits.
Phase 5 S4: uv_mode memcpy from FFmpeg's fill_compressed_hdr
omitted — rkvdec reads uv_mode from kernel's persistent
probability_tables, NOT from prob_updates ctrl.
Clause 3 compile-time _Static_assert on struct sizes (168/2040)
matches Phase 3 empirical baseline; UAPI shifts will fail loudly.
surface.h: extends params union with vp9 { picture, slice }.
context.h: adds vp9_lf { ref_deltas[4], mode_deltas[2], initialized }.
meson.build: adds vp9.c + vp9.h.
Build: clean on fresnel (linux-fresnel-fourier 7.0-1, libva 1.23).
Runtime: not yet wired in picture.c — next commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
16b397305d |
fresnel-fourier iter4 Phase 6 commit A: VP9 enumeration + dispatch in config.c
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> |
||
|
|
7f8fa93213 |
fresnel-fourier iter4 Phase 6 commit Z: device-path auto-detect via media controller topology
Pre-iter4 backend hardcoded /dev/video0 + /dev/media0 as defaults
when no env override was set. Linux 7.0 udev/probe order changed,
rockchip-rga (RGB color converter, no codec) now claims
/dev/video0 — legacy default returns empty profile list.
Discovery is driven by the media controller graph (the canonical
v4l2-request approach). NOT a /dev/video* walk by enumeration
order — that mispairs video and media nodes when one driver
registers multiple media devices, and depends on probe-order
luck.
Algorithm:
1. Walk /dev/media0..15. MEDIA_IOC_DEVICE_INFO names the driver.
Match against {rkvdec, hantro-vpu, cedrus, sun4i_csi}.
2. MEDIA_IOC_G_TOPOLOGY enumerates the entity/interface graph.
The MEDIA_INTF_T_V4L_VIDEO interface carries major:minor of
the V4L2 video node owned by THIS media controller — paired
by the kernel, not by /dev/* enumeration order.
3. Resolve major:minor to /dev/videoN via /sys/dev/char/<M>:<N>
(the kernel's char-device sysfs symlink whose basename is
the device node name).
LIBVA_V4L2_REQUEST_NO_AUTODETECT=1 escape hatch reverts to legacy
/dev/video0 + /dev/media0 hardcoded behavior for callers that
depended on it.
Phase 5 C4 amendment: walk-and-pick-first selects rkvdec on RK3399
(rkvdec's media controller enumerates before hantro's). H.264 /
HEVC / VP9 (rkvdec codecs) work without env override after this
commit. MPEG-2 / VP8 (hantro) still require explicit
LIBVA_V4L2_REQUEST_VIDEO_PATH=/dev/video3 override; full
multi-decoder dispatch is iter4-B1 backlog item.
Verified empirically on fresnel (linux-fresnel-fourier 7.0-1):
- vainfo (no env) -> "auto-selected codec device: /dev/video1 +
/dev/media0", enumerates H264*5 + HEVCMain (rkvdec) — paired
via topology graph, not /dev/video* enumeration.
- vainfo NO_AUTODETECT=1 -> empty list (legacy /dev/video0 = rga).
- vainfo with explicit /dev/video3 + /dev/media1 -> MPEG2*2 + VP8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
e1aca9cc6b |
fresnel-fourier iter3 Phase 6 commit D: buffer.c whitelist for
VAProbabilityBufferType
Phase 2 source-read assumed buffer.c was type-agnostic ("the buffer
registry is type-agnostic" per phase2_iter3_situation.md non-bugs
list). FALSE. RequestCreateBuffer at buffer.c:59-70 has an explicit
allow-list switch:
case VAPictureParameterBufferType:
case VAIQMatrixBufferType:
case VASliceParameterBufferType:
case VASliceDataBufferType:
case VAImageBufferType:
break;
default:
return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
Without VAProbabilityBufferType in the allow-list, the consumer gets
VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE on vaCreateBuffer for the
probability buffer, BEFORE codec_store_buffer is ever reached.
ffmpeg-vaapi log:
[vp8] Failed to create parameter buffer (type 13): 15
(the requested VABufferType is not supported).
Same iter1 Commit D pattern: Phase 2 grep didn't find this, runtime
enumerated authoritatively. Per memory feedback_header_deletion_
check.md ("let the compiler enumerate them") — but extended here:
runtime enumerates allow-list violations the same way the compiler
enumerates include-site violations.
Fix: add `case VAProbabilityBufferType:` to the buffer.c allow-list.
+1 line, mechanical.
Refs:
../fresnel-fourier/phase2_iter3_situation.md (incorrect non-bug
claim about buffer.c)
../fresnel-fourier/phase4_iter3_plan.md (Commit D placeholder for
fix-forward — used)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
7f84bbb50f |
fresnel-fourier iter3 Phase 6 commit C: picture.c VP8 dispatch + 4
buffer-type cases + new VAProbabilityBufferType outer case + per-
frame reset + surface.h params.vp8 union extension
Five sites in picture.c + one site in surface.h wire up the VP8
codec dispatcher introduced by commit B:
1. Include #include "vp8.h" in the codec headers block.
2. codec_set_controls: NEW case VAProfileVP8Version0_3 calling
vp8_set_controls(driver_data, context, surface_object).
Same shape as MPEG-2 + HEVC dispatch.
3. codec_store_buffer VAPictureParameterBufferType: NEW VP8 case
memcpy'ing into surface_object->params.vp8.picture
(sizeof VAPictureParameterBufferVP8).
4. codec_store_buffer VASliceParameterBufferType: NEW VP8 case
memcpy'ing into surface_object->params.vp8.slice (single,
no slices[] array — VP8 is frame-mode, no multi-slice).
5. codec_store_buffer VAIQMatrixBufferType: NEW VP8 case
memcpy'ing into surface_object->params.vp8.iqmatrix +
setting iqmatrix_set true.
6. codec_store_buffer NEW outer case VAProbabilityBufferType
(Phase 5 C3: NOT VAProbabilityDataBufferType — that's the
STRUCT name; the buffer-type enum constant is
VAProbabilityBufferType = 13 per va.h:2058). Inner switch
dispatches by profile, with VP8 case memcpy'ing into
surface_object->params.vp8.probability + setting
probability_set true.
7. RequestBeginPicture: NEW per-frame reset for the two VP8
flags — params.vp8.iqmatrix_set = false +
params.vp8.probability_set = false. Mirrors the existing
iter1 (h264.matrix_set) + iter2 (h265.num_slices) per-frame
resets.
surface.h extension:
8. params union: NEW vp8 struct after h265 — holds the 4 VAAPI
buffer-type structs (VAPictureParameterBufferVP8,
VASliceParameterBufferVP8, VAIQMatrixBufferVP8 + iqmatrix_set,
VAProbabilityDataBufferVP8 + probability_set).
The NEW vp8 union member adds ~5300 bytes (sizeof
VAProbabilityDataBufferVP8 dominated by dct_coeff_probs[4][8][3]
[11] = 1056 + bookkeeping). The h265 member with slices[64] array
remains the largest (~17 KB), so the union size doesn't grow.
After this commit: backend builds clean, links cleanly. mpv-vaapi
VP8 decode should engage end-to-end on hantro env binding. Phase
1 criteria 1 + 2 + 3 expected satisfied; criterion 4 (HW=SW byte-
identical) and criterion 5 (3-codec regression) verified at Phase
6 smoke + Phase 7.
Refs:
../fresnel-fourier/phase4_iter3_plan.md (Commit C site list)
../fresnel-fourier/phase2_iter3_situation.md (B6, B7, B8, B9
bug enumeration)
../fresnel-fourier/phase5_iter3_review.md (C3 VAProbabilityBuffer
Type rename
empirically verified)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
017e27f389 |
fresnel-fourier iter3 Phase 6 commit B: NEW src/vp8.c + src/vp8.h
+ meson.build VP8 entries
Net-new VP8 codec dispatcher implemented against
V4L2_CID_STATELESS_VP8_FRAME (kernel UAPI <linux/v4l2-controls.h>:
1900-1958). Single batched control per frame, no init-time device-
wide menus (VP8 has no DECODE_MODE/START_CODE).
Per-frame submission: ONE VIDIOC_S_EXT_CTRLS, count=1, with full
v4l2_ctrl_vp8_frame struct (1232 bytes — corrected vs Phase 2
implicit ~400 estimate; entropy.coeff_probs[4][8][3][11] alone is
1056 bytes).
vp8_set_controls() implements 10 contract clauses per
phase4_iter3_plan.md:
Clause 1: single-control batched submission (count=1)
Clause 2: stack alloc + memset zero (covers all padding)
Clause 3: width/height/version/per-frame scalars; off-by-one
num_dct_parts = num_of_partitions - 1
Clause 4: DPB timestamp resolution (3 refs: last/golden/alt;
NULL surface → 0-sentinel via memset; mirrors iter1
mpeg2.c::pic.forward_ref_ts)
Clause 5: loop filter (6 fields + 3 flag bits; ADJ_ENABLE/
DELTA_UPDATE/FILTER_TYPE_SIMPLE)
Clause 6: quant base + delta derivation from VAAPI's per-segment
absolute index matrix (subtraction recovers signed
deltas; correct for typical content per Phase 5 S1)
Clause 7: segment fields (segment_probs direct copy; flags
assembled with DELTA_VALUE_MODE set unconditionally
per FFmpeg pattern)
Clause 8: entropy table — 3 VAAPI sources merged (Picture: y_mode +
uv_mode + mv_probs; ProbabilityData: coeff_probs[4][8][3]
[11] direct memcpy; IQMatrix: quant)
Clause 9: coder state + first-partition fields + flags assembly
Clause 10: v4l2_set_controls submission
Phase 5 review amendments incorporated:
C1 first_part_header_bits = slice->macroblock_offset
NOT 0 — kernel hantro_g1_vp8_dec.c:260 + rockchip_vpu2_hw_vp8_
dec.c:372 read this field unconditionally to compute the MB-
data DMA offset. Verified via source identity: vaapi_vp8.c:204
and v4l2_request_vp8.c:83 use byte-identical formulas
(8 * (input - data) - bit_count - 8); VAAPI exposes via
slice->macroblock_offset, V4L2 names it first_part_header_bits.
C2 first_part_size = slice->partition_size[0] +
((macroblock_offset + 7) / 8)
VAAPI's partition_size[0] is the REMAINING bytes after parsing
(vaapi_vp8.c:209; va_dec_vp8.h:193-196). Kernel needs the
TOTAL control partition size; recover by adding back ceil
(macroblock_offset/8) bytes.
Phase 3 keyframe verbatim cross-check: 21923 + 819 = 22742 ✓
C4 (int8_t) cast (NOT (s8); s8 is kernel-internal typedef from
<linux/types.h> not exposed to userspace; userspace UAPI
exposes __s8 with double-underscore; portable userspace cast
is int8_t from <stdint.h>).
S3 assert(probability_set) — kernel hantro_vp8.c::hantro_vp8_
prob_update reads coeff_probs unconditionally; NO default-
table fallback. Practical risk low (FFmpeg vaapi_vp8.c always
sends VAProbabilityBufferType per frame), but assert surfaces
immediately if a future consumer doesn't.
Flags assembly: 6 mainline-documented bits only (KEY_FRAME, SHOW_
FRAME, MB_NO_SKIP_COEFF, SIGN_BIAS_GOLDEN, SIGN_BIAS_ALT). EXP +
bit 0x40 NOT replicated despite ffmpeg-v4l2-request-git setting
them on inter frames — kernel hantro_vp8.c only inspects KEY_FRAME
bit. SHOW_FRAME forced unconditional per Phase 3 Q4 (BBB has no
alt-ref invisible frames; documented fidelity gap).
VAAPI inverts: key_frame=0 means it IS a keyframe per VP8 spec.
Backend writes V4L2_VP8_FRAME_FLAG_KEY_FRAME iff
!picture->pic_fields.bits.key_frame.
After this commit alone: vp8.o compiles standalone; meson.build
links it into the shared library. picture.c can't dispatch yet
(commit C wires that).
Refs:
../fresnel-fourier/phase4_iter3_plan.md (10 contract clauses,
Phase 5 amendments
section)
../fresnel-fourier/phase5_iter3_review.md (C1, C2, C3, C4, S3
all incorporated)
../fresnel-fourier/phase3_iter3_baseline.md (verbatim payload
anchors)
references/ffmpeg-kwiboo/libavcodec/v4l2_request_vp8.c (V4L2 ref)
references/ffmpeg-kwiboo/libavcodec/vaapi_vp8.c (VAAPI source ref)
references/linux-mainline/drivers/media/platform/verisilicon/
hantro_g1_vp8_dec.c (RK3399 kernel driver — first_part_header_
bits + first_part_size usage)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
27d82e3cf4 |
fresnel-fourier iter3 Phase 6 commit A: VP8 enumeration + dispatch in config.c
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>
|
||
|
|
8d71e20bf7 |
fresnel-fourier iter2 Phase 6 commit B: rewrite h265.c against new V4L2 stateless HEVC API
Rewrites src/h265.c (407 lines → 588 lines) and the picture.c HEVC
dispatch + per-slice accumulation against the modern split V4L2_CID_
STATELESS_HEVC_{SPS,PPS,SLICE_PARAMS,SCALING_MATRIX,DECODE_PARAMS,
DECODE_MODE,START_CODE} stateless controls. Replaces the staging-era
V4L2_CID_MPEG_VIDEO_HEVC_{SPS,PPS,SLICE_PARAMS} CIDs that were
removed from the kernel UAPI.
Per-frame submission: ONE batched VIDIOC_S_EXT_CTRLS, count=5,
ctrl_class=V4L2_CTRL_CLASS_CODEC_STATELESS:
0xa40a90 SPS (40 bytes)
0xa40a91 PPS (64 bytes)
0xa40a92 SLICE_PARAMS (variable; dynamic-array; one entry per slice)
0xa40a93 SCALING_MATRIX (1296 bytes; memset-zero when no scaling list)
0xa40a94 DECODE_PARAMS (328 bytes; per-frame DPB info)
Plus device-wide menus set once at context.c init (separate batched
S_EXT_CTRLS call so a kernel without HEVC controls — e.g. hantro on
RK3568/RK3399 — silently fails its batch without invalidating H.264):
0xa40a95 DECODE_MODE (FRAME_BASED on rkvdec)
0xa40a96 START_CODE (ANNEX_B on rkvdec)
Reference: FFmpeg libavcodec/v4l2_request_hevc.c:505-565
(v4l2_request_hevc_queue_decode batched submission shape).
Phase 5 review amendments incorporated:
C1 (data_byte_offset NOT data_bit_offset):
Old h265.c at lines 184-209 ran an 8-bit search to compute
bit-granularity offset. New API renames the field to
data_byte_offset (u32 byte offset). Bit-search dropped; replaced
with plain byte offset = source_offset + slice->slice_data_byte_offset.
C2 (dpb_entry.flags only LONG_TERM_REFERENCE; pic_order_cnt_val
singular; poc_st_curr_*[] arrays hold DPB INDICES not POC):
h265_fill_decode_params replaces old slice-params DPB iteration
with explicit DPB classification + index-array population.
For each VAAPI ReferenceFrames[i]:
- Classify into ST_CURR_BEFORE / ST_CURR_AFTER / LT_CURR via
VA_PICTURE_HEVC_RPS_* flags.
- Set dpb[j].timestamp, .pic_order_cnt_val (singular), .field_pic.
- Set dpb[j].flags = LONG_TERM_REFERENCE iff RPS_LT_CURR.
- Append j (DPB index, u8) to poc_st_curr_before[k] /
poc_st_curr_after[k] / poc_lt_curr[k] based on classification.
C3 (union-aliasing reasoning corrected):
BeginPicture's params.h265.num_slices = 0 reset is benign for
non-HEVC profiles because byte ~17764 of the params union is past
any field non-HEVC profiles read, NOT because RenderPicture's
per-buffer copies overwrite that location. Wording amended in
phase4_iter2_plan.md per phase5_iter2_review.md.
S1 (PPS flags 19 + 20 — DEBLOCKING_FILTER_CONTROL_PRESENT and
UNIFORM_SPACING):
Empirically VAAPI does NOT expose either flag in the
VAPictureParameterBufferHEVC pic_fields.bits or
slice_parsing_fields.bits. Both bits left zero. BBB-720p10s_hevc
fixture uses neither tiles nor explicit deblocking-control
parameters, so the omission is correct for the iter2 binding cell.
S2 (3 PPS scalars added):
pic_parameter_set_id (default 0; VAAPI doesn't expose),
num_ref_idx_l0_default_active_minus1, num_ref_idx_l1_default_
active_minus1 (both populated from VAAPI picture struct).
Q2 (slice_segment_addr populated):
Was missing in old h265.c. Now sourced from
VAAPI's slice->slice_segment_address.
S3 (SCALING_MATRIX content choice):
Implementer choice taken: when iqmatrix_set==false (BBB has no
scaling list per SPS flags = SAO|STRONG_INTRA_SMOOTHING),
h265_fill_scaling_matrix sends memset-zero. Matches FFmpeg's
sl=NULL pattern at v4l2_request_hevc.c:384-403 (preserves
byte-equality vs cross-validator anchor).
S4 (FFmpeg function name fix): cosmetic; no code impact.
Plus one Phase 6 inline correction: phase 5 review S1 suggested
VAAPI exposes uniform_spacing_flag in pic_fields.bits; empirical
test-compile shows it doesn't. Comment added in h265_fill_pps
documenting the omission.
Picture.c changes (3 edits):
1. codec_set_controls HEVCMain dispatch (lines 204-206 → call
h265_set_controls; replaces explicit Fourier-local: HEVC stripped
reject).
2. codec_store_buffer HEVC VASliceParameterBufferType case: append
VAAPI slice param to params.h265.slices[N] array, increment
num_slices. Single-slice mirror at .slice retained for
h265_fill_pps (which reads dependent_slice_segment_flag from
LongSliceFlags).
3. RequestBeginPicture: add params.h265.num_slices = 0 reset
alongside existing h264.matrix_set = false reset.
Surface.h: extend params.h265 struct with slices[HEVC_MAX_SLICES_PER_
FRAME=64] array + num_slices counter. ~17 KB extra per surface union;
24 surfaces in iter7 cap_pool = ~400 KB total surface_heap growth.
object_heap allocator picks up new size automatically via
sizeof(struct object_surface).
Context.c: separate 2-control batched call sets HEVC DECODE_MODE +
START_CODE device-wide. Same best-effort (void)v4l2_set_controls
pattern as the existing H.264 device-init block; if kernel doesn't
advertise HEVC controls (hantro on RK3568/RK3399), the batch silently
fails without invalidating the H.264 batch.
Meson.build: uncomment 'h265.c' (line 50) and 'h265.h' (line 73)
in sources + headers lists.
H265.h: added HEVC_MAX_SLICES_PER_FRAME=64 #define before struct
forward declarations.
Phase 6 smoke test on fresnel (post Commit A + Commit B):
Criterion 1: vainfo lists VAProfileHEVCMain on rkvdec env binding
(/dev/video1 + /dev/media0). PASS.
Criterion 3: ffmpeg -hwaccel vaapi HEVC decode of bbb_720p10s_hevc.mp4
-frames:v 5 -f null -, exit 0. cap_pool_init: 24 slots
ready. PASS.
Criterion 4: mpv --hwdec=vaapi --vo=image at +02s seek, HEVC fixture:
HW frame 1: 47a5f3850df5d8c732767a227830c2272ff78402a7b6adeea329e29838808be5
SW frame 1: 47a5f3850df5d8c732767a227830c2272ff78402a7b6adeea329e29838808be5
HW frame 2: a467b3bc9d7b6374b6786ecfac46932d6c7bb932ab11d311edaa233d7863e656
SW frame 2: a467b3bc9d7b6374b6786ecfac46932d6c7bb932ab11d311edaa233d7863e656
HW=SW byte-identical for both frames; frame1 != frame2 (real motion).
PASS.
Criterion 5: regression hashes hold for both prior cells:
H.264 +30s HW frame 1: f623d5f7a41697f67dd227275c6f1b21ffc257f65626d32fde8229357f8764c9 (T4 ref MATCH)
H.264 +30s HW frame 2: 7d7bc6f2146dda8b2d223bba622c4b9fbe9674181ff1e02afe286b620342e0a8 (T4 ref MATCH)
MPEG-2 +02s HW frame 1: 6e7873030dbf0403c67f35dd106ebef3c7909a0fd12433b82ad758e7fee9f092 (iter1 ref MATCH)
MPEG-2 +02s HW frame 2: ccc7ce08810d4a96e9ba7a19f4f95bbf6cc861bda9337604b5c668ad52bef7de (iter1 ref MATCH)
PASS.
All five criteria green on first build attempt — Phase 5 review
caught the 3 Critical UAPI errors (data_bit_offset → data_byte_offset
rename; dpb.rps field gone + pic_order_cnt_val rename + index-array
semantics) that would have been Phase 6 compile failures or silent
Phase 7 byte-compare divergences. Without that review pass, this
commit would have been the start of a 2+ loopback debugging cycle.
Refs:
../fresnel-fourier/phase4_iter2_plan.md (10 contract clauses,
File 4 patch shape)
../fresnel-fourier/phase5_iter2_review.md (C1, C2, C3, S1, S2,
S3, S4, Q2 amendments
all incorporated)
../fresnel-fourier/phase0_evidence/2026-05-08/iter2_phase3/
ffmpeg_v4l2req.stdout (cross-validator anchor — Phase 7
bonus byte-compare verification target)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
cca539d5f9 |
fresnel-fourier iter2 Phase 6 commit A: config.c break for HEVCMain case
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>
|
||
|
|
229d6d11be |
fresnel-fourier iter1 Phase 6 commit D: drop missed mpeg2-ctrls.h include from context.c
Fix-forward for commit C (
|
||
|
|
3aab1879cb |
fresnel-fourier iter1 Phase 6 commit C: delete staging-era include/mpeg2-ctrls.h
Removes the local fork-internal header include/mpeg2-ctrls.h. The
header explicitly self-described as staging-era in its preamble:
These are the MPEG2 state controls for use with stateless MPEG-2
codec drivers. It turns out that these structs are not stable yet
and will undergo more changes. So keep them private until they
are stable and ready to become part of the official public API.
The structs DID stabilize and become public in mainline Linux —
at different CIDs (V4L2_CID_STATELESS_MPEG2_{SEQUENCE,PICTURE,
QUANTISATION} = 0xa409dc/dd/de) and with redesigned struct
layouts (split sequence/picture/quantisation, slice header parsing
moved kernel-side, boolean fields collapsed to flags bitmask).
Before this commit, two source files included this header:
- src/config.c:37 #include <mpeg2-ctrls.h>
- src/mpeg2.c:38 #include <mpeg2-ctrls.h>
Both includes were removed in commit B. After this commit:
$ git grep -l 'mpeg2-ctrls' --
(no matches)
The kernel UAPI providing the new MPEG-2 stateless symbols is in
<linux/v4l2-controls.h>, pulled in transitively via
<linux/videodev2.h> (and explicitly in src/mpeg2.c).
include/hevc-ctrls.h is kept untouched per
phase5_iter1_review.md Nit 6 (lower-risk path; HEVC iteration
will delete its corresponding staging header in a separate commit).
Refs:
../fresnel-fourier/phase4_iter1_plan.md (File 3)
../fresnel-fourier/phase5_iter1_review.md (Nit 6)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
5fe873c144 |
fresnel-fourier iter1 Phase 6 commit B: rewrite mpeg2.c against new V4L2 stateless API
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>
|
||
|
|
e7dad7abb5 |
fresnel-fourier iter1 Phase 6 commit A: config.c break for MPEG-2 cases
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> |
||
|
|
65969da3ee |
iter8 Phase 4: tests/run_perf_binding_cell.sh — perf binding cell harness
Anchors campaign-wide claims with measured numbers. Runs four consumer configurations against $FIXTURE for $DURATION seconds each: 1. mpv --hwdec=vaapi (DMA-BUF zero-copy through libva) 2. mpv --hwdec=vaapi-copy (HW decode + VAImage readback) 3. firefox (iter5-amend, sandbox enabled, file:// URL) 4. mpv --hwdec=no (SW decode baseline / control) Captures per consumer: CPU% (median + p90 from pidstat), GPU freq median (from /sys/class/devfreq/fde60000.gpu/cur_freq, polled at 100ms cadence), drops in window (from mpv --term-status-msg), p50 frame interval (mpv only), VmRSS delta (from /proc/PID/status). Emits a markdown table with raw numbers per consumer — no aggregation, no improvement ratios, no curated-benchmark framing. Honest schema including '—' for measurements not available per consumer (e.g. Firefox drops without internal hooks). Phase 5 sonnet review caught 3 issues, all addressed before commit: 1. pidstat $8 column heuristic — replaced with header-driven %CPU field detection (robust across sysstat 12.x point releases) 2. GPU freq median computation used /dev/stdin in nested subshell- over-pipe (unreliable) — replaced with temp-file path 3. --frames=$((DURATION * 30)) hardcoded 30fps (fixture-hardcoding per feedback_no_fixture_hardcoding.md) — replaced with --length=$DURATION (wall-time bounded, framerate-agnostic) Plus minor: empty cpu_pct.log now emits ERR rather than silent 0, distinguishing measurement failure from "process used no CPU." Reproducibility surface: run date, host, kernel, driver sha256, fixture path+size, duration captured in the output markdown. Hardware constants (/dev/video1, /dev/media0, devfreq path, driver install path) are documented as PineTab2 (RK3566 via hantro/rk3568-vpu) specific. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
dcaa1f12e5 |
docs: clarify Rockchip silicon — PineTab2 is RK3566, not RK3568
Surfaced during iter7 Track F research: the campaign target hardware is Rockchip RK3566 silicon (PineTab2). The hantro driver attaches via the rockchip,rk3568-vpu DT compatible because the RK3566 silicon is close enough to RK3568 to share that variant. The proper RK3566 mainline driver target (rkvdec2 / vdpu346) has no kernel support yet — Christian Hewitt's patch series LKML 2025/12/26/206 is unmerged. Updates the two src/ comments that called the hardware "RK3568": - context.c: hantro-vpu device-init S_EXT_CTRLS comment now reads "via rockchip,rk3568-vpu DT compatible (covers RK3568 and RK3566 — PineTab2 silicon — since they're close enough)" - h264.c: DPB pic_num discussion ends "...never surfaced on PineTab2 (RK3566 via hantro/rk3568-vpu)" Not a correctness change. Compiles + decodes identically. The update matters for upstream submission accuracy (bootlin/Rockchip maintainers will care which silicon the campaign tested on). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
7bd0818792 |
iter7 Phase 7 finalization: OUTPUT-pool teardown + test refinements
Surfaced during Phase 7 verification on ohm:
1. **OUTPUT pool stale-slot bug (src/surface.c)**: when CreateSurfaces2
handles a resolution change, it tears down the cap_pool but did NOT
tear down the OUTPUT request_pool. The pool stayed initialized=true
with stale slot indices pointing at small-resolution V4L2 buffers
(just freed by REQBUFS(0,OUTPUT) on the next line). Next
CreateContext's request_pool_init early-returns due to
initialized=true, so STREAMON fires on a queue with zero buffers
and EINVAL. Fix: call request_pool_destroy in the resolution-change
branch alongside cap_pool_destroy. Mirror the cap_pool teardown.
Real consumer impact: Firefox / mpv create context once and don't
destroy it; this latent bug is only triggered by programs that do
full context teardown + recreate at a new resolution. Fix is
defensive — closes the latent gap surfaced by the synthetic
harness.
2. **cap_pool_probe_pattern.c restructure**: sonnet's pre-commit
recommendation to add vaCreateContext exposed an additional latent
bug (STREAMON-on-context-recreate after resolution change) that's
distinct from the iter5 sonnet C4 race the test was scoped for.
Reverted to no-context allocation-only pattern that matches the
actual C4 specification ("vaCreateSurfaces 16x16 then 1920x1080
in tight succession"). The new STREAMON bug is logged as iter8
candidate.
3. **run_cap_pool_probe.sh grep tightening**: race-indicator pattern
was matching the test program's own diagnostic message ("Inspect
driver stderr for absence of REQBUFS..."). Now grep restricts to
lines starting with "v4l2-request:" prefix.
Phase 7 results (clean iter7 driver sha 54999017... + this fix):
- Track A (msync verify): 100 frames byte-for-byte SW=HW (sha
58c8f3f4...) -> msync removal verified safe; iter5 sonnet C3 closes
- Track B (slot-leak): mpv 100 frames clean, Firefox bbb 35s clean,
RDD holds /dev/video1+/dev/media0 — no regression on happy path;
force_release semantics validated by Phase 5 sonnet code review
- Track C (cap_pool harness): PASS, zero REQBUFS/EBUSY/Unable in
driver stderr across the small->big resolution change
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
988b848908 |
iter7: A+B+C — slot-leak fix, cap_pool harness, msync verify harness
Closes three internal carry items in one fork commit. iter6 deferred
these as TODOs; iter7 lands the implementations + supporting tests.
# Track B — slot-leak error recovery (src/)
iter6 documented the RequestSyncSurface error paths as a "bounded
leak we accept" — slots stayed busy=true after REINIT/DQBUF failures
until RequestTerminate ran. With pool=16 and rare errors this was
acceptable, but a sustained-error scenario could starve the pool.
Adds request_pool_force_release(pool, index) which:
1. Tries media_request_reinit on the slot's fd (cheap path)
2. Falls back to close + media_request_alloc (recovery)
3. Leaves the slot dead-busy if even alloc fails (other slots
unaffected, pool capacity reduced by 1 until destroy)
Wires it into surface.c RequestSyncSurface error paths only for
errors before the OUTPUT-DQBUF attempt. After OUTPUT-DQBUF failure
the V4L2 buffer is in indeterminate kernel state, so a separate
error label (`error_buffer_indeterminate`) leaves the slot
dead-busy — reusing the slot would QBUF on a kernel-still-held
buffer and EINVAL.
Phase 5 sonnet review caught this discriminator subtlety pre-commit.
Files: request_pool.{h,c}, surface.c.
# Track C — cap_pool race synthetic harness (tests/)
iter5 sonnet C4 / iter6 candidate A: cap_pool resolution-change
race was organically exercised by YT's quality renegotiations
(iter6 close, 4 cap_pool_init events clean) but had no
deterministic regression test.
tests/cap_pool_probe_pattern.c — ~170-line C program: opens
libva display, vaCreateConfig, vaCreateSurfaces(small) +
vaCreateContext (triggers OUTPUT pool init at small resolution),
dispose, vaCreateSurfaces(big) + vaCreateContext (forces S_FMT
on the new resolution against an in-use OUTPUT pool — the actual
race-hitting path).
Phase 5 sonnet flagged that without vaCreateContext the test
would pass trivially (OUTPUT pool never init'd, REQBUFS(0) on
empty queue is a no-op). Fixed before commit.
tests/run_cap_pool_probe.sh — runner; greps driver stderr for
REQBUFS / EBUSY / "Unable to set format" race indicators.
# Track A — msync pixel-correctness verify harness (tests/)
iter5 sweep removed msync(MS_SYNC|MS_INVALIDATE) from CAPTURE
DQBUF path. iter5 sonnet C3 flagged: no formal pixel verification.
tests/run_msync_pixel_verify.sh — runs FFmpeg SW decode (libavcodec
reference) and FFmpeg HW decode (via our v4l2_request driver),
compares NV12 byte streams. Probes fixture dimensions via ffprobe
and uses crop=$W:$H after hwdownload to normalize MB-padding
artifacts (hantro pads height to 16-line align; SW returns
crop-aligned).
Phase 5 sonnet flagged the stride-mismatch false-failure risk
pre-commit. Fixed: explicit crop + diagnostic that distinguishes
genuine pixel divergence from MB-padding stride artifacts.
# Phase 5 sonnet code review
Verdict: APPROVE-WITH-CHANGES. Three actionable findings, all
addressed before this commit:
1. surface.c error path: separated OUTPUT-DQBUF-failure into
error_buffer_indeterminate label, slot stays dead-busy
2. cap_pool_probe_pattern.c: added vaCreateContext to actually
exercise the OUTPUT pool init at the small resolution
3. run_msync_pixel_verify.sh: explicit crop on HW path,
stride-mismatch diagnostic distinguished from corruption
Empirical verification (Phase 6+7 deploy + run): pending operator
ohm-tools availability.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
a09c03c154 |
iter6 fix: per-OUTPUT-slot request_fd binding via REINIT
iter4 ( |
||
|
|
c8b6edec3d |
iter5 sweep follow-up: remove additional DEBUG sites flagged by Phase 5 review
Phase 5 sonnet review caught four DEBUG sites the first sweep pass
missed (the vaapi-copy + --vo=null stress test didn't exercise the
ExportSurfaceHandle path, so per-frame ExportSurfaceHandle dumps went
undetected).
Removed:
- surface.c::CreateSurfaces2 format-dump (per-CreateSurfaces2 noise,
labeled DEBUG INSTRUMENTATION (surface-export diagnosis 2026-05-04))
- surface.c::ExportSurfaceHandle full-descriptor dump (per-frame for
consumers using DMA-BUF, also labeled DEBUG)
- surface.c::QuerySurfaceStatus -> status= line (per-call noise)
- h264.c V4L2 readback block (~67 lines): static bool readback_warned
+ the per-frame VIDIOC_G_EXT_CTRLS attempt + the readback success
log + the "V4L2 readback unavailable" fallback announcement. With
the iter4 fixes landed, the readback EACCES is no longer load-bearing
to investigate — drop the block + the per-process global state.
Removing the readback block also resolves Phase 5 finding C2: the
static bool readback_warned was new mutable process-global state
introduced post-Track-E, inconsistent with that track's intent.
Net: -107 lines from src/{h264,surface}.c.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
b993355507 |
iter5 Track E: move LAST_OUTPUT_WIDTH/HEIGHT from process-global to per-driver-data
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> |
||
|
|
843febc174 |
iter5 sweep: remove iter1 slice_header parse + VAPicture dump + Sync RETURN trace
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> |
||
|
|
d3a299b4cc |
iter5 sweep: remove iter1 patch-0010 hex-dumps + patch-0011 sentinel
picture.c: remove the 0xab sentinel write into CAPTURE buffer first 32 bytes pre-QBUF + the OUTPUT hex-dump pre-QBUF. Both were iter1 diagnostics for "where does the buffer write go?" investigation. surface.c: remove the post-DQBUF CAPTURE Y-plane hex-dump + luma variance signal. The msync(MS_SYNC|MS_INVALIDATE) was added as a companion fix for the cached-mmap issue surfaced by the dump itself — removing the dump removes the need for the msync. With iter1+iter2+iter3+iter4 fixes landed, these dumps fire on every single frame and produce hundreds of MB of log noise during sustained decode. Now gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
951233a12e |
iter5 sweep: remove iter1 ENTER traces (13 call sites across 4 files)
Removes the iter1 patch-0014 ENTER traces from buffer.c, image.c, picture.c, surface.c. These were diagnostic-only entry-point logs added during iter1's "where does Firefox RDD crash?" investigation. With the iter1+iter2+iter3+iter4 fixes landed, the entry-point traces are pure noise. If a future investigation needs entry-point coverage, strace -e trace on the libva consumer process gives equivalent visibility without modifying the driver. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
39498f0d8e |
iter5 sweep: remove iter4 DPB census instrumentation from h264.c
Removes the pre-S_EXT_CTRLS DPB census + per-entry dump that helped
diagnose iter4's frame-11 EINVAL bug. With the fix landed (
|
||
|
|
848fc0c4c4 |
iter5 sweep: remove iter3+iter4 Y2 instrumentation from v4l2.c
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 (
|