From 0fd4f15601ae6561948426325f0ac91a5159737b 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: (cherry picked from commit 5f4a6b5b00b392a2c98f8565fb967871bdd24a29) --- .pick_status.json | 2 +- src/gallium/drivers/radeonsi/radeon_vcn_dec.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index bf855dace04..1d232b4aaa4 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -554,7 +554,7 @@ "description": "radeonsi/vcn: Ensure at least one reference for H264 P/B frames", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c index cbb9272300e..ee52d8c7f5a 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c @@ -239,15 +239,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; } }