radeonsi/vcn: Check and override primary_ref_frame

The primary_ref_frame is used to load CDF data and has to match between
VCN and the header. Unless the default CDF tables are used, VCN
currently always assumes the CDF data will be loaded from
reference_frame_index (for VCN4) or lsm_reference_frame_index[0] (for
VCN5). This may cause conflict with the application provided
primary_ref_frame.

Check to make sure the primary_ref_frame is the same frame as the used
reference, and override it if necessary.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38030>
This commit is contained in:
Benjamin Cheng 2025-10-23 10:48:28 -04:00 committed by Marge Bot
parent e8c0fdbc45
commit c7883e3a71
3 changed files with 14 additions and 1 deletions

View file

@ -1035,6 +1035,17 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
0xffffffff : pic->dpb_ref_frame_idx[pic->ref_list0[0]];
enc_pic->enc_params.reconstructed_picture_index = pic->dpb_curr_pic;
/* primary_ref_frame can be NONE (7), otherwise it must have the same DPB
* index as the first ref pic. */
if (pic->primary_ref_frame == 7 ||
pic->ref_list0[0] == PIPE_H2645_LIST_REF_INVALID_ENTRY)
enc_pic->av1.primary_ref_frame = 7;
else if (pic->dpb_ref_frame_idx[pic->primary_ref_frame] ==
pic->dpb_ref_frame_idx[pic->ref_list0[0]])
enc_pic->av1.primary_ref_frame = pic->primary_ref_frame;
else
enc_pic->av1.primary_ref_frame = pic->ref_list0[0];
if (sscreen->info.vcn_ip_version >= VCN_5_0_0) {
bool allow_unidir =
pic->rc[0].rate_ctrl_method == PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE;

View file

@ -86,6 +86,7 @@ struct radeon_enc_pic {
struct pipe_av1_enc_picture_desc *desc;
uint32_t coded_width;
uint32_t coded_height;
uint32_t primary_ref_frame;
bool compound;
bool skip_mode_allowed;
} av1;

View file

@ -143,6 +143,7 @@ static void radeon_enc_cdf_default_table(struct radeon_encoder *enc)
bool use_cdf_default = 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.frame_type == PIPE_AV1_ENC_FRAME_TYPE_SWITCH ||
enc->enc_pic.av1.primary_ref_frame == 7 /* PRIMARY_REF_NONE */ ||
(enc->enc_pic.enable_error_resilient_mode);
enc->enc_pic.av1_cdf_default_table.use_cdf_default = use_cdf_default ? 1 : 0;
@ -447,7 +448,7 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, struct radeo
if (!frame_is_intra && !error_resilient_mode)
/* primary_ref_frame */
radeon_bs_code_fixed_bits(bs, av1->primary_ref_frame, 3);
radeon_bs_code_fixed_bits(bs, enc->enc_pic.av1.primary_ref_frame, 3);
if ((enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_SWITCH) &&
(enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_KEY || !av1->show_frame))