From 2732a022f813db275d2d49372fa0374867609fa3 Mon Sep 17 00:00:00 2001 From: claude-noether Date: Mon, 25 May 2026 14:05:56 +0200 Subject: [PATCH] ffmpeg-v4l2-request-fourier: route remaining H.264 qpel 8x8 positions through daedalus-fourier (0012) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the H.264 qpel substitution. Extends 0007 (which routed only mc20 put_) to ALL 15 useful positions in BOTH the put_ and avg_ tables, skipping mc00 (integer copy / pointer-only fast path). 29 substitutions total: 14 new put_ + 15 avg_. Each wraps a single daedalus_recipe_dispatch_h264_qpel_{avg_,}mcXY call (the dispatches landed in daedalus-fourier PRs #15-#20). Collapsed via a single DEFINE_QPEL_WRAPPER macro on the libavcodec shim side so the diff is uniform. All recipe-table entries route AUTO to CPU NEON — no QPU shaders for any qpel position other than mc20 yet. Plumbing-only NEON-to-NEON via the daedalus recipe layer; bit-exact against the in-tree ff_*_h264_qpel8_*_neon path (each daedalus dispatch is already bit-exact-gated by the corresponding fourier PR's test). 16x16 qpel tables ([0][...]) stay on the in-tree NEON. daedalus only exposes 8x8 today; 16x16 substitution can land once fourier provides those variants. Verified the patch applies cleanly on top of 0001-0011 against the pinned upstream commit b57fbbe5 on hertz. --- ...0012-h264-qpel-rest-daedalus-fourier.patch | 245 ++++++++++++++++++ arch/ffmpeg-v4l2-request-fourier/PKGBUILD | 6 +- ...0012-h264-qpel-rest-daedalus-fourier.patch | 245 ++++++++++++++++++ .../ffmpeg-v4l2-request-fourier/build-deb.sh | 1 + 4 files changed, 495 insertions(+), 2 deletions(-) create mode 100644 arch/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch create mode 100644 debian/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch diff --git a/arch/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch b/arch/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch new file mode 100644 index 000000000..d61582e77 --- /dev/null +++ b/arch/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch @@ -0,0 +1,245 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: claude-noether +Date: Sun, 25 May 2026 14:00:00 +0200 +Subject: [PATCH] avcodec/aarch64/h264qpel: route remaining qpel 8x8 positions through daedalus-fourier + +Closes the H.264 qpel substitution. Extends 0007 (which routed only +mc20 put_) to ALL 15 useful positions in BOTH the put_ and avg_ +tables, skipping mc00 (integer copy / pointer-only fast path). + +29 substitutions total: 14 new put_ + 15 avg_. Each is a uniform +wrapper around daedalus_recipe_dispatch_h264_qpel_{avg_,}mcXY exposed +by daedalus-fourier PRs #15-#20. + +All recipe-table entries route AUTO to CPU NEON (no QPU shaders +for any qpel position other than mc20 yet), so this is plumbing-only +NEON-to-NEON — bit-exact against the in-tree ff_*_h264_qpel8_*_neon +path. + +16x16 qpel tables ([0][...]) stay on the in-tree NEON. daedalus +only exposes 8x8 today; 16x16 substitution can land once fourier +provides those variants (likely just dispatching the 8x8 path four +times with shifted dst/src offsets). + +Refs reauktion/daedalus-v4l2#11 — substitution arc qpel buildout. +--- +diff --git a/libavcodec/aarch64/h264_qpel_daedalus.c b/libavcodec/aarch64/h264_qpel_daedalus.c +--- a/libavcodec/aarch64/h264_qpel_daedalus.c 2026-05-25 14:05:05.789298250 +0200 ++++ libavcodec/aarch64/h264_qpel_daedalus.c 2026-05-25 14:05:05.818358374 +0200 +@@ -1,10 +1,13 @@ + /* +- * H.264 luma qpel mc20 (8x8, horizontal half-pel, 6-tap "put") +- * — daedalus-fourier substitution shim. ++ * H.264 luma qpel 8x8 — daedalus-fourier substitution shims (put_ + avg_). + * +- * Routes H264QpelContext.put_h264_qpel_pixels_tab[1][2] through +- * daedalus_recipe_dispatch_h264_qpel_mc20 instead of +- * ff_put_h264_qpel8_mc20_neon. The recipe layer picks the substrate ++ * Routes ALL 15 useful positions in H264QpelContext's 8x8 put_ and ++ * avg_ tables through daedalus_recipe_dispatch_h264_qpel_mc{XY} ++ * (skipping mc00 which is integer copy / FFmpeg's pointer-only fast ++ * path). Plumbing-only NEON-by-recipe — daedalus-fourier PRs #15-#20 ++ * exposed each variant via the same dispatch signature, so the ++ * substitution is a uniform macro across put_/avg_ and across all ++ * 15 mc positions. The recipe layer picks the substrate + * (CPU NEON for cycle 9; QPU not viable — per-block 7.6 ns vs + * ~250 ns QPU dispatch floor, see docs/k9_h264qpel_mc20.md). + * +@@ -48,3 +51,53 @@ + daedalus_recipe_dispatch_h264_qpel_mc20(g_dctx, dst, src, (size_t)stride, + 1, &meta); + } ++ ++ ++/* All other 8x8 qpel positions follow the same dispatch shape as mc20 ++ * above. The macro collapses ~600 LOC of one-wrapper-per-variant ++ * boilerplate (29 variants total: 14 put_ + 15 avg_). */ ++#define DEFINE_QPEL_WRAPPER(type, suffix, dispatch_fn) \ ++void ff_ ## type ## _h264_qpel8_ ## suffix ## _daedalus(uint8_t *dst, \ ++ const uint8_t *src, ptrdiff_t stride); \ ++void ff_ ## type ## _h264_qpel8_ ## suffix ## _daedalus(uint8_t *dst, \ ++ const uint8_t *src, ptrdiff_t stride) \ ++{ \ ++ static const daedalus_h264_qpel_meta meta = { .dst_off = 0, .src_off = 0 }; \ ++ pthread_once(&g_dctx_once, daedalus_ctx_init_once); \ ++ dispatch_fn(g_dctx, dst, src, (size_t)stride, 1, &meta); \ ++} ++ ++/* put_ variants (mc20 stays on the explicit definition above). */ ++DEFINE_QPEL_WRAPPER(put, mc10, daedalus_recipe_dispatch_h264_qpel_mc10) ++DEFINE_QPEL_WRAPPER(put, mc30, daedalus_recipe_dispatch_h264_qpel_mc30) ++DEFINE_QPEL_WRAPPER(put, mc01, daedalus_recipe_dispatch_h264_qpel_mc01) ++DEFINE_QPEL_WRAPPER(put, mc11, daedalus_recipe_dispatch_h264_qpel_mc11) ++DEFINE_QPEL_WRAPPER(put, mc21, daedalus_recipe_dispatch_h264_qpel_mc21) ++DEFINE_QPEL_WRAPPER(put, mc31, daedalus_recipe_dispatch_h264_qpel_mc31) ++DEFINE_QPEL_WRAPPER(put, mc02, daedalus_recipe_dispatch_h264_qpel_mc02) ++DEFINE_QPEL_WRAPPER(put, mc12, daedalus_recipe_dispatch_h264_qpel_mc12) ++DEFINE_QPEL_WRAPPER(put, mc22, daedalus_recipe_dispatch_h264_qpel_mc22) ++DEFINE_QPEL_WRAPPER(put, mc32, daedalus_recipe_dispatch_h264_qpel_mc32) ++DEFINE_QPEL_WRAPPER(put, mc03, daedalus_recipe_dispatch_h264_qpel_mc03) ++DEFINE_QPEL_WRAPPER(put, mc13, daedalus_recipe_dispatch_h264_qpel_mc13) ++DEFINE_QPEL_WRAPPER(put, mc23, daedalus_recipe_dispatch_h264_qpel_mc23) ++DEFINE_QPEL_WRAPPER(put, mc33, daedalus_recipe_dispatch_h264_qpel_mc33) ++ ++/* avg_ variants — all 15 useful positions. */ ++DEFINE_QPEL_WRAPPER(avg, mc10, daedalus_recipe_dispatch_h264_qpel_avg_mc10) ++DEFINE_QPEL_WRAPPER(avg, mc20, daedalus_recipe_dispatch_h264_qpel_avg_mc20) ++DEFINE_QPEL_WRAPPER(avg, mc30, daedalus_recipe_dispatch_h264_qpel_avg_mc30) ++DEFINE_QPEL_WRAPPER(avg, mc01, daedalus_recipe_dispatch_h264_qpel_avg_mc01) ++DEFINE_QPEL_WRAPPER(avg, mc11, daedalus_recipe_dispatch_h264_qpel_avg_mc11) ++DEFINE_QPEL_WRAPPER(avg, mc21, daedalus_recipe_dispatch_h264_qpel_avg_mc21) ++DEFINE_QPEL_WRAPPER(avg, mc31, daedalus_recipe_dispatch_h264_qpel_avg_mc31) ++DEFINE_QPEL_WRAPPER(avg, mc02, daedalus_recipe_dispatch_h264_qpel_avg_mc02) ++DEFINE_QPEL_WRAPPER(avg, mc12, daedalus_recipe_dispatch_h264_qpel_avg_mc12) ++DEFINE_QPEL_WRAPPER(avg, mc22, daedalus_recipe_dispatch_h264_qpel_avg_mc22) ++DEFINE_QPEL_WRAPPER(avg, mc32, daedalus_recipe_dispatch_h264_qpel_avg_mc32) ++DEFINE_QPEL_WRAPPER(avg, mc03, daedalus_recipe_dispatch_h264_qpel_avg_mc03) ++DEFINE_QPEL_WRAPPER(avg, mc13, daedalus_recipe_dispatch_h264_qpel_avg_mc13) ++DEFINE_QPEL_WRAPPER(avg, mc23, daedalus_recipe_dispatch_h264_qpel_avg_mc23) ++DEFINE_QPEL_WRAPPER(avg, mc33, daedalus_recipe_dispatch_h264_qpel_avg_mc33) ++ ++#undef DEFINE_QPEL_WRAPPER +diff --git a/libavcodec/aarch64/h264qpel_init_aarch64.c b/libavcodec/aarch64/h264qpel_init_aarch64.c +--- a/libavcodec/aarch64/h264qpel_init_aarch64.c 2026-05-25 14:05:05.790403989 +0200 ++++ libavcodec/aarch64/h264qpel_init_aarch64.c 2026-05-25 14:05:05.819136071 +0200 +@@ -50,6 +50,64 @@ + void ff_put_h264_qpel8_mc30_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + void ff_put_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride); ++void ff_put_h264_qpel8_mc10_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc30_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc01_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc11_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc21_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc31_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc02_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc12_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc22_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc32_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc03_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc13_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc23_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc33_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc10_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc30_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc01_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc11_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc21_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc31_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc02_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc12_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc22_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc32_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc03_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc13_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc23_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc33_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); + void ff_put_h264_qpel8_mc01_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + void ff_put_h264_qpel8_mc11_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + void ff_put_h264_qpel8_mc21_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +@@ -164,21 +222,21 @@ + c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon; + + c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon; +- c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon; ++ c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_daedalus; + c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_daedalus; +- c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon; +- c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon; +- c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon; +- c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon; +- c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon; +- c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon; +- c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon; +- c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon; +- c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon; +- c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon; +- c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon; +- c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon; +- c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon; ++ c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_daedalus; ++ c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_daedalus; ++ c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_daedalus; ++ c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_daedalus; ++ c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_daedalus; ++ c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_daedalus; ++ c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_daedalus; + + c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon; + c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon; +@@ -198,21 +256,21 @@ + c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon; + + c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon; +- c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon; +- c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon; +- c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon; +- c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon; +- c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon; +- c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon; +- c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon; +- c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon; +- c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon; +- c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon; +- c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon; +- c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon; +- c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon; +- c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon; +- c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon; ++ c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_daedalus; + } else if (have_neon(cpu_flags) && bit_depth == 10) { + c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon_10; + c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon_10; +-- +2.47.3 + diff --git a/arch/ffmpeg-v4l2-request-fourier/PKGBUILD b/arch/ffmpeg-v4l2-request-fourier/PKGBUILD index d8e4e35a4..f2e145c35 100644 --- a/arch/ffmpeg-v4l2-request-fourier/PKGBUILD +++ b/arch/ffmpeg-v4l2-request-fourier/PKGBUILD @@ -98,8 +98,9 @@ source=("git+https://github.com/Kwiboo/FFmpeg.git#commit=${_commit}" '0008-h264-deblock-luma-h-daedalus-fourier.patch' '0009-h264-deblock-chroma-daedalus-fourier.patch' '0010-h264-deblock-luma-intra-daedalus-fourier.patch' - '0011-h264-chroma-dc-hadamard-daedalus-fourier.patch') -sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP') + '0011-h264-chroma-dc-hadamard-daedalus-fourier.patch' + '0012-h264-qpel-rest-daedalus-fourier.patch') +sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP') pkgver() { cd "${_srcname}" @@ -121,6 +122,7 @@ prepare() { patch -Np1 -i "${srcdir}/0009-h264-deblock-chroma-daedalus-fourier.patch" patch -Np1 -i "${srcdir}/0010-h264-deblock-luma-intra-daedalus-fourier.patch" patch -Np1 -i "${srcdir}/0011-h264-chroma-dc-hadamard-daedalus-fourier.patch" + patch -Np1 -i "${srcdir}/0012-h264-qpel-rest-daedalus-fourier.patch" } build() { diff --git a/debian/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch b/debian/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch new file mode 100644 index 000000000..d61582e77 --- /dev/null +++ b/debian/ffmpeg-v4l2-request-fourier/0012-h264-qpel-rest-daedalus-fourier.patch @@ -0,0 +1,245 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: claude-noether +Date: Sun, 25 May 2026 14:00:00 +0200 +Subject: [PATCH] avcodec/aarch64/h264qpel: route remaining qpel 8x8 positions through daedalus-fourier + +Closes the H.264 qpel substitution. Extends 0007 (which routed only +mc20 put_) to ALL 15 useful positions in BOTH the put_ and avg_ +tables, skipping mc00 (integer copy / pointer-only fast path). + +29 substitutions total: 14 new put_ + 15 avg_. Each is a uniform +wrapper around daedalus_recipe_dispatch_h264_qpel_{avg_,}mcXY exposed +by daedalus-fourier PRs #15-#20. + +All recipe-table entries route AUTO to CPU NEON (no QPU shaders +for any qpel position other than mc20 yet), so this is plumbing-only +NEON-to-NEON — bit-exact against the in-tree ff_*_h264_qpel8_*_neon +path. + +16x16 qpel tables ([0][...]) stay on the in-tree NEON. daedalus +only exposes 8x8 today; 16x16 substitution can land once fourier +provides those variants (likely just dispatching the 8x8 path four +times with shifted dst/src offsets). + +Refs reauktion/daedalus-v4l2#11 — substitution arc qpel buildout. +--- +diff --git a/libavcodec/aarch64/h264_qpel_daedalus.c b/libavcodec/aarch64/h264_qpel_daedalus.c +--- a/libavcodec/aarch64/h264_qpel_daedalus.c 2026-05-25 14:05:05.789298250 +0200 ++++ libavcodec/aarch64/h264_qpel_daedalus.c 2026-05-25 14:05:05.818358374 +0200 +@@ -1,10 +1,13 @@ + /* +- * H.264 luma qpel mc20 (8x8, horizontal half-pel, 6-tap "put") +- * — daedalus-fourier substitution shim. ++ * H.264 luma qpel 8x8 — daedalus-fourier substitution shims (put_ + avg_). + * +- * Routes H264QpelContext.put_h264_qpel_pixels_tab[1][2] through +- * daedalus_recipe_dispatch_h264_qpel_mc20 instead of +- * ff_put_h264_qpel8_mc20_neon. The recipe layer picks the substrate ++ * Routes ALL 15 useful positions in H264QpelContext's 8x8 put_ and ++ * avg_ tables through daedalus_recipe_dispatch_h264_qpel_mc{XY} ++ * (skipping mc00 which is integer copy / FFmpeg's pointer-only fast ++ * path). Plumbing-only NEON-by-recipe — daedalus-fourier PRs #15-#20 ++ * exposed each variant via the same dispatch signature, so the ++ * substitution is a uniform macro across put_/avg_ and across all ++ * 15 mc positions. The recipe layer picks the substrate + * (CPU NEON for cycle 9; QPU not viable — per-block 7.6 ns vs + * ~250 ns QPU dispatch floor, see docs/k9_h264qpel_mc20.md). + * +@@ -48,3 +51,53 @@ + daedalus_recipe_dispatch_h264_qpel_mc20(g_dctx, dst, src, (size_t)stride, + 1, &meta); + } ++ ++ ++/* All other 8x8 qpel positions follow the same dispatch shape as mc20 ++ * above. The macro collapses ~600 LOC of one-wrapper-per-variant ++ * boilerplate (29 variants total: 14 put_ + 15 avg_). */ ++#define DEFINE_QPEL_WRAPPER(type, suffix, dispatch_fn) \ ++void ff_ ## type ## _h264_qpel8_ ## suffix ## _daedalus(uint8_t *dst, \ ++ const uint8_t *src, ptrdiff_t stride); \ ++void ff_ ## type ## _h264_qpel8_ ## suffix ## _daedalus(uint8_t *dst, \ ++ const uint8_t *src, ptrdiff_t stride) \ ++{ \ ++ static const daedalus_h264_qpel_meta meta = { .dst_off = 0, .src_off = 0 }; \ ++ pthread_once(&g_dctx_once, daedalus_ctx_init_once); \ ++ dispatch_fn(g_dctx, dst, src, (size_t)stride, 1, &meta); \ ++} ++ ++/* put_ variants (mc20 stays on the explicit definition above). */ ++DEFINE_QPEL_WRAPPER(put, mc10, daedalus_recipe_dispatch_h264_qpel_mc10) ++DEFINE_QPEL_WRAPPER(put, mc30, daedalus_recipe_dispatch_h264_qpel_mc30) ++DEFINE_QPEL_WRAPPER(put, mc01, daedalus_recipe_dispatch_h264_qpel_mc01) ++DEFINE_QPEL_WRAPPER(put, mc11, daedalus_recipe_dispatch_h264_qpel_mc11) ++DEFINE_QPEL_WRAPPER(put, mc21, daedalus_recipe_dispatch_h264_qpel_mc21) ++DEFINE_QPEL_WRAPPER(put, mc31, daedalus_recipe_dispatch_h264_qpel_mc31) ++DEFINE_QPEL_WRAPPER(put, mc02, daedalus_recipe_dispatch_h264_qpel_mc02) ++DEFINE_QPEL_WRAPPER(put, mc12, daedalus_recipe_dispatch_h264_qpel_mc12) ++DEFINE_QPEL_WRAPPER(put, mc22, daedalus_recipe_dispatch_h264_qpel_mc22) ++DEFINE_QPEL_WRAPPER(put, mc32, daedalus_recipe_dispatch_h264_qpel_mc32) ++DEFINE_QPEL_WRAPPER(put, mc03, daedalus_recipe_dispatch_h264_qpel_mc03) ++DEFINE_QPEL_WRAPPER(put, mc13, daedalus_recipe_dispatch_h264_qpel_mc13) ++DEFINE_QPEL_WRAPPER(put, mc23, daedalus_recipe_dispatch_h264_qpel_mc23) ++DEFINE_QPEL_WRAPPER(put, mc33, daedalus_recipe_dispatch_h264_qpel_mc33) ++ ++/* avg_ variants — all 15 useful positions. */ ++DEFINE_QPEL_WRAPPER(avg, mc10, daedalus_recipe_dispatch_h264_qpel_avg_mc10) ++DEFINE_QPEL_WRAPPER(avg, mc20, daedalus_recipe_dispatch_h264_qpel_avg_mc20) ++DEFINE_QPEL_WRAPPER(avg, mc30, daedalus_recipe_dispatch_h264_qpel_avg_mc30) ++DEFINE_QPEL_WRAPPER(avg, mc01, daedalus_recipe_dispatch_h264_qpel_avg_mc01) ++DEFINE_QPEL_WRAPPER(avg, mc11, daedalus_recipe_dispatch_h264_qpel_avg_mc11) ++DEFINE_QPEL_WRAPPER(avg, mc21, daedalus_recipe_dispatch_h264_qpel_avg_mc21) ++DEFINE_QPEL_WRAPPER(avg, mc31, daedalus_recipe_dispatch_h264_qpel_avg_mc31) ++DEFINE_QPEL_WRAPPER(avg, mc02, daedalus_recipe_dispatch_h264_qpel_avg_mc02) ++DEFINE_QPEL_WRAPPER(avg, mc12, daedalus_recipe_dispatch_h264_qpel_avg_mc12) ++DEFINE_QPEL_WRAPPER(avg, mc22, daedalus_recipe_dispatch_h264_qpel_avg_mc22) ++DEFINE_QPEL_WRAPPER(avg, mc32, daedalus_recipe_dispatch_h264_qpel_avg_mc32) ++DEFINE_QPEL_WRAPPER(avg, mc03, daedalus_recipe_dispatch_h264_qpel_avg_mc03) ++DEFINE_QPEL_WRAPPER(avg, mc13, daedalus_recipe_dispatch_h264_qpel_avg_mc13) ++DEFINE_QPEL_WRAPPER(avg, mc23, daedalus_recipe_dispatch_h264_qpel_avg_mc23) ++DEFINE_QPEL_WRAPPER(avg, mc33, daedalus_recipe_dispatch_h264_qpel_avg_mc33) ++ ++#undef DEFINE_QPEL_WRAPPER +diff --git a/libavcodec/aarch64/h264qpel_init_aarch64.c b/libavcodec/aarch64/h264qpel_init_aarch64.c +--- a/libavcodec/aarch64/h264qpel_init_aarch64.c 2026-05-25 14:05:05.790403989 +0200 ++++ libavcodec/aarch64/h264qpel_init_aarch64.c 2026-05-25 14:05:05.819136071 +0200 +@@ -50,6 +50,64 @@ + void ff_put_h264_qpel8_mc30_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + void ff_put_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride); ++void ff_put_h264_qpel8_mc10_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc30_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc01_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc11_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc21_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc31_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc02_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc12_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc22_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc32_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc03_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc13_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc23_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_put_h264_qpel8_mc33_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc10_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc20_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc30_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc01_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc11_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc21_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc31_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc02_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc12_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc22_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc32_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc03_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc13_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc23_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); ++void ff_avg_h264_qpel8_mc33_daedalus(uint8_t *dst, const uint8_t *src, ++ ptrdiff_t stride); + void ff_put_h264_qpel8_mc01_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + void ff_put_h264_qpel8_mc11_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + void ff_put_h264_qpel8_mc21_neon(uint8_t *dst, const uint8_t *src, ptrdiff_t stride); +@@ -164,21 +222,21 @@ + c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon; + + c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon; +- c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon; ++ c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_daedalus; + c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_daedalus; +- c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon; +- c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon; +- c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon; +- c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon; +- c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon; +- c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon; +- c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon; +- c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon; +- c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon; +- c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon; +- c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon; +- c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon; +- c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon; ++ c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_daedalus; ++ c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_daedalus; ++ c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_daedalus; ++ c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_daedalus; ++ c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_daedalus; ++ c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_daedalus; ++ c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_daedalus; ++ c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_daedalus; + + c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon; + c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon; +@@ -198,21 +256,21 @@ + c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon; + + c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon; +- c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon; +- c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon; +- c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon; +- c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon; +- c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon; +- c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon; +- c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon; +- c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon; +- c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon; +- c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon; +- c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon; +- c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon; +- c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon; +- c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon; +- c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon; ++ c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_daedalus; ++ c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_daedalus; + } else if (have_neon(cpu_flags) && bit_depth == 10) { + c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon_10; + c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon_10; +-- +2.47.3 + diff --git a/debian/ffmpeg-v4l2-request-fourier/build-deb.sh b/debian/ffmpeg-v4l2-request-fourier/build-deb.sh index 9fb2bb1d5..a9e7131af 100755 --- a/debian/ffmpeg-v4l2-request-fourier/build-deb.sh +++ b/debian/ffmpeg-v4l2-request-fourier/build-deb.sh @@ -78,6 +78,7 @@ patch -Np1 -i "$HERE/0008-h264-deblock-luma-h-daedalus-fourier.patch" patch -Np1 -i "$HERE/0009-h264-deblock-chroma-daedalus-fourier.patch" patch -Np1 -i "$HERE/0010-h264-deblock-luma-intra-daedalus-fourier.patch" patch -Np1 -i "$HERE/0011-h264-chroma-dc-hadamard-daedalus-fourier.patch" +patch -Np1 -i "$HERE/0012-h264-qpel-rest-daedalus-fourier.patch" # --- daedalus-fourier: fetch + build static .a with PIC, install to a # per-build prefix; libavcodec.so links it into the shared object so