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] = [6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42];
23
24pub(super) const DEFAULT_4X4_INTER: [u8; 16] = [10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34];
25
26pub(super) const DEFAULT_8X8_INTRA: [u8; 64] = [
27 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27,
28 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33, 33, 33, 33, 33, 36, 36, 36, 36,
29 38, 38, 38, 40, 40, 42,
30];
31
32pub(super) const DEFAULT_8X8_INTER: [u8; 64] = [
33 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24,
34 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, 30, 30, 30,
35 32, 32, 32, 33, 33, 35,
36];
37
38const MAX_PPS_COUNT: u16 = 256;
39const MAX_SPS_COUNT: u8 = 32;
40
41const DPB_MAX_SIZE: usize = 16;
43
44#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
45pub struct Point<T> {
46 pub x: T,
47 pub y: T,
48}
49
50#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
51pub struct Rect<T> {
52 pub min: Point<T>,
53 pub max: Point<T>,
54}
55
56#[derive(Debug, PartialEq, Eq, Clone, Copy)]
57pub enum NaluType {
58 Unknown = 0,
59 Slice = 1,
60 SliceDpa = 2,
61 SliceDpb = 3,
62 SliceDpc = 4,
63 SliceIdr = 5,
64 Sei = 6,
65 Sps = 7,
66 Pps = 8,
67 AuDelimiter = 9,
68 SeqEnd = 10,
69 StreamEnd = 11,
70 FillerData = 12,
71 SpsExt = 13,
72 PrefixUnit = 14,
73 SubsetSps = 15,
74 DepthSps = 16,
75 SliceAux = 19,
76 SliceExt = 20,
77 SliceDepth = 21,
78}
79
80impl TryFrom<u8> for NaluType {
81 type Error = String;
82
83 fn try_from(value: u8) -> Result<Self, Self::Error> {
84 match value {
85 0 => Ok(NaluType::Unknown),
86 1 => Ok(NaluType::Slice),
87 2 => Ok(NaluType::SliceDpa),
88 3 => Ok(NaluType::SliceDpb),
89 4 => Ok(NaluType::SliceDpc),
90 5 => Ok(NaluType::SliceIdr),
91 6 => Ok(NaluType::Sei),
92 7 => Ok(NaluType::Sps),
93 8 => Ok(NaluType::Pps),
94 9 => Ok(NaluType::AuDelimiter),
95 10 => Ok(NaluType::SeqEnd),
96 11 => Ok(NaluType::StreamEnd),
97 12 => Ok(NaluType::FillerData),
98 13 => Ok(NaluType::SpsExt),
99 14 => Ok(NaluType::PrefixUnit),
100 15 => Ok(NaluType::SubsetSps),
101 16 => Ok(NaluType::DepthSps),
102 19 => Ok(NaluType::SliceAux),
103 20 => Ok(NaluType::SliceExt),
104 21 => Ok(NaluType::SliceDepth),
105 _ => Err(format!("Invalid NaluType {}", value)),
106 }
107 }
108}
109
110#[derive(Clone, Debug, Default, PartialEq, Eq)]
111pub struct RefPicListModification {
112 pub modification_of_pic_nums_idc: u8,
113 pub abs_diff_pic_num_minus1: u32,
115 pub long_term_pic_num: u32,
117 pub abs_diff_view_idx_minus1: u32,
119}
120
121#[derive(Clone, Debug, Default, PartialEq, Eq)]
122pub struct PredWeightTable {
123 pub luma_log2_weight_denom: u8,
124 pub chroma_log2_weight_denom: u8,
125
126 pub luma_weight_l0: [i16; 32],
127 pub luma_offset_l0: [i8; 32],
128
129 pub chroma_weight_l0: [[i16; 2]; 32],
131 pub chroma_offset_l0: [[i8; 2]; 32],
132
133 pub luma_weight_l1: [i16; 32],
135 pub luma_offset_l1: [i16; 32],
136
137 pub chroma_weight_l1: [[i16; 2]; 32],
139 pub chroma_offset_l1: [[i8; 2]; 32],
140}
141
142#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
149pub enum MaxLongTermFrameIdx {
150 #[default]
151 NoLongTermFrameIndices,
152 Idx(u32),
153}
154
155impl MaxLongTermFrameIdx {
156 pub fn from_value_plus1(max_long_term_frame_idx_plus1: u32) -> Self {
158 match max_long_term_frame_idx_plus1 {
159 0 => Self::NoLongTermFrameIndices,
160 i @ 1.. => Self::Idx(i - 1),
161 }
162 }
163
164 pub fn to_value_plus1(self) -> u32 {
166 match self {
167 Self::NoLongTermFrameIndices => 0,
168 Self::Idx(i) => i + 1,
169 }
170 }
171}
172
173impl PartialEq<u32> for MaxLongTermFrameIdx {
174 fn eq(&self, other: &u32) -> bool {
175 match self {
176 MaxLongTermFrameIdx::NoLongTermFrameIndices => false,
177 MaxLongTermFrameIdx::Idx(idx) => idx.eq(other),
178 }
179 }
180}
181
182impl PartialOrd<u32> for MaxLongTermFrameIdx {
183 fn partial_cmp(&self, other: &u32) -> Option<std::cmp::Ordering> {
184 match self {
185 MaxLongTermFrameIdx::NoLongTermFrameIndices => Some(std::cmp::Ordering::Less),
186 MaxLongTermFrameIdx::Idx(idx) => Some(idx.cmp(other)),
187 }
188 }
189}
190
191#[derive(Clone, Debug, Default, PartialEq, Eq)]
192pub struct RefPicMarkingInner {
193 pub memory_management_control_operation: u8,
200
201 pub difference_of_pic_nums_minus1: u32,
205
206 pub long_term_pic_num: u32,
209
210 pub long_term_frame_idx: u32,
213
214 pub max_long_term_frame_idx: MaxLongTermFrameIdx,
218}
219
220#[derive(Clone, Debug, Default, PartialEq, Eq)]
221pub struct RefPicMarking {
222 pub no_output_of_prior_pics_flag: bool,
225
226 pub long_term_reference_flag: bool,
233
234 pub adaptive_ref_pic_marking_mode_flag: bool,
237
238 pub inner: Vec<RefPicMarkingInner>,
240}
241
242#[derive(Clone, Debug, Default, PartialEq, Eq)]
243pub struct SliceHeader {
244 pub first_mb_in_slice: u32,
246
247 pub slice_type: SliceType,
249
250 pub pic_parameter_set_id: u8,
252
253 pub colour_plane_id: u8,
256
257 pub frame_num: u16,
260
261 pub field_pic_flag: bool,
264
265 pub bottom_field_flag: bool,
268
269 pub idr_pic_id: u16,
275
276 pub pic_order_cnt_lsb: u16,
281
282 pub delta_pic_order_cnt_bottom: i32,
285
286 pub delta_pic_order_cnt: [i32; 2],
292
293 pub pic_order_cnt_bit_size: usize,
296
297 pub redundant_pic_cnt: u8,
302
303 pub direct_spatial_mv_pred_flag: bool,
306
307 pub num_ref_idx_active_override_flag: bool,
313
314 pub num_ref_idx_l0_active_minus1: u8,
317
318 pub num_ref_idx_l1_active_minus1: u8,
321
322 pub ref_pic_list_modification_flag_l0: bool,
326
327 pub ref_pic_list_modification_l0: Vec<RefPicListModification>,
330
331 pub ref_pic_list_modification_flag_l1: bool,
335
336 pub ref_pic_list_modification_l1: Vec<RefPicListModification>,
339
340 pub pred_weight_table: PredWeightTable,
342
343 pub dec_ref_pic_marking: RefPicMarking,
345
346 pub dec_ref_pic_marking_bit_size: usize,
349
350 pub cabac_init_idc: u8,
353
354 pub slice_qp_delta: i8,
359
360 pub sp_for_switch_flag: bool,
363
364 pub slice_qs_delta: i8,
367
368 pub disable_deblocking_filter_idc: u8,
372
373 pub slice_alpha_c0_offset_div2: i8,
378
379 pub slice_beta_offset_div2: i8,
384
385 pub max_pic_num: u32,
387
388 pub header_bit_size: usize,
390
391 pub n_emulation_prevention_bytes: usize,
393}
394
395impl SliceHeader {
396 pub fn field(&self) -> Field {
398 if self.field_pic_flag {
399 if self.bottom_field_flag {
400 Field::Bottom
401 } else {
402 Field::Top
403 }
404 } else {
405 Field::Frame
406 }
407 }
408}
409
410pub struct SliceHeaderBuilder(SliceHeader);
411
412impl SliceHeaderBuilder {
413 pub fn new(pps: &Pps) -> Self {
414 SliceHeaderBuilder(SliceHeader {
415 pic_parameter_set_id: pps.pic_parameter_set_id,
416 ..Default::default()
417 })
418 }
419
420 pub fn slice_type(mut self, type_: SliceType) -> Self {
421 self.0.slice_type = type_;
422 self
423 }
424
425 pub fn first_mb_in_slice(mut self, value: u32) -> Self {
426 self.0.first_mb_in_slice = value;
427 self
428 }
429
430 pub fn frame_num(mut self, value: u16) -> Self {
431 self.0.frame_num = value;
432 self
433 }
434
435 pub fn pic_order_cnt_lsb(mut self, value: u16) -> Self {
436 self.0.pic_order_cnt_lsb = value;
437 self
438 }
439
440 pub fn idr_pic_id(mut self, value: u16) -> Self {
441 self.0.idr_pic_id = value;
442 self
443 }
444
445 pub fn num_ref_idx_active_override_flag(mut self, value: bool) -> Self {
446 self.0.num_ref_idx_active_override_flag = value;
447 self
448 }
449
450 pub fn num_ref_idx_l0_active_minus1(mut self, value: u8) -> Self {
451 self = self.num_ref_idx_active_override_flag(true);
452 self.0.num_ref_idx_l0_active_minus1 = value;
453 self
454 }
455
456 pub fn num_ref_idx_l0_active(self, value: u8) -> Self {
457 self.num_ref_idx_l0_active_minus1(value - 1)
458 }
459
460 pub fn num_ref_idx_l1_active_minus1(mut self, value: u8) -> Self {
461 self = self.num_ref_idx_active_override_flag(true);
462 self.0.num_ref_idx_l1_active_minus1 = value;
463 self
464 }
465
466 pub fn num_ref_idx_l1_active(self, value: u8) -> Self {
467 self.num_ref_idx_l1_active_minus1(value - 1)
468 }
469
470 pub fn build(self) -> SliceHeader {
471 self.0
472 }
473}
474
475pub struct Slice<'a> {
478 pub header: SliceHeader,
480 pub nalu: Nalu<'a>,
482}
483
484#[derive(Clone, Copy, Debug, PartialEq, Eq)]
485pub enum SliceType {
487 P = 0,
488 B = 1,
489 I = 2,
490 Sp = 3,
491 Si = 4,
492}
493
494impl TryFrom<u8> for SliceType {
495 type Error = String;
496
497 fn try_from(value: u8) -> Result<Self, Self::Error> {
498 match value {
499 0 => Ok(SliceType::P),
500 1 => Ok(SliceType::B),
501 2 => Ok(SliceType::I),
502 3 => Ok(SliceType::Sp),
503 4 => Ok(SliceType::Si),
504 _ => Err(format!("Invalid SliceType {}", value)),
505 }
506 }
507}
508
509impl SliceType {
510 pub fn is_p(&self) -> bool {
512 matches!(self, SliceType::P)
513 }
514
515 pub fn is_b(&self) -> bool {
517 matches!(self, SliceType::B)
518 }
519
520 pub fn is_i(&self) -> bool {
522 matches!(self, SliceType::I)
523 }
524
525 pub fn is_sp(&self) -> bool {
527 matches!(self, SliceType::Sp)
528 }
529
530 pub fn is_si(&self) -> bool {
532 matches!(self, SliceType::Si)
533 }
534}
535
536impl Default for SliceType {
537 fn default() -> Self {
538 Self::P
539 }
540}
541
542#[derive(Clone, Copy, PartialEq, Eq)]
543#[repr(u8)]
544pub enum Profile {
545 Baseline = 66,
546 Main = 77,
547 Extended = 88,
548 High = 100,
549 High10 = 110,
550 High422P = 122,
551}
552
553impl TryFrom<u8> for Profile {
554 type Error = String;
555
556 fn try_from(value: u8) -> Result<Self, Self::Error> {
557 match value {
558 66 => Ok(Profile::Baseline),
559 77 => Ok(Profile::Main),
560 88 => Ok(Profile::Extended),
561 100 => Ok(Profile::High),
562 110 => Ok(Profile::High10),
563 122 => Ok(Profile::High422P),
564 _ => Err(format!("Invalid Profile {}", value)),
565 }
566 }
567}
568
569#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
570pub enum Level {
571 #[default]
572 L1 = 10,
573 L1B = 9,
574 L1_1 = 11,
575 L1_2 = 12,
576 L1_3 = 13,
577 L2_0 = 20,
578 L2_1 = 21,
579 L2_2 = 22,
580 L3 = 30,
581 L3_1 = 31,
582 L3_2 = 32,
583 L4 = 40,
584 L4_1 = 41,
585 L4_2 = 42,
586 L5 = 50,
587 L5_1 = 51,
588 L5_2 = 52,
589 L6 = 60,
590 L6_1 = 61,
591 L6_2 = 62,
592}
593
594impl TryFrom<u8> for Level {
595 type Error = String;
596
597 fn try_from(value: u8) -> Result<Self, Self::Error> {
598 match value {
599 10 => Ok(Level::L1),
600 9 => Ok(Level::L1B),
601 11 => Ok(Level::L1_1),
602 12 => Ok(Level::L1_2),
603 13 => Ok(Level::L1_3),
604 20 => Ok(Level::L2_0),
605 21 => Ok(Level::L2_1),
606 22 => Ok(Level::L2_2),
607 30 => Ok(Level::L3),
608 31 => Ok(Level::L3_1),
609 32 => Ok(Level::L3_2),
610 40 => Ok(Level::L4),
611 41 => Ok(Level::L4_1),
612 42 => Ok(Level::L4_2),
613 50 => Ok(Level::L5),
614 51 => Ok(Level::L5_1),
615 52 => Ok(Level::L5_2),
616 60 => Ok(Level::L6),
617 61 => Ok(Level::L6_1),
618 62 => Ok(Level::L6_2),
619 _ => Err(format!("Invalid Level {}", value)),
620 }
621 }
622}
623
624#[derive(Debug, PartialEq, Eq)]
630pub struct Sps {
631 pub seq_parameter_set_id: u8,
634
635 pub profile_idc: u8,
637
638 pub constraint_set0_flag: bool,
640 pub constraint_set1_flag: bool,
642 pub constraint_set2_flag: bool,
644 pub constraint_set3_flag: bool,
646 pub constraint_set4_flag: bool,
648 pub constraint_set5_flag: bool,
650
651 pub level_idc: Level,
653
654 pub chroma_format_idc: u8,
657
658 pub separate_colour_plane_flag: bool,
661
662 pub bit_depth_luma_minus8: u8,
666
667 pub bit_depth_chroma_minus8: u8,
671
672 pub qpprime_y_zero_transform_bypass_flag: bool,
682
683 pub seq_scaling_matrix_present_flag: bool,
687
688 pub scaling_lists_4x4: [[u8; 16]; 6],
690 pub scaling_lists_8x8: [[u8; 64]; 6],
692
693 pub log2_max_frame_num_minus4: u8,
697
698 pub pic_order_cnt_type: u8,
701
702 pub log2_max_pic_order_cnt_lsb_minus4: u8,
707
708 pub delta_pic_order_always_zero_flag: bool,
715
716 pub offset_for_non_ref_pic: i32,
719
720 pub offset_for_top_to_bottom_field: i32,
723
724 pub num_ref_frames_in_pic_order_cnt_cycle: u8,
727
728 pub offset_for_ref_frame: [i32; 255],
732
733 pub max_num_ref_frames: u8,
740
741 pub gaps_in_frame_num_value_allowed_flag: bool,
745
746 pub pic_width_in_mbs_minus1: u16,
749 pub pic_height_in_map_units_minus1: u16,
752
753 pub frame_mbs_only_flag: bool,
758
759 pub mb_adaptive_frame_field_flag: bool,
763
764 pub direct_8x8_inference_flag: bool,
768
769 pub frame_cropping_flag: bool,
773
774 pub frame_crop_left_offset: u32,
778 pub frame_crop_right_offset: u32,
782 pub frame_crop_top_offset: u32,
786 pub frame_crop_bottom_offset: u32,
790
791 pub expected_delta_per_pic_order_cnt_cycle: i32,
794
795 pub vui_parameters_present_flag: bool,
796 pub vui_parameters: VuiParams,
797}
798
799impl Sps {
800 pub const fn width(&self) -> u32 {
804 (self.pic_width_in_mbs_minus1 as u32 + 1) * 16
805 }
806
807 pub const fn height(&self) -> u32 {
811 (self.pic_height_in_map_units_minus1 as u32 + 1) * 16 * (2 - self.frame_mbs_only_flag as u32)
812 }
813
814 pub const fn chroma_array_type(&self) -> u8 {
816 match self.separate_colour_plane_flag {
817 false => self.chroma_format_idc,
818 true => 0,
819 }
820 }
821
822 fn sub_width_height_c(&self) -> (u32, u32) {
826 match (self.chroma_format_idc, self.separate_colour_plane_flag) {
827 (1, false) => (2, 2),
828 (2, false) => (2, 1),
829 (3, false) => (1, 1),
830 _ => (1, 1),
832 }
833 }
834
835 fn crop_unit_x_y(&self) -> (u32, u32) {
839 match self.chroma_array_type() {
840 0 => (1, 2 - u32::from(self.frame_mbs_only_flag)),
841 _ => {
842 let (sub_width_c, sub_height_c) = self.sub_width_height_c();
843 (sub_width_c, sub_height_c * (2 - u32::from(self.frame_mbs_only_flag)))
844 }
845 }
846 }
847
848 pub fn max_frame_num(&self) -> u32 {
850 1 << (self.log2_max_frame_num_minus4 + 4)
851 }
852
853 pub fn visible_rectangle(&self) -> Rect<u32> {
854 if !self.frame_cropping_flag {
855 return Rect {
856 min: Point { x: 0, y: 0 },
857 max: Point {
858 x: self.width(),
859 y: self.height(),
860 },
861 };
862 }
863
864 let (crop_unit_x, crop_unit_y) = self.crop_unit_x_y();
865
866 let crop_left = crop_unit_x * self.frame_crop_left_offset;
867 let crop_right = crop_unit_x * self.frame_crop_right_offset;
868 let crop_top = crop_unit_y * self.frame_crop_top_offset;
869 let crop_bottom = crop_unit_y * self.frame_crop_bottom_offset;
870
871 Rect {
872 min: Point {
873 x: crop_left,
874 y: crop_top,
875 },
876 max: Point {
877 x: self.width() - crop_left - crop_right,
878 y: self.height() - crop_top - crop_bottom,
879 },
880 }
881 }
882
883 pub fn max_dpb_frames(&self) -> usize {
884 let profile = self.profile_idc;
885 let mut level = self.level_idc;
886
887 if matches!(level, Level::L1_1)
890 && (profile == Profile::Baseline as u8 || profile == Profile::Main as u8)
891 && self.constraint_set3_flag
892 {
893 level = Level::L1B;
894 };
895
896 let max_dpb_mbs = match level {
898 Level::L1 => 396,
899 Level::L1B => 396,
900 Level::L1_1 => 900,
901 Level::L1_2 => 2376,
902 Level::L1_3 => 2376,
903 Level::L2_0 => 2376,
904 Level::L2_1 => 4752,
905 Level::L2_2 => 8100,
906 Level::L3 => 8100,
907 Level::L3_1 => 18000,
908 Level::L3_2 => 20480,
909 Level::L4 => 32768,
910 Level::L4_1 => 32768,
911 Level::L4_2 => 34816,
912 Level::L5 => 110400,
913 Level::L5_1 => 184320,
914 Level::L5_2 => 184320,
915 Level::L6 => 696320,
916 Level::L6_1 => 696320,
917 Level::L6_2 => 696320,
918 };
919
920 let width_mb = self.width() / 16;
921 let height_mb = self.height() / 16;
922
923 let max_dpb_frames = std::cmp::min(max_dpb_mbs / (width_mb * height_mb), DPB_MAX_SIZE as u32) as usize;
924
925 let mut max_dpb_frames = std::cmp::max(max_dpb_frames, self.max_num_ref_frames as usize);
926
927 if self.vui_parameters_present_flag && self.vui_parameters.bitstream_restriction_flag {
928 max_dpb_frames = std::cmp::max(1, self.vui_parameters.max_dec_frame_buffering as usize);
929 }
930
931 max_dpb_frames
932 }
933
934 pub fn max_num_order_frames(&self) -> u32 {
935 let vui = &self.vui_parameters;
936 let present = self.vui_parameters_present_flag && vui.bitstream_restriction_flag;
937
938 if present {
939 vui.max_num_reorder_frames
940 } else {
941 let profile = self.profile_idc;
942 if (profile == 44 || profile == 86 || profile == 100 || profile == 110 || profile == 122 || profile == 244)
943 && self.constraint_set3_flag
944 {
945 0
946 } else {
947 self.max_dpb_frames() as u32
948 }
949 }
950 }
951}
952
953impl Default for Sps {
955 fn default() -> Self {
956 Self {
957 scaling_lists_4x4: [[0; 16]; 6],
958 scaling_lists_8x8: [[0; 64]; 6],
959 offset_for_ref_frame: [0; 255],
960 seq_parameter_set_id: Default::default(),
961 profile_idc: Default::default(),
962 constraint_set0_flag: Default::default(),
963 constraint_set1_flag: Default::default(),
964 constraint_set2_flag: Default::default(),
965 constraint_set3_flag: Default::default(),
966 constraint_set4_flag: Default::default(),
967 constraint_set5_flag: Default::default(),
968 level_idc: Default::default(),
969 chroma_format_idc: Default::default(),
970 separate_colour_plane_flag: Default::default(),
971 bit_depth_luma_minus8: Default::default(),
972 bit_depth_chroma_minus8: Default::default(),
973 qpprime_y_zero_transform_bypass_flag: Default::default(),
974 seq_scaling_matrix_present_flag: Default::default(),
975 log2_max_frame_num_minus4: Default::default(),
976 pic_order_cnt_type: Default::default(),
977 log2_max_pic_order_cnt_lsb_minus4: Default::default(),
978 delta_pic_order_always_zero_flag: Default::default(),
979 offset_for_non_ref_pic: Default::default(),
980 offset_for_top_to_bottom_field: Default::default(),
981 num_ref_frames_in_pic_order_cnt_cycle: Default::default(),
982 max_num_ref_frames: Default::default(),
983 gaps_in_frame_num_value_allowed_flag: Default::default(),
984 pic_width_in_mbs_minus1: Default::default(),
985 pic_height_in_map_units_minus1: Default::default(),
986 frame_mbs_only_flag: Default::default(),
987 mb_adaptive_frame_field_flag: Default::default(),
988 direct_8x8_inference_flag: Default::default(),
989 frame_cropping_flag: Default::default(),
990 frame_crop_left_offset: Default::default(),
991 frame_crop_right_offset: Default::default(),
992 frame_crop_top_offset: Default::default(),
993 frame_crop_bottom_offset: Default::default(),
994 expected_delta_per_pic_order_cnt_cycle: Default::default(),
995 vui_parameters_present_flag: Default::default(),
996 vui_parameters: Default::default(),
997 }
998 }
999}
1000
1001#[derive(Default)]
1002pub struct SpsBuilder(Sps);
1003
1004impl SpsBuilder {
1005 pub fn new() -> Self {
1006 Default::default()
1007 }
1008
1009 pub fn seq_parameter_set_id(mut self, value: u8) -> Self {
1010 self.0.seq_parameter_set_id = value;
1011 self
1012 }
1013
1014 pub fn profile_idc(mut self, value: Profile) -> Self {
1015 self.0.profile_idc = value as u8;
1016 self
1017 }
1018
1019 pub fn level_idc(mut self, value: Level) -> Self {
1020 self.0.level_idc = value;
1021 self
1022 }
1023
1024 pub fn frame_crop_offsets(mut self, top: u32, bottom: u32, left: u32, right: u32) -> Self {
1025 self.0.frame_cropping_flag = true;
1026 self.0.frame_crop_top_offset = top;
1027 self.0.frame_crop_bottom_offset = bottom;
1028 self.0.frame_crop_left_offset = left;
1029 self.0.frame_crop_right_offset = right;
1030 self
1031 }
1032
1033 pub fn frame_crop(self, top: u32, bottom: u32, left: u32, right: u32) -> Self {
1034 let sub_width_c = if self.0.chroma_format_idc > 2 { 1 } else { 2 };
1035 let sub_height_c = if self.0.chroma_format_idc > 1 { 1 } else { 2 };
1036
1037 let crop_unit_x = sub_width_c;
1038 let crop_unit_y = sub_height_c * (if self.0.frame_mbs_only_flag { 1 } else { 2 });
1039
1040 self.frame_crop_offsets(
1041 top / crop_unit_y,
1042 bottom / crop_unit_y,
1043 left / crop_unit_x,
1044 right / crop_unit_x,
1045 )
1046 }
1047
1048 pub fn resolution(mut self, width: u32, height: u32) -> Self {
1049 const MB_SIZE: u32 = 16;
1050
1051 let mb_width = (width + MB_SIZE - 1) / MB_SIZE;
1052 let mb_height = (height + MB_SIZE - 1) / MB_SIZE;
1053
1054 self.0.pic_width_in_mbs_minus1 = (mb_width - 1) as u16;
1055 self.0.pic_height_in_map_units_minus1 = (mb_height - 1) as u16;
1056
1057 let compressed_width = mb_width * MB_SIZE;
1058 let compressed_height = mb_height * MB_SIZE;
1059
1060 if compressed_width != width || compressed_height != height {
1061 self = self.frame_crop(0, compressed_height - height, 0, compressed_width - width);
1062 }
1063
1064 self
1065 }
1066
1067 pub fn chroma_format_idc(mut self, value: u8) -> Self {
1068 self.0.chroma_format_idc = value;
1069 self
1070 }
1071
1072 pub fn max_num_ref_frames(mut self, value: u8) -> Self {
1073 self.0.max_num_ref_frames = value;
1074 self
1075 }
1076
1077 pub fn frame_mbs_only_flag(mut self, value: bool) -> Self {
1078 self.0.frame_mbs_only_flag = value;
1079 self
1080 }
1081
1082 pub fn mb_adaptive_frame_field_flag(mut self, value: bool) -> Self {
1083 self.0.mb_adaptive_frame_field_flag = value;
1084 self
1085 }
1086
1087 pub fn seq_scaling_matrix_present_flag(mut self, value: bool) -> Self {
1088 self.0.seq_scaling_matrix_present_flag = value;
1089 self
1090 }
1091
1092 pub fn direct_8x8_inference_flag(mut self, value: bool) -> Self {
1093 self.0.direct_8x8_inference_flag = value;
1094 self
1095 }
1096
1097 pub fn vui_parameters_present(mut self) -> Self {
1098 if self.0.vui_parameters_present_flag {
1099 return self;
1100 }
1101
1102 self.0.vui_parameters_present_flag = true;
1103 self.0.vui_parameters.aspect_ratio_info_present_flag = false;
1105 self.0.vui_parameters.overscan_info_present_flag = false;
1106 self.0.vui_parameters.video_signal_type_present_flag = false;
1107 self.0.vui_parameters.colour_description_present_flag = false;
1108 self.0.vui_parameters.chroma_loc_info_present_flag = false;
1109 self.0.vui_parameters.timing_info_present_flag = false;
1110 self.0.vui_parameters.nal_hrd_parameters_present_flag = false;
1111 self.0.vui_parameters.vcl_hrd_parameters_present_flag = false;
1112 self.0.vui_parameters.pic_struct_present_flag = false;
1113 self.0.vui_parameters.bitstream_restriction_flag = false;
1114 self
1115 }
1116
1117 pub fn aspect_ratio_idc(mut self, value: u8) -> Self {
1118 self = self.vui_parameters_present();
1119 self.0.vui_parameters.aspect_ratio_info_present_flag = true;
1120 self.0.vui_parameters.aspect_ratio_idc = value;
1121 self
1122 }
1123
1124 pub fn sar_resolution(mut self, width: u16, height: u16) -> Self {
1125 self = self.aspect_ratio_idc(255);
1126 self.0.vui_parameters.sar_width = width;
1127 self.0.vui_parameters.sar_height = height;
1128 self
1129 }
1130
1131 pub fn aspect_ratio(self, width_ratio: u16, height_ratio: u16) -> Self {
1132 match (width_ratio, height_ratio) {
1134 (1, 1) => self.aspect_ratio_idc(1),
1135 (12, 11) => self.aspect_ratio_idc(2),
1136 (10, 11) => self.aspect_ratio_idc(3),
1137 (16, 11) => self.aspect_ratio_idc(4),
1138 (40, 33) => self.aspect_ratio_idc(5),
1139 (24, 11) => self.aspect_ratio_idc(6),
1140 (20, 11) => self.aspect_ratio_idc(7),
1141 (32, 11) => self.aspect_ratio_idc(8),
1142 (80, 33) => self.aspect_ratio_idc(9),
1143 (18, 11) => self.aspect_ratio_idc(10),
1144 (15, 11) => self.aspect_ratio_idc(11),
1145 (64, 33) => self.aspect_ratio_idc(12),
1146 (160, 99) => self.aspect_ratio_idc(13),
1147 (4, 3) => self.aspect_ratio_idc(14),
1148 (3, 2) => self.aspect_ratio_idc(15),
1149 (2, 1) => self.aspect_ratio_idc(16),
1150
1151 _ => self.sar_resolution(width_ratio, height_ratio),
1152 }
1153 }
1154
1155 pub fn timing_info(mut self, num_units_in_tick: u32, time_scale: u32, fixed_frame_rate_flag: bool) -> Self {
1156 self = self.vui_parameters_present();
1157 self.0.vui_parameters.timing_info_present_flag = true;
1158 self.0.vui_parameters.num_units_in_tick = num_units_in_tick;
1159 self.0.vui_parameters.time_scale = time_scale;
1160 self.0.vui_parameters.fixed_frame_rate_flag = fixed_frame_rate_flag;
1161 self
1162 }
1163
1164 pub fn video_signal_type(
1170 mut self,
1171 full_range: bool,
1172 colour_primaries: u8,
1173 transfer_characteristics: u8,
1174 matrix_coefficients: u8,
1175 ) -> Self {
1176 self = self.vui_parameters_present();
1177 self.0.vui_parameters.video_signal_type_present_flag = true;
1178 self.0.vui_parameters.video_format = 5;
1179 self.0.vui_parameters.video_full_range_flag = full_range;
1180 self.0.vui_parameters.colour_description_present_flag = true;
1181 self.0.vui_parameters.colour_primaries = colour_primaries;
1182 self.0.vui_parameters.transfer_characteristics = transfer_characteristics;
1183 self.0.vui_parameters.matrix_coefficients = matrix_coefficients;
1184 self
1185 }
1186
1187 pub fn bitstream_restrictions_present(mut self) -> Self {
1188 if self.0.vui_parameters.bitstream_restriction_flag {
1189 return self;
1190 }
1191 self = self.vui_parameters_present();
1192 self.0.vui_parameters.max_num_reorder_frames = self.0.max_num_order_frames();
1195 self.0.vui_parameters.max_dec_frame_buffering = self.0.vui_parameters.max_num_reorder_frames;
1196 self.0.vui_parameters.bitstream_restriction_flag = true;
1197 self.0.vui_parameters.motion_vectors_over_pic_boundaries_flag = true;
1199 self.0.vui_parameters.max_bytes_per_pic_denom = 2;
1200 self.0.vui_parameters.max_bits_per_mb_denom = 1;
1201 self.0.vui_parameters.log2_max_mv_length_horizontal = 16;
1202 self.0.vui_parameters.log2_max_mv_length_vertical = 16;
1203 self
1204 }
1205
1206 pub fn max_num_reorder_frames(mut self, value: u32) -> Self {
1207 self = self.bitstream_restrictions_present();
1208 self.0.vui_parameters.max_num_reorder_frames = value;
1209 self
1210 }
1211
1212 pub fn max_dec_frame_buffering(mut self, value: u32) -> Self {
1213 self = self.bitstream_restrictions_present();
1214 self.0.vui_parameters.max_dec_frame_buffering = value;
1215 self
1216 }
1217
1218 pub fn log2_max_frame_num_minus4(mut self, value: u8) -> Self {
1219 self.0.log2_max_frame_num_minus4 = value;
1220 self
1221 }
1222
1223 pub fn max_frame_num(self, value: u32) -> Self {
1224 self.log2_max_frame_num_minus4(value.ilog2() as u8 - 4u8)
1225 }
1226
1227 pub fn pic_order_cnt_type(mut self, value: u8) -> Self {
1228 self.0.pic_order_cnt_type = value;
1229 self
1230 }
1231
1232 pub fn log2_max_pic_order_cnt_lsb_minus4(mut self, value: u8) -> Self {
1233 self.0.log2_max_pic_order_cnt_lsb_minus4 = value;
1234 self
1235 }
1236
1237 pub fn max_pic_order_cnt_lsb(self, value: u32) -> Self {
1238 self.log2_max_pic_order_cnt_lsb_minus4(value.ilog2() as u8 - 4u8)
1239 }
1240
1241 pub fn delta_pic_order_always_zero_flag(mut self, value: bool) -> Self {
1242 self.0.delta_pic_order_always_zero_flag = value;
1243 self
1244 }
1245
1246 pub fn bit_depth_chroma_minus8(mut self, value: u8) -> Self {
1247 self.0.bit_depth_chroma_minus8 = value;
1248 self
1249 }
1250
1251 pub fn bit_depth_chroma(self, value: u8) -> Self {
1252 self.bit_depth_luma_minus8(value - 8u8)
1253 }
1254
1255 pub fn bit_depth_luma_minus8(mut self, value: u8) -> Self {
1256 self.0.bit_depth_luma_minus8 = value;
1257 self
1258 }
1259
1260 pub fn bit_depth_luma(self, value: u8) -> Self {
1261 self.bit_depth_luma_minus8(value - 8u8)
1262 }
1263
1264 pub fn build(self) -> Rc<Sps> {
1265 Rc::new(self.0)
1266 }
1267}
1268
1269#[derive(Clone, Debug, Default, PartialEq, Eq)]
1270pub struct HrdParams {
1271 pub cpb_cnt_minus1: u8,
1275 pub bit_rate_scale: u8,
1278 pub cpb_size_scale: u8,
1281
1282 pub bit_rate_value_minus1: [u32; 32],
1285 pub cpb_size_value_minus1: [u32; 32],
1288 pub cbr_flag: [bool; 32],
1294
1295 pub initial_cpb_removal_delay_length_minus1: u8,
1299 pub cpb_removal_delay_length_minus1: u8,
1301 pub dpb_output_delay_length_minus1: u8,
1303 pub time_offset_length: u8,
1307}
1308
1309#[derive(Clone, Debug, PartialEq, Eq)]
1310pub struct VuiParams {
1311 pub aspect_ratio_info_present_flag: bool,
1313 pub aspect_ratio_idc: u8,
1319
1320 pub sar_width: u16,
1324 pub sar_height: u16,
1327
1328 pub overscan_info_present_flag: bool,
1331 pub overscan_appropriate_flag: bool,
1339
1340 pub video_signal_type_present_flag: bool,
1343 pub video_format: u8,
1348 pub video_full_range_flag: bool,
1352 pub colour_description_present_flag: bool,
1355 pub colour_primaries: u8,
1359 pub transfer_characteristics: u8,
1361 pub matrix_coefficients: u8,
1365
1366 pub chroma_loc_info_present_flag: bool,
1369 pub chroma_sample_loc_type_top_field: u8,
1371 pub chroma_sample_loc_type_bottom_field: u8,
1373
1374 pub timing_info_present_flag: bool,
1377 pub num_units_in_tick: u32,
1382 pub time_scale: u32,
1386 pub fixed_frame_rate_flag: bool,
1388
1389 pub nal_hrd_parameters_present_flag: bool,
1392 pub nal_hrd_parameters: HrdParams,
1395 pub vcl_hrd_parameters_present_flag: bool,
1398 pub vcl_hrd_parameters: HrdParams,
1401
1402 pub low_delay_hrd_flag: bool,
1404
1405 pub pic_struct_present_flag: bool,
1408
1409 pub bitstream_restriction_flag: bool,
1412 pub motion_vectors_over_pic_boundaries_flag: bool,
1422 pub max_bytes_per_pic_denom: u32,
1426 pub max_bits_per_mb_denom: u32,
1430 pub log2_max_mv_length_horizontal: u32,
1432 pub log2_max_mv_length_vertical: u32,
1434 pub max_num_reorder_frames: u32,
1455 pub max_dec_frame_buffering: u32,
1477}
1478
1479impl Default for VuiParams {
1480 fn default() -> Self {
1481 Self {
1482 aspect_ratio_info_present_flag: Default::default(),
1483 aspect_ratio_idc: Default::default(),
1484 sar_width: Default::default(),
1485 sar_height: Default::default(),
1486 overscan_info_present_flag: Default::default(),
1487 overscan_appropriate_flag: Default::default(),
1488 video_signal_type_present_flag: Default::default(),
1489 video_format: 5,
1490 video_full_range_flag: Default::default(),
1491 colour_description_present_flag: Default::default(),
1492 colour_primaries: 2,
1493 transfer_characteristics: 2,
1494 matrix_coefficients: 2,
1495 chroma_loc_info_present_flag: Default::default(),
1496 chroma_sample_loc_type_top_field: Default::default(),
1497 chroma_sample_loc_type_bottom_field: Default::default(),
1498 timing_info_present_flag: Default::default(),
1499 num_units_in_tick: Default::default(),
1500 time_scale: Default::default(),
1501 fixed_frame_rate_flag: Default::default(),
1502 nal_hrd_parameters_present_flag: Default::default(),
1503 nal_hrd_parameters: Default::default(),
1504 vcl_hrd_parameters_present_flag: Default::default(),
1505 vcl_hrd_parameters: Default::default(),
1506 low_delay_hrd_flag: Default::default(),
1507 pic_struct_present_flag: Default::default(),
1508 bitstream_restriction_flag: Default::default(),
1509 motion_vectors_over_pic_boundaries_flag: Default::default(),
1510 max_bytes_per_pic_denom: Default::default(),
1511 max_bits_per_mb_denom: Default::default(),
1512 log2_max_mv_length_horizontal: Default::default(),
1513 log2_max_mv_length_vertical: Default::default(),
1514 max_num_reorder_frames: Default::default(),
1515 max_dec_frame_buffering: Default::default(),
1516 }
1517 }
1518}
1519
1520#[derive(Debug, PartialEq, Eq)]
1524pub struct Pps {
1525 pub pic_parameter_set_id: u8,
1527
1528 pub seq_parameter_set_id: u8,
1530
1531 pub entropy_coding_mode_flag: bool,
1539
1540 pub bottom_field_pic_order_in_frame_present_flag: bool,
1548
1549 pub num_slice_groups_minus1: u32,
1554
1555 pub num_ref_idx_l0_default_active_minus1: u8,
1558
1559 pub num_ref_idx_l1_default_active_minus1: u8,
1562
1563 pub weighted_pred_flag: bool,
1567
1568 pub weighted_bipred_idc: u8,
1574
1575 pub pic_init_qp_minus26: i8,
1580
1581 pub pic_init_qs_minus26: i8,
1585
1586 pub chroma_qp_index_offset: i8,
1589
1590 pub deblocking_filter_control_present_flag: bool,
1596
1597 pub constrained_intra_pred_flag: bool,
1605
1606 pub redundant_pic_cnt_present_flag: bool,
1617
1618 pub transform_8x8_mode_flag: bool,
1622
1623 pub pic_scaling_matrix_present_flag: bool,
1628
1629 pub scaling_lists_4x4: [[u8; 16]; 6],
1631 pub scaling_lists_8x8: [[u8; 64]; 6],
1633
1634 pub second_chroma_qp_index_offset: i8,
1639
1640 pub sps: Rc<Sps>,
1642}
1643
1644pub struct PpsBuilder(Pps);
1645
1646impl PpsBuilder {
1647 pub fn new(sps: Rc<Sps>) -> Self {
1648 PpsBuilder(Pps {
1649 pic_parameter_set_id: 0,
1650 seq_parameter_set_id: sps.seq_parameter_set_id,
1651 entropy_coding_mode_flag: false,
1652 bottom_field_pic_order_in_frame_present_flag: false,
1653 num_slice_groups_minus1: 0,
1654 num_ref_idx_l0_default_active_minus1: 0,
1655 num_ref_idx_l1_default_active_minus1: 0,
1656 weighted_pred_flag: false,
1657 weighted_bipred_idc: 0,
1658 pic_init_qp_minus26: 0,
1659 pic_init_qs_minus26: 0,
1660 chroma_qp_index_offset: 0,
1661 deblocking_filter_control_present_flag: false,
1662 constrained_intra_pred_flag: false,
1663 redundant_pic_cnt_present_flag: false,
1664 transform_8x8_mode_flag: false,
1665 pic_scaling_matrix_present_flag: false,
1666 scaling_lists_4x4: [[0; 16]; 6],
1667 scaling_lists_8x8: [[0; 64]; 6],
1668 second_chroma_qp_index_offset: 0,
1669 sps,
1670 })
1671 }
1672
1673 pub fn pic_parameter_set_id(mut self, value: u8) -> Self {
1674 self.0.pic_parameter_set_id = value;
1675 self
1676 }
1677
1678 pub fn pic_init_qp_minus26(mut self, value: i8) -> Self {
1679 self.0.pic_init_qp_minus26 = value;
1680 self
1681 }
1682
1683 pub fn pic_init_qp(self, value: u8) -> Self {
1684 self.pic_init_qp_minus26(value as i8 - 26)
1685 }
1686
1687 pub fn entropy_coding_mode_flag(mut self, value: bool) -> Self {
1688 self.0.entropy_coding_mode_flag = value;
1689 self
1690 }
1691
1692 pub fn transform_8x8_mode_flag(mut self, value: bool) -> Self {
1693 self.0.transform_8x8_mode_flag = value;
1694 self
1695 }
1696
1697 pub fn deblocking_filter_control_present_flag(mut self, value: bool) -> Self {
1698 self.0.deblocking_filter_control_present_flag = value;
1699 self
1700 }
1701
1702 pub fn num_ref_idx_l0_default_active_minus1(mut self, value: u8) -> Self {
1703 self.0.num_ref_idx_l0_default_active_minus1 = value;
1704 self
1705 }
1706
1707 pub fn num_ref_idx_l0_default_active(self, value: u8) -> Self {
1708 self.num_ref_idx_l0_default_active_minus1(value - 1)
1709 }
1710
1711 pub fn num_ref_idx_l1_default_active_minus1(mut self, value: u8) -> Self {
1712 self.0.num_ref_idx_l1_default_active_minus1 = value;
1713 self
1714 }
1715
1716 pub fn num_ref_idx_l1_default_active(self, value: u8) -> Self {
1717 self.num_ref_idx_l1_default_active_minus1(value - 1)
1718 }
1719
1720 pub fn build(self) -> Rc<Pps> {
1721 Rc::new(self.0)
1722 }
1723}
1724
1725#[derive(Debug, Default)]
1726pub struct Parser {
1727 active_spses: BTreeMap<u8, Rc<Sps>>,
1728 active_ppses: BTreeMap<u8, Rc<Pps>>,
1729}
1730
1731impl Parser {
1732 fn fill_default_scaling_list_4x4(scaling_list4x4: &mut [u8; 16], i: usize) {
1733 assert!(i < 6);
1735 if i < 3 {
1736 *scaling_list4x4 = DEFAULT_4X4_INTRA;
1737 } else if i < 6 {
1738 *scaling_list4x4 = DEFAULT_4X4_INTER;
1739 }
1740 }
1741
1742 fn fill_default_scaling_list_8x8(scaling_list8x8: &mut [u8; 64], i: usize) {
1743 assert!(i < 6);
1744 if i % 2 == 0 {
1745 *scaling_list8x8 = DEFAULT_8X8_INTRA;
1746 } else {
1747 *scaling_list8x8 = DEFAULT_8X8_INTER;
1748 }
1749 }
1750
1751 fn fill_fallback_scaling_list_4x4(
1752 scaling_list4x4: &mut [[u8; 16]; 6],
1753 i: usize,
1754 default_scaling_list_intra: &[u8; 16],
1755 default_scaling_list_inter: &[u8; 16],
1756 ) {
1757 scaling_list4x4[i] = match i {
1759 0 => *default_scaling_list_intra,
1760 1 => scaling_list4x4[0],
1761 2 => scaling_list4x4[1],
1762 3 => *default_scaling_list_inter,
1763 4 => scaling_list4x4[3],
1764 5 => scaling_list4x4[4],
1765 _ => panic!("Unexpected value {}", i),
1766 }
1767 }
1768
1769 fn fill_fallback_scaling_list_8x8(
1770 scaling_list8x8: &mut [[u8; 64]; 6],
1771 i: usize,
1772 default_scaling_list_intra: &[u8; 64],
1773 default_scaling_list_inter: &[u8; 64],
1774 ) {
1775 scaling_list8x8[i] = match i {
1777 0 => *default_scaling_list_intra,
1778 1 => *default_scaling_list_inter,
1779 2 => scaling_list8x8[0],
1780 3 => scaling_list8x8[1],
1781 4 => scaling_list8x8[2],
1782 5 => scaling_list8x8[3],
1783 _ => panic!("Unexpected value {}", i),
1784 }
1785 }
1786
1787 fn fill_scaling_list_flat(scaling_list4x4: &mut [[u8; 16]; 6], scaling_list8x8: &mut [[u8; 64]; 6]) {
1788 for outer in scaling_list4x4 {
1790 for inner in outer {
1791 *inner = 16;
1792 }
1793 }
1794
1795 for outer in scaling_list8x8 {
1797 for inner in outer {
1798 *inner = 16;
1799 }
1800 }
1801 }
1802
1803 fn parse_scaling_list<U: AsMut<[u8]>>(
1804 r: &mut BitReader,
1805 scaling_list: &mut U,
1806 use_default: &mut bool,
1807 ) -> Result<(), String> {
1808 let mut last_scale = 8u8;
1810 let mut next_scale = 8u8;
1811
1812 for j in 0..scaling_list.as_mut().len() {
1813 if next_scale != 0 {
1814 let delta_scale = r.read_se::<i32>()?;
1815 next_scale = ((last_scale as i32 + delta_scale + 256) % 256) as u8;
1816 *use_default = j == 0 && next_scale == 0;
1817 if *use_default {
1818 return Ok(());
1819 }
1820 }
1821
1822 scaling_list.as_mut()[j] = if next_scale == 0 { last_scale } else { next_scale };
1823
1824 last_scale = scaling_list.as_mut()[j];
1825 }
1826
1827 Ok(())
1828 }
1829
1830 fn parse_sps_scaling_lists(r: &mut BitReader, sps: &mut Sps) -> Result<(), String> {
1831 let scaling_lists4x4 = &mut sps.scaling_lists_4x4;
1832 let scaling_lisst8x8 = &mut sps.scaling_lists_8x8;
1833
1834 for i in 0..6 {
1836 let seq_scaling_list_present_flag = r.read_bit()?;
1837 if seq_scaling_list_present_flag {
1838 let mut use_default = false;
1839
1840 Parser::parse_scaling_list(r, &mut scaling_lists4x4[i], &mut use_default)?;
1841
1842 if use_default {
1843 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1844 }
1845 } else {
1846 Parser::fill_fallback_scaling_list_4x4(scaling_lists4x4, i, &DEFAULT_4X4_INTRA, &DEFAULT_4X4_INTER);
1847 }
1848 }
1849
1850 let num_8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
1852 for i in 0..num_8x8 {
1853 let seq_scaling_list_present_flag = r.read_bit()?;
1854 if seq_scaling_list_present_flag {
1855 let mut use_default = false;
1856 Parser::parse_scaling_list(r, &mut scaling_lisst8x8[i], &mut use_default)?;
1857
1858 if use_default {
1859 Parser::fill_default_scaling_list_8x8(&mut scaling_lisst8x8[i], i);
1860 }
1861 } else {
1862 Parser::fill_fallback_scaling_list_8x8(scaling_lisst8x8, i, &DEFAULT_8X8_INTRA, &DEFAULT_8X8_INTER);
1863 }
1864 }
1865 Ok(())
1866 }
1867
1868 fn parse_pps_scaling_lists(r: &mut BitReader, pps: &mut Pps, sps: &Sps) -> Result<(), String> {
1869 let scaling_lists4x4 = &mut pps.scaling_lists_4x4;
1870 let scaling_lists8x8 = &mut pps.scaling_lists_8x8;
1871
1872 for i in 0..6 {
1873 let pic_scaling_list_present_flag = r.read_bit()?;
1874 if pic_scaling_list_present_flag {
1875 let mut use_default = false;
1876
1877 Parser::parse_scaling_list(r, &mut scaling_lists4x4[i], &mut use_default)?;
1878
1879 if use_default {
1880 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1881 }
1882 } else if !sps.seq_scaling_matrix_present_flag {
1883 Parser::fill_fallback_scaling_list_4x4(scaling_lists4x4, i, &DEFAULT_4X4_INTRA, &DEFAULT_4X4_INTER);
1885 } else {
1886 Parser::fill_fallback_scaling_list_4x4(
1888 scaling_lists4x4,
1889 i,
1890 &sps.scaling_lists_4x4[0],
1891 &sps.scaling_lists_4x4[3],
1892 );
1893 }
1894 }
1895
1896 if pps.transform_8x8_mode_flag {
1897 let num8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
1898
1899 for i in 0..num8x8 {
1900 let pic_scaling_list_present_flag = r.read_bit()?;
1901 if pic_scaling_list_present_flag {
1902 let mut use_default = false;
1903
1904 Parser::parse_scaling_list(r, &mut scaling_lists8x8[i], &mut use_default)?;
1905
1906 if use_default {
1907 Parser::fill_default_scaling_list_8x8(&mut scaling_lists8x8[i], i);
1908 }
1909 } else if !sps.seq_scaling_matrix_present_flag {
1910 Parser::fill_fallback_scaling_list_8x8(scaling_lists8x8, i, &DEFAULT_8X8_INTRA, &DEFAULT_8X8_INTER);
1912 } else {
1913 Parser::fill_fallback_scaling_list_8x8(
1915 scaling_lists8x8,
1916 i,
1917 &sps.scaling_lists_8x8[0],
1918 &sps.scaling_lists_8x8[1],
1919 );
1920 }
1921 }
1922 }
1923
1924 Ok(())
1925 }
1926
1927 fn parse_hrd(r: &mut BitReader, hrd: &mut HrdParams) -> Result<(), String> {
1928 hrd.cpb_cnt_minus1 = r.read_ue_max(31)?;
1929 hrd.bit_rate_scale = r.read_bits(4)?;
1930 hrd.cpb_size_scale = r.read_bits(4)?;
1931
1932 for sched_sel_idx in 0..=usize::from(hrd.cpb_cnt_minus1) {
1933 hrd.bit_rate_value_minus1[sched_sel_idx] = r.read_ue()?;
1934 hrd.cpb_size_value_minus1[sched_sel_idx] = r.read_ue()?;
1935 hrd.cbr_flag[sched_sel_idx] = r.read_bit()?;
1936 }
1937
1938 hrd.initial_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
1939 hrd.cpb_removal_delay_length_minus1 = r.read_bits(5)?;
1940 hrd.dpb_output_delay_length_minus1 = r.read_bits(5)?;
1941 hrd.time_offset_length = r.read_bits(5)?;
1942 Ok(())
1943 }
1944
1945 fn parse_vui(r: &mut BitReader, sps: &mut Sps) -> Result<(), String> {
1946 let vui = &mut sps.vui_parameters;
1947
1948 vui.aspect_ratio_info_present_flag = r.read_bit()?;
1949 if vui.aspect_ratio_info_present_flag {
1950 vui.aspect_ratio_idc = r.read_bits(8)?;
1951 if vui.aspect_ratio_idc == 255 {
1952 vui.sar_width = r.read_bits(16)?;
1953 vui.sar_height = r.read_bits(16)?;
1954 }
1955 }
1956
1957 vui.overscan_info_present_flag = r.read_bit()?;
1958 if vui.overscan_info_present_flag {
1959 vui.overscan_appropriate_flag = r.read_bit()?;
1960 }
1961
1962 vui.video_signal_type_present_flag = r.read_bit()?;
1963 if vui.video_signal_type_present_flag {
1964 vui.video_format = r.read_bits(3)?;
1965 vui.video_full_range_flag = r.read_bit()?;
1966 vui.colour_description_present_flag = r.read_bit()?;
1967 if vui.colour_description_present_flag {
1968 vui.colour_primaries = r.read_bits(8)?;
1969 vui.transfer_characteristics = r.read_bits(8)?;
1970 vui.matrix_coefficients = r.read_bits(8)?;
1971 }
1972 }
1973
1974 vui.chroma_loc_info_present_flag = r.read_bit()?;
1975 if vui.chroma_loc_info_present_flag {
1976 vui.chroma_sample_loc_type_top_field = r.read_ue_max(5)?;
1977 vui.chroma_sample_loc_type_bottom_field = r.read_ue_max(5)?;
1978 }
1979
1980 vui.timing_info_present_flag = r.read_bit()?;
1981 if vui.timing_info_present_flag {
1982 vui.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
1983 vui.num_units_in_tick |= r.read_bit()? as u32;
1984 if vui.num_units_in_tick == 0 {
1985 return Err("num_units_in_tick == 0, which is not allowed by E.2.1".into());
1986 }
1987
1988 vui.time_scale = r.read_bits::<u32>(31)? << 1;
1989 vui.time_scale |= r.read_bit()? as u32;
1990 if vui.time_scale == 0 {
1991 return Err("time_scale == 0, which is not allowed by E.2.1".into());
1992 }
1993
1994 vui.fixed_frame_rate_flag = r.read_bit()?;
1995 }
1996
1997 vui.nal_hrd_parameters_present_flag = r.read_bit()?;
1998 if vui.nal_hrd_parameters_present_flag {
1999 Parser::parse_hrd(r, &mut vui.nal_hrd_parameters)?;
2000 }
2001
2002 vui.vcl_hrd_parameters_present_flag = r.read_bit()?;
2003 if vui.vcl_hrd_parameters_present_flag {
2004 Parser::parse_hrd(r, &mut vui.vcl_hrd_parameters)?;
2005 }
2006
2007 if vui.nal_hrd_parameters_present_flag || vui.vcl_hrd_parameters_present_flag {
2008 vui.low_delay_hrd_flag = r.read_bit()?;
2009 }
2010
2011 vui.pic_struct_present_flag = r.read_bit()?;
2012 vui.bitstream_restriction_flag = r.read_bit()?;
2013
2014 if vui.bitstream_restriction_flag {
2015 vui.motion_vectors_over_pic_boundaries_flag = r.read_bit()?;
2016 vui.max_bytes_per_pic_denom = r.read_ue()?;
2017 vui.max_bits_per_mb_denom = r.read_ue_max(16)?;
2018 vui.log2_max_mv_length_horizontal = r.read_ue_max(16)?;
2019 vui.log2_max_mv_length_vertical = r.read_ue_max(16)?;
2020 vui.max_num_reorder_frames = r.read_ue()?;
2021 vui.max_dec_frame_buffering = r.read_ue()?;
2022 }
2023
2024 Ok(())
2025 }
2026
2027 pub fn parse_sps(&mut self, nalu: &Nalu) -> Result<&Rc<Sps>, String> {
2031 if !matches!(nalu.header.type_, NaluType::Sps) {
2032 return Err(format!(
2033 "Invalid NALU type, expected {:?}, got {:?}",
2034 NaluType::Sps,
2035 nalu.header.type_
2036 ));
2037 }
2038
2039 let data = nalu.as_ref();
2040 let mut r = BitReader::new(&data[nalu.header.len()..], true);
2042 let mut sps = Sps {
2043 profile_idc: r.read_bits(8)?,
2044 constraint_set0_flag: r.read_bit()?,
2045 constraint_set1_flag: r.read_bit()?,
2046 constraint_set2_flag: r.read_bit()?,
2047 constraint_set3_flag: r.read_bit()?,
2048 constraint_set4_flag: r.read_bit()?,
2049 constraint_set5_flag: r.read_bit()?,
2050 ..Default::default()
2051 };
2052
2053 r.skip_bits(2)?;
2055
2056 let level: u8 = r.read_bits(8)?;
2057 sps.level_idc = Level::try_from(level)?;
2058 sps.seq_parameter_set_id = r.read_ue_max(31)?;
2059
2060 if sps.profile_idc == 100
2061 || sps.profile_idc == 110
2062 || sps.profile_idc == 122
2063 || sps.profile_idc == 244
2064 || sps.profile_idc == 44
2065 || sps.profile_idc == 83
2066 || sps.profile_idc == 86
2067 || sps.profile_idc == 118
2068 || sps.profile_idc == 128
2069 || sps.profile_idc == 138
2070 || sps.profile_idc == 139
2071 || sps.profile_idc == 134
2072 || sps.profile_idc == 135
2073 {
2074 sps.chroma_format_idc = r.read_ue_max(3)?;
2075 if sps.chroma_format_idc == 3 {
2076 sps.separate_colour_plane_flag = r.read_bit()?;
2077 }
2078
2079 sps.bit_depth_luma_minus8 = r.read_ue_max(6)?;
2080 sps.bit_depth_chroma_minus8 = r.read_ue_max(6)?;
2081 sps.qpprime_y_zero_transform_bypass_flag = r.read_bit()?;
2082 sps.seq_scaling_matrix_present_flag = r.read_bit()?;
2083
2084 if sps.seq_scaling_matrix_present_flag {
2085 Parser::parse_sps_scaling_lists(&mut r, &mut sps)?;
2086 } else {
2087 Parser::fill_scaling_list_flat(&mut sps.scaling_lists_4x4, &mut sps.scaling_lists_8x8);
2088 }
2089 } else {
2090 sps.chroma_format_idc = 1;
2091 Parser::fill_scaling_list_flat(&mut sps.scaling_lists_4x4, &mut sps.scaling_lists_8x8);
2092 }
2093
2094 sps.log2_max_frame_num_minus4 = r.read_ue_max(12)?;
2095
2096 sps.pic_order_cnt_type = r.read_ue_max(2)?;
2097
2098 if sps.pic_order_cnt_type == 0 {
2099 sps.log2_max_pic_order_cnt_lsb_minus4 = r.read_ue_max(12)?;
2100 sps.expected_delta_per_pic_order_cnt_cycle = 0;
2101 } else if sps.pic_order_cnt_type == 1 {
2102 sps.delta_pic_order_always_zero_flag = r.read_bit()?;
2103 sps.offset_for_non_ref_pic = r.read_se()?;
2104 sps.offset_for_top_to_bottom_field = r.read_se()?;
2105 sps.num_ref_frames_in_pic_order_cnt_cycle = r.read_ue_max(254)?;
2106
2107 let mut offset_acc = 0;
2108 for i in 0..usize::from(sps.num_ref_frames_in_pic_order_cnt_cycle) {
2109 sps.offset_for_ref_frame[i] = r.read_se()?;
2110
2111 offset_acc += sps.offset_for_ref_frame[i];
2113 }
2114
2115 sps.expected_delta_per_pic_order_cnt_cycle = offset_acc;
2116 }
2117
2118 sps.max_num_ref_frames = r.read_ue_max(DPB_MAX_SIZE as u32)?;
2119 sps.gaps_in_frame_num_value_allowed_flag = r.read_bit()?;
2120 sps.pic_width_in_mbs_minus1 = r.read_ue()?;
2121 sps.pic_height_in_map_units_minus1 = r.read_ue()?;
2122 sps.frame_mbs_only_flag = r.read_bit()?;
2123
2124 if !sps.frame_mbs_only_flag {
2125 sps.mb_adaptive_frame_field_flag = r.read_bit()?;
2126 }
2127
2128 sps.direct_8x8_inference_flag = r.read_bit()?;
2129 sps.frame_cropping_flag = r.read_bit()?;
2130
2131 if sps.frame_cropping_flag {
2132 sps.frame_crop_left_offset = r.read_ue()?;
2133 sps.frame_crop_right_offset = r.read_ue()?;
2134 sps.frame_crop_top_offset = r.read_ue()?;
2135 sps.frame_crop_bottom_offset = r.read_ue()?;
2136
2137 let (crop_unit_x, crop_unit_y) = sps.crop_unit_x_y();
2139
2140 let _ = sps
2141 .frame_crop_left_offset
2142 .checked_add(sps.frame_crop_right_offset)
2143 .and_then(|r| r.checked_mul(crop_unit_x))
2144 .and_then(|r| sps.width().checked_sub(r))
2145 .ok_or::<String>("Invalid frame crop width".into())?;
2146
2147 let _ = sps
2148 .frame_crop_top_offset
2149 .checked_add(sps.frame_crop_bottom_offset)
2150 .and_then(|r| r.checked_mul(crop_unit_y))
2151 .and_then(|r| sps.height().checked_sub(r))
2152 .ok_or::<String>("invalid frame crop height".into())?;
2153 }
2154
2155 sps.vui_parameters_present_flag = r.read_bit()?;
2156 if sps.vui_parameters_present_flag {
2157 Parser::parse_vui(&mut r, &mut sps)?;
2158 }
2159
2160 let key = sps.seq_parameter_set_id;
2161
2162 if self.active_spses.keys().len() >= MAX_SPS_COUNT as usize {
2163 return Err("Broken data: Number of active SPSs > MAX_SPS_COUNT".into());
2164 }
2165
2166 let sps = Rc::new(sps);
2167 self.active_spses.remove(&key);
2168 Ok(self.active_spses.entry(key).or_insert(sps))
2169 }
2170
2171 pub fn parse_pps(&mut self, nalu: &Nalu) -> Result<&Pps, String> {
2172 if !matches!(nalu.header.type_, NaluType::Pps) {
2173 return Err(format!(
2174 "Invalid NALU type, expected {:?}, got {:?}",
2175 NaluType::Pps,
2176 nalu.header.type_
2177 ));
2178 }
2179
2180 let data = nalu.as_ref();
2181 let mut r = BitReader::new(&data[nalu.header.len()..], true);
2183 let pic_parameter_set_id = r.read_ue_max(MAX_PPS_COUNT as u32 - 1)?;
2184 let seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
2185 let sps = self.get_sps(seq_parameter_set_id).ok_or::<String>(format!(
2186 "Could not get SPS for seq_parameter_set_id {}",
2187 seq_parameter_set_id
2188 ))?;
2189 let mut pps = Pps {
2190 pic_parameter_set_id,
2191 seq_parameter_set_id,
2192 sps: Rc::clone(sps),
2193 scaling_lists_4x4: [[0; 16]; 6],
2194 scaling_lists_8x8: [[0; 64]; 6],
2195 entropy_coding_mode_flag: Default::default(),
2196 bottom_field_pic_order_in_frame_present_flag: Default::default(),
2197 num_slice_groups_minus1: Default::default(),
2198 num_ref_idx_l0_default_active_minus1: Default::default(),
2199 num_ref_idx_l1_default_active_minus1: Default::default(),
2200 weighted_pred_flag: Default::default(),
2201 weighted_bipred_idc: Default::default(),
2202 pic_init_qp_minus26: Default::default(),
2203 pic_init_qs_minus26: Default::default(),
2204 chroma_qp_index_offset: Default::default(),
2205 deblocking_filter_control_present_flag: Default::default(),
2206 constrained_intra_pred_flag: Default::default(),
2207 redundant_pic_cnt_present_flag: Default::default(),
2208 transform_8x8_mode_flag: Default::default(),
2209 second_chroma_qp_index_offset: Default::default(),
2210 pic_scaling_matrix_present_flag: Default::default(),
2211 };
2212
2213 pps.entropy_coding_mode_flag = r.read_bit()?;
2214 pps.bottom_field_pic_order_in_frame_present_flag = r.read_bit()?;
2215 pps.num_slice_groups_minus1 = r.read_ue_max(7)?;
2216
2217 if pps.num_slice_groups_minus1 > 0 {
2218 return Err("Stream contain unsupported/unimplemented NALs".into());
2219 }
2220
2221 pps.num_ref_idx_l0_default_active_minus1 = r.read_ue_max(31)?;
2222 pps.num_ref_idx_l1_default_active_minus1 = r.read_ue_max(31)?;
2223
2224 pps.weighted_pred_flag = r.read_bit()?;
2225 pps.weighted_bipred_idc = r.read_bits(2)?;
2226
2227 let qp_bd_offset_y = i32::from(6 * (sps.bit_depth_luma_minus8));
2228 pps.pic_init_qp_minus26 = r.read_se_bounded(-(26 + qp_bd_offset_y), 25)?;
2229 pps.pic_init_qs_minus26 = r.read_se_bounded(-26, 25)?;
2230
2231 pps.chroma_qp_index_offset = r.read_se_bounded(-12, 12)?;
2232
2233 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;
2236
2237 pps.deblocking_filter_control_present_flag = r.read_bit()?;
2238 pps.constrained_intra_pred_flag = r.read_bit()?;
2239 pps.redundant_pic_cnt_present_flag = r.read_bit()?;
2240
2241 if r.has_more_rsbp_data() {
2242 pps.transform_8x8_mode_flag = r.read_bit()?;
2243 pps.pic_scaling_matrix_present_flag = r.read_bit()?;
2244
2245 if pps.pic_scaling_matrix_present_flag {
2246 Parser::parse_pps_scaling_lists(&mut r, &mut pps, sps)?;
2247 }
2248
2249 pps.second_chroma_qp_index_offset = r.read_se()?;
2250 }
2251
2252 if !pps.pic_scaling_matrix_present_flag {
2253 pps.scaling_lists_4x4 = sps.scaling_lists_4x4;
2258 pps.scaling_lists_8x8 = sps.scaling_lists_8x8;
2259 }
2260
2261 let key = pps.pic_parameter_set_id;
2262
2263 if self.active_ppses.keys().len() >= MAX_PPS_COUNT as usize {
2264 return Err("Broken Data: number of active PPSs > MAX_PPS_COUNT".into());
2265 }
2266
2267 let pps = Rc::new(pps);
2268 self.active_ppses.remove(&key);
2269 Ok(self.active_ppses.entry(key).or_insert(pps))
2270 }
2271
2272 fn parse_ref_pic_list_modification(
2273 r: &mut BitReader,
2274 num_ref_idx_active_minus1: u8,
2275 ref_list_mods: &mut Vec<RefPicListModification>,
2276 ) -> Result<(), String> {
2277 if num_ref_idx_active_minus1 >= 32 {
2278 return Err("Broken Data: num_ref_idx_active_minus1 >= 32".into());
2279 }
2280
2281 loop {
2282 let mut pic_num_mod = RefPicListModification {
2283 modification_of_pic_nums_idc: r.read_ue_max(3)?,
2284 ..Default::default()
2285 };
2286
2287 match pic_num_mod.modification_of_pic_nums_idc {
2288 0 | 1 => {
2289 pic_num_mod.abs_diff_pic_num_minus1 = r.read_ue()?;
2290 }
2291
2292 2 => {
2293 pic_num_mod.long_term_pic_num = r.read_ue()?;
2294 }
2295
2296 3 => {
2297 ref_list_mods.push(pic_num_mod);
2298 break;
2299 }
2300
2301 _ => return Err("Broken Data: modification_of_pic_nums_idc > 3".into()),
2302 }
2303
2304 ref_list_mods.push(pic_num_mod);
2305 }
2306
2307 Ok(())
2308 }
2309
2310 fn parse_ref_pic_list_modifications(r: &mut BitReader, header: &mut SliceHeader) -> Result<(), String> {
2311 if !header.slice_type.is_i() && !header.slice_type.is_si() {
2312 header.ref_pic_list_modification_flag_l0 = r.read_bit()?;
2313 if header.ref_pic_list_modification_flag_l0 {
2314 Parser::parse_ref_pic_list_modification(
2315 r,
2316 header.num_ref_idx_l0_active_minus1,
2317 &mut header.ref_pic_list_modification_l0,
2318 )?;
2319 }
2320 }
2321
2322 if header.slice_type.is_b() {
2323 header.ref_pic_list_modification_flag_l1 = r.read_bit()?;
2324 if header.ref_pic_list_modification_flag_l1 {
2325 Parser::parse_ref_pic_list_modification(
2326 r,
2327 header.num_ref_idx_l1_active_minus1,
2328 &mut header.ref_pic_list_modification_l1,
2329 )?;
2330 }
2331 }
2332
2333 Ok(())
2334 }
2335
2336 fn parse_pred_weight_table(r: &mut BitReader, sps: &Sps, header: &mut SliceHeader) -> Result<(), String> {
2337 let pt = &mut header.pred_weight_table;
2338 pt.luma_log2_weight_denom = r.read_ue_max(7)?;
2339
2340 let default_luma_weight = 1 << pt.luma_log2_weight_denom;
2344 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2345 pt.luma_weight_l0[usize::from(i)] = default_luma_weight;
2346 }
2347
2348 if header.slice_type.is_b() {
2352 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2353 pt.luma_weight_l1[usize::from(i)] = default_luma_weight;
2354 }
2355 }
2356
2357 if sps.chroma_array_type() != 0 {
2358 pt.chroma_log2_weight_denom = r.read_ue_max(7)?;
2359 let default_chroma_weight = 1 << pt.chroma_log2_weight_denom;
2360
2361 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2365 pt.chroma_weight_l0[usize::from(i)][0] = default_chroma_weight;
2366 pt.chroma_weight_l0[usize::from(i)][1] = default_chroma_weight;
2367 }
2368
2369 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2373 pt.chroma_weight_l1[usize::from(i)][0] = default_chroma_weight;
2374 pt.chroma_weight_l1[usize::from(i)][1] = default_chroma_weight;
2375 }
2376 }
2377
2378 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2379 let luma_weight_l0_flag = r.read_bit()?;
2380
2381 if luma_weight_l0_flag {
2382 pt.luma_weight_l0[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2383 pt.luma_offset_l0[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2384 }
2385
2386 if sps.chroma_array_type() != 0 {
2387 let chroma_weight_l0_flag = r.read_bit()?;
2388 if chroma_weight_l0_flag {
2389 for j in 0..2 {
2390 pt.chroma_weight_l0[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2391 pt.chroma_offset_l0[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2392 }
2393 }
2394 }
2395 }
2396
2397 if header.slice_type.is_b() {
2398 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2399 let luma_weight_l1_flag = r.read_bit()?;
2400
2401 if luma_weight_l1_flag {
2402 pt.luma_weight_l1[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2403 pt.luma_offset_l1[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2404 }
2405
2406 if sps.chroma_array_type() != 0 {
2407 let chroma_weight_l1_flag = r.read_bit()?;
2408 if chroma_weight_l1_flag {
2409 for j in 0..2 {
2410 pt.chroma_weight_l1[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2411 pt.chroma_offset_l1[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2412 }
2413 }
2414 }
2415 }
2416 }
2417
2418 Ok(())
2419 }
2420
2421 fn parse_dec_ref_pic_marking(r: &mut BitReader, nalu: &Nalu, header: &mut SliceHeader) -> Result<(), String> {
2422 let rpm = &mut header.dec_ref_pic_marking;
2423
2424 let num_bits_left = r.num_bits_left();
2425 if nalu.header.idr_pic_flag {
2426 rpm.no_output_of_prior_pics_flag = r.read_bit()?;
2427 rpm.long_term_reference_flag = r.read_bit()?;
2428 } else {
2429 rpm.adaptive_ref_pic_marking_mode_flag = r.read_bit()?;
2430
2431 if rpm.adaptive_ref_pic_marking_mode_flag {
2432 loop {
2433 let mut marking = RefPicMarkingInner::default();
2434
2435 let mem_mgmt_ctrl_op = r.read_ue_max::<u8>(6)?;
2436 marking.memory_management_control_operation = mem_mgmt_ctrl_op;
2437
2438 if mem_mgmt_ctrl_op == 0 {
2439 break;
2440 }
2441
2442 if mem_mgmt_ctrl_op == 1 || mem_mgmt_ctrl_op == 3 {
2443 marking.difference_of_pic_nums_minus1 = r.read_ue()?;
2444 }
2445
2446 if mem_mgmt_ctrl_op == 2 {
2447 marking.long_term_pic_num = r.read_ue()?;
2448 }
2449
2450 if mem_mgmt_ctrl_op == 3 || mem_mgmt_ctrl_op == 6 {
2451 marking.long_term_frame_idx = r.read_ue()?;
2452 }
2453
2454 if mem_mgmt_ctrl_op == 4 {
2455 marking.max_long_term_frame_idx = MaxLongTermFrameIdx::from_value_plus1(r.read_ue()?);
2456 }
2457
2458 rpm.inner.push(marking);
2459 }
2460 }
2461 }
2462 header.dec_ref_pic_marking_bit_size = num_bits_left - r.num_bits_left();
2463
2464 Ok(())
2465 }
2466
2467 pub fn parse_slice_header<'a>(&self, nalu: Nalu<'a>) -> Result<Slice<'a>, String> {
2468 if !matches!(
2469 nalu.header.type_,
2470 NaluType::Slice
2471 | NaluType::SliceDpa
2472 | NaluType::SliceDpb
2473 | NaluType::SliceDpc
2474 | NaluType::SliceIdr
2475 | NaluType::SliceExt
2476 ) {
2477 return Err(format!(
2478 "Invalid NALU type: {:?} is not a slice NALU",
2479 nalu.header.type_
2480 ));
2481 }
2482
2483 let data = nalu.as_ref();
2484 let mut r = BitReader::new(&data[nalu.header.len()..], true);
2486
2487 let mut header = SliceHeader {
2488 first_mb_in_slice: r.read_ue()?,
2489 ..Default::default()
2490 };
2491
2492 let slice_type = r.read_ue_max::<u8>(9)? % 5;
2493 header.slice_type = SliceType::try_from(slice_type)?;
2494
2495 header.pic_parameter_set_id = r.read_ue()?;
2496
2497 let pps = self.get_pps(header.pic_parameter_set_id).ok_or::<String>(format!(
2498 "Could not get PPS for pic_parameter_set_id {}",
2499 header.pic_parameter_set_id
2500 ))?;
2501
2502 let sps = &pps.sps;
2503
2504 if sps.separate_colour_plane_flag {
2505 header.colour_plane_id = r.read_bits(2)?;
2506 }
2507
2508 header.frame_num = r.read_bits(usize::from(sps.log2_max_frame_num_minus4) + 4)?;
2509
2510 if !sps.frame_mbs_only_flag {
2511 header.field_pic_flag = r.read_bit()?;
2512 if header.field_pic_flag {
2513 header.bottom_field_flag = r.read_bit()?;
2514 }
2515 }
2516
2517 if header.field_pic_flag {
2518 header.max_pic_num = 2 * sps.max_frame_num();
2519 } else {
2520 header.max_pic_num = sps.max_frame_num();
2521 }
2522
2523 if nalu.header.idr_pic_flag {
2524 header.idr_pic_id = r.read_ue_max(0xffff)?;
2525 }
2526
2527 let num_bits_left = r.num_bits_left();
2528 if sps.pic_order_cnt_type == 0 {
2529 header.pic_order_cnt_lsb = r.read_bits(usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4)?;
2530
2531 if pps.bottom_field_pic_order_in_frame_present_flag && !header.field_pic_flag {
2532 header.delta_pic_order_cnt_bottom = r.read_se()?;
2533 }
2534 }
2535
2536 if sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag {
2537 header.delta_pic_order_cnt[0] = r.read_se()?;
2538 if pps.bottom_field_pic_order_in_frame_present_flag && !header.field_pic_flag {
2539 header.delta_pic_order_cnt[1] = r.read_se()?;
2540 }
2541 }
2542 header.pic_order_cnt_bit_size = num_bits_left - r.num_bits_left();
2543
2544 if pps.redundant_pic_cnt_present_flag {
2545 header.redundant_pic_cnt = r.read_ue_max(127)?;
2546 }
2547
2548 if header.slice_type.is_b() {
2549 header.direct_spatial_mv_pred_flag = r.read_bit()?;
2550 }
2551
2552 if header.slice_type.is_p() || header.slice_type.is_sp() || header.slice_type.is_b() {
2553 header.num_ref_idx_active_override_flag = r.read_bit()?;
2554 if header.num_ref_idx_active_override_flag {
2555 header.num_ref_idx_l0_active_minus1 = r.read_ue()?;
2556 if header.slice_type.is_b() {
2557 header.num_ref_idx_l1_active_minus1 = r.read_ue()?;
2558 }
2559 } else {
2560 header.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1;
2561 if header.slice_type.is_b() {
2562 header.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1;
2563 }
2564 }
2565 }
2566
2567 if header.field_pic_flag {
2568 if header.num_ref_idx_l0_active_minus1 > 31 || header.num_ref_idx_l1_active_minus1 > 31 {
2569 return Err("Broken Data".into());
2570 }
2571 } else if header.num_ref_idx_l0_active_minus1 > 15 || header.num_ref_idx_l1_active_minus1 > 15 {
2572 return Err("Broken Data".into());
2573 }
2574
2575 if let NaluType::SliceExt = nalu.header.type_ {
2576 return Err("Stream contain unsupported/unimplemented NALs".into());
2577 }
2578
2579 Parser::parse_ref_pic_list_modifications(&mut r, &mut header)?;
2580
2581 if (pps.weighted_pred_flag && (header.slice_type.is_p() || header.slice_type.is_sp()))
2582 || (pps.weighted_bipred_idc == 1 && header.slice_type.is_b())
2583 {
2584 Parser::parse_pred_weight_table(&mut r, sps, &mut header)?;
2585 }
2586
2587 if nalu.header.ref_idc != 0 {
2588 Parser::parse_dec_ref_pic_marking(&mut r, &nalu, &mut header)?;
2589 }
2590
2591 if pps.entropy_coding_mode_flag && !header.slice_type.is_i() && !header.slice_type.is_si() {
2592 header.cabac_init_idc = r.read_ue_max(2)?;
2593 }
2594
2595 header.slice_qp_delta = r.read_se_bounded(-87, 77)?;
2596
2597 if header.slice_type.is_sp() || header.slice_type.is_si() {
2598 if header.slice_type.is_sp() {
2599 header.sp_for_switch_flag = r.read_bit()?;
2600 }
2601
2602 header.slice_qs_delta = r.read_se_bounded(-51, 51)?;
2603 }
2604
2605 if pps.deblocking_filter_control_present_flag {
2606 header.disable_deblocking_filter_idc = r.read_ue_max(2)?;
2607
2608 if header.disable_deblocking_filter_idc != 1 {
2609 header.slice_alpha_c0_offset_div2 = r.read_se_bounded(-6, 6)?;
2610 header.slice_beta_offset_div2 = r.read_se_bounded(-6, 6)?;
2611 }
2612 }
2613
2614 if pps.num_slice_groups_minus1 > 0 {
2615 return Err("Stream contain unsupported/unimplemented NALs".into());
2616 }
2617
2618 let epb = r.num_epb();
2619 header.header_bit_size = (nalu.size - epb) * 8 - r.num_bits_left();
2620
2621 header.n_emulation_prevention_bytes = epb;
2622
2623 Ok(Slice { header, nalu })
2624 }
2625
2626 pub fn get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>> {
2627 self.active_spses.get(&sps_id)
2628 }
2629
2630 pub fn get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>> {
2631 self.active_ppses.get(&pps_id)
2632 }
2633}
2634
2635#[derive(Debug)]
2636pub struct NaluHeader {
2637 pub ref_idc: u8,
2638 pub type_: NaluType,
2639 pub idr_pic_flag: bool,
2640}
2641
2642impl Header for NaluHeader {
2643 fn parse<T: AsRef<[u8]>>(cursor: &mut Cursor<T>) -> Result<Self, String> {
2644 let mut byte_buf = [0u8; 1];
2645 cursor
2646 .read_exact(&mut byte_buf)
2647 .map_err(|_| String::from("Broken Data"))?;
2648 let byte = byte_buf[0];
2649 let _ = cursor.seek(SeekFrom::Current(-1 * byte_buf.len() as i64));
2650
2651 let type_ = NaluType::try_from(byte & 0x1f)?;
2652
2653 if let NaluType::SliceExt = type_ {
2654 return Err("Stream contain unsupported/unimplemented NALs".into());
2655 }
2656
2657 let ref_idc = (byte & 0x60) >> 5;
2658 let idr_pic_flag = matches!(type_, NaluType::SliceIdr);
2659
2660 Ok(NaluHeader {
2661 ref_idc,
2662 type_,
2663 idr_pic_flag,
2664 })
2665 }
2666
2667 fn is_end(&self) -> bool {
2668 matches!(self.type_, NaluType::SeqEnd | NaluType::StreamEnd)
2669 }
2670
2671 fn len(&self) -> usize {
2672 1
2673 }
2674}