1use crate::DecodeError;
7use rusty_h264_common::BitReader;
8
9const HIGH_PROFILE_IDCS: &[u8] = &[
14 100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135,
15];
16
17const MAX_FRAME_MBS: u64 = 36_864 * 4;
21
22pub(crate) const DEFAULT_4X4_INTRA: [u8; 16] =
24 [6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42];
25pub(crate) const DEFAULT_4X4_INTER: [u8; 16] =
26 [10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34];
27pub(crate) const DEFAULT_8X8_INTRA: [u8; 64] = [
29 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25,
30 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
31 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
32];
33pub(crate) const DEFAULT_8X8_INTER: [u8; 64] = [
34 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22,
35 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
36 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
37];
38
39fn parse_scaling_list(r: &mut BitReader, out: &mut [u8], size: usize) -> Result<bool, DecodeError> {
43 let mut last_scale = 8i32;
44 let mut next_scale = 8i32;
45 let mut use_default = false;
46 for (j, slot) in out.iter_mut().enumerate().take(size) {
47 if next_scale != 0 {
48 let delta = r.read_se()?;
49 next_scale = (last_scale + delta + 256).rem_euclid(256);
50 if j == 0 && next_scale == 0 {
51 use_default = true;
52 }
53 }
54 let v = if next_scale == 0 { last_scale } else { next_scale };
55 *slot = v as u8;
56 last_scale = v;
57 }
58 Ok(use_default)
59}
60
61#[derive(Debug, Clone)]
63pub struct Sps {
64 pub profile_idc: u8,
65 pub level_idc: u8,
66 pub seq_parameter_set_id: u32,
67 pub log2_max_frame_num: u32,
68 pub pic_order_cnt_type: u32,
69 pub log2_max_pic_order_cnt_lsb: u32,
70 pub delta_pic_order_always_zero: bool,
72 pub gaps_in_frame_num_allowed: bool,
75 pub direct_8x8_inference: bool,
78 pub max_num_ref_frames: u32,
79 pub pic_width_in_mbs: usize,
80 pub pic_height_in_mbs: usize,
81 pub frame_crop_left: u32,
82 pub frame_crop_right: u32,
83 pub frame_crop_top: u32,
84 pub frame_crop_bottom: u32,
85 pub chroma_format_idc: u32,
87 pub scaling_4x4: [[u8; 16]; 6],
90 pub scaling_8x8: [[u8; 64]; 2],
91 pub has_scaling: bool,
93 pub transform_bypass: bool,
97}
98
99impl Sps {
100 pub fn coded_width(&self) -> usize {
102 self.pic_width_in_mbs * 16
103 }
104 pub fn coded_height(&self) -> usize {
105 self.pic_height_in_mbs * 16
106 }
107
108 pub fn display_width(&self) -> usize {
110 self.coded_width() - 2 * (self.frame_crop_left + self.frame_crop_right) as usize
111 }
112 pub fn display_height(&self) -> usize {
114 self.coded_height() - 2 * (self.frame_crop_top + self.frame_crop_bottom) as usize
115 }
116
117 pub fn parse(rbsp: &[u8]) -> Result<Self, DecodeError> {
120 let mut r = BitReader::new(rbsp);
121 let profile_idc = r.read_bits(8)? as u8;
122 let _constraints = r.read_bits(8)?;
123 let level_idc = r.read_bits(8)? as u8;
124 let seq_parameter_set_id = r.read_ue()?;
125 let mut chroma_format_idc = 1u32;
129 let mut transform_bypass = false;
130 let mut scaling_4x4 = [[16u8; 16]; 6];
131 let mut scaling_8x8 = [[16u8; 64]; 2];
132 let mut has_scaling = false;
133 if HIGH_PROFILE_IDCS.contains(&profile_idc) {
134 chroma_format_idc = r.read_ue()?;
135 if chroma_format_idc == 3 {
136 let _separate_colour_plane = r.read_bit()?;
137 }
138 if chroma_format_idc != 1 {
139 return Err(DecodeError::Unsupported("non-4:2:0 chroma"));
140 }
141 if r.read_ue()? != 0 || r.read_ue()? != 0 {
142 return Err(DecodeError::Unsupported("bit depth > 8"));
143 }
144 transform_bypass = r.read_bit()?;
145 if r.read_bit()? {
146 has_scaling = true;
150 for i in 0..8 {
151 let present = r.read_bit()?;
152 if i < 6 {
153 if present {
154 let dflt = parse_scaling_list(&mut r, &mut scaling_4x4[i], 16)?;
155 if dflt {
156 scaling_4x4[i] = if i < 3 { DEFAULT_4X4_INTRA } else { DEFAULT_4X4_INTER };
157 }
158 } else {
159 scaling_4x4[i] = match i {
160 0 => DEFAULT_4X4_INTRA,
161 3 => DEFAULT_4X4_INTER,
162 _ => *scaling_4x4.get(i - 1).unwrap_or(&DEFAULT_4X4_INTRA),
164 };
165 }
166 } else if present {
167 let dflt = parse_scaling_list(&mut r, &mut scaling_8x8[i - 6], 64)?;
168 if dflt {
169 scaling_8x8[i - 6] = if i == 6 { DEFAULT_8X8_INTRA } else { DEFAULT_8X8_INTER };
170 }
171 } else {
172 scaling_8x8[i - 6] = if i == 6 { DEFAULT_8X8_INTRA } else { DEFAULT_8X8_INTER };
173 }
174 }
175 }
176 }
177 let log2_max_frame_num = r.read_ue()? + 4;
182 if log2_max_frame_num > 16 {
183 return Err(DecodeError::Unsupported("invalid log2_max_frame_num"));
184 }
185 let pic_order_cnt_type = r.read_ue()?;
186 let mut log2_max_pic_order_cnt_lsb = 0;
187 let mut delta_pic_order_always_zero = false;
188 if pic_order_cnt_type == 0 {
189 log2_max_pic_order_cnt_lsb = r.read_ue()? + 4;
190 if log2_max_pic_order_cnt_lsb > 16 {
191 return Err(DecodeError::Unsupported("invalid log2_max_pic_order_cnt_lsb"));
192 }
193 } else if pic_order_cnt_type == 1 {
194 delta_pic_order_always_zero = r.read_bit()?;
199 let _offset_for_non_ref_pic = r.read_se()?;
200 let _offset_for_top_to_bottom = r.read_se()?;
201 let n = r.read_ue()?;
202 if n > 255 {
203 return Err(DecodeError::Unsupported("oversized poc cycle"));
204 }
205 for _ in 0..n {
206 let _offset = r.read_se()?;
207 }
208 } else if pic_order_cnt_type != 2 {
209 return Err(DecodeError::Unsupported("invalid pic_order_cnt_type"));
210 }
211 let max_num_ref_frames = r.read_ue()?;
212 let gaps_in_frame_num_allowed = r.read_bit()?;
213 let pic_width_in_mbs = (r.read_ue()? as u64 + 1) as usize;
214 let pic_height_in_mbs = (r.read_ue()? as u64 + 1) as usize;
215 if (pic_width_in_mbs as u64) * (pic_height_in_mbs as u64) > MAX_FRAME_MBS {
217 return Err(DecodeError::Unsupported("frame too large"));
218 }
219 let frame_mbs_only_flag = r.read_bit()?;
220 if !frame_mbs_only_flag {
221 return Err(DecodeError::Unsupported("interlace / field coding"));
222 }
223 let direct_8x8_inference = r.read_bit()?;
224 let cropping = r.read_bit()?;
225 let (mut cl, mut cr, mut ct, mut cb) = (0, 0, 0, 0);
226 if cropping {
227 cl = r.read_ue()?;
228 cr = r.read_ue()?;
229 ct = r.read_ue()?;
230 cb = r.read_ue()?;
231 if (cl + cr) as usize * 2 >= pic_width_in_mbs * 16
234 || (ct + cb) as usize * 2 >= pic_height_in_mbs * 16
235 {
236 return Err(DecodeError::Unsupported("crop exceeds frame"));
237 }
238 }
239 Ok(Self {
241 profile_idc,
242 level_idc,
243 seq_parameter_set_id,
244 log2_max_frame_num,
245 pic_order_cnt_type,
246 log2_max_pic_order_cnt_lsb,
247 delta_pic_order_always_zero,
248 gaps_in_frame_num_allowed,
249 direct_8x8_inference,
250 max_num_ref_frames,
251 pic_width_in_mbs,
252 pic_height_in_mbs,
253 frame_crop_left: cl,
254 frame_crop_right: cr,
255 frame_crop_top: ct,
256 frame_crop_bottom: cb,
257 chroma_format_idc,
258 scaling_4x4,
259 scaling_8x8,
260 has_scaling,
261 transform_bypass,
262 })
263 }
264}
265
266#[derive(Debug, Clone)]
268pub struct Pps {
269 pub pic_parameter_set_id: u32,
270 pub seq_parameter_set_id: u32,
271 pub entropy_coding_mode_flag: bool,
272 pub bottom_field_pic_order_present: bool,
275 pub num_ref_idx_l0_default: u32,
276 pub num_ref_idx_l1_default: u32,
277 pub weighted_pred: bool,
278 pub weighted_bipred_idc: u8,
279 pub pic_init_qp: i32,
280 pub chroma_qp_index_offset: i32,
282 pub deblocking_filter_control_present_flag: bool,
283 pub constrained_intra_pred_flag: bool,
284 pub redundant_pic_cnt_present_flag: bool,
285 pub transform_8x8_mode_flag: bool,
288 pub second_chroma_qp_index_offset: i32,
291 pub pic_scaling_matrix_present: bool,
294 pub scaling_4x4: [[u8; 16]; 6],
298 pub scaling_8x8: [[u8; 64]; 2],
299 pub scaling_present_4x4: [bool; 6],
300 pub scaling_present_8x8: [bool; 2],
301}
302
303impl Pps {
304 pub fn parse(rbsp: &[u8]) -> Result<Self, DecodeError> {
306 let mut r = BitReader::new(rbsp);
307 let pic_parameter_set_id = r.read_ue()?;
308 let seq_parameter_set_id = r.read_ue()?;
309 let entropy_coding_mode_flag = r.read_bit()?;
310 let bottom_field_pic_order_present = r.read_bit()?;
311 let num_slice_groups_minus1 = r.read_ue()?;
312 if num_slice_groups_minus1 != 0 {
313 return Err(DecodeError::Unsupported("slice groups (FMO)"));
316 }
317 let num_ref_idx_l0_default = r.read_ue()? + 1;
318 let num_ref_idx_l1_default = r.read_ue()? + 1;
319 let weighted_pred = r.read_bit()?;
320 let weighted_bipred_idc = r.read_bits(2)? as u8;
321 let pic_init_qp = 26 + r.read_se()?;
322 let _pic_init_qs = r.read_se()?;
323 let chroma_qp_index_offset = r.read_se()?;
324 let deblocking_filter_control_present_flag = r.read_bit()?;
325 let constrained_intra_pred_flag = r.read_bit()?;
326 let redundant_pic_cnt_present_flag = r.read_bit()?;
327 let mut transform_8x8_mode_flag = false;
329 let mut second_chroma_qp_index_offset = chroma_qp_index_offset;
330 let mut pic_scaling_matrix_present = false;
331 let mut scaling_4x4 = [[16u8; 16]; 6];
332 let mut scaling_8x8 = [[16u8; 64]; 2];
333 let mut scaling_present_4x4 = [false; 6];
334 let mut scaling_present_8x8 = [false; 2];
335 if r.more_rbsp_data() {
336 transform_8x8_mode_flag = r.read_bit()?;
337 if r.read_bit()? {
338 pic_scaling_matrix_present = true;
342 let n = 6 + if transform_8x8_mode_flag { 2 } else { 0 };
343 for i in 0..n {
344 let present = r.read_bit()?;
345 if i < 6 {
346 scaling_present_4x4[i] = present;
347 if present {
348 let dflt = parse_scaling_list(&mut r, &mut scaling_4x4[i], 16)?;
349 if dflt {
350 scaling_4x4[i] =
351 if i < 3 { DEFAULT_4X4_INTRA } else { DEFAULT_4X4_INTER };
352 }
353 }
354 } else {
355 scaling_present_8x8[i - 6] = present;
356 if present {
357 let dflt = parse_scaling_list(&mut r, &mut scaling_8x8[i - 6], 64)?;
358 if dflt {
359 scaling_8x8[i - 6] =
360 if i == 6 { DEFAULT_8X8_INTRA } else { DEFAULT_8X8_INTER };
361 }
362 }
363 }
364 }
365 }
366 second_chroma_qp_index_offset = r.read_se()?;
367 }
368 Ok(Self {
369 pic_parameter_set_id,
370 seq_parameter_set_id,
371 entropy_coding_mode_flag,
372 bottom_field_pic_order_present,
373 num_ref_idx_l0_default,
374 num_ref_idx_l1_default,
375 weighted_pred,
376 weighted_bipred_idc,
377 pic_init_qp,
378 chroma_qp_index_offset,
379 deblocking_filter_control_present_flag,
380 constrained_intra_pred_flag,
381 redundant_pic_cnt_present_flag,
382 transform_8x8_mode_flag,
383 second_chroma_qp_index_offset,
384 pic_scaling_matrix_present,
385 scaling_4x4,
386 scaling_8x8,
387 scaling_present_4x4,
388 scaling_present_8x8,
389 })
390 }
391}