From 5f4a6b5b00b392a2c98f8565fb967871bdd24a29 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 3 May 2024 16:20:44 +0200 Subject: [PATCH] radeonsi/vcn: Ensure at least one reference for H264 P/B frames The original fix from 0f3370eede2 ("raseonsi/vcn: fix a h264 decoding issue") would in some cases also trigger for I frames with interlaced streams. Instead of checking used_for_reference_flags, use slice type and only add one reference for P/B frames if needed. This change still fixes playback of the sample from the original issue, avoids the issue with interlaced streams and also fixes the case where application provides no references at all. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11060 Cc: mesa-stable Reviewed-by: Leo Liu Part-of: --- src/gallium/drivers/radeonsi/radeon_vcn_dec.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c index 10b091ba5c0..08677b9d2f0 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c @@ -242,15 +242,13 @@ static rvcn_dec_message_avc_t get_h264_msg(struct radeon_decoder *dec, } } - /* if reference picture exists, however no reference picture found at the end - curr_pic_ref_frame_num == 0, which is not reasonable, should be corrected. */ - if (result.used_for_reference_flags && (result.curr_pic_ref_frame_num == 0)) { - for (i = 0; i < ARRAY_SIZE(result.ref_frame_list); i++) { - result.ref_frame_list[i] = pic->ref[i] ? - (uintptr_t)vl_video_buffer_get_associated_data(pic->ref[i], &dec->base) : 0xff; - if (result.ref_frame_list[i] != 0xff) { + /* need at least one reference for P/B frames */ + if (result.curr_pic_ref_frame_num == 0 && pic->slice_parameter.slice_info_present) { + for (i = 0; i < pic->slice_count; i++) { + if (pic->slice_parameter.slice_type[i] % 5 != 2) { result.curr_pic_ref_frame_num++; - result.non_existing_frame_flags &= ~(1 << i); + result.ref_frame_list[0] = 0; + result.non_existing_frame_flags &= ~1; break; } }