mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 04:20:08 +01:00
radeonsi/vcn: Add support for VCN5 AV1 compound
Reviewed-by: Ruijing Dong <ruijing.dong@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31520>
This commit is contained in:
parent
05f7589fec
commit
1e1f078099
6 changed files with 106 additions and 4 deletions
|
|
@ -337,6 +337,7 @@ typedef struct rvcn_enc_av1_spec_misc_s {
|
|||
uint32_t cdef_y_sec_strength[RENCODE_AV1_CDEF_MAX_NUM];
|
||||
uint32_t cdef_uv_pri_strength[RENCODE_AV1_CDEF_MAX_NUM];
|
||||
uint32_t cdef_uv_sec_strength[RENCODE_AV1_CDEF_MAX_NUM];
|
||||
uint32_t disallow_skip_mode;
|
||||
int32_t delta_q_y_dc;
|
||||
int32_t delta_q_u_dc;
|
||||
int32_t delta_q_u_ac;
|
||||
|
|
|
|||
|
|
@ -691,6 +691,8 @@ static void radeon_vcn_enc_hevc_get_param(struct radeon_encoder *enc,
|
|||
static void radeon_vcn_enc_av1_get_spec_misc_param(struct radeon_encoder *enc,
|
||||
struct pipe_av1_enc_picture_desc *pic)
|
||||
{
|
||||
struct si_screen *sscreen = (struct si_screen *)enc->screen;
|
||||
|
||||
enc->enc_pic.av1_spec_misc.cdef_mode = pic->seq.seq_bits.enable_cdef;
|
||||
enc->enc_pic.av1_spec_misc.disable_cdf_update = pic->disable_cdf_update;
|
||||
enc->enc_pic.av1_spec_misc.disable_frame_end_update_cdf = pic->disable_frame_end_update_cdf;
|
||||
|
|
@ -724,6 +726,15 @@ static void radeon_vcn_enc_av1_get_spec_misc_param(struct radeon_encoder *enc,
|
|||
enc->enc_pic.av1_spec_misc.mv_precision = RENCODE_AV1_MV_PRECISION_FORCE_INTEGER_MV;
|
||||
else
|
||||
enc->enc_pic.av1_spec_misc.mv_precision = RENCODE_AV1_MV_PRECISION_ALLOW_HIGH_PRECISION;
|
||||
|
||||
if (sscreen->info.vcn_ip_version >= VCN_5_0_0) {
|
||||
enc->enc_pic.av1.skip_mode_allowed = radeon_enc_av1_skip_mode_allowed(enc);
|
||||
if (enc->enc_pic.av1.compound) {
|
||||
enc->need_spec_misc =
|
||||
!enc->enc_pic.av1.skip_mode_allowed != enc->enc_pic.av1_spec_misc.disallow_skip_mode;
|
||||
enc->enc_pic.av1_spec_misc.disallow_skip_mode = !enc->enc_pic.av1.skip_mode_allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc,
|
||||
|
|
@ -759,12 +770,15 @@ static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc,
|
|||
enc->enc_pic.rc_per_pic.max_qp_app_obs = pic->rc[0].max_qp ? pic->rc[0].max_qp : 255;
|
||||
enc->enc_pic.rc_per_pic.qp_i = pic->rc[0].qp;
|
||||
enc->enc_pic.rc_per_pic.qp_p = pic->rc[0].qp_inter;
|
||||
enc->enc_pic.rc_per_pic.qp_b = pic->rc[0].qp_inter;
|
||||
min_qp = pic->rc[0].min_qp ? pic->rc[0].min_qp : 1;
|
||||
enc->enc_pic.rc_per_pic.min_qp_i = min_qp;
|
||||
enc->enc_pic.rc_per_pic.min_qp_p = min_qp;
|
||||
enc->enc_pic.rc_per_pic.min_qp_b = min_qp;
|
||||
max_qp = pic->rc[0].max_qp ? pic->rc[0].max_qp : 255;
|
||||
enc->enc_pic.rc_per_pic.max_qp_i = max_qp;
|
||||
enc->enc_pic.rc_per_pic.max_qp_p = max_qp;
|
||||
enc->enc_pic.rc_per_pic.max_qp_b = max_qp;
|
||||
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;
|
||||
|
|
@ -793,6 +807,7 @@ static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc,
|
|||
enc->enc_pic.rc_per_pic.max_au_size_obs = pic->rc[0].max_au_size;
|
||||
enc->enc_pic.rc_per_pic.max_au_size_i = pic->rc[0].max_au_size;
|
||||
enc->enc_pic.rc_per_pic.max_au_size_p = pic->rc[0].max_au_size;
|
||||
enc->enc_pic.rc_per_pic.max_au_size_b = pic->rc[0].max_au_size;
|
||||
}
|
||||
|
||||
static void radeon_vcn_enc_av1_get_tile_config(struct radeon_encoder *enc,
|
||||
|
|
@ -825,6 +840,7 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
|
|||
{
|
||||
struct si_screen *sscreen = (struct si_screen *)enc->screen;
|
||||
struct radeon_enc_pic *enc_pic = &enc->enc_pic;
|
||||
|
||||
enc_pic->av1.desc = pic;
|
||||
enc_pic->frame_type = pic->frame_type;
|
||||
enc_pic->bit_depth_luma_minus8 = enc_pic->bit_depth_chroma_minus8 =
|
||||
|
|
@ -855,6 +871,15 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
|
|||
enc_pic->av1_enc_params.lsm_reference_frame_index[0] =
|
||||
pic->ref_list0[0] == PIPE_H2645_LIST_REF_INVALID_ENTRY ? 0xffffffff : pic->ref_list0[0];
|
||||
enc_pic->av1_enc_params.lsm_reference_frame_index[1] = 0xffffffff;
|
||||
enc_pic->av1.compound = false;
|
||||
|
||||
if (pic->ref_list1[0] != PIPE_H2645_LIST_REF_INVALID_ENTRY) {
|
||||
enc_pic->av1.compound = true; /* BIDIR_COMP */
|
||||
enc_pic->av1_enc_params.lsm_reference_frame_index[1] = pic->ref_list1[0];
|
||||
} else if (pic->ref_list0[1] != PIPE_H2645_LIST_REF_INVALID_ENTRY) {
|
||||
enc_pic->av1.compound = true; /* UNIDIR_COMP */
|
||||
enc_pic->av1_enc_params.lsm_reference_frame_index[1] = pic->ref_list0[1];
|
||||
}
|
||||
}
|
||||
|
||||
radeon_vcn_enc_av1_get_spec_misc_param(enc, pic);
|
||||
|
|
@ -1302,7 +1327,7 @@ static void radeon_enc_begin_frame(struct pipe_video_codec *encoder,
|
|||
enc->need_rc_per_pic =
|
||||
(enc->enc_pic.rc_per_pic.qp_i != pic->rc[0].qp) ||
|
||||
(enc->enc_pic.rc_per_pic.qp_p != pic->rc[0].qp_inter) ||
|
||||
(enc->enc_pic.rc_per_pic.qp_p != pic->rc[0].qp_inter) ||
|
||||
(enc->enc_pic.rc_per_pic.qp_b != pic->rc[0].qp_inter) ||
|
||||
(enc->enc_pic.rc_per_pic.max_au_size_i != pic->rc[0].max_au_size) ||
|
||||
(enc->enc_pic.rc_per_pic.qvbr_quality_level != pic->rc[0].vbr_quality_factor);
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ struct radeon_enc_pic {
|
|||
struct pipe_av1_enc_picture_desc *desc;
|
||||
uint32_t coded_width;
|
||||
uint32_t coded_height;
|
||||
bool compound;
|
||||
bool skip_mode_allowed;
|
||||
} av1;
|
||||
};
|
||||
|
||||
|
|
@ -234,6 +236,7 @@ struct radeon_encoder {
|
|||
bool need_feedback;
|
||||
bool need_rate_control;
|
||||
bool need_rc_per_pic;
|
||||
bool need_spec_misc;
|
||||
unsigned dpb_size;
|
||||
unsigned dpb_slots;
|
||||
unsigned roi_size;
|
||||
|
|
@ -362,4 +365,7 @@ bool radeon_enc_is_av1_uniform_tile (uint32_t nb_sb, uint32_t nb_tiles,
|
|||
|
||||
void radeon_enc_av1_tile_layout (uint32_t nb_sb, uint32_t nb_tiles, uint32_t min_nb_sb,
|
||||
struct tile_1d_layout *p);
|
||||
|
||||
bool radeon_enc_av1_skip_mode_allowed(struct radeon_encoder *enc);
|
||||
|
||||
#endif // _RADEON_VCN_ENC_H
|
||||
|
|
|
|||
|
|
@ -150,6 +150,9 @@ static void encode(struct radeon_encoder *enc)
|
|||
enc->total_task_size = 0;
|
||||
enc->task_info(enc, enc->need_feedback);
|
||||
|
||||
if (enc->need_spec_misc)
|
||||
enc->spec_misc(enc);
|
||||
|
||||
if (enc->need_rate_control || enc->need_rc_per_pic) {
|
||||
i = 0;
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,10 @@ static void radeon_enc_encode_params(struct radeon_encoder *enc)
|
|||
break;
|
||||
case PIPE_AV1_ENC_FRAME_TYPE_INTER:
|
||||
case PIPE_AV1_ENC_FRAME_TYPE_SWITCH:
|
||||
enc->enc_pic.enc_params.pic_type = RENCODE_PICTURE_TYPE_P;
|
||||
if (enc->enc_pic.av1.compound)
|
||||
enc->enc_pic.enc_params.pic_type = RENCODE_PICTURE_TYPE_B;
|
||||
else
|
||||
enc->enc_pic.enc_params.pic_type = RENCODE_PICTURE_TYPE_P;
|
||||
break;
|
||||
default:
|
||||
assert(0); /* never come to this condition */
|
||||
|
|
@ -187,7 +190,7 @@ static void radeon_enc_spec_misc_av1(struct radeon_encoder *enc)
|
|||
RADEON_ENC_CS(0);
|
||||
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.disable_cdf_update);
|
||||
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.disable_frame_end_update_cdf);
|
||||
RADEON_ENC_CS(0);
|
||||
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.disallow_skip_mode);
|
||||
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.delta_q_y_dc);
|
||||
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.delta_q_u_dc);
|
||||
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.delta_q_u_ac);
|
||||
|
|
@ -721,6 +724,62 @@ static void radeon_enc_av1_quantization_params(struct radeon_encoder *enc)
|
|||
radeon_enc_code_fixed_bits(enc, 0, 1);
|
||||
}
|
||||
|
||||
static int32_t radeon_enc_av1_get_relative_dist(struct radeon_encoder *enc, uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t diff = a - b;
|
||||
uint32_t m = 1 << (enc->enc_pic.av1.desc->seq.order_hint_bits - 1);
|
||||
diff = (diff & (m - 1)) - (diff & m);
|
||||
return diff;
|
||||
}
|
||||
|
||||
bool radeon_enc_av1_skip_mode_allowed(struct radeon_encoder *enc)
|
||||
{
|
||||
if (enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_KEY ||
|
||||
enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_INTRA_ONLY ||
|
||||
!enc->enc_pic.av1.compound ||
|
||||
!enc->enc_pic.av1.desc->seq.seq_bits.enable_order_hint)
|
||||
return false;
|
||||
|
||||
int32_t forward_idx = -1, backward_idx = -1;
|
||||
uint32_t forward_hint, backward_hint;
|
||||
|
||||
for (uint32_t i = 0; i < RENCODE_AV1_REFS_PER_FRAME; i++) {
|
||||
uint32_t ref_hint = enc->enc_pic.av1.desc->dpb[enc->enc_pic.av1.desc->dpb_ref_frame_idx[i]].order_hint;
|
||||
int32_t dist = radeon_enc_av1_get_relative_dist(enc, ref_hint, enc->enc_pic.av1.desc->order_hint);
|
||||
if (dist < 0) {
|
||||
if (forward_idx < 0 || radeon_enc_av1_get_relative_dist(enc, ref_hint, forward_hint) > 0) {
|
||||
forward_idx = i;
|
||||
forward_hint = ref_hint;
|
||||
}
|
||||
} else if (dist > 0) {
|
||||
if (backward_idx < 0 || radeon_enc_av1_get_relative_dist(enc, ref_hint, backward_hint) < 0) {
|
||||
backward_idx = i;
|
||||
backward_hint = ref_hint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (forward_idx < 0)
|
||||
return false;
|
||||
else if (backward_idx >= 0)
|
||||
return true;
|
||||
|
||||
int32_t second_forward_idx = -1;
|
||||
uint32_t second_forward_hint;
|
||||
|
||||
for (uint32_t i = 0; i < RENCODE_AV1_REFS_PER_FRAME; i++) {
|
||||
uint32_t ref_hint = enc->enc_pic.av1.desc->dpb[enc->enc_pic.av1.desc->dpb_ref_frame_idx[i]].order_hint;
|
||||
if (radeon_enc_av1_get_relative_dist(enc, ref_hint, forward_hint) < 0) {
|
||||
if (second_forward_idx < 0 || radeon_enc_av1_get_relative_dist(enc, ref_hint, second_forward_hint) > 0) {
|
||||
second_forward_idx = i;
|
||||
second_forward_hint = ref_hint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return second_forward_idx >= 0;
|
||||
}
|
||||
|
||||
static void radeon_enc_av1_frame_header(struct radeon_encoder *enc, bool frame_header)
|
||||
{
|
||||
bool frame_is_intra = enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_KEY ||
|
||||
|
|
@ -750,7 +809,11 @@ static void radeon_enc_av1_frame_header(struct radeon_encoder *enc, bool frame_h
|
|||
|
||||
if (!frame_is_intra)
|
||||
/* reference_select */
|
||||
radeon_enc_code_fixed_bits(enc, 0, 1);
|
||||
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1.compound, 1);
|
||||
|
||||
if (enc->enc_pic.av1.skip_mode_allowed)
|
||||
/* skip_mode_present */
|
||||
radeon_enc_code_fixed_bits(enc, 1, 1);
|
||||
|
||||
/* reduced_tx_set */
|
||||
radeon_enc_code_fixed_bits(enc, 0, 1);
|
||||
|
|
|
|||
|
|
@ -842,6 +842,10 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
|
|||
if (sscreen->info.vcn_ip_version >= VCN_3_0_0) {
|
||||
int refPicList0 = 1;
|
||||
int refPicList1 = codec == PIPE_VIDEO_FORMAT_MPEG4_AVC ? 1 : 0;
|
||||
if (sscreen->info.vcn_ip_version >= VCN_5_0_0 && codec == PIPE_VIDEO_FORMAT_AV1) {
|
||||
refPicList0 = 2;
|
||||
refPicList1 = 1;
|
||||
}
|
||||
return refPicList0 | (refPicList1 << 16);
|
||||
} else
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue