From 5973aa85059a8a01ef8a9fe73a97245a9ec50d24 Mon Sep 17 00:00:00 2001 From: Yinjie Yao Date: Mon, 21 Apr 2025 11:58:47 -0400 Subject: [PATCH] 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 Reviewed-by: Boyuan Zhang Reviewed-by: Ruijing Dong Part-of: (cherry picked from commit eecfb02463e7dacbb2f3f949b46bd5c0d9ebbe3e) --- .pick_status.json | 2 +- src/gallium/frontends/va/picture_av1.c | 11 ++++++++++- src/gallium/frontends/va/picture_h264.c | 11 ++++++++++- src/gallium/frontends/va/picture_hevc.c | 11 ++++++++++- src/gallium/frontends/va/picture_vp9.c | 11 ++++++++++- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 1e37278a895..ef1de340181 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/gallium/frontends/va/picture_av1.c b/src/gallium/frontends/va/picture_av1.c index 5542c7db1f6..d7a7d60c277 100644 --- a/src/gallium/frontends/va/picture_av1.c +++ b/src/gallium/frontends/va/picture_av1.c @@ -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] = diff --git a/src/gallium/frontends/va/picture_h264.c b/src/gallium/frontends/va/picture_h264.c index 158f40811c9..b329436b745 100644 --- a/src/gallium/frontends/va/picture_h264.c +++ b/src/gallium/frontends/va/picture_h264.c @@ -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; diff --git a/src/gallium/frontends/va/picture_hevc.c b/src/gallium/frontends/va/picture_hevc.c index b4e79558f30..29bcac5488d 100644 --- a/src/gallium/frontends/va/picture_hevc.c +++ b/src/gallium/frontends/va/picture_hevc.c @@ -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 */ diff --git a/src/gallium/frontends/va/picture_vp9.c b/src/gallium/frontends/va/picture_vp9.c index f08b019fac1..11206f66851 100644 --- a/src/gallium/frontends/va/picture_vp9.c +++ b/src/gallium/frontends/va/picture_vp9.c @@ -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] =