From 719d813f4a35f2ef7193efcea153c77e6dbbe7ea Mon Sep 17 00:00:00 2001 From: claude-noether Date: Thu, 14 May 2026 10:17:55 +0000 Subject: [PATCH] =?UTF-8?q?iter27=20=CE=B1-27:=20populate=20slice=5Fparams?= =?UTF-8?q?.num=5Fentry=5Fpoint=5Foffsets=20from=20VAAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BBB HEVC uses WPP (entropy_coding_sync_enabled_flag=1); slice header contains entry_point_offset_minus1 syntax elements. libva was setting num_entry_point_offsets=0 with the comment 'iter2 doesn't do tiles', but WPP uses the same mechanism — rkvdec miscounted the slice header skip distance and read slice data starting at wrong byte for P/B frames → frame 2+ decoded with garbage reference data. iter27 kernel printk diff: libva frame 2 sl[8..11] = 00 00 00 00 (=0) kdirect frame 2 sl[8..11] = 16 00 00 00 (=22) VAAPI exposes VASliceParameterBufferHEVC.num_entry_point_offsets. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/h265.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/h265.c b/src/h265.c index e32331e..0f186a4 100644 --- a/src/h265.c +++ b/src/h265.c @@ -79,6 +79,7 @@ #include #include +#include "utils.h" #include "v4l2.h" /* @@ -386,7 +387,21 @@ static void h265_fill_slice_params(VAPictureParameterBufferHEVC *picture, * buffer. FFmpeg pattern at v4l2_request_hevc.c:190. */ slice_params->data_byte_offset = source_offset + slice->slice_data_byte_offset; - slice_params->num_entry_point_offsets = 0; /* iter2 doesn't do tiles */ + /* + * iter27 α-27: populate num_entry_point_offsets from VAAPI. + * + * BBB HEVC uses WPP (entropy_coding_sync_enabled_flag); each CTU row + * after the first creates an entry point. For 720p with 32-pixel + * CTUs that's 22 entry points per slice. Hardcoding 0 made rkvdec + * miscount the slice header skip distance → wrong slice data + * boundary → frame 2+ decoded with garbage reference data. + * + * Comment "iter2 doesn't do tiles" was inaccurate: WPP isn't tiles + * but uses the same entry_point_offsets mechanism. + */ + slice_params->num_entry_point_offsets = slice->num_entry_point_offsets; + request_log("iter27diag: slice %p num_entry_point_offsets=%u\n", + (void *)slice, (unsigned)slice->num_entry_point_offsets); slice_params->nal_unit_type = nal_unit_type; slice_params->nuh_temporal_id_plus1 = nuh_temporal_id_plus1;