vulkan/video: Fix H.265 long-term reference handling

Without these fixes, H.265 streams using long-term references would
fail to decode correctly as the decoder wouldn't distinguish between
short-term and long-term reference frames.

Fixes: 896f95a37e ("vulkan/video: fix h265 decoding with LT enabled.")

Signed-off-by: Hyunjun Ko <zzoon@igalia.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38571>
(cherry picked from commit 01de6ac134)
This commit is contained in:
Hyunjun Ko 2025-11-19 14:09:15 +01:00 committed by Dylan Baker
parent 79f83a1c6b
commit db00a91bad
4 changed files with 15 additions and 5 deletions

View file

@ -3054,7 +3054,7 @@
"description": "vulkan/video: Fix H.265 long-term reference handling",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "896f95a37ef6c21ebdb5084bce1cf3288e6d596a",
"notes": null

View file

@ -811,6 +811,7 @@ anv_h265_decode_video(struct anv_cmd_buffer *cmd_buffer,
ref.ReferenceListEntry[i].ListEntry = dpb_idx[slot_idx];
ref.ReferenceListEntry[i].ReferencePicturetbValue = CLAMP(diff_poc, -128, 127) & 0xff;
ref.ReferenceListEntry[i].TopField = true;
ref.ReferenceListEntry[i].LongTermReference = ref_slots[0][i].lt;
}
}
}
@ -830,6 +831,7 @@ anv_h265_decode_video(struct anv_cmd_buffer *cmd_buffer,
ref.ReferenceListEntry[i].ListEntry = dpb_idx[slot_idx];
ref.ReferenceListEntry[i].ReferencePicturetbValue = CLAMP(diff_poc, -128, 127) & 0xff;
ref.ReferenceListEntry[i].TopField = true;
ref.ReferenceListEntry[i].LongTermReference = ref_slots[1][i].lt;
}
}
}

View file

@ -1244,10 +1244,15 @@ vk_fill_video_h265_reference_info(const VkVideoDecodeInfoKHR *frame_info,
const uint8_t *cur_rps = rps[i];
for (j = 0; (cur_rps[j] != 0xff) && ((j + ref_idx) < 8); j++) {
ref_slots_tmp[list_idx][j + ref_idx].slot_index = cur_rps[j];
ref_slots_tmp[list_idx][j + ref_idx].pic_order_cnt =
vk_video_h265_poc_by_slot(frame_info, cur_rps[j]);
if (i == 2)
ref_slots_tmp[list_idx][j + ref_idx].lt = true;
}
/* TODO handle pps_curr_pic_ref_enabled_flag here */
ref_idx += j;
}
@ -1259,9 +1264,11 @@ vk_fill_video_h265_reference_info(const VkVideoDecodeInfoKHR *frame_info,
ref_slots_tmp[list_idx][slice_params->list_entry_lx[list_idx][i]].slot_index;
ref_slots[list_idx][i].pic_order_cnt =
ref_slots_tmp[list_idx][slice_params->list_entry_lx[list_idx][i]].pic_order_cnt;
ref_slots[list_idx][i].lt =
ref_slots_tmp[list_idx][slice_params->list_entry_lx[list_idx][i]].lt;
}
} else {
memcpy(ref_slots, &ref_slots_tmp, sizeof(ref_slots_tmp));
memcpy(ref_slots[list_idx], &ref_slots_tmp[list_idx], sizeof(ref_slots_tmp[list_idx]));
}
}
}
@ -1534,12 +1541,12 @@ vk_video_parse_h265_slice_header(const struct VkVideoDecodeInfoKHR *frame_info,
for (unsigned i = 0; i < num_refs; i++) {
if (i < num_lt_sps) {
int lt_idx_sps = 0;
if (sps->num_long_term_ref_pics_sps > 1)
/* lt_idx_sps */
vl_rbsp_u(&rbsp,
lt_idx_sps = vl_rbsp_u(&rbsp,
util_logbase2_ceil(sps->num_long_term_ref_pics_sps));
if (sps->pLongTermRefPicsSps->used_by_curr_pic_lt_sps_flag)
if (sps->pLongTermRefPicsSps->used_by_curr_pic_lt_sps_flag & (1 << lt_idx_sps))
nb_refs++;
} else {
/* poc_lsb_lt */

View file

@ -295,6 +295,7 @@ struct vk_video_h265_reference {
StdVideoDecodeH265ReferenceInfoFlags flags;
uint32_t slot_index;
int32_t pic_order_cnt;
bool lt;
};
int vk_video_h265_poc_by_slot(const struct VkVideoDecodeInfoKHR *frame_info, int slot);