radeonsi/vcn: Support raw packed headers for AV1

Same as H264/HEVC, we still write sequence header ourselves
and slice header is sent to FW, everything else gets copied
directly to output bitstream buffer.
Fixes generating correct output with libva-utils/av1encode.
Also fixes temporal delimiter insertion, it's no longer forced
on every frame, but instead it lets application handle it.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31520>
This commit is contained in:
David Rosca 2024-10-04 08:39:59 +02:00 committed by Marge Bot
parent 46d8e57f16
commit 8b2f0fb574
5 changed files with 138 additions and 403 deletions

View file

@ -591,33 +591,6 @@ typedef struct rvcn_enc_metadata_buffer_s {
uint32_t two_pass_search_center_map_offset;
} rvcn_enc_metadata_buffer_t;
typedef struct rvcn_enc_sei_hdr_cll_s {
uint16_t max_cll;
uint16_t max_fall;
} rvcn_enc_sei_hdr_cll_t;
typedef struct rvcn_enc_sei_hdr_mdcv_s {
uint16_t primary_chromaticity_x[3];
uint16_t primary_chromaticity_y[3];
uint16_t white_point_chromaticity_x;
uint16_t white_point_chromaticity_y;
uint32_t luminance_max;
uint32_t luminance_min;
} rvcn_enc_sei_hdr_mdcv_t;
/* shared sei structure */
typedef struct rvcn_enc_seidata_s {
union {
struct {
uint32_t hdr_cll:1;
uint32_t hdr_mdcv:1;
};
uint32_t value;
} flags;
rvcn_enc_sei_hdr_cll_t hdr_cll;
rvcn_enc_sei_hdr_mdcv_t hdr_mdcv;
} rvcn_enc_seidata_t;
typedef struct rvcn_enc_video_bitstream_buffer_s {
uint32_t mode;
uint32_t video_bitstream_buffer_address_hi;
@ -732,46 +705,6 @@ typedef struct rvcn_enc_output_format_s
uint32_t output_color_bit_depth;
} rvcn_enc_output_format_t;
typedef struct rvcn_enc_av1_timing_info_s
{
uint32_t num_units_in_display_tick;
uint32_t time_scale;
uint32_t num_tick_per_picture_minus1;
}rvcn_enc_av1_timing_info_t;
typedef struct rvcn_enc_av1_color_description_s
{
uint32_t color_primaries;
uint32_t transfer_characteristics;
uint32_t maxtrix_coefficients;
uint32_t color_range;
uint32_t chroma_sample_position;
}rvcn_enc_av1_color_description_t;
#define AV1_ENC_FRAME_TYPE_KEY 0x00
#define AV1_ENC_FRAME_TYPE_INTER 0x01
#define AV1_ENC_FRAME_TYPE_INTRA_ONLY 0x02
#define AV1_ENC_FRAME_TYPE_SWITCH 0x03
#define AV1_ENC_FRAME_TYPE_SHOW_EXISTING 0x04
typedef struct rvcn_enc_av1_ref_frame_s
{
bool in_use;
bool is_ltr;
uint32_t frame_id;
uint32_t temporal_id;
uint32_t slot_id;
uint32_t frame_type;
uint32_t ltr_seq;
void *frame_signature;
} rvcn_enc_av1_ref_frame_t;
typedef struct rvcn_enc_av1_recon_slot_s
{
bool in_use;
bool is_orphaned;
} rvcn_enc_av1_recon_slot_t;
#define RENCODE_QP_MAP_TYPE_NONE 0
#define RENCODE_QP_MAP_TYPE_DELTA 1
#define RENCODE_QP_MAP_TYPE_MAP_PA 4

View file

