Files
ampere-kernel-decoders/phase3_baseline_iter2.md
marfrit f5e681caf5 iter2 phase3: HEVC BEFORE-state baseline
HEVC OOPS reproducer captured with strace ioctl trace. Backend
submits 4 VIDIOC_S_EXT_CTRLS (existing SPS/PPS/SCALING_MATRIX/
DECODE_PARAMS) and 1 MEDIA_REQUEST_IOC_QUEUE, kernel faults in
rkvdec_hevc_prepare_hw_st_rps -> __pi_memcmp during processing of
that single request, ffmpeg hangs (m2m wedged), needs SIGKILL.

ZERO V4L2_CID_STATELESS_HEVC_EXT_SPS_*_RPS calls in trace —
corroborates iter2 hypothesis that the backend never sets the new
7.0-UAPI controls. Confirms by independent evidence (in addition
to grep of source which already showed zero hits).

Phase 7 prediction table: VIDIOC_S_EXT_CTRLS 4 -> 6, QBUF 2 -> 10
(for 5 frames), MEDIA_REQUEST_IOC_QUEUE 1 -> 5, dmesg empty
(no new rkvdec_hevc_prepare_hw_st_rps oops).

Falsifier anchor F1: if the trace re-appears post-patch, iter2 loops
back to Phase 0 with re-opened kernel-agent#11.

ampere is in wedged-m2m state post-capture; reboot needed before
Phase 6 / Phase 7. Documented as pre-action for those phases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 08:48:12 +00:00

6.1 KiB

Phase 3 — iter2 baseline measurements (HEVC BEFORE-state)

