1#![allow(dead_code)]
7
8use std::collections::BTreeMap;
9use std::io::Cursor;
10use std::rc::Rc;
11
12use anyhow::anyhow;
13use anyhow::Context;
14use bytes::Buf;
15use enumn::N;
16
17use crate::codec::h264::nalu;
18use crate::codec::h264::nalu::Header;
19use crate::codec::h264::nalu_reader::NaluReader;
20use crate::codec::h264::picture::Field;
21
22pub type Nalu<'a> = nalu::Nalu<'a, NaluHeader>;
23
24pub(super) const DEFAULT_4X4_INTRA: [u8; 16] = [
25 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42,
26];
27
28pub(super) const DEFAULT_4X4_INTER: [u8; 16] = [
29 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34,
30];
31
32pub(super) const DEFAULT_8X8_INTRA: [u8; 64] = [
33 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25,
34 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
35 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
36];
37
38pub(super) const DEFAULT_8X8_INTER: [u8; 64] = [
39 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22,
40 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
41 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
42];
43
44const MAX_PPS_COUNT: u16 = 256;
45const MAX_SPS_COUNT: u8 = 32;
46
47const DPB_MAX_SIZE: usize = 16;
49
50#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
51pub struct Point<T> {
52 pub x: T,
53 pub y: T,
54}
55
56#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
57pub struct Rect<T> {
58 pub min: Point<T>,
59 pub max: Point<T>,
60}
61
62#[derive(N, Debug, PartialEq, Eq, Clone, Copy)]
63pub enum NaluType {
64 Unknown = 0,
65 Slice = 1,
66 SliceDpa = 2,
67 SliceDpb = 3,
68 SliceDpc = 4,
69 SliceIdr = 5,
70 Sei = 6,
71 Sps = 7,
72 Pps = 8,
73 AuDelimiter = 9,
74 SeqEnd = 10,
75 StreamEnd = 11,
76 FillerData = 12,
77 SpsExt = 13,
78 PrefixUnit = 14,
79 SubsetSps = 15,
80 DepthSps = 16,
81 SliceAux = 19,
82 SliceExt = 20,
83 SliceDepth = 21,
84}
85
86#[derive(Clone, Debug, Default, PartialEq, Eq)]
87pub struct RefPicListModification {
88 pub modification_of_pic_nums_idc: u8,
89 pub abs_diff_pic_num_minus1: u32,
91 pub long_term_pic_num: u32,
93 pub abs_diff_view_idx_minus1: u32,
95}
96
97#[derive(Clone, Debug, Default, PartialEq, Eq)]
98pub struct PredWeightTable {
99 pub luma_log2_weight_denom: u8,
100 pub chroma_log2_weight_denom: u8,
101
102 pub luma_weight_l0: [i16; 32],
103 pub luma_offset_l0: [i8; 32],
104
105 pub chroma_weight_l0: [[i16; 2]; 32],
107 pub chroma_offset_l0: [[i8; 2]; 32],
108
109 pub luma_weight_l1: [i16; 32],
111 pub luma_offset_l1: [i16; 32],
112
113 pub chroma_weight_l1: [[i16; 2]; 32],
115 pub chroma_offset_l1: [[i8; 2]; 32],
116}
117
118#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
125pub enum MaxLongTermFrameIdx {
126 #[default]
127 NoLongTermFrameIndices,
128 Idx(u32),
129}
130
131impl MaxLongTermFrameIdx {
132 pub fn from_value_plus1(max_long_term_frame_idx_plus1: u32) -> Self {
134 match max_long_term_frame_idx_plus1 {
135 0 => Self::NoLongTermFrameIndices,
136 i @ 1.. => Self::Idx(i - 1),
137 }
138 }
139
140 pub fn to_value_plus1(self) -> u32 {
142 match self {
143 Self::NoLongTermFrameIndices => 0,
144 Self::Idx(i) => i + 1,
145 }
146 }
147}
148
149impl PartialEq<u32> for MaxLongTermFrameIdx {
150 fn eq(&self, other: &u32) -> bool {
151 match self {
152 MaxLongTermFrameIdx::NoLongTermFrameIndices => false,
153 MaxLongTermFrameIdx::Idx(idx) => idx.eq(other),
154 }
155 }
156}
157
158impl PartialOrd<u32> for MaxLongTermFrameIdx {
159 fn partial_cmp(&self, other: &u32) -> Option<std::cmp::Ordering> {
160 match self {
161 MaxLongTermFrameIdx::NoLongTermFrameIndices => Some(std::cmp::Ordering::Less),
162 MaxLongTermFrameIdx::Idx(idx) => Some(idx.cmp(other)),
163 }
164 }
165}
166
167#[derive(Clone, Debug, Default, PartialEq, Eq)]
168pub struct RefPicMarkingInner {
169 pub memory_management_control_operation: u8,
176
177 pub difference_of_pic_nums_minus1: u32,
181
182 pub long_term_pic_num: u32,
185
186 pub long_term_frame_idx: u32,
189
190 pub max_long_term_frame_idx: MaxLongTermFrameIdx,
194}
195
196#[derive(Clone, Debug, Default, PartialEq, Eq)]
197pub struct RefPicMarking {
198 pub no_output_of_prior_pics_flag: bool,
201
202 pub long_term_reference_flag: bool,
209
210 pub adaptive_ref_pic_marking_mode_flag: bool,
213
214 pub inner: Vec<RefPicMarkingInner>,
216}
217
218#[derive(Clone, Debug, Default, PartialEq, Eq)]
219pub struct SliceHeader {
220 pub first_mb_in_slice: u32,
222
223 pub slice_type: SliceType,
225
226 pub pic_parameter_set_id: u8,
228
229 pub colour_plane_id: u8,
232
233 pub frame_num: u16,
236
237 pub field_pic_flag: bool,
240
241 pub bottom_field_flag: bool,
244
245 pub idr_pic_id: u16,
251
252 pub pic_order_cnt_lsb: u16,
257
258 pub delta_pic_order_cnt_bottom: i32,
261
262 pub delta_pic_order_cnt: [i32; 2],
268
269 pub redundant_pic_cnt: u8,
274
275 pub direct_spatial_mv_pred_flag: bool,
278
279 pub num_ref_idx_active_override_flag: bool,
285
286 pub num_ref_idx_l0_active_minus1: u8,
289
290 pub num_ref_idx_l1_active_minus1: u8,
293
294 pub ref_pic_list_modification_flag_l0: bool,
298
299 pub ref_pic_list_modification_l0: Vec<RefPicListModification>,
302
303 pub ref_pic_list_modification_flag_l1: bool,
307
308 pub ref_pic_list_modification_l1: Vec<RefPicListModification>,
311
312 pub pred_weight_table: PredWeightTable,
314
315 pub dec_ref_pic_marking: RefPicMarking,
317
318 pub cabac_init_idc: u8,
321
322 pub slice_qp_delta: i8,
327
328 pub sp_for_switch_flag: bool,
331
332 pub slice_qs_delta: i8,
335
336 pub disable_deblocking_filter_idc: u8,
340
341 pub slice_alpha_c0_offset_div2: i8,
346
347 pub slice_beta_offset_div2: i8,
352
353 pub max_pic_num: u32,
355
356 pub header_bit_size: usize,
358
359 pub n_emulation_prevention_bytes: usize,
361}
362
363impl SliceHeader {
364 pub fn field(&self) -> Field {
366 if self.field_pic_flag {
367 if self.bottom_field_flag {
368 Field::Bottom
369 } else {
370 Field::Top
371 }
372 } else {
373 Field::Frame
374 }
375 }
376}
377
378pub struct SliceHeaderBuilder(SliceHeader);
379
380impl SliceHeaderBuilder {
381 pub fn new(pps: &Pps) -> Self {
382 SliceHeaderBuilder(SliceHeader {
383 pic_parameter_set_id: pps.pic_parameter_set_id,
384 ..Default::default()
385 })
386 }
387
388 pub fn slice_type(mut self, type_: SliceType) -> Self {
389 self.0.slice_type = type_;
390 self
391 }
392
393 pub fn first_mb_in_slice(mut self, value: u32) -> Self {
394 self.0.first_mb_in_slice = value;
395 self
396 }
397
398 pub fn pic_order_cnt_lsb(mut self, value: u16) -> Self {
399 self.0.pic_order_cnt_lsb = value;
400 self
401 }
402
403 pub fn idr_pic_id(mut self, value: u16) -> Self {
404 self.0.idr_pic_id = value;
405 self
406 }
407
408 pub fn num_ref_idx_active_override_flag(mut self, value: bool) -> Self {
409 self.0.num_ref_idx_active_override_flag = value;
410 self
411 }
412
413 pub fn num_ref_idx_l0_active_minus1(mut self, value: u8) -> Self {
414 self = self.num_ref_idx_active_override_flag(true);
415 self.0.num_ref_idx_l0_active_minus1 = value;
416 self
417 }
418
419 pub fn num_ref_idx_l0_active(self, value: u8) -> Self {
420 self.num_ref_idx_l0_active_minus1(value - 1)
421 }
422
423 pub fn num_ref_idx_l1_active_minus1(mut self, value: u8) -> Self {
424 self = self.num_ref_idx_active_override_flag(true);
425 self.0.num_ref_idx_l1_active_minus1 = value;
426 self
427 }
428
429 pub fn num_ref_idx_l1_active(self, value: u8) -> Self {
430 self.num_ref_idx_l1_active_minus1(value - 1)
431 }
432
433 pub fn build(self) -> SliceHeader {
434 self.0
435 }
436}
437
438pub struct Slice<'a> {
441 pub header: SliceHeader,
443 pub nalu: Nalu<'a>,
445}
446
447#[derive(N, Clone, Copy, Debug, PartialEq, Eq)]
448pub enum SliceType {
450 P = 0,
451 B = 1,
452 I = 2,
453 Sp = 3,
454 Si = 4,
455}
456
457impl SliceType {
458 pub fn is_p(&self) -> bool {
460 matches!(self, SliceType::P)
461 }
462
463 pub fn is_b(&self) -> bool {
465 matches!(self, SliceType::B)
466 }
467
468 pub fn is_i(&self) -> bool {
470 matches!(self, SliceType::I)
471 }
472
473 pub fn is_sp(&self) -> bool {
475 matches!(self, SliceType::Sp)
476 }
477
478 pub fn is_si(&self) -> bool {
480 matches!(self, SliceType::Si)
481 }
482}
483
484impl Default for SliceType {
485 fn default() -> Self {
486 Self::P
487 }
488}
489
490#[derive(N, Clone, Copy)]
491#[repr(u8)]
492pub enum Profile {
493 Baseline = 66,
494 Main = 77,
495 Extended = 88,
496 High = 100,
497 High10 = 110,
498 High422P = 122,
499}
500
501#[derive(N, Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
502pub enum Level {
503 #[default]
504 L1 = 10,
505 L1B = 9,
506 L1_1 = 11,
507 L1_2 = 12,
508 L1_3 = 13,
509 L2_0 = 20,
510 L2_1 = 21,
511 L2_2 = 22,
512 L3 = 30,
513 L3_1 = 31,
514 L3_2 = 32,
515 L4 = 40,
516 L4_1 = 41,
517 L4_2 = 42,
518 L5 = 50,
519 L5_1 = 51,
520 L5_2 = 52,
521 L6 = 60,
522 L6_1 = 61,
523 L6_2 = 62,
524}
525
526#[derive(Debug, PartialEq, Eq)]
532pub struct Sps {
533 pub seq_parameter_set_id: u8,
536
537 pub profile_idc: u8,
539
540 pub constraint_set0_flag: bool,
542 pub constraint_set1_flag: bool,
544 pub constraint_set2_flag: bool,
546 pub constraint_set3_flag: bool,
548 pub constraint_set4_flag: bool,
550 pub constraint_set5_flag: bool,
552
553 pub level_idc: Level,
555
556 pub chroma_format_idc: u8,
559
560 pub separate_colour_plane_flag: bool,
563
564 pub bit_depth_luma_minus8: u8,
568
569 pub bit_depth_chroma_minus8: u8,
573
574 pub qpprime_y_zero_transform_bypass_flag: bool,
584
585 pub seq_scaling_matrix_present_flag: bool,
589
590 pub scaling_lists_4x4: [[u8; 16]; 6],
592 pub scaling_lists_8x8: [[u8; 64]; 6],
594
595 pub log2_max_frame_num_minus4: u8,
599
600 pub pic_order_cnt_type: u8,
603
604 pub log2_max_pic_order_cnt_lsb_minus4: u8,
609
610 pub delta_pic_order_always_zero_flag: bool,
617
618 pub offset_for_non_ref_pic: i32,
621
622 pub offset_for_top_to_bottom_field: i32,
625
626 pub num_ref_frames_in_pic_order_cnt_cycle: u8,
629
630 pub offset_for_ref_frame: [i32; 255],
634
635 pub max_num_ref_frames: u8,
642
643 pub gaps_in_frame_num_value_allowed_flag: bool,
647
648 pub pic_width_in_mbs_minus1: u16,
651 pub pic_height_in_map_units_minus1: u16,
654
655 pub frame_mbs_only_flag: bool,
660
661 pub mb_adaptive_frame_field_flag: bool,
665
666 pub direct_8x8_inference_flag: bool,
670
671 pub frame_cropping_flag: bool,
675
676 pub frame_crop_left_offset: u32,
680 pub frame_crop_right_offset: u32,
684 pub frame_crop_top_offset: u32,
688 pub frame_crop_bottom_offset: u32,
692
693 pub expected_delta_per_pic_order_cnt_cycle: i32,
696
697 pub vui_parameters_present_flag: bool,
698 pub vui_parameters: VuiParams,
699}
700
701impl Sps {
702 pub const fn width(&self) -> u32 {
706 (self.pic_width_in_mbs_minus1 as u32 + 1) * 16
707 }
708
709 pub const fn height(&self) -> u32 {
713 (self.pic_height_in_map_units_minus1 as u32 + 1)
714 * 16
715 * (2 - self.frame_mbs_only_flag as u32)
716 }
717
718 pub const fn chroma_array_type(&self) -> u8 {
720 match self.separate_colour_plane_flag {
721 false => self.chroma_format_idc,
722 true => 0,
723 }
724 }
725
726 fn sub_width_height_c(&self) -> (u32, u32) {
730 match (self.chroma_format_idc, self.separate_colour_plane_flag) {
731 (1, false) => (2, 2),
732 (2, false) => (2, 1),
733 (3, false) => (1, 1),
734 _ => (1, 1),
736 }
737 }
738
739 fn crop_unit_x_y(&self) -> (u32, u32) {
743 match self.chroma_array_type() {
744 0 => (1, 2 - u32::from(self.frame_mbs_only_flag)),
745 _ => {
746 let (sub_width_c, sub_height_c) = self.sub_width_height_c();
747 (
748 sub_width_c,
749 sub_height_c * (2 - u32::from(self.frame_mbs_only_flag)),
750 )
751 }
752 }
753 }
754
755 pub fn max_frame_num(&self) -> u32 {
757 1 << (self.log2_max_frame_num_minus4 + 4)
758 }
759
760 pub fn visible_rectangle(&self) -> Rect<u32> {
761 if !self.frame_cropping_flag {
762 return Rect {
763 min: Point { x: 0, y: 0 },
764 max: Point {
765 x: self.width(),
766 y: self.height(),
767 },
768 };
769 }
770
771 let (crop_unit_x, crop_unit_y) = self.crop_unit_x_y();
772
773 let crop_left = crop_unit_x * self.frame_crop_left_offset;
774 let crop_right = crop_unit_x * self.frame_crop_right_offset;
775 let crop_top = crop_unit_y * self.frame_crop_top_offset;
776 let crop_bottom = crop_unit_y * self.frame_crop_bottom_offset;
777
778 Rect {
779 min: Point {
780 x: crop_left,
781 y: crop_top,
782 },
783 max: Point {
784 x: self.width() - crop_left - crop_right,
785 y: self.height() - crop_top - crop_bottom,
786 },
787 }
788 }
789
790 pub fn max_dpb_frames(&self) -> usize {
791 let profile = self.profile_idc;
792 let mut level = self.level_idc;
793
794 if matches!(level, Level::L1_1)
797 && (profile == Profile::Baseline as u8 || profile == Profile::Main as u8)
798 && self.constraint_set3_flag
799 {
800 level = Level::L1B;
801 };
802
803 let max_dpb_mbs = match level {
805 Level::L1 => 396,
806 Level::L1B => 396,
807 Level::L1_1 => 900,
808 Level::L1_2 => 2376,
809 Level::L1_3 => 2376,
810 Level::L2_0 => 2376,
811 Level::L2_1 => 4752,
812 Level::L2_2 => 8100,
813 Level::L3 => 8100,
814 Level::L3_1 => 18000,
815 Level::L3_2 => 20480,
816 Level::L4 => 32768,
817 Level::L4_1 => 32768,
818 Level::L4_2 => 34816,
819 Level::L5 => 110400,
820 Level::L5_1 => 184320,
821 Level::L5_2 => 184320,
822 Level::L6 => 696320,
823 Level::L6_1 => 696320,
824 Level::L6_2 => 696320,
825 };
826
827 let width_mb = self.width() / 16;
828 let height_mb = self.height() / 16;
829
830 let max_dpb_frames =
831 std::cmp::min(max_dpb_mbs / (width_mb * height_mb), DPB_MAX_SIZE as u32) as usize;
832
833 let mut max_dpb_frames = std::cmp::max(max_dpb_frames, self.max_num_ref_frames as usize);
834
835 if self.vui_parameters_present_flag && self.vui_parameters.bitstream_restriction_flag {
836 max_dpb_frames = std::cmp::max(1, self.vui_parameters.max_dec_frame_buffering as usize);
837 }
838
839 max_dpb_frames
840 }
841
842 pub fn max_num_order_frames(&self) -> u32 {
843 let vui = &self.vui_parameters;
844 let present = self.vui_parameters_present_flag && vui.bitstream_restriction_flag;
845
846 if present {
847 vui.max_num_reorder_frames
848 } else {
849 let profile = self.profile_idc;
850 if (profile == 44
851 || profile == 86
852 || profile == 100
853 || profile == 110
854 || profile == 122
855 || profile == 244)
856 && self.constraint_set3_flag
857 {
858 0
859 } else {
860 self.max_dpb_frames() as u32
861 }
862 }
863 }
864}
865
866impl Default for Sps {
868 fn default() -> Self {
869 Self {
870 scaling_lists_4x4: [[0; 16]; 6],
871 scaling_lists_8x8: [[0; 64]; 6],
872 offset_for_ref_frame: [0; 255],
873 seq_parameter_set_id: Default::default(),
874 profile_idc: Default::default(),
875 constraint_set0_flag: Default::default(),
876 constraint_set1_flag: Default::default(),
877 constraint_set2_flag: Default::default(),
878 constraint_set3_flag: Default::default(),
879 constraint_set4_flag: Default::default(),
880 constraint_set5_flag: Default::default(),
881 level_idc: Default::default(),
882 chroma_format_idc: Default::default(),
883 separate_colour_plane_flag: Default::default(),
884 bit_depth_luma_minus8: Default::default(),
885 bit_depth_chroma_minus8: Default::default(),
886 qpprime_y_zero_transform_bypass_flag: Default::default(),
887 seq_scaling_matrix_present_flag: Default::default(),
888 log2_max_frame_num_minus4: Default::default(),
889 pic_order_cnt_type: Default::default(),
890 log2_max_pic_order_cnt_lsb_minus4: Default::default(),
891 delta_pic_order_always_zero_flag: Default::default(),
892 offset_for_non_ref_pic: Default::default(),
893 offset_for_top_to_bottom_field: Default::default(),
894 num_ref_frames_in_pic_order_cnt_cycle: Default::default(),
895 max_num_ref_frames: Default::default(),
896 gaps_in_frame_num_value_allowed_flag: Default::default(),
897 pic_width_in_mbs_minus1: Default::default(),
898 pic_height_in_map_units_minus1: Default::default(),
899 frame_mbs_only_flag: Default::default(),
900 mb_adaptive_frame_field_flag: Default::default(),
901 direct_8x8_inference_flag: Default::default(),
902 frame_cropping_flag: Default::default(),
903 frame_crop_left_offset: Default::default(),
904 frame_crop_right_offset: Default::default(),
905 frame_crop_top_offset: Default::default(),
906 frame_crop_bottom_offset: Default::default(),
907 expected_delta_per_pic_order_cnt_cycle: Default::default(),
908 vui_parameters_present_flag: Default::default(),
909 vui_parameters: Default::default(),
910 }
911 }
912}
913
914#[derive(Default)]
915pub struct SpsBuilder(Sps);
916
917impl SpsBuilder {
918 pub fn new() -> Self {
919 Default::default()
920 }
921
922 pub fn seq_parameter_set_id(mut self, value: u8) -> Self {
923 self.0.seq_parameter_set_id = value;
924 self
925 }
926
927 pub fn profile_idc(mut self, value: Profile) -> Self {
928 self.0.profile_idc = value as u8;
929 self
930 }
931
932 pub fn level_idc(mut self, value: Level) -> Self {
933 self.0.level_idc = value;
934 self
935 }
936
937 pub fn frame_crop_offsets(mut self, top: u32, bottom: u32, left: u32, right: u32) -> Self {
938 self.0.frame_cropping_flag = true;
939 self.0.frame_crop_top_offset = top;
940 self.0.frame_crop_bottom_offset = bottom;
941 self.0.frame_crop_left_offset = left;
942 self.0.frame_crop_right_offset = right;
943 self
944 }
945
946 pub fn frame_crop(self, top: u32, bottom: u32, left: u32, right: u32) -> Self {
947 let sub_width_c = if self.0.chroma_format_idc > 2 { 1 } else { 2 };
948 let sub_height_c = if self.0.chroma_format_idc > 1 { 1 } else { 2 };
949
950 let crop_unit_x = sub_width_c;
951 let crop_unit_y = sub_height_c * (if self.0.frame_mbs_only_flag { 1 } else { 2 });
952
953 self.frame_crop_offsets(
954 top / crop_unit_y,
955 bottom / crop_unit_y,
956 left / crop_unit_x,
957 right / crop_unit_x,
958 )
959 }
960
961 pub fn resolution(mut self, width: u32, height: u32) -> Self {
962 const MB_SIZE: u32 = 16;
963
964 let mb_width = (width + MB_SIZE - 1) / MB_SIZE;
965 let mb_height = (height + MB_SIZE - 1) / MB_SIZE;
966
967 self.0.pic_width_in_mbs_minus1 = (mb_width - 1) as u16;
968 self.0.pic_height_in_map_units_minus1 = (mb_height - 1) as u16;
969
970 let compressed_width = mb_width * MB_SIZE;
971 let compressed_height = mb_height * MB_SIZE;
972
973 if compressed_width != width || compressed_height != height {
974 self = self.frame_crop(0, compressed_height - height, 0, compressed_width - width);
975 }
976
977 self
978 }
979
980 pub fn chroma_format_idc(mut self, value: u8) -> Self {
981 self.0.chroma_format_idc = value;
982 self
983 }
984
985 pub fn max_num_ref_frames(mut self, value: u8) -> Self {
986 self.0.max_num_ref_frames = value;
987 self
988 }
989
990 pub fn frame_mbs_only_flag(mut self, value: bool) -> Self {
991 self.0.frame_mbs_only_flag = value;
992 self
993 }
994
995 pub fn mb_adaptive_frame_field_flag(mut self, value: bool) -> Self {
996 self.0.mb_adaptive_frame_field_flag = value;
997 self
998 }
999
1000 pub fn seq_scaling_matrix_present_flag(mut self, value: bool) -> Self {
1001 self.0.seq_scaling_matrix_present_flag = value;
1002 self
1003 }
1004
1005 pub fn direct_8x8_inference_flag(mut self, value: bool) -> Self {
1006 self.0.direct_8x8_inference_flag = value;
1007 self
1008 }
1009
1010 pub fn vui_parameters_present(mut self) -> Self {
1011 if self.0.vui_parameters_present_flag {
1012 return self;
1013 }
1014
1015 self.0.vui_parameters_present_flag = true;
1016 self.0.vui_parameters.aspect_ratio_info_present_flag = false;
1018 self.0.vui_parameters.overscan_info_present_flag = false;
1019 self.0.vui_parameters.video_signal_type_present_flag = false;
1020 self.0.vui_parameters.colour_description_present_flag = false;
1021 self.0.vui_parameters.chroma_loc_info_present_flag = false;
1022 self.0.vui_parameters.timing_info_present_flag = false;
1023 self.0.vui_parameters.nal_hrd_parameters_present_flag = false;
1024 self.0.vui_parameters.vcl_hrd_parameters_present_flag = false;
1025 self.0.vui_parameters.pic_struct_present_flag = false;
1026 self.0.vui_parameters.bitstream_restriction_flag = false;
1027 self
1028 }
1029
1030 pub fn aspect_ratio_idc(mut self, value: u8) -> Self {
1031 self = self.vui_parameters_present();
1032 self.0.vui_parameters.aspect_ratio_info_present_flag = true;
1033 self.0.vui_parameters.aspect_ratio_idc = value;
1034 self
1035 }
1036
1037 pub fn sar_resolution(mut self, width: u16, height: u16) -> Self {
1038 self = self.aspect_ratio_idc(255);
1039 self.0.vui_parameters.sar_width = width;
1040 self.0.vui_parameters.sar_height = height;
1041 self
1042 }
1043
1044 pub fn aspect_ratio(self, width_ratio: u16, height_ratio: u16) -> Self {
1045 match (width_ratio, height_ratio) {
1047 (1, 1) => self.aspect_ratio_idc(1),
1048 (12, 11) => self.aspect_ratio_idc(2),
1049 (10, 11) => self.aspect_ratio_idc(3),
1050 (16, 11) => self.aspect_ratio_idc(4),
1051 (40, 33) => self.aspect_ratio_idc(5),
1052 (24, 11) => self.aspect_ratio_idc(6),
1053 (20, 11) => self.aspect_ratio_idc(7),
1054 (32, 11) => self.aspect_ratio_idc(8),
1055 (80, 33) => self.aspect_ratio_idc(9),
1056 (18, 11) => self.aspect_ratio_idc(10),
1057 (15, 11) => self.aspect_ratio_idc(11),
1058 (64, 33) => self.aspect_ratio_idc(12),
1059 (160, 99) => self.aspect_ratio_idc(13),
1060 (4, 3) => self.aspect_ratio_idc(14),
1061 (3, 2) => self.aspect_ratio_idc(15),
1062 (2, 1) => self.aspect_ratio_idc(16),
1063
1064 _ => self.sar_resolution(width_ratio, height_ratio),
1065 }
1066 }
1067
1068 pub fn timing_info(
1069 mut self,
1070 num_units_in_tick: u32,
1071 time_scale: u32,
1072 fixed_frame_rate_flag: bool,
1073 ) -> Self {
1074 self = self.vui_parameters_present();
1075 self.0.vui_parameters.timing_info_present_flag = true;
1076 self.0.vui_parameters.num_units_in_tick = num_units_in_tick;
1077 self.0.vui_parameters.time_scale = time_scale;
1078 self.0.vui_parameters.fixed_frame_rate_flag = fixed_frame_rate_flag;
1079 self
1080 }
1081
1082 pub fn log2_max_frame_num_minus4(mut self, value: u8) -> Self {
1083 self.0.log2_max_frame_num_minus4 = value;
1084 self
1085 }
1086
1087 pub fn max_frame_num(self, value: u32) -> Self {
1088 self.log2_max_frame_num_minus4(value.ilog2() as u8 - 4u8)
1089 }
1090
1091 pub fn pic_order_cnt_type(mut self, value: u8) -> Self {
1092 self.0.pic_order_cnt_type = value;
1093 self
1094 }
1095
1096 pub fn log2_max_pic_order_cnt_lsb_minus4(mut self, value: u8) -> Self {
1097 self.0.log2_max_pic_order_cnt_lsb_minus4 = value;
1098 self
1099 }
1100
1101 pub fn max_pic_order_cnt_lsb(self, value: u32) -> Self {
1102 self.log2_max_pic_order_cnt_lsb_minus4(value.ilog2() as u8 - 4u8)
1103 }
1104
1105 pub fn delta_pic_order_always_zero_flag(mut self, value: bool) -> Self {
1106 self.0.delta_pic_order_always_zero_flag = value;
1107 self
1108 }
1109
1110 pub fn bit_depth_chroma_minus8(mut self, value: u8) -> Self {
1111 self.0.bit_depth_chroma_minus8 = value;
1112 self
1113 }
1114
1115 pub fn bit_depth_chroma(self, value: u8) -> Self {
1116 self.bit_depth_luma_minus8(value - 8u8)
1117 }
1118
1119 pub fn bit_depth_luma_minus8(mut self, value: u8) -> Self {
1120 self.0.bit_depth_luma_minus8 = value;
1121 self
1122 }
1123
1124 pub fn bit_depth_luma(self, value: u8) -> Self {
1125 self.bit_depth_luma_minus8(value - 8u8)
1126 }
1127
1128 pub fn build(self) -> Rc<Sps> {
1129 Rc::new(self.0)
1130 }
1131}
1132
1133#[derive(Clone, Debug, Default, PartialEq, Eq)]
1134pub struct HrdParams {
1135 pub cpb_cnt_minus1: u8,
1139 pub bit_rate_scale: u8,
1142 pub cpb_size_scale: u8,
1145
1146 pub bit_rate_value_minus1: [u32; 32],
1149 pub cpb_size_value_minus1: [u32; 32],
1152 pub cbr_flag: [bool; 32],
1158
1159 pub initial_cpb_removal_delay_length_minus1: u8,
1163 pub cpb_removal_delay_length_minus1: u8,
1165 pub dpb_output_delay_length_minus1: u8,
1167 pub time_offset_length: u8,
1171}
1172
1173#[derive(Clone, Debug, PartialEq, Eq)]
1174pub struct VuiParams {
1175 pub aspect_ratio_info_present_flag: bool,
1177 pub aspect_ratio_idc: u8,
1183
1184 pub sar_width: u16,
1188 pub sar_height: u16,
1191
1192 pub overscan_info_present_flag: bool,
1195 pub overscan_appropriate_flag: bool,
1203
1204 pub video_signal_type_present_flag: bool,
1207 pub video_format: u8,
1212 pub video_full_range_flag: bool,
1216 pub colour_description_present_flag: bool,
1219 pub colour_primaries: u8,
1223 pub transfer_characteristics: u8,
1225 pub matrix_coefficients: u8,
1229
1230 pub chroma_loc_info_present_flag: bool,
1233 pub chroma_sample_loc_type_top_field: u8,
1235 pub chroma_sample_loc_type_bottom_field: u8,
1237
1238 pub timing_info_present_flag: bool,
1241 pub num_units_in_tick: u32,
1246 pub time_scale: u32,
1250 pub fixed_frame_rate_flag: bool,
1252
1253 pub nal_hrd_parameters_present_flag: bool,
1256 pub nal_hrd_parameters: HrdParams,
1259 pub vcl_hrd_parameters_present_flag: bool,
1262 pub vcl_hrd_parameters: HrdParams,
1265
1266 pub low_delay_hrd_flag: bool,
1268
1269 pub pic_struct_present_flag: bool,
1272
1273 pub bitstream_restriction_flag: bool,
1276 pub motion_vectors_over_pic_boundaries_flag: bool,
1286 pub max_bytes_per_pic_denom: u32,
1290 pub max_bits_per_mb_denom: u32,
1294 pub log2_max_mv_length_horizontal: u32,
1296 pub log2_max_mv_length_vertical: u32,
1298 pub max_num_reorder_frames: u32,
1319 pub max_dec_frame_buffering: u32,
1341}
1342
1343impl Default for VuiParams {
1344 fn default() -> Self {
1345 Self {
1346 aspect_ratio_info_present_flag: Default::default(),
1347 aspect_ratio_idc: Default::default(),
1348 sar_width: Default::default(),
1349 sar_height: Default::default(),
1350 overscan_info_present_flag: Default::default(),
1351 overscan_appropriate_flag: Default::default(),
1352 video_signal_type_present_flag: Default::default(),
1353 video_format: 5,
1354 video_full_range_flag: Default::default(),
1355 colour_description_present_flag: Default::default(),
1356 colour_primaries: 2,
1357 transfer_characteristics: 2,
1358 matrix_coefficients: 2,
1359 chroma_loc_info_present_flag: Default::default(),
1360 chroma_sample_loc_type_top_field: Default::default(),
1361 chroma_sample_loc_type_bottom_field: Default::default(),
1362 timing_info_present_flag: Default::default(),
1363 num_units_in_tick: Default::default(),
1364 time_scale: Default::default(),
1365 fixed_frame_rate_flag: Default::default(),
1366 nal_hrd_parameters_present_flag: Default::default(),
1367 nal_hrd_parameters: Default::default(),
1368 vcl_hrd_parameters_present_flag: Default::default(),
1369 vcl_hrd_parameters: Default::default(),
1370 low_delay_hrd_flag: Default::default(),
1371 pic_struct_present_flag: Default::default(),
1372 bitstream_restriction_flag: Default::default(),
1373 motion_vectors_over_pic_boundaries_flag: Default::default(),
1374 max_bytes_per_pic_denom: Default::default(),
1375 max_bits_per_mb_denom: Default::default(),
1376 log2_max_mv_length_horizontal: Default::default(),
1377 log2_max_mv_length_vertical: Default::default(),
1378 max_num_reorder_frames: Default::default(),
1379 max_dec_frame_buffering: Default::default(),
1380 }
1381 }
1382}
1383
1384#[derive(Debug, PartialEq, Eq)]
1388pub struct Pps {
1389 pub pic_parameter_set_id: u8,
1391
1392 pub seq_parameter_set_id: u8,
1394
1395 pub entropy_coding_mode_flag: bool,
1403
1404 pub bottom_field_pic_order_in_frame_present_flag: bool,
1412
1413 pub num_slice_groups_minus1: u32,
1418
1419 pub num_ref_idx_l0_default_active_minus1: u8,
1422
1423 pub num_ref_idx_l1_default_active_minus1: u8,
1426
1427 pub weighted_pred_flag: bool,
1431
1432 pub weighted_bipred_idc: u8,
1438
1439 pub pic_init_qp_minus26: i8,
1444
1445 pub pic_init_qs_minus26: i8,
1449
1450 pub chroma_qp_index_offset: i8,
1453
1454 pub deblocking_filter_control_present_flag: bool,
1460
1461 pub constrained_intra_pred_flag: bool,
1469
1470 pub redundant_pic_cnt_present_flag: bool,
1481
1482 pub transform_8x8_mode_flag: bool,
1486
1487 pub pic_scaling_matrix_present_flag: bool,
1492
1493 pub scaling_lists_4x4: [[u8; 16]; 6],
1495 pub scaling_lists_8x8: [[u8; 64]; 6],
1497
1498 pub second_chroma_qp_index_offset: i8,
1503
1504 pub sps: Rc<Sps>,
1506}
1507
1508pub struct PpsBuilder(Pps);
1509
1510impl PpsBuilder {
1511 pub fn new(sps: Rc<Sps>) -> Self {
1512 PpsBuilder(Pps {
1513 pic_parameter_set_id: 0,
1514 seq_parameter_set_id: sps.seq_parameter_set_id,
1515 entropy_coding_mode_flag: false,
1516 bottom_field_pic_order_in_frame_present_flag: false,
1517 num_slice_groups_minus1: 0,
1518 num_ref_idx_l0_default_active_minus1: 0,
1519 num_ref_idx_l1_default_active_minus1: 0,
1520 weighted_pred_flag: false,
1521 weighted_bipred_idc: 0,
1522 pic_init_qp_minus26: 0,
1523 pic_init_qs_minus26: 0,
1524 chroma_qp_index_offset: 0,
1525 deblocking_filter_control_present_flag: false,
1526 constrained_intra_pred_flag: false,
1527 redundant_pic_cnt_present_flag: false,
1528 transform_8x8_mode_flag: false,
1529 pic_scaling_matrix_present_flag: false,
1530 scaling_lists_4x4: [[0; 16]; 6],
1531 scaling_lists_8x8: [[0; 64]; 6],
1532 second_chroma_qp_index_offset: 0,
1533 sps,
1534 })
1535 }
1536
1537 pub fn pic_parameter_set_id(mut self, value: u8) -> Self {
1538 self.0.pic_parameter_set_id = value;
1539 self
1540 }
1541
1542 pub fn pic_init_qp_minus26(mut self, value: i8) -> Self {
1543 self.0.pic_init_qp_minus26 = value;
1544 self
1545 }
1546
1547 pub fn pic_init_qp(self, value: u8) -> Self {
1548 self.pic_init_qp_minus26(value as i8 - 26)
1549 }
1550
1551 pub fn deblocking_filter_control_present_flag(mut self, value: bool) -> Self {
1552 self.0.deblocking_filter_control_present_flag = value;
1553 self
1554 }
1555
1556 pub fn num_ref_idx_l0_default_active_minus1(mut self, value: u8) -> Self {
1557 self.0.num_ref_idx_l0_default_active_minus1 = value;
1558 self
1559 }
1560
1561 pub fn num_ref_idx_l0_default_active(self, value: u8) -> Self {
1562 self.num_ref_idx_l0_default_active_minus1(value - 1)
1563 }
1564
1565 pub fn num_ref_idx_l1_default_active_minus1(mut self, value: u8) -> Self {
1566 self.0.num_ref_idx_l1_default_active_minus1 = value;
1567 self
1568 }
1569
1570 pub fn num_ref_idx_l1_default_active(self, value: u8) -> Self {
1571 self.num_ref_idx_l1_default_active_minus1(value - 1)
1572 }
1573
1574 pub fn build(self) -> Rc<Pps> {
1575 Rc::new(self.0)
1576 }
1577}
1578
1579#[derive(Debug, Default)]
1580pub struct Parser {
1581 active_spses: BTreeMap<u8, Rc<Sps>>,
1582 active_ppses: BTreeMap<u8, Rc<Pps>>,
1583}
1584
1585impl Parser {
1586 fn fill_default_scaling_list_4x4(scaling_list4x4: &mut [u8; 16], i: usize) {
1587 assert!(i < 6);
1589 if i < 3 {
1590 *scaling_list4x4 = DEFAULT_4X4_INTRA;
1591 } else if i < 6 {
1592 *scaling_list4x4 = DEFAULT_4X4_INTER;
1593 }
1594 }
1595
1596 fn fill_default_scaling_list_8x8(scaling_list8x8: &mut [u8; 64], i: usize) {
1597 assert!(i < 6);
1598 if i % 2 == 0 {
1599 *scaling_list8x8 = DEFAULT_8X8_INTRA;
1600 } else {
1601 *scaling_list8x8 = DEFAULT_8X8_INTER;
1602 }
1603 }
1604
1605 fn fill_fallback_scaling_list_4x4(
1606 scaling_list4x4: &mut [[u8; 16]; 6],
1607 i: usize,
1608 default_scaling_list_intra: &[u8; 16],
1609 default_scaling_list_inter: &[u8; 16],
1610 ) {
1611 scaling_list4x4[i] = match i {
1613 0 => *default_scaling_list_intra,
1614 1 => scaling_list4x4[0],
1615 2 => scaling_list4x4[1],
1616 3 => *default_scaling_list_inter,
1617 4 => scaling_list4x4[3],
1618 5 => scaling_list4x4[4],
1619 _ => panic!("Unexpected value {}", i),
1620 }
1621 }
1622
1623 fn fill_fallback_scaling_list_8x8(
1624 scaling_list8x8: &mut [[u8; 64]; 6],
1625 i: usize,
1626 default_scaling_list_intra: &[u8; 64],
1627 default_scaling_list_inter: &[u8; 64],
1628 ) {
1629 scaling_list8x8[i] = match i {
1631 0 => *default_scaling_list_intra,
1632 1 => *default_scaling_list_inter,
1633 2 => scaling_list8x8[0],
1634 3 => scaling_list8x8[1],
1635 4 => scaling_list8x8[2],
1636 5 => scaling_list8x8[3],
1637 _ => panic!("Unexpected value {}", i),
1638 }
1639 }
1640
1641 fn fill_scaling_list_flat(
1642 scaling_list4x4: &mut [[u8; 16]; 6],
1643 scaling_list8x8: &mut [[u8; 64]; 6],
1644 ) {
1645 for outer in scaling_list4x4 {
1647 for inner in outer {
1648 *inner = 16;
1649 }
1650 }
1651
1652 for outer in scaling_list8x8 {
1654 for inner in outer {
1655 *inner = 16;
1656 }
1657 }
1658 }
1659
1660 fn parse_scaling_list<U: AsMut<[u8]>>(
1661 r: &mut NaluReader,
1662 scaling_list: &mut U,
1663 use_default: &mut bool,
1664 ) -> anyhow::Result<()> {
1665 let mut last_scale = 8u8;
1667 let mut next_scale = 8u8;
1668
1669 for j in 0..scaling_list.as_mut().len() {
1670 if next_scale != 0 {
1671 let delta_scale = r.read_se::<i32>()?;
1672 next_scale = ((last_scale as i32 + delta_scale + 256) % 256) as u8;
1673 *use_default = j == 0 && next_scale == 0;
1674 if *use_default {
1675 return Ok(());
1676 }
1677 }
1678
1679 scaling_list.as_mut()[j] = if next_scale == 0 {
1680 last_scale
1681 } else {
1682 next_scale
1683 };
1684
1685 last_scale = scaling_list.as_mut()[j];
1686 }
1687
1688 Ok(())
1689 }
1690
1691 fn parse_sps_scaling_lists(r: &mut NaluReader, sps: &mut Sps) -> anyhow::Result<()> {
1692 let scaling_lists4x4 = &mut sps.scaling_lists_4x4;
1693 let scaling_lisst8x8 = &mut sps.scaling_lists_8x8;
1694
1695 for i in 0..6 {
1697 let seq_scaling_list_present_flag = r.read_bit()?;
1698 if seq_scaling_list_present_flag {
1699 let mut use_default = false;
1700
1701 Parser::parse_scaling_list(r, &mut scaling_lists4x4[i], &mut use_default)?;
1702
1703 if use_default {
1704 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1705 }
1706 } else {
1707 Parser::fill_fallback_scaling_list_4x4(
1708 scaling_lists4x4,
1709 i,
1710 &DEFAULT_4X4_INTRA,
1711 &DEFAULT_4X4_INTER,
1712 );
1713 }
1714 }
1715
1716 let num_8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
1718 for i in 0..num_8x8 {
1719 let seq_scaling_list_present_flag = r.read_bit()?;
1720 if seq_scaling_list_present_flag {
1721 let mut use_default = false;
1722 Parser::parse_scaling_list(r, &mut scaling_lisst8x8[i], &mut use_default)?;
1723
1724 if use_default {
1725 Parser::fill_default_scaling_list_8x8(&mut scaling_lisst8x8[i], i);
1726 }
1727 } else {
1728 Parser::fill_fallback_scaling_list_8x8(
1729 scaling_lisst8x8,
1730 i,
1731 &DEFAULT_8X8_INTRA,
1732 &DEFAULT_8X8_INTER,
1733 );
1734 }
1735 }
1736 Ok(())
1737 }
1738
1739 fn parse_pps_scaling_lists(r: &mut NaluReader, pps: &mut Pps, sps: &Sps) -> anyhow::Result<()> {
1740 let scaling_lists4x4 = &mut pps.scaling_lists_4x4;
1741 let scaling_lists8x8 = &mut pps.scaling_lists_8x8;
1742
1743 for i in 0..6 {
1744 let pic_scaling_list_present_flag = r.read_bit()?;
1745 if pic_scaling_list_present_flag {
1746 let mut use_default = false;
1747
1748 Parser::parse_scaling_list(r, &mut scaling_lists4x4[i], &mut use_default)?;
1749
1750 if use_default {
1751 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1752 }
1753 } else if !sps.seq_scaling_matrix_present_flag {
1754 Parser::fill_fallback_scaling_list_4x4(
1756 scaling_lists4x4,
1757 i,
1758 &DEFAULT_4X4_INTRA,
1759 &DEFAULT_4X4_INTER,
1760 );
1761 } else {
1762 Parser::fill_fallback_scaling_list_4x4(
1764 scaling_lists4x4,
1765 i,
1766 &sps.scaling_lists_4x4[0],
1767 &sps.scaling_lists_4x4[3],
1768 );
1769 }
1770 }
1771
1772 if pps.transform_8x8_mode_flag {
1773 let num8x8 = if sps.chroma_format_idc != 3 { 2 } else { 6 };
1774
1775 for i in 0..num8x8 {
1776 let pic_scaling_list_present_flag = r.read_bit()?;
1777 if pic_scaling_list_present_flag {
1778 let mut use_default = false;
1779
1780 Parser::parse_scaling_list(r, &mut scaling_lists8x8[i], &mut use_default)?;
1781
1782 if use_default {
1783 Parser::fill_default_scaling_list_4x4(&mut scaling_lists4x4[i], i);
1784 }
1785 } else if !sps.seq_scaling_matrix_present_flag {
1786 Parser::fill_fallback_scaling_list_8x8(
1788 scaling_lists8x8,
1789 i,
1790 &DEFAULT_8X8_INTRA,
1791 &DEFAULT_8X8_INTER,
1792 );
1793 } else {
1794 Parser::fill_fallback_scaling_list_8x8(
1796 scaling_lists8x8,
1797 i,
1798 &sps.scaling_lists_8x8[0],
1799 &sps.scaling_lists_8x8[1],
1800 );
1801 }
1802 }
1803 }
1804
1805 Ok(())
1806 }
1807
1808 fn parse_hrd(r: &mut NaluReader, hrd: &mut HrdParams) -> anyhow::Result<()> {
1809 hrd.cpb_cnt_minus1 = r.read_ue_max(31)?;
1810 hrd.bit_rate_scale = r.read_bits(4)?;
1811 hrd.cpb_size_scale = r.read_bits(4)?;
1812
1813 for sched_sel_idx in 0..=usize::from(hrd.cpb_cnt_minus1) {
1814 hrd.bit_rate_value_minus1[sched_sel_idx] = r.read_ue()?;
1815 hrd.cpb_size_value_minus1[sched_sel_idx] = r.read_ue()?;
1816 hrd.cbr_flag[sched_sel_idx] = r.read_bit()?;
1817 }
1818
1819 hrd.initial_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
1820 hrd.cpb_removal_delay_length_minus1 = r.read_bits(5)?;
1821 hrd.dpb_output_delay_length_minus1 = r.read_bits(5)?;
1822 hrd.time_offset_length = r.read_bits(5)?;
1823 Ok(())
1824 }
1825
1826 fn parse_vui(r: &mut NaluReader, sps: &mut Sps) -> anyhow::Result<()> {
1827 let vui = &mut sps.vui_parameters;
1828
1829 vui.aspect_ratio_info_present_flag = r.read_bit()?;
1830 if vui.aspect_ratio_info_present_flag {
1831 vui.aspect_ratio_idc = r.read_bits(8)?;
1832 if vui.aspect_ratio_idc == 255 {
1833 vui.sar_width = r.read_bits(16)?;
1834 vui.sar_height = r.read_bits(16)?;
1835 }
1836 }
1837
1838 vui.overscan_info_present_flag = r.read_bit()?;
1839 if vui.overscan_info_present_flag {
1840 vui.overscan_appropriate_flag = r.read_bit()?;
1841 }
1842
1843 vui.video_signal_type_present_flag = r.read_bit()?;
1844 if vui.video_signal_type_present_flag {
1845 vui.video_format = r.read_bits(3)?;
1846 vui.video_full_range_flag = r.read_bit()?;
1847 vui.colour_description_present_flag = r.read_bit()?;
1848 if vui.colour_description_present_flag {
1849 vui.colour_primaries = r.read_bits(8)?;
1850 vui.transfer_characteristics = r.read_bits(8)?;
1851 vui.matrix_coefficients = r.read_bits(8)?;
1852 }
1853 }
1854
1855 vui.chroma_loc_info_present_flag = r.read_bit()?;
1856 if vui.chroma_loc_info_present_flag {
1857 vui.chroma_sample_loc_type_top_field = r.read_ue_max(5)?;
1858 vui.chroma_sample_loc_type_bottom_field = r.read_ue_max(5)?;
1859 }
1860
1861 vui.timing_info_present_flag = r.read_bit()?;
1862 if vui.timing_info_present_flag {
1863 vui.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
1864 vui.num_units_in_tick |= r.read_bit()? as u32;
1865 if vui.num_units_in_tick == 0 {
1866 return Err(anyhow!(
1867 "num_units_in_tick == 0, which is not allowed by E.2.1"
1868 ));
1869 }
1870
1871 vui.time_scale = r.read_bits::<u32>(31)? << 1;
1872 vui.time_scale |= r.read_bit()? as u32;
1873 if vui.time_scale == 0 {
1874 return Err(anyhow!("time_scale == 0, which is not allowed by E.2.1"));
1875 }
1876
1877 vui.fixed_frame_rate_flag = r.read_bit()?;
1878 }
1879
1880 vui.nal_hrd_parameters_present_flag = r.read_bit()?;
1881 if vui.nal_hrd_parameters_present_flag {
1882 Parser::parse_hrd(r, &mut vui.nal_hrd_parameters)?;
1883 }
1884
1885 vui.vcl_hrd_parameters_present_flag = r.read_bit()?;
1886 if vui.vcl_hrd_parameters_present_flag {
1887 Parser::parse_hrd(r, &mut vui.vcl_hrd_parameters)?;
1888 }
1889
1890 if vui.nal_hrd_parameters_present_flag || vui.vcl_hrd_parameters_present_flag {
1891 vui.low_delay_hrd_flag = r.read_bit()?;
1892 }
1893
1894 vui.pic_struct_present_flag = r.read_bit()?;
1895 vui.bitstream_restriction_flag = r.read_bit()?;
1896
1897 if vui.bitstream_restriction_flag {
1898 vui.motion_vectors_over_pic_boundaries_flag = r.read_bit()?;
1899 vui.max_bytes_per_pic_denom = r.read_ue()?;
1900 vui.max_bits_per_mb_denom = r.read_ue_max(16)?;
1901 vui.log2_max_mv_length_horizontal = r.read_ue_max(16)?;
1902 vui.log2_max_mv_length_vertical = r.read_ue_max(16)?;
1903 vui.max_num_reorder_frames = r.read_ue()?;
1904 vui.max_dec_frame_buffering = r.read_ue()?;
1905 }
1906
1907 Ok(())
1908 }
1909
1910 pub fn parse_sps(&mut self, nalu: &Nalu) -> anyhow::Result<&Rc<Sps>> {
1914 if !matches!(nalu.header.type_, NaluType::Sps) {
1915 return Err(anyhow!(
1916 "Invalid NALU type, expected {:?}, got {:?}",
1917 NaluType::Sps,
1918 nalu.header.type_
1919 ));
1920 }
1921
1922 let data = nalu.as_ref();
1923 let mut r = NaluReader::new(&data[nalu.header.len()..]);
1925 let mut sps = Sps {
1926 profile_idc: r.read_bits(8)?,
1927 constraint_set0_flag: r.read_bit()?,
1928 constraint_set1_flag: r.read_bit()?,
1929 constraint_set2_flag: r.read_bit()?,
1930 constraint_set3_flag: r.read_bit()?,
1931 constraint_set4_flag: r.read_bit()?,
1932 constraint_set5_flag: r.read_bit()?,
1933 ..Default::default()
1934 };
1935
1936 r.skip_bits(2)?;
1938
1939 let level: u8 = r.read_bits(8)?;
1940 sps.level_idc = Level::n(level).with_context(|| format!("Unsupported level {}", level))?;
1941 sps.seq_parameter_set_id = r.read_ue_max(31)?;
1942
1943 if sps.profile_idc == 100
1944 || sps.profile_idc == 110
1945 || sps.profile_idc == 122
1946 || sps.profile_idc == 244
1947 || sps.profile_idc == 44
1948 || sps.profile_idc == 83
1949 || sps.profile_idc == 86
1950 || sps.profile_idc == 118
1951 || sps.profile_idc == 128
1952 || sps.profile_idc == 138
1953 || sps.profile_idc == 139
1954 || sps.profile_idc == 134
1955 || sps.profile_idc == 135
1956 {
1957 sps.chroma_format_idc = r.read_ue_max(3)?;
1958 if sps.chroma_format_idc == 3 {
1959 sps.separate_colour_plane_flag = r.read_bit()?;
1960 }
1961
1962 sps.bit_depth_luma_minus8 = r.read_ue_max(6)?;
1963 sps.bit_depth_chroma_minus8 = r.read_ue_max(6)?;
1964 sps.qpprime_y_zero_transform_bypass_flag = r.read_bit()?;
1965 sps.seq_scaling_matrix_present_flag = r.read_bit()?;
1966
1967 if sps.seq_scaling_matrix_present_flag {
1968 Parser::parse_sps_scaling_lists(&mut r, &mut sps)?;
1969 } else {
1970 Parser::fill_scaling_list_flat(
1971 &mut sps.scaling_lists_4x4,
1972 &mut sps.scaling_lists_8x8,
1973 );
1974 }
1975 } else {
1976 sps.chroma_format_idc = 1;
1977 Parser::fill_scaling_list_flat(&mut sps.scaling_lists_4x4, &mut sps.scaling_lists_8x8);
1978 }
1979
1980 sps.log2_max_frame_num_minus4 = r.read_ue_max(12)?;
1981
1982 sps.pic_order_cnt_type = r.read_ue_max(2)?;
1983
1984 if sps.pic_order_cnt_type == 0 {
1985 sps.log2_max_pic_order_cnt_lsb_minus4 = r.read_ue_max(12)?;
1986 sps.expected_delta_per_pic_order_cnt_cycle = 0;
1987 } else if sps.pic_order_cnt_type == 1 {
1988 sps.delta_pic_order_always_zero_flag = r.read_bit()?;
1989 sps.offset_for_non_ref_pic = r.read_se()?;
1990 sps.offset_for_top_to_bottom_field = r.read_se()?;
1991 sps.num_ref_frames_in_pic_order_cnt_cycle = r.read_ue_max(254)?;
1992
1993 let mut offset_acc = 0;
1994 for i in 0..usize::from(sps.num_ref_frames_in_pic_order_cnt_cycle) {
1995 sps.offset_for_ref_frame[i] = r.read_se()?;
1996
1997 offset_acc += sps.offset_for_ref_frame[i];
1999 }
2000
2001 sps.expected_delta_per_pic_order_cnt_cycle = offset_acc;
2002 }
2003
2004 sps.max_num_ref_frames = r.read_ue_max(DPB_MAX_SIZE as u32)?;
2005 sps.gaps_in_frame_num_value_allowed_flag = r.read_bit()?;
2006 sps.pic_width_in_mbs_minus1 = r.read_ue()?;
2007 sps.pic_height_in_map_units_minus1 = r.read_ue()?;
2008 sps.frame_mbs_only_flag = r.read_bit()?;
2009
2010 if !sps.frame_mbs_only_flag {
2011 sps.mb_adaptive_frame_field_flag = r.read_bit()?;
2012 }
2013
2014 sps.direct_8x8_inference_flag = r.read_bit()?;
2015 sps.frame_cropping_flag = r.read_bit()?;
2016
2017 if sps.frame_cropping_flag {
2018 sps.frame_crop_left_offset = r.read_ue()?;
2019 sps.frame_crop_right_offset = r.read_ue()?;
2020 sps.frame_crop_top_offset = r.read_ue()?;
2021 sps.frame_crop_bottom_offset = r.read_ue()?;
2022
2023 let (crop_unit_x, crop_unit_y) = sps.crop_unit_x_y();
2025
2026 let _ = sps
2027 .frame_crop_left_offset
2028 .checked_add(sps.frame_crop_right_offset)
2029 .and_then(|r| r.checked_mul(crop_unit_x))
2030 .and_then(|r| sps.width().checked_sub(r))
2031 .ok_or(anyhow!("Invalid frame crop width"))?;
2032
2033 let _ = sps
2034 .frame_crop_top_offset
2035 .checked_add(sps.frame_crop_bottom_offset)
2036 .and_then(|r| r.checked_mul(crop_unit_y))
2037 .and_then(|r| sps.height().checked_sub(r))
2038 .ok_or(anyhow!("invalid frame crop height"))?;
2039 }
2040
2041 sps.vui_parameters_present_flag = r.read_bit()?;
2042 if sps.vui_parameters_present_flag {
2043 Parser::parse_vui(&mut r, &mut sps)?;
2044 }
2045
2046 let key = sps.seq_parameter_set_id;
2047
2048 if self.active_spses.keys().len() >= MAX_SPS_COUNT as usize {
2049 return Err(anyhow!(
2050 "Broken data: Number of active SPSs > MAX_SPS_COUNT"
2051 ));
2052 }
2053
2054 let sps = Rc::new(sps);
2055 self.active_spses.remove(&key);
2056 Ok(self.active_spses.entry(key).or_insert(sps))
2057 }
2058
2059 pub fn parse_pps(&mut self, nalu: &Nalu) -> anyhow::Result<&Pps> {
2060 if !matches!(nalu.header.type_, NaluType::Pps) {
2061 return Err(anyhow!(
2062 "Invalid NALU type, expected {:?}, got {:?}",
2063 NaluType::Pps,
2064 nalu.header.type_
2065 ));
2066 }
2067
2068 let data = nalu.as_ref();
2069 let mut r = NaluReader::new(&data[nalu.header.len()..]);
2071 let pic_parameter_set_id = r.read_ue_max(MAX_PPS_COUNT as u32 - 1)?;
2072 let seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
2073 let sps = self.get_sps(seq_parameter_set_id).context(
2074 "Broken stream: stream references a SPS that has not been successfully parsed",
2075 )?;
2076 let mut pps = Pps {
2077 pic_parameter_set_id,
2078 seq_parameter_set_id,
2079 sps: Rc::clone(sps),
2080 scaling_lists_4x4: [[0; 16]; 6],
2081 scaling_lists_8x8: [[0; 64]; 6],
2082 entropy_coding_mode_flag: Default::default(),
2083 bottom_field_pic_order_in_frame_present_flag: Default::default(),
2084 num_slice_groups_minus1: Default::default(),
2085 num_ref_idx_l0_default_active_minus1: Default::default(),
2086 num_ref_idx_l1_default_active_minus1: Default::default(),
2087 weighted_pred_flag: Default::default(),
2088 weighted_bipred_idc: Default::default(),
2089 pic_init_qp_minus26: Default::default(),
2090 pic_init_qs_minus26: Default::default(),
2091 chroma_qp_index_offset: Default::default(),
2092 deblocking_filter_control_present_flag: Default::default(),
2093 constrained_intra_pred_flag: Default::default(),
2094 redundant_pic_cnt_present_flag: Default::default(),
2095 transform_8x8_mode_flag: Default::default(),
2096 second_chroma_qp_index_offset: Default::default(),
2097 pic_scaling_matrix_present_flag: Default::default(),
2098 };
2099
2100 pps.entropy_coding_mode_flag = r.read_bit()?;
2101 pps.bottom_field_pic_order_in_frame_present_flag = r.read_bit()?;
2102 pps.num_slice_groups_minus1 = r.read_ue_max(7)?;
2103
2104 if pps.num_slice_groups_minus1 > 0 {
2105 return Err(anyhow!("Stream contain unsupported/unimplemented NALs"));
2106 }
2107
2108 pps.num_ref_idx_l0_default_active_minus1 = r.read_ue_max(31)?;
2109 pps.num_ref_idx_l1_default_active_minus1 = r.read_ue_max(31)?;
2110
2111 pps.weighted_pred_flag = r.read_bit()?;
2112 pps.weighted_bipred_idc = r.read_bits(2)?;
2113
2114 let qp_bd_offset_y = i32::from(6 * (sps.bit_depth_luma_minus8));
2115 pps.pic_init_qp_minus26 = r.read_se_bounded(-(26 + qp_bd_offset_y), 25)?;
2116 pps.pic_init_qs_minus26 = r.read_se_bounded(-26, 25)?;
2117
2118 pps.chroma_qp_index_offset = r.read_se_bounded(-12, 12)?;
2119
2120 pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset;
2123
2124 pps.deblocking_filter_control_present_flag = r.read_bit()?;
2125 pps.constrained_intra_pred_flag = r.read_bit()?;
2126 pps.redundant_pic_cnt_present_flag = r.read_bit()?;
2127
2128 if r.has_more_rsbp_data() {
2129 pps.transform_8x8_mode_flag = r.read_bit()?;
2130 pps.pic_scaling_matrix_present_flag = r.read_bit()?;
2131
2132 if pps.pic_scaling_matrix_present_flag {
2133 Parser::parse_pps_scaling_lists(&mut r, &mut pps, sps)?;
2134 }
2135
2136 pps.second_chroma_qp_index_offset = r.read_se()?;
2137 }
2138
2139 if !pps.pic_scaling_matrix_present_flag {
2140 pps.scaling_lists_4x4 = sps.scaling_lists_4x4;
2145 pps.scaling_lists_8x8 = sps.scaling_lists_8x8;
2146 }
2147
2148 let key = pps.pic_parameter_set_id;
2149
2150 if self.active_ppses.keys().len() >= MAX_PPS_COUNT as usize {
2151 return Err(anyhow!(
2152 "Broken Data: number of active PPSs > MAX_PPS_COUNT"
2153 ));
2154 }
2155
2156 let pps = Rc::new(pps);
2157 self.active_ppses.remove(&key);
2158 Ok(self.active_ppses.entry(key).or_insert(pps))
2159 }
2160
2161 fn parse_ref_pic_list_modification(
2162 r: &mut NaluReader,
2163 num_ref_idx_active_minus1: u8,
2164 ref_list_mods: &mut Vec<RefPicListModification>,
2165 ) -> anyhow::Result<()> {
2166 if num_ref_idx_active_minus1 >= 32 {
2167 return Err(anyhow!("Broken Data: num_ref_idx_active_minus1 >= 32"));
2168 }
2169
2170 loop {
2171 let mut pic_num_mod = RefPicListModification {
2172 modification_of_pic_nums_idc: r.read_ue_max(3)?,
2173 ..Default::default()
2174 };
2175
2176 match pic_num_mod.modification_of_pic_nums_idc {
2177 0 | 1 => {
2178 pic_num_mod.abs_diff_pic_num_minus1 = r.read_ue()?;
2179 }
2180
2181 2 => {
2182 pic_num_mod.long_term_pic_num = r.read_ue()?;
2183 }
2184
2185 3 => {
2186 ref_list_mods.push(pic_num_mod);
2187 break;
2188 }
2189
2190 _ => return Err(anyhow!("Broken Data: modification_of_pic_nums_idc > 3")),
2191 }
2192
2193 ref_list_mods.push(pic_num_mod);
2194 }
2195
2196 Ok(())
2197 }
2198
2199 fn parse_ref_pic_list_modifications(
2200 r: &mut NaluReader,
2201 header: &mut SliceHeader,
2202 ) -> anyhow::Result<()> {
2203 if !header.slice_type.is_i() && !header.slice_type.is_si() {
2204 header.ref_pic_list_modification_flag_l0 = r.read_bit()?;
2205 if header.ref_pic_list_modification_flag_l0 {
2206 Parser::parse_ref_pic_list_modification(
2207 r,
2208 header.num_ref_idx_l0_active_minus1,
2209 &mut header.ref_pic_list_modification_l0,
2210 )?;
2211 }
2212 }
2213
2214 if header.slice_type.is_b() {
2215 header.ref_pic_list_modification_flag_l1 = r.read_bit()?;
2216 if header.ref_pic_list_modification_flag_l1 {
2217 Parser::parse_ref_pic_list_modification(
2218 r,
2219 header.num_ref_idx_l1_active_minus1,
2220 &mut header.ref_pic_list_modification_l1,
2221 )?;
2222 }
2223 }
2224
2225 Ok(())
2226 }
2227
2228 fn parse_pred_weight_table(
2229 r: &mut NaluReader,
2230 sps: &Sps,
2231 header: &mut SliceHeader,
2232 ) -> anyhow::Result<()> {
2233 let pt = &mut header.pred_weight_table;
2234 pt.luma_log2_weight_denom = r.read_ue_max(7)?;
2235
2236 let default_luma_weight = 1 << pt.luma_log2_weight_denom;
2240 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2241 pt.luma_weight_l0[usize::from(i)] = default_luma_weight;
2242 }
2243
2244 if header.slice_type.is_b() {
2248 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2249 pt.luma_weight_l1[usize::from(i)] = default_luma_weight;
2250 }
2251 }
2252
2253 if sps.chroma_array_type() != 0 {
2254 pt.chroma_log2_weight_denom = r.read_ue_max(7)?;
2255 let default_chroma_weight = 1 << pt.chroma_log2_weight_denom;
2256
2257 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2261 pt.chroma_weight_l0[usize::from(i)][0] = default_chroma_weight;
2262 pt.chroma_weight_l0[usize::from(i)][1] = default_chroma_weight;
2263 }
2264
2265 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2269 pt.chroma_weight_l1[usize::from(i)][0] = default_chroma_weight;
2270 pt.chroma_weight_l1[usize::from(i)][1] = default_chroma_weight;
2271 }
2272 }
2273
2274 for i in 0..=header.num_ref_idx_l0_active_minus1 {
2275 let luma_weight_l0_flag = r.read_bit()?;
2276
2277 if luma_weight_l0_flag {
2278 pt.luma_weight_l0[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2279 pt.luma_offset_l0[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2280 }
2281
2282 if sps.chroma_array_type() != 0 {
2283 let chroma_weight_l0_flag = r.read_bit()?;
2284 if chroma_weight_l0_flag {
2285 for j in 0..2 {
2286 pt.chroma_weight_l0[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2287 pt.chroma_offset_l0[usize::from(i)][j] = r.read_se_bounded(-128, 127)?;
2288 }
2289 }
2290 }
2291 }
2292
2293 if header.slice_type.is_b() {
2294 for i in 0..=header.num_ref_idx_l1_active_minus1 {
2295 let luma_weight_l1_flag = r.read_bit()?;
2296
2297 if luma_weight_l1_flag {
2298 pt.luma_weight_l1[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2299 pt.luma_offset_l1[usize::from(i)] = r.read_se_bounded(-128, 127)?;
2300 }
2301
2302 if sps.chroma_array_type() != 0 {
2303 let chroma_weight_l1_flag = r.read_bit()?;
2304 if chroma_weight_l1_flag {
2305 for j in 0..2 {
2306 pt.chroma_weight_l1[usize::from(i)][j] =
2307 r.read_se_bounded(-128, 127)?;
2308 pt.chroma_offset_l1[usize::from(i)][j] =
2309 r.read_se_bounded(-128, 127)?;
2310 }
2311 }
2312 }
2313 }
2314 }
2315
2316 Ok(())
2317 }
2318
2319 fn parse_dec_ref_pic_marking(
2320 r: &mut NaluReader,
2321 nalu: &Nalu,
2322 header: &mut SliceHeader,
2323 ) -> anyhow::Result<()> {
2324 let rpm = &mut header.dec_ref_pic_marking;
2325
2326 if nalu.header.idr_pic_flag {
2327 rpm.no_output_of_prior_pics_flag = r.read_bit()?;
2328 rpm.long_term_reference_flag = r.read_bit()?;
2329 } else {
2330 rpm.adaptive_ref_pic_marking_mode_flag = r.read_bit()?;
2331
2332 if rpm.adaptive_ref_pic_marking_mode_flag {
2333 loop {
2334 let mut marking = RefPicMarkingInner::default();
2335
2336 let mem_mgmt_ctrl_op = r.read_ue_max::<u8>(6)?;
2337 marking.memory_management_control_operation = mem_mgmt_ctrl_op;
2338
2339 if mem_mgmt_ctrl_op == 0 {
2340 break;
2341 }
2342
2343 if mem_mgmt_ctrl_op == 1 || mem_mgmt_ctrl_op == 3 {
2344 marking.difference_of_pic_nums_minus1 = r.read_ue()?;
2345 }
2346
2347 if mem_mgmt_ctrl_op == 2 {
2348 marking.long_term_pic_num = r.read_ue()?;
2349 }
2350
2351 if mem_mgmt_ctrl_op == 3 || mem_mgmt_ctrl_op == 6 {
2352 marking.long_term_frame_idx = r.read_ue()?;
2353 }
2354
2355 if mem_mgmt_ctrl_op == 4 {
2356 marking.max_long_term_frame_idx =
2357 MaxLongTermFrameIdx::from_value_plus1(r.read_ue()?);
2358 }
2359
2360 rpm.inner.push(marking);
2361 }
2362 }
2363 }
2364
2365 Ok(())
2366 }
2367
2368 pub fn parse_slice_header<'a>(&self, nalu: Nalu<'a>) -> anyhow::Result<Slice<'a>> {
2369 if !matches!(
2370 nalu.header.type_,
2371 NaluType::Slice
2372 | NaluType::SliceDpa
2373 | NaluType::SliceDpb
2374 | NaluType::SliceDpc
2375 | NaluType::SliceIdr
2376 | NaluType::SliceExt
2377 ) {
2378 return Err(anyhow!(
2379 "Invalid NALU type: {:?} is not a slice NALU",
2380 nalu.header.type_
2381 ));
2382 }
2383
2384 let data = nalu.as_ref();
2385 let mut r = NaluReader::new(&data[nalu.header.len()..]);
2387
2388 let mut header = SliceHeader {
2389 first_mb_in_slice: r.read_ue()?,
2390 ..Default::default()
2391 };
2392
2393 let slice_type = r.read_ue_max::<u8>(9)? % 5;
2394 header.slice_type = SliceType::n(slice_type)
2395 .with_context(|| format!("Invalid slice type {}", slice_type))?;
2396
2397 header.pic_parameter_set_id = r.read_ue()?;
2398
2399 let pps = self.get_pps(header.pic_parameter_set_id).context(
2400 "Broken stream: slice references PPS that has not been successfully parsed.",
2401 )?;
2402
2403 let sps = &pps.sps;
2404
2405 if sps.separate_colour_plane_flag {
2406 header.colour_plane_id = r.read_bits(2)?;
2407 }
2408
2409 header.frame_num = r.read_bits(usize::from(sps.log2_max_frame_num_minus4) + 4)?;
2410
2411 if !sps.frame_mbs_only_flag {
2412 header.field_pic_flag = r.read_bit()?;
2413 if header.field_pic_flag {
2414 header.bottom_field_flag = r.read_bit()?;
2415 }
2416 }
2417
2418 if header.field_pic_flag {
2419 header.max_pic_num = 2 * sps.max_frame_num();
2420 } else {
2421 header.max_pic_num = sps.max_frame_num();
2422 }
2423
2424 if nalu.header.idr_pic_flag {
2425 header.idr_pic_id = r.read_ue_max(0xffff)?;
2426 }
2427
2428 if sps.pic_order_cnt_type == 0 {
2429 header.pic_order_cnt_lsb =
2430 r.read_bits(usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4)?;
2431
2432 if pps.bottom_field_pic_order_in_frame_present_flag && !header.field_pic_flag {
2433 header.delta_pic_order_cnt_bottom = r.read_se()?;
2434 }
2435 }
2436
2437 if sps.pic_order_cnt_type == 1 && !sps.delta_pic_order_always_zero_flag {
2438 header.delta_pic_order_cnt[0] = r.read_se()?;
2439 if pps.bottom_field_pic_order_in_frame_present_flag && !header.field_pic_flag {
2440 header.delta_pic_order_cnt[1] = r.read_se()?;
2441 }
2442 }
2443
2444 if pps.redundant_pic_cnt_present_flag {
2445 header.redundant_pic_cnt = r.read_ue_max(127)?;
2446 }
2447
2448 if header.slice_type.is_b() {
2449 header.direct_spatial_mv_pred_flag = r.read_bit()?;
2450 }
2451
2452 if header.slice_type.is_p() || header.slice_type.is_sp() || header.slice_type.is_b() {
2453 header.num_ref_idx_active_override_flag = r.read_bit()?;
2454 if header.num_ref_idx_active_override_flag {
2455 header.num_ref_idx_l0_active_minus1 = r.read_ue()?;
2456 if header.slice_type.is_b() {
2457 header.num_ref_idx_l1_active_minus1 = r.read_ue()?;
2458 }
2459 } else {
2460 header.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1;
2461 if header.slice_type.is_b() {
2462 header.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1;
2463 }
2464 }
2465 }
2466
2467 if header.field_pic_flag {
2468 if header.num_ref_idx_l0_active_minus1 > 31 || header.num_ref_idx_l1_active_minus1 > 31
2469 {
2470 return Err(anyhow!("Broken Data"));
2471 }
2472 } else if header.num_ref_idx_l0_active_minus1 > 15
2473 || header.num_ref_idx_l1_active_minus1 > 15
2474 {
2475 return Err(anyhow!("Broken Data"));
2476 }
2477
2478 if let NaluType::SliceExt = nalu.header.type_ {
2479 return Err(anyhow!("Stream contain unsupported/unimplemented NALs"));
2480 }
2481
2482 Parser::parse_ref_pic_list_modifications(&mut r, &mut header)?;
2483
2484 if (pps.weighted_pred_flag && (header.slice_type.is_p() || header.slice_type.is_sp()))
2485 || (pps.weighted_bipred_idc == 1 && header.slice_type.is_b())
2486 {
2487 Parser::parse_pred_weight_table(&mut r, sps, &mut header)?;
2488 }
2489
2490 if nalu.header.ref_idc != 0 {
2491 Parser::parse_dec_ref_pic_marking(&mut r, &nalu, &mut header)?;
2492 }
2493
2494 if pps.entropy_coding_mode_flag && !header.slice_type.is_i() && !header.slice_type.is_si() {
2495 header.cabac_init_idc = r.read_ue_max(2)?;
2496 }
2497
2498 header.slice_qp_delta = r.read_se_bounded(-87, 77)?;
2499
2500 if header.slice_type.is_sp() || header.slice_type.is_si() {
2501 if header.slice_type.is_sp() {
2502 header.sp_for_switch_flag = r.read_bit()?;
2503 }
2504
2505 header.slice_qs_delta = r.read_se_bounded(-51, 51)?;
2506 }
2507
2508 if pps.deblocking_filter_control_present_flag {
2509 header.disable_deblocking_filter_idc = r.read_ue_max(2)?;
2510
2511 if header.disable_deblocking_filter_idc != 1 {
2512 header.slice_alpha_c0_offset_div2 = r.read_se_bounded(-6, 6)?;
2513 header.slice_beta_offset_div2 = r.read_se_bounded(-6, 6)?;
2514 }
2515 }
2516
2517 if pps.num_slice_groups_minus1 > 0 {
2518 return Err(anyhow!("Stream contain unsupported/unimplemented NALs"));
2519 }
2520
2521 let epb = r.num_epb();
2522 header.header_bit_size = (nalu.size - epb) * 8 - r.num_bits_left();
2523
2524 header.n_emulation_prevention_bytes = epb;
2525
2526 Ok(Slice { header, nalu })
2527 }
2528
2529 pub fn get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>> {
2530 self.active_spses.get(&sps_id)
2531 }
2532
2533 pub fn get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>> {
2534 self.active_ppses.get(&pps_id)
2535 }
2536}
2537
2538#[derive(Debug)]
2539pub struct NaluHeader {
2540 pub ref_idc: u8,
2541 pub type_: NaluType,
2542 pub idr_pic_flag: bool,
2543}
2544
2545impl Header for NaluHeader {
2546 fn parse<T: AsRef<[u8]>>(cursor: &Cursor<T>) -> anyhow::Result<Self> {
2547 if !cursor.has_remaining() {
2548 return Err(anyhow!("Broken Data"));
2549 }
2550
2551 let byte = cursor.chunk()[0];
2552
2553 let type_ = NaluType::n(byte & 0x1f).ok_or(anyhow!("Broken Data"))?;
2554
2555 if let NaluType::SliceExt = type_ {
2556 return Err(anyhow!("Stream contain unsupported/unimplemented NALs"));
2557 }
2558
2559 let ref_idc = (byte & 0x60) >> 5;
2560 let idr_pic_flag = matches!(type_, NaluType::SliceIdr);
2561
2562 Ok(NaluHeader {
2563 ref_idc,
2564 type_,
2565 idr_pic_flag,
2566 })
2567 }
2568
2569 fn is_end(&self) -> bool {
2570 matches!(self.type_, NaluType::SeqEnd | NaluType::StreamEnd)
2571 }
2572
2573 fn len(&self) -> usize {
2574 1
2575 }
2576}
2577
2578#[cfg(test)]
2579mod tests {
2580 use std::io::Cursor;
2581
2582 use crate::codec::h264::parser::Level;
2583 use crate::codec::h264::parser::MaxLongTermFrameIdx;
2584 use crate::codec::h264::parser::Nalu;
2585 use crate::codec::h264::parser::NaluType;
2586 use crate::codec::h264::parser::Parser;
2587
2588 const STREAM_TEST_25_FPS: &[u8] = include_bytes!("test_data/test-25fps.h264");
2589 const STREAM_TEST_25_FPS_NUM_NALUS: usize = 759;
2590
2591 const STREAM_TEST_25_FPS_SLICE_0: &[u8] =
2592 include_bytes!("test_data/test-25fps-h264-slice-data-0.bin");
2593 const STREAM_TEST_25_FPS_SLICE_2: &[u8] =
2594 include_bytes!("test_data/test-25fps-h264-slice-data-2.bin");
2595 const STREAM_TEST_25_FPS_SLICE_4: &[u8] =
2596 include_bytes!("test_data/test-25fps-h264-slice-data-4.bin");
2597
2598 #[test]
2600 fn parse_nalus_from_stream_file() {
2601 let mut cursor = Cursor::new(STREAM_TEST_25_FPS);
2602 let mut num_nalus = 0;
2603 while Nalu::next(&mut cursor).is_ok() {
2604 num_nalus += 1;
2605 }
2606
2607 assert_eq!(num_nalus, STREAM_TEST_25_FPS_NUM_NALUS)
2608 }
2609
2610 #[test]
2615 fn parse_test25fps() {
2616 let mut cursor = Cursor::new(STREAM_TEST_25_FPS);
2617 let mut sps_ids = Vec::new();
2618 let mut pps_ids = Vec::new();
2619 let mut slices = Vec::new();
2620
2621 let mut parser = Parser::default();
2622
2623 while let Ok(nalu) = Nalu::next(&mut cursor) {
2624 match nalu.header.type_ {
2625 NaluType::Slice
2626 | NaluType::SliceDpa
2627 | NaluType::SliceDpb
2628 | NaluType::SliceDpc
2629 | NaluType::SliceIdr
2630 | NaluType::SliceExt => {
2631 let slice = parser.parse_slice_header(nalu).unwrap();
2632 slices.push(slice);
2633 }
2634 NaluType::Sps => {
2635 let sps = parser.parse_sps(&nalu).unwrap();
2636 sps_ids.push(sps.seq_parameter_set_id);
2637 }
2638 NaluType::Pps => {
2639 let pps = parser.parse_pps(&nalu).unwrap();
2640 pps_ids.push(pps.pic_parameter_set_id);
2641 }
2642 _ => {
2643 continue;
2644 }
2645 }
2646 }
2647
2648 for sps_id in &sps_ids {
2649 let sps = parser.get_sps(*sps_id).unwrap();
2651
2652 assert_eq!(sps.seq_parameter_set_id, 0);
2653 assert_eq!(sps.profile_idc, 77);
2654 assert!(!sps.constraint_set0_flag);
2655 assert!(sps.constraint_set1_flag);
2656 assert!(!sps.constraint_set2_flag);
2657 assert!(!sps.constraint_set3_flag);
2658 assert!(!sps.constraint_set4_flag);
2659 assert!(!sps.constraint_set5_flag);
2660 assert_eq!(sps.level_idc, Level::L1_3);
2661 assert_eq!(sps.chroma_format_idc, 1);
2662 assert!(!sps.separate_colour_plane_flag);
2663 assert_eq!(sps.bit_depth_luma_minus8, 0);
2664 assert_eq!(sps.bit_depth_chroma_minus8, 0);
2665 assert!(!sps.qpprime_y_zero_transform_bypass_flag);
2666 assert!(!sps.seq_scaling_matrix_present_flag);
2667
2668 for outer in &sps.scaling_lists_4x4 {
2669 for inner in outer {
2670 assert_eq!(*inner, 16);
2671 }
2672 }
2673
2674 for outer in &sps.scaling_lists_8x8 {
2675 for inner in outer {
2676 assert_eq!(*inner, 16);
2677 }
2678 }
2679
2680 assert_eq!(sps.log2_max_frame_num_minus4, 1);
2681 assert_eq!(sps.pic_order_cnt_type, 0);
2682 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 3);
2683 assert!(!sps.delta_pic_order_always_zero_flag);
2684 assert_eq!(sps.offset_for_non_ref_pic, 0);
2685 assert_eq!(sps.offset_for_top_to_bottom_field, 0);
2686 assert_eq!(sps.num_ref_frames_in_pic_order_cnt_cycle, 0);
2687
2688 for offset in sps.offset_for_ref_frame {
2689 assert_eq!(offset, 0);
2690 }
2691
2692 assert_eq!(sps.max_num_ref_frames, 2);
2693 assert!(!sps.gaps_in_frame_num_value_allowed_flag);
2694 assert_eq!(sps.pic_width_in_mbs_minus1, 19);
2695 assert_eq!(sps.pic_height_in_map_units_minus1, 14);
2696 assert!(sps.frame_mbs_only_flag);
2697 assert!(!sps.mb_adaptive_frame_field_flag);
2698 assert!(!sps.direct_8x8_inference_flag);
2699 assert!(!sps.frame_cropping_flag);
2700 assert_eq!(sps.frame_crop_left_offset, 0);
2701 assert_eq!(sps.frame_crop_right_offset, 0);
2702 assert_eq!(sps.frame_crop_top_offset, 0);
2703 assert_eq!(sps.frame_crop_bottom_offset, 0);
2704 assert_eq!(sps.chroma_array_type(), 1);
2705 assert_eq!(sps.max_frame_num(), 32);
2706 assert_eq!(sps.width(), 320);
2707 assert_eq!(sps.height(), 240);
2708 }
2709
2710 for pps_id in &pps_ids {
2711 let pps = parser.get_pps(*pps_id).unwrap();
2713 assert_eq!(pps.pic_parameter_set_id, 0);
2714 assert_eq!(pps.seq_parameter_set_id, 0);
2715 assert!(pps.bottom_field_pic_order_in_frame_present_flag);
2716 assert_eq!(pps.num_slice_groups_minus1, 0);
2717 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0);
2718 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0);
2719 assert!(!pps.weighted_pred_flag);
2720 assert_eq!(pps.weighted_bipred_idc, 0);
2721 assert_eq!(pps.pic_init_qp_minus26, 2);
2722 assert_eq!(pps.pic_init_qs_minus26, 0);
2723 assert_eq!(pps.chroma_qp_index_offset, 0);
2724 assert!(!pps.deblocking_filter_control_present_flag);
2725 assert!(!pps.constrained_intra_pred_flag);
2726 assert!(!pps.redundant_pic_cnt_present_flag);
2727 assert!(!pps.transform_8x8_mode_flag);
2728
2729 for outer in &pps.scaling_lists_4x4 {
2730 for inner in outer {
2731 assert_eq!(*inner, 16);
2732 }
2733 }
2734
2735 for outer in &pps.scaling_lists_8x8 {
2736 for inner in outer {
2737 assert_eq!(*inner, 16);
2738 }
2739 }
2740
2741 assert_eq!(pps.second_chroma_qp_index_offset, 0);
2742 assert!(!pps.pic_scaling_matrix_present_flag);
2743 }
2744
2745 let hdr = &slices[0].header;
2747 let nalu = &slices[0].nalu;
2748 assert_eq!(nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_0);
2749
2750 assert_eq!(hdr.first_mb_in_slice, 0);
2751 assert!(hdr.slice_type.is_i());
2752 assert_eq!(hdr.colour_plane_id, 0);
2753 assert_eq!(hdr.frame_num, 0);
2754 assert!(!hdr.field_pic_flag);
2755 assert!(!hdr.bottom_field_flag);
2756 assert_eq!(hdr.idr_pic_id, 0);
2757 assert_eq!(hdr.pic_order_cnt_lsb, 0);
2758 assert_eq!(hdr.delta_pic_order_cnt_bottom, 0);
2759 assert_eq!(hdr.delta_pic_order_cnt[0], 0);
2760 assert_eq!(hdr.delta_pic_order_cnt[1], 0);
2761 assert_eq!(hdr.redundant_pic_cnt, 0);
2762 assert!(!hdr.direct_spatial_mv_pred_flag);
2763 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
2764 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
2765 assert!(!hdr.ref_pic_list_modification_flag_l0);
2766
2767 assert_eq!(hdr.ref_pic_list_modification_l0.len(), 0);
2768
2769 for rplm in &hdr.ref_pic_list_modification_l0 {
2770 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2771 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2772 assert_eq!(rplm.long_term_pic_num, 0);
2773 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2774 }
2775
2776 assert!(!hdr.ref_pic_list_modification_flag_l1);
2777 assert_eq!(hdr.ref_pic_list_modification_l1.len(), 0);
2778
2779 for rplm in &hdr.ref_pic_list_modification_l1 {
2780 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2781 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2782 assert_eq!(rplm.long_term_pic_num, 0);
2783 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2784 }
2785
2786 assert_eq!(hdr.pred_weight_table, unsafe { std::mem::zeroed() });
2788
2789 assert_eq!(hdr.dec_ref_pic_marking, Default::default());
2790
2791 assert_eq!(hdr.cabac_init_idc, 0);
2792 assert_eq!(hdr.slice_qp_delta, 12);
2793 assert_eq!(hdr.slice_qs_delta, 0);
2794 assert_eq!(hdr.disable_deblocking_filter_idc, 0);
2795 assert_eq!(hdr.slice_alpha_c0_offset_div2, 0);
2796 assert_eq!(hdr.slice_beta_offset_div2, 0);
2797 assert_eq!(hdr.max_pic_num, 32);
2798 assert_eq!(hdr.header_bit_size, 38);
2799 assert!(!hdr.num_ref_idx_active_override_flag);
2800
2801 let hdr = &slices[2].header;
2803 let nalu = &slices[2].nalu;
2804 assert_eq!(nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_2);
2805
2806 assert_eq!(hdr.first_mb_in_slice, 0);
2807 assert!(hdr.slice_type.is_p());
2808 assert_eq!(hdr.colour_plane_id, 0);
2809 assert_eq!(hdr.frame_num, 1);
2810 assert!(!hdr.field_pic_flag);
2811 assert!(!hdr.bottom_field_flag);
2812 assert_eq!(hdr.idr_pic_id, 0);
2813 assert_eq!(hdr.pic_order_cnt_lsb, 4);
2814 assert_eq!(hdr.delta_pic_order_cnt_bottom, 0);
2815 assert_eq!(hdr.delta_pic_order_cnt[0], 0);
2816 assert_eq!(hdr.delta_pic_order_cnt[1], 0);
2817 assert_eq!(hdr.redundant_pic_cnt, 0);
2818 assert!(!hdr.direct_spatial_mv_pred_flag);
2819 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
2820 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
2821 assert!(!hdr.ref_pic_list_modification_flag_l0);
2822
2823 assert_eq!(hdr.ref_pic_list_modification_l0.len(), 0);
2824
2825 for rplm in &hdr.ref_pic_list_modification_l0 {
2826 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2827 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2828 assert_eq!(rplm.long_term_pic_num, 0);
2829 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2830 }
2831
2832 assert!(!hdr.ref_pic_list_modification_flag_l1);
2833 assert_eq!(hdr.ref_pic_list_modification_l1.len(), 0);
2834
2835 for rplm in &hdr.ref_pic_list_modification_l1 {
2836 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2837 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2838 assert_eq!(rplm.long_term_pic_num, 0);
2839 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2840 }
2841
2842 assert_eq!(hdr.pred_weight_table, unsafe { std::mem::zeroed() });
2844
2845 assert_eq!(hdr.dec_ref_pic_marking, Default::default());
2846
2847 assert_eq!(hdr.cabac_init_idc, 0);
2848 assert_eq!(hdr.slice_qp_delta, 0);
2849 assert_eq!(hdr.slice_qs_delta, 0);
2850 assert_eq!(hdr.disable_deblocking_filter_idc, 0);
2851 assert_eq!(hdr.slice_alpha_c0_offset_div2, 0);
2852 assert_eq!(hdr.slice_beta_offset_div2, 0);
2853 assert_eq!(hdr.max_pic_num, 32);
2854 assert_eq!(hdr.header_bit_size, 28);
2855 assert!(!hdr.num_ref_idx_active_override_flag);
2856
2857 let hdr = &slices[4].header;
2859 let nalu = &slices[4].nalu;
2860 assert_eq!(nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_4);
2861
2862 assert_eq!(hdr.first_mb_in_slice, 0);
2863 assert!(hdr.slice_type.is_b());
2864 assert_eq!(hdr.colour_plane_id, 0);
2865 assert_eq!(hdr.frame_num, 2);
2866 assert!(!hdr.field_pic_flag);
2867 assert!(!hdr.bottom_field_flag);
2868 assert_eq!(hdr.idr_pic_id, 0);
2869 assert_eq!(hdr.pic_order_cnt_lsb, 2);
2870 assert_eq!(hdr.delta_pic_order_cnt_bottom, 0);
2871 assert_eq!(hdr.delta_pic_order_cnt[0], 0);
2872 assert_eq!(hdr.delta_pic_order_cnt[1], 0);
2873 assert_eq!(hdr.redundant_pic_cnt, 0);
2874 assert!(hdr.direct_spatial_mv_pred_flag);
2875 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
2876 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
2877 assert!(!hdr.ref_pic_list_modification_flag_l0);
2878
2879 assert_eq!(hdr.ref_pic_list_modification_l0.len(), 0);
2880
2881 for rplm in &hdr.ref_pic_list_modification_l0 {
2882 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2883 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2884 assert_eq!(rplm.long_term_pic_num, 0);
2885 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2886 }
2887
2888 assert!(!hdr.ref_pic_list_modification_flag_l1);
2889 assert_eq!(hdr.ref_pic_list_modification_l1.len(), 0);
2890
2891 for rplm in &hdr.ref_pic_list_modification_l1 {
2892 assert_eq!(rplm.modification_of_pic_nums_idc, 0);
2893 assert_eq!(rplm.abs_diff_pic_num_minus1, 0);
2894 assert_eq!(rplm.long_term_pic_num, 0);
2895 assert_eq!(rplm.abs_diff_view_idx_minus1, 0);
2896 }
2897
2898 assert_eq!(hdr.pred_weight_table, unsafe { std::mem::zeroed() });
2900
2901 assert_eq!(hdr.dec_ref_pic_marking, Default::default());
2902
2903 assert_eq!(hdr.cabac_init_idc, 0);
2904 assert_eq!(hdr.slice_qp_delta, 16);
2905 assert_eq!(hdr.slice_qs_delta, 0);
2906 assert_eq!(hdr.disable_deblocking_filter_idc, 0);
2907 assert_eq!(hdr.slice_alpha_c0_offset_div2, 0);
2908 assert_eq!(hdr.slice_beta_offset_div2, 0);
2909 assert_eq!(hdr.max_pic_num, 32);
2910 assert_eq!(hdr.header_bit_size, 41);
2911 assert!(!hdr.num_ref_idx_active_override_flag);
2912 }
2913
2914 #[test]
2915 fn invalid_sps_crop_width() {
2916 let invalid_sps = vec![
2920 0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x0a, 0xfb, 0xb0, 0x32, 0xc0, 0xca, 0x80,
2921 ];
2922
2923 let mut cursor = Cursor::new(invalid_sps.as_ref());
2924 let mut parser = Parser::default();
2925
2926 while let Ok(nalu) = Nalu::next(&mut cursor) {
2927 assert_eq!(nalu.header.type_, NaluType::Sps);
2928 parser.parse_sps(&nalu).unwrap_err();
2929 }
2930 }
2931
2932 #[test]
2933 fn max_long_term_frame_idx() {
2934 assert_eq!(
2935 MaxLongTermFrameIdx::from_value_plus1(0),
2936 MaxLongTermFrameIdx::NoLongTermFrameIndices
2937 );
2938 assert_eq!(
2939 MaxLongTermFrameIdx::NoLongTermFrameIndices.to_value_plus1(),
2940 0
2941 );
2942
2943 assert_eq!(
2944 MaxLongTermFrameIdx::from_value_plus1(1),
2945 MaxLongTermFrameIdx::Idx(0)
2946 );
2947 assert_eq!(MaxLongTermFrameIdx::Idx(0).to_value_plus1(), 1);
2948
2949 assert_eq!(
2950 MaxLongTermFrameIdx::from_value_plus1(25),
2951 MaxLongTermFrameIdx::Idx(24)
2952 );
2953 assert_eq!(MaxLongTermFrameIdx::Idx(24).to_value_plus1(), 25);
2954
2955 assert!(MaxLongTermFrameIdx::NoLongTermFrameIndices < 0);
2957 assert_ne!(MaxLongTermFrameIdx::NoLongTermFrameIndices, 0);
2958 assert_eq!(MaxLongTermFrameIdx::Idx(0), 0);
2959 assert!(MaxLongTermFrameIdx::Idx(0) < 1);
2960 assert_eq!(MaxLongTermFrameIdx::Idx(24), 24);
2961 assert!(MaxLongTermFrameIdx::Idx(24) < 25);
2962 }
2963}