1#![allow(dead_code)]
7
8use std::collections::BTreeMap;
9use std::io::Cursor;
10use std::io::Read;
11use std::io::Seek;
12use std::io::SeekFrom;
13use std::rc::Rc;
14
15use crate::bitstream_utils::BitReader;
16use crate::codec::h264::nalu;
17use crate::codec::h264::nalu::Header;
18use crate::codec::h264::picture::Field;
19
20pub type Nalu<'a> = nalu::Nalu<'a, NaluHeader>;
21
22pub(super) const DEFAULT_4X4_INTRA: [u8; 16] =
23 [6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42];
24
25pub(super) const DEFAULT_4X4_INTER: [u8; 16] =
26 [10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34];
27
28pub(super) 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];
33
34pub(super) const DEFAULT_8X8_INTER: [u8; 64] = [
35 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22,
36 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
37 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
38];
39
40const MAX_PPS_COUNT: u16 = 256;
41const MAX_SPS_COUNT: u8 = 32;
42
43const DPB_MAX_SIZE: usize = 16;
45
46#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
47pub struct Point<T> {
48 pub x: T,
49 pub y: T,
50}
51
52#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
53pub struct Rect<T> {
54 pub min: Point<T>,
55 pub max: Point<T>,
56}
57
58#[derive(Debug, PartialEq, Eq, Clone, Copy)]
59pub enum NaluType {
60 Unknown = 0,
61 Slice = 1,
62 SliceDpa = 2,
63 SliceDpb = 3,
64 SliceDpc = 4,
65 SliceIdr = 5,
66 Sei = 6,
67 Sps = 7,
68 Pps = 8,
69 AuDelimiter = 9,
70 SeqEnd = 10,
71 StreamEnd = 11,
72 FillerData = 12,
73 SpsExt = 13,
74 PrefixUnit = 14,
75 SubsetSps = 15,
76 DepthSps = 16,
77 SliceAux = 19,
78 SliceExt = 20,
79 SliceDepth = 21,
80}
81
82impl TryFrom<u8> for NaluType {
83 type Error = String;
84
85 fn try_from(value: u8) -> Result<Self, Self::Error> {
86 match value {
87 0 => Ok(NaluType::Unknown),
88 1 => Ok(NaluType::Slice),
89 2 => Ok(NaluType::SliceDpa),
90 3 => Ok(NaluType::SliceDpb),
91 4 => Ok(NaluType::SliceDpc),
92 5 => Ok(NaluType::SliceIdr),
93 6 => Ok(NaluType::Sei),
94 7 => Ok(NaluType::Sps),
95 8 => Ok(NaluType::Pps),
96 9 => Ok(NaluType::AuDelimiter),
97 10 => Ok(NaluType::SeqEnd),
98 11 => Ok(NaluType::StreamEnd),
99 12 => Ok(NaluType::FillerData),
100 13 => Ok(NaluType::SpsExt),
101 14 => Ok(NaluType::PrefixUnit),
102 15 => Ok(NaluType::SubsetSps),
103 16 => Ok(NaluType::DepthSps),
104 19 => Ok(NaluType::SliceAux),
105 20 => Ok(NaluType::SliceExt),
106 21 => Ok(NaluType::SliceDepth),
107 _ => Err(format!("Invalid NaluType {}", value)),
108 }
109 }
110}
111
112#[derive(Clone, Debug, Default, PartialEq, Eq)]
113pub struct RefPicListModification {
114 pub modification_of_pic_nums_idc: u8,
115 pub abs_diff_pic_num_minus1: u32,
117 pub long_term_pic_num: u32,
119 pub abs_diff_view_idx_minus1: u32,
121}
122
123#[derive(Clone, Debug, Default, PartialEq, Eq)]
124pub struct PredWeightTable {
125 pub luma_log2_weight_denom: u8,
126 pub chroma_log2_weight_denom: u8,
127
128 pub luma_weight_l0: [i16; 32],
129 pub luma_offset_l0: [i8; 32],
130
131 pub chroma_weight_l0: [[i16; 2]; 32],
133 pub chroma_offset_l0: [[i8; 2]; 32],
134
135 pub luma_weight_l1: [i16; 32],
137 pub luma_offset_l1: [i16; 32],
138
139 pub chroma_weight_l1: [[i16; 2]; 32],
141 pub chroma_offset_l1: [[i8; 2]; 32],
142}
143
144#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
151pub enum MaxLongTermFrameIdx {
152 #[default]
153 NoLongTermFrameIndices,
154 Idx(u32),
155}
156
157impl MaxLongTermFrameIdx {
158 pub fn from_value_plus1(max_long_term_frame_idx_plus1: u32) -> Self {
160 match max_long_term_frame_idx_plus1 {
161 0 => Self::NoLongTermFrameIndices,
162 i @ 1.. => Self::Idx(i - 1),
163 }
164 }
165
166 pub fn to_value_plus1(self) -> u32 {
168 match self {
169 Self::NoLongTermFrameIndices => 0,
170 Self::Idx(i) => i + 1,
171 }
172 }
173}
174
175impl PartialEq<u32> for MaxLongTermFrameIdx {
176 fn eq(&self, other: &u32) -> bool {
177 match self {
178 MaxLongTermFrameIdx::NoLongTermFrameIndices => false,
179 MaxLongTermFrameIdx::Idx(idx) => idx.eq(other),
180 }
181 }
182}
183
184impl PartialOrd<u32> for MaxLongTermFrameIdx {
185 fn partial_cmp(&self, other: &u32) -> Option<std::cmp::Ordering> {
186 match self {
187 MaxLongTermFrameIdx::NoLongTermFrameIndices => Some(std::cmp::Ordering::Less),
188 MaxLongTermFrameIdx::Idx(idx) => Some(idx.cmp(other)),
189 }
190 }
191}
192
193#[derive(Clone, Debug, Default, PartialEq, Eq)]
194pub struct RefPicMarkingInner {
195 pub memory_management_control_operation: u8,
202
203 pub difference_of_pic_nums_minus1: u32,
207
208 pub long_term_pic_num: u32,
211
212 pub long_term_frame_idx: u32,
215
216 pub max_long_term_frame_idx: MaxLongTermFrameIdx,
220}
221
222#[derive(Clone, Debug, Default, PartialEq, Eq)]
223pub struct RefPicMarking {
224 pub no_output_of_prior_pics_flag: bool,
227
228 pub long_term_reference_flag: bool,
235
236 pub adaptive_ref_pic_marking_mode_flag: bool,
239
240 pub inner: Vec<RefPicMarkingInner>,
242}
243
244#[derive(Clone, Debug, Default, PartialEq, Eq)]
245pub struct SliceHeader {
246 pub first_mb_in_slice: u32,
248
249 pub slice_type: SliceType,
251
252 pub pic_parameter_set_id: u8,
254
255 pub colour_plane_id: u8,
258
259 pub frame_num: u16,
262
263 pub field_pic_flag: bool,
266
267 pub bottom_field_flag: bool,
270
271 pub idr_pic_id: u16,
277
278 pub pic_order_cnt_lsb: u16,
283
284 pub delta_pic_order_cnt_bottom: i32,
287
288 pub delta_pic_order_cnt: [i32; 2],
294
295 pub pic_order_cnt_bit_size: usize,
298
299 pub redundant_pic_cnt: u8,
304
305 pub direct_spatial_mv_pred_flag: bool,
308
309 pub num_ref_idx_active_override_flag: bool,
315
316 pub num_ref_idx_l0_active_minus1: u8,
319
320 pub num_ref_idx_l1_active_minus1: u8,
323
324 pub ref_pic_list_modification_flag_l0: bool,
328
329 pub ref_pic_list_modification_l0: Vec<RefPicListModification>,
332
333 pub ref_pic_list_modification_flag_l1: bool,
337
338 pub ref_pic_list_modification_l1: Vec<RefPicListModification>,
341
342 pub pred_weight_table: PredWeightTable,
344
345 pub dec_ref_pic_marking: RefPicMarking,
347
348 pub dec_ref_pic_marking_bit_size: usize,
351
352 pub cabac_init_idc: u8,
355
356 pub slice_qp_delta: i8,
361
362 pub sp_for_switch_flag: bool,
365
366 pub slice_qs_delta: i8,
369
370 pub disable_deblocking_filter_idc: u8,
374
375 pub slice_alpha_c0_offset_div2: i8,
380
381 pub slice_beta_offset_div2: i8,
386
387 pub max_pic_num: u32,
389
390 pub header_bit_size: usize,
392
393 pub n_emulation_prevention_bytes: usize,
395}
396
397impl SliceHeader {
398 pub fn field(&self) -> Field {
400 if self.field_pic_flag {
401 if self.bottom_field_flag {
402 Field::Bottom
403 } else {
404 Field::Top
405 }
406 } else {
407 Field::Frame
408 }
409 }
410}
411
412pub struct SliceHeaderBuilder(SliceHeader);
413
414impl SliceHeaderBuilder {
415 pub fn new(pps: &Pps) -> Self {
416 SliceHeaderBuilder(SliceHeader {
417 pic_parameter_set_id: pps.pic_parameter_set_id,
418 ..Default::default()
419 })
420 }
421
422 pub fn slice_type(mut self, type_: SliceType) -> Self {
423 self.0.slice_type = type_;
424 self
425 }
426
427 pub fn first_mb_in_slice(mut self, value: u32) -> Self {
428 self.0.first_mb_in_slice = value;
429 self
430 }
431
432 pub fn pic_order_cnt_lsb(mut self, value: u16) -> Self {
433 self.0.pic_order_cnt_lsb = value;
434 self
435 }
436
437 pub fn idr_pic_id(mut self, value: u16) -> Self {
438 self.0.idr_pic_id = value;
439 self
440 }
441
442 pub fn num_ref_idx_active_override_flag(mut self, value: bool) -> Self {
443 self.0.num_ref_idx_active_override_flag = value;
444 self
445 }
446
447 pub fn num_ref_idx_l0_active_minus1(mut self, value: u8) -> Self {
448 self = self.num_ref_idx_active_override_flag(true);
449 self.0.num_ref_idx_l0_active_minus1 = value;
450 self
451 }
452
453 pub fn num_ref_idx_l0_active(self, value: u8) -> Self {
454 self.num_ref_idx_l0_active_minus1(value - 1)
455 }
456
457 pub fn num_ref_idx_l1_active_minus1(mut self, value: u8) -> Self {
458 self = self.num_ref_idx_active_override_flag(true);
459 self.0.num_ref_idx_l1_active_minus1 = value;
460 self
461 }
462
463 pub fn num_ref_idx_l1_active(self, value: u8) -> Self {
464 self.num_ref_idx_l1_active_minus1(value - 1)
465 }
466
467 pub fn build(self) -> SliceHeader {
468 self.0
469 }
470}
471
472pub struct Slice<'a> {
475 pub header: SliceHeader,
477 pub nalu: Nalu<'a>,
479}
480
481#[derive(Clone, Copy, Debug, PartialEq, Eq)]
482pub enum SliceType {
484 P = 0,
485 B = 1,
486 I = 2,
487 Sp = 3,
488 Si = 4,
489}
490
491impl TryFrom<u8> for SliceType {
492 type Error = String;
493
494 fn try_from(value: u8) -> Result<Self, Self::Error> {
495 match value {
496 0 => Ok(SliceType::P),
497 1 => Ok(SliceType::B),
498 2 => Ok(SliceType::I),
499 3 => Ok(SliceType::Sp),
500 4 => Ok(SliceType::Si),
501 _ => Err(format!("Invalid SliceType {}", value)),
502 }
503 }
504}
505
506impl SliceType {
507 pub fn is_p(&self) -> bool {
509 matches!(self, SliceType::P)
510 }
511
512 pub fn is_b(&self) -> bool {
514 matches!(self, SliceType::B)
515 }
516
517 pub fn is_i(&self) -> bool {
519 matches!(self, SliceType::I)
520 }
521
522 pub fn is_sp(&self) -> bool {
524 matches!(self, SliceType::Sp)
525 }
526
527 pub fn is_si(&self) -> bool {
529 matches!(self, SliceType::Si)
530 }
531}
532
533impl Default for SliceType {
534 fn default() -> Self {
535 Self::P
536 }
537}
538
539#[derive(Clone, Copy)]
540#[repr(u8)]
541pub enum Profile {
542 Baseline = 66,
543 Main = 77,
544 Extended = 88,
545 High = 100,
546 High10 = 110,
547 High422P = 122,
548}
549
550impl TryFrom<u8> for Profile {
551 type Error = String;
552
553 fn try_from(value: u8) -> Result<Self, Self::Error> {
554 match value {
555 66 => Ok(Profile::Baseline),
556 77 => Ok(Profile::Main),
557 88 => Ok(Profile::Extended),
558 100 => Ok(Profile::High),
559 110 => Ok(Profile::High10),
560 122 => Ok(Profile::High422P),
561 _ => Err(format!("Invalid Profile {}", value)),
562 }
563 }
564}
565
566#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
567pub enum Level {
568 #[default]
569 L1 = 10,
570 L1B = 9,
571 L1_1 = 11,
572 L1_2 = 12,
573 L1_3 = 13,
574 L2_0 = 20,
575 L2_1 = 21,
576 L2_2 = 22,
577 L3 = 30,
578 L3_1 = 31,
579 L3_2 = 32,
580 L4 = 40,
581 L4_1 = 41,
582 L4_2 = 42,
583 L5 = 50,
584 L5_1 = 51,
585 L5_2 = 52,
586 L6 = 60,
587 L6_1 = 61,
588 L6_2 = 62,
589}
590
591impl TryFrom<u8> for Level {
592 type Error = String;
593
594 fn try_from(value: u8) -> Result<Self, Self::Error> {
595 match value {
596 10 => Ok(Level::L1),
597 9 => Ok(Level::L1B),
598 11 => Ok(Level::L1_1),
599 12 => Ok(Level::L1_2),
600 13 => Ok(Level::L1_3),
601 20 => Ok(Level::L2_0),
602 21 => Ok(Level::L2_1),
603 22 => Ok(Level::L2_2),
604 30 => Ok(Level::L3),
605 31 => Ok(Level::L3_1),
606 32 => Ok(Level::L3_2),
607 40 => Ok(Level::L4),
608 41 => Ok(Level::L4_1),
609 42 => Ok(Level::L4_2),
610 50 => Ok(Level::L5),
611 51 => Ok(Level::L5_1),
612 52 => Ok(Level::L5_2),
613 60 => Ok(Level::L6),
614 61 => Ok(Level::L6_1),
615 62 => Ok(Level::L6_2),
616 _ => Err(format!("Invalid Level {}", value)),
617 }
618 }
619}
620
621#[derive(Debug, PartialEq, Eq)]
627pub struct Sps {
628 pub seq_parameter_set_id: u8,
631
632 pub profile_idc: u8,
634
635 pub constraint_set0_flag: bool,
637 pub constraint_set1_flag: bool,
639 pub constraint_set2_flag: bool,
641 pub constraint_set3_flag: bool,
643 pub constraint_set4_flag: bool,
645 pub constraint_set5_flag: bool,
647
648 pub level_idc: Level,
650
651 pub chroma_format_idc: u8,
654
655 pub separate_colour_plane_flag: bool,
658
659 pub bit_depth_luma_minus8: u8,
663
664 pub bit_depth_chroma_minus8: u8,
668
669 pub qpprime_y_zero_transform_bypass_flag: bool,
679
680 pub seq_scaling_matrix_present_flag: bool,
684
685 pub scaling_lists_4x4: [[u8; 16]; 6],
687 pub scaling_lists_8x8: [[u8; 64]; 6],
689
690 pub log2_max_frame_num_minus4: u8,
694
695 pub pic_order_cnt_type: u8,
698
699 pub log2_max_pic_order_cnt_lsb_minus4: u8,
704
705 pub delta_pic_order_always_zero_flag: bool,
712
713 pub offset_for_non_ref_pic: i32,
716
717 pub offset_for_top_to_bottom_field: i32,
720
721 pub num_ref_frames_in_pic_order_cnt_cycle: u8,
724
725 pub offset_for_ref_frame: [i32; 255],
729
730 pub max_num_ref_frames: u8,
737
738 pub gaps_in_frame_num_value_allowed_flag: bool,
742
743 pub pic_width_in_mbs_minus1: u16,
746 pub pic_height_in_map_units_minus1: u16,
749
750 pub frame_mbs_only_flag: bool,
755
756 pub mb_adaptive_frame_field_flag: bool,
760
761 pub direct_8x8_inference_flag: bool,
765
766 pub frame_cropping_flag: bool,
770
771 pub frame_crop_left_offset: u32,
775 pub frame_crop_right_offset: u32,
779 pub frame_crop_top_offset: u32,
783 pub frame_crop_bottom_offset: u32,
787
788 pub expected_delta_per_pic_order_cnt_cycle: i32,
791
792 pub vui_parameters_present_flag: bool,
793 pub vui_parameters: VuiParams,
794}
795
796impl Sps {
797 pub const fn width(&self) -> u32 {
801 (self.pic_width_in_mbs_minus1 as u32 + 1) * 16
802 }
803
804 pub const fn height(&self) -> u32 {
808 (self.pic_height_in_map_units_minus1 as u32 + 1)
809 * 16
810 * (2 - self.frame_mbs_only_flag as u32)
811 }
812
813 pub const fn chroma_array_type(&self) -> u8 {
815 match self.separate_colour_plane_flag {
816 false => self.chroma_format_idc,
817 true => 0,
818 }
819 }
820
821 fn sub_width_height_c(&self) -> (u32, u32) {
825 match (self.chroma_format_idc, self.separate_colour_plane_flag) {
826 (1, false) => (2, 2),
827 (2, false) => (2, 1),
828 (3, false) => (1, 1),
829 _ => (1, 1),
831 }
832 }
833
834 fn crop_unit_x_y(&self) -> (u32, u32) {
838 match self.chroma_array_type() {
839 0 => (1, 2 - u32::from(self.frame_mbs_only_flag)),
840 _ => {
841 let (sub_width_c, sub_height_c) = self.sub_width_height_c();
842 (sub_width_c, sub_height_c * (2 - u32::from(self.frame_mbs_only_flag)))
843 }
844 }
845 }
846
847 pub fn max_frame_num(&self) -> u32 {
849 1 << (self.log2_max_frame_num_minus4 + 4)
850 }
851
852 pub fn visible_rectangle(&self) -> Rect<u32> {
853 if !self.frame_cropping_flag {
854 return Rect {
855 min: Point { x: 0, y: 0 },
856 max: Point { x: self.width(), y: self.height() },
857 };
858 }
859
860 let (crop_unit_x, crop_unit_y) = self.crop_unit_x_y();
861
862 let crop_left = crop_unit_x * self.frame_crop_left_offset;
863 let crop_right = crop_unit_x * self.frame_crop_right_offset;
864 let crop_top = crop_unit_y * self.frame_crop_top_offset;
865 let crop_bottom = crop_unit_y * self.frame_crop_bottom_offset;
866
867 Rect {
868 min: Point { x: crop_left, y: crop_top },
869 max: Point {
870 x: self.width() - crop_left - crop_right,
871 y: self.height() - crop_top - crop_bottom,
872 },
873 }
874 }
875
876 pub fn max_dpb_frames(&self) -> usize {
877 let profile = self.profile_idc;
878 let mut level = self.level_idc;
879
880 if matches!(level, Level::L1_1)
883 && (profile == Profile::Baseline as u8 || profile == Profile::Main as u8)
884 && self.constraint_set3_flag
885 {
886 level = Level::L1B;
887 };
888
889 let max_dpb_mbs = match level {
891 Level::L1 => 396,
892 Level::L1B => 396,
893 Level::L1_1 => 900,
894 Level::L1_2 => 2376,
895 Level::L1_3 => 2376,
896 Level::L2_0 => 2376,
897 Level::L2_1 => 4752,
898 Level::L2_2 => 8100,
899 Level::L3 => 8100,
900 Level::L3_1 => 18000,
901 Level::L3_2 => 20480,
902 Level::L4 => 32768,
903 Level::L4_1 => 32768,
904 Level::L4_2 => 34816,
905 Level::L5 => 110400,
906 Level::L5_1 => 184320,
907 Level::L5_2 => 184320,
908 Level::L6 => 696320,
909 Level::L6_1 => 696320,
910 Level::L6_2 => 696320,
911 };
912
913 let width_mb = self.width() / 16;
914 let height_mb = self.height() / 16;
915
916 let max_dpb_frames =
917 std::cmp::min(max_dpb_mbs / (width_mb * height_mb), DPB_MAX_SIZE as u32) as usize;
918
919 let mut max_dpb_frames = std::cmp::max(max_dpb_frames, self.max_num_ref_frames as usize);
920
921 if self.vui_parameters_present_flag && self.vui_parameters.bitstream_restriction_flag {
922 max_dpb_frames = std::cmp::max(1, self.vui_parameters.max_dec_frame_buffering as usize);
923 }
924
925 max_dpb_frames
926 }
927
928 pub fn max_num_order_frames(&self) -> u32 {
929 let vui = &self.vui_parameters;
930 let present = self.vui_parameters_present_flag && vui.bitstream_restriction_flag;
931
932 if present {
933 vui.max_num_reorder_frames
934 } else {
935 let profile = self.profile_idc;
936 if (profile == 44
937 || profile == 86
938 || profile == 100
939 || profile == 110
940 || profile == 122
941 || profile == 244)
942 && self.constraint_set3_flag
943 {
944 0
945 } else {
946 self.max_dpb_frames() as u32
947 }
948 }
949 }
950}
951
952impl Default for Sps {
954 fn default() -> Self {
955 Self {
956 scaling_lists_4x4: [[0; 16]; 6],
957 scaling_lists_8x8: [[0; 64]; 6],
958 offset_for_ref_frame: [0; 255],
959 seq_parameter_set_id: Default::default(),
960 profile_idc: Default::default(),
961 constraint_set0_flag: Default::default(),
962 constraint_set1_flag: Default::default(),
963 constraint_set2_flag: Default::default(),
964 constraint_set3_flag: Default::default(),
965 constraint_set4_flag: Default::default(),
966 constraint_set5_flag: Default::default(),
967 level_idc: Default::default(),
968 chroma_format_idc: Default::default(),
969 separate_colour_plane_flag: Default::default(),
970 bit_depth_luma_minus8: Default::default(),
971 bit_depth_chroma_minus8: Default::default(),
972 qpprime_y_zero_transform_bypass_flag: Default::default(),
973 seq_scaling_matrix_present_flag: Default::default(),
974 log2_max_frame_num_minus4: Default::default(),
975 pic_order_cnt_type: Default::default(),
976 log2_max_pic_order_cnt_lsb_minus4: Default::default(),
977 delta_pic_order_always_zero_flag: Default::default(),
978 offset_for_non_ref_pic: Default::default(),
979 offset_for_top_to_bottom_field: Default::default(),
980 num_ref_frames_in_pic_order_cnt_cycle: Default::default(),
981 max_num_ref_frames: Default::default(),
982 gaps_in_frame_num_value_allowed_flag: Default::default(),
983 pic_width_in_mbs_minus1: Default::default(),
984 pic_height_in_map_units_minus1: Default::default(),
985 frame_mbs_only_flag: Default::default(),
986 mb_adaptive_frame_field_flag: Default::default(),
987 direct_8x8_inference_flag: Default::default(),
988 frame_cropping_flag: Default::default(),
989 frame_crop_left_offset: Default::default(),
990 frame_crop_right_offset: Default::default(),
991 frame_crop_top_offset: Default::default(),
992 frame_crop_bottom_offset: Default::default(),
993 expected_delta_per_pic_order_cnt_cycle: Default::default(),
994 vui_parameters_present_flag: Default::default(),
995 vui_parameters: Default::default(),
996 }
997 }
998}
999
1000#[derive(Default)]
1001pub struct SpsBuilder(Sps);
1002
1003impl SpsBuilder {
1004 pub fn new() -> Self {
1005 Default::default()
1006 }
1007
1008 pub fn seq_parameter_set_id(mut self, value: u8) -> Self {
1009 self.0.seq_parameter_set_id = value;
1010 self
1011 }
1012
1013 pub fn profile_idc(mut self, value: Profile) -> Self {
1014 self.0.profile_idc = value as u8;
1015 self
1016 }
1017
1018 pub fn level_idc(mut self, value: Level) -> Self {
1019 self.0.level_idc = value;
1020 self
1021 }
1022
1023 pub fn frame_crop_offsets(mut self, top: u32, bottom: u32, left: u32, right: u32) -> Self {
1024 self.0.frame_cropping_flag = true;
1025 self.0.frame_crop_top_offset = top;
1026 self.0.frame_crop_bottom_offset = bottom;
1027 self.0.frame_crop_left_offset = left;
1028 self.0.frame_crop_right_offset = right;
1029 self
1030 }
1031
1032 pub fn frame_crop(self, top: u32, bottom: u32, left: u32, right: u32) -> Self {
1033 let sub_width_c = if self.0.chroma_format_idc > 2 { 1 } else { 2 };
1034 let sub_height_c = if self.0.chroma_format_idc > 1 { 1 } else { 2 };
1035
1036 let crop_unit_x = sub_width_c;
1037 let crop_unit_y = sub_height_c * (if self.0.frame_mbs_only_flag { 1 } else { 2 });
1038
1039 self.frame_crop_offsets(
1040 top / crop_unit_y,
1041 bottom / crop_unit_y,
1042 left / crop_unit_x,
1043 right / crop_unit_x,
1044 )
1045 }
1046
1047 pub fn resolution(mut self, width: u32, height: u32) -> Self {
1048 const MB_SIZE: u32 = 16;
1049
1050 let mb_width = (width + MB_SIZE - 1) / MB_SIZE;
1051 let mb_height = (height + MB_SIZE - 1) / MB_SIZE;
1052
1053 self.0.pic_width_in_mbs_minus1 = (mb_width - 1) as u16;
1054 self.0.pic_height_in_map_units_minus1 = (mb_height - 1) as u16;
1055
1056 let compressed_width = mb_width * MB_SIZE;
1057 let compressed_height = mb_height * MB_SIZE;
1058
1059 if compressed_width != width || compressed_height != height {
1060 self = self.frame_crop(0, compressed_height - height, 0, compressed_width - width);
1061 }
1062
1063 self
1064 }
1065
1066 pub fn chroma_format_idc(mut self, value: u8) -> Self {
1067 self.0.chroma_format_idc = value;
1068 self
1069 }
1070
1071 pub fn max_num_ref_frames(mut self, value: u8) -> Self {
1072 self.0.max_num_ref_frames = value;
1073 self
1074 }
1075
1076 pub fn frame_mbs_only_flag(mut self, value: bool) -> Self {
1077 self.0.frame_mbs_only_flag = value;
1078 self
1079 }
1080
1081 pub fn mb_adaptive_frame_field_flag(mut self, value: bool) -> Self {
1082 self.0.mb_adaptive_frame_field_flag = value;
1083 self
1084 }
1085
1086 pub fn seq_scaling_matrix_present_flag(mut self, value: bool) -> Self {
1087 self.0.seq_scaling_matrix_present_flag = value;
1088 self
1089 }
1090
1091 pub fn direct_8x8_inference_flag(mut self, value: bool) -> Self {
1092 self.0.direct_8x8_inference_flag = value;
1093 self
1094 }
1095
1096 pub fn vui_parameters_present(mut self) -> Self {
1097 if self.0.vui_parameters_present_flag {
1098 return self;
1099 }
1100
1101 self.0.vui_parameters_present_flag = true;
1102 self.0.vui_parameters.aspect_ratio_info_present_flag = false;
1104 self.0.vui_parameters.overscan_info_present_flag = false;
1105 self.0.vui_parameters.video_signal_type_present_flag = false;
1106 self.0.vui_parameters.colour_description_present_flag = false;
1107 self.0.vui_parameters.chroma_loc_info_present_flag = false;
1108 self.0.vui_parameters.timing_info_present_flag = false;
1109 self.0.vui_parameters.nal_hrd_parameters_present_flag = false;
1110 self.0.vui_parameters.vcl_hrd_parameters_present_flag = false;
1111 self.0.vui_parameters.pic_struct_present_flag = false;
1112 self.0.vui_parameters.bitstream_restriction_flag = false;
1113 self
1114 }
1115
1116 pub fn aspect_ratio_idc(mut self, value: u8) -> Self {
1117 self = self.vui_parameters_present();
1118 self.0.vui_parameters.aspect_ratio_info_present_flag = true;
1119 self.0.vui_parameters.aspect_ratio_idc = value;
1120 self
1121 }
1122
1123 pub fn sar_resolution(mut self, width: u16, height: u16) -> Self {
1124 self = self.aspect_ratio_idc(255);
1125 self.0.vui_parameters.sar_width = width;
1126 self.0.vui_parameters.sar_height = height;
1127 self
1128 }
1129
1130 pub fn aspect_ratio(self, width_ratio: u16, height_ratio: u16) -> Self {
1131 match (width_ratio, height_ratio) {
1133 (1, 1) => self.aspect_ratio_idc(1),
1134 (12, 11) => self.aspect_ratio_idc(2),
1135 (10, 11) => self.aspect_ratio_idc(3),
1136 (16, 11) => self.aspect_ratio_idc(4),
1137 (40, 33) => self.aspect_ratio_idc(5),
1138 (24, 11) => self.aspect_ratio_idc(6),
1139 (20, 11) => self.aspect_ratio_idc(7),
1140 (32, 11) => self.aspect_ratio_idc(8),
1141 (80, 33) => self.aspect_ratio_idc(9),
1142 (18, 11) => self.aspect_ratio_idc(10),
1143 (15, 11) => self.aspect_ratio_idc(11),
1144 (64, 33) => self.aspect_ratio_idc(12),
1145 (160, 99) => self.aspect_ratio_idc(13),
1146 (4, 3) => self.aspect_ratio_idc(14),
1147 (3, 2) => self.aspect_ratio_idc(15),
1148 (2, 1) => self.aspect_ratio_idc(16),
1149
1150 _ => self.sar_resolution(width_ratio, height_ratio),
1151 }
1152 }
1153
1154 pub fn timing_info(
1155 mut self,
1156 num_units_in_tick: u32,
1157 time_scale: u32,
1158 fixed_frame_rate_flag: bool,
1159 ) -> Self {
1160 self = self.vui_parameters_present();
1161 self.0.vui_parameters.timing_info_present_flag = true;
1162 self.0.vui_parameters.num_units_in_tick = num_units_in_tick;
1163 self.0.vui_parameters.time_scale = time_scale;
1164 self.0.vui_parameters.fixed_frame_rate_flag = fixed_frame_rate_flag;
1165 self
1166 }
1167
1168 pub fn log2_max_frame_num_minus4(mut self, value: u8) -> Self {
1169 self.0.log2_max_frame_num_minus4 = value;
1170 self
1171 }
1172
1173 pub fn max_frame_num(self, value: u32) -> Self {
1174 self.log2_max_frame_num_minus4(value.ilog2() as u8 - 4u8)
1175 }
1176
1177 pub fn pic_order_cnt_type(mut self, value: u8) -> Self {
1178 self.0.pic_order_cnt_type = value;
1179 self
1180 }
1181
1182 pub fn log2_max_pic_order_cnt_lsb_minus4(mut self, value: u8) -> Self {
1183 self.0.log2_max_pic_order_cnt_lsb_minus4 = value;
1184 self
1185 }
1186
1187 pub fn max_pic_order_cnt_lsb(self, value: u32) -> Self {
1188 self.log2_max_pic_order_cnt_lsb_minus4(value.ilog2() as u8 - 4u8)
1189 }
1190
1191 pub fn delta_pic_order_always_zero_flag(mut self, value: bool) -> Self {
1192 self.0.delta_pic_order_always_zero_flag = value;
1193 self
1194 }
1195
1196 pub fn bit_depth_chroma_minus8(mut self, value: u8) -> Self {
1197 self.0.bit_depth_chroma_minus8 = value;
1198 self
1199 }
1200
1201 pub fn bit_depth_chroma(self, value: u8) -> Self {
1202 self.bit_depth_luma_minus8(value - 8u8)
1203 }
1204
1205 pub fn bit_depth_luma_minus8(mut self, value: u8) -> Self {
1206 self.0.bit_depth_luma_minus8 = value;
1207 self
1208 }
1209
1210 pub fn bit_depth_luma(self, value: u8) -> Self {
1211 self.bit_depth_luma_minus8(value - 8u8)
1212 }
1213
1214 pub fn build(self) -> Rc<Sps> {
1215 Rc::new(self.0)
1216 }
1217}
1218
1219#[derive(Clone, Debug, Default, PartialEq, Eq)]
1220pub struct HrdParams {
1221 pub cpb_cnt_minus1: u8,
1225 pub bit_rate_scale: u8,
1228 pub cpb_size_scale: u8,
1231
1232 pub bit_rate_value_minus1: [u32; 32],
1235 pub cpb_size_value_minus1: [u32; 32],
1238 pub cbr_flag: [bool; 32],
1244
1245 pub initial_cpb_removal_delay_length_minus1: u8,
1249 pub cpb_removal_delay_length_minus1: u8,
1251 pub dpb_output_delay_length_minus1: u8,
1253 pub time_offset_length: u8,
1257}
1258
1259#[derive(Clone, Debug, PartialEq, Eq)]
1260pub struct VuiParams {
1261 pub aspect_ratio_info_present_flag: bool,
1263 pub aspect_ratio_idc: u8,
1269
1270 pub sar_width: u16,
1274 pub sar_height: u16,
1277
1278 pub overscan_info_present_flag: bool,
1281 pub overscan_appropriate_flag: bool,
1289
1290 pub video_signal_type_present_flag: bool,
1293 pub video_format: u8,
1298 pub video_full_range_flag: bool,
1302 pub colour_description_present_flag: bool,
1305 pub colour_primaries: u8,
1309 pub transfer_characteristics: u8,
1311 pub matrix_coefficients: u8,
1315
1316 pub chroma_loc_info_present_flag: bool,
1319 pub chroma_sample_loc_type_top_field: u8,
1321 pub chroma_sample_loc_type_bottom_field: u8,
1323
1324 pub timing_info_present_flag: bool,
1327 pub num_units_in_tick: u32,
1332 pub time_scale: u32,
1336 pub fixed_frame_rate_flag: bool,
1338
1339 pub nal_hrd_parameters_present_flag: bool,
1342 pub nal_hrd_parameters: HrdParams,
1345 pub vcl_hrd_parameters_present_flag: bool,
1348 pub vcl_hrd_parameters: HrdParams,
1351
1352 pub low_delay_hrd_flag: bool,
1354
1355 pub pic_struct_present_flag: bool,
1358
1359 pub bitstream_restriction_flag: bool,
1362 pub motion_vectors_over_pic_boundaries_flag: bool,
1372 pub max_bytes_per_pic_denom: u32,
1376 pub max_bits_per_mb_denom: u32,
1380 pub log2_max_mv_length_horizontal: u32,
1382 pub log2_max_mv_length_vertical: u32,
1384 pub max_num_reorder_frames: u32,
1405 pub max_dec_frame_buffering: u32,
1427}
1428
1429impl Default for VuiParams {
1430 fn default() -> Self {
1431 Self {
1432 aspect_ratio_info_present_flag: Default::default(),
1433 aspect_ratio_idc: Default::default(),
1434 sar_width: Default::default(),
1435 sar_height: Default::default(),
1436 overscan_info_present_flag: Default::default(),
1437 overscan_appropriate_flag: Default::default(),
1438 video_signal_type_present_flag: Default::default(),
1439 video_format: 5,
1440 video_full_range_flag: Default::default(),
1441 colour_description_present_flag: Default::default(),
1442 colour_primaries: 2,
1443 transfer_characteristics: 2,
1444 matrix_coefficients: 2,
1445 chroma_loc_info_present_flag: Default::default(),
1446 chroma_sample_loc_type_top_field: Default::default(),
1447 chroma_sample_loc_type_bottom_field: Default::default(),
1448 timing_info_present_flag: Default::default(),
1449 num_units_in_tick: Default::default(),
1450 time_scale: Default::default(),
1451 fixed_frame_rate_flag: Default::default(),
1452 nal_hrd_parameters_present_flag: Default::default(),
1453 nal_hrd_parameters: Default::default(),
1454 vcl_hrd_parameters_present_flag: Default::default(),
1455 vcl_hrd_parameters: Default::default(),
1456 low_delay_hrd_flag: Default::default(),
1457 pic_struct_present_flag: Default::default(),
1458 bitstream_restriction_flag: Default::default(),
1459 motion_vectors_over_pic_boundaries_flag: Default::default(),
1460 max_bytes_per_pic_denom: Default::default(),
1461 max_bits_per_mb_denom: Default::default(),
1462 log2_max_mv_length_horizontal: Default::default(),
1463 log2_max_mv_length_vertical: Default::default(),
1464 max_num_reorder_frames: Default::default(),
1465 max_dec_frame_buffering: Default::default(),
1466 }
1467 }
1468}
1469
1470#[derive(Debug, PartialEq, Eq)]
1474pub struct Pps {
1475 pub pic_parameter_set_id: u8,
1477
1478 pub seq_parameter_set_id: u8,
1480
1481 pub entropy_coding_mode_flag: bool,
1489
1490 pub bottom_field_pic_order_in_frame_present_flag: bool,
1498
1499 pub num_slice_groups_minus1: u32,
1504
1505 pub num_ref_idx_l0_default_active_minus1: u8,
1508
1509 pub num_ref_idx_l1_default_active_minus1: u8,
1512
1513 pub weighted_pred_flag: bool,
1517
1518 pub weighted_bipred_idc: u8,
1524
1525 pub pic_init_qp_minus26: i8,
1530
1531 pub pic_init_qs_minus26: i8,
1535
1536 pub chroma_qp_index_offset: i8,
1539
1540 pub deblocking_filter_control_present_flag: bool,
1546
1547 pub constrained_intra_pred_flag: bool,
1555
1556 pub redundant_pic_cnt_present_flag: bool,
1567
1568 pub transform_8x8_mode_flag: bool,
1572
1573 pub pic_scaling_matrix_present_flag: bool,
1578
1579 pub scaling_lists_4x4: [[u8; 16]; 6],
1581 pub scaling_lists_8x8: [[u8; 64]; 6],
1583
1584 pub second_chroma_qp_index_offset: i8,
1589
1590 pub sps: Rc<Sps>,
1592}
1593
1594pub struct PpsBuilder(Pps);
1595
1596impl PpsBuilder {
1597 pub fn new(sps: Rc<Sps>) -> Self {
1598 PpsBuilder(Pps {
1599 pic_parameter_set_id: 0,
1600 seq_parameter_set_id: sps.seq_parameter_set_id,
1601 entropy_coding_mode_flag: false,
1602 bottom_field_pic_order_in_frame_present_flag: false,
1603 num_slice_groups_minus1: 0,
1604 num_ref_idx_l0_default_active_minus1: 0,
1605 num_ref_idx_l1_default_active_minus1: 0,
1606 weighted_pred_flag: false,
1607 weighted_bipred_idc: 0,
1608 pic_init_qp_minus26: 0,
1609 pic_init_qs_minus26: 0,
1610 chroma_qp_index_offset: 0,
1611 deblocking_filter_control_present_flag: false,
1612 constrained_intra_pred_flag: false,
1613 redundant_pic_cnt_present_flag: false,
1614 transform_8x8_mode_flag: false,
1615 pic_scaling_matrix_present_flag: false,
1616 scaling_lists_4x4: [[0; 16]; 6],
1617 scaling_lists_8x8: [[0; 64]; 6],
1618 second_chroma_qp_index_offset: 0,
1619 sps,
1620 })
1621 }
1622
1623 pub fn pic_parameter_set_id(mut self, value: u8) -> Self {
1624 self.0.pic_parameter_set_id = value;
1625 self
1626 }
1627
1628 pub fn pic_init_qp_minus26(mut self, value: i8) -> Self {
1629 self.0.pic_init_qp_minus26 = value;
1630 self
1631 }
1632
1633 pub fn pic_init_qp(self, value: u8) -> Self {
1634 self.pic_init_qp_minus26(value as i8 - 26)
1635 }
1636
1637 pub fn deblocking_filter_control_present_flag(mut self, value: bool) -> Self {
1638 self.0.deblocking_filter_control_present_flag = value;
1639 self
1640 }
1641
1642 pub fn num_ref_idx_l0_default_active_minus1(mut self, value: u8) -> Self {
1643 self.0.num_ref_idx_l0_default_active_minus1 = value;
1644 self
1645 }
1646
1647 pub fn num_ref_idx_l0_default_active(self, value: u8) -> Self {
1648 self.num_ref_idx_l0_default_active_minus1(value - 1)
1649 }
1650
1651 pub fn num_ref_idx_l1_default_active_minus1(mut self, value: u8) -> Self {
1652 self.0.num_ref_idx_l1_default_active_minus1 = value;
1653 self
1654 }
1655
1656 pub fn num_ref_idx_l1_default_active(self, value: u8) -> Self {
1657 self.num_ref_idx_l1_default_active_minus1(value - 1)
1658 }
1659
1660 pub fn build(self) -> Rc<Pps> {
1661 Rc::new(self.0)
1662 }
1663}
1664
1665#[derive(Debug, Default)]
1666pub struct Parser {
1667 active_spses: BTreeMap<u8, Rc<Sps>>,
1668 active_ppses: BTreeMap<u8, Rc<Pps>>,
1669}
1670
1671impl Parser {
1672 fn fill_default_scaling_list_4x4(scaling_list4x4: &mut [u8; 16], i: usize) {
1673 assert!(i < 6);
1675 if i < 3 {
1676 *scaling_list4x4 = DEFAULT_4X4_INTRA;
1677 } else if i < 6 {
1678 *scaling_list4x4 = DEFAULT_4X4_INTER;
1679 }
1680 }
1681
1682 fn fill_default_scaling_list_8x8(scaling_list8x8: &mut [u8; 64], i: usize) {
1683 assert!(i < 6);
1684 if i % 2 == 0 {
1685 *scaling_list8x8 = DEFAULT_8X8_INTRA;
1686 } else {
1687 *scaling_list8x8 = DEFAULT_8X8_INTER;
1688 }
1689 }
1690
1691 fn fill_fallback_scaling_list_4x4(
1692 scaling_list4x4: &mut [[u8; 16]; 6],
1693 i: usize,
1694 default_scaling_list_intra: &[u8; 16],
1695 default_scaling_list_inter: &[u8; 16],
1696 ) {
1697 scaling_list4x4[i] = match i {
1699 0 => *default_scaling_list_intra,
1700 1 => scaling_list4x4[0],
1701 2 => scaling_list4x4[1],
1702 3 => *default_scaling_list_inter,
1703 4 => scaling_list4x4[3],
1704 5 => scaling_list4x4[4],
1705 _ => panic!("Unexpected value {}", i),
1706 }
1707 }
1708
1709 fn fill_fallback_scaling_list_8x8(
1710 scaling_list8x8: &mut [[u8; 64]; 6],
1711 i: usize,
1712 default_scaling_list_intra: &[u8; 64],
1713 default_scaling_list_inter: &[u8; 64],
1714 ) {
1715 scaling_list8x8[i] = match i {
1717 0 => *default_scaling_list_intra,
1718 1 => *default_scaling_list_inter,
1719 2 => scaling_list8x8[0],
1720 3 => scaling_list8x8[1],
1721 4 => scaling_list8x8[2],
1722 5 => scaling_list8x8[3],
1723 _ => panic!("Unexpected value {}", i),
1724 }
1725 }
1726
1727 fn fill_scaling_list_flat(
1728 scaling_list4x4: &mut [[u8; 16]; 6],
1729 scaling_list8x8: &mut [[u8; 64]; 6],
1730 ) {
1731 for outer in scaling_list4x4 {
1733 for inner in outer {
1734 *inner = 16;
1735 }
1736 }
1737
1738 for outer in scaling_list8x8 {
1740 for inner in outer {
1741 *inner = 16;
1742 }
1743 }
1744 }
1745
1746 fn parse_scaling_list<U: AsMut<[u8]>>(
1747 r: &mut BitReader,
1748 scaling_list: &mut U,
1749 use_default: &mut bool,
1750 ) -> Result<(), String> {
1751 let mut last_scale = 8u8;
1753 let mut next_scale = 8u8;
1754
1755 for j in 0..scaling_list.as_mut().len() {
1756 if next_scale != 0 {
1757 let delta_scale = r.read_se::<i32>()?;
1758 next_scale = ((last_scale as i32 + delta_scale + 256) % 256) as u8;
1759 *use_default = j == 0 && next_scale == 0;
1760 if *use_default {
1761 return Ok(());
1762 }
1763 }
1764
1765 scaling_list.as_mut()[j] = if next_scale == 0 { last_scale } else { next_scale };
1766
1767 last_scale = scaling_list.as_mut()[j];
1768 }
1769
1770 Ok(())
1771 }
1772
1773 fn parse_sps_scaling_lists(r: &mut BitReader, sps: &mut Sps) -> Result<(), String> {
1774 let scaling_lists4x4 = &mut sps.scaling_lists_4x4;
1775 let scaling_lisst8x8 = &mut sps.scaling_lists_8x8;
1776
1777 for i in 0..6 {
1779 let seq_scaling_list_present_flag = r.read_bit()?;
1780 if seq_scaling_list_present_flag {
1781 let mut use_default = false;
1782
1783 Parser::parse_scaling_list(r, &mut scaling_lists4x4[i], &mut use_default)?;
1784
1785 if use_default {
1786 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1787 }
1788 } else {
1789 Parser::fill_fallback_scaling_list_4x4(
1790 scaling_lists4x4,
1791 i,
1792 &DEFAULT_4X4_INTRA,
1793 &DEFAULT_4X4_INTER,
1794 );
1795 }
1796 }
1797
1798 let num_8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
1800 for i in 0..num_8x8 {
1801 let seq_scaling_list_present_flag = r.read_bit()?;
1802 if seq_scaling_list_present_flag {
1803 let mut use_default = false;
1804 Parser::parse_scaling_list(r, &mut scaling_lisst8x8[i], &mut use_default)?;
1805
1806 if use_default {
1807 Parser::fill_default_scaling_list_8x8(&mut scaling_lisst8x8[i], i);
1808 }
1809 } else {
1810 Parser::fill_fallback_scaling_list_8x8(
1811 scaling_lisst8x8,
1812 i,
1813 &DEFAULT_8X8_INTRA,
1814 &DEFAULT_8X8_INTER,
1815 );
1816 }
1817 }
1818 Ok(())
1819 }
1820
1821 fn parse_pps_scaling_lists(r: &mut BitReader, pps: &mut Pps, sps: &Sps) -> Result<(), String> {
1822 let scaling_lists4x4 = &mut pps.scaling_lists_4x4;
1823 let scaling_lists8x8 = &mut pps.scaling_lists_8x8;
1824
1825 for i in 0..6 {
1826 let pic_scaling_list_present_flag = r.read_bit()?;
1827 if pic_scaling_list_present_flag {
1828 let mut use_default = false;
1829
1830 Parser::parse_scaling_list(r, &mut scaling_lists4x4[i], &mut use_default)?;
1831
1832 if use_default {
1833 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1834 }
1835 } else if !sps.seq_scaling_matrix_present_flag {
1836 Parser::fill_fallback_scaling_list_4x4(
1838 scaling_lists4x4,
1839 i,
1840 &DEFAULT_4X4_INTRA,
1841 &DEFAULT_4X4_INTER,
1842 );
1843 } else {
1844 Parser::fill_fallback_scaling_list_4x4(
1846 scaling_lists4x4,
1847 i,
1848 &sps.scaling_lists_4x4[0],
1849 &sps.scaling_lists_4x4[3],
1850 );
1851 }
1852 }
1853
1854 if pps.transform_8x8_mode_flag {
1855 let num8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
1856
1857 for i in 0..num8x8 {
1858 let pic_scaling_list_present_flag = r.read_bit()?;
1859 if pic_scaling_list_present_flag {
1860 let mut use_default = false;
1861
1862 Parser::parse_scaling_list(r, &mut scaling_lists8x8[i], &mut use_default)?;
1863
1864 if use_default {
1865 Parser::fill_default_scaling_list_8x8(&mut scaling_lists8x8[i], i);
1866 }
1867 } else if !sps.seq_scaling_matrix_present_flag {
1868 Parser::fill_fallback_scaling_list_8x8(
1870 scaling_lists8x8,
1871 i,
1872 &DEFAULT_8X8_INTRA,
1873 &DEFAULT_8X8_INTER,
1874 );
1875 } else {
1876 Parser::fill_fallback_scaling_list_8x8(
1878 scaling_lists8x8,
1879 i,
1880 &sps.scaling_lists_8x8[0],
1881 &sps.scaling_lists_8x8[1],
1882 );
1883 }
1884 }
1885 }
1886
1887 Ok(())
1888 }
1889
1890 fn parse_hrd(r: &mut BitReader, hrd: &mut HrdParams) -> Result<(), String> {
1891 hrd.cpb_cnt_minus1 = r.read_ue_max(31)?;
1892 hrd.bit_rate_scale = r.read_bits(4)?;
1893 hrd.cpb_size_scale = r.read_bits(4)?;
1894
1895 for sched_sel_idx in 0..=usize::from(hrd.cpb_cnt_minus1) {
1896 hrd.bit_rate_value_minus1[sched_sel_idx] = r.read_ue()?;
1897 hrd.cpb_size_value_minus1[sched_sel_idx] = r.read_ue()?;
1898 hrd.cbr_flag[sched_sel_idx] = r.read_bit()?;
1899 }
1900
1901 hrd.initial_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
1902 hrd.cpb_removal_delay_length_minus1 = r.read_bits(5)?;
1903 hrd.dpb_output_delay_length_minus1 = r.read_bits(5)?;
1904 hrd.time_offset_length = r.read_bits(5)?;
1905 Ok(())
1906 }
1907
1908 fn parse_vui(r: &mut BitReader, sps: &mut Sps) -> Result<(), String> {
1909 let vui = &mut sps.vui_parameters;
1910
1911 vui.aspect_ratio_info_present_flag = r.read_bit()?;
1912 if vui.aspect_ratio_info_present_flag {
1913 vui.aspect_ratio_idc = r.read_bits(8)?;
1914 if vui.aspect_ratio_idc == 255 {
1915 vui.sar_width = r.read_bits(16)?;
1916 vui.sar_height = r.read_bits(16)?;
1917 }
1918 }
1919
1920 vui.overscan_info_present_flag = r.read_bit()?;
1921 if vui.overscan_info_present_flag {
1922 vui.overscan_appropriate_flag = r.read_bit()?;
1923 }
1924
1925 vui.video_signal_type_present_flag = r.read_bit()?;
1926 if vui.video_signal_type_present_flag {
1927 vui.video_format = r.read_bits(3)?;
1928 vui.video_full_range_flag = r.read_bit()?;
1929 vui.colour_description_present_flag = r.read_bit()?;
1930 if vui.colour_description_present_flag {
1931 vui.colour_primaries = r.read_bits(8)?;
1932 vui.transfer_characteristics = r.read_bits(8)?;
1933 vui.matrix_coefficients = r.read_bits(8)?;
1934 }
1935 }
1936
1937 vui.chroma_loc_info_present_flag = r.read_bit()?;
1938 if vui.chroma_loc_info_present_flag {
1939 vui.chroma_sample_loc_type_top_field = r.read_ue_max(5)?;
1940 vui.chroma_sample_loc_type_bottom_field = r.read_ue_max(5)?;
1941 }
1942
1943 vui.timing_info_present_flag = r.read_bit()?;
1944 if vui.timing_info_present_flag {
1945 vui.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
1946 vui.num_units_in_tick |= r.read_bit()? as u32;
1947 if vui.num_units_in_tick == 0 {
1948 return Err("num_units_in_tick == 0, which is not allowed by E.2.1".into());
1949 }
1950
1951 vui.time_scale = r.read_bits::<u32>(31)? << 1;
1952 vui.time_scale |= r.read_bit()? as u32;
1953 if vui.time_scale == 0 {
1954 return Err("time_scale == 0, which is not allowed by E.2.1".into());
1955 }
1956
1957 vui.fixed_frame_rate_flag = r.read_bit()?;
1958 }
1959
1960 vui.nal_hrd_parameters_present_flag = r.read_bit()?;
1961 if vui.nal_hrd_parameters_present_flag {
1962 Parser::parse_hrd(r, &mut vui.nal_hrd_parameters)?;
1963 }
1964
1965 vui.vcl_hrd_parameters_present_flag = r.read_bit()?;
1966 if vui.vcl_hrd_parameters_present_flag {
1967 Parser::parse_hrd(r, &mut vui.vcl_hrd_parameters)?;
1968 }
1969
1970 if vui.nal_hrd_parameters_present_flag || vui.vcl_hrd_parameters_present_flag {
1971 vui.low_delay_hrd_flag = r.read_bit()?;
1972 }
1973
1974 vui.pic_struct_present_flag = r.read_bit()?;
1975 vui.bitstream_restriction_flag = r.read_bit()?;
1976
1977 if vui.bitstream_restriction_flag {
1978 vui.motion_vectors_over_pic_boundaries_flag = r.read_bit()?;
1979 vui.max_bytes_per_pic_denom = r.read_ue()?;
1980 vui.max_bits_per_mb_denom = r.read_ue_max(16)?;
1981 vui.log2_max_mv_length_horizontal = r.read_ue_max(16)?;
1982 vui.log2_max_mv_length_vertical = r.read_ue_max(16)?;
1983 vui.max_num_reorder_frames = r.read_ue()?;
1984 vui.max_dec_frame_buffering = r.read_ue()?;
1985 }
1986
1987 Ok(())
1988 }
1989
1990 pub fn parse_sps(&mut self, nalu: &Nalu) -> Result<&Rc<Sps>, String> {
1994 if !matches!(nalu.header.type_, NaluType::Sps) {
1995 return Err(format!(
1996 "Invalid NALU type, expected {:?}, got {:?}",
1997 NaluType::Sps,
1998 nalu.header.type_
1999 ));
2000 }
2001
2002 let data = nalu.as_ref();
2003 let mut r = BitReader::new(&data[nalu.header.len()..], true);
2005 let mut sps = Sps {
2006 profile_idc: r.read_bits(8)?,
2007 constraint_set0_flag: r.read_bit()?,
2008 constraint_set1_flag: r.read_bit()?,
2009 constraint_set2_flag: r.read_bit()?,
2010 constraint_set3_flag: r.read_bit()?,
2011 constraint_set4_flag: r.read_bit()?,
2012 constraint_set5_flag: r.read_bit()?,
2013 ..Default::default()
2014 };
2015
2016 r.skip_bits(2)?;
2018
2019 let level: u8 = r.read_bits(8)?;
2020 sps.level_idc = Level::try_from(level)?;
2021 sps.seq_parameter_set_id = r.read_ue_max(31)?;
2022
2023 if sps.profile_idc == 100
2024 || sps.profile_idc == 110
2025 || sps.profile_idc == 122
2026 || sps.profile_idc == 244
2027 || sps.profile_idc == 44
2028 || sps.profile_idc == 83
2029 || sps.profile_idc == 86
2030 || sps.profile_idc == 118
2031 || sps.profile_idc == 128
2032 || sps.profile_idc == 138
2033 || sps.profile_idc == 139
2034 || sps.profile_idc == 134
2035 || sps.profile_idc == 135
2036 {
2037 sps.chroma_format_idc = r.read_ue_max(3)?;
2038 if sps.chroma_format_idc == 3 {
2039 sps.separate_colour_plane_flag = r.read_bit()?;
2040 }
2041
2042 sps.bit_depth_luma_minus8 = r.read_ue_max(6)?;
2043 sps.bit_depth_chroma_minus8 = r.read_ue_max(6)?;
2044 sps.qpprime_y_zero_transform_bypass_flag = r.read_bit()?;
2045 sps.seq_scaling_matrix_present_flag = r.read_bit()?;
2046
2047 if sps.seq_scaling_matrix_present_flag {
2048 Parser::parse_sps_scaling_lists(&mut r, &mut sps)?;
2049 } else {
2050 Parser::fill_scaling_list_flat(
2051 &mut sps.scaling_lists_4x4,
2052 &mut sps.scaling_lists_8x8,
2053 );
2054 }
2055 } else {
2056 sps.chroma_format_idc = 1;
2057 Parser::fill_scaling_list_flat(&mut sps.scaling_lists_4x4, &mut sps.scaling_lists_8x8);
2058 }
2059
2060 sps.log2_max_frame_num_minus4 = r.read_ue_max(12)?;
2061
2062 sps.pic_order_cnt_type = r.read_ue_max(2)?;
2063
2064 if sps.pic_order_cnt_type == 0 {
2065 sps.log2_max_pic_order_cnt_lsb_minus4 = r.read_ue_max(12)?;
2066 sps.expected_delta_per_pic_order_cnt_cycle = 0;
2067 } else if sps.pic_order_cnt_type == 1 {
2068 sps.delta_pic_order_always_zero_flag = r.read_bit()?;
2069 sps.offset_for_non_ref_pic = r.read_se()?;
2070 sps.offset_for_top_to_bottom_field = r.read_se()?;
2071 sps.num_ref_frames_in_pic_order_cnt_cycle = r.read_ue_max(254)?;
2072
2073 let mut offset_acc = 0;
2074 for i in 0..usize::from(sps.num_ref_frames_in_pic_order_cnt_cycle) {
2075 sps.offset_for_ref_frame[i] = r.read_se()?;
2076
2077 offset_acc += sps.offset_for_ref_frame[i];
2079 }
2080
2081 sps.expected_delta_per_pic_order_cnt_cycle = offset_acc;
2082 }
2083
2084 sps.max_num_ref_frames = r.read_ue_max(DPB_MAX_SIZE as u32)?;
2085 sps.gaps_in_frame_num_value_allowed_flag = r.read_bit()?;
2086 sps.pic_width_in_mbs_minus1 = r.read_ue()?;
2087 sps.pic_height_in_map_units_minus1 = r.read_ue()?;
2088 sps.frame_mbs_only_flag = r.read_bit()?;
2089
2090 if !sps.frame_mbs_only_flag {
2091 sps.mb_adaptive_frame_field_flag = r.read_bit()?;
2092 }
2093
2094 sps.direct_8x8_inference_flag = r.read_bit()?;
2095 sps.frame_cropping_flag = r.read_bit()?;
2096
2097 if sps.frame_cropping_flag {
2098 sps.frame_crop_left_offset = r.read_ue()?;
2099 sps.frame_crop_right_offset = r.read_ue()?;
2100 sps.frame_crop_top_offset = r.read_ue()?;
2101 sps.frame_crop_bottom_offset = r.read_ue()?;
2102
2103 let (crop_unit_x, crop_unit_y) = sps.crop_unit_x_y();
2105
2106 let _ = sps
2107 .frame_crop_left_offset
2108 .checked_add(sps.frame_crop_right_offset)
2109 .and_then(|r| r.checked_mul(crop_unit_x))
2110 .and_then(|r| sps.width().checked_sub(r))
2111 .ok_or::<String>("Invalid frame crop width".into())?;
2112
2113 let _ = sps
2114 .frame_crop_top_offset
2115 .checked_add(sps.frame_crop_bottom_offset)
2116 .and_then(|r| r.checked_mul(crop_unit_y))
2117 .and_then(|r| sps.height().checked_sub(r))
2118 .ok_or::<String>("invalid frame crop height".into())?;
2119 }
2120
2121 sps.vui_parameters_present_flag = r.read_bit()?;
2122 if sps.vui_parameters_present_flag {
2123 Parser::parse_vui(&mut r, &mut sps)?;
2124 }
2125
2126 let key = sps.seq_parameter_set_id;
2127
2128 if self.active_spses.keys().len() >= MAX_SPS_COUNT as usize {
2129 return Err("Broken data: Number of active SPSs > MAX_SPS_COUNT".into());
2130 }
2131
2132 let sps = Rc::new(sps);
2133 self.active_spses.remove(&key);
2134 Ok(self.active_spses.entry(key).or_insert(sps))
2135 }
2136
2137 pub fn parse_pps(&mut self, nalu: &Nalu) -> Result<&Pps, String> {
2138 if !matches!(nalu.header.type_, NaluType::Pps) {
2139 return Err(format!(
2140 "Invalid NALU type, expected {:?}, got {:?}",
2141 NaluType::Pps,
2142 nalu.header.type_
2143 ));
2144 }
2145
2146 let data = nalu.as_ref();
2147 let mut r = BitReader::new(&data[nalu.header.len()..], true);
2149 let pic_parameter_set_id = r.read_ue_max(MAX_PPS_COUNT as u32 - 1)?;
2150 let seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
2151 let sps = self.get_sps(seq_parameter_set_id).ok_or::<String>(format!(
2152 "Could not get SPS for seq_parameter_set_id {}",
2153 seq_parameter_set_id
2154 ))?;
2155 let mut pps = Pps {
2156 pic_parameter_set_id,
2157 seq_parameter_set_id,
2158 sps: Rc::clone(sps),
2159 scaling_lists_4x4: [[0; 16]; 6],
2160 scaling_lists_8x8: [[0; 64]; 6],
2161 entropy_coding_mode_flag: Default::default(),
2162 bottom_field_pic_order_in_frame_present_flag: Default::default(),
2163 num_slice_groups_minus1: Default::default(),
2164 num_ref_idx_l0_default_active_minus1: Default::default(),
2165 num_ref_idx_l1_default_active_minus1: Default::default(),
2166 weighted_pred_flag: Default::default(),
2167 weighted_bipred_idc: Default::default(),
2168 pic_init_qp_minus26: Default::default(),
2169 pic_init_qs_minus26: Default::default(),
2170 chroma_qp_index_offset: Default::default(),
2171 deblocking_filter_control_present_flag: Default::default(),
2172 constrained_intra_pred_flag: Default::default(),
2173 redundant_pic_cnt_present_flag: Default::default(),
2174 transform_8x8_mode_flag: Default::default(),
2175 second_chroma_qp_index_offset: Default::default(),
2176 pic_scaling_matrix_present_flag: Default::default(),
2177 };
2178
2179 pps.entropy_coding_mode_flag = r.read_bit()?;
2180 pps.bottom_field_pic_order_in_frame_present_flag = r.read_bit()?;
2181 pps.num_slice_groups_minus1 = r.read_ue_max(7)?;
2182
2183 if pps.num_slice_groups_minus1 > 0 {
2184 return Err("Stream contain unsupported/unimplemented NALs".into());
2185 }
2186
2187 pps.num_ref_idx_l0_default_active_minus1 = r.read_ue_max(31)?;
2188 pps.num_ref_idx_l1_default_active_minus1 = r.read_ue_max(31)?;
2189
2190 pps.weighted_pred_flag = r.read_bit()?;
2191 pps.weighted_bipred_idc = r.read_bits(2)?;
2192
2193 let qp_bd_offset_y = i32::from(6 * (sps.bit_depth_luma_minus8));
2194 pps.pic_init_qp_minus26 = r.read_se_bounded(-(26 + qp_bd_offset_y), 25)?;
2195 pps.pic_init_qs_minus26 = r.read_se_bounded(-26, 25)?;
2196
2197 pps.chroma_qp_index_offset = r.read_se_bounded(-12, 12)?;
2198
2199 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;
2202
2203 pps.deblocking_filter_control_present_flag = r.read_bit()?;
2204 pps.constrained_intra_pred_flag = r.read_bit()?;
2205 pps.redundant_pic_cnt_present_flag = r.read_bit()?;
2206
2207 if r.has_more_rsbp_data() {
2208 pps.transform_8x8_mode_flag = r.read_bit()?;
2209 pps.pic_scaling_matrix_present_flag = r.read_bit()?;
2210
2211 if pps.pic_scaling_matrix_present_flag {
2212 Parser::parse_pps_scaling_lists(&mut r, &mut pps, sps)?;
2213 }
2214
2215 pps.second_chroma_qp_index_offset = r.read_se()?;
2216 }
2217
2218 if !pps.pic_scaling_matrix_present_flag {
2219 pps.scaling_lists_4x4 = sps.scaling_lists_4x4;
2224 pps.scaling_lists_8x8 = sps.scaling_lists_8x8;
2225 }
2226
2227 let key = pps.pic_parameter_set_id;
2228
2229 if self.active_ppses.keys().len() >= MAX_PPS_COUNT as usize {
2230 return Err("Broken Data: number of active PPSs > MAX_PPS_COUNT".into());
2231 }
2232
2233 let pps = Rc::new(pps);
2234 self.active_ppses.remove(&key);
2235 Ok(self.active_ppses.entry(key).or_insert(pps))
2236 }
2237
2238 fn parse_ref_pic_list_modification(
2239 r: &mut BitReader,
2240 num_ref_idx_active_minus1: u8,
2241 ref_list_mods: &mut Vec<RefPicListModification>,
2242 ) -> Result<(), String> {
2243 if num_ref_idx_active_minus1 >= 32 {
2244 return Err("Broken Data: num_ref_idx_active_minus1 >= 32".into());
2245 }
2246
2247 loop {
2248 let mut pic_num_mod = RefPicListModification {
2249 modification_of_pic_nums_idc: r.read_ue_max(3)?,
2250 ..Default::default()
2251 };
2252
2253 match pic_num_mod.modification_of_pic_nums_idc {
2254 0 | 1 => {
2255 pic_num_mod.abs_diff_pic_num_minus1 = r.read_ue()?;
2256 }
2257
2258 2 => {
2259 pic_num_mod.long_term_pic_num = r.read_ue()?;
2260 }
2261
2262 3 => {
2263 ref_list_mods.push(pic_num_mod);
2264 break;
2265 }
2266
2267 _ => return Err("Broken Data: modification_of_pic_nums_idc > 3".into()),
2268 }
2269
2270 ref_list_mods.push(pic_num_mod);
2271 }
2272
2273 Ok(())
2274 }
2275
2276 fn parse_ref_pic_list_modifications(
2277 r: &mut BitReader,
2278 header: &mut SliceHeader,
2279 ) -> Result<(), String> {
2280 if !header.slice_type.is_i() && !header.slice_type.is_si() {
2281 header.ref_pic_list_modification_flag_l0 = r.read_bit()?;
2282 if header.ref_pic_list_modification_flag_l0 {
2283 Parser::parse_ref_pic_list_modification(
2284 r,
2285 header.num_ref_idx_l0_active_minus1,
2286 &mut header.ref_pic_list_modification_l0,
2287 )?;
2288 }
2289 }
2290
2291 if header.slice_type.is_b() {
2292 header.ref_pic_list_modification_flag_l1 = r.read_bit()?;
2293 if header.ref_pic_list_modification_flag_l1 {
2294 Parser::parse_ref_pic_list_modification(
2295 r,
2296 header.num_ref_idx_l1_active_minus1,
2297 &mut header.ref_pic_list_modification_l1,
2298 )?;
2299 }
2300 }
2301
2302 Ok(())
2303 }
2304
2305 fn parse_pred_weight_table(
2306 r: &mut BitReader,
2307 sps: &Sps,
2308 header: &mut SliceHeader,
2309 ) -> Result<(), String> {
2310 let pt = &mut header.pred_weight_table;
2311 pt.luma_log2_weight_denom = r.read_ue_max(7)?;
2312
2313 let default_luma_weight = 1 << pt.luma_log2_weight_denom;
2317 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2318 pt.luma_weight_l0[usize::from(i)] = default_luma_weight;
2319 }
2320
2321 if header.slice_type.is_b() {
2325 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2326 pt.luma_weight_l1[usize::from(i)] = default_luma_weight;
2327 }
2328 }
2329
2330 if sps.chroma_array_type() != 0 {
2331 pt.chroma_log2_weight_denom = r.read_ue_max(7)?;
2332 let default_chroma_weight = 1 << pt.chroma_log2_weight_denom;
2333
2334 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2338 pt.chroma_weight_l0[usize::from(i)][0] = default_chroma_weight;
2339 pt.chroma_weight_l0[usize::from(i)][1] = default_chroma_weight;
2340 }
2341
2342 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2346 pt.chroma_weight_l1[usize::from(i)][0] = default_chroma_weight;
2347 pt.chroma_weight_l1[usize::from(i)][1] = default_chroma_weight;
2348 }
2349 }
2350
2351 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2352 let luma_weight_l0_flag = r.read_bit()?;
2353
2354 if luma_weight_l0_flag {
2355 pt.luma_weight_l0[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2356 pt.luma_offset_l0[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2357 }
2358
2359 if sps.chroma_array_type() != 0 {
2360 let chroma_weight_l0_flag = r.read_bit()?;
2361 if chroma_weight_l0_flag {
2362 for j in 0..2 {
2363 pt.chroma_weight_l0[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2364 pt.chroma_offset_l0[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2365 }
2366 }
2367 }
2368 }
2369
2370 if header.slice_type.is_b() {
2371 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2372 let luma_weight_l1_flag = r.read_bit()?;
2373
2374 if luma_weight_l1_flag {
2375 pt.luma_weight_l1[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2376 pt.luma_offset_l1[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2377 }
2378
2379 if sps.chroma_array_type() != 0 {
2380 let chroma_weight_l1_flag = r.read_bit()?;
2381 if chroma_weight_l1_flag {
2382 for j in 0..2 {
2383 pt.chroma_weight_l1[usize::from(i)][j] =
2384 r.read_se_bounded(-128, 127)?;
2385 pt.chroma_offset_l1[usize::from(i)][j] =
2386 r.read_se_bounded(-128, 127)?;
2387 }
2388 }
2389 }
2390 }
2391 }
2392
2393 Ok(())
2394 }
2395
2396 fn parse_dec_ref_pic_marking(
2397 r: &mut BitReader,
2398 nalu: &Nalu,
2399 header: &mut SliceHeader,
2400 ) -> Result<(), String> {
2401 let rpm = &mut header.dec_ref_pic_marking;
2402
2403 let num_bits_left = r.num_bits_left();
2404 if nalu.header.idr_pic_flag {
2405 rpm.no_output_of_prior_pics_flag = r.read_bit()?;
2406 rpm.long_term_reference_flag = r.read_bit()?;
2407 } else {
2408 rpm.adaptive_ref_pic_marking_mode_flag = r.read_bit()?;
2409
2410 if rpm.adaptive_ref_pic_marking_mode_flag {
2411 loop {
2412 let mut marking = RefPicMarkingInner::default();
2413
2414 let mem_mgmt_ctrl_op = r.read_ue_max::<u8>(6)?;
2415 marking.memory_management_control_operation = mem_mgmt_ctrl_op;
2416
2417 if mem_mgmt_ctrl_op == 0 {
2418 break;
2419 }
2420
2421 if mem_mgmt_ctrl_op == 1 || mem_mgmt_ctrl_op == 3 {
2422 marking.difference_of_pic_nums_minus1 = r.read_ue()?;
2423 }
2424
2425 if mem_mgmt_ctrl_op == 2 {
2426 marking.long_term_pic_num = r.read_ue()?;
2427 }
2428
2429 if mem_mgmt_ctrl_op == 3 || mem_mgmt_ctrl_op == 6 {
2430 marking.long_term_frame_idx = r.read_ue()?;
2431 }
2432
2433 if mem_mgmt_ctrl_op == 4 {
2434 marking.max_long_term_frame_idx =
2435 MaxLongTermFrameIdx::from_value_plus1(r.read_ue()?);
2436 }
2437
2438 rpm.inner.push(marking);
2439 }
2440 }
2441 }
2442 header.dec_ref_pic_marking_bit_size = num_bits_left - r.num_bits_left();
2443
2444 Ok(())
2445 }
2446
2447 pub fn parse_slice_header<'a>(&self, nalu: Nalu<'a>) -> Result<Slice<'a>, String> {
2448 if !matches!(
2449 nalu.header.type_,
2450 NaluType::Slice
2451 | NaluType::SliceDpa
2452 | NaluType::SliceDpb
2453 | NaluType::SliceDpc
2454 | NaluType::SliceIdr
2455 | NaluType::SliceExt
2456 ) {
2457 return Err(format!("Invalid NALU type: {:?} is not a slice NALU", nalu.header.type_));
2458 }
2459
2460 let data = nalu.as_ref();
2461 let mut r = BitReader::new(&data[nalu.header.len()..], true);
2463
2464 let mut header = SliceHeader { first_mb_in_slice: r.read_ue()?, ..Default::default() };
2465
2466 let slice_type = r.read_ue_max::<u8>(9)? % 5;
2467 header.slice_type = SliceType::try_from(slice_type)?;
2468
2469 header.pic_parameter_set_id = r.read_ue()?;
2470
2471 let pps = self.get_pps(header.pic_parameter_set_id).ok_or::<String>(format!(
2472 "Could not get PPS for pic_parameter_set_id {}",
2473 header.pic_parameter_set_id
2474 ))?;
2475
2476 let sps = &pps.sps;
2477
2478 if sps.separate_colour_plane_flag {
2479 header.colour_plane_id = r.read_bits(2)?;
2480 }
2481
2482 header.frame_num = r.read_bits(usize::from(sps.log2_max_frame_num_minus4) + 4)?;
2483
2484 if !sps.frame_mbs_only_flag {
2485 header.field_pic_flag = r.read_bit()?;
2486 if header.field_pic_flag {
2487 header.bottom_field_flag = r.read_bit()?;
2488 }
2489 }
2490
2491 if header.field_pic_flag {
2492 header.max_pic_num = 2 * sps.max_frame_num();
2493 } else {
2494 header.max_pic_num = sps.max_frame_num();
2495 }
2496
2497 if nalu.header.idr_pic_flag {
2498 header.idr_pic_id = r.read_ue_max(0xffff)?;
2499 }
2500
2501 let num_bits_left = r.num_bits_left();
2502 if sps.pic_order_cnt_type == 0 {
2503 header.pic_order_cnt_lsb =
2504 r.read_bits(usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4)?;
2505
2506 if pps.bottom_field_pic_order_in_frame_present_flag && !header.field_pic_flag {
2507 header.delta_pic_order_cnt_bottom = r.read_se()?;
2508 }
2509 }
2510
2511 if sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag {
2512 header.delta_pic_order_cnt[0] = r.read_se()?;
2513 if pps.bottom_field_pic_order_in_frame_present_flag && !header.field_pic_flag {
2514 header.delta_pic_order_cnt[1] = r.read_se()?;
2515 }
2516 }
2517 header.pic_order_cnt_bit_size = num_bits_left - r.num_bits_left();
2518
2519 if pps.redundant_pic_cnt_present_flag {
2520 header.redundant_pic_cnt = r.read_ue_max(127)?;
2521 }
2522
2523 if header.slice_type.is_b() {
2524 header.direct_spatial_mv_pred_flag = r.read_bit()?;
2525 }
2526
2527 if header.slice_type.is_p() || header.slice_type.is_sp() || header.slice_type.is_b() {
2528 header.num_ref_idx_active_override_flag = r.read_bit()?;
2529 if header.num_ref_idx_active_override_flag {
2530 header.num_ref_idx_l0_active_minus1 = r.read_ue()?;
2531 if header.slice_type.is_b() {
2532 header.num_ref_idx_l1_active_minus1 = r.read_ue()?;
2533 }
2534 } else {
2535 header.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1;
2536 if header.slice_type.is_b() {
2537 header.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1;
2538 }
2539 }
2540 }
2541
2542 if header.field_pic_flag {
2543 if header.num_ref_idx_l0_active_minus1 > 31 || header.num_ref_idx_l1_active_minus1 > 31
2544 {
2545 return Err("Broken Data".into());
2546 }
2547 } else if header.num_ref_idx_l0_active_minus1 > 15
2548 || header.num_ref_idx_l1_active_minus1 > 15
2549 {
2550 return Err("Broken Data".into());
2551 }
2552
2553 if let NaluType::SliceExt = nalu.header.type_ {
2554 return Err("Stream contain unsupported/unimplemented NALs".into());
2555 }
2556
2557 Parser::parse_ref_pic_list_modifications(&mut r, &mut header)?;
2558
2559 if (pps.weighted_pred_flag && (header.slice_type.is_p() || header.slice_type.is_sp()))
2560 || (pps.weighted_bipred_idc == 1 && header.slice_type.is_b())
2561 {
2562 Parser::parse_pred_weight_table(&mut r, sps, &mut header)?;
2563 }
2564
2565 if nalu.header.ref_idc != 0 {
2566 Parser::parse_dec_ref_pic_marking(&mut r, &nalu, &mut header)?;
2567 }
2568
2569 if pps.entropy_coding_mode_flag && !header.slice_type.is_i() && !header.slice_type.is_si() {
2570 header.cabac_init_idc = r.read_ue_max(2)?;
2571 }
2572
2573 header.slice_qp_delta = r.read_se_bounded(-87, 77)?;
2574
2575 if header.slice_type.is_sp() || header.slice_type.is_si() {
2576 if header.slice_type.is_sp() {
2577 header.sp_for_switch_flag = r.read_bit()?;
2578 }
2579
2580 header.slice_qs_delta = r.read_se_bounded(-51, 51)?;
2581 }
2582
2583 if pps.deblocking_filter_control_present_flag {
2584 header.disable_deblocking_filter_idc = r.read_ue_max(2)?;
2585
2586 if header.disable_deblocking_filter_idc != 1 {
2587 header.slice_alpha_c0_offset_div2 = r.read_se_bounded(-6, 6)?;
2588 header.slice_beta_offset_div2 = r.read_se_bounded(-6, 6)?;
2589 }
2590 }
2591
2592 if pps.num_slice_groups_minus1 > 0 {
2593 return Err("Stream contain unsupported/unimplemented NALs".into());
2594 }
2595
2596 let epb = r.num_epb();
2597 header.header_bit_size = (nalu.size - epb) * 8 - r.num_bits_left();
2598
2599 header.n_emulation_prevention_bytes = epb;
2600
2601 Ok(Slice { header, nalu })
2602 }
2603
2604 pub fn get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>> {
2605 self.active_spses.get(&sps_id)
2606 }
2607
2608 pub fn get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>> {
2609 self.active_ppses.get(&pps_id)
2610 }
2611}
2612
2613#[derive(Debug)]
2614pub struct NaluHeader {
2615 pub ref_idc: u8,
2616 pub type_: NaluType,
2617 pub idr_pic_flag: bool,
2618}
2619
2620impl Header for NaluHeader {
2621 fn parse<T: AsRef<[u8]>>(cursor: &mut Cursor<T>) -> Result<Self, String> {
2622 let mut byte_buf = [0u8; 1];
2623 cursor.read_exact(&mut byte_buf).map_err(|_| String::from("Broken Data"))?;
2624 let byte = byte_buf[0];
2625 let _ = cursor.seek(SeekFrom::Current(-1 * byte_buf.len() as i64));
2626
2627 let type_ = NaluType::try_from(byte & 0x1f)?;
2628
2629 if let NaluType::SliceExt = type_ {
2630 return Err("Stream contain unsupported/unimplemented NALs".into());
2631 }
2632
2633 let ref_idc = (byte & 0x60) >> 5;
2634 let idr_pic_flag = matches!(type_, NaluType::SliceIdr);
2635
2636 Ok(NaluHeader { ref_idc, type_, idr_pic_flag })
2637 }
2638
2639 fn is_end(&self) -> bool {
2640 matches!(self.type_, NaluType::SeqEnd | NaluType::StreamEnd)
2641 }
2642
2643 fn len(&self) -> usize {
2644 1
2645 }
2646}
2647
2648#[cfg(test)]
2649mod tests {
2650 use std::io::Cursor;
2651
2652 use crate::codec::h264::parser::Level;
2653 use crate::codec::h264::parser::MaxLongTermFrameIdx;
2654 use crate::codec::h264::parser::Nalu;
2655 use crate::codec::h264::parser::NaluType;
2656 use crate::codec::h264::parser::Parser;
2657
2658 const STREAM_TEST_25_FPS: &[u8] = include_bytes!("test_data/test-25fps.h264");
2659 const STREAM_TEST_25_FPS_NUM_NALUS: usize = 759;
2660
2661 const STREAM_TEST_25_FPS_SLICE_0: &[u8] =
2662 include_bytes!("test_data/test-25fps-h264-slice-data-0.bin");
2663 const STREAM_TEST_25_FPS_SLICE_2: &[u8] =
2664 include_bytes!("test_data/test-25fps-h264-slice-data-2.bin");
2665 const STREAM_TEST_25_FPS_SLICE_4: &[u8] =
2666 include_bytes!("test_data/test-25fps-h264-slice-data-4.bin");
2667
2668 #[test]
2670 fn parse_nalus_from_stream_file() {
2671 let mut cursor = Cursor::new(STREAM_TEST_25_FPS);
2672 let mut num_nalus = 0;
2673 while Nalu::next(&mut cursor).is_ok() {
2674 num_nalus += 1;
2675 }
2676
2677 assert_eq!(num_nalus, STREAM_TEST_25_FPS_NUM_NALUS)
2678 }
2679
2680 #[test]
2685 fn parse_test25fps() {
2686 let mut cursor = Cursor::new(STREAM_TEST_25_FPS);
2687 let mut sps_ids = Vec::new();
2688 let mut pps_ids = Vec::new();
2689 let mut slices = Vec::new();
2690
2691 let mut parser = Parser::default();
2692
2693 while let Ok(nalu) = Nalu::next(&mut cursor) {
2694 match nalu.header.type_ {
2695 NaluType::Slice
2696 | NaluType::SliceDpa
2697 | NaluType::SliceDpb
2698 | NaluType::SliceDpc
2699 | NaluType::SliceIdr
2700 | NaluType::SliceExt => {
2701 let slice = parser.parse_slice_header(nalu).unwrap();
2702 slices.push(slice);
2703 }
2704 NaluType::Sps => {
2705 let sps = parser.parse_sps(&nalu).unwrap();
2706 sps_ids.push(sps.seq_parameter_set_id);
2707 }
2708 NaluType::Pps => {
2709 let pps = parser.parse_pps(&nalu).unwrap();
2710 pps_ids.push(pps.pic_parameter_set_id);
2711 }
2712 _ => {
2713 continue;
2714 }
2715 }
2716 }
2717
2718 for sps_id in &sps_ids {
2719 let sps = parser.get_sps(*sps_id).unwrap();
2721
2722 assert_eq!(sps.seq_parameter_set_id, 0);
2723 assert_eq!(sps.profile_idc, 77);
2724 assert!(!sps.constraint_set0_flag);
2725 assert!(sps.constraint_set1_flag);
2726 assert!(!sps.constraint_set2_flag);
2727 assert!(!sps.constraint_set3_flag);
2728 assert!(!sps.constraint_set4_flag);
2729 assert!(!sps.constraint_set5_flag);
2730 assert_eq!(sps.level_idc, Level::L1_3);
2731 assert_eq!(sps.chroma_format_idc, 1);
2732 assert!(!sps.separate_colour_plane_flag);
2733 assert_eq!(sps.bit_depth_luma_minus8, 0);
2734 assert_eq!(sps.bit_depth_chroma_minus8, 0);
2735 assert!(!sps.qpprime_y_zero_transform_bypass_flag);
2736 assert!(!sps.seq_scaling_matrix_present_flag);
2737
2738 for outer in &sps.scaling_lists_4x4 {
2739 for inner in outer {
2740 assert_eq!(*inner, 16);
2741 }
2742 }
2743
2744 for outer in &sps.scaling_lists_8x8 {
2745 for inner in outer {
2746 assert_eq!(*inner, 16);
2747 }
2748 }
2749
2750 assert_eq!(sps.log2_max_frame_num_minus4, 1);
2751 assert_eq!(sps.pic_order_cnt_type, 0);
2752 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 3);
2753 assert!(!sps.delta_pic_order_always_zero_flag);
2754 assert_eq!(sps.offset_for_non_ref_pic, 0);
2755 assert_eq!(sps.offset_for_top_to_bottom_field, 0);
2756 assert_eq!(sps.num_ref_frames_in_pic_order_cnt_cycle, 0);
2757
2758 for offset in sps.offset_for_ref_frame {
2759 assert_eq!(offset, 0);
2760 }
2761
2762 assert_eq!(sps.max_num_ref_frames, 2);
2763 assert!(!sps.gaps_in_frame_num_value_allowed_flag);
2764 assert_eq!(sps.pic_width_in_mbs_minus1, 19);
2765 assert_eq!(sps.pic_height_in_map_units_minus1, 14);
2766 assert!(sps.frame_mbs_only_flag);
2767 assert!(!sps.mb_adaptive_frame_field_flag);
2768 assert!(!sps.direct_8x8_inference_flag);
2769 assert!(!sps.frame_cropping_flag);
2770 assert_eq!(sps.frame_crop_left_offset, 0);
2771 assert_eq!(sps.frame_crop_right_offset, 0);
2772 assert_eq!(sps.frame_crop_top_offset, 0);
2773 assert_eq!(sps.frame_crop_bottom_offset, 0);
2774 assert_eq!(sps.chroma_array_type(), 1);
2775 assert_eq!(sps.max_frame_num(), 32);
2776 assert_eq!(sps.width(), 320);
2777 assert_eq!(sps.height(), 240);
2778 }
2779
2780 for pps_id in &pps_ids {
2781 let pps = parser.get_pps(*pps_id).unwrap();
2783 assert_eq!(pps.pic_parameter_set_id, 0);
2784 assert_eq!(pps.seq_parameter_set_id, 0);
2785 assert!(pps.bottom_field_pic_order_in_frame_present_flag);
2786 assert_eq!(pps.num_slice_groups_minus1, 0);
2787 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0);
2788 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0);
2789 assert!(!pps.weighted_pred_flag);
2790 assert_eq!(pps.weighted_bipred_idc, 0);
2791 assert_eq!(pps.pic_init_qp_minus26, 2);
2792 assert_eq!(pps.pic_init_qs_minus26, 0);
2793 assert_eq!(pps.chroma_qp_index_offset, 0);
2794 assert!(!pps.deblocking_filter_control_present_flag);
2795 assert!(!pps.constrained_intra_pred_flag);
2796 assert!(!pps.redundant_pic_cnt_present_flag);
2797 assert!(!pps.transform_8x8_mode_flag);
2798
2799 for outer in &pps.scaling_lists_4x4 {
2800 for inner in outer {
2801 assert_eq!(*inner, 16);
2802 }
2803 }
2804
2805 for outer in &pps.scaling_lists_8x8 {
2806 for inner in outer {
2807 assert_eq!(*inner, 16);
2808 }
2809 }
2810
2811 assert_eq!(pps.second_chroma_qp_index_offset, 0);
2812 assert!(!pps.pic_scaling_matrix_present_flag);
2813 }
2814
2815 let hdr = &slices[0].header;
2817 let nalu = &slices[0].nalu;
2818 assert_eq!(nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_0);
2819
2820 assert_eq!(hdr.first_mb_in_slice, 0);
2821 assert!(hdr.slice_type.is_i());
2822 assert_eq!(hdr.colour_plane_id, 0);
2823 assert_eq!(hdr.frame_num, 0);
2824 assert!(!hdr.field_pic_flag);
2825 assert!(!hdr.bottom_field_flag);
2826 assert_eq!(hdr.idr_pic_id, 0);
2827 assert_eq!(hdr.pic_order_cnt_lsb, 0);
2828 assert_eq!(hdr.delta_pic_order_cnt_bottom, 0);
2829 assert_eq!(hdr.delta_pic_order_cnt[0], 0);
2830 assert_eq!(hdr.delta_pic_order_cnt[1], 0);
2831 assert_eq!(hdr.redundant_pic_cnt, 0);
2832 assert!(!hdr.direct_spatial_mv_pred_flag);
2833 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
2834 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
2835 assert!(!hdr.ref_pic_list_modification_flag_l0);
2836
2837 assert_eq!(hdr.ref_pic_list_modification_l0.len(), 0);
2838
2839 for rplm in &hdr.ref_pic_list_modification_l0 {
2840 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2841 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2842 assert_eq!(rplm.long_term_pic_num, 0);
2843 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2844 }
2845
2846 assert!(!hdr.ref_pic_list_modification_flag_l1);
2847 assert_eq!(hdr.ref_pic_list_modification_l1.len(), 0);
2848
2849 for rplm in &hdr.ref_pic_list_modification_l1 {
2850 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2851 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2852 assert_eq!(rplm.long_term_pic_num, 0);
2853 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2854 }
2855
2856 assert_eq!(hdr.pred_weight_table, unsafe { std::mem::zeroed() });
2858
2859 assert_eq!(hdr.dec_ref_pic_marking, Default::default());
2860
2861 assert_eq!(hdr.cabac_init_idc, 0);
2862 assert_eq!(hdr.slice_qp_delta, 12);
2863 assert_eq!(hdr.slice_qs_delta, 0);
2864 assert_eq!(hdr.disable_deblocking_filter_idc, 0);
2865 assert_eq!(hdr.slice_alpha_c0_offset_div2, 0);
2866 assert_eq!(hdr.slice_beta_offset_div2, 0);
2867 assert_eq!(hdr.max_pic_num, 32);
2868 assert_eq!(hdr.header_bit_size, 38);
2869 assert!(!hdr.num_ref_idx_active_override_flag);
2870
2871 let hdr = &slices[2].header;
2873 let nalu = &slices[2].nalu;
2874 assert_eq!(nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_2);
2875
2876 assert_eq!(hdr.first_mb_in_slice, 0);
2877 assert!(hdr.slice_type.is_p());
2878 assert_eq!(hdr.colour_plane_id, 0);
2879 assert_eq!(hdr.frame_num, 1);
2880 assert!(!hdr.field_pic_flag);
2881 assert!(!hdr.bottom_field_flag);
2882 assert_eq!(hdr.idr_pic_id, 0);
2883 assert_eq!(hdr.pic_order_cnt_lsb, 4);
2884 assert_eq!(hdr.delta_pic_order_cnt_bottom, 0);
2885 assert_eq!(hdr.delta_pic_order_cnt[0], 0);
2886 assert_eq!(hdr.delta_pic_order_cnt[1], 0);
2887 assert_eq!(hdr.redundant_pic_cnt, 0);
2888 assert!(!hdr.direct_spatial_mv_pred_flag);
2889 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
2890 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
2891 assert!(!hdr.ref_pic_list_modification_flag_l0);
2892
2893 assert_eq!(hdr.ref_pic_list_modification_l0.len(), 0);
2894
2895 for rplm in &hdr.ref_pic_list_modification_l0 {
2896 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2897 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2898 assert_eq!(rplm.long_term_pic_num, 0);
2899 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2900 }
2901
2902 assert!(!hdr.ref_pic_list_modification_flag_l1);
2903 assert_eq!(hdr.ref_pic_list_modification_l1.len(), 0);
2904
2905 for rplm in &hdr.ref_pic_list_modification_l1 {
2906 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2907 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2908 assert_eq!(rplm.long_term_pic_num, 0);
2909 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2910 }
2911
2912 assert_eq!(hdr.pred_weight_table, unsafe { std::mem::zeroed() });
2914
2915 assert_eq!(hdr.dec_ref_pic_marking, Default::default());
2916
2917 assert_eq!(hdr.cabac_init_idc, 0);
2918 assert_eq!(hdr.slice_qp_delta, 0);
2919 assert_eq!(hdr.slice_qs_delta, 0);
2920 assert_eq!(hdr.disable_deblocking_filter_idc, 0);
2921 assert_eq!(hdr.slice_alpha_c0_offset_div2, 0);
2922 assert_eq!(hdr.slice_beta_offset_div2, 0);
2923 assert_eq!(hdr.max_pic_num, 32);
2924 assert_eq!(hdr.header_bit_size, 28);
2925 assert!(!hdr.num_ref_idx_active_override_flag);
2926
2927 let hdr = &slices[4].header;
2929 let nalu = &slices[4].nalu;
2930 assert_eq!(nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_4);
2931
2932 assert_eq!(hdr.first_mb_in_slice, 0);
2933 assert!(hdr.slice_type.is_b());
2934 assert_eq!(hdr.colour_plane_id, 0);
2935 assert_eq!(hdr.frame_num, 2);
2936 assert!(!hdr.field_pic_flag);
2937 assert!(!hdr.bottom_field_flag);
2938 assert_eq!(hdr.idr_pic_id, 0);
2939 assert_eq!(hdr.pic_order_cnt_lsb, 2);
2940 assert_eq!(hdr.delta_pic_order_cnt_bottom, 0);
2941 assert_eq!(hdr.delta_pic_order_cnt[0], 0);
2942 assert_eq!(hdr.delta_pic_order_cnt[1], 0);
2943 assert_eq!(hdr.redundant_pic_cnt, 0);
2944 assert!(hdr.direct_spatial_mv_pred_flag);
2945 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
2946 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
2947 assert!(!hdr.ref_pic_list_modification_flag_l0);
2948
2949 assert_eq!(hdr.ref_pic_list_modification_l0.len(), 0);
2950
2951 for rplm in &hdr.ref_pic_list_modification_l0 {
2952 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2953 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2954 assert_eq!(rplm.long_term_pic_num, 0);
2955 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2956 }
2957
2958 assert!(!hdr.ref_pic_list_modification_flag_l1);
2959 assert_eq!(hdr.ref_pic_list_modification_l1.len(), 0);
2960
2961 for rplm in &hdr.ref_pic_list_modification_l1 {
2962 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2963 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2964 assert_eq!(rplm.long_term_pic_num, 0);
2965 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2966 }
2967
2968 assert_eq!(hdr.pred_weight_table, unsafe { std::mem::zeroed() });
2970
2971 assert_eq!(hdr.dec_ref_pic_marking, Default::default());
2972
2973 assert_eq!(hdr.cabac_init_idc, 0);
2974 assert_eq!(hdr.slice_qp_delta, 16);
2975 assert_eq!(hdr.slice_qs_delta, 0);
2976 assert_eq!(hdr.disable_deblocking_filter_idc, 0);
2977 assert_eq!(hdr.slice_alpha_c0_offset_div2, 0);
2978 assert_eq!(hdr.slice_beta_offset_div2, 0);
2979 assert_eq!(hdr.max_pic_num, 32);
2980 assert_eq!(hdr.header_bit_size, 41);
2981 assert!(!hdr.num_ref_idx_active_override_flag);
2982 }
2983
2984 #[test]
2985 fn invalid_sps_crop_width() {
2986 let invalid_sps =
2990 vec![0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x0a, 0xfb, 0xb0, 0x32, 0xc0, 0xca, 0x80];
2991
2992 let mut cursor = Cursor::new(invalid_sps.as_ref());
2993 let mut parser = Parser::default();
2994
2995 while let Ok(nalu) = Nalu::next(&mut cursor) {
2996 assert_eq!(nalu.header.type_, NaluType::Sps);
2997 parser.parse_sps(&nalu).unwrap_err();
2998 }
2999 }
3000
3001 #[test]
3002 fn max_long_term_frame_idx() {
3003 assert_eq!(
3004 MaxLongTermFrameIdx::from_value_plus1(0),
3005 MaxLongTermFrameIdx::NoLongTermFrameIndices
3006 );
3007 assert_eq!(MaxLongTermFrameIdx::NoLongTermFrameIndices.to_value_plus1(), 0);
3008
3009 assert_eq!(MaxLongTermFrameIdx::from_value_plus1(1), MaxLongTermFrameIdx::Idx(0));
3010 assert_eq!(MaxLongTermFrameIdx::Idx(0).to_value_plus1(), 1);
3011
3012 assert_eq!(MaxLongTermFrameIdx::from_value_plus1(25), MaxLongTermFrameIdx::Idx(24));
3013 assert_eq!(MaxLongTermFrameIdx::Idx(24).to_value_plus1(), 25);
3014
3015 assert!(MaxLongTermFrameIdx::NoLongTermFrameIndices < 0);
3017 assert_ne!(MaxLongTermFrameIdx::NoLongTermFrameIndices, 0);
3018 assert_eq!(MaxLongTermFrameIdx::Idx(0), 0);
3019 assert!(MaxLongTermFrameIdx::Idx(0) < 1);
3020 assert_eq!(MaxLongTermFrameIdx::Idx(24), 24);
3021 assert!(MaxLongTermFrameIdx::Idx(24) < 25);
3022 }
3023}