frontends/va: get av1 encoding ref frame infos for L0.

Reference frame list is formed by each of the provided
recon_frame, while the assumption here is to use the API
provided by VAAPI interface, when a frame is marked as
"long term reference" by

av1->picture_flags.bits.long_term_reference

Its recon_frame will be kept in DPB marked by its
recon_frame as signature. When a future input requests
refering to it, it can go this way:

1. set av1->ref_frame_ctrl_l0.field.search_idx2 to indicate
   which ref_frame_idx slot will be used.
   x = av1->ref_frame_ctrl_l0.field.search_idx2;
2. n = av1->ref_frame_idx[x-1];
   av1->reference_frames[n] as the signature to compare with.
   if av1->reference_frames[n] is pointing to the
   same video buffer (signature) as the one marked as
   "long term reference". Then the new input is refering to
   it only.
3. in SVC case, long terms are used for temproal_id 0 only,
   because using long term means potentially scene change
   could happen.
4. the "long term reference" recon_frame should be kept,
   instead of being reused until it is no longer needed to
   avoid signature duplication.

Reviewed-by: Leo Liu <leo.liu@amd.com>
Signed-off-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27771>
This commit is contained in:
Ruijing Dong 2024-02-22 15:21:30 -05:00 committed by Marge Bot
parent 4b92fa9e10
commit eb74aa8515

View file

@ -133,6 +133,7 @@ VAStatus vlVaHandleVAEncSequenceParameterBufferTypeAV1(vlVaDriver *drv, vlVaCont
VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
{
VAEncPictureParameterBufferAV1 *av1 = buf->data;
struct pipe_video_buffer *video_buf = NULL;
vlVaBuffer *coded_buf;
int i;
@ -142,6 +143,7 @@ VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaConte
context->desc.av1enc.enable_frame_obu = av1->picture_flags.bits.enable_frame_obu;
context->desc.av1enc.allow_high_precision_mv = av1->picture_flags.bits.allow_high_precision_mv;
context->desc.av1enc.palette_mode_enable = av1->picture_flags.bits.palette_mode_enable;
context->desc.av1enc.long_term_reference = av1->picture_flags.bits.long_term_reference;
context->desc.av1enc.num_tiles_in_pic = av1->tile_cols * av1->tile_rows;
context->desc.av1enc.tile_rows = av1->tile_rows;
context->desc.av1enc.tile_cols = av1->tile_cols;
@ -157,14 +159,14 @@ VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaConte
/* The last tile column or row size needs to be derived. */
for (uint8_t i = 0 ; i < ARRAY_SIZE(av1->width_in_sbs_minus_1); i++)
context->desc.av1enc.width_in_sbs_minus_1[i] = av1->width_in_sbs_minus_1[i];
/* The last tile column or row size needs to be derived. */
for (uint8_t i = 0 ; i < ARRAY_SIZE(av1->height_in_sbs_minus_1); i++)
context->desc.av1enc.height_in_sbs_minus_1[i] = av1->height_in_sbs_minus_1[i];
context->desc.av1enc.cdef.cdef_damping_minus_3 = av1->cdef_damping_minus_3;
context->desc.av1enc.cdef.cdef_bits = av1->cdef_bits;
for (uint8_t i = 0 ; i < ARRAY_SIZE(av1->cdef_y_strengths); i++)
context->desc.av1enc.cdef.cdef_y_strengths[i] = av1->cdef_y_strengths[i];
@ -226,7 +228,7 @@ VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaConte
context->desc.av1enc.rc[i].min_qp = av1->min_base_qindex ? av1->min_base_qindex : 1;
context->desc.av1enc.rc[i].max_qp = av1->max_base_qindex ? av1->max_base_qindex : 255;
/* Distinguishes from the default params set for these values and app specific params passed down */
context->desc.av1enc.rc[i].app_requested_qp_range =
context->desc.av1enc.rc[i].app_requested_qp_range =
((context->desc.av1enc.rc[i].max_qp != AV1_MAX_QP_DEFAULT) || (context->desc.av1enc.rc[i].min_qp != AV1_MIN_QP_DEFAULT));
}
@ -250,7 +252,25 @@ VAStatus vlVaHandleVAEncPictureParameterBufferTypeAV1(vlVaDriver *drv, vlVaConte
if (context->desc.av1enc.frame_type == FRAME_TYPE_KEY_FRAME)
context->desc.av1enc.last_key_frame_num = context->desc.av1enc.frame_num;
for (uint8_t i = 0 ; i < ARRAY_SIZE(av1->ref_frame_idx); i++)
if (av1->reconstructed_frame != VA_INVALID_ID) {
vlVaGetReferenceFrame(drv, av1->reconstructed_frame, &video_buf);
context->desc.av1enc.recon_frame = video_buf;
}
else
context->desc.av1enc.recon_frame = NULL;
for (int i = 0 ; i < ARRAY_SIZE(context->desc.av1enc.ref_list); i++) {
if (av1->reference_frames[i] != VA_INVALID_ID) {
vlVaGetReferenceFrame(drv, av1->reference_frames[i], &video_buf);
context->desc.av1enc.ref_list[i] = video_buf;
}
else
context->desc.av1enc.ref_list[i] = NULL;
}
context->desc.av1enc.ref_frame_ctrl_l0 = av1->ref_frame_ctrl_l0.value;
for (int i = 0 ; i < ARRAY_SIZE(av1->ref_frame_idx); i++)
context->desc.av1enc.ref_frame_idx[i] = av1->ref_frame_idx[i];
/* Initialize slice descriptors for this picture */
@ -817,7 +837,7 @@ void getEncParamPresetAV1(vlVaContext *context)
VAStatus vlVaHandleVAEncSliceParameterBufferTypeAV1(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
{
VAEncTileGroupBufferAV1 *tile_buf = (VAEncTileGroupBufferAV1*) buf->data;
if (context->desc.av1enc.num_tile_groups < ARRAY_SIZE(context->desc.av1enc.tile_groups)) {
context->desc.av1enc.tile_groups[context->desc.av1enc.num_tile_groups].tile_group_start = tile_buf->tg_start;
context->desc.av1enc.tile_groups[context->desc.av1enc.num_tile_groups].tile_group_end = tile_buf->tg_end;
@ -825,7 +845,7 @@ VAStatus vlVaHandleVAEncSliceParameterBufferTypeAV1(vlVaDriver *drv, vlVaContext
} else {
return VA_STATUS_ERROR_NOT_ENOUGH_BUFFER;
}
return VA_STATUS_SUCCESS;
}
#endif /* VA_CHECK_VERSION(1, 16, 0) */