radeonsi/vce: Support raw packed headers

Same logic as VCN, but this also needs PPS/SPS encoding.

Reviewed-by: Ruijing Dong <ruijing.dong@amd.com>
Acked-by: Leo Liu <leo.liu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32829>
This commit is contained in:
David Rosca 2024-12-30 17:39:45 +01:00 committed by Marge Bot
parent f13c5fe53e
commit 901aafb030
3 changed files with 268 additions and 188 deletions

View file

@ -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, static void rvce_encode_bitstream(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source, struct pipe_video_buffer *source,
struct pipe_resource *destination, void **fb) 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; struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
enc->get_buffer(destination, &enc->bs_handle, NULL); enc->get_buffer(destination, &enc->bs_handle, NULL);
enc->bs_size = destination->width0; enc->bs_size = destination->width0;
enc->bs_offset = 0;
*fb = enc->fb = CALLOC_STRUCT(rvid_buffer); *fb = enc->fb = CALLOC_STRUCT(rvid_buffer);
if (!si_vid_create_buffer(enc->screen, enc->fb, 512, PIPE_USAGE_STAGING)) { if (!si_vid_create_buffer(enc->screen, enc->fb, 512, PIPE_USAGE_STAGING)) {
RVID_ERR("Can't create feedback buffer.\n"); RVID_ERR("Can't create feedback buffer.\n");
return; return;
} }
enc->fb->user_data = si_vce_encode_headers(enc);
if (!radeon_emitted(&enc->cs, 0)) if (!radeon_emitted(&enc->cs, 0))
enc->session(enc); enc->session(enc);
enc->encode(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 rvce_encoder *enc = (struct rvce_encoder *)encoder;
struct rvid_buffer *fb = feedback; struct rvid_buffer *fb = feedback;
if (size) { uint32_t *ptr = enc->ws->buffer_map(enc->ws, fb->res->buf, &enc->cs,
uint32_t *ptr = enc->ws->buffer_map(enc->ws, fb->res->buf, &enc->cs, PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY);
PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY);
if (ptr[1]) { if (ptr[1]) {
*size = ptr[4] - ptr[9]; *size = ptr[4] - ptr[9];
} else { } else {
*size = 0; *size = 0;
}
enc->ws->buffer_unmap(enc->ws, fb->res->buf);
} }
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); // dump_feedback(enc, fb);
si_vid_destroy_buffer(fb); si_vid_destroy_buffer(fb);
FREE(fb); FREE(fb);

View file