@ -105,7 +105,6 @@ static void radeon_vcn_enc_get_intra_refresh_param(struct radeon_encoder *enc,
if (enc->enc_pic.spec_misc.b_picture_enabled || enc->enc_pic.num_temporal_layers > 1) {
enc->enc_pic.intra_refresh.region_size = 0;
enc->enc_pic.intra_refresh.offset = 0;
enc->enc_pic.need_sequence_header = 0;
return;
}
@ -136,11 +135,9 @@ static void radeon_vcn_enc_get_intra_refresh_param(struct radeon_encoder *enc,
intra_refresh->region_size + 1 :
intra_refresh->region_size;
enc->enc_pic.intra_refresh.offset = intra_refresh->offset;
enc->enc_pic.need_sequence_header = !!(intra_refresh->need_sequence_header);
} else {
enc->enc_pic.intra_refresh.region_size = 0;
enc->enc_pic.intra_refresh.offset = 0;
enc->enc_pic.need_sequence_header = 0;
}
}
@ -729,32 +726,6 @@ 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_ALLOW_HIGH_PRECISION;
}
static void radeon_vcn_enc_av1_timing_info(struct radeon_encoder *enc,
struct pipe_av1_enc_picture_desc *pic)
{
if (pic->seq.seq_bits.timing_info_present_flag)
{
enc->enc_pic.av1_timing_info.num_units_in_display_tick =
pic->seq.num_units_in_display_tick;
enc->enc_pic.av1_timing_info.time_scale = pic->seq.time_scale;
enc->enc_pic.av1_timing_info.num_tick_per_picture_minus1 =
pic->seq.num_tick_per_picture_minus1;
}
}
static void radeon_vcn_enc_av1_color_description(struct radeon_encoder *enc,
struct pipe_av1_enc_picture_desc *pic)
{
if (pic->seq.seq_bits.color_description_present_flag)
{
enc->enc_pic.av1_color_description.color_primaries = pic->seq.color_config.color_primaries;
enc->enc_pic.av1_color_description.transfer_characteristics = pic->seq.color_config.transfer_characteristics;
enc->enc_pic.av1_color_description.maxtrix_coefficients = pic->seq.color_config.matrix_coefficients;
}
enc->enc_pic.av1_color_description.color_range = pic->seq.color_config.color_range;
enc->enc_pic.av1_color_description.chroma_sample_position = pic->seq.color_config.chroma_sample_position;
}
static void radeon_vcn_enc_av1_get_rc_param(struct radeon_encoder *enc,
struct pipe_av1_enc_picture_desc *pic)
{
@ -849,43 +820,6 @@ static void radeon_vcn_enc_av1_get_tile_config(struct radeon_encoder *enc,
enc->enc_pic.av1_tile_config.context_update_tile_id = pic->context_update_tile_id;
}
static void radeon_vcn_enc_av1_get_meta_param(struct radeon_encoder *enc,
struct pipe_av1_enc_picture_desc *pic)
{
memset (&enc->enc_pic.enc_sei, 0, sizeof(rvcn_enc_seidata_t));
if (!pic->metadata_flags.value) {
enc->enc_pic.enc_sei.flags.value = 0;
return;
}
if (pic->metadata_flags.hdr_cll) {
enc->enc_pic.enc_sei.flags.hdr_cll = 1;
enc->enc_pic.enc_sei.hdr_cll = (rvcn_enc_sei_hdr_cll_t) {
.max_cll = pic->metadata_hdr_cll.max_cll,
.max_fall = pic->metadata_hdr_cll.max_fall
};
}
if (pic->metadata_flags.hdr_mdcv) {
enc->enc_pic.enc_sei.flags.hdr_mdcv = 1;
for (int32_t i = 0; i < 3; i++) {
enc->enc_pic.enc_sei.hdr_mdcv.primary_chromaticity_x[i]
= pic->metadata_hdr_mdcv.primary_chromaticity_x[i];
enc->enc_pic.enc_sei.hdr_mdcv.primary_chromaticity_y[i]
= pic->metadata_hdr_mdcv.primary_chromaticity_y[i];
}
enc->enc_pic.enc_sei.hdr_mdcv.white_point_chromaticity_x =
pic->metadata_hdr_mdcv.white_point_chromaticity_x;
enc->enc_pic.enc_sei.hdr_mdcv.white_point_chromaticity_y =
pic->metadata_hdr_mdcv.white_point_chromaticity_y;
enc->enc_pic.enc_sei.hdr_mdcv.luminance_max =
pic->metadata_hdr_mdcv.luminance_max;
enc->enc_pic.enc_sei.hdr_mdcv.luminance_min =
pic->metadata_hdr_mdcv.luminance_min;
}
}
static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
struct pipe_av1_enc_picture_desc *pic)
{
@ -897,9 +831,13 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
pic->seq.bit_depth_minus8;
enc_pic->pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples;
enc_pic->pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples;
enc_pic->general_profile_idc = pic->seq.profile;
enc_pic->general_level_idc = pic->seq.level;
enc_pic->general_tier_flag = pic->seq.tier;
enc_pic->enable_render_size = pic->enable_render_size;
enc_pic->enable_error_resilient_mode = pic->error_resilient_mode;
enc_pic->force_integer_mv = pic->force_integer_mv;
enc_pic->disable_screen_content_tools = !pic->allow_screen_content_tools;
enc_pic->is_obu_frame = pic->enable_frame_obu;
enc_pic->render_width = pic->render_width;
enc_pic->render_height = pic->render_height;
enc_pic->num_temporal_layers =
pic->seq.num_temporal_layers <= RENCODE_MAX_NUM_TEMPORAL_LAYERS ?
@ -919,24 +857,7 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
enc_pic->av1_enc_params.lsm_reference_frame_index[1] = 0xffffffff;
}
enc_pic->frame_id_numbers_present = pic->seq.seq_bits.frame_id_number_present_flag;
enc_pic->enable_error_resilient_mode = pic->error_resilient_mode;
enc_pic->force_integer_mv = pic->force_integer_mv;
enc_pic->enable_order_hint = pic->seq.seq_bits.enable_order_hint;
enc_pic->order_hint_bits = pic->seq.order_hint_bits;
enc_pic->enable_render_size = pic->enable_render_size;
enc_pic->render_width = pic->render_width;
enc_pic->render_height = pic->render_height;
enc_pic->enable_color_description = pic->seq.seq_bits.color_description_present_flag;
enc_pic->timing_info_present = pic->seq.seq_bits.timing_info_present_flag;
enc_pic->timing_info_equal_picture_interval = pic->seq.seq_bits.equal_picture_interval;
enc_pic->disable_screen_content_tools = !pic->allow_screen_content_tools;
enc_pic->is_obu_frame = pic->enable_frame_obu;
enc_pic->need_av1_seq = (pic->frame_type == PIPE_AV1_ENC_FRAME_TYPE_KEY);
radeon_vcn_enc_av1_get_spec_misc_param(enc, pic);
radeon_vcn_enc_av1_timing_info(enc, pic);
radeon_vcn_enc_av1_color_description(enc, pic);
radeon_vcn_enc_av1_get_rc_param(enc, pic);
radeon_vcn_enc_av1_get_tile_config(enc, pic);
radeon_vcn_enc_get_input_format_param(enc, &pic->base);
@ -947,7 +868,6 @@ static void radeon_vcn_enc_av1_get_param(struct radeon_encoder *enc,
&pic->intra_refresh);
radeon_vcn_enc_get_roi_param(enc, &pic->roi);
radeon_vcn_enc_get_latency_param(enc);
radeon_vcn_enc_av1_get_meta_param(enc, pic);
radeon_vcn_enc_quality_modes(enc, &pic->quality_modes);
}
@ -1524,10 +1444,25 @@ static uint32_t radeon_vcn_enc_encode_hevc_header(struct radeon_encoder *enc,
}
}
static uint32_t radeon_vcn_enc_encode_av1_header(struct radeon_encoder *enc,
struct pipe_enc_raw_header *header,
uint8_t *out)
{
switch (header->type) {
case 1: /* SEQUENCE_HEADER */
return radeon_enc_write_sequence_header(enc, header->buffer, out);
default:
assert(header->buffer);
memcpy(out, header->buffer, header->size);
return header->size;
}
}
static void *radeon_vcn_enc_encode_headers(struct radeon_encoder *enc)
{
const bool is_h264 = u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC;
const bool is_hevc = u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC;
const bool is_av1 = u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_AV1;
struct util_dynarray *headers;
unsigned num_slices = 0, num_headers = 0;
@ -1535,6 +1470,8 @@ static void *radeon_vcn_enc_encode_headers(struct radeon_encoder *enc)
headers = &enc->enc_pic.h264.desc->raw_headers;
else if (is_hevc)
headers = &enc->enc_pic.hevc.desc->raw_headers;
else if (is_av1)
headers = &enc->enc_pic.av1.desc->raw_headers;
else
return NULL;
@ -1577,6 +1514,8 @@ static void *radeon_vcn_enc_encode_headers(struct radeon_encoder *enc)
size = radeon_vcn_enc_encode_h264_header(enc, header, ptr + offset);
else if (is_hevc)
size = radeon_vcn_enc_encode_hevc_header(enc, header, ptr + offset);
else if (is_av1)
size = radeon_vcn_enc_encode_av1_header(enc, header, ptr + offset);
data->segments[data->num_segments].size = size;
data->segments[data->num_segments].offset = offset;
offset += size;

View file

@ -79,9 +79,6 @@ struct radeon_enc_pic {
unsigned crop_right;
unsigned crop_top;
unsigned crop_bottom;
unsigned general_tier_flag;
unsigned general_profile_idc;
unsigned general_level_idc;
unsigned pic_width_in_luma_samples;
unsigned pic_height_in_luma_samples;
unsigned bit_depth_luma_minus8;
@ -92,37 +89,24 @@ struct radeon_enc_pic {
rvcn_enc_quality_modes_t quality_modes;
bool not_referenced;
bool need_sequence_header;
bool use_rc_per_pic_ex;
bool av1_tile_splitting_legacy_flag;
struct {
struct {
struct {
uint32_t enable_tile_obu:1;
uint32_t enable_render_size:1;
uint32_t enable_error_resilient_mode:1;
uint32_t enable_order_hint:1;
uint32_t enable_color_description:1;
uint32_t timing_info_present:1;
uint32_t timing_info_equal_picture_interval:1;
uint32_t frame_id_numbers_present:1;
uint32_t force_integer_mv:1;
uint32_t disable_screen_content_tools:1;
uint32_t is_obu_frame:1;
uint32_t stream_obu_frame:1; /* all frames have the same number of tiles */
uint32_t need_av1_seq:1;
};
uint32_t render_width;
uint32_t render_height;
uint32_t order_hint;
uint32_t order_hint_bits;
uint32_t *copy_start;
};
rvcn_enc_av1_spec_misc_t av1_spec_misc;
rvcn_enc_av1_cdf_default_table_t av1_cdf_default_table;
rvcn_enc_av1_timing_info_t av1_timing_info;
rvcn_enc_av1_color_description_t av1_color_description;
};
rvcn_enc_session_info_t session_info;
@ -155,7 +139,6 @@ struct radeon_enc_pic {
rvcn_enc_qp_map_t enc_qp_map;
rvcn_enc_metadata_buffer_t metadata;
rvcn_enc_latency_t enc_latency;
rvcn_enc_seidata_t enc_sei;
};
struct radeon_encoder {
@ -338,6 +321,8 @@ unsigned int radeon_enc_write_sps_hevc(struct radeon_encoder *enc, uint8_t *out)
unsigned int radeon_enc_write_pps_hevc(struct radeon_encoder *enc, uint8_t *out);
unsigned int radeon_enc_write_sequence_header(struct radeon_encoder *enc, uint8_t *obu_bytes, uint8_t *out);
void radeon_enc_hrd_parameters(struct radeon_encoder *enc,
struct pipe_h264_enc_hrd_params *hrd);
@ -360,16 +345,10 @@ void radeon_enc_av1_bs_instruction_type(struct radeon_encoder *enc,
void radeon_enc_av1_obu_header(struct radeon_encoder *enc, uint32_t obu_type);
void radeon_enc_av1_temporal_delimiter(struct radeon_encoder *enc);
void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_delta_q);
void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_header);
void radeon_enc_av1_tile_group(struct radeon_encoder *enc);
void radeon_enc_av1_metadata_obu(struct radeon_encoder *enc);
unsigned char *radeon_enc_av1_header_size_offset(struct radeon_encoder *enc);
unsigned int radeon_enc_value_bits(unsigned int value);

View file

@ -171,11 +171,10 @@ static void radeon_enc_spec_misc_av1(struct radeon_encoder *enc)
num_tiles_rows = tile_layout.nb_main_tile + tile_layout.nb_border_tile;
num_of_tiles = num_tiles_cols * num_tiles_rows;
/* in case of multiple tiles, it should be an obu frame */
if (num_of_tiles > 1)
enc->enc_pic.stream_obu_frame = 1;
else
enc->enc_pic.stream_obu_frame = enc->enc_pic.is_obu_frame;
enc->enc_pic.is_obu_frame = 1;
RADEON_ENC_BEGIN(enc->cmd.spec_misc_av1);
RADEON_ENC_CS(enc->enc_pic.av1_spec_misc.palette_mode_enable);
@ -207,97 +206,112 @@ static void radeon_enc_cdf_default_table(struct radeon_encoder *enc)
RADEON_ENC_END();
}
uint8_t *radeon_enc_av1_header_size_offset(struct radeon_encoder *enc)
{
uint32_t *bits_start = enc->enc_pic.copy_start + 3;
assert(enc->bits_output % 8 == 0); /* should be always byte aligned */
return (uint8_t *)(bits_start) + (enc->bits_output >> 3);
}
void radeon_enc_av1_obu_header(struct radeon_encoder *enc, uint32_t obu_type)
{
bool use_extension_flag = (enc->enc_pic.num_temporal_layers) > 1 &&
(enc->enc_pic.temporal_id) > 0 ? 1 : 0;
/* obu header () */
/* obu_forbidden_bit */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* obu_type */
radeon_enc_code_fixed_bits(enc, obu_type, 4);
/* obu_extension_flag */
radeon_enc_code_fixed_bits(enc, use_extension_flag ? 1 : 0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1.desc->obu_extension_flag ? 1 : 0, 1);
/* obu_has_size_field */
radeon_enc_code_fixed_bits(enc, 1, 1);
/* obu_reserved_1bit */
radeon_enc_code_fixed_bits(enc, 0, 1);
if (use_extension_flag) {
if (enc->enc_pic.av1.desc->obu_extension_flag) {
radeon_enc_code_fixed_bits(enc, enc->enc_pic.temporal_id, 3);
radeon_enc_code_fixed_bits(enc, 0, 2); /* spatial_id should always be zero */
radeon_enc_code_fixed_bits(enc, 0, 3); /* reserved 3 bits */
}
}
void radeon_enc_av1_temporal_delimiter(struct radeon_encoder *enc)
{
radeon_enc_av1_obu_header(enc, RENCODE_OBU_TYPE_TEMPORAL_DELIMITER);
radeon_enc_code_fixed_bits(enc, 0, 8); /* obu has size */
}
void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_delta_q)
unsigned int radeon_enc_write_sequence_header(struct radeon_encoder *enc, uint8_t *obu_bytes, uint8_t *out)
{
uint8_t *size_offset;
uint8_t obu_size_bin[2];
uint32_t obu_size;
uint32_t width_bits;
uint32_t height_bits;
uint32_t max_temporal_layers = enc->enc_pic.num_temporal_layers;
struct pipe_av1_enc_seq_param *seq = &enc->enc_pic.av1.desc->seq;
radeon_enc_av1_obu_header(enc, RENCODE_OBU_TYPE_SEQUENCE_HEADER);
radeon_enc_reset(enc);
radeon_enc_set_output_buffer(enc, out);
radeon_enc_code_fixed_bits(enc, obu_bytes[0], 8);
if (obu_bytes[0] & 0x4) /* obu_extension_flag */
radeon_enc_code_fixed_bits(enc, obu_bytes[1], 8);
/* obu_size, use two bytes for header, the size will be written in afterwards */
size_offset = radeon_enc_av1_header_size_offset(enc);
radeon_enc_code_fixed_bits(enc, 0, 2 * 8);
/* obu_size, use one byte for header, the size will be written in afterwards */
size_offset = &enc->bits_buf[enc->bits_buf_pos];
radeon_enc_code_fixed_bits(enc, 0, 8);
/* sequence_header_obu() */
/* seq_profile, only seq_profile = 0 is supported */
radeon_enc_code_fixed_bits(enc, 0, 3);
/* seq_profile */
radeon_enc_code_fixed_bits(enc, seq->profile, 3);
/* still_picture */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* reduced_still_picture_header */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* timing_info_present_flag */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.timing_info_present ? 1 : 0, 1);
radeon_enc_code_fixed_bits(enc, seq->seq_bits.timing_info_present_flag, 1);
if (enc->enc_pic.timing_info_present) {
if (seq->seq_bits.timing_info_present_flag) {
/* num_units_in_display_tick */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_timing_info.num_units_in_display_tick, 32);
radeon_enc_code_fixed_bits(enc, seq->num_units_in_display_tick, 32);
/* time_scale */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_timing_info.time_scale, 32);
radeon_enc_code_fixed_bits(enc, seq->time_scale, 32);
/* equal_picture_interval */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.timing_info_equal_picture_interval, 1);
radeon_enc_code_fixed_bits(enc, seq->seq_bits.equal_picture_interval, 1);
/* num_ticks_per_picture_minus_1 */
if (enc->enc_pic.timing_info_equal_picture_interval)
radeon_enc_code_uvlc(enc, enc->enc_pic.av1_timing_info.num_tick_per_picture_minus1);
if (seq->seq_bits.equal_picture_interval)
radeon_enc_code_uvlc(enc, seq->num_tick_per_picture_minus1);
/* decoder_model_info_present_flag */
radeon_enc_code_fixed_bits(enc, 0, 1);
radeon_enc_code_fixed_bits(enc, seq->seq_bits.decoder_model_info_present_flag, 1);
if (seq->seq_bits.decoder_model_info_present_flag) {
/* buffer_delay_length_minus1 */
radeon_enc_code_fixed_bits(enc, seq->decoder_model_info.buffer_delay_length_minus1, 5);
/* num_units_in_decoding_tick */
radeon_enc_code_fixed_bits(enc, seq->decoder_model_info.num_units_in_decoding_tick, 32);
/* buffer_removal_time_length_minus1 */
radeon_enc_code_fixed_bits(enc, seq->decoder_model_info.buffer_removal_time_length_minus1, 5);
/* frame_presentation_time_length_minus1 */
radeon_enc_code_fixed_bits(enc, seq->decoder_model_info.frame_presentation_time_length_minus1, 5);
}
}
/* initial_display_delay_present_flag */
radeon_enc_code_fixed_bits(enc, 0, 1);
radeon_enc_code_fixed_bits(enc, seq->seq_bits.initial_display_delay_present_flag, 1);
/* operating_points_cnt_minus_1 */
radeon_enc_code_fixed_bits(enc, max_temporal_layers - 1, 5);
radeon_enc_code_fixed_bits(enc, seq->num_temporal_layers - 1, 5);
for (uint32_t i = 0; i < max_temporal_layers; i++) {
uint32_t operating_point_idc = 0;
if (max_temporal_layers > 1) {
operating_point_idc = (1 << (max_temporal_layers - i)) - 1;
operating_point_idc |= 0x100; /* spatial layer not supported */
for (uint32_t i = 0; i < seq->num_temporal_layers; i++) {
/* operating_point_idc[i] */
radeon_enc_code_fixed_bits(enc, seq->operating_point_idc[i], 12);
/* seq_level_idx[i] */
radeon_enc_code_fixed_bits(enc, seq->seq_level_idx[i], 5);
if (seq->seq_level_idx[i] > 7)
/* seq_tier[i] */
radeon_enc_code_fixed_bits(enc, seq->seq_tier[i], 1);
if (seq->seq_bits.decoder_model_info_present_flag) {
/* decoder_model_present_for_this_op[i] */
radeon_enc_code_fixed_bits(enc, seq->decoder_model_present_for_this_op[i], 1);
if (seq->decoder_model_present_for_this_op[i]) {
uint32_t length = seq->decoder_model_info.buffer_delay_length_minus1 + 1;
/* decoder_buffer_delay[i] */
radeon_enc_code_fixed_bits(enc, seq->decoder_buffer_delay[i], length);
/* encoder_buffer_delay[i] */
radeon_enc_code_fixed_bits(enc, seq->encoder_buffer_delay[i], length);
/* low_delay_mode_flag[i] */
radeon_enc_code_fixed_bits(enc, seq->low_delay_mode_flag[i], 1);
}
}
if (seq->seq_bits.initial_display_delay_present_flag) {
/* initial_display_delay_present_for_this_op[i] */
radeon_enc_code_fixed_bits(enc, seq->initial_display_delay_present_for_this_op[i], 1);
if (seq->initial_display_delay_present_for_this_op[i])
/* initial_display_delay_minus_1[i] */
radeon_enc_code_fixed_bits(enc, seq->initial_display_delay_minus_1[i], 4);
}
radeon_enc_code_fixed_bits(enc, operating_point_idc, 12);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 5);
if (enc->enc_pic.general_level_idc > 7)
radeon_enc_code_fixed_bits(enc, 0, 1); /* tier */
}
/* frame_width_bits_minus_1 */
@ -314,8 +328,8 @@ void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_de
height_bits);
/* frame_id_numbers_present_flag */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.frame_id_numbers_present, 1);
if (enc->enc_pic.frame_id_numbers_present) {
radeon_enc_code_fixed_bits(enc, seq->seq_bits.frame_id_number_present_flag, 1);
if (seq->seq_bits.frame_id_number_present_flag) {
/* delta_frame_id_length_minus_2 */
radeon_enc_code_fixed_bits(enc, seq->delta_frame_id_length - 2, 4);
/* additional_frame_id_length_minus_1 */
@ -337,9 +351,9 @@ void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_de
/* enable_dual_filter */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* enable_order_hint */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.enable_order_hint ? 1 : 0, 1);
radeon_enc_code_fixed_bits(enc, seq->seq_bits.enable_order_hint, 1);
if (enc->enc_pic.enable_order_hint) {
if (seq->seq_bits.enable_order_hint) {
/* enable_jnt_comp */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* enable_ref_frame_mvs */
@ -355,9 +369,9 @@ void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_de
/* seq_choose_integer_mv */
radeon_enc_code_fixed_bits(enc, 1, 1);
if(enc->enc_pic.enable_order_hint)
if (seq->seq_bits.enable_order_hint)
/* order_hint_bits_minus_1 */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.order_hint_bits - 1, 3);
radeon_enc_code_fixed_bits(enc, seq->order_hint_bits - 1, 3);
/* enable_superres */
radeon_enc_code_fixed_bits(enc, 0, 1);
@ -370,21 +384,22 @@ void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_de
/* mono_chrome */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* color_description_present_flag */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.enable_color_description ? 1 : 0, 1);
radeon_enc_code_fixed_bits(enc, seq->seq_bits.color_description_present_flag, 1);
if(enc->enc_pic.enable_color_description) {
if (seq->seq_bits.color_description_present_flag) {
/* color_primaries */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_color_description.color_primaries, 8);
radeon_enc_code_fixed_bits(enc, seq->color_config.color_primaries, 8);
/* transfer_characteristics */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_color_description.transfer_characteristics, 8);
radeon_enc_code_fixed_bits(enc, seq->color_config.transfer_characteristics, 8);
/* matrix_coefficients */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_color_description.maxtrix_coefficients, 8);
radeon_enc_code_fixed_bits(enc, seq->color_config.matrix_coefficients, 8);
}
/* color_range */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_color_description.color_range, 1);
radeon_enc_code_fixed_bits(enc, seq->color_config.color_range, 1);
/* chroma_sample_position */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.av1_color_description.chroma_sample_position, 2);
radeon_enc_code_fixed_bits(enc, seq->color_config.chroma_sample_position, 2);
/* separate_uv_delta_q */
bool separate_delta_q = false;
radeon_enc_code_fixed_bits(enc, !!(separate_delta_q), 1);
/* film_grain_params_present */
radeon_enc_code_fixed_bits(enc, 0, 1);
@ -393,19 +408,10 @@ void radeon_enc_av1_sequence_header(struct radeon_encoder *enc, bool separate_de
radeon_enc_code_fixed_bits(enc, 1, 1);
radeon_enc_byte_align(enc);
/* obu_size doesn't include the bytes within obu_header
* or obu_size syntax element (6.2.1), here we use 2 bytes for obu_size syntax
* which needs to be removed from the size.
*/
obu_size = (uint32_t)(radeon_enc_av1_header_size_offset(enc) - size_offset - 2);
radeon_enc_code_leb128(obu_size_bin, obu_size, 2);
obu_size = (uint32_t)(&enc->bits_buf[enc->bits_buf_pos] - size_offset - 1);
radeon_enc_code_leb128(size_offset, obu_size, 1);
/* update obu_size */
for (int i = 0; i < sizeof(obu_size_bin); i++) {
uint8_t *p = (uint8_t *)((((uintptr_t)size_offset & 3) ^ 3) | ((uintptr_t)size_offset & ~3));
*p = obu_size_bin[i];
size_offset++;
}
return enc->bits_buf_pos;
}
void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_header)
@ -431,6 +437,7 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_h
/* show_frame */
radeon_enc_code_fixed_bits(enc, av1->show_frame, 1);
if (!av1->show_frame)
/* showable_frame */
radeon_enc_code_fixed_bits(enc, av1->showable_frame, 1);
bool error_resilient_mode = false;
@ -457,7 +464,7 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_h
/* force_integer_mv */
radeon_enc_code_fixed_bits(enc, enc->enc_pic.force_integer_mv ? 1 : 0, 1);
if (enc->enc_pic.frame_id_numbers_present)
if (av1->seq.seq_bits.frame_id_number_present_flag)
/* current_frame_id */
radeon_enc_code_fixed_bits(enc, av1->current_frame_id,
av1->seq.delta_frame_id_length + av1->seq.additional_frame_id_length);
@ -471,8 +478,9 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_h
radeon_enc_code_fixed_bits(enc, 0, 1);
}
if (enc->enc_pic.enable_order_hint)
radeon_enc_code_fixed_bits(enc, enc->enc_pic.order_hint, enc->enc_pic.order_hint_bits);
if (av1->seq.seq_bits.enable_order_hint)
/* order_hint */
radeon_enc_code_fixed_bits(enc, av1->order_hint, av1->seq.order_hint_bits);
if (!frame_is_intra && !error_resilient_mode)
/* primary_ref_frame */
@ -484,10 +492,10 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_h
radeon_enc_code_fixed_bits(enc, av1->refresh_frame_flags, 8);
if ((!frame_is_intra || av1->refresh_frame_flags != 0xff) &&
error_resilient_mode && enc->enc_pic.enable_order_hint)
error_resilient_mode && av1->seq.seq_bits.enable_order_hint)
for (i = 0; i < RENCODE_AV1_NUM_REF_FRAMES; i++)
/* ref_order_hint */
radeon_enc_code_fixed_bits(enc, av1->ref_order_hint[i], enc->enc_pic.order_hint_bits);
radeon_enc_code_fixed_bits(enc, av1->ref_order_hint[i], av1->seq.order_hint_bits);
if (frame_is_intra) {
/* render_and_frame_size_different */
@ -503,13 +511,18 @@ void radeon_enc_av1_frame_header_common(struct radeon_encoder *enc, bool frame_h
/* allow_intrabc */
radeon_enc_code_fixed_bits(enc, 0, 1);
} else {
if (enc->enc_pic.enable_order_hint)
if (av1->seq.seq_bits.enable_order_hint)
/* frame_refs_short_signaling */
radeon_enc_code_fixed_bits(enc, 0, 1);
radeon_enc_code_fixed_bits(enc, av1->frame_refs_short_signaling, 1);
if (av1->frame_refs_short_signaling) {
radeon_enc_code_fixed_bits(enc, av1->last_frame_idx, 3);
radeon_enc_code_fixed_bits(enc, av1->gold_frame_idx, 3);
}
for (i = 0; i < RENCODE_AV1_REFS_PER_FRAME; i++) {
/* ref_frame_idx */
/* ref_frame_idx[i] */
radeon_enc_code_fixed_bits(enc, av1->ref_frame_idx[i], 3);
if (enc->enc_pic.frame_id_numbers_present)
if (av1->seq.seq_bits.frame_id_number_present_flag)
/* delta_frame_id_minus_1[i] */
radeon_enc_code_fixed_bits(enc, av1->delta_frame_id_minus_1[i], av1->seq.delta_frame_id_length);
}
@ -582,11 +595,14 @@ static void radeon_enc_av1_frame_header(struct radeon_encoder *enc, bool frame_h
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_READ_TX_MODE, 0);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_COPY, 0);
if (!frame_is_intra)
/* reference_select */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* reduced_tx_set */
radeon_enc_code_fixed_bits(enc, 0, 1);
if (!frame_is_intra)
for (uint32_t ref = 1 /*LAST_FRAME*/; ref <= 7 /*ALTREF_FRAME*/; ref++)
/* is_global */
@ -607,122 +623,11 @@ void radeon_enc_av1_tile_group(struct radeon_encoder *enc)
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_OBU_END, 0);
}
static void radeon_enc_av1_metadata_obu_hdr_cll(struct radeon_encoder *enc)
{
uint8_t *size_offset;
uint8_t obu_size_bin;
uint8_t metadata_type;
uint8_t *p;
uint32_t obu_size;
uint32_t nb_obu_size_byte = sizeof(obu_size_bin);
rvcn_enc_sei_hdr_cll_t *p_cll = &enc->enc_pic.enc_sei.hdr_cll;
radeon_enc_av1_obu_header(enc, RENCODE_OBU_TYPE_METADATA);
/* obu_size, use nb_obu_size_byte bytes for header,
* the size will be written in afterwards */
size_offset = radeon_enc_av1_header_size_offset(enc);
radeon_enc_code_fixed_bits(enc, 0, nb_obu_size_byte * 8);
radeon_enc_code_leb128(&metadata_type, RENCODE_METADATA_TYPE_HDR_CLL, 1);
radeon_enc_code_fixed_bits(enc, metadata_type, 8);
radeon_enc_code_fixed_bits(enc, p_cll->max_cll, 16);
radeon_enc_code_fixed_bits(enc, p_cll->max_fall, 16);
/* trailing_one_bit */
radeon_enc_code_fixed_bits(enc, 1, 1);
radeon_enc_byte_align(enc);
/* obu_size doesn't include the bytes within obu_header
* or obu_size syntax element (6.2.1), here we use
* nb_obu_size_byte bytes for obu_size syntax
* which needs to be removed from the size.
*/
obu_size = (uint32_t)(radeon_enc_av1_header_size_offset(enc)
- size_offset - nb_obu_size_byte);
radeon_enc_code_leb128(&obu_size_bin, obu_size, nb_obu_size_byte);
p = (uint8_t *)((((uintptr_t)size_offset & 3) ^ 3) | ((uintptr_t)size_offset & ~3));
*p = obu_size_bin;
}
static void radeon_enc_av1_metadata_obu_hdr_mdcv(struct radeon_encoder *enc)
{
uint8_t *size_offset;
uint8_t obu_size_bin;
uint8_t metadata_type;
uint8_t *p;
uint32_t obu_size;
uint32_t nb_obu_size_byte = sizeof(obu_size_bin);
rvcn_enc_sei_hdr_mdcv_t *p_mdcv = &enc->enc_pic.enc_sei.hdr_mdcv;
radeon_enc_av1_obu_header(enc, RENCODE_OBU_TYPE_METADATA);
/* obu_size, use nb_obu_size_byte bytes for header,
* the size will be written in afterwards */
size_offset = radeon_enc_av1_header_size_offset(enc);
radeon_enc_code_fixed_bits(enc, 0, nb_obu_size_byte * 8);
radeon_enc_code_leb128(&metadata_type, RENCODE_METADATA_TYPE_HDR_MDCV, 1);
radeon_enc_code_fixed_bits(enc, metadata_type, 8);
for (int32_t i = 0; i < 3; i++) {
radeon_enc_code_fixed_bits(enc, p_mdcv->primary_chromaticity_x[i], 16);
radeon_enc_code_fixed_bits(enc, p_mdcv->primary_chromaticity_y[i], 16);
}
radeon_enc_code_fixed_bits(enc, p_mdcv->white_point_chromaticity_x, 16);
radeon_enc_code_fixed_bits(enc, p_mdcv->white_point_chromaticity_y, 16);
radeon_enc_code_fixed_bits(enc, p_mdcv->luminance_max, 32);
radeon_enc_code_fixed_bits(enc, p_mdcv->luminance_min, 32);
/* trailing_one_bit */
radeon_enc_code_fixed_bits(enc, 1, 1);
radeon_enc_byte_align(enc);
/* obu_size doesn't include the bytes within obu_header
* or obu_size syntax element (6.2.1), here we use
* nb_obu_size_byte bytes for obu_size syntax
* which needs to be removed from the size.
*/
obu_size = (uint32_t)(radeon_enc_av1_header_size_offset(enc)
- size_offset - nb_obu_size_byte);
radeon_enc_code_leb128(&obu_size_bin, obu_size, nb_obu_size_byte);
p = (uint8_t *)((((uintptr_t)size_offset & 3) ^ 3) | ((uintptr_t)size_offset & ~3));
*p = obu_size_bin;
}
void radeon_enc_av1_metadata_obu(struct radeon_encoder *enc)
{
if (!enc->enc_pic.enc_sei.flags.value)
return;
if (enc->enc_pic.enc_sei.flags.hdr_mdcv)
radeon_enc_av1_metadata_obu_hdr_mdcv(enc);
if (enc->enc_pic.enc_sei.flags.hdr_cll)
radeon_enc_av1_metadata_obu_hdr_cll(enc);
}
static void radeon_enc_obu_instruction(struct radeon_encoder *enc)
{
bool frame_header = !enc->enc_pic.stream_obu_frame ||
(enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING);
bool frame_header = !enc->enc_pic.is_obu_frame;
radeon_enc_reset(enc);
RADEON_ENC_BEGIN(enc->cmd.bitstream_instruction_av1);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_COPY, 0);
radeon_enc_av1_temporal_delimiter(enc);
if (enc->enc_pic.need_av1_seq || enc->enc_pic.need_sequence_header)
radeon_enc_av1_sequence_header(enc, false);
/* if others OBU types are needed such as meta data, then they need to be byte aligned and added here
*
* if (others)
* radeon_enc_av1_others(enc); */
radeon_enc_av1_metadata_obu(enc);
radeon_enc_av1_bs_instruction_type(enc,
RENCODE_AV1_BITSTREAM_INSTRUCTION_OBU_START,
@ -731,12 +636,12 @@ static void radeon_enc_obu_instruction(struct radeon_encoder *enc)
radeon_enc_av1_frame_header(enc, frame_header);
if (!frame_header && (enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING))
if (!frame_header)
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_TILE_GROUP_OBU, 0);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_OBU_END, 0);
if (frame_header && (enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING))
if (frame_header)
radeon_enc_av1_tile_group(enc);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_END, 0);
@ -755,7 +660,6 @@ static void radeon_enc_av1_encode_params(struct radeon_encoder *enc)
break;
case PIPE_AV1_ENC_FRAME_TYPE_INTER:
case PIPE_AV1_ENC_FRAME_TYPE_SWITCH:
case PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING:
enc->enc_pic.enc_params.pic_type = RENCODE_PICTURE_TYPE_P;
break;
default:
@ -775,19 +679,9 @@ static void radeon_enc_av1_encode_params(struct radeon_encoder *enc)
RADEON_ENC_BEGIN(enc->cmd.enc_params);
RADEON_ENC_CS(enc->enc_pic.enc_params.pic_type);
RADEON_ENC_CS(enc->enc_pic.enc_params.allowed_max_bitstream_size);
/* show existing type doesn't need input picture */
if (enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING) {
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
} else {
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->luma->u.gfx9.surf_offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->chroma ?
enc->chroma->u.gfx9.surf_offset : enc->luma->u.gfx9.surf_pitch);
}
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->luma->u.gfx9.surf_offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->chroma ?
enc->chroma->u.gfx9.surf_offset : enc->luma->u.gfx9.surf_pitch);
RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_luma_pitch);
RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_chroma_pitch);
RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_swizzle_mode);

