use super::annexb_rw::{AnnexBBitstreamReader, AnnexBBitstreamWriter};
pub fn rewrite_sps_vui(buffer: &[u8]) -> Vec<u8> {
let mut reader = AnnexBBitstreamReader::new(&buffer[1..]);
let mut writer = AnnexBBitstreamWriter::new();
macro_rules! rb { ($n:expr) => { reader.read_bits($n) } }
macro_rules! wb { ($v:expr, $n:expr) => { writer.write_bits($v, $n) } }
macro_rules! ru { ($n:expr) => { reader.read_unsigned($n) } }
macro_rules! wu { ($v:expr, $n:expr) => { writer.write_unsigned($v, $n) } }
macro_rules! rue { () => { reader.read_ue() } }
macro_rules! wue { ($v:expr) => { writer.write_ue($v) } }
macro_rules! rse { () => { reader.read_se() } }
macro_rules! wse { ($v:expr) => { writer.write_se($v) } }
wu!(buffer[0] as u32, 8);
let profile_idc = ru!(8);
wu!(profile_idc, 8);
let constraint_flags = ru!(8);
wu!(constraint_flags, 8);
let level_idc = ru!(8);
wu!(level_idc, 8);
let seq_parameter_set_id = rue!();
wue!(seq_parameter_set_id);
const HIGH_PROFILES: &[u32] = &[100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 144];
if HIGH_PROFILES.contains(&profile_idc) {
let chroma_format_idc = rue!();
wue!(chroma_format_idc);
if chroma_format_idc == 3 {
let separate_colour_plane_flag = rb!(1);
wb!(separate_colour_plane_flag, 1);
}
let bit_depth_luma_minus8 = rue!();
wue!(bit_depth_luma_minus8);
let bit_depth_chroma_minus8 = rue!();
wue!(bit_depth_chroma_minus8);
let qpprime_y_zero_transform_bypass_flag = rb!(1);
wb!(qpprime_y_zero_transform_bypass_flag, 1);
let seq_scaling_matrix_present_flag = rb!(1);
wb!(seq_scaling_matrix_present_flag, 1);
if seq_scaling_matrix_present_flag != 0 {
let scaling_count = if chroma_format_idc != 3 { 8 } else { 12 };
for i in 0..scaling_count {
let seq_scaling_list_present_flag = rb!(1);
wb!(seq_scaling_list_present_flag, 1);
if seq_scaling_list_present_flag != 0 {
let size = if i < 6 { 16 } else { 64 };
let mut last_scale: i32 = 8;
let mut next_scale: i32 = 8;
for _ in 0..size {
let delta = rse!();
wse!(delta);
next_scale = (last_scale + delta + 256) % 256;
if next_scale != 0 {
last_scale = next_scale;
}
}
let _ = next_scale;
}
}
}
}
let log2_max_frame_num_minus4 = rue!();
wue!(log2_max_frame_num_minus4);
let pic_order_cnt_type = rue!();
wue!(pic_order_cnt_type);
if pic_order_cnt_type == 0 {
let log2_max_pic_order_cnt_lsb_minus4 = rue!();
wue!(log2_max_pic_order_cnt_lsb_minus4);
} else if pic_order_cnt_type == 1 {
let delta_pic_order_always_zero_flag = rb!(1);
wb!(delta_pic_order_always_zero_flag, 1);
let offset_for_non_ref_pic = rse!();
wse!(offset_for_non_ref_pic);
let offset_for_top_to_bottom_field = rse!();
wse!(offset_for_top_to_bottom_field);
let num_ref_frames_in_pic_order_cnt_cycle = rue!();
wue!(num_ref_frames_in_pic_order_cnt_cycle);
for _ in 0..num_ref_frames_in_pic_order_cnt_cycle {
let offset_for_ref_frame = rse!();
wse!(offset_for_ref_frame);
}
}
let max_num_ref_frames = rue!();
wue!(max_num_ref_frames);
let gaps_in_frame_num_value_allowed_flag = rb!(1);
wb!(gaps_in_frame_num_value_allowed_flag, 1);
let pic_width_in_mbs_minus1 = rue!();
wue!(pic_width_in_mbs_minus1);
let pic_height_in_map_units_minus1 = rue!();
wue!(pic_height_in_map_units_minus1);
let frame_mbs_only_flag = rb!(1);
wb!(frame_mbs_only_flag, 1);
if frame_mbs_only_flag == 0 {
let mb_adaptive_frame_field_flag = rb!(1);
wb!(mb_adaptive_frame_field_flag, 1);
}
let direct_8x8_inference_flag = rb!(1);
wb!(direct_8x8_inference_flag, 1);
let frame_cropping_flag = rb!(1);
wb!(frame_cropping_flag, 1);
if frame_cropping_flag != 0 {
let frame_crop_left_offset = rue!();
wue!(frame_crop_left_offset);
let frame_crop_right_offset = rue!();
wue!(frame_crop_right_offset);
let frame_crop_top_offset = rue!();
wue!(frame_crop_top_offset);
let frame_crop_bottom_offset = rue!();
wue!(frame_crop_bottom_offset);
}
let vui_parameters_present_flag = rb!(1);
wb!(1, 1);
if vui_parameters_present_flag == 0 {
wb!(0, 2); wb!(0, 1); wb!(0, 5); wb!(1, 1); write_bitstream_restriction(&mut writer, max_num_ref_frames);
} else {
let aspect_ratio_info_present_flag = rb!(1);
wb!(aspect_ratio_info_present_flag, 1);
if aspect_ratio_info_present_flag != 0 {
let aspect_ratio_idc = ru!(8);
wu!(aspect_ratio_idc, 8);
if aspect_ratio_idc == 255 {
let sar_width = ru!(16);
wu!(sar_width, 16);
let sar_height = ru!(16);
wu!(sar_height, 16);
}
}
let overscan_info_present_flag = rb!(1);
wb!(overscan_info_present_flag, 1);
if overscan_info_present_flag != 0 {
let overscan_appropriate_flag = rb!(1);
wb!(overscan_appropriate_flag, 1);
}
let video_signal_type_present_flag = rb!(1);
wb!(0, 1); if video_signal_type_present_flag != 0 {
let _video_format = rb!(3);
let _video_full_range_flag = rb!(1);
let colour_description_present_flag = rb!(1);
if colour_description_present_flag != 0 {
let _colour_primaries = ru!(8);
let _transfer_characteristics = ru!(8);
let _matrix_coeffs = ru!(8);
}
}
let chroma_loc_info_present_flag = rb!(1);
wb!(chroma_loc_info_present_flag, 1);
if chroma_loc_info_present_flag != 0 {
let chroma_sample_loc_type_top_field = rue!();
wue!(chroma_sample_loc_type_top_field);
let chroma_sample_loc_type_bottom_field = rue!();
wue!(chroma_sample_loc_type_bottom_field);
}
let timing_info_present_flag = rb!(1);
wb!(timing_info_present_flag, 1);
if timing_info_present_flag != 0 {
let num_units_in_tick = ru!(32);
wu!(num_units_in_tick, 32);
let time_scale = ru!(32);
wu!(time_scale, 32);
let fixed_frame_rate_flag = rb!(1);
wb!(fixed_frame_rate_flag, 1);
}
let nal_hrd_parameters_present_flag = rb!(1);
wb!(nal_hrd_parameters_present_flag, 1);
if nal_hrd_parameters_present_flag != 0 {
copy_hrd_parameters(&mut reader, &mut writer);
}
let vcl_hrd_parameters_present_flag = rb!(1);
wb!(vcl_hrd_parameters_present_flag, 1);
if vcl_hrd_parameters_present_flag != 0 {
copy_hrd_parameters(&mut reader, &mut writer);
}
if nal_hrd_parameters_present_flag != 0 || vcl_hrd_parameters_present_flag != 0 {
let low_delay_hrd_flag = rb!(1);
wb!(low_delay_hrd_flag, 1);
}
let pic_struct_present_flag = rb!(1);
wb!(pic_struct_present_flag, 1);
let bitstream_restriction_flag = rb!(1);
wb!(1, 1);
if bitstream_restriction_flag == 0 {
write_bitstream_restriction(&mut writer, max_num_ref_frames);
} else {
let motion_vectors_over_pic_boundaries_flag = rb!(1);
wb!(motion_vectors_over_pic_boundaries_flag, 1);
let max_bytes_per_pic_denom = rue!();
wue!(max_bytes_per_pic_denom);
let max_bits_per_mb_denom = rue!();
wue!(max_bits_per_mb_denom);
let log2_max_mv_length_horizontal = rue!();
wue!(log2_max_mv_length_horizontal);
let log2_max_mv_length_vertical = rue!();
wue!(log2_max_mv_length_vertical);
let _num_reorder_frames = rue!();
wue!(0); let _max_dec_frame_buffering = rue!();
wue!(max_num_ref_frames); }
}
wb!(1, 1); writer.flush_final();
writer.to_vec()
}
fn write_bitstream_restriction(writer: &mut AnnexBBitstreamWriter, max_num_ref_frames: u32) {
writer.write_bits(1, 1); writer.write_ue(2); writer.write_ue(1); writer.write_ue(16); writer.write_ue(16); writer.write_ue(0); writer.write_ue(max_num_ref_frames); }
fn copy_hrd_parameters(
reader: &mut AnnexBBitstreamReader<'_>,
writer: &mut AnnexBBitstreamWriter,
) {
let cpb_cnt_minus1 = reader.read_ue();
writer.write_ue(cpb_cnt_minus1);
let bit_rate_scale = reader.read_bits(4);
writer.write_bits(bit_rate_scale, 4);
let cpb_size_scale = reader.read_bits(4);
writer.write_bits(cpb_size_scale, 4);
for _ in 0..=cpb_cnt_minus1 {
let bit_rate_value_minus1 = reader.read_ue();
writer.write_ue(bit_rate_value_minus1);
let cpb_size_value_minus1 = reader.read_ue();
writer.write_ue(cpb_size_value_minus1);
let cbr_flag = reader.read_bits(1);
writer.write_bits(cbr_flag, 1);
}
for _ in 0..4 {
let v = reader.read_bits(5);
writer.write_bits(v, 5);
}
}