From 1f5e857d853f4f655733416d0a930b84dd12320b Mon Sep 17 00:00:00 2001 From: David Rosca Date: Mon, 30 Dec 2024 16:00:02 +0100 Subject: [PATCH] radeonsi/uvd_enc: Use app DPB management Reviewed-by: Ruijing Dong Acked-by: Leo Liu Part-of: --- src/gallium/drivers/radeonsi/radeon_uvd_enc.c | 70 +- src/gallium/drivers/radeonsi/radeon_uvd_enc.h | 59 +- .../drivers/radeonsi/radeon_uvd_enc_1_1.c | 692 +++++++----------- 3 files changed, 282 insertions(+), 539 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc.c b/src/gallium/drivers/radeonsi/radeon_uvd_enc.c index 26c0a0a18d6..02fb45c4d80 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc.c @@ -17,47 +17,18 @@ #include -static void radeon_uvd_enc_get_vui_param(struct radeon_uvd_encoder *enc, - struct pipe_h265_enc_picture_desc *pic) -{ - enc->enc_pic.vui_info.vui_parameters_present_flag = - pic->seq.vui_parameters_present_flag; - enc->enc_pic.vui_info.flags.aspect_ratio_info_present_flag = - pic->seq.vui_flags.aspect_ratio_info_present_flag; - enc->enc_pic.vui_info.flags.timing_info_present_flag = - pic->seq.vui_flags.timing_info_present_flag; - enc->enc_pic.vui_info.flags.video_signal_type_present_flag = - pic->seq.vui_flags.video_signal_type_present_flag; - enc->enc_pic.vui_info.flags.colour_description_present_flag = - pic->seq.vui_flags.colour_description_present_flag; - enc->enc_pic.vui_info.flags.chroma_loc_info_present_flag = - pic->seq.vui_flags.chroma_loc_info_present_flag; - enc->enc_pic.vui_info.aspect_ratio_idc = pic->seq.aspect_ratio_idc; - enc->enc_pic.vui_info.sar_width = pic->seq.sar_width; - enc->enc_pic.vui_info.sar_height = pic->seq.sar_height; - enc->enc_pic.vui_info.num_units_in_tick = pic->seq.num_units_in_tick; - enc->enc_pic.vui_info.time_scale = pic->seq.time_scale; - enc->enc_pic.vui_info.video_format = pic->seq.video_format; - enc->enc_pic.vui_info.video_full_range_flag = pic->seq.video_full_range_flag; - enc->enc_pic.vui_info.colour_primaries = pic->seq.colour_primaries; - enc->enc_pic.vui_info.transfer_characteristics = pic->seq.transfer_characteristics; - enc->enc_pic.vui_info.matrix_coefficients = pic->seq.matrix_coefficients; - enc->enc_pic.vui_info.chroma_sample_loc_type_top_field = - pic->seq.chroma_sample_loc_type_top_field; - enc->enc_pic.vui_info.chroma_sample_loc_type_bottom_field = - pic->seq.chroma_sample_loc_type_bottom_field; -} - static void radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc, struct pipe_h265_enc_picture_desc *pic) { + enc->enc_pic.desc = pic; enc->enc_pic.picture_type = pic->picture_type; - enc->enc_pic.frame_num = pic->frame_num; - enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; - enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type; - enc->enc_pic.not_referenced = pic->not_referenced; + enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type; + enc->enc_pic.temporal_id = pic->pic.temporal_id; enc->enc_pic.is_iframe = (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) || (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_I); + enc->enc_pic.enc_params.reference_picture_index = + pic->ref_list0[0] == PIPE_H2645_LIST_REF_INVALID_ENTRY ? 0xffffffff : pic->ref_list0[0]; + enc->enc_pic.enc_params.reconstructed_picture_index = pic->dpb_curr_pic; if (pic->seq.conformance_window_flag) { enc->enc_pic.crop_left = pic->seq.conf_win_left_offset; @@ -70,34 +41,6 @@ static void radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc, enc->enc_pic.crop_top = 0; enc->enc_pic.crop_bottom = 0; } - - enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag; - enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc; - enc->enc_pic.general_level_idc = pic->seq.general_level_idc; - enc->enc_pic.max_poc = MAX2(16, util_next_power_of_two(pic->seq.intra_period)); - enc->enc_pic.log2_max_poc = 0; - for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++) - i = (i >> 1); - enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc; - enc->enc_pic.pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples; - enc->enc_pic.pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples; - enc->enc_pic.log2_diff_max_min_luma_coding_block_size = - pic->seq.log2_diff_max_min_luma_coding_block_size; - enc->enc_pic.log2_min_transform_block_size_minus2 = - pic->seq.log2_min_transform_block_size_minus2; - enc->enc_pic.log2_diff_max_min_transform_block_size = - pic->seq.log2_diff_max_min_transform_block_size; - enc->enc_pic.max_transform_hierarchy_depth_inter = pic->seq.max_transform_hierarchy_depth_inter; - enc->enc_pic.max_transform_hierarchy_depth_intra = pic->seq.max_transform_hierarchy_depth_intra; - enc->enc_pic.log2_parallel_merge_level_minus2 = pic->pic.log2_parallel_merge_level_minus2; - enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8; - enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8; - enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type; - enc->enc_pic.max_num_merge_cand = pic->slice.max_num_merge_cand; - enc->enc_pic.sample_adaptive_offset_enabled_flag = pic->seq.sample_adaptive_offset_enabled_flag; - enc->enc_pic.pcm_enabled_flag = 0; /*HW not support PCM */ - enc->enc_pic.sps_temporal_mvp_enabled_flag = pic->seq.sps_temporal_mvp_enabled_flag; - radeon_uvd_enc_get_vui_param(enc, pic); } static int flush(struct radeon_uvd_encoder *enc, unsigned flags, struct pipe_fence_handle **fence) @@ -307,7 +250,6 @@ struct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context *context, enc->base.fence_wait = radeon_uvd_enc_fence_wait; enc->base.destroy_fence = radeon_uvd_enc_destroy_fence; enc->get_buffer = get_buffer; - enc->bits_in_shifter = 0; enc->screen = context->screen; enc->ws = ws; diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc.h b/src/gallium/drivers/radeonsi/radeon_uvd_enc.h index 759a3ec6e9a..695008c1d9e 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc.h +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc.h @@ -303,31 +303,6 @@ typedef struct ruvd_enc_feedback_buffer_s { uint32_t feedback_data_size; } ruvd_enc_feedback_buffer_t; -typedef struct ruvd_enc_vui_info_s -{ - uint32_t vui_parameters_present_flag; - struct { - uint32_t aspect_ratio_info_present_flag : 1; - uint32_t timing_info_present_flag : 1; - uint32_t video_signal_type_present_flag : 1; - uint32_t colour_description_present_flag : 1; - uint32_t chroma_loc_info_present_flag : 1; - } flags; - uint32_t aspect_ratio_idc; - uint32_t sar_width; - uint32_t sar_height; - uint32_t num_units_in_tick; - uint32_t time_scale; - uint32_t video_format; - uint32_t video_full_range_flag; - uint32_t colour_primaries; - uint32_t transfer_characteristics; - uint32_t matrix_coefficients; - uint32_t chroma_sample_loc_type_top_field; - uint32_t chroma_sample_loc_type_bottom_field; - uint32_t max_num_reorder_frames; -} ruvd_enc_vui_info; - typedef void (*radeon_uvd_enc_get_buffer)(struct pipe_resource *resource, struct pb_buffer_lean **handle, struct radeon_surf **surface); @@ -338,40 +313,16 @@ struct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context *context, struct radeon_uvd_enc_pic { enum pipe_h2645_enc_picture_type picture_type; + struct pipe_h265_enc_picture_desc *desc; - unsigned frame_num; - unsigned pic_order_cnt; - unsigned pic_order_cnt_type; unsigned crop_left; unsigned crop_right; unsigned crop_top; unsigned crop_bottom; - unsigned general_tier_flag; - unsigned general_profile_idc; - unsigned general_level_idc; - unsigned max_poc; - unsigned log2_max_poc; - unsigned chroma_format_idc; - unsigned pic_width_in_luma_samples; - unsigned pic_height_in_luma_samples; - unsigned log2_diff_max_min_luma_coding_block_size; - unsigned log2_min_transform_block_size_minus2; - unsigned log2_diff_max_min_transform_block_size; - unsigned max_transform_hierarchy_depth_inter; - unsigned max_transform_hierarchy_depth_intra; - unsigned log2_parallel_merge_level_minus2; - unsigned bit_depth_luma_minus8; - unsigned bit_depth_chroma_minus8; unsigned nal_unit_type; - unsigned max_num_merge_cand; - ruvd_enc_vui_info vui_info; + unsigned temporal_id; - bool not_referenced; bool is_iframe; - bool is_even_frame; - bool sample_adaptive_offset_enabled_flag; - bool pcm_enabled_flag; - bool sps_temporal_mvp_enabled_flag; ruvd_enc_task_info_t task_info; ruvd_enc_session_init_t session_init; @@ -420,15 +371,9 @@ struct radeon_uvd_encoder { struct rvid_buffer dpb; struct radeon_uvd_enc_pic enc_pic; - unsigned shifter; - unsigned bits_in_shifter; - unsigned num_zeros; - unsigned byte_index; - unsigned bits_output; uint32_t total_task_size; uint32_t *p_task_size; - bool emulation_prevention; bool need_feedback; }; diff --git a/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c b/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c index b73f49aa74c..7c4e06700b0 100644 --- a/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c +++ b/src/gallium/drivers/radeonsi/radeon_uvd_enc_1_1.c @@ -9,6 +9,7 @@ #include "pipe/p_video_codec.h" #include "radeon_uvd_enc.h" #include "radeon_video.h" +#include "radeon_bitstream.h" #include "radeonsi/si_pipe.h" #include "util/u_memory.h" #include "util/u_video.h" @@ -32,8 +33,6 @@ enc->total_task_size += *begin; \ } -static const unsigned index_to_shifts[4] = {24, 16, 8, 0}; - static void radeon_uvd_enc_add_buffer(struct radeon_uvd_encoder *enc, struct pb_buffer_lean *buf, unsigned usage, enum radeon_bo_domain domain, signed offset) @@ -46,130 +45,6 @@ static void radeon_uvd_enc_add_buffer(struct radeon_uvd_encoder *enc, struct pb_ RADEON_ENC_CS(addr); } -static void radeon_uvd_enc_set_emulation_prevention(struct radeon_uvd_encoder *enc, bool set) -{ - if (set != enc->emulation_prevention) { - enc->emulation_prevention = set; - enc->num_zeros = 0; - } -} - -static void radeon_uvd_enc_output_one_byte(struct radeon_uvd_encoder *enc, unsigned char byte) -{ - if (enc->byte_index == 0) - enc->cs.current.buf[enc->cs.current.cdw] = 0; - enc->cs.current.buf[enc->cs.current.cdw] |= - ((unsigned int)(byte) << index_to_shifts[enc->byte_index]); - enc->byte_index++; - - if (enc->byte_index >= 4) { - enc->byte_index = 0; - enc->cs.current.cdw++; - } -} - -static void radeon_uvd_enc_emulation_prevention(struct radeon_uvd_encoder *enc, unsigned char byte) -{ - if (enc->emulation_prevention) { - if ((enc->num_zeros >= 2) && - ((byte == 0x00) || (byte == 0x01) || (byte == 0x02) || (byte == 0x03))) { - radeon_uvd_enc_output_one_byte(enc, 0x03); - enc->bits_output += 8; - enc->num_zeros = 0; - } - enc->num_zeros = (byte == 0 ? (enc->num_zeros + 1) : 0); - } -} - -static void radeon_uvd_enc_code_fixed_bits(struct radeon_uvd_encoder *enc, unsigned int value, - unsigned int num_bits) -{ - unsigned int bits_to_pack = 0; - - while (num_bits > 0) { - unsigned int value_to_pack = value & (0xffffffff >> (32 - num_bits)); - bits_to_pack = - num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits; - - if (bits_to_pack < num_bits) - value_to_pack = value_to_pack >> (num_bits - bits_to_pack); - - enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack); - num_bits -= bits_to_pack; - enc->bits_in_shifter += bits_to_pack; - - while (enc->bits_in_shifter >= 8) { - unsigned char output_byte = (unsigned char)(enc->shifter >> 24); - enc->shifter <<= 8; - radeon_uvd_enc_emulation_prevention(enc, output_byte); - radeon_uvd_enc_output_one_byte(enc, output_byte); - enc->bits_in_shifter -= 8; - enc->bits_output += 8; - } - } -} - -static void radeon_uvd_enc_reset(struct radeon_uvd_encoder *enc) -{ - enc->emulation_prevention = false; - enc->shifter = 0; - enc->bits_in_shifter = 0; - enc->bits_output = 0; - enc->num_zeros = 0; - enc->byte_index = 0; -} - -static void radeon_uvd_enc_byte_align(struct radeon_uvd_encoder *enc) -{ - unsigned int num_padding_zeros = (32 - enc->bits_in_shifter) % 8; - - if (num_padding_zeros > 0) - radeon_uvd_enc_code_fixed_bits(enc, 0, num_padding_zeros); -} - -static void radeon_uvd_enc_flush_headers(struct radeon_uvd_encoder *enc) -{ - if (enc->bits_in_shifter != 0) { - unsigned char output_byte = (unsigned char)(enc->shifter >> 24); - radeon_uvd_enc_emulation_prevention(enc, output_byte); - radeon_uvd_enc_output_one_byte(enc, output_byte); - enc->bits_output += enc->bits_in_shifter; - enc->shifter = 0; - enc->bits_in_shifter = 0; - enc->num_zeros = 0; - } - - if (enc->byte_index > 0) { - enc->cs.current.cdw++; - enc->byte_index = 0; - } -} - -static void radeon_uvd_enc_code_ue(struct radeon_uvd_encoder *enc, unsigned int value) -{ - int x = -1; - unsigned int ue_code = value + 1; - value += 1; - - while (value) { - value = (value >> 1); - x += 1; - } - - unsigned int ue_length = (x << 1) + 1; - radeon_uvd_enc_code_fixed_bits(enc, ue_code, ue_length); -} - -static void radeon_uvd_enc_code_se(struct radeon_uvd_encoder *enc, int value) -{ - unsigned int v = 0; - - if (value != 0) - v = (value < 0 ? ((unsigned int)(0 - value) << 1) : (((unsigned int)(value) << 1) - 1)); - - radeon_uvd_enc_code_ue(enc, v); -} - static void radeon_uvd_enc_session_info(struct radeon_uvd_encoder *enc) { unsigned int interface_version = @@ -374,329 +249,298 @@ static void radeon_uvd_enc_quality_params(struct radeon_uvd_encoder *enc) static void radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc) { + struct radeon_bitstream bs; + struct pipe_h265_enc_seq_param *sps = &enc->enc_pic.desc->seq; + int i; + RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER); RADEON_ENC_CS(RENC_UVD_NALU_TYPE_SPS); uint32_t *size_in_bytes = &enc->cs.current.buf[enc->cs.current.cdw++]; - int i; - radeon_uvd_enc_reset(enc); - radeon_uvd_enc_set_emulation_prevention(enc, false); - radeon_uvd_enc_code_fixed_bits(enc, 0x00000001, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x4201, 16); - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_set_emulation_prevention(enc, true); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 4); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_profile_idc, 5); - radeon_uvd_enc_code_fixed_bits(enc, 0x60000000, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0xb0000000, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 16); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 8); + radeon_bs_reset(&bs, NULL, &enc->cs); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, 0x4201, 16); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_fixed_bits(&bs, 0x0, 4); /* sps_video_parameter_set_id */ + radeon_bs_code_fixed_bits(&bs, sps->sps_max_sub_layers_minus1, 3); + radeon_bs_code_fixed_bits(&bs, sps->sps_temporal_id_nesting_flag, 1); + radeon_bs_hevc_profile_tier_level(&bs, sps->sps_max_sub_layers_minus1, &sps->profile_tier_level); + radeon_bs_code_ue(&bs, 0x0); /* sps_seq_parameter_set_id */ + radeon_bs_code_ue(&bs, sps->chroma_format_idc); + radeon_bs_code_ue(&bs, enc->enc_pic.session_init.aligned_picture_width); + radeon_bs_code_ue(&bs, enc->enc_pic.session_init.aligned_picture_height); - for (i = 0; i < (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i++) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); - - if ((enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) > 0) { - for (i = (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i < 8; i++) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); + radeon_bs_code_fixed_bits(&bs, sps->conformance_window_flag, 1); + if (sps->conformance_window_flag) { + radeon_bs_code_ue(&bs, sps->conf_win_left_offset); + radeon_bs_code_ue(&bs, sps->conf_win_right_offset); + radeon_bs_code_ue(&bs, sps->conf_win_top_offset); + radeon_bs_code_ue(&bs, sps->conf_win_bottom_offset); } - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.chroma_format_idc); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_width); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_height); - - int conformance_window_flag = (enc->enc_pic.crop_top > 0) || (enc->enc_pic.crop_bottom > 0) || - (enc->enc_pic.crop_left > 0) || (enc->enc_pic.crop_right > 0) - ? 0x1 - : 0x0; - radeon_uvd_enc_code_fixed_bits(enc, conformance_window_flag, 1); - - if (conformance_window_flag == 1) { - radeon_uvd_enc_code_ue(enc, enc->enc_pic.crop_left); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.crop_right); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.crop_top); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.crop_bottom); + radeon_bs_code_ue(&bs, sps->bit_depth_luma_minus8); + radeon_bs_code_ue(&bs, sps->bit_depth_chroma_minus8); + radeon_bs_code_ue(&bs, sps->log2_max_pic_order_cnt_lsb_minus4); + radeon_bs_code_fixed_bits(&bs, sps->sps_sub_layer_ordering_info_present_flag, 1); + i = sps->sps_sub_layer_ordering_info_present_flag ? 0 : sps->sps_max_sub_layers_minus1; + for (; i <= sps->sps_max_sub_layers_minus1; i++) { + radeon_bs_code_ue(&bs, sps->sps_max_dec_pic_buffering_minus1[i]); + radeon_bs_code_ue(&bs, sps->sps_max_num_reorder_pics[i]); + radeon_bs_code_ue(&bs, sps->sps_max_latency_increase_plus1[i]); } - radeon_uvd_enc_code_ue(enc, enc->enc_pic.bit_depth_luma_minus8); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.bit_depth_chroma_minus8); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.log2_max_poc - 4); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_ue(enc, 1); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); - /* Only support CTBSize 64 */ - radeon_uvd_enc_code_ue( - enc, 6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3)); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.log2_min_transform_block_size_minus2); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.log2_diff_max_min_transform_block_size); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_inter); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_intra); + unsigned log2_diff_max_min_luma_coding_block_size = + 6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3); + unsigned log2_min_transform_block_size_minus2 = + enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3; + unsigned log2_diff_max_min_transform_block_size = log2_diff_max_min_luma_coding_block_size; + unsigned max_transform_hierarchy_depth_inter = log2_diff_max_min_luma_coding_block_size + 1; + unsigned max_transform_hierarchy_depth_intra = max_transform_hierarchy_depth_inter; - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.sample_adaptive_offset_enabled_flag, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.pcm_enabled_flag, 1); + radeon_bs_code_ue(&bs, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); + radeon_bs_code_ue(&bs, log2_diff_max_min_luma_coding_block_size); + radeon_bs_code_ue(&bs, log2_min_transform_block_size_minus2); + radeon_bs_code_ue(&bs, log2_diff_max_min_transform_block_size); + radeon_bs_code_ue(&bs, max_transform_hierarchy_depth_inter); + radeon_bs_code_ue(&bs, max_transform_hierarchy_depth_intra); - radeon_uvd_enc_code_ue(enc, 1); - radeon_uvd_enc_code_ue(enc, 1); - radeon_uvd_enc_code_ue(enc, 0); - radeon_uvd_enc_code_ue(enc, 0); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* scaling_list_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* sample_adaptive_offset_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* pcm_enabled_flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); + radeon_bs_code_ue(&bs, sps->num_short_term_ref_pic_sets); + for (i = 0; i < sps->num_short_term_ref_pic_sets; i++) + radeon_bs_hevc_st_ref_pic_set(&bs, i, sps->num_short_term_ref_pic_sets, sps->st_ref_pic_set); - radeon_uvd_enc_code_fixed_bits(enc, 0, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled, - 1); + radeon_bs_code_fixed_bits(&bs, sps->long_term_ref_pics_present_flag, 1); + if (sps->long_term_ref_pics_present_flag) { + radeon_bs_code_ue(&bs, sps->num_long_term_ref_pics_sps); + for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) { + radeon_bs_code_fixed_bits(&bs, sps->lt_ref_pic_poc_lsb_sps[i], sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + radeon_bs_code_fixed_bits(&bs, sps->used_by_curr_pic_lt_sps_flag[i], 1); + } + } - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.vui_parameters_present_flag), 1); - if (enc->enc_pic.vui_info.vui_parameters_present_flag) { + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* sps_temporal_mvp_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled, 1); + + /* VUI parameters present flag */ + radeon_bs_code_fixed_bits(&bs, (sps->vui_parameters_present_flag), 1); + if (sps->vui_parameters_present_flag) { /* aspect ratio present flag */ - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.flags.aspect_ratio_info_present_flag), 1); - if (enc->enc_pic.vui_info.flags.aspect_ratio_info_present_flag) { - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.aspect_ratio_idc), 8); - if (enc->enc_pic.vui_info.aspect_ratio_idc == PIPE_H2645_EXTENDED_SAR) { - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.sar_width), 16); - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.sar_height), 16); + radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.aspect_ratio_info_present_flag), 1); + if (sps->vui_flags.aspect_ratio_info_present_flag) { + radeon_bs_code_fixed_bits(&bs, (sps->aspect_ratio_idc), 8); + if (sps->aspect_ratio_idc == PIPE_H2645_EXTENDED_SAR) { + radeon_bs_code_fixed_bits(&bs, (sps->sar_width), 16); + radeon_bs_code_fixed_bits(&bs, (sps->sar_height), 16); } } - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* overscan info present flag */ + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.overscan_info_present_flag, 1); + if (sps->vui_flags.overscan_info_present_flag) + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.overscan_appropriate_flag, 1); /* video signal type present flag */ - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.flags.video_signal_type_present_flag, 1); - if (enc->enc_pic.vui_info.flags.video_signal_type_present_flag) { - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.video_format, 3); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.video_full_range_flag, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.flags.colour_description_present_flag, 1); - if (enc->enc_pic.vui_info.flags.colour_description_present_flag) { - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.colour_primaries, 8); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.transfer_characteristics, 8); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.matrix_coefficients, 8); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.video_signal_type_present_flag, 1); + if (sps->vui_flags.video_signal_type_present_flag) { + radeon_bs_code_fixed_bits(&bs, sps->video_format, 3); + radeon_bs_code_fixed_bits(&bs, sps->video_full_range_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.colour_description_present_flag, 1); + if (sps->vui_flags.colour_description_present_flag) { + radeon_bs_code_fixed_bits(&bs, sps->colour_primaries, 8); + radeon_bs_code_fixed_bits(&bs, sps->transfer_characteristics, 8); + radeon_bs_code_fixed_bits(&bs, sps->matrix_coefficients, 8); } } /* chroma loc info present flag */ - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.vui_info.flags.chroma_loc_info_present_flag, 1); - if (enc->enc_pic.vui_info.flags.chroma_loc_info_present_flag) { - radeon_uvd_enc_code_ue(enc, enc->enc_pic.vui_info.chroma_sample_loc_type_top_field); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.vui_info.chroma_sample_loc_type_bottom_field); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.chroma_loc_info_present_flag, 1); + if (sps->vui_flags.chroma_loc_info_present_flag) { + radeon_bs_code_ue(&bs, sps->chroma_sample_loc_type_top_field); + radeon_bs_code_ue(&bs, sps->chroma_sample_loc_type_bottom_field); } - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* neutral chroma indication flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* field seq flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* frame field info present flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* default display windows flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* neutral chroma indication flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* field seq flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* frame field info present flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* default display windows flag */ /* vui timing info present flag */ - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.flags.timing_info_present_flag), 1); - if (enc->enc_pic.vui_info.flags.timing_info_present_flag) { - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.num_units_in_tick), 32); - radeon_uvd_enc_code_fixed_bits(enc, (enc->enc_pic.vui_info.time_scale), 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); + radeon_bs_code_fixed_bits(&bs, (sps->vui_flags.timing_info_present_flag), 1); + if (sps->vui_flags.timing_info_present_flag) { + radeon_bs_code_fixed_bits(&bs, (sps->num_units_in_tick), 32); + radeon_bs_code_fixed_bits(&bs, (sps->time_scale), 32); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.poc_proportional_to_timing_flag, 1); + if (sps->vui_flags.poc_proportional_to_timing_flag) + radeon_bs_code_ue(&bs, sps->num_ticks_poc_diff_one_minus1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.hrd_parameters_present_flag, 1); + if (sps->vui_flags.hrd_parameters_present_flag) + radeon_bs_hevc_hrd_parameters(&bs, 1, sps->sps_max_sub_layers_minus1, &sps->hrd_parameters); } - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* bitstream restriction flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* bitstream restriction flag */ } + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* sps extension present flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_flush_headers(enc); - *size_in_bytes = (enc->bits_output + 7) / 8; + radeon_bs_flush_headers(&bs); + *size_in_bytes = bs.bits_output / 8; RADEON_ENC_END(); } static void radeon_uvd_enc_nalu_pps_hevc(struct radeon_uvd_encoder *enc) { + struct radeon_bitstream bs; + struct pipe_h265_enc_pic_param *pps = &enc->enc_pic.desc->pic; + RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER); RADEON_ENC_CS(RENC_UVD_NALU_TYPE_PPS); uint32_t *size_in_bytes = &enc->cs.current.buf[enc->cs.current.cdw++]; - radeon_uvd_enc_reset(enc); - radeon_uvd_enc_set_emulation_prevention(enc, false); - radeon_uvd_enc_code_fixed_bits(enc, 0x00000001, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x4401, 16); - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_set_emulation_prevention(enc, true); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* output_flag_resent_flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 3); /* num_extra_slice_header_bits */ - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_se(enc, 0x0); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - if (enc->enc_pic.rc_session_init.rate_control_method == RENC_UVD_RATE_CONTROL_METHOD_NONE) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - else { - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - radeon_uvd_enc_code_ue(enc, 0x0); - } - radeon_uvd_enc_code_se(enc, enc->enc_pic.hevc_deblock.cb_qp_offset); - radeon_uvd_enc_code_se(enc, enc->enc_pic.hevc_deblock.cr_qp_offset); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, - 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.deblocking_filter_disabled, 1); + + radeon_bs_reset(&bs, NULL, &enc->cs); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, 0x4401, 16); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_ue(&bs, 0x0); /* pps_pic_parameter_set_id */ + radeon_bs_code_ue(&bs, 0x0); /* pps_seq_parameter_set_id */ + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* dependent_slice_segments_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, pps->output_flag_present_flag, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 3); /* num_extra_slice_header_bits */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* sign_data_hiding_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* cabac_init_present_flag */ + radeon_bs_code_ue(&bs, pps->num_ref_idx_l0_default_active_minus1); + radeon_bs_code_ue(&bs, pps->num_ref_idx_l1_default_active_minus1); + radeon_bs_code_se(&bs, 0x0); /* init_qp_minus26 */ + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* transform_skip_enabled */ + bool cu_qp_delta_enabled_flag = + enc->enc_pic.rc_session_init.rate_control_method != RENC_UVD_RATE_CONTROL_METHOD_NONE; + radeon_bs_code_fixed_bits(&bs, cu_qp_delta_enabled_flag, 1); + if (cu_qp_delta_enabled_flag) + radeon_bs_code_ue(&bs, 0x0); /* diff_cu_qp_delta_depth */ + radeon_bs_code_se(&bs, enc->enc_pic.hevc_deblock.cb_qp_offset); + radeon_bs_code_se(&bs, enc->enc_pic.hevc_deblock.cr_qp_offset); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* pps_slice_chroma_qp_offsets_present_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* weighted_pred_flag + weighted_bipred_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* transquant_bypass_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* tiles_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* entropy_coding_sync_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1); + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* deblocking_filter_control_present_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* deblocking_filter_override_enabled_flag */ + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.hevc_deblock.deblocking_filter_disabled, 1); if (!enc->enc_pic.hevc_deblock.deblocking_filter_disabled) { - radeon_uvd_enc_code_se(enc, enc->enc_pic.hevc_deblock.beta_offset_div2); - radeon_uvd_enc_code_se(enc, enc->enc_pic.hevc_deblock.tc_offset_div2); + radeon_bs_code_se(&bs, enc->enc_pic.hevc_deblock.beta_offset_div2); + radeon_bs_code_se(&bs, enc->enc_pic.hevc_deblock.tc_offset_div2); } - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_ue(enc, enc->enc_pic.log2_parallel_merge_level_minus2); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* pps_scaling_list_data_present_flag */ + radeon_bs_code_fixed_bits(&bs, pps->lists_modification_present_flag, 1); + radeon_bs_code_ue(&bs, pps->log2_parallel_merge_level_minus2); + radeon_bs_code_fixed_bits(&bs, 0x0, 2); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_flush_headers(enc); - *size_in_bytes = (enc->bits_output + 7) / 8; + radeon_bs_flush_headers(&bs); + *size_in_bytes = bs.bits_output / 8; RADEON_ENC_END(); } static void radeon_uvd_enc_nalu_vps_hevc(struct radeon_uvd_encoder *enc) { + struct radeon_bitstream bs; + struct pipe_h265_enc_vid_param *vps = &enc->enc_pic.desc->vid; + int i; + RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER); RADEON_ENC_CS(RENC_UVD_NALU_TYPE_VPS); uint32_t *size_in_bytes = &enc->cs.current.buf[enc->cs.current.cdw++]; - int i; - radeon_uvd_enc_reset(enc); - radeon_uvd_enc_set_emulation_prevention(enc, false); - radeon_uvd_enc_code_fixed_bits(enc, 0x00000001, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x4001, 16); - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_set_emulation_prevention(enc, true); - - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 4); - radeon_uvd_enc_code_fixed_bits(enc, 0x3, 2); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 6); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0xffff, 16); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_profile_idc, 5); - radeon_uvd_enc_code_fixed_bits(enc, 0x60000000, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0xb0000000, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 16); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 8); - - for (i = 0; i < (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i++) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); - - if ((enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) > 0) { - for (i = (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i < 8; i++) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2); + radeon_bs_reset(&bs, NULL, &enc->cs); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, 0x4001, 16); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_fixed_bits(&bs, 0x0, 4); /* vps_video_parameter_set_id*/ + radeon_bs_code_fixed_bits(&bs, vps->vps_base_layer_internal_flag, 1); + radeon_bs_code_fixed_bits(&bs, vps->vps_base_layer_available_flag, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 6); /* vps_max_layers_minus1 */ + radeon_bs_code_fixed_bits(&bs, vps->vps_max_sub_layers_minus1, 3); + radeon_bs_code_fixed_bits(&bs, vps->vps_temporal_id_nesting_flag, 1); + radeon_bs_code_fixed_bits(&bs, 0xffff, 16); /* vps_reserved_0xffff_16bits */ + radeon_bs_hevc_profile_tier_level(&bs, vps->vps_max_sub_layers_minus1, &vps->profile_tier_level); + radeon_bs_code_fixed_bits(&bs, vps->vps_sub_layer_ordering_info_present_flag, 1); + i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers_minus1; + for (; i <= vps->vps_max_sub_layers_minus1; i++) { + radeon_bs_code_ue(&bs, vps->vps_max_dec_pic_buffering_minus1[i]); + radeon_bs_code_ue(&bs, vps->vps_max_num_reorder_pics[i]); + radeon_bs_code_ue(&bs, vps->vps_max_latency_increase_plus1[i]); } - - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_ue(enc, 0x1); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, 0x0); - - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 6); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_flush_headers(enc); - *size_in_bytes = (enc->bits_output + 7) / 8; - RADEON_ENC_END(); -} - -static void radeon_uvd_enc_nalu_aud_hevc(struct radeon_uvd_encoder *enc) -{ - RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER); - RADEON_ENC_CS(RENC_UVD_NALU_TYPE_AUD); - uint32_t *size_in_bytes = &enc->cs.current.buf[enc->cs.current.cdw++]; - radeon_uvd_enc_reset(enc); - radeon_uvd_enc_set_emulation_prevention(enc, false); - radeon_uvd_enc_code_fixed_bits(enc, 0x00000001, 32); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 35, 6); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 6); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 3); - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_set_emulation_prevention(enc, true); - switch (enc->enc_pic.picture_type) { - case PIPE_H2645_ENC_PICTURE_TYPE_I: - case PIPE_H2645_ENC_PICTURE_TYPE_IDR: - radeon_uvd_enc_code_fixed_bits(enc, 0x00, 3); - break; - case PIPE_H2645_ENC_PICTURE_TYPE_P: - radeon_uvd_enc_code_fixed_bits(enc, 0x01, 3); - break; - case PIPE_H2645_ENC_PICTURE_TYPE_B: - radeon_uvd_enc_code_fixed_bits(enc, 0x02, 3); - break; - default: - assert(0 && "Unsupported picture type!"); + radeon_bs_code_fixed_bits(&bs, 0x0, 6); /* vps_max_layer_id */ + radeon_bs_code_ue(&bs, 0x0); /* vps_num_layer_sets_minus1 */ + radeon_bs_code_fixed_bits(&bs, vps->vps_timing_info_present_flag, 1); + if (vps->vps_timing_info_present_flag) { + radeon_bs_code_fixed_bits(&bs, vps->vps_num_units_in_tick, 32); + radeon_bs_code_fixed_bits(&bs, vps->vps_time_scale, 32); + radeon_bs_code_fixed_bits(&bs, vps->vps_poc_proportional_to_timing_flag, 1); + if (vps->vps_poc_proportional_to_timing_flag) + radeon_bs_code_ue(&bs, vps->vps_num_ticks_poc_diff_one_minus1); + radeon_bs_code_ue(&bs, 0x0); /* vps_num_hrd_parameters */ } + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* vps_extension_flag */ - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); - radeon_uvd_enc_byte_align(enc); - radeon_uvd_enc_flush_headers(enc); - *size_in_bytes = (enc->bits_output + 7) / 8; + radeon_bs_flush_headers(&bs); + *size_in_bytes = bs.bits_output / 8; RADEON_ENC_END(); } static void radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc) { + struct radeon_bitstream bs; + struct pipe_h265_enc_seq_param *sps = &enc->enc_pic.desc->seq; + struct pipe_h265_enc_pic_param *pps = &enc->enc_pic.desc->pic; + struct pipe_h265_enc_slice_param *slice = &enc->enc_pic.desc->slice; uint32_t instruction[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = {0}; uint32_t num_bits[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = {0}; unsigned int inst_index = 0; - unsigned int bit_index = 0; + unsigned int cdw_start = 0; + unsigned int cdw_filled = 0; unsigned int bits_copied = 0; + unsigned int num_pic_total_curr = 0; + RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_SLICE_HEADER); - radeon_uvd_enc_reset(enc); - radeon_uvd_enc_set_emulation_prevention(enc, false); + radeon_bs_reset(&bs, NULL, &enc->cs); + radeon_bs_set_emulation_prevention(&bs, false); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.nal_unit_type, 6); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 6); - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 3); + cdw_start = enc->cs.current.cdw; + radeon_bs_code_fixed_bits(&bs, 0x0, 1); + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.nal_unit_type, 6); + radeon_bs_code_fixed_bits(&bs, 0x0, 6); + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.temporal_id + 1, 3); - radeon_uvd_enc_flush_headers(enc); - bit_index++; + radeon_bs_flush_headers(&bs); instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_COPY; - num_bits[inst_index] = enc->bits_output - bits_copied; - bits_copied = enc->bits_output; + num_bits[inst_index] = bs.bits_output - bits_copied; + bits_copied = bs.bits_output; inst_index++; instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_FIRST_SLICE; inst_index++; if ((enc->enc_pic.nal_unit_type >= 16) && (enc->enc_pic.nal_unit_type <= 23)) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); + radeon_bs_code_fixed_bits(&bs, slice->no_output_of_prior_pics_flag, 1); - radeon_uvd_enc_code_ue(enc, 0x0); + radeon_bs_code_ue(&bs, 0x0); /* slice_pic_parameter_set_id */ - radeon_uvd_enc_flush_headers(enc); - bit_index++; + radeon_bs_flush_headers(&bs); instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_COPY; - num_bits[inst_index] = enc->bits_output - bits_copied; - bits_copied = enc->bits_output; + num_bits[inst_index] = bs.bits_output - bits_copied; + bits_copied = bs.bits_output; inst_index++; instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_SLICE_SEGMENT; @@ -708,46 +552,70 @@ static void radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc) switch (enc->enc_pic.picture_type) { case PIPE_H2645_ENC_PICTURE_TYPE_I: case PIPE_H2645_ENC_PICTURE_TYPE_IDR: - radeon_uvd_enc_code_ue(enc, 0x2); + radeon_bs_code_ue(&bs, 0x2); break; case PIPE_H2645_ENC_PICTURE_TYPE_P: case PIPE_H2645_ENC_PICTURE_TYPE_SKIP: - radeon_uvd_enc_code_ue(enc, 0x1); - break; - case PIPE_H2645_ENC_PICTURE_TYPE_B: - radeon_uvd_enc_code_ue(enc, 0x0); - break; default: - radeon_uvd_enc_code_ue(enc, 0x1); + radeon_bs_code_ue(&bs, 0x1); + break; } + if (pps->output_flag_present_flag) + radeon_bs_code_fixed_bits(&bs, slice->pic_output_flag, 1); + if ((enc->enc_pic.nal_unit_type != 19) && (enc->enc_pic.nal_unit_type != 20)) { - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.pic_order_cnt, enc->enc_pic.log2_max_poc); - if (enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P) - radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1); - else { - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_ue(enc, 0x0); - radeon_uvd_enc_code_ue(enc, 0x0); + radeon_bs_code_fixed_bits(&bs, slice->slice_pic_order_cnt_lsb, sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + radeon_bs_code_fixed_bits(&bs, slice->short_term_ref_pic_set_sps_flag, 1); + if (!slice->short_term_ref_pic_set_sps_flag) { + num_pic_total_curr = + radeon_bs_hevc_st_ref_pic_set(&bs, sps->num_short_term_ref_pic_sets, + sps->num_short_term_ref_pic_sets, sps->st_ref_pic_set); + } else if (sps->num_short_term_ref_pic_sets > 1) { + radeon_bs_code_fixed_bits(&bs, slice->short_term_ref_pic_set_idx, + util_logbase2_ceil(sps->num_short_term_ref_pic_sets)); + } + if (sps->long_term_ref_pics_present_flag) { + if (sps->num_long_term_ref_pics_sps > 0) + radeon_bs_code_ue(&bs, slice->num_long_term_sps); + radeon_bs_code_ue(&bs, slice->num_long_term_pics); + for (unsigned i = 0; i < slice->num_long_term_sps + slice->num_long_term_pics; i++) { + if (i < slice->num_long_term_sps) { + if (sps->num_long_term_ref_pics_sps > 1) + radeon_bs_code_fixed_bits(&bs, slice->lt_idx_sps[i], util_logbase2_ceil(sps->num_long_term_ref_pics_sps)); + } else { + radeon_bs_code_fixed_bits(&bs, slice->poc_lsb_lt[i], sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + radeon_bs_code_fixed_bits(&bs, slice->used_by_curr_pic_lt_flag[i], 1); + if (slice->used_by_curr_pic_lt_flag[i]) + num_pic_total_curr++; + } + radeon_bs_code_fixed_bits(&bs, slice->delta_poc_msb_present_flag[i], 1); + if (slice->delta_poc_msb_present_flag[i]) + radeon_bs_code_ue(&bs, slice->delta_poc_msb_cycle_lt[i]); + } } } - if (enc->enc_pic.sample_adaptive_offset_enabled_flag) - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* slice_sao_luma_flag */ - - if ((enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P) || - (enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B)) { - radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); - radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.cabac_init_flag, 1); - radeon_uvd_enc_code_ue(enc, 5 - enc->enc_pic.max_num_merge_cand); + if (enc->enc_pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P) { + radeon_bs_code_fixed_bits(&bs, slice->num_ref_idx_active_override_flag, 1); + if (slice->num_ref_idx_active_override_flag) + radeon_bs_code_ue(&bs, slice->num_ref_idx_l0_active_minus1); + if (pps->lists_modification_present_flag && num_pic_total_curr > 1) { + unsigned num_bits = util_logbase2_ceil(num_pic_total_curr); + unsigned num_ref_l0_minus1 = slice->num_ref_idx_active_override_flag ? + slice->num_ref_idx_l0_active_minus1 : pps->num_ref_idx_l0_default_active_minus1; + radeon_bs_code_fixed_bits(&bs, slice->ref_pic_lists_modification.ref_pic_list_modification_flag_l0, 1); + for (unsigned i = 0; i <= num_ref_l0_minus1; i++) + radeon_bs_code_fixed_bits(&bs, slice->ref_pic_lists_modification.list_entry_l0[i], num_bits); + } + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.hevc_spec_misc.cabac_init_flag, 1); + radeon_bs_code_ue(&bs, 5 - slice->max_num_merge_cand); } - radeon_uvd_enc_flush_headers(enc); - bit_index++; + radeon_bs_flush_headers(&bs); instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_COPY; - num_bits[inst_index] = enc->bits_output - bits_copied; - bits_copied = enc->bits_output; + num_bits[inst_index] = bs.bits_output - bits_copied; + bits_copied = bs.bits_output; inst_index++; instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_SLICE_QP_DELTA; @@ -755,20 +623,18 @@ static void radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc) if ((enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled) && (!enc->enc_pic.hevc_deblock.deblocking_filter_disabled)) { - radeon_uvd_enc_code_fixed_bits( - enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1); - - radeon_uvd_enc_flush_headers(enc); - bit_index++; + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1); + radeon_bs_flush_headers(&bs); instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_COPY; - num_bits[inst_index] = enc->bits_output - bits_copied; - bits_copied = enc->bits_output; + num_bits[inst_index] = bs.bits_output - bits_copied; + bits_copied = bs.bits_output; inst_index++; } instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_END; - for (int i = bit_index; i < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS; i++) + cdw_filled = enc->cs.current.cdw - cdw_start; + for (int i = 0; i < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS - cdw_filled; i++) RADEON_ENC_CS(0x00000000); for (int j = 0; j < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS; j++) { @@ -792,7 +658,6 @@ static void radeon_uvd_enc_ctx(struct radeon_uvd_encoder *enc) enc->enc_pic.ctx_buf.rec_luma_pitch = enc->luma->u.gfx9.surf_pitch * enc->luma->bpe; enc->enc_pic.ctx_buf.rec_chroma_pitch = enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe; } - enc->enc_pic.ctx_buf.num_reconstructed_pictures = 2; RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_ENCODE_CONTEXT_BUFFER); RADEON_ENC_READWRITE(enc->dpb.res->buf, enc->dpb.res->domains, 0); @@ -914,13 +779,6 @@ static void radeon_uvd_enc_encode_params_hevc(struct radeon_uvd_encoder *enc) } enc->enc_pic.enc_params.input_pic_swizzle_mode = RENC_UVD_SWIZZLE_MODE_LINEAR; - if (enc->enc_pic.enc_params.pic_type == RENC_UVD_PICTURE_TYPE_I) - enc->enc_pic.enc_params.reference_picture_index = 0xFFFFFFFF; - else - enc->enc_pic.enc_params.reference_picture_index = (enc->enc_pic.frame_num - 1) % 2; - - enc->enc_pic.enc_params.reconstructed_picture_index = enc->enc_pic.frame_num % 2; - RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_ENCODE_PARAMS); RADEON_ENC_CS(enc->enc_pic.enc_params.pic_type); RADEON_ENC_CS(enc->enc_pic.enc_params.allowed_max_bitstream_size); @@ -1007,8 +865,6 @@ static void encode(struct radeon_uvd_encoder *enc) enc->total_task_size = 0; radeon_uvd_enc_task_info(enc, enc->need_feedback); - radeon_uvd_enc_nalu_aud_hevc(enc); - if (enc->enc_pic.is_iframe) { radeon_uvd_enc_nalu_vps_hevc(enc); radeon_uvd_enc_nalu_pps_hevc(enc);