iter8 Phase 6c α-2: pass H.264 POC values through unchanged for rkvdec

Bug 4 root cause per Phase 7 γ + Phase 4c strace re-decode:
libva strips FFmpeg's bit-16 POC sentinel; kdirect (ffmpeg-v4l2request)
does NOT strip. rkvdec writes top/bottom_field_order_cnt directly to
MMIO via writel_relaxed; with libva sending 0 instead of kdirect's
65536, hardware POC comparisons mismatch and motion compensation
silently corrupts (16x32 patch + nothing else).

The original h264_strip_ffmpeg_poc_sentinel was hantro-specific
(hantro_h264.c prepare_table fed unmasked tbl->poc[]). Hantro+H.264
is not exercised on RK3399; deferring per-driver gating to iter9 if
it surfaces.

Preserve VA_PICTURE_H264_INVALID → return 0 (correct zero-init for
empty DPB slots per Phase 5c amendment).

4 call sites unchanged (h264.c:309, 312, 462, 465 — for ref and current
frame TopFieldOrderCnt / BottomFieldOrderCnt). Both reference and
current-frame POCs now pass through unchanged so hardware compares
agree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
claude-noether
2026-05-13 12:57:51 +00:00
parent 6f4e5833f0
commit 02266841c6
+12 -2
View File
@@ -220,8 +220,18 @@ static inline int32_t h264_strip_ffmpeg_poc_sentinel(int32_t poc, uint32_t flags
{
if (flags & VA_PICTURE_H264_INVALID)
return 0;
if (poc & (1 << 16))
return poc - (1 << 16);
/*
* iter8 α-2: pass POC values through unchanged for rkvdec. The
* sentinel-subtract was added for hantro's tbl->poc[] prepare_table
* which fed the value through unmasked. rkvdec writes POC to MMIO
* via writel_relaxed (rkvdec-h264.c:975-978) and the macro
* RKVDEC_CUR_POC is a 32-bit passthrough. kdirect (ffmpeg-v4l2request)
* delivers the sentinel-encoded value directly and decodes
* correctly; libva's strip was the cause of the 16x32 partial-fill
* Bug 4 symptom. Hantro+H.264 isn't exercised on RK3399 (hantro-dec
* doesn't advertise H.264 there) — restoring the strip per-driver
* is iter9 work if it ever surfaces.
*/
return poc;
}