diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index 31d5bc1c26f..11ac77ccb3f 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -261,7 +261,7 @@ handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf) } static void -handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num) +handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num_slice_buffers, unsigned num_slices) { switch (u_reduce_video_profile(context->templat.profile)) { case PIPE_VIDEO_FORMAT_MPEG12: @@ -293,7 +293,7 @@ handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer *buf, unsigned num) break; case PIPE_VIDEO_FORMAT_AV1: - vlVaHandleSliceParameterBufferAV1(context, buf, num); + vlVaHandleSliceParameterBufferAV1(context, buf, num_slice_buffers, num_slices); break; default: @@ -695,6 +695,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff unsigned i; unsigned slice_param_idx = 0; + unsigned slice_idx = 0; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; @@ -735,8 +736,20 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff break; case VASliceParameterBufferType: - handleSliceParameterBuffer(context, buf, slice_param_idx++); - break; + { + /* Some apps like gstreamer send all the slices at once + and some others send individual VASliceParameterBufferType buffers + + slice_param_idx is the zero based count of VASliceParameterBufferType + (including multiple buffers with num_elements > 1) received + before this call to handleSliceParameterBuffer + + slice_idx is the zero based number of total slices received + before this call to handleSliceParameterBuffer + */ + handleSliceParameterBuffer(context, buf, slice_param_idx++, slice_idx); + slice_idx += buf->num_elements; + } break; case VASliceDataBufferType: vaStatus = handleVASliceDataBufferType(context, buf); diff --git a/src/gallium/frontends/va/picture_av1.c b/src/gallium/frontends/va/picture_av1.c index c373a4f234a..970aa7c8d27 100644 --- a/src/gallium/frontends/va/picture_av1.c +++ b/src/gallium/frontends/va/picture_av1.c @@ -370,13 +370,20 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, vlVaContext *context, } } -void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned int num) +void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned num_slice_buffers, unsigned num_slices) { - VASliceParameterBufferAV1 *av1 = buf->data; + for (uint32_t buffer_idx = 0; buffer_idx < buf->num_elements; buffer_idx++) { + uint32_t slice_index = + /* slices obtained so far from vaRenderPicture in previous calls*/ + num_slices + + /* current slice index processing this VASliceParameterBufferAV1 */ + buffer_idx; - context->desc.av1.slice_parameter.slice_data_size[num] = av1->slice_data_size; - context->desc.av1.slice_parameter.slice_data_offset[num] = av1->slice_data_offset; - context->desc.av1.slice_parameter.slice_data_row[num] = av1->tile_row; - context->desc.av1.slice_parameter.slice_data_col[num] = av1->tile_column; - context->desc.av1.slice_parameter.slice_data_anchor_frame_idx[num] = av1->anchor_frame_idx; + 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_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 9a4f5e7c0b0..6f3f8306c6c 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -490,7 +490,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 int num); +void vlVaHandleSliceParameterBufferAV1(vlVaContext *context, vlVaBuffer *buf, unsigned num_slice_buffers, unsigned num_slices); void getEncParamPresetH264(vlVaContext *context); void getEncParamPresetH265(vlVaContext *context); void vlVaHandleVAEncMiscParameterTypeQualityLevel(struct pipe_enc_quality_modes *p, vlVaQualityBits *in);