Captured 2026-05-16 10:42 CEST. Anchors what the kernel + backend currently do (and DON'T do) for HEVC, against which Phase 7 will verify the iter2 patch produces the predicted delta.

iter2 inherits the ampere-fourier iter1 baseline for the 3 working codecs (H.264 / VP8 / MPEG-2) as reference history. iter2 Phase 3 captures one additional artefact: the HEVC OOPS reproducer instrumented with strace, so we know exactly which ioctls (and how many) the current backend issues before the kernel wedges.

HEVC OOPS reproducer (iter2 BEFORE-state)

System state at capture:

  • ampere uptime 1:24 (post-SDDM-auto-login restart; no stale wedge)
  • Backend /usr/lib/dri/v4l2_request_drv_video.so md5 0c9a7efaab… (the hand-built 7ac934e from ampere-fourier iter1)
  • dmesg pre-capture: clean (last kernel msg from 10:36, devfreq frequency-update warning unrelated to media)
  • Kernel 7.0.0-rc3-devices+, unchanged from iter1

Invocation (with strace per-thread capture):

strace -ff -e trace=ioctl -o /tmp/iter2_before.strace \
    -- env LIBVA_DRIVER_NAME=v4l2_request \
        timeout 8 ffmpeg -hide_banner -loglevel error \
            -hwaccel vaapi -hwaccel_output_format vaapi \
            -i ~/measurements/encoded/bbb_60s_720p.hevc.mp4 \
            -vf "hwdownload,format=nv12" -frames:v 5 -f null -

Outcome: ffmpeg hangs after submitting first request → timeout 8 SIGTERM doesn't take effect (kernel m2m wedged) → manual kill -9 of strace + ffmpeg required.

ioctl pattern (24 strace files per ffmpeg, aggregated)

     84 VIDIOC_ENUM_FMT
     40 VIDIOC_QUERYBUF
      4 VIDIOC_S_EXT_CTRLS
      3 VIDIOC_G_FMT
      2 VIDIOC_S_FMT
      2 VIDIOC_STREAMON
      2 VIDIOC_QBUF
      2 VIDIOC_CREATE_BUFS
      1 VIDIOC_QUERYCAP
      1 MEDIA_REQUEST_IOC_QUEUE

Read of this pattern:

  • 84 ENUM_FMT — capability probing of all 3 backend-tracked fds (rkvdec, hantro, plus iter38 alt-probe walking).
  • 2 STREAMON + 2 CREATE_BUFS + 2 S_FMT — one OUTPUT + one CAPTURE setup, single decode-context cycle.
  • 4 VIDIOC_S_EXT_CTRLS — corresponds to the backend's 5 standard HEVC controls registered at h265.c:660-688 (SPS, PPS, SLICE_PARAMS, SCALING_MATRIX, DECODE_PARAMS). The "4" count is per-strace-fd; submitted as one ioctl carrying all controls but counted on each thread the backend touched.
  • 1 MEDIA_REQUEST_IOC_QUEUE — backend submitted exactly ONE request, the kernel started processing it, and that's when rkvdec_hevc_prepare_hw_st_rps faulted in __pi_memcmp.
  • 0 VIDIOC_S_EXT_CTRLS for V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS or _LT_RPS — confirmed by absence in strace text (and by source-grep against the backend, which has zero references to these CIDs).

The ioctl count summary IS the BEFORE-state contract for Phase 7. After iter2 patch the predicted delta:

ioctl BEFORE AFTER prediction Reasoning
VIDIOC_ENUM_FMT 84 ~84 (unchanged) Capability probing is at init; iter2 patch doesn't add to it
VIDIOC_QUERYCTRL 0 in trace 2 added (probe for each new CID at init) Runtime probe per Phase 1 spec
VIDIOC_S_EXT_CTRLS 4 6 (per-frame, plus per-init) Adding EXT_SPS_ST_RPS + EXT_SPS_LT_RPS
VIDIOC_QBUF 2 ~10 (for -frames:v 5 → 5 OUTPUT + 5 CAPTURE) Decode proceeds beyond first frame
MEDIA_REQUEST_IOC_QUEUE 1 5 One per decoded frame
dmesg new lines OOPS trace empty (no rkvdec_hevc_prepare_hw_st_rps fault) C6

Kernel OOPS trace (BEFORE-state, captured fresh)

dmesg fragment for --time-format=ctime 'Sat May 16 10:42:24':

[Sat May 16 10:42:24 2026]  media_request_ioctl+0xc8/0x160 [mc]
[Sat May 16 10:42:24 2026]  __arm64_sys_ioctl+0xa4/0x100
[Sat May 16 10:42:24 2026]  invoke_syscall.constprop.0+0x40/0xf0
[Sat May 16 10:42:24 2026]  el0_svc_common.constprop.0+0xb8/0xd8
[Sat May 16 10:42:24 2026]  do_el0_svc+0x1c/0x28
[Sat May 16 10:42:24 2026]  el0_svc+0x30/0xc8
[Sat May 16 10:42:24 2026]  el0t_64_sync_handler+0xa0/0xe4
[Sat May 16 10:42:24 2026]  el0t_64_sync+0x198/0x19c
[Sat May 16 10:42:24 2026] Code: d503245f f1002042 54000643 f8408403 (f8408425)
[Sat May 16 10:42:24 2026] ---[ end trace 0000000000000000 ]---

(Top of the trace not captured here — dmesg | grep -A cut it off; full trace at ampere-fourier iter1 Phase 0 with the same stack: rkvdec_hevc_prepare_hw_st_rps+0x38/0x300 [rockchip_vdec]__pi_memcmp+0x10/0x110rkvdec_hevc_assemble_hw_rps+0x1c/0xacrkvdec_hevc_runrkvdec_device_runv4l2_m2m_try_runv4l2_m2m_request_queuemedia_request_ioctl_queue → above.)

OOPS is reproducible 100% post-reboot. Cascade behaviour confirmed: m2m wedges; subsequent decode attempts hang. Same as iter1 Phase 0 finding.

Falsification anchor for Phase 7

The iter2 patch is judged F1 (kernel still OOPSes despite valid RPS data) if after the patch the dmesg rkvdec_hevc_prepare_hw_st_rps trace re-appears for an HEVC decode. The before-state trace above is the literal pattern that must NOT recur.

If F1 fires, iter2 loops back to Phase 0 with re-opened kernel-agent#11 and richer evidence: "even with valid GStreamer-parser-sourced RPS data + runtime-probed control submission, the kernel still faults — mechanism is something other than UAPI-gap."

Phase 7 success-criterion-7 (C7 carry-over) anchor

C7 (firefox-fourier vendor-default HEVC engagement) is now testable post-SDDM-auto-login. iter2 Phase 7 will run the empty-profile sweep adapted from ampere-fourier's earlier ~/measurements/firefox-test-v2/sweep.sh with HEVC added. Not iter2-blocking.

Phase 3 close

iter2 BEFORE-state captured: HEVC OOPS reproducible, exact ioctl sequence pre-wedge documented (84 ENUM_FMT, 40 QUERYBUF, 4 S_EXT_CTRLS, 1 MEDIA_REQUEST_IOC_QUEUE), zero EXT_SPS_*_RPS calls (corroborates iter2 hypothesis), predicted AFTER-state delta tabulated. Phase 7 has a concrete contract to verify against.

Ampere is in a wedged-m2m state post-capture; next iter2 phase touching the kernel needs a reboot first. Documented as a Phase 6 / Phase 7 pre-action.