ffmpeg-v4l2-request-fourier: restore AV_CODEC_FLAG_LOW_DELAY in H.264 decoder

FFmpeg 8.x dropped the H.264 decoder's low_delay code path —
AV_CODEC_FLAG_LOW_DELAY no longer prevents h264_select_output_frame
from running the display-order DPB output queue.  The daedalus-v4l2
daemon's `ctx->flags |= AV_CODEC_FLAG_LOW_DELAY` at
daemon/src/decoder.c:202 has been a silent no-op since the SONAME
61→62 jump landed in reauktion/daedalus-v4l2 PR #16; on Firefox
YouTube this re-introduced the 2-1-4-3 B-frame pair-swap that PR
#12's daemon flag was supposed to prevent.

Fix lives in libavcodec, not the daemon: restore the documented
LOW_DELAY semantics so the daemon (and any other V4L2-stateless-
style consumer) keeps the one-frame-per-send_packet decode-order
output contract it already declares.

## Patch

0006-h264-restore-low-delay.patch touches libavcodec/h264_slice.c:

- h264_select_output_frame: early-exit when LOW_DELAY is set.
  Emit the just-decoded picture as next_output_pic, mirror the
  corruption / recovery-point tracking the main path performs,
  skip delayed_pic[] / POC reorder machinery entirely.

- h264_field_start: suppress the SPS-driven
  `has_b_frames = sps->num_reorder_frames` clobber when LOW_DELAY
  is set.  Without this the per-slice bitstream_restriction_flag
  re-pickup would reintroduce a nonzero reorder buffer mid-stream
  even after the daemon set has_b_frames=0 at avcodec_open2.

## Why not daemon-side

A daemon SPS-rewrite (`num_reorder_frames=0`) was considered but
rejected: it works only for the daemon's reconstructed SPS NAL,
not for any in-band SPS the daemon dlopens libavformat to parse
in other code paths.  Restoring documented FFmpeg flag semantics
is the smaller, more durable change and keeps the daemon
interface stable.

## Packaging

- PKGREL/pkgrel bump to 9.
- No new build-deps, no Depends change.
- Substitution arc cycles 6/7/8 unchanged.

## Refs

- reauktion/daedalus-v4l2#11 / #12 (LOW_DELAY half-measure on
  daemon side, originally landed against FFmpeg 7.x).
- daemon/src/decoder.c:202 (`ctx->flags |= AV_CODEC_FLAG_LOW_DELAY`
  for H.264 only — unchanged, but now actually has effect again).
This commit is contained in:
2026-05-22 14:20:37 +02:00
parent d11a52405d
commit 5c69460722
5 changed files with 202 additions and 10 deletions
+8 -7
View File
@@ -33,13 +33,13 @@ FFMPEG_VERSION=8.1
# epoch 2 matches Debian's stock ffmpeg (currently 7:7.1.x in trixie);
# +rfourier suffix to avoid colliding with upstream/Debian rebuilds.
PKGVER=2:${FFMPEG_VERSION}+rfourier+gb57fbbe
PKGREL=8 # pkgrel=8H.264 luma-v deblock daedalus-fourier substitution
# (cycle 8, non-intra bS<4 vertical luma). Stacks on cycles
# 6/7 (IDCT 4x4 + 8x8). Wires H264DSPContext.v_loop_filter_luma
# through daedalus_recipe_dispatch_h264_deblock_luma_v.
# ctx stays no-QPU until a separate change gates Vulkan init
# on a feature flag; cycle-8 dispatch is NEON-by-recipe for
# now. (2026-05-22)
PKGREL=9 # pkgrel=9restore AV_CODEC_FLAG_LOW_DELAY semantics in the
# H.264 decoder (FFmpeg 8.x dropped them). Fixes the 2-1-4-3
# B-frame pair-swap that re-appeared in Firefox YouTube after
# the SONAME 61→62 jump (PR #75) silently neutered the
# daemon's ctx->flags |= AV_CODEC_FLAG_LOW_DELAY at
# daemon/src/decoder.c:202. Substitution arc unchanged.
# (2026-05-22)
# daedalus-fourier pin — first kernel substitution in libavcodec (cycle 6
# H.264 IDCT 4x4). Same SHA as the daedalus-v4l2 daemon already ships
@@ -71,6 +71,7 @@ patch -Np1 -i "$HERE/0002-nv15-to-p010-unpack.patch"
patch -Np1 -i "$HERE/0003-h264-idct4-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0004-h264-idct8-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0005-h264-deblock-luma-v-daedalus-fourier.patch"
patch -Np1 -i "$HERE/0006-h264-restore-low-delay.patch"
# --- daedalus-fourier: fetch + build static .a with PIC, install to a
# per-build prefix; libavcodec.so links it into the shared object so