frontends/va: add HRD, filler data enable and etc
authorRuijing Dong <ruijing.dong@amd.com>
Sat, 10 Sep 2022 20:52:12 +0000 (16:52 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 14 Sep 2022 00:16:20 +0000 (00:16 +0000)
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 <ruijing.dong@amd.com>
Reviewed-By: Sil Vilerino <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18534>

src/gallium/drivers/radeonsi/radeon_vcn_enc.c
src/gallium/frontends/va/picture.c
src/gallium/frontends/va/picture_h264_enc.c
src/gallium/frontends/va/picture_hevc_enc.c
src/gallium/frontends/va/va_private.h
src/gallium/include/pipe/p_video_state.h

index 6f1ce27..208dcc7 100644 (file)
@@ -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:
index a8e86b2..d0a98fd 100644 (file)
@@ -544,6 +544,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)
 {
    VAStatus vaStatus = VA_STATUS_SUCCESS;
@@ -571,6 +592,10 @@ handleVAEncMiscParameterBufferType(vlVaContext *context, vlVaBuffer *buf)
       vaStatus = handleVAEncMiscParameterTypeMaxFrameSize(context, misc);
       break;
 
+   case VAEncMiscParameterTypeHRD:
+      vaStatus = handleVAEncMiscParameterTypeHRD(context, misc);
+      break;
+
    default:
       break;
    }
index b9848b9..9fe12d2 100644 (file)
@@ -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) {
index 910ecf6..72a42c9 100644 (file)
@@ -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;
index 4ec79b5..e5b4a31 100644 (file)
@@ -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
index 918c9e2..c6aa603 100644 (file)
@@ -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