frontends/va: Handle properly when decoding more slices than limit

For h264/h265/av1/vp9, give warning when application is
sending more slices than allowed by limit, and stop copying
remaining slices to avoid unwanted behaviour.

Cc: mesa-stable
Signed-off-by: Yinjie Yao <yinjie.yao@amd.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34633>
(cherry picked from commit eecfb02463e7dacbb2f3f949b46bd5c0d9ebbe3e)
This commit is contained in:
Yinjie Yao
2025-04-21 11:58:47 -04:00
committed by Eric Engestrom
parent c3c65d8b25
commit 5973aa8505
5 changed files with 41 additions and 5 deletions

View File

@@ -914,7 +914,7 @@
"description": "frontends/va: Handle properly when decoding more slices than limit",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View File

@@ -420,8 +420,17 @@ void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf)
for (uint32_t buffer_idx = 0; buffer_idx < buf->num_elements; buffer_idx++, av1++) {
uint32_t slice_index = context->desc.av1.slice_parameter.slice_count + buffer_idx;
ASSERTED const size_t max_pipe_av1_slices = ARRAY_SIZE(context->desc.av1.slice_parameter.slice_data_offset);
const size_t max_pipe_av1_slices = ARRAY_SIZE(context->desc.av1.slice_parameter.slice_data_offset);
assert(slice_index < max_pipe_av1_slices);
if (slice_index >= max_pipe_av1_slices) {
static bool warn_once = true;
if (warn_once) {
fprintf(stderr, "Warning: Number of slices (%d) provided exceed driver's max supported (%d), stop handling remaining slices.\n",
slice_index + 1, (int)max_pipe_av1_slices);
warn_once = false;
}
return;
}
context->desc.av1.slice_parameter.slice_data_size[slice_index] = av1->slice_data_size;
context->desc.av1.slice_parameter.slice_data_offset[slice_index] =

View File

@@ -183,8 +183,17 @@ void vlVaHandleSliceParameterBufferH264(vlVaContext *context, vlVaBuffer *buf)
for (uint32_t buffer_idx = 0; buffer_idx < buf->num_elements; buffer_idx++, h264++) {
uint32_t slice_index = context->desc.h264.slice_count + buffer_idx;
ASSERTED const size_t max_pipe_h264_slices = ARRAY_SIZE(context->desc.h264.slice_parameter.slice_data_offset);
const size_t max_pipe_h264_slices = ARRAY_SIZE(context->desc.h264.slice_parameter.slice_data_offset);
assert(slice_index < max_pipe_h264_slices);
if (slice_index >= max_pipe_h264_slices) {
static bool warn_once = true;
if (warn_once) {
fprintf(stderr, "Warning: Number of slices (%d) provided exceed driver's max supported (%d), stop handling remaining slices.\n",
slice_index + 1, (int)max_pipe_h264_slices);
warn_once = false;
}
return;
}
context->desc.h264.slice_parameter.slice_info_present = true;
context->desc.h264.slice_parameter.slice_type[slice_index] = h264->slice_type;

View File

@@ -230,8 +230,17 @@ void vlVaHandleSliceParameterBufferHEVC(vlVaContext *context, vlVaBuffer *buf)
for (uint32_t buffer_idx = 0; buffer_idx < buf->num_elements; buffer_idx++, h265++) {
uint32_t slice_index = context->desc.h265.slice_parameter.slice_count + buffer_idx;
ASSERTED const size_t max_pipe_hevc_slices = ARRAY_SIZE(context->desc.h265.slice_parameter.slice_data_offset);
const size_t max_pipe_hevc_slices = ARRAY_SIZE(context->desc.h265.slice_parameter.slice_data_offset);
assert(slice_index < max_pipe_hevc_slices);
if (slice_index >= max_pipe_hevc_slices) {
static bool warn_once = true;
if (warn_once) {
fprintf(stderr, "Warning: Number of slices (%d) provided exceed driver's max supported (%d), stop handling remaining slices.\n",
slice_index + 1, (int)max_pipe_hevc_slices);
warn_once = false;
}
return;
}
switch(h265->LongSliceFlags.fields.slice_type) {
/* Depending on slice_type, only update relevant reference */

View File

@@ -113,8 +113,17 @@ void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf)
assert(buf->size >= sizeof(VASliceParameterBufferVP9) && buf->num_elements == 1);
ASSERTED const size_t max_pipe_vp9_slices = ARRAY_SIZE(context->desc.vp9.slice_parameter.slice_data_offset);
const size_t max_pipe_vp9_slices = ARRAY_SIZE(context->desc.vp9.slice_parameter.slice_data_offset);
assert(context->desc.vp9.slice_parameter.slice_count < max_pipe_vp9_slices);
if (context->desc.vp9.slice_parameter.slice_count >= max_pipe_vp9_slices) {
static bool warn_once = true;
if (warn_once) {
fprintf(stderr, "Warning: Number of slices (%d) provided exceed driver's max supported (%d), stop handling remaining slices.\n",
context->desc.vp9.slice_parameter.slice_count + 1, (int)max_pipe_vp9_slices);
warn_once = false;
}
return;
}
context->desc.vp9.slice_parameter.slice_info_present = true;
context->desc.vp9.slice_parameter.slice_data_size[context->desc.vp9.slice_parameter.slice_count] =