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>
This commit is contained in:
Hyunjun Ko 2025-11-19 14:09:15 +01:00 committed by Marge Bot
parent 0fd0b76922
commit 01de6ac134
3 changed files with 14 additions and 4 deletions

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

@ -1259,10 +1259,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;
}
@ -1274,9 +1279,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]));
}
}
}
@ -1549,12 +1556,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

@ -304,6 +304,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);