From 0308abbe4625972735b8ca3cfe60eec76ca482f0 Mon Sep 17 00:00:00 2001 From: Ruijing Dong Date: Sat, 10 Sep 2022 16:52:12 -0400 Subject: [PATCH] frontends/va: add HRD, filler data enable and etc HRD parameters and filler data enable and skip frame enable data are needed even though some application doesn't use them. Also for per picture rate control, max_qp and min_qp are added. Signed-off-by: Ruijing Dong Reviewed-By: Sil Vilerino Part-of: --- src/gallium/drivers/radeonsi/radeon_vcn_enc.c | 15 ++++++----- src/gallium/frontends/va/picture.c | 25 +++++++++++++++++++ src/gallium/frontends/va/picture_h264_enc.c | 20 +++++++++++++++ src/gallium/frontends/va/picture_hevc_enc.c | 21 ++++++++++++++++ src/gallium/frontends/va/va_private.h | 2 ++ src/gallium/include/pipe/p_video_state.h | 6 +++++ 6 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c index 6f1ce274e14..208dcc70ae0 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c @@ -115,11 +115,11 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic } enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl[0].vbv_buf_lv; enc->enc_pic.rc_per_pic.qp = pic->quant_i_frames; - enc->enc_pic.rc_per_pic.min_qp_app = 0; - enc->enc_pic.rc_per_pic.max_qp_app = 51; - enc->enc_pic.rc_per_pic.max_au_size = 0; + enc->enc_pic.rc_per_pic.min_qp_app = pic->rate_ctrl[0].min_qp; + enc->enc_pic.rc_per_pic.max_qp_app = pic->rate_ctrl[0].max_qp ? + pic->rate_ctrl[0].max_qp : 51; enc->enc_pic.rc_per_pic.enabled_filler_data = pic->rate_ctrl[0].fill_data_enable; - enc->enc_pic.rc_per_pic.skip_frame_enable = false; + enc->enc_pic.rc_per_pic.skip_frame_enable = pic->rate_ctrl[0].skip_frame_enable; enc->enc_pic.rc_per_pic.enforce_hrd = pic->rate_ctrl[0].enforce_hrd; switch (pic->rate_ctrl[0].rate_ctrl_method) { @@ -247,11 +247,10 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic pic->rc.frame_rate_num); enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv; enc->enc_pic.rc_per_pic.qp = pic->rc.quant_i_frames; - enc->enc_pic.rc_per_pic.min_qp_app = 0; - enc->enc_pic.rc_per_pic.max_qp_app = 51; - enc->enc_pic.rc_per_pic.max_au_size = 0; + enc->enc_pic.rc_per_pic.min_qp_app = pic->rc.min_qp; + enc->enc_pic.rc_per_pic.max_qp_app = pic->rc.max_qp ? pic->rc.max_qp : 51; enc->enc_pic.rc_per_pic.enabled_filler_data = pic->rc.fill_data_enable; - enc->enc_pic.rc_per_pic.skip_frame_enable = false; + enc->enc_pic.rc_per_pic.skip_frame_enable = pic->rc.skip_frame_enable; enc->enc_pic.rc_per_pic.enforce_hrd = pic->rc.enforce_hrd; switch (pic->rc.rate_ctrl_method) { case PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE: diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index a8e86b2b4c4..d0a98fd51f2 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -543,6 +543,27 @@ handleVAEncMiscParameterTypeMaxFrameSize(vlVaContext *context, VAEncMiscParamete return status; } +static VAStatus +handleVAEncMiscParameterTypeHRD(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAStatus status = VA_STATUS_SUCCESS; + + switch (u_reduce_video_profile(context->templat.profile)) { + case PIPE_VIDEO_FORMAT_MPEG4_AVC: + status = vlVaHandleVAEncMiscParameterTypeHRDH264(context, misc); + break; + + case PIPE_VIDEO_FORMAT_HEVC: + status = vlVaHandleVAEncMiscParameterTypeHRDHEVC(context, misc); + break; + + default: + break; + } + + return status; +} + static VAStatus handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) { @@ -571,6 +592,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf) vaStatus = handleVAEncMiscParameterTypeMaxFrameSize(context, misc); break; + case VAEncMiscParameterTypeHRD: + vaStatus = handleVAEncMiscParameterTypeHRD(context, misc); + break; + default: break; } diff --git a/src/gallium/frontends/va/picture_h264_enc.c b/src/gallium/frontends/va/picture_h264_enc.c index b9848b9b1db..9fe12d2a4d6 100644 --- a/src/gallium/frontends/va/picture_h264_enc.c +++ b/src/gallium/frontends/va/picture_h264_enc.c @@ -202,6 +202,8 @@ vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscP temporal_id >= context->desc.h264enc.num_temporal_layers) return VA_STATUS_ERROR_INVALID_PARAMETER; + context->desc.h264enc.rate_ctrl[temporal_id].fill_data_enable = !(rc->rc_flags.bits.disable_bit_stuffing); + context->desc.h264enc.rate_ctrl[temporal_id].skip_frame_enable = !(rc->rc_flags.bits.disable_frame_skip); context->desc.h264enc.rate_ctrl[temporal_id].peak_bitrate = rc->bits_per_second; if (context->desc.h264enc.rate_ctrl[temporal_id].target_bitrate < 2000000) context->desc.h264enc.rate_ctrl[temporal_id].vbv_buffer_size = @@ -210,6 +212,9 @@ vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscP context->desc.h264enc.rate_ctrl[temporal_id].vbv_buffer_size = context->desc.h264enc.rate_ctrl[0].target_bitrate; + context->desc.h264enc.rate_ctrl[temporal_id].max_qp = rc->max_qp; + context->desc.h264enc.rate_ctrl[temporal_id].min_qp = rc->min_qp; + return VA_STATUS_SUCCESS; } @@ -267,6 +272,19 @@ vlVaHandleVAEncMiscParameterTypeMaxFrameSizeH264(vlVaContext *context, VAEncMisc return VA_STATUS_SUCCESS; } +VAStatus +vlVaHandleVAEncMiscParameterTypeHRDH264(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterHRD *ms = (VAEncMiscParameterHRD *)misc->data; + + if (ms->buffer_size) { + context->desc.h264enc.rate_ctrl[0].vbv_buffer_size = ms->buffer_size; + context->desc.h264enc.rate_ctrl[0].vbv_buf_lv = (ms->initial_buffer_fullness << 6 ) / ms->buffer_size; + } + + return VA_STATUS_SUCCESS; +} + void getEncParamPresetH264(vlVaContext *context) { //rate control @@ -274,6 +292,8 @@ void getEncParamPresetH264(vlVaContext *context) context->desc.h264enc.rate_ctrl[0].vbv_buf_lv = 48; context->desc.h264enc.rate_ctrl[0].fill_data_enable = 1; context->desc.h264enc.rate_ctrl[0].enforce_hrd = 1; + context->desc.h264enc.rate_ctrl[0].max_qp = 51; + context->desc.h264enc.rate_ctrl[0].min_qp = 0; context->desc.h264enc.enable_vui = false; if (context->desc.h264enc.rate_ctrl[0].frame_rate_num == 0 || context->desc.h264enc.rate_ctrl[0].frame_rate_den == 0) { diff --git a/src/gallium/frontends/va/picture_hevc_enc.c b/src/gallium/frontends/va/picture_hevc_enc.c index 910ecf60836..72a42c95296 100644 --- a/src/gallium/frontends/va/picture_hevc_enc.c +++ b/src/gallium/frontends/va/picture_hevc_enc.c @@ -180,6 +180,11 @@ vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscP else context->desc.h265enc.rc.vbv_buffer_size = context->desc.h265enc.rc.target_bitrate; + context->desc.h265enc.rc.fill_data_enable = !(rc->rc_flags.bits.disable_bit_stuffing); + context->desc.h265enc.rc.skip_frame_enable = !(rc->rc_flags.bits.disable_frame_skip); + context->desc.h265enc.rc.max_qp = rc->max_qp; + context->desc.h265enc.rc.min_qp = rc->min_qp; + return VA_STATUS_SUCCESS; } @@ -339,6 +344,19 @@ vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext *context, VAEncMisc return VA_STATUS_SUCCESS; } +VAStatus +vlVaHandleVAEncMiscParameterTypeHRDHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc) +{ + VAEncMiscParameterHRD *ms = (VAEncMiscParameterHRD *)misc->data; + + if (ms->buffer_size) { + context->desc.h265enc.rc.vbv_buffer_size = ms->buffer_size; + context->desc.h265enc.rc.vbv_buf_lv = (ms->initial_buffer_fullness << 6 ) / ms->buffer_size; + } + + return VA_STATUS_SUCCESS; +} + void getEncParamPresetH265(vlVaContext *context) { //rate control @@ -346,6 +364,9 @@ void getEncParamPresetH265(vlVaContext *context) context->desc.h265enc.rc.vbv_buf_lv = 48; context->desc.h265enc.rc.fill_data_enable = 1; context->desc.h265enc.rc.enforce_hrd = 1; + context->desc.h265enc.rc.max_qp = 51; + context->desc.h265enc.rc.min_qp = 0; + if (context->desc.h265enc.rc.frame_rate_num == 0 || context->desc.h265enc.rc.frame_rate_den == 0) { context->desc.h265enc.rc.frame_rate_num = 30; diff --git a/src/gallium/frontends/va/va_private.h b/src/gallium/frontends/va/va_private.h index 4ec79b55dce..e5b4a310c46 100644 --- a/src/gallium/frontends/va/va_private.h +++ b/src/gallium/frontends/va/va_private.h @@ -499,6 +499,7 @@ VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateH264(vlVaContext *context, VAE VAStatus vlVaHandleVAEncMiscParameterTypeTemporalLayerH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeMaxFrameSizeH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); +VAStatus vlVaHandleVAEncMiscParameterTypeHRDH264(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf); @@ -507,4 +508,5 @@ VAStatus vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAE VAStatus vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); VAStatus vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); +VAStatus vlVaHandleVAEncMiscParameterTypeHRDHEVC(vlVaContext *context, VAEncMiscParameterBuffer *buf); #endif //VA_PRIVATE_H diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 918c9e22b7b..c6aa603c50a 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -383,8 +383,11 @@ struct pipe_h264_enc_rate_control unsigned peak_bits_picture_integer; unsigned peak_bits_picture_fraction; unsigned fill_data_enable; + unsigned skip_frame_enable; unsigned enforce_hrd; unsigned max_au_size; + unsigned max_qp; + unsigned min_qp; }; struct pipe_h264_enc_motion_estimation @@ -520,8 +523,11 @@ struct pipe_h265_enc_rate_control unsigned peak_bits_picture_integer; unsigned peak_bits_picture_fraction; unsigned fill_data_enable; + unsigned skip_frame_enable; unsigned enforce_hrd; unsigned max_au_size; + unsigned max_qp; + unsigned min_qp; }; struct pipe_h265_enc_picture_desc