Module: Mesa Branch: main Commit: 8e03c189147cd226177bd5134dc1eb11cf6791c8 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8e03c189147cd226177bd5134dc1eb11cf6791c8
Author: Ruijing Dong <ruijing.d...@amd.com> Date: Thu Nov 9 12:03:04 2023 -0500 frontends/va: add intra-refresh in VAAPI interface Row and column modes are enabled, not the mixed mode, application should have a logic of sending a period of intra-refresh sequence to complete the intra-refresh cycle. Reviewed-by: Sil Vilerino <sivil...@microsoft.com> Reviewed-by: Boyuan Zhang <boyuan.zh...@amd.com> Signed-off-by: Ruijing Dong <ruijing.d...@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26133> --- src/gallium/frontends/va/config.c | 11 ++++++ src/gallium/frontends/va/picture.c | 57 +++++++++++++++++++++++++++++ src/gallium/frontends/va/picture_av1_enc.c | 4 ++ src/gallium/frontends/va/picture_h264_enc.c | 4 ++ src/gallium/frontends/va/picture_hevc_enc.c | 4 ++ 5 files changed, 80 insertions(+) diff --git a/src/gallium/frontends/va/config.c b/src/gallium/frontends/va/config.c index f94dc6bc241..26328be4e3c 100644 --- a/src/gallium/frontends/va/config.c +++ b/src/gallium/frontends/va/config.c @@ -516,6 +516,17 @@ vlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint en value = max_tile_cols; } break; #endif + case VAConfigAttribEncIntraRefresh: + { + int ir_support = pscreen->get_video_param(pscreen, ProfileToPipe(profile), + PIPE_VIDEO_ENTRYPOINT_ENCODE, + PIPE_VIDEO_CAP_ENC_INTRA_REFRESH); + if (ir_support <= 0) + value = VA_ATTRIB_NOT_SUPPORTED; + else + value = ir_support; + } break; + default: value = VA_ATTRIB_NOT_SUPPORTED; break; diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index ffedf77d0c8..12acf96641c 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -643,6 +643,59 @@ handleVAEncMiscParameterTypeHRD(vlVaContext *context, VAEncMiscParameterBuffer * return status; } +static VAStatus +handleVAEncMiscParameterTypeRIR(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAStatus status = VA_STATUS_SUCCESS; + struct pipe_enc_intra_refresh *p_intra_refresh = NULL; + + switch (u_reduce_video_profile(context->templat.profile)) { + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + p_intra_refresh = &context->desc.h264enc.intra_refresh; + break; + case PIPE_VIDEO_FORMAT_HEVC: + p_intra_refresh = &context->desc.h265enc.intra_refresh; + break; +#if VA_CHECK_VERSION(1, 16, 0) + case PIPE_VIDEO_FORMAT_AV1: + p_intra_refresh = &context->desc.av1enc.intra_refresh; + break; +#endif + default: + p_intra_refresh = NULL; + break; + }; + + if (p_intra_refresh) { + VAEncMiscParameterRIR *ir = (VAEncMiscParameterRIR *)misc->data; + + if (ir->rir_flags.value == VA_ENC_INTRA_REFRESH_ROLLING_ROW) + p_intra_refresh->mode = INTRA_REFRESH_MODE_UNIT_ROWS; + else if (ir->rir_flags.value == VA_ENC_INTRA_REFRESH_ROLLING_COLUMN) + p_intra_refresh->mode = INTRA_REFRESH_MODE_UNIT_COLUMNS; + else if (ir->rir_flags.value) /* if any other values to use the default one*/ + p_intra_refresh->mode = INTRA_REFRESH_MODE_UNIT_COLUMNS; + else /* if no mode specified then no intra-refresh */ + p_intra_refresh->mode = INTRA_REFRESH_MODE_NONE; + + /* intra refresh should be started with sequence level headers */ + p_intra_refresh->need_sequence_header = 0; + if (p_intra_refresh->mode) { + p_intra_refresh->region_size = ir->intra_insert_size; + p_intra_refresh->offset = ir->intra_insertion_location; + if (p_intra_refresh->offset == 0) + p_intra_refresh->need_sequence_header = 1; + } + } else { + p_intra_refresh->mode = INTRA_REFRESH_MODE_NONE; + p_intra_refresh->region_size = 0; + p_intra_refresh->offset = 0; + p_intra_refresh->need_sequence_header = 0; + } + + return status; +} + static VAStatus handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) { @@ -675,6 +728,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) vaStatus = handleVAEncMiscParameterTypeHRD(context, misc); break; + case VAEncMiscParameterTypeRIR: + vaStatus = handleVAEncMiscParameterTypeRIR(context, misc); + break; + default: break; } diff --git a/src/gallium/frontends/va/picture_av1_enc.c b/src/gallium/frontends/va/picture_av1_enc.c index 19348cf95ed..1865c62a7c1 100644 --- a/src/gallium/frontends/va/picture_av1_enc.c +++ b/src/gallium/frontends/va/picture_av1_enc.c @@ -111,6 +111,10 @@ VAStatus vlVaHandleVAEncSequenceParameterBufferTypeAV1(vlVaDriver *drv, vlVaCont return VA_STATUS_ERROR_ALLOCATION_FAILED; getEncParamPresetAV1(context); + context->desc.av1enc.intra_refresh.mode = INTRA_REFRESH_MODE_NONE; + context->desc.av1enc.intra_refresh.offset = 0; + context->desc.av1enc.intra_refresh.region_size = 0; + context->desc.av1enc.intra_refresh.need_sequence_header = 0; } context->desc.av1enc.seq.tier = av1->seq_tier; diff --git a/src/gallium/frontends/va/picture_h264_enc.c b/src/gallium/frontends/va/picture_h264_enc.c index 56c600613dc..0184648311a 100644 --- a/src/gallium/frontends/va/picture_h264_enc.c +++ b/src/gallium/frontends/va/picture_h264_enc.c @@ -201,6 +201,10 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con context->desc.h264enc.rate_ctrl[0].max_qp = 51; context->desc.h264enc.rate_ctrl[0].min_qp = 0; context->desc.h264enc.enable_vui = false; + context->desc.h264enc.intra_refresh.mode = INTRA_REFRESH_MODE_NONE; + context->desc.h264enc.intra_refresh.offset = 0; + context->desc.h264enc.intra_refresh.region_size = 0; + context->desc.h264enc.intra_refresh.need_sequence_header = 0; } context->desc.h264enc.intra_idr_period = diff --git a/src/gallium/frontends/va/picture_hevc_enc.c b/src/gallium/frontends/va/picture_hevc_enc.c index b0aa1b946b0..b3b8b689272 100644 --- a/src/gallium/frontends/va/picture_hevc_enc.c +++ b/src/gallium/frontends/va/picture_hevc_enc.c @@ -173,6 +173,10 @@ vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *con context->desc.h265enc.rc.enforce_hrd = 1; context->desc.h265enc.rc.max_qp = 51; context->desc.h265enc.rc.min_qp = 0; + context->desc.h265enc.intra_refresh.mode = INTRA_REFRESH_MODE_NONE; + context->desc.h265enc.intra_refresh.offset = 0; + context->desc.h265enc.intra_refresh.region_size = 0; + context->desc.h265enc.intra_refresh.need_sequence_header = 0; } context->desc.h265enc.seq.general_profile_idc = h265->general_profile_idc;