From 6746d4df6eac83d048e88c2d54aa19e7c1a0a696 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Sat, 27 Apr 2024 19:06:24 +0200 Subject: [PATCH] frontends/va: Fix AV1 slice_data_offset with multiple slice data buffers The slice parameter data offset refers to offset in the submitted data buffer. When multiple slice data buffers are submitted, the offsets of all slices needs to be adjusted to be based from the start of the first data buffer. Cc: mesa-stable Reviewed-by: Leo Liu Part-of: --- src/gallium/frontends/va/picture.c | 10 +++++++--- src/gallium/frontends/va/picture_av1.c | 4 ++-- src/gallium/frontends/va/va_private.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index 256d0af5c11..0956b065caa 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -299,7 +299,7 @@ handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf) } static void -handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num_slices) +handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num_slices, unsigned slice_offset) { switch (u_reduce_video_profile(context->templat.profile)) { case PIPE_VIDEO_FORMAT_MPEG12: @@ -331,7 +331,7 @@ handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num_s break; case PIPE_VIDEO_FORMAT_AV1: - vlVaHandleSliceParameterBufferAV1(context, buf, num_slices); + vlVaHandleSliceParameterBufferAV1(context, buf, num_slices, slice_offset); break; default: @@ -968,6 +968,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff unsigned i; unsigned slice_idx = 0; + unsigned slice_offset = 0; vlVaBuffer *seq_param_buf = NULL; if (!ctx) @@ -1023,13 +1024,16 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff slice_idx is the zero based number of total slices received before this call to handleSliceParameterBuffer + + slice_offset is the slice offset in bitstream buffer */ - handleSliceParameterBuffer(context, buf, slice_idx); + handleSliceParameterBuffer(context, buf, slice_idx, slice_offset); slice_idx += buf->num_elements; } break; case VASliceDataBufferType: vaStatus = handleVASliceDataBufferType(context, buf); + slice_offset += buf->size; break; case VAProcPipelineParameterBufferType: diff --git a/src/gallium/frontends/va/picture_av1.c b/src/gallium/frontends/va/picture_av1.c index e6f2652e362..c014b0b1168 100644 --- a/src/gallium/frontends/va/picture_av1.c +++ b/src/gallium/frontends/va/picture_av1.c @@ -396,7 +396,7 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, context->desc.av1.slice_parameter.slice_count = 0; } -void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned num_slices) +void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned num_slices, unsigned slice_offset) { for (uint32_t buffer_idx = 0; buffer_idx < buf->num_elements; buffer_idx++) { uint32_t slice_index = @@ -407,7 +407,7 @@ void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, un VASliceParameterBufferAV1 *av1 = &(((VASliceParameterBufferAV1*)buf->data)[buffer_idx]); context->desc.av1.slice_parameter.slice_data_size[slice_index] = av1->slice_data_size; - context->desc.av1.slice_parameter.slice_data_offset[slice_index] = av1->slice_data_offset; + context->desc.av1.slice_parameter.slice_data_offset[slice_index] = slice_offset + av1->slice_data_offset; context->desc.av1.slice_parameter.slice_data_row[slice_index] = av1->tile_row; context->desc.av1.slice_parameter.slice_data_col[slice_index] = av1->tile_column; context->desc.av1.slice_parameter.slice_data_anchor_frame_idx[slice_index] = av1->anchor_frame_idx; diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index 7e3890073fe..b1baec6619a 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -542,7 +542,7 @@ void vlVaHandlePictureParameterBufferVP9(vlVaDriver *drv, vlVaContext *context, void vlVaHandleSliceParameterBufferVP9(vlVaContext *context, vlVaBuffer *buf); void vlVaDecoderVP9BitstreamHeader(vlVaContext *context, vlVaBuffer *buf); void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); -void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned num_slices); +void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned num_slices, unsigned slice_offset); void getEncParamPresetH264(vlVaContext *context); void getEncParamPresetH265(vlVaContext *context); void getEncParamPresetAV1(vlVaContext *context);