@ -157,50 +157,6 @@ struct rvce_rdo {
uint32_t enc_chroma_coeff_cost; 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 { struct rvce_enc_operation {
uint32_t insert_headers; uint32_t insert_headers;
uint32_t picture_structure; uint32_t picture_structure;
@ -315,7 +271,6 @@ struct rvce_h264_enc_pic {
struct rvce_task_info ti; struct rvce_task_info ti;
struct rvce_feedback_buf_pkg fb; struct rvce_feedback_buf_pkg fb;
struct rvce_rdo rdo; struct rvce_rdo rdo;
struct rvce_vui vui;
struct rvce_enc_operation eo; struct rvce_enc_operation eo;
struct rvce_enc_create ec; struct rvce_enc_create ec;
struct rvce_config_ext ce; struct rvce_config_ext ce;
@ -337,7 +292,6 @@ struct rvce_h264_enc_pic {
bool not_referenced; bool not_referenced;
bool is_idr; bool is_idr;
bool enable_vui;
}; };
/* VCE encoder representation */ /* VCE encoder representation */
@ -353,7 +307,6 @@ struct rvce_encoder {
void (*pic_control)(struct rvce_encoder *enc); void (*pic_control)(struct rvce_encoder *enc);
void (*motion_estimation)(struct rvce_encoder *enc); void (*motion_estimation)(struct rvce_encoder *enc);
void (*rdo)(struct rvce_encoder *enc); void (*rdo)(struct rvce_encoder *enc);
void (*vui)(struct rvce_encoder *enc);
void (*config)(struct rvce_encoder *enc); void (*config)(struct rvce_encoder *enc);
void (*encode)(struct rvce_encoder *enc); void (*encode)(struct rvce_encoder *enc);
void (*destroy)(struct rvce_encoder *enc); void (*destroy)(struct rvce_encoder *enc);
@ -375,6 +328,7 @@ struct rvce_encoder {
struct pb_buffer_lean *bs_handle; struct pb_buffer_lean *bs_handle;
unsigned bs_size; unsigned bs_size;
unsigned bs_offset;
unsigned dpb_slots; unsigned dpb_slots;
@ -390,6 +344,20 @@ struct rvce_encoder {
bool dual_pipe; 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 */ /* CPB handling functions */
void si_vce_frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_offset, void si_vce_frame_offset(struct rvce_encoder *enc, unsigned slot, signed *luma_offset,
signed *chroma_offset); signed *chroma_offset);

View file

@ -9,6 +9,7 @@
#include "pipe/p_video_codec.h" #include "pipe/p_video_codec.h"
#include "radeon_vce.h" #include "radeon_vce.h"
#include "radeon_video.h" #include "radeon_video.h"
#include "radeon_bitstream.h"
#include "radeonsi/si_pipe.h" #include "radeonsi/si_pipe.h"
#include "util/u_memory.h" #include "util/u_memory.h"
#include "util/u_video.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; 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) static void get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
{ {
int i; 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_pic_control_param(enc, pic);
get_task_info_param(enc); get_task_info_param(enc);
get_feedback_buffer_param(enc, NULL); get_feedback_buffer_param(enc, NULL);
get_vui_param(enc, pic);
get_config_ext_param(enc); get_config_ext_param(enc);
enc->enc_pic.picture_type = pic->picture_type; 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.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_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_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; 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) static void encode(struct rvce_encoder *enc)
{ {
struct si_screen *sscreen = (struct si_screen *)enc->screen; 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++; unsigned bs_idx = enc->bs_idx++;
int i; 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_READWRITE(enc->dpb.res->buf, enc->dpb.res->domains, 0); // encodeContextAddressHi/Lo
RVCE_END(); RVCE_END();
bs_offset = -(signed)(bs_idx * enc->bs_size);
RVCE_BEGIN(0x05000004); // video bitstream buffer 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_CS(enc->bs_size); // videoBitstreamRingSize
RVCE_END(); RVCE_END();
@ -427,7 +350,7 @@ static void encode(struct rvce_encoder *enc)
RVCE_BEGIN(0x03000001); // encode RVCE_BEGIN(0x03000001); // encode
RVCE_CS(enc->enc_pic.eo.insert_headers); RVCE_CS(enc->enc_pic.eo.insert_headers);
RVCE_CS(enc->enc_pic.eo.picture_structure); 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.force_refresh_map);
RVCE_CS(enc->enc_pic.eo.insert_aud); RVCE_CS(enc->enc_pic.eo.insert_aud);
RVCE_CS(enc->enc_pic.eo.end_of_sequence); 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->config_extension(enc);
enc->motion_estimation(enc); enc->motion_estimation(enc);
enc->rdo(enc); enc->rdo(enc);
enc->vui(enc);
enc->pic_control(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(); 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) radeon_bs_reset(&bs, out, NULL);
return; 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 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
RVCE_CS(enc->enc_pic.vui.aspect_ratio_info_present_flag); sps->profile_idc == 122 || sps->profile_idc == 244 ||
RVCE_CS(enc->enc_pic.vui.aspect_ratio_idc); sps->profile_idc == 44 || sps->profile_idc == 83 ||
RVCE_CS(enc->enc_pic.vui.sar_width); sps->profile_idc == 86 || sps->profile_idc == 118 ||
RVCE_CS(enc->enc_pic.vui.sar_height); sps->profile_idc == 128 || sps->profile_idc == 138) {
RVCE_CS(enc->enc_pic.vui.overscan_info_present_flag); radeon_bs_code_ue(&bs, 0x1); /* chroma_format_idc */
RVCE_CS(enc->enc_pic.vui.overscan_Approp_flag); radeon_bs_code_ue(&bs, 0x0); /* bit_depth_luma_minus8 */
RVCE_CS(enc->enc_pic.vui.video_signal_type_present_flag); radeon_bs_code_ue(&bs, 0x0); /* bit_depth_chroma_minus8 */
RVCE_CS(enc->enc_pic.vui.video_format); 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.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);
} }
RVCE_CS(enc->enc_pic.vui.initial_cpb_removal_delay_length_minus1);
RVCE_CS(enc->enc_pic.vui.cpb_removal_delay_length_minus1); radeon_bs_code_ue(&bs, 3); /* log2_max_frame_num_minus4 */
RVCE_CS(enc->enc_pic.vui.dpb_output_delay_length_minus1); radeon_bs_code_ue(&bs, sps->pic_order_cnt_type);
RVCE_CS(enc->enc_pic.vui.time_offset_length);
RVCE_CS(enc->enc_pic.vui.low_delay_hrd_flag); if (sps->pic_order_cnt_type == 0)
RVCE_CS(enc->enc_pic.vui.pic_struct_present_flag); radeon_bs_code_ue(&bs, sps->log2_max_pic_order_cnt_lsb_minus4);
RVCE_CS(enc->enc_pic.vui.bitstream_restriction_present_flag);
RVCE_CS(enc->enc_pic.vui.motion_vectors_over_pic_boundaries_flag); radeon_bs_code_ue(&bs, sps->max_num_ref_frames);
RVCE_CS(enc->enc_pic.vui.max_bytes_per_pic_denom); radeon_bs_code_fixed_bits(&bs, sps->gaps_in_frame_num_value_allowed_flag, 1);
RVCE_CS(enc->enc_pic.vui.max_bits_per_mb_denom); radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.width, 16) - 1);
RVCE_CS(enc->enc_pic.vui.log2_max_mv_length_hori); radeon_bs_code_ue(&bs, DIV_ROUND_UP(enc->base.height, 16) - 1);
RVCE_CS(enc->enc_pic.vui.log2_max_mv_length_vert); radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* frame_mbs_only_flag */
RVCE_CS(enc->enc_pic.vui.num_reorder_frames); radeon_bs_code_fixed_bits(&bs, 0x1, 1); /* direct_8x8_inference_flag */
RVCE_CS(enc->enc_pic.vui.max_dec_frame_buffering);
RVCE_END(); 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) 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->pic_control = pic_control;
enc->motion_estimation = motion_estimation; enc->motion_estimation = motion_estimation;
enc->rdo = rdo; enc->rdo = rdo;
enc->vui = vui;
enc->config = config; enc->config = config;
enc->encode = encode; enc->encode = encode;
enc->destroy = destroy; enc->destroy = destroy;