1use crate::DecodeError;
7#[allow(unused_imports)]
8use alloc::borrow::ToOwned;
9#[allow(unused_imports)]
10use alloc::boxed::Box;
11#[allow(unused_imports)]
12use alloc::format;
13#[allow(unused_imports)]
14use alloc::string::{String, ToString};
15#[allow(unused_imports)]
16use alloc::vec;
17#[allow(unused_imports)]
18use alloc::vec::Vec;
19use rusty_h264_common::BitReader;
20
21const HIGH_PROFILE_IDCS: &[u8] = &[100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135];
26
27const MAX_FRAME_MBS: u64 = 36_864 * 4;
31
32pub(crate) const DEFAULT_4X4_INTRA: [u8; 16] = [
34 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42,
35];
36pub(crate) const DEFAULT_4X4_INTER: [u8; 16] = [
37 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34,
38];
39pub(crate) const DEFAULT_8X8_INTRA: [u8; 64] = [
41 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25,
42 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
43 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
44];
45pub(crate) const DEFAULT_8X8_INTER: [u8; 64] = [
46 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22,
47 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
48 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
49];
50
51fn parse_scaling_list(r: &mut BitReader, out: &mut [u8], size: usize) -> Result<bool, DecodeError> {
55 let mut last_scale = 8i32;
56 let mut next_scale = 8i32;
57 let mut use_default = false;
58 for (j, slot) in out.iter_mut().enumerate().take(size) {
59 if next_scale != 0 {
60 let delta = r.read_se()?;
61 next_scale = (last_scale + delta + 256).rem_euclid(256);
62 if j == 0 && next_scale == 0 {
63 use_default = true;
64 }
65 }
66 let v = if next_scale == 0 {
67 last_scale
68 } else {
69 next_scale
70 };
71 *slot = v as u8;
72 last_scale = v;
73 }
74 Ok(use_default)
75}
76
77#[derive(Debug, Clone)]
79pub struct Sps {
80 pub profile_idc: u8,
81 pub level_idc: u8,
82 pub seq_parameter_set_id: u32,
83 pub log2_max_frame_num: u32,
84 pub pic_order_cnt_type: u32,
85 pub log2_max_pic_order_cnt_lsb: u32,
86 pub delta_pic_order_always_zero: bool,
88 pub gaps_in_frame_num_allowed: bool,
91 pub direct_8x8_inference: bool,
94 pub max_num_ref_frames: u32,
95 pub pic_width_in_mbs: usize,
96 pub pic_height_in_mbs: usize,
97 pub frame_crop_left: u32,
98 pub frame_crop_right: u32,
99 pub frame_crop_top: u32,
100 pub frame_crop_bottom: u32,
101 pub chroma_format_idc: u32,
103 pub scaling_4x4: [[u8; 16]; 6],
106 pub scaling_8x8: [[u8; 64]; 2],
107 pub has_scaling: bool,
109 pub transform_bypass: bool,
113 pub frame_mbs_only: bool,
117}
118
119impl Sps {
120 pub fn coded_width(&self) -> usize {
122 self.pic_width_in_mbs * 16
123 }
124 pub fn coded_height(&self) -> usize {
125 self.pic_height_in_mbs * 16
126 }
127
128 pub fn display_width(&self) -> usize {
130 self.coded_width() - 2 * (self.frame_crop_left + self.frame_crop_right) as usize
131 }
132 pub fn display_height(&self) -> usize {
134 self.coded_height()
135 - self.crop_unit_y() * (self.frame_crop_top + self.frame_crop_bottom) as usize
136 }
137
138 pub fn crop_unit_y(&self) -> usize {
140 if self.frame_mbs_only {
141 2
142 } else {
143 4
144 }
145 }
146
147 pub fn parse(rbsp: &[u8]) -> Result<Self, DecodeError> {
150 let mut r = BitReader::new(rbsp);
151 let profile_idc = r.read_bits(8)? as u8;
152 let _constraints = r.read_bits(8)?;
153 let level_idc = r.read_bits(8)? as u8;
154 let seq_parameter_set_id = r.read_ue()?;
155 let mut chroma_format_idc = 1u32;
159 let mut transform_bypass = false;
160 let mut scaling_4x4 = [[16u8; 16]; 6];
161 let mut scaling_8x8 = [[16u8; 64]; 2];
162 let mut has_scaling = false;
163 if HIGH_PROFILE_IDCS.contains(&profile_idc) {
164 chroma_format_idc = r.read_ue()?;
165 if chroma_format_idc == 3 {
166 let _separate_colour_plane = r.read_bit()?;
167 }
168 if chroma_format_idc != 1 {
169 return Err(DecodeError::Unsupported("non-4:2:0 chroma"));
170 }
171 if r.read_ue()? != 0 || r.read_ue()? != 0 {
172 return Err(DecodeError::Unsupported("bit depth > 8"));
173 }
174 transform_bypass = r.read_bit()?;
175 if r.read_bit()? {
176 has_scaling = true;
180 for i in 0..8 {
181 let present = r.read_bit()?;
182 if i < 6 {
183 if present {
184 let dflt = parse_scaling_list(&mut r, &mut scaling_4x4[i], 16)?;
185 if dflt {
186 scaling_4x4[i] = if i < 3 {
187 DEFAULT_4X4_INTRA
188 } else {
189 DEFAULT_4X4_INTER
190 };
191 }
192 } else {
193 scaling_4x4[i] = match i {
194 0 => DEFAULT_4X4_INTRA,
195 3 => DEFAULT_4X4_INTER,
196 _ => *scaling_4x4.get(i - 1).unwrap_or(&DEFAULT_4X4_INTRA),
198 };
199 }
200 } else if present {
201 let dflt = parse_scaling_list(&mut r, &mut scaling_8x8[i - 6], 64)?;
202 if dflt {
203 scaling_8x8[i - 6] = if i == 6 {
204 DEFAULT_8X8_INTRA
205 } else {
206 DEFAULT_8X8_INTER
207 };
208 }
209 } else {
210 scaling_8x8[i - 6] = if i == 6 {
211 DEFAULT_8X8_INTRA
212 } else {
213 DEFAULT_8X8_INTER
214 };
215 }
216 }
217 }
218 }
219 let log2_max_frame_num = r.read_ue()? + 4;
224 if log2_max_frame_num > 16 {
225 return Err(DecodeError::Unsupported("invalid log2_max_frame_num"));
226 }
227 let pic_order_cnt_type = r.read_ue()?;
228 let mut log2_max_pic_order_cnt_lsb = 0;
229 let mut delta_pic_order_always_zero = false;
230 if pic_order_cnt_type == 0 {
231 log2_max_pic_order_cnt_lsb = r.read_ue()? + 4;
232 if log2_max_pic_order_cnt_lsb > 16 {
233 return Err(DecodeError::Unsupported(
234 "invalid log2_max_pic_order_cnt_lsb",
235 ));
236 }
237 } else if pic_order_cnt_type == 1 {
238 delta_pic_order_always_zero = r.read_bit()?;
243 let _offset_for_non_ref_pic = r.read_se()?;
244 let _offset_for_top_to_bottom = r.read_se()?;
245 let n = r.read_ue()?;
246 if n > 255 {
247 return Err(DecodeError::Unsupported("oversized poc cycle"));
248 }
249 for _ in 0..n {
250 let _offset = r.read_se()?;
251 }
252 } else if pic_order_cnt_type != 2 {
253 return Err(DecodeError::Unsupported("invalid pic_order_cnt_type"));
254 }
255 let max_num_ref_frames = r.read_ue()?;
256 let gaps_in_frame_num_allowed = r.read_bit()?;
257 let pic_width_in_mbs = (r.read_ue()? as u64 + 1) as usize;
258 let pic_height_in_map_units = r.read_ue()? as u64 + 1;
259 let frame_mbs_only_flag = r.read_bit()?;
260 let pic_height_in_mbs = if frame_mbs_only_flag {
262 pic_height_in_map_units
263 } else {
264 2 * pic_height_in_map_units
265 };
266 if (pic_width_in_mbs as u64) * pic_height_in_mbs > MAX_FRAME_MBS {
268 return Err(DecodeError::Unsupported("frame too large"));
269 }
270 let pic_height_in_mbs = pic_height_in_mbs as usize;
271 if !frame_mbs_only_flag && r.read_bit()? {
276 return Err(DecodeError::Unsupported("interlace / field coding (MBAFF)"));
277 }
278 let crop_unit_y = if frame_mbs_only_flag { 2 } else { 4 };
279 let direct_8x8_inference = r.read_bit()?;
280 let cropping = r.read_bit()?;
281 let (mut cl, mut cr, mut ct, mut cb) = (0, 0, 0, 0);
282 if cropping {
283 cl = r.read_ue()?;
284 cr = r.read_ue()?;
285 ct = r.read_ue()?;
286 cb = r.read_ue()?;
287 if (cl + cr) as usize * 2 >= pic_width_in_mbs * 16
290 || (ct + cb) as usize * crop_unit_y >= pic_height_in_mbs * 16
291 {
292 return Err(DecodeError::Unsupported("crop exceeds frame"));
293 }
294 }
295 Ok(Self {
297 profile_idc,
298 level_idc,
299 seq_parameter_set_id,
300 log2_max_frame_num,
301 pic_order_cnt_type,
302 log2_max_pic_order_cnt_lsb,
303 delta_pic_order_always_zero,
304 gaps_in_frame_num_allowed,
305 direct_8x8_inference,
306 max_num_ref_frames,
307 pic_width_in_mbs,
308 pic_height_in_mbs,
309 frame_crop_left: cl,
310 frame_crop_right: cr,
311 frame_crop_top: ct,
312 frame_crop_bottom: cb,
313 chroma_format_idc,
314 scaling_4x4,
315 scaling_8x8,
316 has_scaling,
317 transform_bypass,
318 frame_mbs_only: frame_mbs_only_flag,
319 })
320 }
321}
322
323#[derive(Debug, Clone)]
325pub struct Pps {
326 pub pic_parameter_set_id: u32,
327 pub seq_parameter_set_id: u32,
328 pub entropy_coding_mode_flag: bool,
329 pub bottom_field_pic_order_present: bool,
332 pub num_ref_idx_l0_default: u32,
333 pub num_ref_idx_l1_default: u32,
334 pub weighted_pred: bool,
335 pub weighted_bipred_idc: u8,
336 pub pic_init_qp: i32,
337 pub chroma_qp_index_offset: i32,
339 pub deblocking_filter_control_present_flag: bool,
340 pub constrained_intra_pred_flag: bool,
341 pub redundant_pic_cnt_present_flag: bool,
342 pub transform_8x8_mode_flag: bool,
345 pub second_chroma_qp_index_offset: i32,
348 pub pic_scaling_matrix_present: bool,
351 pub scaling_4x4: [[u8; 16]; 6],
355 pub scaling_8x8: [[u8; 64]; 2],
356 pub scaling_present_4x4: [bool; 6],
357 pub scaling_present_8x8: [bool; 2],
358}
359
360impl Pps {
361 pub fn parse(rbsp: &[u8]) -> Result<Self, DecodeError> {
363 let mut r = BitReader::new(rbsp);
364 let pic_parameter_set_id = r.read_ue()?;
365 let seq_parameter_set_id = r.read_ue()?;
366 let entropy_coding_mode_flag = r.read_bit()?;
367 let bottom_field_pic_order_present = r.read_bit()?;
368 let num_slice_groups_minus1 = r.read_ue()?;
369 if num_slice_groups_minus1 != 0 {
370 return Err(DecodeError::Unsupported("slice groups (FMO)"));
373 }
374 let num_ref_idx_l0_default = r.read_ue()? + 1;
375 let num_ref_idx_l1_default = r.read_ue()? + 1;
376 let weighted_pred = r.read_bit()?;
377 let weighted_bipred_idc = r.read_bits(2)? as u8;
378 let pic_init_qp = 26 + r.read_se()?;
379 let _pic_init_qs = r.read_se()?;
380 let chroma_qp_index_offset = r.read_se()?;
381 let deblocking_filter_control_present_flag = r.read_bit()?;
382 let constrained_intra_pred_flag = r.read_bit()?;
383 let redundant_pic_cnt_present_flag = r.read_bit()?;
384 let mut transform_8x8_mode_flag = false;
386 let mut second_chroma_qp_index_offset = chroma_qp_index_offset;
387 let mut pic_scaling_matrix_present = false;
388 let mut scaling_4x4 = [[16u8; 16]; 6];
389 let mut scaling_8x8 = [[16u8; 64]; 2];
390 let mut scaling_present_4x4 = [false; 6];
391 let mut scaling_present_8x8 = [false; 2];
392 if r.more_rbsp_data() {
393 transform_8x8_mode_flag = r.read_bit()?;
394 if r.read_bit()? {
395 pic_scaling_matrix_present = true;
399 let n = 6 + if transform_8x8_mode_flag { 2 } else { 0 };
400 for i in 0..n {
401 let present = r.read_bit()?;
402 if i < 6 {
403 scaling_present_4x4[i] = present;
404 if present {
405 let dflt = parse_scaling_list(&mut r, &mut scaling_4x4[i], 16)?;
406 if dflt {
407 scaling_4x4[i] = if i < 3 {
408 DEFAULT_4X4_INTRA
409 } else {
410 DEFAULT_4X4_INTER
411 };
412 }
413 }
414 } else {
415 scaling_present_8x8[i - 6] = present;
416 if present {
417 let dflt = parse_scaling_list(&mut r, &mut scaling_8x8[i - 6], 64)?;
418 if dflt {
419 scaling_8x8[i - 6] = if i == 6 {
420 DEFAULT_8X8_INTRA
421 } else {
422 DEFAULT_8X8_INTER
423 };
424 }
425 }
426 }
427 }
428 }
429 second_chroma_qp_index_offset = r.read_se()?;
430 }
431 Ok(Self {
432 pic_parameter_set_id,
433 seq_parameter_set_id,
434 entropy_coding_mode_flag,
435 bottom_field_pic_order_present,
436 num_ref_idx_l0_default,
437 num_ref_idx_l1_default,
438 weighted_pred,
439 weighted_bipred_idc,
440 pic_init_qp,
441 chroma_qp_index_offset,
442 deblocking_filter_control_present_flag,
443 constrained_intra_pred_flag,
444 redundant_pic_cnt_present_flag,
445 transform_8x8_mode_flag,
446 second_chroma_qp_index_offset,
447 pic_scaling_matrix_present,
448 scaling_4x4,
449 scaling_8x8,
450 scaling_present_4x4,
451 scaling_present_8x8,
452 })
453 }
454}