1use {
2 super::errors::H264Error, super::utils, bytes::BytesMut, bytesio::bits_reader::BitsReader,
3 bytesio::bytes_reader::BytesReader, std::vec::Vec,
4};
5
6#[derive(Default, Debug)]
7pub struct Sps {
8 pub profile_idc: u8, flag: u8,
10
11 pub level_idc: u8, seq_parameter_set_id: u32, chroma_format_idc: u32, separate_colour_plane_flag: u8, bit_depth_luma_minus8: u32, bit_depth_chroma_minus8: u32, qpprime_y_zero_transform_bypass_flag: u8, seq_scaling_matrix_present_flag: u8, seq_scaling_list_present_flag: Vec<u8>, log2_max_frame_num_minus4: u32, pic_order_cnt_type: u32, log2_max_pic_order_cnt_lsb_minus4: u32, delta_pic_order_always_zero_flag: u8, offset_for_non_ref_pic: i32, offset_for_top_to_bottom_field: i32, num_ref_frames_in_pic_order_cnt_cycle: u32, offset_for_ref_frame: Vec<i32>, max_num_ref_frames: u32, gaps_in_frame_num_value_allowed_flag: u8, pic_width_in_mbs_minus1: u32, pic_height_in_map_units_minus1: u32, frame_mbs_only_flag: u8, mb_adaptive_frame_field_flag: u8, direct_8x8_inference_flag: u8, frame_cropping_flag: u8, frame_crop_left_offset: u32, frame_crop_right_offset: u32, frame_crop_top_offset: u32, frame_crop_bottom_offset: u32, vui_parameters_present_flag: u8, }
57
58pub struct SpsParser {
59 pub bytes_reader: BytesReader,
60 pub bits_reader: BitsReader,
61 pub sps: Sps,
62}
63
64impl SpsParser {
65 pub fn new(reader: BytesReader) -> SpsParser {
66 Self {
67 bytes_reader: BytesReader::new(BytesMut::new()),
68 bits_reader: BitsReader::new(reader),
69 sps: Sps::default(),
70 }
71 }
72
73 pub fn extend_data(&mut self, data: BytesMut) {
74 self.bits_reader.extend_data(data);
75 }
76
77 pub fn parse(&mut self) -> Result<(u32, u32), H264Error> {
78 self.sps.profile_idc = self.bits_reader.read_byte()?;
79 log::info!("profile_idc: {}", self.sps.profile_idc);
80 self.sps.flag = self.bits_reader.read_byte()?;
81 self.sps.level_idc = self.bits_reader.read_byte()?;
82 log::info!("level_idc: {}", self.sps.level_idc);
83 self.sps.seq_parameter_set_id = utils::read_uev(&mut self.bits_reader)?;
84
85 match self.sps.profile_idc {
86 100 | 110 | 122 | 244 | 44 | 83 | 86 | 118 | 128 => {
87 self.sps.chroma_format_idc = utils::read_uev(&mut self.bits_reader)?;
88 if self.sps.chroma_format_idc == 3 {
89 self.sps.separate_colour_plane_flag = self.bits_reader.read_bit()?;
90 }
91 self.sps.bit_depth_luma_minus8 = utils::read_uev(&mut self.bits_reader)?;
92 self.sps.bit_depth_chroma_minus8 = utils::read_uev(&mut self.bits_reader)?;
93
94 self.sps.qpprime_y_zero_transform_bypass_flag = self.bits_reader.read_bit()?;
95 self.sps.seq_scaling_matrix_present_flag = self.bits_reader.read_bit()?;
96
97 if self.sps.seq_scaling_matrix_present_flag > 0 {
98 let matrix_dim: usize = if self.sps.chroma_format_idc != 2 {
99 8
100 } else {
101 12
102 };
103
104 for _ in 0..matrix_dim {
105 self.sps
106 .seq_scaling_list_present_flag
107 .push(self.bits_reader.read_bit()?);
108 }
109 }
110 }
111 _ => {}
112 }
113
114 self.sps.log2_max_frame_num_minus4 = utils::read_uev(&mut self.bits_reader)?;
115 self.sps.pic_order_cnt_type = utils::read_uev(&mut self.bits_reader)?;
116
117 match self.sps.pic_order_cnt_type {
118 0 => {
119 self.sps.log2_max_pic_order_cnt_lsb_minus4 =
120 utils::read_uev(&mut self.bits_reader)?;
121 }
122 1 => {
123 self.sps.delta_pic_order_always_zero_flag = self.bits_reader.read_bit()?;
124 self.sps.offset_for_non_ref_pic = utils::read_sev(&mut self.bits_reader)?;
125 self.sps.offset_for_top_to_bottom_field = utils::read_sev(&mut self.bits_reader)?;
126 self.sps.num_ref_frames_in_pic_order_cnt_cycle =
127 utils::read_uev(&mut self.bits_reader)?;
128
129 for i in 0..self.sps.num_ref_frames_in_pic_order_cnt_cycle as usize {
130 self.sps.offset_for_ref_frame[i] = utils::read_sev(&mut self.bits_reader)?;
131 }
132 }
133 _ => {}
134 }
135
136 self.sps.max_num_ref_frames = utils::read_uev(&mut self.bits_reader)?;
137 self.sps.gaps_in_frame_num_value_allowed_flag = self.bits_reader.read_bit()?;
138
139 self.sps.pic_width_in_mbs_minus1 = utils::read_uev(&mut self.bits_reader)?;
140 self.sps.pic_height_in_map_units_minus1 = utils::read_uev(&mut self.bits_reader)?;
141
142 self.sps.frame_mbs_only_flag = self.bits_reader.read_bit()?;
143
144 if self.sps.frame_mbs_only_flag == 0 {
145 self.sps.mb_adaptive_frame_field_flag = self.bits_reader.read_bit()?;
146 }
147 self.sps.direct_8x8_inference_flag = self.bits_reader.read_bit()?;
148 self.sps.frame_cropping_flag = self.bits_reader.read_bit()?;
149
150 if self.sps.frame_cropping_flag > 0 {
151 self.sps.frame_crop_left_offset = utils::read_uev(&mut self.bits_reader)?;
152 self.sps.frame_crop_right_offset = utils::read_uev(&mut self.bits_reader)?;
153 self.sps.frame_crop_top_offset = utils::read_uev(&mut self.bits_reader)?;
154 self.sps.frame_crop_bottom_offset = utils::read_uev(&mut self.bits_reader)?;
155 }
156
157 self.sps.vui_parameters_present_flag = self.bits_reader.read_bit()?;
158
159 let width = (self.sps.pic_width_in_mbs_minus1 + 1) * 16
160 - self.sps.frame_crop_left_offset * 2
161 - self.sps.frame_crop_right_offset * 2;
162 let height = ((2 - self.sps.frame_mbs_only_flag as u32)
163 * (self.sps.pic_height_in_map_units_minus1 + 1)
164 * 16)
165 - (self.sps.frame_crop_top_offset * 2)
166 - (self.sps.frame_crop_bottom_offset * 2);
167
168 log::trace!("parsed sps data: {:?}", self.sps);
169 Ok((width, height))
170 }
171}