The original 0005 patch was generated from the pre-Phase-5-review source
snapshot (phase5_review_input_2026-05-21.tgz), missing the four
load-bearing review fixes that landed in the post-review snapshot:
- probe_hantro gate on KHR_video_* extension advertisement
- per-session ts_counter (was process-global static)
- panvk_v4l2_session_finish full unwind (munmap + STREAMOFF + REQBUFS=0)
- MIN2(rb.count, 18) clamp on num_*_buffers
Run #162 (job 17032) failed in prepare() because the PKGBUILD sanity
check 'grep -q "KHR_video_queue = PAN_ARCH < 9 && panvk_v4l2_probe_hantro()"'
didn't match the actual patched output (which still had the pre-review
'KHR_video_queue = PAN_ARCH < 9,').
This patch (regenerated from phase5_post_review_2026-05-21.tgz) carries
all four review fixes. Validated locally: vanilla mesa-26.0.6 + r1..r4 +
this patch reproduces prepare()-OK byte-for-byte.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The original PR #79 used symlinks for 0001..0004 patches (pointing into
../mesa-panvk-bifrost/) to avoid drift between siblings. CI's
"cp -r arch/mesa-panvk-bifrost-video /tmp/build-..." preserves the
symlinks, but the destination /tmp/build-... has no sibling dir to
resolve them against, so makepkg errors with:
==> ERROR: 0001-panvk-expose-robustness2-nullDescriptor-bifrost.patch
was not found in the build directory and is not a URL.
Each Arch PKGBUILD owns its source files per convention; the
duplication risk is low because r1..r4 are closed-release patches.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The merge commit for PR #79 (e7cc22e42) did not auto-fire the
Gitea Actions workflow despite touching paths matched by the
build.yml filter (arch/** + .gitea/workflows/**). No run row
exists between #160 (PR #78 merge) and now. This README touch
is a no-op content change to force a fresh workflow_dispatch
through the standard push trigger.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Gitea debian-aarch64 runner has been upgraded past Debian trixie
and now ships libxml2 ≥ 2.14 (SONAME 16) while higgs (and any other
trixie target) still has libxml2 2.12 (SONAME 2). -5 built cleanly,
but on higgs the daedalus-v4l2 daemon's dlopen of libavformat.so.62
fails:
dlopen(libavformat.so.62): libxml2.so.16:
cannot open shared object file: No such file or directory
Drop --enable-libxml2 from the Debian configure invocation; remove
the libxml2 entry from Depends; remove libxml2-dev from the CI
build-deps. FFmpeg's libxml2-backed DASH demuxer is unused on the
Fourier fleet — daedalus-v4l2 daemon feeds AVPackets straight to
avcodec_send_packet (no demux); mpv-fourier uses ytdlp + mpv's own
stream code; firefox-fourier uses gecko-media's DASH demux.
Bumps PKGREL 5 → 6. No source code or substitution-patch change.
Mirrors the libva trixie/runner ABI-skew workaround pattern
(marfrit-packages PR #62).
Arch PKGBUILD unaffected — Arch runner + Arch consumers both
rolling, libxml2 SONAMEs match.
After this lands, re-deploy on higgs via:
sudo apt update && sudo apt install -y ffmpeg-v4l2-request-fourier
sudo systemctl restart daedalus-v4l2
panvk-bifrost-video campaign close. Phase 4 byte-exact validated
2026-05-21 on RK3566/PineTab2 (Mali-G52 r1 MC1 + hantro VPU): 48/48
unique BBB display frames decoded by this driver are byte-identical
to ffmpeg+libva-v4l2-request-fourier on the same hantro hardware
(frame 42 Y md5 = 54b9b396e6cd377256eb4bce0efc0bed both ways).
Phase 5 second-model review passed; load-bearing findings applied.
Co-installs at /usr/lib/panvk-bifrost-video/ parallel to the r4
sibling at /usr/lib/panvk-bifrost/; opt-in via VK_ICD_FILENAMES.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR #76 (H.264 IDCT 4×4 daedalus-fourier substitution) was merged but
the resulting .deb was not actually built: an orphan
ffmpeg-v4l2-request-fourier_8.1+rfourier+gb57fbbe-4_arm64.deb (dated
2026-05-19, no matching source commit in main) sat in the apt pool.
.gitea/scripts/check-already-published.sh's debian branch compares
`dpkg --compare-versions $pool_ver ge $source_full` — pool -4
≥ source -3, so CI's skip-check emitted skip=1 and short-circuited
the build. The ffmpeg-v4l2-request-debian Action reported success
without actually publishing.
Bump source PKGREL past -4 so the next CI run sees source >= pool
and proceeds to build + publish.
No source code change beyond PKGREL + changelog. Arch side
unaffected (its skip-check is exact-URL-match, not pool-head-ge).
The ffmpeg-v4l2-request-debian job now needs to build daedalus-fourier
into a temp prefix before configuring FFmpeg (substitution patch
0003-h264-idct4-daedalus-fourier.patch links libdaedalus_core.a into
libavcodec.so). Mirror the build-deps the daedalus-v4l2-debian job
already declared for the same reason.
No-op on Arch — makepkg --syncdeps auto-installs cmake/ninja/
vulkan-headers from the PKGBUILD makedepends.
First cycle of the libavcodec.so substitution arc (reauktion/daedalus-v4l2#11
step 2). H264DSPContext.idct_add — called per 4×4 block from the
intra-4×4 decode path in libavcodec/h264_mb.c — now dispatches through
daedalus_recipe_dispatch_h264_idct4 instead of ff_h264_idct_add_neon.
## What
- Add 0003-h264-idct4-daedalus-fourier.patch (in both arch/ and
debian/ ffmpeg-v4l2-request-fourier/). Creates
libavcodec/aarch64/h264_idct_daedalus.c (ff_h264_idct_add_daedalus
shim + lazy pthread_once context init via
daedalus_ctx_create_no_qpu), patches
libavcodec/aarch64/h264dsp_init_aarch64.c to wire c->idct_add to
the shim, adds the new .o to libavcodec/aarch64/Makefile.
- arch/PKGBUILD + debian/build-deb.sh: fetch + build
daedalus-fourier (pinned at d87239d — lockstep with the
daedalus-v4l2 daemon's inline build) with
-DCMAKE_POSITION_INDEPENDENT_CODE=ON into a per-build temp prefix,
then pass --extra-cflags=-I.../include --extra-ldflags=-L.../lib
--extra-libs="-ldaedalus_core -lvulkan -lpthread" to FFmpeg
configure. daedalus_core.a is static-linked into libavcodec.so.62.
- debian/control Depends gains libvulkan1 (daedalus_core PUBLIC-links
Vulkan::Vulkan for the queryable QPU substrate; the no-QPU
constructor still works at runtime but the loader needs
libvulkan.so.1 present to dlopen libavcodec.so.62).
- arch/PKGBUILD depends gains vulkan-icd-loader, makedepends gains
cmake / ninja / vulkan-headers.
## Why
The recipe layer picks the substrate; for cycle 6 (H.264 IDCT 4×4)
the recipe is CPU NEON, so this is effectively a NEON-to-NEON
substitution with one extra dispatch call and recipe-table lookup.
The point of this first cycle isn't perf wins — it's plumbing. Once
the path is wired and stable, follow-up patches batch through the
bulk paths (idct_add16 / idct_add16intra / idct_add8) and stack
cycles 7/8/9 (IDCT 8×8, luma-v deblock, qpel mc20).
Bit-exact against ff_h264_idct_add_neon (daedalus-fourier cycle 6
green; FFmpeg's 4×4 block storage matches daedalus's column-major
convention).
## Scope NOT covered
- Bulk paths (idct_add16 / idct_add16intra / idct_add8) — most IDCT
4×4 calls in real H.264 streams go through these, not the per-
block c->idct_add path; intra-4×4-only macroblocks are a minority.
Batched substitution lands in a follow-up.
- High-bit-depth (10-bit) path — not touched; 8-bit only.
- Cycles 7/8/9 — separate PRs.
## SONAME
Unchanged. libavcodec.so.62 / libavformat.so.62 / libavutil.so.60.
No daedalus-v4l2-dkms or daedalus-v4l2 bump required.
## Refs
- reauktion/daedalus-v4l2 issue #11 (substitution arc): reauktion/daedalus-v4l2#11
- marfrit/daedalus-fourier cycle 6 close (H.264 IDCT 4×4 NEON green)
The daedalus-v4l2 build-deb.sh (post marfrit-packages#72) now fetches
+ cmake-builds daedalus-fourier into a per-build temp prefix before
building the daemon, so the static-archive can be linked in.
daedalus-fourier's CMakeLists requires Vulkan headers and glslangValidator
(for SPIR-V compilation of the .comp compute shaders). Without them
the configure step on the debian-aarch64 runner fails with:
CMake Error at FindPackageHandleStandardArgs.cmake:233 (message):
Could NOT find Vulkan (missing: Vulkan_LIBRARY Vulkan_INCLUDE_DIR)
(Observed on Gitea Actions run 1056.)
Add `libvulkan-dev` and `glslang-tools` to the apt-get install line so
the in-build daedalus-fourier compile succeeds and the daemon can link.
Daemon-only bump (no daedalus-v4l2-dkms change needed; PROTO_VERSION
stays at 0).
#12 (LOW_DELAY half-measure): daemon sets AV_CODEC_FLAG_LOW_DELAY on
the H.264 AVCodecContext so libavcodec emits frames in decode order
~99% of the time (a few stragglers at GOP boundaries when the
stream's SPS num_reorder_frames overrides the flag). Visible
improvement vs the 2-1-4-3 pair-swap on Firefox + mpv playback;
not the permanent fix — see daedalus-v4l2#11 for the architectural
plan to substitute daedalus-fourier kernels for libavcodec's
pixel math one cycle at a time.
#13 (daedalus-fourier linkage): daemon now pkg-config-links against
the daedalus-fourier kernel library (marfrit/daedalus-fourier) and
logs substrate availability at startup. No kernels dispatched yet
— this is the build-time foundation for the substitution work.
build-deb.sh updated to fetch + build + install daedalus-fourier
(pinned at d87239d, marfrit/daedalus-fourier PR #1) into a per-
build temp prefix before invoking the daemon's cmake, exposing it
via PKG_CONFIG_PATH. Static-linked, so the resulting .deb has no
new runtime deps. Requires libvulkan-dev + glslang-tools on the
CI runner.
Arch PKGBUILD bumped to the same upstream commit but Arch packaging
for daedalus-fourier itself is a follow-up; until that lands the
Arch build expects daedalus-fourier installed by the user (AUR-style).
Debian-side is end-to-end self-contained via build-deb.sh.
Refs:
* reauktion/daedalus-v4l2#12
* reauktion/daedalus-v4l2#13
* reauktion/daedalus-v4l2#11
* marfrit/daedalus-fourier#1
Lock-step downgrade of both packages to the revert tip of
daedalus-v4l2 (PR #10 closed PRs #7 + #8). After
0.1.0+r28+g79256dc-1 / 0.1.0+r30+g6ffe92b-1 landed in production,
mpv (--hwdec=vaapi-copy) failed pre-playing with "Unable to dequeue
buffer: Resource temporarily unavailable" because the daemon
parked CAPTURE buffers waiting for libavcodec's display-order
reorder, violating libva's V4L2 stateless 1:1 contract. See
daedalus-v4l2#9 for the diagnostic, #10 for the revert PR.
DAEDALUS_PROTO_VERSION drops 1 → 0; install both .debs in the same
apt transaction. Userspace ABI returns to the f0d4186-equivalent
behaviour, plus PR #4 (cosmetic H.264 menu controls). The
daedalus-v4l2-dkms #64 multi-kernel postinst behaviour stays in
build-deb.sh.
Visible regression: H.264 B-frame streams in Firefox return to the
"2 1 4 3 6 5" pair-swap visual. Proper fix (concurrent in-flight
requests in daemon + display-order reorder moved into libva-v4l2-
request-fourier) tracked at daedalus-v4l2#11.
Refs:
* reauktion/daedalus-v4l2#9
* reauktion/daedalus-v4l2#10 (merged)
* reauktion/daedalus-v4l2#11
iter17 closes the 162 winding_* CTS failures from iter15's baseline by
replacing the upstream pan_nir_lower_xfb call with a panvk-specific NIR
pass (panvk_per_arch(nir_lower_xfb)) that handles per-primitive
decomposition for non-LIST topologies (LINE_STRIP, TRIANGLE_STRIP,
TRIANGLE_FAN, and the four _WITH_ADJACENCY variants).
Topology + per-instance output vertex count are threaded as new sysvals
(vs.xfb_topology + vs.xfb_output_count) so the NIR pass can dispatch
per-topology at runtime without compiling 7+ shader variants.
dEQP-VK.transform_feedback.simple.* result (133596 cases total):
iter15 baseline -> iter17
Pass: 796 958 (+162)
Fail: 243 81 (-162; resume_* by-design only)
NotSupported: 132551 132551
Fatal-skip: 6 6
Pass rate of runnable: 76.2% -> 91.7% (+15.5pp)
100% of the iter15 winding-fail cluster closed. The remaining 81 fails
are all resume_* (pause/resume XFB, by design — we advertise
transformFeedbackDraw=false).
Second-model review (janet) produced 3 findings; Findings 1+2 were
already fixed in the in-tree applied state (stale applied_state/ snapshot
read by reviewer), Finding 3 (degenerate N underflow on N<2) addressed
by gating non-LIST emission on `output_count > 0` predicate.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Kernel-only bump. Fixes the hard-reboot regression introduced by
the daedalus-v4l2#7 split-completion design and observed on higgs
(Pi CM5) during the first mpv vaapi-copy playback of 720p H.264:
device_run now removes src + dst from m2m_ctx's rdy_queue at the
moment it picks them up, not at buf_done time. Without this, a
parked dst_buf (waiting for libavcodec's display-order release)
stayed in the rdy_queue and got re-picked by the next device_run
after SRC_CONSUMED's job_finish released the scheduler — two
inflight entries on the same vb2_buffer, later HAS_PIXELS calls
list_del on an already-detached list_head, panic.
DAEDALUS_PROTO_VERSION stays at 1 — daemon (userspace
daedalus-v4l2) need NOT bump in lockstep with this DKMS update.
The existing daedalus-v4l2 0.1.0+r28+g79256dc is wire-compatible
with daedalus-v4l2-dkms 0.1.0+r30+g6ffe92b.
Refs:
* reauktion/daedalus-v4l2#8
Bumps both Arch PKGBUILD and Debian build-deb.sh pins to PR #16 —
codec_store_buffer + request_pool_resize transparent OUTPUT-pool grow
on a mid-session resolution upshift overrun. Picks up the frame-
survival path that supersedes #13's drop-and-recreate fallback.
Dual-pin per feedback_marfrit_packages_dual_pin so both Arch and
Debian repos see check-already-published.sh report a new version.
Lock-step bump of both packages to daedalus-v4l2#7 + #4. PROTO_VERSION
bumps 0 → 1 at the daemon ↔ kernel chardev wire: REQ_DECODE adds
__u64 src_pts (the OUTPUT vb2 timestamp); RESP_FRAME adds __u32 flags
(HAS_PIXELS / SRC_CONSUMED) + __u64 output_src_pts (= frame->pts on
drain). Both .debs must be installed atomically or the chardev
handshake rejects the version mismatch.
* daedalus-v4l2: daemon's send_packet → receive_frame loop now
stamps pkt->pts = req->src_pts and looks up the cookie for each
drained frame via frame->pts. chardev_client emits multiple
RESP_FRAME messages per REQ_DECODE when libavcodec's display-
order DPB releases an earlier frame on receipt of a later
bitstream — fixes the "2 1 4 3 6 5" pair-swap on H.264 streams
with B-frames.
* daedalus-v4l2-dkms: kernel device_run mirrors src_buf timestamp
into REQ_DECODE.src_pts. Completion path splits HAS_PIXELS /
SRC_CONSUMED: src is released as soon as send_packet succeeds
(so the m2m scheduler moves on), dst stays parked until the
matching frame is drained later. TIMESTAMP_COPY's auto src→dst
pairing no longer applies once lifecycles decouple — dst is
stamped explicitly from inflight->src_pts at HAS_PIXELS time.
* daedalus-v4l2-dkms also carries forward the -2 multi-kernel
postinst fix (#64) from the prior PKGREL. PKGREL resets to 1 on
the new upstream pin.
The daedalus-v4l2#4 H.264 DECODE_MODE + START_CODE menu controls (a
cosmetic warning fix that PR landed alongside #7) is also subsumed —
"Unable to set control(s) error_idx=2/2" no longer fires.
Refs:
* reauktion/daedalus-v4l2#7
* reauktion/daedalus-v4l2#4
* reauktion/daedalus-v4l2#6
Bumps both the Arch PKGBUILD and the Debian build-deb.sh pins to PR
#14 merge — codec_store_buffer bounds-checks for VASliceDataBufferType.
Picks up the SIGSEGV fix for mpv --hwdec=vaapi-copy on resolution
upshift mid-stream (issue #13).
Dual-pin so check-already-published.sh detects both pool ABIs as
needing a fresh build.
Previously dkms autoinstall ran only against $(uname -r), so installing
the package on kernel A and rebooting into separately-installed kernel B
left /lib/modules/B/updates/dkms/ empty. /dev/daedalus-v4l2 absent,
daedalus daemon nothing to talk to, browser/VAAPI silently falling back
to software with no obvious diagnostic for the user.
Now we enumerate every /lib/modules/*/build that resolves to a real
directory (i.e. headers are actually installed for that kernel) and run
'dkms autoinstall -k <kver>' for each. Per-kernel verify; aggregated
warning only for the kernels that didn't build.
Tested locally: enumeration filters dangling /build symlinks correctly
(2 kernels installed, 1 has headers → only that one is built against).
Bumps PKGREL 1 → 2. Closes#64.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Closes#60.
Resolves the malformed-patch issue from #61 (since reverted in #62)
by regenerating the 0003 patch via actual application against firefox
150.0.3 Pi-OS source.
Functional change vs prior 0003: walking hw_configs accepts
AV_HWDEVICE_TYPE_DRM (legacy) OR integer device_type values 13/14
(AV_HWDEVICE_TYPE_V4L2REQUEST in Kwibos no-AMF / upstream-AMF trees).
CreateV4L2RequestDeviceContext passes integer 13 (Kwibos value) cast
to enum AVHWDeviceType for the av_hwdevice_ctx_create call.
Tested: applied cleanly via patch -p1 against firefox-150.0.3 source
post-Pi-OS-quilt-patches. Test build follow-up in firefox-rpios EC2
script (drops the in-source sed hack from v7-v8).
Closes part of #60 (firefox-side patch update for fourier2 ffmpeg).
Background: libavcodec61-fourier2 (Kwiboo v4l2-request-n7.1.3 backed)
registers its hwaccels with AV_HWDEVICE_TYPE_V4L2REQUEST (the dedicated
enum added in FFmpeg 7.1+), not AV_HWDEVICE_TYPE_DRM as fourier1 did.
The firefox-fourier patch #3 walked hw_configs looking only for DRM
and fell through to software for every codec.
Patch updates:
- CreateV4L2RequestDeviceContext now takes an int aDeviceType (Mozillas
bundled libavutil headers may lack the V4L2REQUEST enumerator), passed
through to av_hwdevice_ctx_create.
- hw_configs walk accepts DRM (legacy) OR V4L2REQUEST integer value
(13 on Kwibooss no-AMF tree, 14 on upstream-AMF tree).
- Renamed mDRMDeviceContext to mV4L2RequestDeviceContext for accuracy.
Build pkgrel will be bumped at debian-package level to +fourier2.
Upstream PR #3 — kernel per-context vb2_queue lock so concurrent
clients of /dev/video0 don't serialise on a device-wide mutex.
Pi 5 Firefox VAAPI playback (RDD + content + GPU processes each
opening the device) now works without S_FMT EBUSY collisions.
Verified on higgs: YouTube playback engages daedalus at sustained
~230 fps decode through the libavcodec dlopen path, ~7× headroom
over the 30fps@1080p Pi 5 Fourier target.
Both packages: pkgver 0.1.0.r24.f0d4186, pkgrel reset to 1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bumps both Arch (PKGBUILD) and Debian (build-deb.sh) sides in one commit
this time — following the dual-pin lesson from PR #53.
77f9236 = libva PR #12 merge: src/av1.{c,h} implements av1_set_controls
mapping VAPictureParameterBufferAV1 onto struct v4l2_ctrl_av1_sequence,
queued via S_EXT_CTRLS as V4L2_CID_STATELESS_AV1_SEQUENCE. The
daedalus_v4l2 daemon track will consume the ctrl to synthesise an
OBU_SEQUENCE_HEADER and prepend it to the slice bitstream, so libdav1d
can parse the OUTPUT buffer that ffmpeg-vaapi delivers without the
sequence header.
Until the daemon-side OBU synth lands (issue #11 operator track), the
SEQUENCE ctrl is just sitting in the request unused. Harmless on the
RK3588 vpu981 hardware path (vpu981 parses OBU bytes directly, ignores
the ctrl payload).
pkgver: r382.c1bb444 -> r386.77f9236 (commit count 382 -> 386, two new
upstream commits: 9fa18f2 av1 + 77f9236 merge).
pkgrel: 1 (fresh pkgver, no rebuild-only iteration).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Closes#55.
PR #47 routed ffmpeg-v4l2-request-debian and mpv-fourier-debian to
runs-on: debian-aarch64 (bohr), but their install-deps steps still
called pacman -Syu. That is a latent break that would surface on the
next pkgver bump (currently silent-skipped by check-already-published.sh
since pool versions match the staged PKGVER).
This patch follows PR #50's pattern (daedalus-v4l2{,-dkms}-debian):
- Replace retry pacman -Syu ... with retry apt-get install ...
- Translate Arch package names to Debian (base-devel -> build-essential,
pkgconf -> pkg-config, libdrm -> libdrm-dev, x264 -> libx264-dev, etc.).
- For mpv: drop the "configure [marfrit] repo + pre-install
ffmpeg-v4l2-request-fourier" step entirely. Under apt, stock
libavcodec-dev / libavformat-dev / libavutil-dev provide trixie-ABI
headers matching what mpv-fourier's binary will see at runtime; the
daemon dlopens the fourier libs if installed but doesn't link against
them at build time.
Validated upstream: equivalent debian build-deps installed cleanly in
PRs #44 (libva) and #50 (daedalus).
Upstream PR #2 landed the one-line kernel fix that was the missing
half of issue libva-v4l2-request-fourier#8: device_run now calls
v4l2_ctrl_request_setup() before reading ctrl->p_cur, so the
daedalus_h264_meta the daemon receives reflects the in-flight
media_request's bound H.264 stateless control values instead of
stale/default ones.
Pairs with libva-v4l2-request-fourier 1.0.0+r382+gc1bb444 (max_num_
ref_frames fallback + Fix 4 instrumentation that exposed the
control-binding gap in the first place).
Effect on Pi 5 / CM5 hosts (higgs): ffmpeg -hwaccel vaapi against
H.264 sources now produces actual decoded content (per-frame
fnv1a hashes differ, zero MB-decode errors) instead of the
constant 0x6a6a05c5 "best-effort give-up" hash and cascading
decode warnings.
Both packages: pkgver 0.1.0.r22.462aa4b, pkgrel reset to 1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>