From 63f2fa10cca834c0da049369cecefc2bfa30ee10 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 21 Feb 2025 14:39:55 +0100 Subject: [PATCH] frontends/va: Set AV1 max_width/height to surface size Ideally this would be passed in pic params as the values are in sequence header, but using the surface size also works. Also add sanity checks for frame size. Fixes decoding av1-1-b8-22-svc-L2T1 and av1-1-b8-22-svc-L2T2. Cc: mesa-stable Reviewed-by: Ruijing Dong Part-of: (cherry picked from commit d0414ef7fbaf3c9eaaac6fc2f1899b11250df664) --- .pick_status.json | 2 +- src/gallium/frontends/va/picture.c | 2 +- src/gallium/frontends/va/picture_av1.c | 21 +++++++++++++++++---- src/gallium/frontends/va/va_private.h | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index b8292c19709..b8956371455 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -34,7 +34,7 @@ "description": "frontends/va: Set AV1 max_width/height to surface size", "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.c b/src/gallium/frontends/va/picture.c index c61ee47996a..3440c356be5 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -260,7 +260,7 @@ handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext *context, vlVaBuffer * break; case PIPE_VIDEO_FORMAT_AV1: - vlVaHandlePictureParameterBufferAV1(drv, context, buf); + vaStatus = vlVaHandlePictureParameterBufferAV1(drv, context, buf); break; default: diff --git a/src/gallium/frontends/va/picture_av1.c b/src/gallium/frontends/va/picture_av1.c index 5100a652010..5542c7db1f6 100644 --- a/src/gallium/frontends/va/picture_av1.c +++ b/src/gallium/frontends/va/picture_av1.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "util/vl_vlc.h" +#include "util/u_handle_table.h" #include "va_private.h" #define AV1_REFS_PER_FRAME 7 @@ -114,11 +115,12 @@ static void tile_info(vlVaContext *context, VADecPictureParameterBufferAV1 *av1) } } -void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +VAStatus vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) { VADecPictureParameterBufferAV1 *av1 = buf->data; int i, j; bool use_lr; + vlVaSurface *surf; assert(buf->size >= sizeof(VADecPictureParameterBufferAV1) && buf->num_elements == 1); @@ -134,8 +136,6 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, context->desc.av1.picture_parameter.seq_info_fields.enable_intra_edge_filter = av1->seq_info_fields.fields.enable_intra_edge_filter; context->desc.av1.picture_parameter.order_hint_bits_minus_1 = av1->order_hint_bits_minus_1; - context->desc.av1.picture_parameter.max_width = av1->frame_width_minus1 + 1; - context->desc.av1.picture_parameter.max_height = av1->frame_height_minus1 + 1; context->desc.av1.picture_parameter.seq_info_fields.enable_interintra_compound = av1->seq_info_fields.fields.enable_interintra_compound; context->desc.av1.picture_parameter.seq_info_fields.enable_masked_compound = @@ -202,9 +202,20 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, context->desc.av1.picture_parameter.order_hint = av1->order_hint; context->desc.av1.picture_parameter.primary_ref_frame = av1->primary_ref_frame; + + surf = handle_table_get(drv->htab, av1->current_frame); + if (!surf) + return VA_STATUS_ERROR_INVALID_SURFACE; + + context->desc.av1.picture_parameter.max_width = surf->templat.width; + context->desc.av1.picture_parameter.max_height = surf->templat.height; context->desc.av1.picture_parameter.frame_width = av1->frame_width_minus1 + 1; context->desc.av1.picture_parameter.frame_height = av1->frame_height_minus1 + 1; + if (context->desc.av1.picture_parameter.frame_width > context->desc.av1.picture_parameter.max_width || + context->desc.av1.picture_parameter.frame_height > context->desc.av1.picture_parameter.max_height) + return VA_STATUS_ERROR_INVALID_PARAMETER; + context->desc.av1.picture_parameter.superres_scale_denominator = av1->superres_scale_denominator; @@ -397,7 +408,9 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, vlVaGetReferenceFrame(drv, av1->ref_frame_map[i], &context->desc.av1.ref[i]); } - context->desc.av1.slice_parameter.slice_count = 0; + context->desc.av1.slice_parameter.slice_count = 0; + + return VA_STATUS_SUCCESS; } void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf) diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index 86fe7fa8de5..3e470b1ffd9 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -603,7 +603,7 @@ void vlVaHandleSliceParameterBufferMJPEG(vlVaContext *context, vlVaBuffer *buf); void vlVaHandlePictureParameterBufferVP9(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf); void vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf); -void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); +VAStatus vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf); void vlVaHandleVAEncMiscParameterTypeQualityLevel(struct pipe_enc_quality_modes *p, vlVaQualityBits *in); VAStatus vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);