Mesa (main): frontends/va: change to per-layer rate control

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 26 20:27:35 UTC 2021


Module: Mesa
Branch: main
Commit: 856e2b75291bf29ecdbce8879b3da1e8cad826c1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=856e2b75291bf29ecdbce8879b3da1e8cad826c1

Author: Thong Thai <thong.thai at amd.com>
Date:   Tue Jul 13 12:04:39 2021 -0400

frontends/va: change to per-layer rate control

Allows for each layer in a Scalable Video Coding (SVC) video to have its
own rate control setting, when encoding H.264.

Signed-off-by: Thong Thai <thong.thai at amd.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11850>

---

 src/gallium/frontends/va/context.c          |  2 +-
 src/gallium/frontends/va/picture_h264_enc.c | 91 +++++++++++++++++++----------
 2 files changed, 60 insertions(+), 33 deletions(-)

diff --git a/src/gallium/frontends/va/context.c b/src/gallium/frontends/va/context.c
index 53077ee45c7..e036c4d99bf 100644
--- a/src/gallium/frontends/va/context.c
+++ b/src/gallium/frontends/va/context.c
@@ -316,7 +316,7 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
    if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
       switch (u_reduce_video_profile(context->templat.profile)) {
       case PIPE_VIDEO_FORMAT_MPEG4_AVC:
-         context->desc.h264enc.rate_ctrl.rate_ctrl_method = config->rc;
+         context->desc.h264enc.rate_ctrl[0].rate_ctrl_method = config->rc;
          context->desc.h264enc.frame_idx = util_hash_table_create_ptr_keys();
          break;
       case PIPE_VIDEO_FORMAT_HEVC:
diff --git a/src/gallium/frontends/va/picture_h264_enc.c b/src/gallium/frontends/va/picture_h264_enc.c
index 6bcc926f27e..ba67f6eb018 100644
--- a/src/gallium/frontends/va/picture_h264_enc.c
+++ b/src/gallium/frontends/va/picture_h264_enc.c
@@ -124,8 +124,8 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con
    if (context->gop_coeff > VL_VA_ENC_GOP_COEFF)
       context->gop_coeff = VL_VA_ENC_GOP_COEFF;
    context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff;
-   context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2;
-   context->desc.h264enc.rate_ctrl.frame_rate_den = h264->num_units_in_tick;
+   context->desc.h264enc.rate_ctrl[0].frame_rate_num = h264->time_scale / 2;
+   context->desc.h264enc.rate_ctrl[0].frame_rate_den = h264->num_units_in_tick;
    context->desc.h264enc.pic_order_cnt_type = h264->seq_fields.bits.pic_order_cnt_type;
 
    if (h264->frame_cropping_flag) {
@@ -141,17 +141,32 @@ vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver *drv, vlVaContext *con
 VAStatus
 vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscParameterBuffer *misc)
 {
+   unsigned temporal_id;
    VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data;
-   if (context->desc.h264enc.rate_ctrl.rate_ctrl_method ==
-         PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT)
-      context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second;
+
+   temporal_id = context->desc.h264enc.rate_ctrl[0].rate_ctrl_method !=
+                 PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE ?
+                 rc->rc_flags.bits.temporal_id :
+                 0;
+
+   if (context->desc.h264enc.rate_ctrl[0].rate_ctrl_method ==
+       PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT)
+      context->desc.h264enc.rate_ctrl[temporal_id].target_bitrate =
+         rc->bits_per_second;
    else
-      context->desc.h264enc.rate_ctrl.target_bitrate = rc->bits_per_second * (rc->target_percentage / 100.0);
-   context->desc.h264enc.rate_ctrl.peak_bitrate = rc->bits_per_second;
-   if (context->desc.h264enc.rate_ctrl.target_bitrate < 2000000)
-      context->desc.h264enc.rate_ctrl.vbv_buffer_size = MIN2((context->desc.h264enc.rate_ctrl.target_bitrate * 2.75), 2000000);
+      context->desc.h264enc.rate_ctrl[temporal_id].target_bitrate =
+         rc->bits_per_second * (rc->target_percentage / 100.0);
+
+   if (temporal_id >= context->desc.h264enc.num_temporal_layers)
+      return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+   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 =
+         MIN2((context->desc.h264enc.rate_ctrl[0].target_bitrate * 2.75), 2000000);
    else
-      context->desc.h264enc.rate_ctrl.vbv_buffer_size = context->desc.h264enc.rate_ctrl.target_bitrate;
+      context->desc.h264enc.rate_ctrl[temporal_id].vbv_buffer_size =
+         context->desc.h264enc.rate_ctrl[0].target_bitrate;
 
    return VA_STATUS_SUCCESS;
 }
@@ -159,14 +174,26 @@ vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext *context, VAEncMiscP
 VAStatus
 vlVaHandleVAEncMiscParameterTypeFrameRateH264(vlVaContext *context, VAEncMiscParameterBuffer *misc)
 {
+   unsigned temporal_id;
    VAEncMiscParameterFrameRate *fr = (VAEncMiscParameterFrameRate *)misc->data;
+
+   temporal_id = context->desc.h264enc.rate_ctrl[0].rate_ctrl_method !=
+                 PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE ?
+                 fr->framerate_flags.bits.temporal_id :
+                 0;
+
+   if (context->desc.h264enc.num_temporal_layers > 0 &&
+       temporal_id >= context->desc.h264enc.num_temporal_layers)
+      return VA_STATUS_ERROR_INVALID_PARAMETER;
+
    if (fr->framerate & 0xffff0000) {
-      context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate       & 0xffff;
-      context->desc.h264enc.rate_ctrl.frame_rate_den = fr->framerate >> 16 & 0xffff;
+      context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_num = fr->framerate       & 0xffff;
+      context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_den = fr->framerate >> 16 & 0xffff;
    } else {
-      context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate;
-      context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
+      context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_num = fr->framerate;
+      context->desc.h264enc.rate_ctrl[temporal_id].frame_rate_den = 1;
    }
+
    return VA_STATUS_SUCCESS;
 }
 
@@ -196,25 +223,25 @@ void getEncParamPresetH264(vlVaContext *context)
    context->desc.h264enc.pic_ctrl.enc_constraint_set_flags = 0x00000040;
 
    //rate control
-   context->desc.h264enc.rate_ctrl.vbv_buffer_size = 20000000;
-   context->desc.h264enc.rate_ctrl.vbv_buf_lv = 48;
-   context->desc.h264enc.rate_ctrl.fill_data_enable = 1;
-   context->desc.h264enc.rate_ctrl.enforce_hrd = 1;
+   context->desc.h264enc.rate_ctrl[0].vbv_buffer_size = 20000000;
+   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.enable_vui = false;
-   if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0 ||
-       context->desc.h264enc.rate_ctrl.frame_rate_den == 0) {
-         context->desc.h264enc.rate_ctrl.frame_rate_num = 30;
-         context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
+   if (context->desc.h264enc.rate_ctrl[0].frame_rate_num == 0 ||
+       context->desc.h264enc.rate_ctrl[0].frame_rate_den == 0) {
+         context->desc.h264enc.rate_ctrl[0].frame_rate_num = 30;
+         context->desc.h264enc.rate_ctrl[0].frame_rate_den = 1;
    }
-   context->desc.h264enc.rate_ctrl.target_bits_picture =
-      context->desc.h264enc.rate_ctrl.target_bitrate *
-      ((float)context->desc.h264enc.rate_ctrl.frame_rate_den /
-      context->desc.h264enc.rate_ctrl.frame_rate_num);
-   context->desc.h264enc.rate_ctrl.peak_bits_picture_integer =
-      context->desc.h264enc.rate_ctrl.peak_bitrate *
-      ((float)context->desc.h264enc.rate_ctrl.frame_rate_den /
-      context->desc.h264enc.rate_ctrl.frame_rate_num);
-
-   context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0;
+   context->desc.h264enc.rate_ctrl[0].target_bits_picture =
+      context->desc.h264enc.rate_ctrl[0].target_bitrate *
+      ((float)context->desc.h264enc.rate_ctrl[0].frame_rate_den /
+      context->desc.h264enc.rate_ctrl[0].frame_rate_num);
+   context->desc.h264enc.rate_ctrl[0].peak_bits_picture_integer =
+      context->desc.h264enc.rate_ctrl[0].peak_bitrate *
+      ((float)context->desc.h264enc.rate_ctrl[0].frame_rate_den /
+      context->desc.h264enc.rate_ctrl[0].frame_rate_num);
+
+   context->desc.h264enc.rate_ctrl[0].peak_bits_picture_fraction = 0;
    context->desc.h264enc.ref_pic_mode = 0x00000201;
 }



More information about the mesa-commit mailing list