Files
marfrit 25610930ad ffmpeg-v4l2-request-fourier: export ff_h264_set_mb_inspect_cb (0016 amend, PKGREL 15)
The 0016 patch declared ff_h264_set_mb_inspect_cb in h264dec.h and
defined it in h264_mb.c, but didn't touch libavcodec/libavcodec.v.
FFmpeg's default version script exports only `av_*`, `avcodec_*`,
`avpriv_*`, and `avsubtitle_free`; everything else is hidden as LOCAL
behind a `*` glob.  Result: `nm -D libavcodec.so.62 | grep
ff_h264_set_mb_inspect_cb` returned nothing → dlsym() returned NULL.

Static-link CLI consumer (daedalus_decode_h264) was unaffected
because static linking doesn't care about symbol visibility.  The
daedalus-v4l2 daemon shadow_decoder path (PR-Q3a.1) dlopens
libavcodec.so.62 and resolves the callback via dlsym — that needs
the symbol exported.

Fix: add ff_h264_set_mb_inspect_cb to the global list in
libavcodec/libavcodec.v.  Single-line addition to the 0016 patch.
Mirrored across the arch/ + debian/ patch trees.

PKGREL bump 14 → 15, changelog entry added (debian side).  PKGBUILD
pkgrel bumped on arch side too.  No behaviour change to the decode
path: the callback is still opt-in via the H264Context function
pointer; only consumers that have explicitly installed a callback
pay the one-load-one-branch cost per MB.

dejavu-check: this is fixing the existing 0016 observation-hook to
actually work as a dlsym intercept (the architectural shape the
patch was designed for).  NOT adding new per-kernel substitution.
Same shape, same patch number, same intent.  Just hiding/exporting
plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 15:38:03 +02:00

133 lines
5.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Markus Fritsche <mfritsche@reauktion.de>
Date: Tue, 26 May 2026 06:00:00 +0200
Subject: [PATCH] avcodec/h264: per-MB inspection callback (daedalus-decoder
hook)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds an opt-in callback fired in ff_h264_hl_decode_mb after the
existing pixel work, used by tools that need per-MB visibility into
the H.264 decode. Initially driven by daedalus-decoder's CLI test
harness (tools/daedalus_decode_h264) which shadows libavcodec's
decode with a frame-major daedalus-decoder run for byte-exact diff
on real H.264 streams; later target is a daedalus-v4l2 daemon
refactor that drives daedalus_decoder_append_mb directly from the
callback instead of letting libavcodec do per-MB pixel work.
Shape: ONE inspection point per MB. Distinct from the per-kernel
function-pointer-hijack pattern that used to live in 0003-0014
patches (now reverted via 0015 for ctx, and architecturally retired
per daedalus-fourier PR #37's measurement-correction). Per-block
synchronous Vulkan dispatch from libavcodec was structurally non-
competitive; per-MB CPU-side observation feeding a per-frame batch
submit is the right shape.
Two new fields in H264Context (appended at end of struct; no ABI
surface visible to non-libavcodec callers since H264Context is
internal — declared in h264dec.h, not h264.h). One new exported
function ff_h264_set_mb_inspect_cb to set them.
Zero behaviour change when cb == NULL (the default): one load +
one branch per MB in the decoder hot path, both branch-predicted
to fall through.
Used by:
- daedalus-decoder/tools/daedalus_decode_h264 (PR-A1b)
- daedalus-v4l2 daemon shadow-mode path (PR-Q3a.1+)
The CLI static-links libavcodec.a so symbol visibility doesn't matter
there. The daemon dlopens libavcodec.so.62 and resolves the callback
via dlsym, so the symbol MUST be exported — added to libavcodec.v
explicitly (FFmpeg's default version script hides every `ff_*` symbol
as LOCAL behind a glob).
Refs reauktion/daedalus-decoder!12 (Stage 2 PR-b complete).
---
libavcodec/h264_mb.c | 20 ++++++++++++++++++++
libavcodec/h264dec.h | 26 ++++++++++++++++++++++++++
libavcodec/libavcodec.v | 1 +
3 files changed, 47 insertions(+)
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -334,6 +334,16 @@
int pic_order_cnt_bit_size;
} H264SliceContext;
+/* Per-MB inspection callback type — see ff_h264_set_mb_inspect_cb()
+ * below. Fired by ff_h264_hl_decode_mb after the existing pixel work
+ * for every macroblock in coded order. Receives a const H264Context*
+ * so the callback can inspect any slice/picture state (h->slice_ctx
+ * for current slice, h->cur_pic.f->data[plane] for reconstructed
+ * samples, etc.). */
+typedef void (*ff_h264_mb_inspect_cb)(void *opaque,
+ const struct H264Context *h,
+ int mb_x, int mb_y);
+
/**
* H264Context
*/
@@ -579,6 +589,10 @@
int non_gray; ///< Did we encounter a intra frame after a gray gap frame
int noref_gray;
int skip_gray;
+
+ /* Per-MB inspection hook — set via ff_h264_set_mb_inspect_cb. */
+ ff_h264_mb_inspect_cb mb_inspect_cb;
+ void *mb_inspect_opaque;
} H264Context;
extern const uint16_t ff_h264_mb_sizes[4];
@@ -607,6 +621,16 @@
const H2645NAL *nal, void *logctx);
void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
+
+/**
+ * Install an opt-in per-MB inspection callback that fires from
+ * ff_h264_hl_decode_mb after each macroblock's pixel work. Default
+ * is NULL (no callback installed); the check is a single branch on
+ * the decoder hot path. See ff_h264_mb_inspect_cb for signature.
+ */
+void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
+ ff_h264_mb_inspect_cb cb, void *opaque);
+
void ff_h264_decode_init_vlc(void);
/**
--- a/libavcodec/h264_mb.c
+++ b/libavcodec/h264_mb.c
@@ -815,4 +815,20 @@
hl_decode_mb_simple_16(h, sl);
} else
hl_decode_mb_simple_8(h, sl);
+
+ /* Per-MB inspection callback (opt-in via ff_h264_set_mb_inspect_cb).
+ * Fired AFTER pixel work — reconstructed samples are in
+ * h->cur_pic.f->data[plane] at the MB's raster position by the
+ * time this runs. Callback may inspect slice context via
+ * h->slice_ctx + sl->mb_xy, coeffs via sl->mb, etc. */
+ if (h->mb_inspect_cb)
+ h->mb_inspect_cb(h->mb_inspect_opaque, h, sl->mb_x, sl->mb_y);
+}
+
+void ff_h264_set_mb_inspect_cb(AVCodecContext *avctx,
+ ff_h264_mb_inspect_cb cb, void *opaque)
+{
+ H264Context *h = avctx->priv_data;
+ h->mb_inspect_cb = cb;
+ h->mb_inspect_opaque = opaque;
}
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -3,6 +3,7 @@
av_*;
avcodec_*;
avpriv_*;
+ ff_h264_set_mb_inspect_cb;
avsubtitle_free;
local:
*;