View file

@ -81,7 +81,6 @@ 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:
case PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING:
enc->enc_pic.enc_params.pic_type = RENCODE_PICTURE_TYPE_P;
break;
default:
@ -748,11 +747,14 @@ static void radeon_enc_av1_frame_header(struct radeon_encoder *enc, bool frame_h
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_READ_TX_MODE, 0);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_COPY, 0);
if (!frame_is_intra)
/* reference_select */
radeon_enc_code_fixed_bits(enc, 0, 1);
/* reduced_tx_set */
radeon_enc_code_fixed_bits(enc, 0, 1);
if (!frame_is_intra)
for (uint32_t ref = 1 /*LAST_FRAME*/; ref <= 7 /*ALTREF_FRAME*/; ref++)
/* is_global */
@ -762,22 +764,10 @@ static void radeon_enc_av1_frame_header(struct radeon_encoder *enc, bool frame_h
static void radeon_enc_obu_instruction(struct radeon_encoder *enc)
{
bool frame_header = !enc->enc_pic.is_obu_frame ||
(enc->enc_pic.frame_type == PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING);
bool frame_header = !enc->enc_pic.is_obu_frame;
radeon_enc_reset(enc);
RADEON_ENC_BEGIN(enc->cmd.bitstream_instruction_av1);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_COPY, 0);
radeon_enc_av1_temporal_delimiter(enc);
if (enc->enc_pic.need_av1_seq || enc->enc_pic.need_sequence_header)
radeon_enc_av1_sequence_header(enc, enc->enc_pic.av1_spec_misc.separate_delta_q);
/* if others OBU types are needed such as meta data, then they need to be byte aligned and added here
*
* if (others)
* radeon_enc_av1_others(enc); */
radeon_enc_av1_metadata_obu(enc);
radeon_enc_av1_bs_instruction_type(enc,
RENCODE_AV1_BITSTREAM_INSTRUCTION_OBU_START,
@ -786,12 +776,12 @@ static void radeon_enc_obu_instruction(struct radeon_encoder *enc)
radeon_enc_av1_frame_header(enc, frame_header);
if (!frame_header && (enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING))
if (!frame_header)
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_TILE_GROUP_OBU, 0);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_OBU_END, 0);
if (frame_header && (enc->enc_pic.frame_type != PIPE_AV1_ENC_FRAME_TYPE_SHOW_EXISTING))
if (frame_header)
radeon_enc_av1_tile_group(enc);
radeon_enc_av1_bs_instruction_type(enc, RENCODE_AV1_BITSTREAM_INSTRUCTION_END, 0);