radeonsi/vcn: Add support for QVBR rate control mode

This rate control mode needs pre-encode enabled and currently is
supported for VCN3 and VCN4.
AV1 needs quality level scaled down from 255 to 51 range.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4024
Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30221>
This commit is contained in:
David Rosca
2024-07-17 08:58:01 +02:00
committed by Marge Bot
parent ae293d176b
commit 8b1a889e45
5 changed files with 58 additions and 4 deletions
+2 -1
View File
@@ -72,6 +72,7 @@
#define RENCODE_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 0x00000001
#define RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 0x00000002
#define RENCODE_RATE_CONTROL_METHOD_CBR 0x00000003
#define RENCODE_RATE_CONTROL_METHOD_QUALITY_VBR 0x00000004
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_AUD 0x00000000
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_VPS 0x00000001
@@ -391,7 +392,7 @@ typedef struct rvcn_enc_rate_ctl_per_picture_s {
uint32_t enabled_filler_data;
uint32_t skip_frame_enable;
uint32_t enforce_hrd;
uint32_t reserved_0xff;
uint32_t qvbr_quality_level;
} rvcn_enc_rate_ctl_per_picture_t;
typedef struct rvcn_enc_quality_params_s {
@@ -295,6 +295,7 @@ static void radeon_vcn_enc_h264_get_rc_param(struct radeon_encoder *enc,
enc->enc_pic.rc_per_pic.enabled_filler_data = 0;
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;
enc->enc_pic.rc_per_pic.qvbr_quality_level = pic->rate_ctrl[0].vbr_quality_factor;
switch (pic->rate_ctrl[0].rate_ctrl_method) {
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE:
@@ -310,6 +311,12 @@ static void radeon_vcn_enc_h264_get_rc_param(struct radeon_encoder *enc,
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_QUALITY_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_QUALITY_VBR;
/* QVBR requires pre-encode enabled. */
enc->enc_pic.quality_modes.pre_encode_mode = RENCODE_PREENCODE_MODE_4X;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
}
@@ -564,6 +571,7 @@ static void radeon_vcn_enc_hevc_get_rc_param(struct radeon_encoder *enc,
enc->enc_pic.rc_per_pic.enabled_filler_data = 0;
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;
enc->enc_pic.rc_per_pic.qvbr_quality_level = pic->rc.vbr_quality_factor;
switch (pic->rc.rate_ctrl_method) {
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
@@ -578,6 +586,12 @@ static void radeon_vcn_enc_hevc_get_rc_param(struct radeon_encoder *enc,
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_QUALITY_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_QUALITY_VBR;
/* QVBR requires pre-encode enabled. */
enc->enc_pic.quality_modes.pre_encode_mode = RENCODE_PREENCODE_MODE_4X;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
}
@@ -813,6 +827,7 @@ static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc,
enc->enc_pic.rc_per_pic.enabled_filler_data = 0;
enc->enc_pic.rc_per_pic.skip_frame_enable = pic->rc[0].skip_frame_enable;
enc->enc_pic.rc_per_pic.enforce_hrd = pic->rc[0].enforce_hrd;
enc->enc_pic.rc_per_pic.qvbr_quality_level = (pic->rc[0].vbr_quality_factor + 2) / 5;
switch (pic->rc[0].rate_ctrl_method) {
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
@@ -827,6 +842,12 @@ static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc,
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_QUALITY_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_QUALITY_VBR;
/* QVBR requires pre-encode enabled. */
enc->enc_pic.quality_modes.pre_encode_mode = RENCODE_PREENCODE_MODE_4X;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
}
@@ -1213,8 +1213,6 @@ static void radeon_enc_rc_per_pic(struct radeon_encoder *enc)
static void radeon_enc_rc_per_pic_ex(struct radeon_encoder *enc)
{
enc->enc_pic.rc_per_pic.reserved_0xff = 0xFFFFFFFF;
RADEON_ENC_BEGIN(enc->cmd.rc_per_pic);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_i);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_p);
@@ -1231,7 +1229,6 @@ static void radeon_enc_rc_per_pic_ex(struct radeon_encoder *enc)
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enabled_filler_data);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.skip_frame_enable);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enforce_hrd);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.reserved_0xff);
RADEON_ENC_END();
}
@@ -117,6 +117,28 @@ static void radeon_enc_quality_params(struct radeon_encoder *enc)
RADEON_ENC_END();
}
static void radeon_enc_rc_per_pic_ex(struct radeon_encoder *enc)
{
RADEON_ENC_BEGIN(enc->cmd.rc_per_pic);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_i);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_p);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qp_b);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_i);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_i);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_p);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_p);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.min_qp_b);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_qp_b);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size_i);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size_p);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.max_au_size_b);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enabled_filler_data);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.skip_frame_enable);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.enforce_hrd);
RADEON_ENC_CS(enc->enc_pic.rc_per_pic.qvbr_quality_level);
RADEON_ENC_END();
}
static void radeon_enc_nalu_sps(struct radeon_encoder *enc)
{
struct radeon_enc_pic *pic = &enc->enc_pic;
@@ -540,6 +562,8 @@ void radeon_enc_3_0_init(struct radeon_encoder *enc)
enc->session_init = radeon_enc_session_init;
enc->ctx = radeon_enc_ctx;
enc->quality_params = radeon_enc_quality_params;
if (enc->enc_pic.use_rc_per_pic_ex)
enc->rc_per_pic = radeon_enc_rc_per_pic_ex;
if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
enc->spec_misc = radeon_enc_spec_misc;
+11
View File
@@ -876,6 +876,17 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
else
return 0;
case PIPE_VIDEO_CAP_ENC_RATE_CONTROL_QVBR:
if (sscreen->info.vcn_ip_version >= VCN_3_0_0 &&
sscreen->info.vcn_ip_version < VCN_4_0_0)
return sscreen->info.vcn_enc_minor_version >= 30;
if (sscreen->info.vcn_ip_version >= VCN_4_0_0 &&
sscreen->info.vcn_ip_version < VCN_5_0_0)
return sscreen->info.vcn_enc_minor_version >= 15;
return 0;
default:
return 0;
}