b47938e0bc
build and publish packages / distcc-avahi-aarch64 (push) Successful in 1m3s
build and publish packages / lmcp-any (push) Successful in 9s
build and publish packages / lmcp-debian (push) Successful in 4s
build and publish packages / claude-his-any (push) Failing after 4s
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Has been skipped
build and publish packages / claude-his-debian (push) Has been skipped
Mirrors phase6/step1/ from the ohm_gl_fix campaign. Contract-correct
hantro multi-planar / chromium-149-era stateless H.264 port of
bootlin's libva-v4l2-request, patches 0001..0018 + fourier-local.
Honest characterisation in README:
- Builds cleanly on chromium-builder LXC (boltzmann)
- vainfo enumerates H.264 profiles cleanly with LIBVA_DRIVER_NAME=v4l2_request
- NOT on Brave's decode path on ohm_gl_fix stack — Brave uses
Chromium's own V4L2VideoDecoder in media/gpu/v4l2/.
- Most likely useful for a future Firefox-via-libavcodec-vaapi
campaign, modulo a separate Mesa-panfrost WSI pitch issue.
- DEBUG patches (0010, 0011, 0014) intentionally kept in series
for development; remove for cleaner production runs.
Audit trail in the source repo at ohm_gl_fix:
phase6/step1/audit_0008_decode_params_2026-05-01.md
phase6/step1/api_contract_findings_2026-05-01.md
phase3_remeasure_2026-05-02/B3_decoder_discovery.md (why this
isn't on Brave's path)
98 lines
3.9 KiB
Diff
98 lines
3.9 KiB
Diff
From: Markus Fritsche <fritsche.markus@gmail.com>
|
|
Date: 2026-05-01
|
|
Subject: [PATCH] DEBUG: dump VAPictureH264 raw bytes + decoded fields
|
|
|
|
Diagnostic-only. Investigating the observed anomaly:
|
|
|
|
- V4L2 strace shows decode_params.top_field_order_cnt = 65536
|
|
on the first IDR frame submitted by mpv+ffmpeg+libva-v4l2-request
|
|
- GStreamer's reference path writes 0 (spec-correct: PicOrderCnt=0
|
|
for IDR with pic_order_cnt_type=0 / pic_order_cnt_lsb=0)
|
|
- Reading FFmpeg source (libavcodec/vaapi_h264.c::fill_vaapi_pic):
|
|
va_pic->TopFieldOrderCnt = 0;
|
|
if (pic->field_poc[0] != INT_MAX)
|
|
va_pic->TopFieldOrderCnt = pic->field_poc[0];
|
|
For IDR: ff_h264_init_poc sets field_poc[0] = poc_msb + poc_lsb
|
|
= 0 + 0 = 0. So FFmpeg should write 0.
|
|
|
|
If FFmpeg writes 0 but fourier reads 65536, the mismatch is in the
|
|
libva ABI between ffmpeg's writer and our reader. Most likely
|
|
suspect: VA_PADDING_LOW size in VAPictureH264 differs between the
|
|
libva headers ffmpeg+libva were built against and the headers
|
|
fourier was built against, shifting struct field offsets.
|
|
|
|
This patch dumps:
|
|
1. sizeof(VAPictureH264) at our reader's view
|
|
2. First 32 raw bytes of VAPicture->CurrPic
|
|
3. Field-decoded values via the .picture_id, .frame_idx, .flags,
|
|
.TopFieldOrderCnt, .BottomFieldOrderCnt accessors
|
|
|
|
If the raw bytes show 00 00 01 00 at offset 12 (= 65536 LE), the
|
|
field offset is correct and FFmpeg actually wrote 65536 — meaning
|
|
either FFmpeg has a bug, or our test scenario triggers a non-spec
|
|
code path. If the raw bytes show 00 00 00 00 at offset 12 but
|
|
TopFieldOrderCnt accessor returns 65536, the struct ABI is
|
|
mismatched and we need to reconcile libva versions.
|
|
|
|
If sizeof(VAPictureH264) prints as something other than 36 (= 4*5
|
|
+ 4*VA_PADDING_LOW assuming VA_PADDING_LOW=4), the struct layout
|
|
on this build differs from the documented libva-2.x layout.
|
|
|
|
Removed once the source of the 65536 is identified.
|
|
|
|
Signed-off-by: Markus Fritsche <fritsche.markus@gmail.com>
|
|
---
|
|
--- a/src/h264.c 2026-05-01 22:56:42.656744048 +0000
|
|
+++ b/src/h264.c 2026-05-02 00:00:00.000000000 +0000
|
|
@@ -28,6 +28,7 @@
|
|
#include <assert.h>
|
|
#include <limits.h>
|
|
#include <string.h>
|
|
+#include <stdio.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
#include <sys/mman.h>
|
|
@@ -259,6 +259,42 @@
|
|
* the OUTPUT bitstream — a hypothesis verified empirically by
|
|
* running this patch and inspecting the CAPTURE buffer.
|
|
*/
|
|
+ /*
|
|
+ * DEBUG INSTRUMENTATION (0014): dump the raw bytes of
|
|
+ * VAPicture->CurrPic plus sizeof(VAPictureH264) so we can
|
|
+ * tell whether the observed TopFieldOrderCnt=65536 anomaly is
|
|
+ * (a) at the documented byte-offset 12 (ffmpeg-side bug or
|
|
+ * intentional non-spec encoding) or
|
|
+ * (b) at a different offset (libva ABI / VA_PADDING_LOW
|
|
+ * mismatch between ffmpeg's writer and our reader).
|
|
+ *
|
|
+ * Documented VAPictureH264 layout (libva-2.x):
|
|
+ * offset 0: VASurfaceID picture_id (uint32)
|
|
+ * offset 4: uint32 frame_idx
|
|
+ * offset 8: uint32 flags
|
|
+ * offset 12: int32 TopFieldOrderCnt
|
|
+ * offset 16: int32 BottomFieldOrderCnt
|
|
+ * offset 20+: uint32 va_reserved[VA_PADDING_LOW]
|
|
+ */
|
|
+ {
|
|
+ const unsigned char *cp = (const unsigned char *)&VAPicture->CurrPic;
|
|
+ char hex[32 * 3 + 1] = { 0 };
|
|
+ unsigned int i;
|
|
+ for (i = 0; i < 32; i++)
|
|
+ snprintf(hex + i * 3, 4, " %02x", cp[i]);
|
|
+ request_log("VAPictureH264 sizeof=%zu CurrPic[0..31]:%s\n",
|
|
+ sizeof(VAPictureH264), hex);
|
|
+ request_log("VAPictureH264 CurrPic field reads: "
|
|
+ "picture_id=0x%08x frame_idx=%u flags=0x%x "
|
|
+ "TopFOC=%d BottomFOC=%d frame_num=%u\n",
|
|
+ (unsigned)VAPicture->CurrPic.picture_id,
|
|
+ (unsigned)VAPicture->CurrPic.frame_idx,
|
|
+ (unsigned)VAPicture->CurrPic.flags,
|
|
+ (int)VAPicture->CurrPic.TopFieldOrderCnt,
|
|
+ (int)VAPicture->CurrPic.BottomFieldOrderCnt,
|
|
+ (unsigned)VAPicture->frame_num);
|
|
+ }
|
|
+
|
|
decode->nal_ref_idc = nal_ref_idc;
|
|
decode->frame_num = VAPicture->frame_num;
|
|
decode->top_field_order_cnt = VAPicture->CurrPic.TopFieldOrderCnt;
|