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