diff --git a/src/h265.c b/src/h265.c index 26f4881..17b6987 100644 --- a/src/h265.c +++ b/src/h265.c @@ -380,16 +380,25 @@ static void h265_fill_slice_params(VAPictureParameterBufferHEVC *picture, nuh_temporal_id_plus1 = (b[1] >> H265_NUH_TEMPORAL_ID_PLUS1_SHIFT) & H265_NUH_TEMPORAL_ID_PLUS1_MASK; - slice_params->bit_size = slice->slice_data_size * 8; - if (getenv("LIBVA_HEVC_DIAG")) { - request_log("hevc_diag: slice_data_size=%u slice_data_offset=%u " - "slice_data_byte_offset=%u slice_data_flag=%u source_offset=%u\n", - (unsigned)slice->slice_data_size, - (unsigned)slice->slice_data_offset, - (unsigned)slice->slice_data_byte_offset, - (unsigned)slice->slice_data_flag, - source_offset); - } + /* + * iter28 α-28: bit_size formula. + * + * VAAPI's slice_data_size is the size of the slice's source-data + * buffer INCLUDING the NAL header and slice header. rkvdec_hevc + * expects bit_size to cover the slice_data area starting at + * data_byte_offset (the slice payload). Setting bit_size = + * slice_data_size * 8 makes rkvdec read past the slice payload + * into trailing bytes → wrong entropy state → frame 2+ visual + * garbage. + * + * Empirical match with ffmpeg-v4l2request (which uses + * (size+extra_size)*8 for the data it actually appended): + * bit_size = (slice_data_size - slice_data_byte_offset) * 8 + * yields 44096 bits for BBB frame 2 (= 5512 bytes), matching + * kdirect exactly per iter27 dmesg printk. + */ + slice_params->bit_size = + (slice->slice_data_size - slice->slice_data_byte_offset) * 8; /* C1: data_byte_offset, NOT data_bit_offset. Plain byte offset to * the first byte of slice segment header data within the OUTPUT