frontends/va: Support AV1 Decode with multiple tiles (num_elements > 1) in a single VASliceParameterBufferAV1 buffer

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18875>
This commit is contained in:
Sil Vilerino 2022-09-16 10:29:13 -04:00
parent d5b4dec033
commit e91636ae26
3 changed files with 32 additions and 12 deletions

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);