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)
Stock Debian trixie ships FFmpeg 7.1 (libavcodec.so.61), our fork
ships FFmpeg 8.1 (libavcodec.so.62) — different SONAMEs, NOT a
drop-in for trixie's libavcodec61-consuming desktop. Previous
Conflicts: libavcodec61, libavformat61, ... triggered apt to remove
~50 packages (kde-plasma-desktop, vlc, dolphin, ...) when a user
just wanted ffmpeg-v4l2-request-fourier installed alongside.
This commit:
1. ffmpeg-v4l2-request-fourier (pkgrel=2):
- --prefix=/opt/fourier (instead of /usr)
- --extra-ldexeflags / --extra-ldsoflags: -Wl,-rpath,/opt/fourier/lib
so /opt/fourier/bin/ffmpeg finds its own libs without external help
- Ship /etc/ld.so.conf.d/fourier.conf with /opt/fourier/lib + ldconfig
in postinst/postrm. dlopen-by-SONAME consumers (firefox, daedalus)
find libavcodec.so.62 via ld.so cache without LD_LIBRARY_PATH.
- Drop ALL Conflicts/Replaces/Provides for libav* / libpostproc /
libsw* — no SONAME clash with stock libavcodec61, no reason to
evict anything.
- /usr/bin/ffmpeg-fourier + ffprobe-fourier convenience symlinks.
2. daedalus-v4l2 (pkgrel=2):
- Depends: ffmpeg-v4l2-request-fourier (>= 2:8.1+rfourier)
instead of stock 'ffmpeg (>= 7.1)'. The daedalus binary was
linked against libavcodec.so.62 at build time (CI runner had
marfrit/ffmpeg-v4l2-request-fourier installed); at runtime it
needs the .so.62 that only the fourier pkg provides.
Not touched:
- libva-v4l2-request-fourier: ships only v4l2_request_drv_video.so
at /usr/lib/<triplet>/dri/ which libva dlopens by file pattern.
Path A would break the lookup unless every consumer launcher sets
LIBVA_DRIVERS_PATH. Driver name is unique; no conflict. STAY.
- mpv-fourier: Depends already correctly bound to fourier ffmpeg.
Will receive libavcodec.so.62 via the ld.so.cache mechanism
above without recipe changes.
Mirror of arch/ffmpeg-v4l2-request-fourier into the Debian tree.
Same source pin (Kwiboo v4l2-request-n8.1 @ b57fbbe), same 2
patches (libudev-bypass-fallback + nv15-to-p010-unpack), same
configure flag policy (drop X11/AMF/CUDA/Bluray/Vulkan/SDL2/etc.
per Fourier fleet focus).
Output: single .deb at /usr/bin/ffmpeg + /usr/bin/ffprobe +
/usr/lib/aarch64-linux-gnu/libav*.so.61. Conflicts/Replaces
the stock Debian ffmpeg + per-lib packages; takes epoch 2
(matches Debian's existing ffmpeg epoch).
Provides 'ffmpeg -hwaccel v4l2request' + '-hwaccel drm' routes
that drive rkvdec / hantro / cedrus / rpi-hevc-dec /
daedalus_v4l2 stateless decoders through libavcodec's hwdevice
DRM path, bypassing libva. Required by mpv-fourier and
firefox-fourier as their backing FFmpeg; also the kdirect
bit-exact reference for libva-v4l2-request-fourier validation.
NOT strictly required for the VAAPI-only path on
daedalus-v4l2 hosts (stock Debian ffmpeg + libva-v4l2-request-
fourier covers that). Install only when going firefox-fourier
or kdirect.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>