From 901aafb030fc6d483ddd0f1ac6b7e6f0d0beafd4 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Mon, 30 Dec 2024 17:39:45 +0100 Subject: [PATCH] radeonsi/vce: Support raw packed headers Same logic as VCN, but this also needs PPS/SPS encoding. Reviewed-by: Ruijing Dong Acked-by: Leo Liu Part-of: --- src/gallium/drivers/radeonsi/radeon_vce.c | 120 +++++++- src/gallium/drivers/radeonsi/radeon_vce.h | 62 +---- src/gallium/drivers/radeonsi/radeon_vce_52.c | 274 ++++++++++--------- 3 files changed, 268 insertions(+), 188 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeon_vce.c b/src/gallium/drivers/radeonsi/radeon_vce.c index cc5a15b8f04..03c71d15352 100644 --- a/src/gallium/drivers/radeonsi/radeon_vce.c +++ b/src/gallium/drivers/radeonsi/radeon_vce.c @@ -187,6 +187,79 @@ static void rvce_begin_frame(struct pipe_video_codec *encoder, struct pipe_video } } +static void *si_vce_encode_headers(struct rvce_encoder *enc) +{ + unsigned num_slices = 0, num_headers = 0; + + util_dynarray_foreach(&enc->pic.raw_headers, struct pipe_enc_raw_header, header) { + if (header->is_slice) + num_slices++; + num_headers++; + } + + if (!num_headers || !num_slices || num_headers == num_slices) + return NULL; + + size_t segments_size = + sizeof(struct rvce_output_unit_segment) * (num_headers - num_slices + 1); + struct rvce_feedback_data *data = + CALLOC_VARIANT_LENGTH_STRUCT(rvce_feedback_data, segments_size); + if (!data) + return NULL; + + uint8_t *ptr = enc->ws->buffer_map(enc->ws, enc->bs_handle, &enc->cs, + PIPE_MAP_WRITE | RADEON_MAP_TEMPORARY); + if (!ptr) { + RVID_ERR("Can't map bs buffer.\n"); + FREE(data); + return NULL; + } + + unsigned offset = 0; + struct rvce_output_unit_segment *slice_segment = NULL; + + util_dynarray_foreach(&enc->pic.raw_headers, struct pipe_enc_raw_header, header) { + if (header->is_slice) { + if (slice_segment) + continue; + slice_segment = &data->segments[data->num_segments]; + slice_segment->is_slice = true; + } else { + unsigned size; + /* Startcode may be 3 or 4 bytes. */ + const uint8_t nal_byte = header->buffer[header->buffer[2] == 0x1 ? 3 : 4]; + + switch (header->type) { + case PIPE_H264_NAL_SPS: + size = si_vce_write_sps(enc, nal_byte, ptr + offset); + break; + case PIPE_H264_NAL_PPS: + size = si_vce_write_pps(enc, nal_byte, ptr + offset); + break; + default: + assert(header->buffer); + memcpy(ptr + offset, header->buffer, header->size); + size = header->size; + break; + } + data->segments[data->num_segments].size = size; + data->segments[data->num_segments].offset = offset; + offset += size; + } + data->num_segments++; + } + + enc->bs_offset = align(offset, 16); + assert(enc->bs_offset < enc->bs_size); + + assert(slice_segment); + slice_segment->offset = enc->bs_offset; + + enc->ws->buffer_unmap(enc->ws, enc->bs_handle); + + return data; +} + static void rvce_encode_bitstream(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, struct pipe_resource *destination, void **fb) @@ -194,12 +267,16 @@ static void rvce_encode_bitstream(struct pipe_video_codec *encoder, struct rvce_encoder *enc = (struct rvce_encoder *)encoder; enc->get_buffer(destination, &enc->bs_handle, NULL); enc->bs_size = destination->width0; + enc->bs_offset = 0; *fb = enc->fb = CALLOC_STRUCT(rvid_buffer); if (!si_vid_create_buffer(enc->screen, enc->fb, 512, PIPE_USAGE_STAGING)) { RVID_ERR("Can't create feedback buffer.\n"); return; } + + enc->fb->user_data = si_vce_encode_headers(enc); + if (!radeon_emitted(&enc->cs, 0)) enc->session(enc); enc->encode(enc); @@ -222,18 +299,41 @@ static void rvce_get_feedback(struct pipe_video_codec *encoder, void *feedback, struct rvce_encoder *enc = (struct rvce_encoder *)encoder; struct rvid_buffer *fb = feedback; - if (size) { - uint32_t *ptr = enc->ws->buffer_map(enc->ws, fb->res->buf, &enc->cs, - PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY); + uint32_t *ptr = enc->ws->buffer_map(enc->ws, fb->res->buf, &enc->cs, + PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY); - if (ptr[1]) { - *size = ptr[4] - ptr[9]; - } else { - *size = 0; - } - - enc->ws->buffer_unmap(enc->ws, fb->res->buf); + if (ptr[1]) { + *size = ptr[4] - ptr[9]; + } else { + *size = 0; } + + enc->ws->buffer_unmap(enc->ws, fb->res->buf); + + metadata->present_metadata = PIPE_VIDEO_FEEDBACK_METADATA_TYPE_CODEC_UNIT_LOCATION; + + if (fb->user_data) { + struct rvce_feedback_data *data = fb->user_data; + metadata->codec_unit_metadata_count = data->num_segments; + for (unsigned i = 0; i < data->num_segments; i++) { + metadata->codec_unit_metadata[i].offset = data->segments[i].offset; + if (data->segments[i].is_slice) { + metadata->codec_unit_metadata[i].size = *size; + metadata->codec_unit_metadata[i].flags = 0; + } else { + metadata->codec_unit_metadata[i].size = data->segments[i].size; + metadata->codec_unit_metadata[i].flags = PIPE_VIDEO_CODEC_UNIT_LOCATION_FLAG_SINGLE_NALU; + } + } + FREE(fb->user_data); + fb->user_data = NULL; + } else { + metadata->codec_unit_metadata_count = 1; + metadata->codec_unit_metadata[0].offset = 0; + metadata->codec_unit_metadata[0].size = *size; + metadata->codec_unit_metadata[0].flags = 0; + } + // dump_feedback(enc, fb); si_vid_destroy_buffer(fb); FREE(fb); diff --git a/src/gallium/drivers/radeonsi/radeon_vce.h b/src/gallium/drivers/radeonsi/radeon_vce.h index 027adfe15e6..e57521b0487 100644 --- a/src/gallium/drivers/radeonsi/radeon_vce.h +++ b/src/gallium/drivers/radeonsi/radeon_vce.h @@ -157,50 +157,6 @@ struct rvce_rdo { uint32_t enc_chroma_coeff_cost; }; -struct rvce_vui { - uint32_t aspect_ratio_info_present_flag; - uint32_t aspect_ratio_idc; - uint32_t sar_width; - uint32_t sar_height; - uint32_t overscan_info_present_flag; - uint32_t overscan_Approp_flag; - uint32_t video_signal_type_present_flag; - uint32_t video_format; - uint32_t video_full_range_flag; - uint32_t color_description_present_flag; - uint32_t color_prim; - uint32_t transfer_char; - uint32_t matrix_coef; - uint32_t chroma_loc_info_present_flag; - uint32_t chroma_loc_top; - uint32_t chroma_loc_bottom; - uint32_t timing_info_present_flag; - uint32_t num_units_in_tick; - uint32_t time_scale; - uint32_t fixed_frame_rate_flag; - uint32_t nal_hrd_parameters_present_flag; - uint32_t cpb_cnt_minus1; - uint32_t bit_rate_scale; - uint32_t cpb_size_scale; - uint32_t bit_rate_value_minus; - uint32_t cpb_size_value_minus; - uint32_t cbr_flag; - uint32_t initial_cpb_removal_delay_length_minus1; - uint32_t cpb_removal_delay_length_minus1; - uint32_t dpb_output_delay_length_minus1; - uint32_t time_offset_length; - uint32_t low_delay_hrd_flag; - uint32_t pic_struct_present_flag; - uint32_t bitstream_restriction_present_flag; - uint32_t motion_vectors_over_pic_boundaries_flag; - uint32_t max_bytes_per_pic_denom; - uint32_t max_bits_per_mb_denom; - uint32_t log2_max_mv_length_hori; - uint32_t log2_max_mv_length_vert; - uint32_t num_reorder_frames; - uint32_t max_dec_frame_buffering; -}; - struct rvce_enc_operation { uint32_t insert_headers; uint32_t picture_structure; @@ -315,7 +271,6 @@ struct rvce_h264_enc_pic { struct rvce_task_info ti; struct rvce_feedback_buf_pkg fb; struct rvce_rdo rdo; - struct rvce_vui vui; struct rvce_enc_operation eo; struct rvce_enc_create ec; struct rvce_config_ext ce; @@ -337,7 +292,6 @@ struct rvce_h264_enc_pic { bool not_referenced; bool is_idr; - bool enable_vui; }; /* VCE encoder representation */ @@ -353,7 +307,6 @@ struct rvce_encoder { void (*pic_control)(struct rvce_encoder *enc); void (*motion_estimation)(struct rvce_encoder *enc); void (*rdo)(struct rvce_encoder *enc); - void (*vui)(struct rvce_encoder *enc); void (*config)(struct rvce_encoder *enc); void (*encode)(struct rvce_encoder *enc); void (*destroy)(struct rvce_encoder *enc); @@ -375,6 +328,7 @@ struct rvce_encoder { struct pb_buffer_lean *bs_handle; unsigned bs_size; + unsigned bs_offset; unsigned dpb_slots; @@ -390,6 +344,20 @@ struct rvce_encoder { bool dual_pipe; }; +struct rvce_output_unit_segment { + bool is_slice; + unsigned size; + unsigned offset; +}; + +struct rvce_feedback_data { + unsigned num_segments; + struct rvce_output_unit_segment segments[]; +}; + +unsigned int si_vce_write_sps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out); +unsigned int si_vce_write_pps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out); + /* CPB handling functions */ void si_vce_frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_offset, signed *chroma_offset); diff --git a/src/gallium/drivers/radeonsi/radeon_vce_52.c b/src/gallium/drivers/radeonsi/radeon_vce_52.c index a7c22932c15..ea2d56f4e11 100644 --- a/src/gallium/drivers/radeonsi/radeon_vce_52.c +++ b/src/gallium/drivers/radeonsi/radeon_vce_52.c @@ -9,6 +9,7 @@ #include "pipe/p_video_codec.h" #include "radeon_vce.h" #include "radeon_video.h" +#include "radeon_bitstream.h" #include "radeonsi/si_pipe.h" #include "util/u_memory.h" #include "util/u_video.h" @@ -179,63 +180,6 @@ static void get_config_ext_param(struct rvce_encoder *enc) enc->enc_pic.ce.enc_enable_perf_logging = 0x00000003; } -static void get_vui_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) -{ - pipe_h264_enc_hrd_params *hrd_params = NULL; - - if (pic->seq.vui_flags.nal_hrd_parameters_present_flag) - hrd_params = &pic->seq.nal_hrd_parameters; - else if (pic->seq.vui_flags.vcl_hrd_parameters_present_flag) - hrd_params = &pic->seq.vcl_hrd_parameters; - - enc->enc_pic.enable_vui = pic->seq.vui_parameters_present_flag; - enc->enc_pic.vui.aspect_ratio_info_present_flag = - pic->seq.vui_flags.aspect_ratio_info_present_flag; - enc->enc_pic.vui.aspect_ratio_idc = pic->seq.aspect_ratio_idc; - enc->enc_pic.vui.sar_width = pic->seq.sar_width; - enc->enc_pic.vui.sar_height = pic->seq.sar_height; - enc->enc_pic.vui.overscan_info_present_flag = pic->seq.vui_flags.overscan_info_present_flag; - enc->enc_pic.vui.overscan_Approp_flag = pic->seq.vui_flags.overscan_appropriate_flag; - enc->enc_pic.vui.video_signal_type_present_flag = - pic->seq.vui_flags.video_signal_type_present_flag; - enc->enc_pic.vui.video_format = pic->seq.video_format; - enc->enc_pic.vui.video_full_range_flag = pic->seq.video_full_range_flag; - enc->enc_pic.vui.color_description_present_flag = - pic->seq.vui_flags.colour_description_present_flag; - enc->enc_pic.vui.color_prim = pic->seq.colour_primaries; - enc->enc_pic.vui.transfer_char = pic->seq.transfer_characteristics; - enc->enc_pic.vui.matrix_coef = pic->seq.matrix_coefficients; - enc->enc_pic.vui.chroma_loc_info_present_flag = - pic->seq.vui_flags.chroma_loc_info_present_flag; - enc->enc_pic.vui.chroma_loc_top = pic->seq.chroma_sample_loc_type_top_field; - enc->enc_pic.vui.chroma_loc_bottom = pic->seq.chroma_sample_loc_type_bottom_field; - enc->enc_pic.vui.timing_info_present_flag = pic->seq.vui_flags.timing_info_present_flag; - enc->enc_pic.vui.num_units_in_tick = pic->seq.num_units_in_tick; - enc->enc_pic.vui.time_scale = pic->seq.time_scale; - enc->enc_pic.vui.fixed_frame_rate_flag = pic->seq.vui_flags.fixed_frame_rate_flag; - enc->enc_pic.vui.low_delay_hrd_flag = pic->seq.vui_flags.low_delay_hrd_flag; - if (hrd_params) { - enc->enc_pic.vui.bit_rate_scale = hrd_params->bit_rate_scale; - enc->enc_pic.vui.cpb_size_scale = hrd_params->cpb_size_scale; - enc->enc_pic.vui.initial_cpb_removal_delay_length_minus1 = - hrd_params->initial_cpb_removal_delay_length_minus1; - enc->enc_pic.vui.cpb_removal_delay_length_minus1 = hrd_params->cpb_removal_delay_length_minus1; - enc->enc_pic.vui.dpb_output_delay_length_minus1 = hrd_params->dpb_output_delay_length_minus1; - enc->enc_pic.vui.time_offset_length = hrd_params->time_offset_length; - enc->enc_pic.vui.bit_rate_value_minus = hrd_params->bit_rate_value_minus1[0]; - enc->enc_pic.vui.cpb_size_value_minus = hrd_params->bit_rate_value_minus1[0]; - enc->enc_pic.vui.cbr_flag = hrd_params->cbr_flag[0]; - } - enc->enc_pic.vui.bitstream_restriction_present_flag = pic->seq.vui_flags.bitstream_restriction_flag; - enc->enc_pic.vui.motion_vectors_over_pic_boundaries_flag = 0x00000001; - enc->enc_pic.vui.max_bytes_per_pic_denom = 0x00000002; - enc->enc_pic.vui.max_bits_per_mb_denom = 0x00000001; - enc->enc_pic.vui.log2_max_mv_length_hori = 0x00000010; - enc->enc_pic.vui.log2_max_mv_length_vert = 0x00000010; - enc->enc_pic.vui.num_reorder_frames = pic->seq.max_num_reorder_frames; - enc->enc_pic.vui.max_dec_frame_buffering = pic->seq.max_dec_frame_buffering; -} - static void get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic) { int i; @@ -245,7 +189,6 @@ static void get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_des get_pic_control_param(enc, pic); get_task_info_param(enc); get_feedback_buffer_param(enc, NULL); - get_vui_param(enc, pic); get_config_ext_param(enc); enc->enc_pic.picture_type = pic->picture_type; @@ -270,24 +213,6 @@ static void get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_des enc->enc_pic.eo.enable_intra_refresh = 0; } - enc->enc_pic.eo.insert_headers = 0; - enc->enc_pic.eo.insert_aud = 0; - util_dynarray_foreach(&pic->raw_headers, struct pipe_enc_raw_header, header) { - switch (header->type) { - case PIPE_H264_NAL_SPS: - enc->enc_pic.eo.insert_headers |= 0x01; - break; - case PIPE_H264_NAL_PPS: - enc->enc_pic.eo.insert_headers |= 0x10; - break; - case PIPE_H264_NAL_AUD: - enc->enc_pic.eo.insert_aud = 1; - break; - default: - break; - } - } - enc->enc_pic.eo.num_ref_idx_active_override_flag = pic->slice.num_ref_idx_active_override_flag; enc->enc_pic.eo.num_ref_idx_l0_active_minus1 = pic->slice.num_ref_idx_l0_active_minus1; enc->enc_pic.eo.num_ref_idx_l1_active_minus1 = pic->slice.num_ref_idx_l1_active_minus1; @@ -395,7 +320,7 @@ static void create(struct rvce_encoder *enc) static void encode(struct rvce_encoder *enc) { struct si_screen *sscreen = (struct si_screen *)enc->screen; - signed luma_offset, chroma_offset, bs_offset; + signed luma_offset, chroma_offset; unsigned bs_idx = enc->bs_idx++; int i; @@ -405,10 +330,8 @@ static void encode(struct rvce_encoder *enc) RVCE_READWRITE(enc->dpb.res->buf, enc->dpb.res->domains, 0); // encodeContextAddressHi/Lo RVCE_END(); - bs_offset = -(signed)(bs_idx * enc->bs_size); - RVCE_BEGIN(0x05000004); // video bitstream buffer - RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, bs_offset); // videoBitstreamRingAddressHi/Lo + RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, enc->bs_offset); // videoBitstreamRingAddressHi/Lo RVCE_CS(enc->bs_size); // videoBitstreamRingSize RVCE_END(); @@ -427,7 +350,7 @@ static void encode(struct rvce_encoder *enc) RVCE_BEGIN(0x03000001); // encode RVCE_CS(enc->enc_pic.eo.insert_headers); RVCE_CS(enc->enc_pic.eo.picture_structure); - RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize + RVCE_CS(enc->bs_size - enc->bs_offset); // allowedMaxBitstreamSize RVCE_CS(enc->enc_pic.eo.force_refresh_map); RVCE_CS(enc->enc_pic.eo.insert_aud); RVCE_CS(enc->enc_pic.eo.end_of_sequence); @@ -591,7 +514,6 @@ static void config(struct rvce_encoder *enc) enc->config_extension(enc); enc->motion_estimation(enc); enc->rdo(enc); - enc->vui(enc); enc->pic_control(enc); } @@ -738,58 +660,149 @@ static void task_info(struct rvce_encoder *enc, uint32_t op, uint32_t dep, uint3 RVCE_END(); } -static void vui(struct rvce_encoder *enc) +unsigned int si_vce_write_sps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out) { - int i; + struct pipe_h264_enc_seq_param *sps = &enc->pic.seq; + struct radeon_bitstream bs; - if (!enc->enc_pic.enable_vui) - return; + radeon_bs_reset(&bs, out, NULL); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, nal_byte, 8); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_fixed_bits(&bs, sps->profile_idc, 8); + radeon_bs_code_fixed_bits(&bs, sps->enc_constraint_set_flags, 6); + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* reserved_zero_2bits */ + radeon_bs_code_fixed_bits(&bs, sps->level_idc, 8); + radeon_bs_code_ue(&bs, 0x0); /* seq_parameter_set_id */ - RVCE_BEGIN(0x04000009); // vui - RVCE_CS(enc->enc_pic.vui.aspect_ratio_info_present_flag); - RVCE_CS(enc->enc_pic.vui.aspect_ratio_idc); - RVCE_CS(enc->enc_pic.vui.sar_width); - RVCE_CS(enc->enc_pic.vui.sar_height); - RVCE_CS(enc->enc_pic.vui.overscan_info_present_flag); - RVCE_CS(enc->enc_pic.vui.overscan_Approp_flag); - RVCE_CS(enc->enc_pic.vui.video_signal_type_present_flag); - RVCE_CS(enc->enc_pic.vui.video_format); - RVCE_CS(enc->enc_pic.vui.video_full_range_flag); - RVCE_CS(enc->enc_pic.vui.color_description_present_flag); - RVCE_CS(enc->enc_pic.vui.color_prim); - RVCE_CS(enc->enc_pic.vui.transfer_char); - RVCE_CS(enc->enc_pic.vui.matrix_coef); - RVCE_CS(enc->enc_pic.vui.chroma_loc_info_present_flag); - RVCE_CS(enc->enc_pic.vui.chroma_loc_top); - RVCE_CS(enc->enc_pic.vui.chroma_loc_bottom); - RVCE_CS(enc->enc_pic.vui.timing_info_present_flag); - RVCE_CS(enc->enc_pic.vui.num_units_in_tick); - RVCE_CS(enc->enc_pic.vui.time_scale); - RVCE_CS(enc->enc_pic.vui.fixed_frame_rate_flag); - RVCE_CS(enc->enc_pic.vui.nal_hrd_parameters_present_flag); - RVCE_CS(enc->enc_pic.vui.cpb_cnt_minus1); - RVCE_CS(enc->enc_pic.vui.bit_rate_scale); - RVCE_CS(enc->enc_pic.vui.cpb_size_scale); - for (i = 0; i < 32; i++) { - RVCE_CS(enc->enc_pic.vui.bit_rate_value_minus); - RVCE_CS(enc->enc_pic.vui.cpb_size_value_minus); - RVCE_CS(enc->enc_pic.vui.cbr_flag); + if (sps->profile_idc == 100 || sps->profile_idc == 110 || + sps->profile_idc == 122 || sps->profile_idc == 244 || + sps->profile_idc == 44 || sps->profile_idc == 83 || + sps->profile_idc == 86 || sps->profile_idc == 118 || + sps->profile_idc == 128 || sps->profile_idc == 138) { + radeon_bs_code_ue(&bs, 0x1); /* chroma_format_idc */ + radeon_bs_code_ue(&bs, 0x0); /* bit_depth_luma_minus8 */ + radeon_bs_code_ue(&bs, 0x0); /* bit_depth_chroma_minus8 */ + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* qpprime_y_zero_transform_bypass_flag + seq_scaling_matrix_present_flag */ } - RVCE_CS(enc->enc_pic.vui.initial_cpb_removal_delay_length_minus1); - RVCE_CS(enc->enc_pic.vui.cpb_removal_delay_length_minus1); - RVCE_CS(enc->enc_pic.vui.dpb_output_delay_length_minus1); - RVCE_CS(enc->enc_pic.vui.time_offset_length); - RVCE_CS(enc->enc_pic.vui.low_delay_hrd_flag); - RVCE_CS(enc->enc_pic.vui.pic_struct_present_flag); - RVCE_CS(enc->enc_pic.vui.bitstream_restriction_present_flag); - RVCE_CS(enc->enc_pic.vui.motion_vectors_over_pic_boundaries_flag); - RVCE_CS(enc->enc_pic.vui.max_bytes_per_pic_denom); - RVCE_CS(enc->enc_pic.vui.max_bits_per_mb_denom); - RVCE_CS(enc->enc_pic.vui.log2_max_mv_length_hori); - RVCE_CS(enc->enc_pic.vui.log2_max_mv_length_vert); - RVCE_CS(enc->enc_pic.vui.num_reorder_frames); - RVCE_CS(enc->enc_pic.vui.max_dec_frame_buffering); - RVCE_END(); + + radeon_bs_code_ue(&bs, 3); /* log2_max_frame_num_minus4 */ + radeon_bs_code_ue(&bs, sps->pic_order_cnt_type); + + if (sps->pic_order_cnt_type == 0) + radeon_bs_code_ue(&bs, sps->log2_max_pic_order_cnt_lsb_minus4); + + radeon_bs_code_ue(&bs, sps->max_num_ref_frames); + radeon_bs_code_fixed_bits(&bs, sps->gaps_in_frame_num_value_allowed_flag, 1); + radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.width, 16) - 1); + radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.height, 16) - 1); + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* frame_mbs_only_flag */ + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* direct_8x8_inference_flag */ + + radeon_bs_code_fixed_bits(&bs, sps->enc_frame_cropping_flag, 1); + if (sps->enc_frame_cropping_flag) { + radeon_bs_code_ue(&bs, sps->enc_frame_crop_left_offset); + radeon_bs_code_ue(&bs, sps->enc_frame_crop_right_offset); + radeon_bs_code_ue(&bs, sps->enc_frame_crop_top_offset); + radeon_bs_code_ue(&bs, sps->enc_frame_crop_bottom_offset); + } + + radeon_bs_code_fixed_bits(&bs, sps->vui_parameters_present_flag, 1); + if (sps->vui_parameters_present_flag) { + 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_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); + 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); + } + } + 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_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.fixed_frame_rate_flag), 1); + } + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.nal_hrd_parameters_present_flag, 1); + if (sps->vui_flags.nal_hrd_parameters_present_flag) + radeon_bs_h264_hrd_parameters(&bs, &sps->nal_hrd_parameters); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.vcl_hrd_parameters_present_flag, 1); + if (sps->vui_flags.vcl_hrd_parameters_present_flag) + radeon_bs_h264_hrd_parameters(&bs, &sps->vcl_hrd_parameters); + if (sps->vui_flags.nal_hrd_parameters_present_flag || sps->vui_flags.vcl_hrd_parameters_present_flag) + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.low_delay_hrd_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.pic_struct_present_flag, 1); + radeon_bs_code_fixed_bits(&bs, sps->vui_flags.bitstream_restriction_flag, 1); + if (sps->vui_flags.bitstream_restriction_flag) { + radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* motion_vectors_over_pic_boundaries_flag */ + radeon_bs_code_ue(&bs, 0x2); /* max_bytes_per_pic_denom */ + radeon_bs_code_ue(&bs, 0x1); /* max_bits_per_mb_denom */ + radeon_bs_code_ue(&bs, 0x10); /* log2_max_mv_length_horizontal */ + radeon_bs_code_ue(&bs, 0x10); /* log2_max_mv_length_vertical */ + radeon_bs_code_ue(&bs, sps->max_num_reorder_frames); + radeon_bs_code_ue(&bs, sps->max_dec_frame_buffering); + } + } + + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); + + return bs.bits_output / 8; +} + +unsigned int si_vce_write_pps(struct rvce_encoder *enc, uint8_t nal_byte, uint8_t *out) +{ + struct radeon_bitstream bs; + + radeon_bs_reset(&bs, out, NULL); + radeon_bs_set_emulation_prevention(&bs, false); + radeon_bs_code_fixed_bits(&bs, 0x00000001, 32); + radeon_bs_code_fixed_bits(&bs, nal_byte, 8); + radeon_bs_set_emulation_prevention(&bs, true); + radeon_bs_code_ue(&bs, 0x0); /* pic_parameter_set_id */ + radeon_bs_code_ue(&bs, 0x0); /* seq_parameter_set_id */ + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.pc.enc_cabac_enable, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* bottom_field_pic_order_in_frame_present_flag */ + radeon_bs_code_ue(&bs, 0x0); /* num_slice_groups_minus_1 */ + radeon_bs_code_ue(&bs, enc->enc_pic.pc.enc_num_default_active_ref_l0 - 1); + radeon_bs_code_ue(&bs, enc->enc_pic.pc.enc_num_default_active_ref_l1 - 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* weighted_pred_flag */ + radeon_bs_code_fixed_bits(&bs, 0x0, 2); /* weighted_bipred_idc */ + radeon_bs_code_se(&bs, 0x0); /* pic_init_qp_minus26 */ + radeon_bs_code_se(&bs, 0x0); /* pic_init_qs_minus26 */ + radeon_bs_code_se(&bs, 0x0); /* chroma_qp_index_offset */ + bool deblocking_filter_present_flag = + enc->enc_pic.pc.enc_loop_filter_disable || + enc->enc_pic.pc.enc_lf_beta_offset || + enc->enc_pic.pc.enc_lf_alpha_c0_offset; + radeon_bs_code_fixed_bits(&bs, deblocking_filter_present_flag, 1); + radeon_bs_code_fixed_bits(&bs, enc->enc_pic.pc.enc_use_constrained_intra_pred, 1); + radeon_bs_code_fixed_bits(&bs, 0x0, 1); /* redundant_pic_cnt_present_flag */ + + radeon_bs_code_fixed_bits(&bs, 0x1, 1); + radeon_bs_byte_align(&bs); + + return bs.bits_output / 8; } void si_vce_52_init(struct rvce_encoder *enc) @@ -803,7 +816,6 @@ void si_vce_52_init(struct rvce_encoder *enc) enc->pic_control = pic_control; enc->motion_estimation = motion_estimation; enc->rdo = rdo; - enc->vui = vui; enc->config = config; enc->encode = encode; enc->destroy = destroy;