1use std::collections::BTreeMap;
10
11use anyhow::anyhow;
12use anyhow::Context;
13use bitreader::BitReader;
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::parser::Point;
21use crate::codec::h264::parser::Rect;
22
23const MAX_VPS_COUNT: usize = 16;
25const MAX_SPS_COUNT: usize = 16;
27const MAX_PPS_COUNT: usize = 64;
29const MAX_REF_IDX_ACTIVE: u32 = 15;
31
32const MAX_SHORT_TERM_REF_PIC_SETS: usize = 65;
43
44const MAX_LONG_TERM_REF_PIC_SETS: usize = 32;
46
47const DEFAULT_SCALING_LIST_0: [u8; 16] = [16; 16];
49
50const DEFAULT_SCALING_LIST_1: [u8; 64] = [
52 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
53 21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24, 25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
54 29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70, 65, 88, 88, 115,
55];
56
57const DEFAULT_SCALING_LIST_2: [u8; 64] = [
59 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
60 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
61 28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54, 54, 71, 71, 91,
62];
63
64#[derive(N, Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
66pub enum NaluType {
67 #[default]
68 TrailN = 0,
69 TrailR = 1,
70 TsaN = 2,
71 TsaR = 3,
72 StsaN = 4,
73 StsaR = 5,
74 RadlN = 6,
75 RadlR = 7,
76 RaslN = 8,
77 RaslR = 9,
78 RsvVclN10 = 10,
79 RsvVclR11 = 11,
80 RsvVclN12 = 12,
81 RsvVclR13 = 13,
82 RsvVclN14 = 14,
83 RsvVclR15 = 15,
84 BlaWLp = 16,
85 BlaWRadl = 17,
86 BlaNLp = 18,
87 IdrWRadl = 19,
88 IdrNLp = 20,
89 CraNut = 21,
90 RsvIrapVcl22 = 22,
91 RsvIrapVcl23 = 23,
92 RsvVcl24 = 24,
93 RsvVcl25 = 25,
94 RsvVcl26 = 26,
95 RsvVcl27 = 27,
96 RsvVcl28 = 28,
97 RsvVcl29 = 29,
98 RsvVcl30 = 30,
99 RsvVcl31 = 31,
100 VpsNut = 32,
101 SpsNut = 33,
102 PpsNut = 34,
103 AudNut = 35,
104 EosNut = 36,
105 EobNut = 37,
106 FdNut = 38,
107 PrefixSeiNut = 39,
108 SuffixSeiNut = 40,
109 RsvNvcl41 = 41,
110 RsvNvcl42 = 42,
111 RsvNvcl43 = 43,
112 RsvNvcl44 = 44,
113 RsvNvcl45 = 45,
114 RsvNvcl46 = 46,
115 RsvNvcl47 = 47,
116}
117
118impl NaluType {
119 pub fn is_idr(&self) -> bool {
121 matches!(self, Self::IdrWRadl | Self::IdrNLp)
122 }
123
124 pub fn is_irap(&self) -> bool {
126 let type_ = *self as u32;
127 type_ >= Self::BlaWLp as u32 && type_ <= Self::RsvIrapVcl23 as u32
128 }
129
130 pub fn is_bla(&self) -> bool {
132 let type_ = *self as u32;
133 type_ >= Self::BlaWLp as u32 && type_ <= Self::BlaNLp as u32
134 }
135
136 pub fn is_cra(&self) -> bool {
138 matches!(self, Self::CraNut)
139 }
140
141 pub fn is_radl(&self) -> bool {
143 matches!(self, Self::RadlN | Self::RadlR)
144 }
145
146 pub fn is_rasl(&self) -> bool {
148 matches!(self, Self::RaslN | Self::RaslR)
149 }
150
151 pub fn is_slnr(&self) -> bool {
153 matches!(
159 self,
160 Self::TrailN
161 | Self::TsaN
162 | Self::StsaN
163 | Self::RadlN
164 | Self::RaslN
165 | Self::RsvVclN10
166 | Self::RsvVclN12
167 | Self::RsvVclN14
168 )
169 }
170}
171
172#[derive(Clone, Debug, Default, PartialEq, Eq)]
173pub struct NaluHeader {
174 pub type_: NaluType,
176 pub nuh_layer_id: u8,
179 pub nuh_temporal_id_plus1: u8,
182}
183
184impl Header for NaluHeader {
185 fn parse<T: AsRef<[u8]>>(cursor: &std::io::Cursor<T>) -> anyhow::Result<Self> {
186 let data = &cursor.chunk()[0..2];
187 let mut r = BitReader::new(data);
188
189 r.skip(1)?;
191
192 Ok(Self {
193 type_: NaluType::n(r.read_u32(6)?).ok_or(anyhow!("Invalid NALU type"))?,
194 nuh_layer_id: r.read_u8(6)?,
195 nuh_temporal_id_plus1: r.read_u8(3)?,
196 })
197 }
198
199 fn is_end(&self) -> bool {
200 matches!(self.type_, NaluType::EosNut | NaluType::EobNut)
201 }
202
203 fn len(&self) -> usize {
204 2
206 }
207}
208
209pub type Nalu<'a> = nalu::Nalu<'a, NaluHeader>;
210
211#[derive(N, Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
215pub enum Level {
216 #[default]
217 L1 = 30,
218 L2 = 60,
219 L2_1 = 63,
220 L3 = 90,
221 L3_1 = 93,
222 L4 = 120,
223 L4_1 = 123,
224 L5 = 150,
225 L5_1 = 153,
226 L5_2 = 156,
227 L6 = 180,
228 L6_1 = 183,
229 L6_2 = 186,
230}
231
232#[derive(N, Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
234pub enum Profile {
235 #[default]
236 Main = 1,
237 Main10 = 2,
238 MainStill = 3,
239 RangeExtensions = 4,
240 HighThroughput = 5,
241 MultiviewMain = 6,
242 ScalableMain = 7,
243 ThreeDMain = 8,
244 ScreenContentCoding = 9,
245 ScalableRangeExtensions = 10,
246 HighThroughputScreenContentCoding = 11,
247}
248
249#[derive(Clone, Debug, PartialEq, Eq)]
251pub struct Vps {
252 pub video_parameter_set_id: u8,
254 pub base_layer_internal_flag: bool,
258 pub base_layer_available_flag: bool,
260 pub max_layers_minus1: u8,
263 pub max_sub_layers_minus1: u8,
266 pub temporal_id_nesting_flag: bool,
270 pub profile_tier_level: ProfileTierLevel,
272 pub sub_layer_ordering_info_present_flag: bool,
281 pub max_dec_pic_buffering_minus1: [u32; 7],
285 pub max_num_reorder_pics: [u32; 7],
290 pub max_latency_increase_plus1: [u32; 7],
297 pub max_layer_id: u8,
300 pub num_layer_sets_minus1: u32,
303 pub timing_info_present_flag: bool,
307 pub num_units_in_tick: u32,
317 pub time_scale: u32,
321 pub poc_proportional_to_timing_flag: bool,
330 pub num_ticks_poc_diff_one_minus1: u32,
333 pub num_hrd_parameters: u32,
336 pub hrd_layer_set_idx: Vec<u16>,
340 pub cprms_present_flag: Vec<bool>,
349 pub hrd_parameters: Vec<HrdParams>,
351 pub extension_flag: bool,
359}
360
361impl Default for Vps {
362 fn default() -> Self {
363 Self {
364 video_parameter_set_id: Default::default(),
365 base_layer_internal_flag: Default::default(),
366 base_layer_available_flag: Default::default(),
367 max_layers_minus1: Default::default(),
368 max_sub_layers_minus1: Default::default(),
369 temporal_id_nesting_flag: Default::default(),
370 profile_tier_level: Default::default(),
371 sub_layer_ordering_info_present_flag: Default::default(),
372 max_dec_pic_buffering_minus1: Default::default(),
373 max_num_reorder_pics: Default::default(),
374 max_latency_increase_plus1: Default::default(),
375 max_layer_id: Default::default(),
376 num_layer_sets_minus1: Default::default(),
377 timing_info_present_flag: Default::default(),
378 num_units_in_tick: Default::default(),
379 time_scale: Default::default(),
380 poc_proportional_to_timing_flag: Default::default(),
381 num_ticks_poc_diff_one_minus1: Default::default(),
382 num_hrd_parameters: Default::default(),
383 hrd_layer_set_idx: Default::default(),
384 cprms_present_flag: vec![true],
385 hrd_parameters: Default::default(),
386 extension_flag: Default::default(),
387 }
388 }
389}
390
391#[derive(Clone, Debug, Default, PartialEq, Eq)]
392pub struct ProfileTierLevel {
393 pub general_profile_space: u8,
397 pub general_tier_flag: bool,
400 pub general_profile_idc: u8,
406 pub general_profile_compatibility_flag: [bool; 32],
411 pub general_progressive_source_flag: bool,
431 pub general_interlaced_source_flag: bool,
433 pub general_non_packed_constraint_flag: bool,
442 pub general_frame_only_constraint_flag: bool,
445 pub general_max_12bit_constraint_flag: bool,
447 pub general_max_10bit_constraint_flag: bool,
449 pub general_max_8bit_constraint_flag: bool,
451 pub general_max_422chroma_constraint_flag: bool,
453 pub general_max_420chroma_constraint_flag: bool,
455 pub general_max_monochrome_constraint_flag: bool,
457 pub general_intra_constraint_flag: bool,
459 pub general_lower_bit_rate_constraint_flag: bool,
461 pub general_max_14bit_constraint_flag: bool,
463 pub general_one_picture_only_constraint_flag: bool,
465 pub general_inbld_flag: bool,
471 pub general_level_idc: Level,
473 pub sub_layer_profile_present_flag: [bool; 6],
475 pub sub_layer_level_present_flag: [bool; 6],
477 pub sub_layer_profile_space: [u8; 6],
479 pub sub_layer_tier_flag: [bool; 6],
481 pub sub_layer_profile_idc: [u8; 6],
483 pub sub_layer_profile_compatibility_flag: [[bool; 32]; 6],
485 pub sub_layer_progressive_source_flag: [bool; 6],
487 pub sub_layer_interlaced_source_flag: [bool; 6],
489 pub sub_layer_non_packed_constraint_flag: [bool; 6],
491 pub sub_layer_frame_only_constraint_flag: [bool; 6],
493 pub sub_layer_max_12bit_constraint_flag: [bool; 6],
495 pub sub_layer_max_10bit_constraint_flag: [bool; 6],
497 pub sub_layer_max_8bit_constraint_flag: [bool; 6],
499 pub sub_layer_max_422chroma_constraint_flag: [bool; 6],
501 pub sub_layer_max_420chroma_constraint_flag: [bool; 6],
503 pub sub_layer_max_monochrome_constraint_flag: [bool; 6],
505 pub sub_layer_intra_constraint_flag: [bool; 6],
507 pub sub_layer_one_picture_only_constraint_flag: [bool; 6],
509 pub sub_layer_lower_bit_rate_constraint_flag: [bool; 6],
511 pub sub_layer_max_14bit_constraint_flag: [bool; 6],
513 pub sub_layer_inbld_flag: [bool; 6],
515 pub sub_layer_level_idc: [Level; 6],
517}
518
519impl ProfileTierLevel {
520 pub fn max_luma_ps(&self) -> u32 {
521 match self.general_level_idc {
523 Level::L1 => 36864,
524 Level::L2 => 122880,
525 Level::L2_1 => 245760,
526 Level::L3 => 552960,
527 Level::L3_1 => 983040,
528 Level::L4 | Level::L4_1 => 2228224,
529 Level::L5 | Level::L5_1 | Level::L5_2 => 8912896,
530 _ => 35651584,
531 }
532 }
533
534 pub fn max_dpb_pic_buf(&self) -> u32 {
535 if self.general_profile_idc >= 1 && self.general_profile_idc <= 5 {
536 6
537 } else {
538 7
539 }
540 }
541}
542
543#[derive(Clone, Debug, Default, PartialEq, Eq)]
544pub struct SpsRangeExtension {
545 pub transform_skip_rotation_enabled_flag: bool,
546 pub transform_skip_context_enabled_flag: bool,
547 pub implicit_rdpcm_enabled_flag: bool,
548 pub explicit_rdpcm_enabled_flag: bool,
549 pub extended_precision_processing_flag: bool,
550 pub intra_smoothing_disabled_flag: bool,
551 pub high_precision_offsets_enabled_flag: bool,
552 pub persistent_rice_adaptation_enabled_flag: bool,
553 pub cabac_bypass_alignment_enabled_flag: bool,
554}
555
556#[derive(Clone, Debug, PartialEq, Eq)]
557pub struct SpsSccExtension {
558 pub curr_pic_ref_enabled_flag: bool,
563 pub palette_mode_enabled_flag: bool,
567 pub palette_max_size: u8,
569 pub delta_palette_max_predictor_size: u8,
572 pub palette_predictor_initializers_present_flag: bool,
576 pub num_palette_predictor_initializer_minus1: u8,
579 pub palette_predictor_initializer: [[u32; 128]; 3],
583 pub motion_vector_resolution_control_idc: u8,
586 pub intra_boundary_filtering_disabled_flag: bool,
590}
591
592impl Default for SpsSccExtension {
593 fn default() -> Self {
594 Self {
595 curr_pic_ref_enabled_flag: Default::default(),
596 palette_mode_enabled_flag: Default::default(),
597 palette_max_size: Default::default(),
598 delta_palette_max_predictor_size: Default::default(),
599 palette_predictor_initializers_present_flag: Default::default(),
600 num_palette_predictor_initializer_minus1: Default::default(),
601 palette_predictor_initializer: [[0; 128]; 3],
602 motion_vector_resolution_control_idc: Default::default(),
603 intra_boundary_filtering_disabled_flag: Default::default(),
604 }
605 }
606}
607
608#[derive(Clone, Debug, Default, PartialEq, Eq)]
610pub struct Sps {
611 pub video_parameter_set_id: u8,
613 pub max_sub_layers_minus1: u8,
616 pub temporal_id_nesting_flag: bool,
620 pub profile_tier_level: ProfileTierLevel,
622 pub seq_parameter_set_id: u8,
625 pub chroma_format_idc: u8,
628 pub separate_colour_plane_flag: bool,
632 pub pic_width_in_luma_samples: u16,
634 pub pic_height_in_luma_samples: u16,
636 pub conformance_window_flag: bool,
640 pub conf_win_left_offset: u32,
645 pub conf_win_right_offset: u32,
646 pub conf_win_top_offset: u32,
647 pub conf_win_bottom_offset: u32,
648
649 pub bit_depth_luma_minus8: u8,
652 pub bit_depth_chroma_minus8: u8,
656 pub log2_max_pic_order_cnt_lsb_minus4: u8,
659 pub sub_layer_ordering_info_present_flag: bool,
666 pub max_dec_pic_buffering_minus1: [u8; 7],
670 pub max_num_reorder_pics: [u8; 7],
676 pub max_latency_increase_plus1: [u8; 7],
683 pub log2_min_luma_coding_block_size_minus3: u8,
686 pub log2_diff_max_min_luma_coding_block_size: u8,
689 pub log2_min_luma_transform_block_size_minus2: u8,
692 pub log2_diff_max_min_luma_transform_block_size: u8,
695 pub max_transform_hierarchy_depth_inter: u8,
698 pub max_transform_hierarchy_depth_intra: u8,
701 pub scaling_list_enabled_flag: bool,
705 pub scaling_list_data_present_flag: bool,
710 pub scaling_list: ScalingLists,
712 pub amp_enabled_flag: bool,
717 pub sample_adaptive_offset_enabled_flag: bool,
722 pub pcm_enabled_flag: bool,
729
730 pub pcm_sample_bit_depth_luma_minus1: u8,
732 pub pcm_sample_bit_depth_chroma_minus1: u8,
735 pub log2_min_pcm_luma_coding_block_size_minus3: u8,
738 pub log2_diff_max_min_pcm_luma_coding_block_size: u8,
741 pub pcm_loop_filter_disabled_flag: bool,
753 pub num_short_term_ref_pic_sets: u8,
756 pub short_term_ref_pic_set: Vec<ShortTermRefPicSet>,
758 pub long_term_ref_pics_present_flag: bool,
763
764 pub num_long_term_ref_pics_sps: u8,
768 pub lt_ref_pic_poc_lsb_sps: [u32; MAX_LONG_TERM_REF_PIC_SETS],
772 pub used_by_curr_pic_lt_sps_flag: [bool; MAX_LONG_TERM_REF_PIC_SETS],
778 pub temporal_mvp_enabled_flag: bool,
784 pub strong_intra_smoothing_enabled_flag: bool,
788 pub vui_parameters_present_flag: bool,
793 pub vui_parameters: VuiParams,
795 pub extension_present_flag: bool,
801
802 pub range_extension_flag: bool,
803 pub range_extension: SpsRangeExtension,
805 pub scc_extension_flag: bool,
809 pub scc_extension: SpsSccExtension,
811
812 pub min_cb_log2_size_y: u32,
815 pub ctb_log2_size_y: u32,
817 pub ctb_size_y: u32,
819 pub pic_height_in_ctbs_y: u32,
821 pub pic_width_in_ctbs_y: u32,
823 pub pic_size_in_ctbs_y: u32,
825 pub chroma_array_type: u8,
827 pub wp_offset_half_range_y: u32,
829 pub wp_offset_half_range_c: u32,
831 pub max_tb_log2_size_y: u32,
833 pub pic_size_in_samples_y: u32,
835}
836
837impl Sps {
838 pub fn max_dpb_size(&self) -> usize {
839 let max_luma_ps = self.profile_tier_level.max_luma_ps();
840 let max_dpb_pic_buf = self.profile_tier_level.max_dpb_pic_buf();
841
842 let max = if self.pic_size_in_samples_y <= (max_luma_ps >> 2) {
844 std::cmp::min(4 * max_dpb_pic_buf, 16)
845 } else if self.pic_size_in_samples_y <= (max_luma_ps >> 1) {
846 std::cmp::min(2 * max_dpb_pic_buf, 16)
847 } else if self.pic_size_in_samples_y <= ((3 * max_luma_ps) >> 2) {
848 std::cmp::min(4 * max_dpb_pic_buf / 3, 16)
849 } else {
850 max_dpb_pic_buf
851 };
852
853 max as usize
854 }
855
856 pub fn width(&self) -> u16 {
857 self.pic_width_in_luma_samples
858 }
859
860 pub fn height(&self) -> u16 {
861 self.pic_height_in_luma_samples
862 }
863
864 pub fn visible_rectangle(&self) -> Rect<u32> {
865 if !self.conformance_window_flag {
870 return Rect {
871 min: Point { x: 0, y: 0 },
872 max: Point {
873 x: u32::from(self.width()),
874 y: u32::from(self.height()),
875 },
876 };
877 }
878 const SUB_HEIGHT_C: [u32; 5] = [1, 2, 1, 1, 1];
879 const SUB_WIDTH_C: [u32; 5] = [1, 2, 2, 1, 1];
880
881 let crop_unit_y = SUB_HEIGHT_C[usize::from(self.chroma_array_type)];
882 let crop_unit_x = SUB_WIDTH_C[usize::from(self.chroma_array_type)];
883 let crop_left = crop_unit_x * self.conf_win_left_offset;
884 let crop_right = crop_unit_x * self.conf_win_right_offset;
885 let crop_top = crop_unit_y * self.conf_win_top_offset;
886 let crop_bottom = crop_unit_y * self.conf_win_bottom_offset;
887
888 Rect {
889 min: Point {
890 x: crop_left,
891 y: crop_top,
892 },
893 max: Point {
894 x: u32::from(self.width()) - crop_left - crop_right,
895 y: u32::from(self.height()) - crop_top - crop_bottom,
896 },
897 }
898 }
899}
900
901#[derive(Clone, Debug, PartialEq, Eq)]
902pub struct PpsSccExtension {
903 pub curr_pic_ref_enabled_flag: bool,
908 pub residual_adaptive_colour_transform_enabled_flag: bool,
912 pub slice_act_qp_offsets_present_flag: bool,
917 pub act_y_qp_offset_plus5: i8,
919 pub act_cb_qp_offset_plus5: i8,
921 pub act_cr_qp_offset_plus3: i8,
923 pub palette_predictor_initializers_present_flag: bool,
929 pub num_palette_predictor_initializers: u8,
932 pub monochrome_palette_flag: bool,
936 pub luma_bit_depth_entry_minus8: u8,
939 pub chroma_bit_depth_entry_minus8: u8,
942 pub palette_predictor_initializer: [[u8; 128]; 3],
946}
947
948impl Default for PpsSccExtension {
949 fn default() -> Self {
950 Self {
951 curr_pic_ref_enabled_flag: Default::default(),
952 residual_adaptive_colour_transform_enabled_flag: Default::default(),
953 slice_act_qp_offsets_present_flag: Default::default(),
954 act_y_qp_offset_plus5: Default::default(),
955 act_cb_qp_offset_plus5: Default::default(),
956 act_cr_qp_offset_plus3: Default::default(),
957 palette_predictor_initializers_present_flag: Default::default(),
958 num_palette_predictor_initializers: Default::default(),
959 monochrome_palette_flag: Default::default(),
960 luma_bit_depth_entry_minus8: Default::default(),
961 chroma_bit_depth_entry_minus8: Default::default(),
962 palette_predictor_initializer: [[0; 128]; 3],
963 }
964 }
965}
966
967#[derive(Clone, Debug, Default, PartialEq, Eq)]
968pub struct PpsRangeExtension {
969 pub log2_max_transform_skip_block_size_minus2: u32,
976 pub cross_component_prediction_enabled_flag: bool,
982 pub chroma_qp_offset_list_enabled_flag: bool,
986 pub diff_cu_chroma_qp_offset_depth: u32,
989 pub chroma_qp_offset_list_len_minus1: u32,
993 pub cb_qp_offset_list: [i32; 6],
995 pub cr_qp_offset_list: [i32; 6],
997 pub log2_sao_offset_scale_luma: u32,
1000 pub log2_sao_offset_scale_chroma: u32,
1003}
1004
1005#[derive(Clone, Debug, PartialEq, Eq)]
1007pub struct Pps {
1008 pub pic_parameter_set_id: u8,
1010 pub seq_parameter_set_id: u8,
1012 pub dependent_slice_segments_enabled_flag: bool,
1018 pub output_flag_present_flag: bool,
1023 pub num_extra_slice_header_bits: u8,
1026 pub sign_data_hiding_enabled_flag: bool,
1029 pub cabac_init_present_flag: bool,
1033 pub num_ref_idx_l0_default_active_minus1: u8,
1036 pub num_ref_idx_l1_default_active_minus1: u8,
1039 pub init_qp_minus26: i8,
1044 pub constrained_intra_pred_flag: bool,
1051 pub transform_skip_enabled_flag: bool,
1055 pub cu_qp_delta_enabled_flag: bool,
1062
1063 pub diff_cu_qp_delta_depth: u8,
1068 pub cb_qp_offset: i8,
1071 pub cr_qp_offset: i8,
1074 pub slice_chroma_qp_offsets_present_flag: bool,
1080 pub weighted_pred_flag: bool,
1084 pub weighted_bipred_flag: bool,
1088 pub transquant_bypass_enabled_flag: bool,
1091 pub tiles_enabled_flag: bool,
1095 pub entropy_coding_sync_enabled_flag: bool,
1114 pub num_tile_columns_minus1: u8,
1117 pub num_tile_rows_minus1: u8,
1120 pub uniform_spacing_flag: bool,
1127 pub column_width_minus1: [u32; 19],
1130 pub row_height_minus1: [u32; 21],
1133 pub loop_filter_across_tiles_enabled_flag: bool,
1140 pub loop_filter_across_slices_enabled_flag: bool,
1147 pub deblocking_filter_control_present_flag: bool,
1151 pub deblocking_filter_override_enabled_flag: bool,
1156 pub deblocking_filter_disabled_flag: bool,
1163 pub beta_offset_div2: i8,
1169 pub tc_offset_div2: i8,
1175 pub scaling_list_data_present_flag: bool,
1182 pub scaling_list: ScalingLists,
1184 pub lists_modification_present_flag: bool,
1189 pub log2_parallel_merge_level_minus2: u8,
1195 pub slice_segment_header_extension_present_flag: bool,
1201 pub extension_present_flag: bool,
1207 pub range_extension_flag: bool,
1211 pub range_extension: PpsRangeExtension,
1213
1214 pub scc_extension_flag: bool,
1215 pub scc_extension: PpsSccExtension,
1217
1218 pub qp_bd_offset_y: u32,
1221
1222 pub temporal_id: u8,
1224}
1225
1226impl Default for Pps {
1227 fn default() -> Self {
1228 Self {
1229 pic_parameter_set_id: Default::default(),
1230 seq_parameter_set_id: Default::default(),
1231 dependent_slice_segments_enabled_flag: Default::default(),
1232 output_flag_present_flag: Default::default(),
1233 num_extra_slice_header_bits: Default::default(),
1234 sign_data_hiding_enabled_flag: Default::default(),
1235 cabac_init_present_flag: Default::default(),
1236 num_ref_idx_l0_default_active_minus1: Default::default(),
1237 num_ref_idx_l1_default_active_minus1: Default::default(),
1238 init_qp_minus26: Default::default(),
1239 constrained_intra_pred_flag: Default::default(),
1240 transform_skip_enabled_flag: Default::default(),
1241 cu_qp_delta_enabled_flag: Default::default(),
1242 diff_cu_qp_delta_depth: Default::default(),
1243 cb_qp_offset: Default::default(),
1244 cr_qp_offset: Default::default(),
1245 slice_chroma_qp_offsets_present_flag: Default::default(),
1246 weighted_pred_flag: Default::default(),
1247 weighted_bipred_flag: Default::default(),
1248 transquant_bypass_enabled_flag: Default::default(),
1249 tiles_enabled_flag: Default::default(),
1250 entropy_coding_sync_enabled_flag: Default::default(),
1251 num_tile_columns_minus1: Default::default(),
1252 num_tile_rows_minus1: Default::default(),
1253 uniform_spacing_flag: true,
1254 column_width_minus1: Default::default(),
1255 row_height_minus1: Default::default(),
1256 loop_filter_across_tiles_enabled_flag: true,
1257 loop_filter_across_slices_enabled_flag: Default::default(),
1258 deblocking_filter_control_present_flag: Default::default(),
1259 deblocking_filter_override_enabled_flag: Default::default(),
1260 deblocking_filter_disabled_flag: Default::default(),
1261 beta_offset_div2: Default::default(),
1262 tc_offset_div2: Default::default(),
1263 scaling_list_data_present_flag: Default::default(),
1264 scaling_list: Default::default(),
1265 lists_modification_present_flag: Default::default(),
1266 log2_parallel_merge_level_minus2: Default::default(),
1267 slice_segment_header_extension_present_flag: Default::default(),
1268 extension_present_flag: Default::default(),
1269 range_extension_flag: Default::default(),
1270 range_extension: Default::default(),
1271 qp_bd_offset_y: Default::default(),
1272 scc_extension: Default::default(),
1273 scc_extension_flag: Default::default(),
1274 temporal_id: Default::default(),
1275 }
1276 }
1277}
1278
1279#[derive(Clone, Debug, PartialEq, Eq)]
1280pub struct ScalingLists {
1281 pub scaling_list_dc_coef_minus8_16x16: [i16; 6],
1284 pub scaling_list_dc_coef_minus8_32x32: [i16; 6],
1287 pub scaling_list_4x4: [[u8; 16]; 6],
1289 pub scaling_list_8x8: [[u8; 64]; 6],
1291 pub scaling_list_16x16: [[u8; 64]; 6],
1293 pub scaling_list_32x32: [[u8; 64]; 6],
1295}
1296
1297impl Default for ScalingLists {
1298 fn default() -> Self {
1299 Self {
1300 scaling_list_dc_coef_minus8_16x16: Default::default(),
1301 scaling_list_dc_coef_minus8_32x32: Default::default(),
1302 scaling_list_4x4: Default::default(),
1303 scaling_list_8x8: [[0; 64]; 6],
1304 scaling_list_16x16: [[0; 64]; 6],
1305 scaling_list_32x32: [[0; 64]; 6],
1306 }
1307 }
1308}
1309
1310#[derive(Clone, Debug, Default, PartialEq, Eq)]
1311pub struct RefPicListModification {
1312 pub ref_pic_list_modification_flag_l0: bool,
1316 pub list_entry_l0: Vec<u32>,
1320 pub ref_pic_list_modification_flag_l1: bool,
1324 pub list_entry_l1: Vec<u32>,
1328}
1329
1330#[derive(Clone, Debug, Default, PartialEq, Eq)]
1331pub struct PredWeightTable {
1332 pub luma_log2_weight_denom: u8,
1334 pub delta_chroma_log2_weight_denom: i8,
1337 pub luma_weight_l0_flag: [bool; 15],
1342 pub chroma_weight_l0_flag: [bool; 15],
1347 pub delta_luma_weight_l0: [i8; 15],
1351 pub luma_offset_l0: [i8; 15],
1354 pub delta_chroma_weight_l0: [[i8; 2]; 15],
1358 pub delta_chroma_offset_l0: [[i16; 2]; 15],
1362
1363 pub luma_weight_l1_flag: [bool; 15],
1371 pub chroma_weight_l1_flag: [bool; 15],
1372 pub delta_luma_weight_l1: [i8; 15],
1373 pub luma_offset_l1: [i8; 15],
1374
1375 pub delta_chroma_weight_l1: [[i8; 2]; 15],
1376 pub delta_chroma_offset_l1: [[i16; 2]; 15],
1377
1378 pub chroma_log2_weight_denom: u8,
1381}
1382
1383#[derive(Clone, Debug, PartialEq, Eq)]
1384pub struct ShortTermRefPicSet {
1385 pub inter_ref_pic_set_prediction_flag: bool,
1389 pub delta_idx_minus1: u8,
1393 pub delta_rps_sign: bool,
1396 pub abs_delta_rps_minus1: u16,
1399 pub num_negative_pics: u8,
1403 pub num_positive_pics: u8,
1407 pub used_by_curr_pic_s0: [bool; MAX_SHORT_TERM_REF_PIC_SETS],
1409 pub used_by_curr_pic_s1: [bool; MAX_SHORT_TERM_REF_PIC_SETS],
1411 pub delta_poc_s0: [i32; MAX_SHORT_TERM_REF_PIC_SETS],
1413 pub delta_poc_s1: [i32; MAX_SHORT_TERM_REF_PIC_SETS],
1415 pub num_delta_pocs: u32,
1417}
1418
1419impl Default for ShortTermRefPicSet {
1420 fn default() -> Self {
1421 Self {
1422 inter_ref_pic_set_prediction_flag: Default::default(),
1423 delta_idx_minus1: Default::default(),
1424 delta_rps_sign: Default::default(),
1425 abs_delta_rps_minus1: Default::default(),
1426 num_negative_pics: Default::default(),
1427 num_positive_pics: Default::default(),
1428 used_by_curr_pic_s0: [false; MAX_SHORT_TERM_REF_PIC_SETS],
1429 used_by_curr_pic_s1: [false; MAX_SHORT_TERM_REF_PIC_SETS],
1430 delta_poc_s0: [0; MAX_SHORT_TERM_REF_PIC_SETS],
1431 delta_poc_s1: [0; MAX_SHORT_TERM_REF_PIC_SETS],
1432 num_delta_pocs: Default::default(),
1433 }
1434 }
1435}
1436
1437#[derive(N, Clone, Copy, Debug, PartialEq, Eq)]
1438pub enum SliceType {
1440 B = 0,
1441 P = 1,
1442 I = 2,
1443}
1444
1445impl SliceType {
1446 pub fn is_p(&self) -> bool {
1448 matches!(self, SliceType::P)
1449 }
1450
1451 pub fn is_b(&self) -> bool {
1453 matches!(self, SliceType::B)
1454 }
1455
1456 pub fn is_i(&self) -> bool {
1458 matches!(self, SliceType::I)
1459 }
1460}
1461
1462impl Default for SliceType {
1463 fn default() -> Self {
1464 Self::P
1465 }
1466}
1467
1468#[derive(Clone, Debug, PartialEq, Eq)]
1469pub struct SliceHeader {
1470 pub first_slice_segment_in_pic_flag: bool,
1474 pub no_output_of_prior_pics_flag: bool,
1478 pub pic_parameter_set_id: u8,
1480 pub dependent_slice_segment_flag: bool,
1484 pub segment_address: u32,
1487 pub type_: SliceType,
1489 pub pic_output_flag: bool,
1492 pub colour_plane_id: u8,
1497 pub pic_order_cnt_lsb: u16,
1501 pub short_term_ref_pic_set_sps_flag: bool,
1509 pub short_term_ref_pic_set: ShortTermRefPicSet,
1511 pub short_term_ref_pic_set_idx: u8,
1516 pub num_long_term_sps: u8,
1520 pub num_long_term_pics: u8,
1523 pub lt_idx_sps: [u8; 16],
1527 pub poc_lsb_lt: [u32; 16],
1529 pub used_by_curr_pic_lt: [bool; 16],
1531 pub delta_poc_msb_present_flag: [bool; 16],
1533 pub delta_poc_msb_cycle_lt: [u32; 16],
1535 pub temporal_mvp_enabled_flag: bool,
1542 pub sao_luma_flag: bool,
1546 pub sao_chroma_flag: bool,
1550 pub num_ref_idx_active_override_flag: bool,
1556 pub num_ref_idx_l0_active_minus1: u8,
1559 pub num_ref_idx_l1_active_minus1: u8,
1562 pub ref_pic_list_modification: RefPicListModification,
1564 pub mvd_l1_zero_flag: bool,
1569 pub cabac_init_flag: bool,
1572 pub collocated_from_l0_flag: bool,
1577 pub collocated_ref_idx: u8,
1580 pub pred_weight_table: PredWeightTable,
1582 pub five_minus_max_num_merge_cand: u8,
1585 pub use_integer_mv_flag: bool,
1591 pub qp_delta: i8,
1595 pub cb_qp_offset: i8,
1598 pub cr_qp_offset: i8,
1601 pub slice_act_y_qp_offset: i8,
1604 pub slice_act_cb_qp_offset: i8,
1607 pub slice_act_cr_qp_offset: i8,
1610 pub cu_chroma_qp_offset_enabled_flag: bool,
1614 pub deblocking_filter_override_flag: bool,
1618 pub deblocking_filter_disabled_flag: bool,
1622 pub beta_offset_div2: i8,
1625 pub tc_offset_div2: i8,
1628 pub loop_filter_across_slices_enabled_flag: bool,
1634 pub num_entry_point_offsets: u32,
1637 pub offset_len_minus1: u8,
1640 pub entry_point_offset_minus1: [u32; 32],
1647 pub num_pic_total_curr: u32,
1649 pub header_bit_size: u32,
1651 pub n_emulation_prevention_bytes: u32,
1653 pub curr_rps_idx: u8,
1655 pub st_rps_bits: u32,
1657}
1658
1659impl Default for SliceHeader {
1660 fn default() -> Self {
1661 Self {
1662 first_slice_segment_in_pic_flag: Default::default(),
1663 no_output_of_prior_pics_flag: Default::default(),
1664 pic_parameter_set_id: Default::default(),
1665 dependent_slice_segment_flag: Default::default(),
1666 segment_address: Default::default(),
1667 type_: Default::default(),
1668 pic_output_flag: true,
1669 colour_plane_id: Default::default(),
1670 pic_order_cnt_lsb: Default::default(),
1671 short_term_ref_pic_set_sps_flag: Default::default(),
1672 short_term_ref_pic_set: Default::default(),
1673 short_term_ref_pic_set_idx: Default::default(),
1674 num_long_term_sps: Default::default(),
1675 num_long_term_pics: Default::default(),
1676 lt_idx_sps: Default::default(),
1677 poc_lsb_lt: Default::default(),
1678 used_by_curr_pic_lt: Default::default(),
1679 delta_poc_msb_present_flag: Default::default(),
1680 delta_poc_msb_cycle_lt: Default::default(),
1681 temporal_mvp_enabled_flag: Default::default(),
1682 sao_luma_flag: Default::default(),
1683 sao_chroma_flag: Default::default(),
1684 num_ref_idx_active_override_flag: Default::default(),
1685 num_ref_idx_l0_active_minus1: Default::default(),
1686 num_ref_idx_l1_active_minus1: Default::default(),
1687 ref_pic_list_modification: Default::default(),
1688 mvd_l1_zero_flag: Default::default(),
1689 cabac_init_flag: Default::default(),
1690 collocated_from_l0_flag: true,
1691 collocated_ref_idx: Default::default(),
1692 pred_weight_table: Default::default(),
1693 five_minus_max_num_merge_cand: Default::default(),
1694 use_integer_mv_flag: Default::default(),
1695 qp_delta: Default::default(),
1696 cb_qp_offset: Default::default(),
1697 cr_qp_offset: Default::default(),
1698 slice_act_y_qp_offset: Default::default(),
1699 slice_act_cb_qp_offset: Default::default(),
1700 slice_act_cr_qp_offset: Default::default(),
1701 cu_chroma_qp_offset_enabled_flag: Default::default(),
1702 deblocking_filter_override_flag: Default::default(),
1703 deblocking_filter_disabled_flag: Default::default(),
1704 beta_offset_div2: Default::default(),
1705 tc_offset_div2: Default::default(),
1706 loop_filter_across_slices_enabled_flag: Default::default(),
1707 num_entry_point_offsets: Default::default(),
1708 offset_len_minus1: Default::default(),
1709 entry_point_offset_minus1: Default::default(),
1710 num_pic_total_curr: Default::default(),
1711 header_bit_size: Default::default(),
1712 n_emulation_prevention_bytes: Default::default(),
1713 curr_rps_idx: Default::default(),
1714 st_rps_bits: Default::default(),
1715 }
1716 }
1717}
1718
1719pub struct Slice<'a> {
1722 pub header: SliceHeader,
1724 pub nalu: Nalu<'a>,
1726}
1727
1728impl<'a> Slice<'a> {
1729 pub fn replace_header(&mut self, header: SliceHeader) -> anyhow::Result<()> {
1732 if !self.header.dependent_slice_segment_flag {
1733 Err(anyhow!(
1734 "Replacing the slice header is only possible for dependent slices"
1735 ))
1736 } else {
1737 let first_slice_segment_in_pic_flag = self.header.first_slice_segment_in_pic_flag;
1738 let no_output_of_prior_pics_flag = self.header.no_output_of_prior_pics_flag;
1739 let pic_parameter_set_id = self.header.pic_parameter_set_id;
1740 let dependent_slice_segment_flag = self.header.dependent_slice_segment_flag;
1741 let segment_address = self.header.segment_address;
1742
1743 let offset_len_minus1 = self.header.offset_len_minus1;
1744 let entry_point_offset_minus1 = self.header.entry_point_offset_minus1;
1745 let num_pic_total_curr = self.header.num_pic_total_curr;
1746 let header_bit_size = self.header.header_bit_size;
1747 let n_emulation_prevention_bytes = self.header.n_emulation_prevention_bytes;
1748 let curr_rps_idx = self.header.curr_rps_idx;
1749 let st_rps_bits = self.header.st_rps_bits;
1750
1751 self.header = header;
1752
1753 self.header.first_slice_segment_in_pic_flag = first_slice_segment_in_pic_flag;
1754 self.header.no_output_of_prior_pics_flag = no_output_of_prior_pics_flag;
1755 self.header.pic_parameter_set_id = pic_parameter_set_id;
1756 self.header.dependent_slice_segment_flag = dependent_slice_segment_flag;
1757 self.header.segment_address = segment_address;
1758 self.header.offset_len_minus1 = offset_len_minus1;
1759 self.header.entry_point_offset_minus1 = entry_point_offset_minus1;
1760 self.header.num_pic_total_curr = num_pic_total_curr;
1761 self.header.header_bit_size = header_bit_size;
1762 self.header.n_emulation_prevention_bytes = n_emulation_prevention_bytes;
1763 self.header.curr_rps_idx = curr_rps_idx;
1764 self.header.st_rps_bits = st_rps_bits;
1765
1766 Ok(())
1767 }
1768 }
1769}
1770
1771#[derive(Clone, Debug, Default, PartialEq, Eq)]
1772pub struct SublayerHrdParameters {
1773 pub bit_rate_value_minus1: [u32; 32],
1779 pub cpb_size_value_minus1: [u32; 32],
1783 pub cpb_size_du_value_minus1: [u32; 32],
1786 pub bit_rate_du_value_minus1: [u32; 32],
1790 pub cbr_flag: [bool; 32],
1793}
1794
1795#[derive(Clone, Debug, PartialEq, Eq)]
1796pub struct HrdParams {
1797 pub nal_hrd_parameters_present_flag: bool,
1802 pub vcl_hrd_parameters_present_flag: bool,
1807 pub sub_pic_hrd_params_present_flag: bool,
1812 pub tick_divisor_minus2: u8,
1816 pub du_cpb_removal_delay_increment_length_minus1: u8,
1822 pub sub_pic_cpb_params_in_pic_timing_sei_flag: bool,
1830 pub dpb_output_delay_du_length_minus1: u8,
1835 pub bit_rate_scale: u8,
1838 pub cpb_size_scale: u8,
1841 pub cpb_size_du_scale: u8,
1844 pub initial_cpb_removal_delay_length_minus1: u8,
1850 pub au_cpb_removal_delay_length_minus1: u8,
1855 pub dpb_output_delay_length_minus1: u8,
1860 pub fixed_pic_rate_general_flag: [bool; 7],
1866 pub fixed_pic_rate_within_cvs_flag: [bool; 7],
1872 pub elemental_duration_in_tc_minus1: [u32; 7],
1877 pub low_delay_hrd_flag: [bool; 7],
1880 pub cpb_cnt_minus1: [u32; 7],
1884 pub nal_hrd: [SublayerHrdParameters; 7],
1886 pub vcl_hrd: [SublayerHrdParameters; 7],
1888}
1889
1890impl Default for HrdParams {
1891 fn default() -> Self {
1892 Self {
1893 initial_cpb_removal_delay_length_minus1: 23,
1894 au_cpb_removal_delay_length_minus1: 23,
1895 dpb_output_delay_du_length_minus1: 23,
1896 nal_hrd_parameters_present_flag: Default::default(),
1897 vcl_hrd_parameters_present_flag: Default::default(),
1898 sub_pic_hrd_params_present_flag: Default::default(),
1899 tick_divisor_minus2: Default::default(),
1900 du_cpb_removal_delay_increment_length_minus1: Default::default(),
1901 sub_pic_cpb_params_in_pic_timing_sei_flag: Default::default(),
1902 bit_rate_scale: Default::default(),
1903 cpb_size_scale: Default::default(),
1904 cpb_size_du_scale: Default::default(),
1905 dpb_output_delay_length_minus1: Default::default(),
1906 fixed_pic_rate_general_flag: Default::default(),
1907 fixed_pic_rate_within_cvs_flag: Default::default(),
1908 elemental_duration_in_tc_minus1: Default::default(),
1909 low_delay_hrd_flag: Default::default(),
1910 cpb_cnt_minus1: Default::default(),
1911 nal_hrd: Default::default(),
1912 vcl_hrd: Default::default(),
1913 }
1914 }
1915}
1916
1917#[derive(Clone, Debug, PartialEq, Eq)]
1918pub struct VuiParams {
1919 pub aspect_ratio_info_present_flag: bool,
1922 pub aspect_ratio_idc: u32,
1924 pub sar_width: u32,
1927 pub sar_height: u32,
1930 pub overscan_info_present_flag: bool,
1934 pub overscan_appropriate_flag: bool,
1941 pub video_signal_type_present_flag: bool,
1946 pub video_format: u8,
1949 pub video_full_range_flag: bool,
1953 pub colour_description_present_flag: bool,
1958 pub colour_primaries: u32,
1962 pub transfer_characteristics: u32,
1964 pub matrix_coeffs: u32,
1968 pub chroma_loc_info_present_flag: bool,
1973 pub chroma_sample_loc_type_top_field: u32,
1975 pub chroma_sample_loc_type_bottom_field: u32,
1977 pub neutral_chroma_indication_flag: bool,
1981 pub field_seq_flag: bool,
1987 pub frame_field_info_present_flag: bool,
1992 pub default_display_window_flag: bool,
1996 pub def_disp_win_left_offset: u32,
2000 pub def_disp_win_right_offset: u32,
2004 pub def_disp_win_top_offset: u32,
2008 pub def_disp_win_bottom_offset: u32,
2012 pub timing_info_present_flag: bool,
2019 pub num_units_in_tick: u32,
2023 pub time_scale: u32,
2027 pub poc_proportional_to_timing_flag: bool,
2036 pub num_ticks_poc_diff_one_minus1: u32,
2040 pub hrd_parameters_present_flag: bool,
2045 pub hrd: HrdParams,
2047 pub bitstream_restriction_flag: bool,
2051 pub tiles_fixed_structure_flag: bool,
2058 pub motion_vectors_over_pic_boundaries_flag: bool,
2065 pub restricted_ref_pic_lists_flag: bool,
2070 pub min_spatial_segmentation_idc: u32,
2073 pub max_bytes_per_pic_denom: u32,
2076 pub max_bits_per_min_cu_denom: u32,
2079 pub log2_max_mv_length_horizontal: u32,
2083 pub log2_max_mv_length_vertical: u32,
2087}
2088
2089impl Default for VuiParams {
2090 fn default() -> Self {
2091 Self {
2092 aspect_ratio_info_present_flag: Default::default(),
2093 aspect_ratio_idc: Default::default(),
2094 sar_width: Default::default(),
2095 sar_height: Default::default(),
2096 overscan_info_present_flag: Default::default(),
2097 overscan_appropriate_flag: Default::default(),
2098 video_signal_type_present_flag: Default::default(),
2099 video_format: 5,
2100 video_full_range_flag: Default::default(),
2101 colour_description_present_flag: Default::default(),
2102 colour_primaries: 2,
2103 transfer_characteristics: 2,
2104 matrix_coeffs: 2,
2105 chroma_loc_info_present_flag: Default::default(),
2106 chroma_sample_loc_type_top_field: Default::default(),
2107 chroma_sample_loc_type_bottom_field: Default::default(),
2108 neutral_chroma_indication_flag: Default::default(),
2109 field_seq_flag: Default::default(),
2110 frame_field_info_present_flag: Default::default(),
2111 default_display_window_flag: Default::default(),
2112 def_disp_win_left_offset: Default::default(),
2113 def_disp_win_right_offset: Default::default(),
2114 def_disp_win_top_offset: Default::default(),
2115 def_disp_win_bottom_offset: Default::default(),
2116 timing_info_present_flag: Default::default(),
2117 num_units_in_tick: Default::default(),
2118 time_scale: Default::default(),
2119 poc_proportional_to_timing_flag: Default::default(),
2120 num_ticks_poc_diff_one_minus1: Default::default(),
2121 hrd_parameters_present_flag: Default::default(),
2122 hrd: Default::default(),
2123 bitstream_restriction_flag: Default::default(),
2124 tiles_fixed_structure_flag: Default::default(),
2125 motion_vectors_over_pic_boundaries_flag: true,
2126 restricted_ref_pic_lists_flag: Default::default(),
2127 min_spatial_segmentation_idc: Default::default(),
2128 max_bytes_per_pic_denom: 2,
2129 max_bits_per_min_cu_denom: 1,
2130 log2_max_mv_length_horizontal: 15,
2131 log2_max_mv_length_vertical: 15,
2132 }
2133 }
2134}
2135
2136#[derive(Clone, Debug, Default)]
2137pub struct Parser {
2138 active_vpses: BTreeMap<u8, Vps>,
2139 active_spses: BTreeMap<u8, Sps>,
2140 active_ppses: BTreeMap<u8, Pps>,
2141}
2142
2143impl Parser {
2144 pub fn parse_vps(&mut self, nalu: &Nalu) -> anyhow::Result<&Vps> {
2146 if !matches!(nalu.header.type_, NaluType::VpsNut) {
2147 return Err(anyhow!(
2148 "Invalid NALU type, expected {:?}, got {:?}",
2149 NaluType::VpsNut,
2150 nalu.header.type_
2151 ));
2152 }
2153
2154 let data = nalu.as_ref();
2155 let header = &nalu.header;
2156 let hdr_len = header.len();
2157 let mut r = NaluReader::new(&data[hdr_len..]);
2159
2160 let mut vps = Vps {
2161 video_parameter_set_id: r.read_bits(4)?,
2162 base_layer_internal_flag: r.read_bit()?,
2163 base_layer_available_flag: r.read_bit()?,
2164 max_layers_minus1: r.read_bits(6)?,
2165 max_sub_layers_minus1: r.read_bits(3)?,
2166 temporal_id_nesting_flag: r.read_bit()?,
2167 ..Default::default()
2168 };
2169
2170 r.skip_bits(16)?; let ptl = &mut vps.profile_tier_level;
2173 Self::parse_profile_tier_level(ptl, &mut r, true, vps.max_sub_layers_minus1)?;
2174
2175 vps.sub_layer_ordering_info_present_flag = r.read_bit()?;
2176
2177 let start = if vps.sub_layer_ordering_info_present_flag {
2178 0
2179 } else {
2180 vps.max_sub_layers_minus1
2181 } as usize;
2182
2183 for i in start..=usize::from(vps.max_sub_layers_minus1) {
2184 vps.max_dec_pic_buffering_minus1[i] = r.read_ue_max(15)?;
2185 vps.max_num_reorder_pics[i] = r.read_ue_max(vps.max_dec_pic_buffering_minus1[i])?;
2186 vps.max_latency_increase_plus1[i] = r.read_ue()?;
2187
2188 if i > 0 {
2189 if vps.max_dec_pic_buffering_minus1[i] < vps.max_dec_pic_buffering_minus1[i - 1] {
2190 return Err(anyhow!(
2191 "Invalid max_dec_pic_buffering_minus1[{}]: {}",
2192 i,
2193 vps.max_dec_pic_buffering_minus1[i]
2194 ));
2195 }
2196
2197 if vps.max_num_reorder_pics[i] < vps.max_num_reorder_pics[i - 1] {
2198 return Err(anyhow!(
2199 "Invalid max_num_reorder_pics[{}]: {}",
2200 i,
2201 vps.max_num_reorder_pics[i]
2202 ));
2203 }
2204 }
2205 }
2206
2207 if !vps.sub_layer_ordering_info_present_flag {
2213 let max_num_sublayers = usize::from(vps.max_sub_layers_minus1);
2214 for i in 0..max_num_sublayers {
2215 vps.max_dec_pic_buffering_minus1[i] =
2216 vps.max_dec_pic_buffering_minus1[max_num_sublayers];
2217
2218 vps.max_num_reorder_pics[i] = vps.max_num_reorder_pics[max_num_sublayers];
2219
2220 vps.max_latency_increase_plus1[i] =
2221 vps.max_latency_increase_plus1[max_num_sublayers];
2222 }
2223 }
2224
2225 vps.max_layer_id = r.read_bits(6)?;
2226 if vps.max_layer_id > 62 {
2227 return Err(anyhow!("Invalid max_layer_id {}", vps.max_layer_id));
2228 }
2229
2230 vps.num_layer_sets_minus1 = r.read_ue_max(1023)?;
2231
2232 for _ in 1..=vps.num_layer_sets_minus1 {
2233 for _ in 0..=vps.max_layer_id {
2234 r.skip_bits(1)?;
2236 }
2237 }
2238
2239 vps.timing_info_present_flag = r.read_bit()?;
2240
2241 if vps.timing_info_present_flag {
2242 vps.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
2243 vps.num_units_in_tick |= r.read_bits::<u32>(1)?;
2244
2245 vps.time_scale = r.read_bits::<u32>(31)? << 1;
2246 vps.time_scale |= r.read_bits::<u32>(1)?;
2247
2248 vps.poc_proportional_to_timing_flag = r.read_bit()?;
2249 if vps.poc_proportional_to_timing_flag {
2250 vps.num_ticks_poc_diff_one_minus1 = r.read_ue()?;
2251 }
2252
2253 vps.num_hrd_parameters = r.read_ue()?;
2254
2255 for i in 0..vps.num_hrd_parameters as usize {
2256 vps.hrd_layer_set_idx.push(r.read_ue()?);
2257 if i > 0 {
2258 vps.cprms_present_flag.push(r.read_bit()?);
2259 }
2260
2261 let mut hrd = HrdParams::default();
2262 Self::parse_hrd_parameters(
2263 vps.cprms_present_flag[i],
2264 vps.max_sub_layers_minus1,
2265 &mut hrd,
2266 &mut r,
2267 )?;
2268
2269 vps.hrd_parameters.push(hrd);
2270 }
2271 }
2272
2273 vps.extension_flag = r.read_bit()?;
2274
2275 let key = vps.video_parameter_set_id;
2276 self.active_vpses.insert(key, vps);
2277
2278 if self.active_spses.keys().len() > MAX_VPS_COUNT {
2279 return Err(anyhow!(
2280 "Broken data: Number of active SPSs > MAX_SPS_COUNT"
2281 ));
2282 }
2283
2284 Ok(self.get_vps(key).unwrap())
2285 }
2286
2287 fn parse_profile_tier_level(
2288 ptl: &mut ProfileTierLevel,
2289 r: &mut NaluReader,
2290 profile_present_flag: bool,
2291 sps_max_sub_layers_minus_1: u8,
2292 ) -> anyhow::Result<()> {
2293 if profile_present_flag {
2294 ptl.general_profile_space = r.read_bits(2)?;
2295 ptl.general_tier_flag = r.read_bit()?;
2296 ptl.general_profile_idc = r.read_bits(5)?;
2297
2298 for i in 0..32 {
2299 ptl.general_profile_compatibility_flag[i] = r.read_bit()?;
2300 }
2301
2302 ptl.general_progressive_source_flag = r.read_bit()?;
2303 ptl.general_interlaced_source_flag = r.read_bit()?;
2304 ptl.general_non_packed_constraint_flag = r.read_bit()?;
2305 ptl.general_frame_only_constraint_flag = r.read_bit()?;
2306
2307 if ptl.general_profile_idc == 4
2308 || ptl.general_profile_compatibility_flag[4]
2309 || ptl.general_profile_idc == 5
2310 || ptl.general_profile_compatibility_flag[5]
2311 || ptl.general_profile_idc == 6
2312 || ptl.general_profile_compatibility_flag[6]
2313 || ptl.general_profile_idc == 7
2314 || ptl.general_profile_compatibility_flag[7]
2315 || ptl.general_profile_idc == 8
2316 || ptl.general_profile_compatibility_flag[8]
2317 || ptl.general_profile_idc == 9
2318 || ptl.general_profile_compatibility_flag[9]
2319 || ptl.general_profile_idc == 10
2320 || ptl.general_profile_compatibility_flag[10]
2321 || ptl.general_profile_idc == 11
2322 || ptl.general_profile_compatibility_flag[11]
2323 {
2324 ptl.general_max_12bit_constraint_flag = r.read_bit()?;
2325 ptl.general_max_10bit_constraint_flag = r.read_bit()?;
2326 ptl.general_max_8bit_constraint_flag = r.read_bit()?;
2327 ptl.general_max_422chroma_constraint_flag = r.read_bit()?;
2328 ptl.general_max_420chroma_constraint_flag = r.read_bit()?;
2329 ptl.general_max_monochrome_constraint_flag = r.read_bit()?;
2330 ptl.general_intra_constraint_flag = r.read_bit()?;
2331 ptl.general_one_picture_only_constraint_flag = r.read_bit()?;
2332 ptl.general_lower_bit_rate_constraint_flag = r.read_bit()?;
2333 if ptl.general_profile_idc == 5
2334 || ptl.general_profile_compatibility_flag[5]
2335 || ptl.general_profile_idc == 9
2336 || ptl.general_profile_compatibility_flag[9]
2337 || ptl.general_profile_idc == 10
2338 || ptl.general_profile_compatibility_flag[10]
2339 || ptl.general_profile_idc == 11
2340 || ptl.general_profile_compatibility_flag[11]
2341 {
2342 ptl.general_max_14bit_constraint_flag = r.read_bit()?;
2343 r.skip_bits(31)?;
2345 r.skip_bits(2)?;
2346 } else {
2347 r.skip_bits(31)?;
2349 r.skip_bits(3)?;
2350 }
2351 } else if ptl.general_profile_idc == 2 || ptl.general_profile_compatibility_flag[2] {
2352 r.skip_bits(7)?;
2354 ptl.general_one_picture_only_constraint_flag = r.read_bit()?;
2355 r.skip_bits(31)?;
2357 r.skip_bits(4)?;
2358 } else {
2359 r.skip_bits(31)?;
2360 r.skip_bits(12)?;
2361 }
2362
2363 if ptl.general_profile_idc == 1
2364 || ptl.general_profile_compatibility_flag[1]
2365 || ptl.general_profile_idc == 2
2366 || ptl.general_profile_compatibility_flag[2]
2367 || ptl.general_profile_idc == 3
2368 || ptl.general_profile_compatibility_flag[3]
2369 || ptl.general_profile_idc == 4
2370 || ptl.general_profile_compatibility_flag[4]
2371 || ptl.general_profile_idc == 5
2372 || ptl.general_profile_compatibility_flag[5]
2373 || ptl.general_profile_idc == 9
2374 || ptl.general_profile_compatibility_flag[9]
2375 || ptl.general_profile_idc == 11
2376 || ptl.general_profile_compatibility_flag[11]
2377 {
2378 ptl.general_inbld_flag = r.read_bit()?;
2379 } else {
2380 r.skip_bits(1)?;
2381 }
2382 }
2383
2384 let level: u8 = r.read_bits(8)?;
2385 ptl.general_level_idc =
2386 Level::n(level).with_context(|| format!("Unsupported level {}", level))?;
2387
2388 for i in 0..sps_max_sub_layers_minus_1 as usize {
2389 ptl.sub_layer_profile_present_flag[i] = r.read_bit()?;
2390 ptl.sub_layer_level_present_flag[i] = r.read_bit()?;
2391 }
2392
2393 if sps_max_sub_layers_minus_1 > 0 {
2394 for _ in sps_max_sub_layers_minus_1..8 {
2395 r.skip_bits(2)?;
2396 }
2397 }
2398
2399 for i in 0..sps_max_sub_layers_minus_1 as usize {
2400 if ptl.sub_layer_level_present_flag[i] {
2401 ptl.sub_layer_profile_space[i] = r.read_bits(2)?;
2402 ptl.sub_layer_tier_flag[i] = r.read_bit()?;
2403 ptl.sub_layer_profile_idc[i] = r.read_bits(5)?;
2404 for j in 0..32 {
2405 ptl.sub_layer_profile_compatibility_flag[i][j] = r.read_bit()?;
2406 }
2407 ptl.sub_layer_progressive_source_flag[i] = r.read_bit()?;
2408 ptl.sub_layer_interlaced_source_flag[i] = r.read_bit()?;
2409 ptl.sub_layer_non_packed_constraint_flag[i] = r.read_bit()?;
2410 ptl.sub_layer_frame_only_constraint_flag[i] = r.read_bit()?;
2411
2412 if ptl.sub_layer_profile_idc[i] == 4
2413 || ptl.sub_layer_profile_compatibility_flag[i][4]
2414 || ptl.sub_layer_profile_idc[i] == 5
2415 || ptl.sub_layer_profile_compatibility_flag[i][5]
2416 || ptl.sub_layer_profile_idc[i] == 6
2417 || ptl.sub_layer_profile_compatibility_flag[i][6]
2418 || ptl.sub_layer_profile_idc[i] == 7
2419 || ptl.sub_layer_profile_compatibility_flag[i][7]
2420 || ptl.sub_layer_profile_idc[i] == 8
2421 || ptl.sub_layer_profile_compatibility_flag[i][8]
2422 || ptl.sub_layer_profile_idc[i] == 9
2423 || ptl.sub_layer_profile_compatibility_flag[i][9]
2424 || ptl.sub_layer_profile_idc[i] == 10
2425 || ptl.sub_layer_profile_compatibility_flag[i][10]
2426 || ptl.sub_layer_profile_idc[i] == 11
2427 || ptl.sub_layer_profile_compatibility_flag[i][11]
2428 {
2429 ptl.sub_layer_max_12bit_constraint_flag[i] = r.read_bit()?;
2430 ptl.sub_layer_max_10bit_constraint_flag[i] = r.read_bit()?;
2431 ptl.sub_layer_max_8bit_constraint_flag[i] = r.read_bit()?;
2432 ptl.sub_layer_max_422chroma_constraint_flag[i] = r.read_bit()?;
2433 ptl.sub_layer_max_420chroma_constraint_flag[i] = r.read_bit()?;
2434 ptl.sub_layer_max_monochrome_constraint_flag[i] = r.read_bit()?;
2435 ptl.sub_layer_intra_constraint_flag[i] = r.read_bit()?;
2436 ptl.sub_layer_one_picture_only_constraint_flag[i] = r.read_bit()?;
2437 ptl.sub_layer_lower_bit_rate_constraint_flag[i] = r.read_bit()?;
2438
2439 if ptl.sub_layer_profile_idc[i] == 5
2440 || ptl.sub_layer_profile_compatibility_flag[i][5]
2441 || ptl.sub_layer_profile_idc[i] == 9
2442 || ptl.sub_layer_profile_compatibility_flag[i][9]
2443 || ptl.sub_layer_profile_idc[i] == 10
2444 || ptl.sub_layer_profile_compatibility_flag[i][10]
2445 || ptl.sub_layer_profile_idc[i] == 11
2446 || ptl.sub_layer_profile_compatibility_flag[i][11]
2447 {
2448 ptl.sub_layer_max_14bit_constraint_flag[i] = r.read_bit()?;
2449 r.skip_bits(33)?;
2450 } else {
2451 r.skip_bits(34)?;
2452 }
2453 } else if ptl.sub_layer_profile_idc[i] == 2
2454 || ptl.sub_layer_profile_compatibility_flag[i][2]
2455 {
2456 r.skip_bits(7)?;
2457 ptl.sub_layer_one_picture_only_constraint_flag[i] = r.read_bit()?;
2458 r.skip_bits(35)?;
2459 } else {
2460 r.skip_bits(43)?;
2461 }
2462
2463 if ptl.sub_layer_profile_idc[i] == 1
2464 || ptl.sub_layer_profile_compatibility_flag[i][1]
2465 || ptl.sub_layer_profile_idc[i] == 2
2466 || ptl.sub_layer_profile_compatibility_flag[i][2]
2467 || ptl.sub_layer_profile_idc[i] == 3
2468 || ptl.sub_layer_profile_compatibility_flag[i][3]
2469 || ptl.sub_layer_profile_idc[i] == 4
2470 || ptl.sub_layer_profile_compatibility_flag[i][4]
2471 || ptl.sub_layer_profile_idc[i] == 5
2472 || ptl.sub_layer_profile_compatibility_flag[i][5]
2473 || ptl.sub_layer_profile_idc[i] == 9
2474 || ptl.sub_layer_profile_compatibility_flag[i][9]
2475 || ptl.sub_layer_profile_idc[i] == 11
2476 || ptl.sub_layer_profile_compatibility_flag[i][11]
2477 {
2478 ptl.sub_layer_inbld_flag[i] = r.read_bit()?;
2479 } else {
2480 r.skip_bits(1)?;
2481 }
2482
2483 if ptl.sub_layer_level_present_flag[i] {
2484 let level: u8 = r.read_bits(8)?;
2485 ptl.sub_layer_level_idc[i] =
2486 Level::n(level).with_context(|| format!("Unsupported level {}", level))?;
2487 }
2488 }
2489 }
2490 Ok(())
2491 }
2492
2493 fn fill_default_scaling_list(sl: &mut ScalingLists, size_id: i32, matrix_id: i32) {
2494 if size_id == 0 {
2495 sl.scaling_list_4x4[matrix_id as usize] = DEFAULT_SCALING_LIST_0;
2496 return;
2497 }
2498
2499 let dst = match size_id {
2500 1 => &mut sl.scaling_list_8x8[matrix_id as usize],
2501 2 => &mut sl.scaling_list_16x16[matrix_id as usize],
2502 3 => &mut sl.scaling_list_32x32[matrix_id as usize],
2503 _ => panic!("Invalid size_id {}", size_id),
2504 };
2505
2506 let src = if matrix_id < 3 {
2507 &DEFAULT_SCALING_LIST_1
2508 } else if matrix_id <= 5 {
2509 &DEFAULT_SCALING_LIST_2
2510 } else {
2511 panic!("Invalid matrix_id {}", matrix_id);
2512 };
2513
2514 *dst = *src;
2515
2516 if size_id == 2 {
2526 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] = 8;
2527 } else if size_id == 3 {
2528 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] = 8;
2529 }
2530 }
2531
2532 fn parse_scaling_list_data(sl: &mut ScalingLists, r: &mut NaluReader) -> anyhow::Result<()> {
2533 for size_id in 0..4 {
2535 let mut matrix_id = 0;
2536 while matrix_id < 6 {
2537 let scaling_list_pred_mode_flag = r.read_bit()?;
2538 if !scaling_list_pred_mode_flag {
2544 let scaling_list_pred_matrix_id_delta: u32 = r.read_ue()?;
2545 if scaling_list_pred_matrix_id_delta == 0 {
2546 Self::fill_default_scaling_list(sl, size_id, matrix_id);
2547 } else {
2548 let factor = if size_id == 3 { 3 } else { 1 };
2550 let ref_matrix_id =
2551 matrix_id as u32 - scaling_list_pred_matrix_id_delta * factor;
2552 if size_id == 0 {
2553 sl.scaling_list_4x4[matrix_id as usize] =
2554 sl.scaling_list_4x4[ref_matrix_id as usize];
2555 } else {
2556 let src = match size_id {
2557 1 => sl.scaling_list_8x8[ref_matrix_id as usize],
2558 2 => sl.scaling_list_16x16[ref_matrix_id as usize],
2559 3 => sl.scaling_list_32x32[ref_matrix_id as usize],
2560 _ => return Err(anyhow!("Invalid size_id {}", size_id)),
2561 };
2562
2563 let dst = match size_id {
2564 1 => &mut sl.scaling_list_8x8[matrix_id as usize],
2565 2 => &mut sl.scaling_list_16x16[matrix_id as usize],
2566 3 => &mut sl.scaling_list_32x32[matrix_id as usize],
2567 _ => return Err(anyhow!("Invalid size_id {}", size_id)),
2568 };
2569
2570 *dst = src;
2571
2572 if size_id == 2 {
2573 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] =
2574 sl.scaling_list_dc_coef_minus8_16x16[ref_matrix_id as usize];
2575 } else if size_id == 3 {
2576 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] =
2577 sl.scaling_list_dc_coef_minus8_32x32[ref_matrix_id as usize];
2578 }
2579 }
2580 }
2581 } else {
2582 let mut next_coef = 8i32;
2583 let coef_num = std::cmp::min(64, 1 << (4 + (size_id << 1)));
2584
2585 if size_id > 1 {
2586 if size_id == 2 {
2587 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] =
2588 r.read_se_bounded(-7, 247)?;
2589 next_coef =
2590 i32::from(sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize])
2591 + 8;
2592 } else if size_id == 3 {
2593 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] =
2594 r.read_se_bounded(-7, 247)?;
2595 next_coef =
2596 i32::from(sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize])
2597 + 8;
2598 }
2599 }
2600
2601 for i in 0..coef_num as usize {
2602 let scaling_list_delta_coef: i32 = r.read_se_bounded(-128, 127)?;
2603 next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
2604 match size_id {
2605 0 => sl.scaling_list_4x4[matrix_id as usize][i] = next_coef as _,
2606 1 => sl.scaling_list_8x8[matrix_id as usize][i] = next_coef as _,
2607 2 => sl.scaling_list_16x16[matrix_id as usize][i] = next_coef as _,
2608 3 => sl.scaling_list_32x32[matrix_id as usize][i] = next_coef as _,
2609 _ => return Err(anyhow!("Invalid size_id {}", size_id)),
2610 }
2611 }
2612 }
2613 let step = if size_id == 3 { 3 } else { 1 };
2614 matrix_id += step;
2615 }
2616 }
2617 Ok(())
2618 }
2619
2620 fn parse_short_term_ref_pic_set(
2621 sps: &Sps,
2622 st: &mut ShortTermRefPicSet,
2623 r: &mut NaluReader,
2624 st_rps_idx: u8,
2625 ) -> anyhow::Result<()> {
2626 if st_rps_idx != 0 {
2627 st.inter_ref_pic_set_prediction_flag = r.read_bit()?;
2628 }
2629
2630 if st.inter_ref_pic_set_prediction_flag {
2632 if st_rps_idx == sps.num_short_term_ref_pic_sets {
2633 st.delta_idx_minus1 = r.read_ue_max(st_rps_idx as u32 - 1)?;
2634 }
2635
2636 st.delta_rps_sign = r.read_bit()?;
2637 st.abs_delta_rps_minus1 = r.read_ue_max(32767)?;
2640
2641 let ref_rps_idx = st_rps_idx - (st.delta_idx_minus1 + 1);
2642 let delta_rps =
2643 (1 - 2 * st.delta_rps_sign as i32) * (st.abs_delta_rps_minus1 as i32 + 1);
2644
2645 let ref_st = sps
2646 .short_term_ref_pic_set
2647 .get(usize::from(ref_rps_idx))
2648 .ok_or(anyhow!("Invalid ref_rps_idx"))?;
2649
2650 let mut used_by_curr_pic_flag = [false; 64];
2651
2652 let mut use_delta_flag = [true; 64];
2654
2655 for j in 0..=ref_st.num_delta_pocs as usize {
2656 used_by_curr_pic_flag[j] = r.read_bit()?;
2657 if !used_by_curr_pic_flag[j] {
2658 use_delta_flag[j] = r.read_bit()?;
2659 }
2660 }
2661
2662 let mut i = 0;
2664 for j in (0..=isize::from(ref_st.num_positive_pics) - 1)
2668 .rev()
2669 .take_while(|j| *j >= 0)
2670 .map(|j| j as usize)
2671 {
2672 let d_poc = ref_st.delta_poc_s1[j] + delta_rps;
2673 if d_poc < 0 && use_delta_flag[usize::from(ref_st.num_negative_pics) + j] {
2674 st.delta_poc_s0[i] = d_poc;
2675 st.used_by_curr_pic_s0[i] =
2676 used_by_curr_pic_flag[usize::from(ref_st.num_negative_pics) + j];
2677
2678 i += 1;
2679 }
2680 }
2681
2682 if delta_rps < 0 && use_delta_flag[ref_st.num_delta_pocs as usize] {
2683 st.delta_poc_s0[i] = delta_rps;
2684 st.used_by_curr_pic_s0[i] = used_by_curr_pic_flag[ref_st.num_delta_pocs as usize];
2685
2686 i += 1;
2687 }
2688
2689 #[allow(clippy::needless_range_loop)]
2691 for j in 0..ref_st.num_negative_pics as usize {
2692 let d_poc = ref_st.delta_poc_s0[j] + delta_rps;
2693 if d_poc < 0 && use_delta_flag[j] {
2694 st.delta_poc_s0[i] = d_poc;
2695 st.used_by_curr_pic_s0[i] = used_by_curr_pic_flag[j];
2696
2697 i += 1;
2698 }
2699 }
2700
2701 st.num_negative_pics = i as u8;
2702
2703 let mut i = 0;
2705 for j in (0..=isize::from(ref_st.num_negative_pics) - 1)
2709 .rev()
2710 .take_while(|j| *j >= 0)
2711 .map(|j| j as usize)
2712 {
2713 let d_poc = ref_st.delta_poc_s0[j] + delta_rps;
2714 if d_poc > 0 && use_delta_flag[j] {
2715 st.delta_poc_s1[i] = d_poc;
2716 st.used_by_curr_pic_s1[i] = used_by_curr_pic_flag[j];
2717
2718 i += 1;
2719 }
2720 }
2721
2722 if delta_rps > 0 && use_delta_flag[ref_st.num_delta_pocs as usize] {
2723 st.delta_poc_s1[i] = delta_rps;
2724 st.used_by_curr_pic_s1[i] = used_by_curr_pic_flag[ref_st.num_delta_pocs as usize];
2725
2726 i += 1;
2727 }
2728
2729 for j in 0..usize::from(ref_st.num_positive_pics) {
2730 let d_poc = ref_st.delta_poc_s1[j] + delta_rps;
2731 if d_poc > 0 && use_delta_flag[ref_st.num_negative_pics as usize + j] {
2732 st.delta_poc_s1[i] = d_poc;
2733 st.used_by_curr_pic_s1[i] =
2734 used_by_curr_pic_flag[ref_st.num_negative_pics as usize + j];
2735
2736 i += 1;
2737 }
2738 }
2739
2740 st.num_positive_pics = i as u8;
2741 } else {
2742 st.num_negative_pics = r.read_ue_max(u32::from(
2743 sps.max_dec_pic_buffering_minus1[usize::from(sps.max_sub_layers_minus1)],
2744 ))?;
2745
2746 st.num_positive_pics = r.read_ue_max(u32::from(
2747 sps.max_dec_pic_buffering_minus1[usize::from(sps.max_sub_layers_minus1)]
2748 - st.num_negative_pics,
2749 ))?;
2750
2751 for i in 0..usize::from(st.num_negative_pics) {
2752 let delta_poc_s0_minus1: u32 = r.read_ue_max(32767)?;
2753
2754 if i == 0 {
2755 st.delta_poc_s0[i] = -(delta_poc_s0_minus1 as i32 + 1);
2756 } else {
2757 st.delta_poc_s0[i] = st.delta_poc_s0[i - 1] - (delta_poc_s0_minus1 as i32 + 1);
2758 }
2759
2760 st.used_by_curr_pic_s0[i] = r.read_bit()?;
2761 }
2762
2763 for i in 0..usize::from(st.num_positive_pics) {
2764 let delta_poc_s1_minus1: u32 = r.read_ue_max(32767)?;
2765
2766 if i == 0 {
2767 st.delta_poc_s1[i] = delta_poc_s1_minus1 as i32 + 1;
2768 } else {
2769 st.delta_poc_s1[i] = st.delta_poc_s1[i - 1] + (delta_poc_s1_minus1 as i32 + 1);
2770 }
2771
2772 st.used_by_curr_pic_s1[i] = r.read_bit()?;
2773 }
2774 }
2775
2776 st.num_delta_pocs = u32::from(st.num_negative_pics + st.num_positive_pics);
2777
2778 Ok(())
2779 }
2780
2781 fn parse_sublayer_hrd_parameters(
2782 h: &mut SublayerHrdParameters,
2783 cpb_cnt: u32,
2784 sub_pic_hrd_params_present_flag: bool,
2785 r: &mut NaluReader,
2786 ) -> anyhow::Result<()> {
2787 for i in 0..cpb_cnt as usize {
2788 h.bit_rate_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2789 h.cpb_size_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2790 if sub_pic_hrd_params_present_flag {
2791 h.cpb_size_du_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2792 h.bit_rate_du_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2793 }
2794
2795 h.cbr_flag[i] = r.read_bit()?;
2796 }
2797
2798 Ok(())
2799 }
2800
2801 fn parse_hrd_parameters(
2802 common_inf_present_flag: bool,
2803 max_num_sublayers_minus1: u8,
2804 hrd: &mut HrdParams,
2805 r: &mut NaluReader,
2806 ) -> anyhow::Result<()> {
2807 if common_inf_present_flag {
2808 hrd.nal_hrd_parameters_present_flag = r.read_bit()?;
2809 hrd.vcl_hrd_parameters_present_flag = r.read_bit()?;
2810 if hrd.nal_hrd_parameters_present_flag || hrd.vcl_hrd_parameters_present_flag {
2811 hrd.sub_pic_hrd_params_present_flag = r.read_bit()?;
2812 if hrd.sub_pic_hrd_params_present_flag {
2813 hrd.tick_divisor_minus2 = r.read_bits(8)?;
2814 hrd.du_cpb_removal_delay_increment_length_minus1 = r.read_bits(5)?;
2815 hrd.sub_pic_cpb_params_in_pic_timing_sei_flag = r.read_bit()?;
2816 hrd.dpb_output_delay_du_length_minus1 = r.read_bits(5)?;
2817 }
2818 hrd.bit_rate_scale = r.read_bits(4)?;
2819 hrd.cpb_size_scale = r.read_bits(4)?;
2820 if hrd.sub_pic_hrd_params_present_flag {
2821 hrd.cpb_size_du_scale = r.read_bits(4)?;
2822 }
2823 hrd.initial_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
2824 hrd.au_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
2825 hrd.dpb_output_delay_length_minus1 = r.read_bits(5)?;
2826 }
2827 }
2828
2829 for i in 0..=max_num_sublayers_minus1 as usize {
2830 hrd.fixed_pic_rate_general_flag[i] = r.read_bit()?;
2831 if !hrd.fixed_pic_rate_general_flag[i] {
2832 hrd.fixed_pic_rate_within_cvs_flag[i] = r.read_bit()?;
2833 }
2834 if hrd.fixed_pic_rate_within_cvs_flag[i] {
2835 hrd.elemental_duration_in_tc_minus1[i] = r.read_ue_max(2047)?;
2836 } else {
2837 hrd.low_delay_hrd_flag[i] = r.read_bit()?;
2838 }
2839
2840 if !hrd.low_delay_hrd_flag[i] {
2841 hrd.cpb_cnt_minus1[i] = r.read_ue_max(31)?;
2842 }
2843
2844 if hrd.nal_hrd_parameters_present_flag {
2845 Self::parse_sublayer_hrd_parameters(
2846 &mut hrd.nal_hrd[i],
2847 hrd.cpb_cnt_minus1[i] + 1,
2848 hrd.sub_pic_hrd_params_present_flag,
2849 r,
2850 )?;
2851 }
2852
2853 if hrd.vcl_hrd_parameters_present_flag {
2854 Self::parse_sublayer_hrd_parameters(
2855 &mut hrd.vcl_hrd[i],
2856 hrd.cpb_cnt_minus1[i] + 1,
2857 hrd.sub_pic_hrd_params_present_flag,
2858 r,
2859 )?;
2860 }
2861 }
2862
2863 Ok(())
2864 }
2865
2866 fn parse_vui_parameters(sps: &mut Sps, r: &mut NaluReader) -> anyhow::Result<()> {
2867 let vui = &mut sps.vui_parameters;
2868
2869 vui.aspect_ratio_info_present_flag = r.read_bit()?;
2870 if vui.aspect_ratio_info_present_flag {
2871 vui.aspect_ratio_idc = r.read_bits(8)?;
2872 const EXTENDED_SAR: u32 = 255;
2873 if vui.aspect_ratio_idc == EXTENDED_SAR {
2874 vui.sar_width = r.read_bits(16)?;
2875 vui.sar_height = r.read_bits(16)?;
2876 }
2877 }
2878
2879 vui.overscan_info_present_flag = r.read_bit()?;
2880 if vui.overscan_info_present_flag {
2881 vui.overscan_appropriate_flag = r.read_bit()?;
2882 }
2883
2884 vui.video_signal_type_present_flag = r.read_bit()?;
2885 if vui.video_signal_type_present_flag {
2886 vui.video_format = r.read_bits(3)?;
2887 vui.video_full_range_flag = r.read_bit()?;
2888 vui.colour_description_present_flag = r.read_bit()?;
2889 if vui.colour_description_present_flag {
2890 vui.colour_primaries = r.read_bits(8)?;
2891 vui.transfer_characteristics = r.read_bits(8)?;
2892 vui.matrix_coeffs = r.read_bits(8)?;
2893 }
2894 }
2895
2896 vui.chroma_loc_info_present_flag = r.read_bit()?;
2897 if vui.chroma_loc_info_present_flag {
2898 vui.chroma_sample_loc_type_top_field = r.read_ue_max(5)?;
2899 vui.chroma_sample_loc_type_bottom_field = r.read_ue_max(5)?;
2900 }
2901
2902 vui.neutral_chroma_indication_flag = r.read_bit()?;
2903 vui.field_seq_flag = r.read_bit()?;
2904 vui.frame_field_info_present_flag = r.read_bit()?;
2905 vui.default_display_window_flag = r.read_bit()?;
2906
2907 if vui.default_display_window_flag {
2908 vui.def_disp_win_left_offset = r.read_ue()?;
2909 vui.def_disp_win_right_offset = r.read_ue()?;
2910 vui.def_disp_win_top_offset = r.read_ue()?;
2911 vui.def_disp_win_bottom_offset = r.read_ue()?;
2912 }
2913
2914 vui.timing_info_present_flag = r.read_bit()?;
2915 if vui.timing_info_present_flag {
2916 vui.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
2917 vui.num_units_in_tick |= r.read_bits::<u32>(1)?;
2918
2919 if vui.num_units_in_tick == 0 {
2920 log::warn!(
2921 "Incompliant value for num_units_in_tick {}",
2922 vui.num_units_in_tick
2923 );
2924 }
2925
2926 vui.time_scale = r.read_bits::<u32>(31)? << 1;
2927 vui.time_scale |= r.read_bits::<u32>(1)?;
2928
2929 if vui.time_scale == 0 {
2930 log::warn!("Incompliant value for time_scale {}", vui.time_scale);
2931 }
2932
2933 vui.poc_proportional_to_timing_flag = r.read_bit()?;
2934 if vui.poc_proportional_to_timing_flag {
2935 vui.num_ticks_poc_diff_one_minus1 = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2936 }
2937
2938 vui.hrd_parameters_present_flag = r.read_bit()?;
2939 if vui.hrd_parameters_present_flag {
2940 let sps_max_sub_layers_minus1 = sps.max_sub_layers_minus1;
2941 Self::parse_hrd_parameters(true, sps_max_sub_layers_minus1, &mut vui.hrd, r)?;
2942 }
2943 }
2944
2945 vui.bitstream_restriction_flag = r.read_bit()?;
2946 if vui.bitstream_restriction_flag {
2947 vui.tiles_fixed_structure_flag = r.read_bit()?;
2948 vui.motion_vectors_over_pic_boundaries_flag = r.read_bit()?;
2949 vui.restricted_ref_pic_lists_flag = r.read_bit()?;
2950
2951 vui.min_spatial_segmentation_idc = r.read_ue_max(4095)?;
2952 vui.max_bytes_per_pic_denom = r.read_ue()?;
2953 vui.max_bits_per_min_cu_denom = r.read_ue()?;
2954 vui.log2_max_mv_length_horizontal = r.read_ue_max(16)?;
2955 vui.log2_max_mv_length_vertical = r.read_ue_max(15)?;
2956 }
2957
2958 Ok(())
2959 }
2960
2961 fn parse_sps_scc_extension(sps: &mut Sps, r: &mut NaluReader) -> anyhow::Result<()> {
2962 let scc = &mut sps.scc_extension;
2963
2964 scc.curr_pic_ref_enabled_flag = r.read_bit()?;
2965 scc.palette_mode_enabled_flag = r.read_bit()?;
2966 if scc.palette_mode_enabled_flag {
2967 scc.palette_max_size = r.read_ue_max(64)?;
2968 scc.delta_palette_max_predictor_size =
2969 r.read_ue_max(128 - u32::from(scc.palette_max_size))?;
2970 scc.palette_predictor_initializers_present_flag = r.read_bit()?;
2971 if scc.palette_predictor_initializers_present_flag {
2972 let max =
2973 u32::from(scc.palette_max_size + scc.delta_palette_max_predictor_size - 1);
2974 scc.num_palette_predictor_initializer_minus1 = r.read_ue_max(max)?;
2975
2976 let num_comps = if sps.chroma_format_idc == 0 { 1 } else { 3 };
2977 for comp in 0..num_comps {
2978 for i in 0..=usize::from(scc.num_palette_predictor_initializer_minus1) {
2979 let num_bits = if comp == 0 {
2980 sps.bit_depth_luma_minus8 + 8
2981 } else {
2982 sps.bit_depth_chroma_minus8 + 8
2983 };
2984 scc.palette_predictor_initializer[comp][i] =
2985 r.read_bits(usize::from(num_bits))?;
2986 }
2987 }
2988 }
2989 }
2990
2991 scc.motion_vector_resolution_control_idc = r.read_bits(2)?;
2992 scc.intra_boundary_filtering_disabled_flag = r.read_bit()?;
2993
2994 Ok(())
2995 }
2996
2997 fn parse_sps_range_extension(sps: &mut Sps, r: &mut NaluReader) -> anyhow::Result<()> {
2998 let ext = &mut sps.range_extension;
2999
3000 ext.transform_skip_rotation_enabled_flag = r.read_bit()?;
3001 ext.transform_skip_context_enabled_flag = r.read_bit()?;
3002 ext.implicit_rdpcm_enabled_flag = r.read_bit()?;
3003 ext.explicit_rdpcm_enabled_flag = r.read_bit()?;
3004 ext.extended_precision_processing_flag = r.read_bit()?;
3005 ext.intra_smoothing_disabled_flag = r.read_bit()?;
3006 ext.high_precision_offsets_enabled_flag = r.read_bit()?;
3007 ext.persistent_rice_adaptation_enabled_flag = r.read_bit()?;
3008 ext.cabac_bypass_alignment_enabled_flag = r.read_bit()?;
3009
3010 Ok(())
3011 }
3012
3013 pub fn parse_sps(&mut self, nalu: &Nalu) -> anyhow::Result<&Sps> {
3015 if !matches!(nalu.header.type_, NaluType::SpsNut) {
3016 return Err(anyhow!(
3017 "Invalid NALU type, expected {:?}, got {:?}",
3018 NaluType::SpsNut,
3019 nalu.header.type_
3020 ));
3021 }
3022
3023 let data = nalu.as_ref();
3024 let header = &nalu.header;
3025 let hdr_len = header.len();
3026 let mut r = NaluReader::new(&data[hdr_len..]);
3028
3029 let mut sps = Sps {
3030 video_parameter_set_id: r.read_bits(4)?,
3031 max_sub_layers_minus1: r.read_bits(3)?,
3032 temporal_id_nesting_flag: r.read_bit()?,
3033 ..Default::default()
3034 };
3035
3036 Self::parse_profile_tier_level(
3037 &mut sps.profile_tier_level,
3038 &mut r,
3039 true,
3040 sps.max_sub_layers_minus1,
3041 )?;
3042
3043 sps.seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
3044 sps.chroma_format_idc = r.read_ue_max(3)?;
3045
3046 if sps.chroma_format_idc == 3 {
3047 sps.separate_colour_plane_flag = r.read_bit()?;
3048 }
3049
3050 sps.chroma_array_type = if sps.separate_colour_plane_flag {
3051 0
3052 } else {
3053 sps.chroma_format_idc
3054 };
3055
3056 sps.pic_width_in_luma_samples = r.read_ue_bounded(1, 16888)?;
3057 sps.pic_height_in_luma_samples = r.read_ue_bounded(1, 16888)?;
3058
3059 sps.conformance_window_flag = r.read_bit()?;
3060 if sps.conformance_window_flag {
3061 sps.conf_win_left_offset = r.read_ue()?;
3062 sps.conf_win_right_offset = r.read_ue()?;
3063 sps.conf_win_top_offset = r.read_ue()?;
3064 sps.conf_win_bottom_offset = r.read_ue()?;
3065 }
3066
3067 sps.bit_depth_luma_minus8 = r.read_ue_max(6)?;
3068 sps.bit_depth_chroma_minus8 = r.read_ue_max(6)?;
3069 sps.log2_max_pic_order_cnt_lsb_minus4 = r.read_ue_max(12)?;
3070 sps.sub_layer_ordering_info_present_flag = r.read_bit()?;
3071
3072 {
3073 let i = if sps.sub_layer_ordering_info_present_flag {
3074 0
3075 } else {
3076 sps.max_sub_layers_minus1
3077 };
3078
3079 for j in i..=sps.max_sub_layers_minus1 {
3080 sps.max_dec_pic_buffering_minus1[j as usize] = r.read_ue_max(16)?;
3081 sps.max_num_reorder_pics[j as usize] =
3082 r.read_ue_max(sps.max_dec_pic_buffering_minus1[j as usize] as _)?;
3083 sps.max_latency_increase_plus1[j as usize] = r.read_ue_max(u32::MAX - 1)?;
3084 }
3085 }
3086
3087 sps.log2_min_luma_coding_block_size_minus3 = r.read_ue_max(3)?;
3088 sps.log2_diff_max_min_luma_coding_block_size = r.read_ue_max(6)?;
3089 sps.log2_min_luma_transform_block_size_minus2 = r.read_ue_max(3)?;
3090 sps.log2_diff_max_min_luma_transform_block_size = r.read_ue_max(3)?;
3091
3092 sps.min_cb_log2_size_y = u32::from(sps.log2_min_luma_coding_block_size_minus3 + 3);
3094 sps.ctb_log2_size_y =
3096 sps.min_cb_log2_size_y + u32::from(sps.log2_diff_max_min_luma_coding_block_size);
3097 sps.ctb_size_y = 1 << sps.ctb_log2_size_y;
3099 sps.pic_height_in_ctbs_y =
3101 (sps.pic_height_in_luma_samples as f64 / sps.ctb_size_y as f64).ceil() as u32;
3102 sps.pic_width_in_ctbs_y =
3104 (sps.pic_width_in_luma_samples as f64 / sps.ctb_size_y as f64).ceil() as u32;
3105
3106 sps.max_tb_log2_size_y = u32::from(
3107 sps.log2_min_luma_transform_block_size_minus2
3108 + 2
3109 + sps.log2_diff_max_min_luma_transform_block_size,
3110 );
3111
3112 sps.pic_size_in_samples_y =
3113 u32::from(sps.pic_width_in_luma_samples) * u32::from(sps.pic_height_in_luma_samples);
3114
3115 if sps.max_tb_log2_size_y > std::cmp::min(sps.ctb_log2_size_y, 5) {
3116 return Err(anyhow!(
3117 "Invalid value for MaxTbLog2SizeY: {}",
3118 sps.max_tb_log2_size_y
3119 ));
3120 }
3121
3122 sps.pic_size_in_ctbs_y = sps.pic_width_in_ctbs_y * sps.pic_height_in_ctbs_y;
3123
3124 sps.max_transform_hierarchy_depth_inter = r.read_ue_max(4)?;
3125 sps.max_transform_hierarchy_depth_intra = r.read_ue_max(4)?;
3126
3127 sps.scaling_list_enabled_flag = r.read_bit()?;
3128 if sps.scaling_list_enabled_flag {
3129 sps.scaling_list_data_present_flag = r.read_bit()?;
3130 if sps.scaling_list_data_present_flag {
3131 Self::parse_scaling_list_data(&mut sps.scaling_list, &mut r)?;
3132 }
3133 }
3134
3135 sps.amp_enabled_flag = r.read_bit()?;
3136 sps.sample_adaptive_offset_enabled_flag = r.read_bit()?;
3137
3138 sps.pcm_enabled_flag = r.read_bit()?;
3139 if sps.pcm_enabled_flag {
3140 sps.pcm_sample_bit_depth_luma_minus1 = r.read_bits(4)?;
3141 sps.pcm_sample_bit_depth_chroma_minus1 = r.read_bits(4)?;
3142 sps.log2_min_pcm_luma_coding_block_size_minus3 = r.read_ue_max(2)?;
3143 sps.log2_diff_max_min_pcm_luma_coding_block_size = r.read_ue_max(2)?;
3144 sps.pcm_loop_filter_disabled_flag = r.read_bit()?;
3145 }
3146
3147 sps.num_short_term_ref_pic_sets = r.read_ue_max(64)?;
3148
3149 for i in 0..sps.num_short_term_ref_pic_sets {
3150 let mut st = ShortTermRefPicSet::default();
3151 Self::parse_short_term_ref_pic_set(&sps, &mut st, &mut r, i)?;
3152 sps.short_term_ref_pic_set.push(st);
3153 }
3154
3155 sps.long_term_ref_pics_present_flag = r.read_bit()?;
3156 if sps.long_term_ref_pics_present_flag {
3157 sps.num_long_term_ref_pics_sps = r.read_ue_max(32)?;
3158 for i in 0..usize::from(sps.num_long_term_ref_pics_sps) {
3159 sps.lt_ref_pic_poc_lsb_sps[i] =
3160 r.read_bits(usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4)?;
3161 sps.used_by_curr_pic_lt_sps_flag[i] = r.read_bit()?;
3162 }
3163 }
3164
3165 sps.temporal_mvp_enabled_flag = r.read_bit()?;
3166 sps.strong_intra_smoothing_enabled_flag = r.read_bit()?;
3167
3168 sps.vui_parameters_present_flag = r.read_bit()?;
3169 if sps.vui_parameters_present_flag {
3170 Self::parse_vui_parameters(&mut sps, &mut r)?;
3171 }
3172
3173 sps.extension_present_flag = r.read_bit()?;
3174 if sps.extension_present_flag {
3175 sps.range_extension_flag = r.read_bit()?;
3176 if sps.range_extension_flag {
3177 Self::parse_sps_range_extension(&mut sps, &mut r)?;
3178 }
3179
3180 let multilayer_extension_flag = r.read_bit()?;
3181 if multilayer_extension_flag {
3182 return Err(anyhow!("Multilayer extension not supported."));
3183 }
3184
3185 let three_d_extension_flag = r.read_bit()?;
3186 if three_d_extension_flag {
3187 return Err(anyhow!("3D extension not supported."));
3188 }
3189
3190 sps.scc_extension_flag = r.read_bit()?;
3191 if sps.scc_extension_flag {
3192 Self::parse_sps_scc_extension(&mut sps, &mut r)?;
3193 }
3194 }
3195
3196 let shift = if sps.range_extension.high_precision_offsets_enabled_flag {
3197 sps.bit_depth_luma_minus8 + 7
3198 } else {
3199 7
3200 };
3201
3202 sps.wp_offset_half_range_y = 1 << shift;
3203
3204 let shift = if sps.range_extension.high_precision_offsets_enabled_flag {
3205 sps.bit_depth_chroma_minus8 + 7
3206 } else {
3207 7
3208 };
3209
3210 sps.wp_offset_half_range_c = 1 << shift;
3211
3212 log::debug!(
3213 "Parsed SPS({}), resolution: ({}, {}): NAL size was {}",
3214 sps.seq_parameter_set_id,
3215 sps.width(),
3216 sps.height(),
3217 nalu.size
3218 );
3219
3220 let key = sps.seq_parameter_set_id;
3221 self.active_spses.insert(key, sps);
3222
3223 if self.active_spses.keys().len() > MAX_SPS_COUNT {
3224 return Err(anyhow!(
3225 "Broken data: Number of active SPSs > MAX_SPS_COUNT"
3226 ));
3227 }
3228
3229 Ok(self.get_sps(key).unwrap())
3230 }
3231
3232 fn parse_pps_scc_extension(pps: &mut Pps, sps: &Sps, r: &mut NaluReader) -> anyhow::Result<()> {
3233 let scc = &mut pps.scc_extension;
3234 scc.curr_pic_ref_enabled_flag = r.read_bit()?;
3235 scc.residual_adaptive_colour_transform_enabled_flag = r.read_bit()?;
3236 if scc.residual_adaptive_colour_transform_enabled_flag {
3237 scc.slice_act_qp_offsets_present_flag = r.read_bit()?;
3238 scc.act_y_qp_offset_plus5 = r.read_se_bounded(-7, 17)?;
3239 scc.act_cb_qp_offset_plus5 = r.read_se_bounded(-7, 17)?;
3240 scc.act_cr_qp_offset_plus3 = r.read_se_bounded(-9, 15)?;
3241 }
3242
3243 scc.palette_predictor_initializers_present_flag = r.read_bit()?;
3244 if scc.palette_predictor_initializers_present_flag {
3245 let max = sps.scc_extension.palette_max_size
3246 + sps.scc_extension.delta_palette_max_predictor_size;
3247 scc.num_palette_predictor_initializers = r.read_ue_max(max.into())?;
3248 if scc.num_palette_predictor_initializers > 0 {
3249 scc.monochrome_palette_flag = r.read_bit()?;
3250 scc.luma_bit_depth_entry_minus8 = r.read_ue_bounded(
3251 sps.bit_depth_luma_minus8.into(),
3252 sps.bit_depth_luma_minus8.into(),
3253 )?;
3254 if !scc.monochrome_palette_flag {
3255 scc.chroma_bit_depth_entry_minus8 = r.read_ue_bounded(
3256 sps.bit_depth_chroma_minus8.into(),
3257 sps.bit_depth_chroma_minus8.into(),
3258 )?;
3259 }
3260
3261 let num_comps = if scc.monochrome_palette_flag { 1 } else { 3 };
3262 for comp in 0..num_comps {
3263 let num_bits = if comp == 0 {
3264 scc.luma_bit_depth_entry_minus8 + 8
3265 } else {
3266 scc.chroma_bit_depth_entry_minus8 + 8
3267 };
3268 for i in 0..usize::from(scc.num_palette_predictor_initializers) {
3269 scc.palette_predictor_initializer[comp][i] =
3270 r.read_bits(num_bits.into())?;
3271 }
3272 }
3273 }
3274 }
3275 Ok(())
3276 }
3277
3278 fn parse_pps_range_extension(
3279 pps: &mut Pps,
3280 sps: &Sps,
3281 r: &mut NaluReader,
3282 ) -> anyhow::Result<()> {
3283 let rext = &mut pps.range_extension;
3284
3285 if pps.transform_skip_enabled_flag {
3286 rext.log2_max_transform_skip_block_size_minus2 =
3287 r.read_ue_max(sps.max_tb_log2_size_y - 2)?;
3288 }
3289
3290 rext.cross_component_prediction_enabled_flag = r.read_bit()?;
3291 rext.chroma_qp_offset_list_enabled_flag = r.read_bit()?;
3292 if rext.chroma_qp_offset_list_enabled_flag {
3293 rext.diff_cu_chroma_qp_offset_depth = r.read_ue()?;
3294 rext.chroma_qp_offset_list_len_minus1 = r.read_ue_max(5)?;
3295 for i in 0..=rext.chroma_qp_offset_list_len_minus1 as usize {
3296 rext.cb_qp_offset_list[i] = r.read_se_bounded(-12, 12)?;
3297 rext.cr_qp_offset_list[i] = r.read_se_bounded(-12, 12)?;
3298 }
3299 }
3300
3301 let bit_depth_y = sps.bit_depth_luma_minus8 + 8;
3302 let max = u32::from(std::cmp::max(0, bit_depth_y - 10));
3303
3304 rext.log2_sao_offset_scale_luma = r.read_ue_max(max)?;
3305 rext.log2_sao_offset_scale_chroma = r.read_ue_max(max)?;
3306
3307 Ok(())
3308 }
3309
3310 pub fn parse_pps(&mut self, nalu: &Nalu) -> anyhow::Result<&Pps> {
3312 if !matches!(nalu.header.type_, NaluType::PpsNut) {
3313 return Err(anyhow!(
3314 "Invalid NALU type, expected {:?}, got {:?}",
3315 NaluType::PpsNut,
3316 nalu.header.type_
3317 ));
3318 }
3319
3320 let data = nalu.as_ref();
3321 let header = &nalu.header;
3322 let hdr_len = header.len();
3323 let mut r = NaluReader::new(&data[hdr_len..]);
3325
3326 let mut pps = Pps {
3327 loop_filter_across_tiles_enabled_flag: true,
3328 ..Default::default()
3329 };
3330
3331 pps.pic_parameter_set_id = r.read_ue_max(MAX_PPS_COUNT as u32 - 1)?;
3332 pps.seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
3333
3334 let sps = self.get_sps(pps.seq_parameter_set_id).context(format!(
3335 "Broken stream: stream references SPS {} that has not been successfully parsed",
3336 pps.seq_parameter_set_id
3337 ))?;
3338
3339 pps.dependent_slice_segments_enabled_flag = r.read_bit()?;
3340 pps.output_flag_present_flag = r.read_bit()?;
3341 pps.num_extra_slice_header_bits = r.read_bits(3)?;
3342 pps.sign_data_hiding_enabled_flag = r.read_bit()?;
3343 pps.cabac_init_present_flag = r.read_bit()?;
3344
3345 pps.num_ref_idx_l0_default_active_minus1 = r.read_ue_max(14)?;
3347 pps.num_ref_idx_l1_default_active_minus1 = r.read_ue_max(14)?;
3348
3349 let qp_bd_offset_y = 6 * i32::from(sps.bit_depth_luma_minus8);
3351
3352 pps.init_qp_minus26 = r.read_se_bounded(-(26 + qp_bd_offset_y), 25)?;
3353 pps.qp_bd_offset_y = qp_bd_offset_y as u32;
3354 pps.constrained_intra_pred_flag = r.read_bit()?;
3355 pps.transform_skip_enabled_flag = r.read_bit()?;
3356 pps.cu_qp_delta_enabled_flag = r.read_bit()?;
3357
3358 if pps.cu_qp_delta_enabled_flag {
3359 pps.diff_cu_qp_delta_depth =
3360 r.read_ue_max(u32::from(sps.log2_diff_max_min_luma_coding_block_size))?;
3361 }
3362
3363 pps.cb_qp_offset = r.read_se_bounded(-12, 12)?;
3364 pps.cr_qp_offset = r.read_se_bounded(-12, 12)?;
3365
3366 pps.slice_chroma_qp_offsets_present_flag = r.read_bit()?;
3367 pps.weighted_pred_flag = r.read_bit()?;
3368 pps.weighted_bipred_flag = r.read_bit()?;
3369 pps.transquant_bypass_enabled_flag = r.read_bit()?;
3370 pps.tiles_enabled_flag = r.read_bit()?;
3371 pps.entropy_coding_sync_enabled_flag = r.read_bit()?;
3372
3373 if pps.tiles_enabled_flag {
3375 pps.num_tile_columns_minus1 = r.read_ue_max(sps.pic_width_in_ctbs_y - 1)?;
3376 pps.num_tile_rows_minus1 = r.read_ue_max(sps.pic_height_in_ctbs_y - 1)?;
3377 pps.uniform_spacing_flag = r.read_bit()?;
3378 if !pps.uniform_spacing_flag {
3379 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] =
3380 sps.pic_width_in_ctbs_y - 1;
3381
3382 for i in 0..usize::from(pps.num_tile_columns_minus1) {
3383 pps.column_width_minus1[i] = r.read_ue_max(
3384 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] - 1,
3385 )?;
3386 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] -=
3387 pps.column_width_minus1[i] + 1;
3388 }
3389
3390 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] =
3391 sps.pic_height_in_ctbs_y - 1;
3392
3393 for i in 0..usize::from(pps.num_tile_rows_minus1) {
3394 pps.row_height_minus1[i] = r.read_ue_max(
3395 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] - 1,
3396 )?;
3397 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] -=
3398 pps.row_height_minus1[i] + 1;
3399 }
3400 } else {
3401 let nrows = u32::from(pps.num_tile_rows_minus1) + 1;
3402 let ncols = u32::from(pps.num_tile_columns_minus1) + 1;
3403
3404 for j in 0..ncols {
3405 pps.column_width_minus1[j as usize] = ((j + 1) * sps.pic_width_in_ctbs_y)
3406 / ncols
3407 - j * sps.pic_width_in_ctbs_y / ncols
3408 - 1;
3409 }
3410
3411 for j in 0..nrows {
3412 pps.row_height_minus1[j as usize] = ((j + 1) * sps.pic_height_in_ctbs_y)
3413 / nrows
3414 - j * sps.pic_height_in_ctbs_y / nrows
3415 - 1;
3416 }
3417 }
3418
3419 pps.loop_filter_across_tiles_enabled_flag = r.read_bit()?;
3420 }
3421
3422 pps.loop_filter_across_slices_enabled_flag = r.read_bit()?;
3423 pps.deblocking_filter_control_present_flag = r.read_bit()?;
3424
3425 if pps.deblocking_filter_control_present_flag {
3426 pps.deblocking_filter_override_enabled_flag = r.read_bit()?;
3427 pps.deblocking_filter_disabled_flag = r.read_bit()?;
3428 if !pps.deblocking_filter_disabled_flag {
3429 pps.beta_offset_div2 = r.read_se_bounded(-6, 6)?;
3430 pps.tc_offset_div2 = r.read_se_bounded(-6, 6)?;
3431 }
3432 }
3433
3434 pps.scaling_list_data_present_flag = r.read_bit()?;
3435
3436 if pps.scaling_list_data_present_flag {
3437 Self::parse_scaling_list_data(&mut pps.scaling_list, &mut r)?;
3438 } else {
3439 for size_id in 0..4 {
3440 let mut matrix_id = 0;
3441 while matrix_id < 6 {
3442 Self::fill_default_scaling_list(&mut pps.scaling_list, size_id, matrix_id);
3443 let step = if size_id == 3 { 3 } else { 1 };
3444 matrix_id += step;
3445 }
3446 }
3447 }
3448
3449 pps.lists_modification_present_flag = r.read_bit()?;
3450 pps.log2_parallel_merge_level_minus2 = r.read_ue_max(sps.ctb_log2_size_y - 2)?;
3451 pps.slice_segment_header_extension_present_flag = r.read_bit()?;
3452
3453 pps.extension_present_flag = r.read_bit()?;
3454 if pps.extension_present_flag {
3455 pps.range_extension_flag = r.read_bit()?;
3456
3457 if pps.range_extension_flag {
3458 Self::parse_pps_range_extension(&mut pps, sps, &mut r)?;
3459 }
3460
3461 let multilayer_extension_flag = r.read_bit()?;
3462 if multilayer_extension_flag {
3463 return Err(anyhow!("Multilayer extension is not supported"));
3464 }
3465
3466 let three_d_extension_flag = r.read_bit()?;
3467 if three_d_extension_flag {
3468 return Err(anyhow!("3D extension is not supported"));
3469 }
3470
3471 pps.scc_extension_flag = r.read_bit()?;
3472 if pps.scc_extension_flag {
3473 Self::parse_pps_scc_extension(&mut pps, sps, &mut r)?;
3474 }
3475
3476 r.skip_bits(4)?; }
3478
3479 pps.temporal_id = nalu.header.nuh_temporal_id_plus1 - 1;
3480
3481 log::debug!(
3482 "Parsed PPS({}), NAL size was {}",
3483 pps.pic_parameter_set_id,
3484 nalu.size
3485 );
3486
3487 let key = pps.pic_parameter_set_id;
3488 self.active_ppses.insert(key, pps);
3489
3490 if self.active_ppses.keys().len() > MAX_PPS_COUNT {
3491 return Err(anyhow!(
3492 "Broken Data: number of active PPSs > MAX_PPS_COUNT"
3493 ));
3494 }
3495
3496 Ok(self.get_pps(key).unwrap())
3497 }
3498
3499 fn parse_pred_weight_table(
3500 hdr: &mut SliceHeader,
3501 r: &mut NaluReader,
3502 sps: &Sps,
3503 ) -> anyhow::Result<()> {
3504 let pwt = &mut hdr.pred_weight_table;
3505
3506 pwt.luma_log2_weight_denom = r.read_ue_max(7)?;
3507 if sps.chroma_array_type != 0 {
3508 pwt.delta_chroma_log2_weight_denom = r.read_se()?;
3509 pwt.chroma_log2_weight_denom = (pwt.luma_log2_weight_denom as i32
3510 + pwt.delta_chroma_log2_weight_denom as i32)
3511 .try_into()?;
3512 }
3513
3514 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) {
3515 pwt.luma_weight_l0_flag[i] = r.read_bit()?;
3516 }
3517
3518 if sps.chroma_array_type != 0 {
3519 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) {
3520 pwt.chroma_weight_l0_flag[i] = r.read_bit()?;
3521 }
3522 }
3523
3524 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) {
3525 if pwt.luma_weight_l0_flag[i] {
3526 pwt.delta_luma_weight_l0[i] = r.read_se_bounded(-128, 127)?;
3527 pwt.luma_offset_l0[i] = r.read_se_bounded(-128, 127)?;
3528 }
3529
3530 if pwt.chroma_weight_l0_flag[i] {
3531 for j in 0..2 {
3532 pwt.delta_chroma_weight_l0[i][j] = r.read_se_bounded(-128, 127)?;
3533 pwt.delta_chroma_offset_l0[i][j] = r.read_se_bounded(
3534 -4 * sps.wp_offset_half_range_c as i32,
3535 4 * sps.wp_offset_half_range_c as i32 - 1,
3536 )?;
3537 }
3538 }
3539 }
3540
3541 if hdr.type_.is_b() {
3542 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) {
3543 pwt.luma_weight_l1_flag[i] = r.read_bit()?;
3544 }
3545
3546 if sps.chroma_format_idc != 0 {
3547 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) {
3548 pwt.chroma_weight_l1_flag[i] = r.read_bit()?;
3549 }
3550 }
3551
3552 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) {
3553 if pwt.luma_weight_l1_flag[i] {
3554 pwt.delta_luma_weight_l1[i] = r.read_se_bounded(-128, 127)?;
3555 pwt.luma_offset_l1[i] = r.read_se_bounded(-128, 127)?;
3556 }
3557
3558 if pwt.chroma_weight_l1_flag[i] {
3559 for j in 0..2 {
3560 pwt.delta_chroma_weight_l1[i][j] = r.read_se_bounded(-128, 127)?;
3561 pwt.delta_chroma_offset_l1[i][j] = r.read_se_bounded(
3562 -4 * sps.wp_offset_half_range_c as i32,
3563 4 * sps.wp_offset_half_range_c as i32 - 1,
3564 )?;
3565 }
3566 }
3567 }
3568 }
3569
3570 Ok(())
3571 }
3572
3573 fn parse_ref_pic_lists_modification(
3574 hdr: &mut SliceHeader,
3575 r: &mut NaluReader,
3576 ) -> anyhow::Result<()> {
3577 let rplm = &mut hdr.ref_pic_list_modification;
3578
3579 rplm.ref_pic_list_modification_flag_l0 = r.read_bit()?;
3580 if rplm.ref_pic_list_modification_flag_l0 {
3581 for _ in 0..=hdr.num_ref_idx_l0_active_minus1 {
3582 let num_bits = (hdr.num_pic_total_curr as f64).log2().ceil() as _;
3583
3584 let entry = r.read_bits(num_bits)?;
3585
3586 if entry > hdr.num_pic_total_curr - 1 {
3587 return Err(anyhow!(
3588 "Invalid list_entry_l0 {}, expected at max NumPicTotalCurr - 1: {}",
3589 entry,
3590 hdr.num_pic_total_curr - 1
3591 ));
3592 }
3593
3594 rplm.list_entry_l0.push(entry);
3595 }
3596 }
3597
3598 if hdr.type_.is_b() {
3599 rplm.ref_pic_list_modification_flag_l1 = r.read_bit()?;
3600 if rplm.ref_pic_list_modification_flag_l1 {
3601 for _ in 0..=hdr.num_ref_idx_l1_active_minus1 {
3602 let num_bits = (hdr.num_pic_total_curr as f64).log2().ceil() as _;
3603
3604 let entry = r.read_bits(num_bits)?;
3605
3606 if entry > hdr.num_pic_total_curr - 1 {
3607 return Err(anyhow!(
3608 "Invalid list_entry_l1 {}, expected at max NumPicTotalCurr - 1: {}",
3609 entry,
3610 hdr.num_pic_total_curr - 1
3611 ));
3612 }
3613
3614 rplm.list_entry_l1.push(entry);
3615 }
3616 }
3617 }
3618
3619 Ok(())
3620 }
3621
3622 pub fn slice_header_set_defaults(hdr: &mut SliceHeader, sps: &Sps, pps: &Pps) {
3624 hdr.deblocking_filter_disabled_flag = pps.deblocking_filter_disabled_flag;
3626 hdr.beta_offset_div2 = pps.beta_offset_div2;
3627 hdr.tc_offset_div2 = pps.tc_offset_div2;
3628 hdr.loop_filter_across_slices_enabled_flag = pps.loop_filter_across_slices_enabled_flag;
3629 hdr.curr_rps_idx = sps.num_short_term_ref_pic_sets;
3630 hdr.use_integer_mv_flag = sps.scc_extension.motion_vector_resolution_control_idc != 0;
3631 }
3632
3633 pub fn parse_slice_header<'a>(&mut self, nalu: Nalu<'a>) -> anyhow::Result<Slice<'a>> {
3635 if !matches!(
3636 nalu.header.type_,
3637 NaluType::TrailN
3638 | NaluType::TrailR
3639 | NaluType::TsaN
3640 | NaluType::TsaR
3641 | NaluType::StsaN
3642 | NaluType::StsaR
3643 | NaluType::RadlN
3644 | NaluType::RadlR
3645 | NaluType::RaslN
3646 | NaluType::RaslR
3647 | NaluType::BlaWLp
3648 | NaluType::BlaWRadl
3649 | NaluType::BlaNLp
3650 | NaluType::IdrWRadl
3651 | NaluType::IdrNLp
3652 | NaluType::CraNut,
3653 ) {
3654 return Err(anyhow!(
3655 "Invalid NALU type: {:?} is not a slice NALU",
3656 nalu.header.type_
3657 ));
3658 }
3659
3660 let data = nalu.as_ref();
3661 let nalu_header = &nalu.header;
3662 let hdr_len = nalu_header.len();
3663 let mut r = NaluReader::new(&data[hdr_len..]);
3665
3666 let mut hdr = SliceHeader {
3667 first_slice_segment_in_pic_flag: r.read_bit()?,
3668 ..Default::default()
3669 };
3670
3671 if nalu.header.type_.is_irap() {
3672 hdr.no_output_of_prior_pics_flag = r.read_bit()?;
3673 }
3674
3675 hdr.pic_parameter_set_id = r.read_ue_max(63)?;
3676
3677 let pps = self.get_pps(hdr.pic_parameter_set_id).with_context(|| {
3678 format!(
3679 "Broken stream: slice references PPS {} that has not been successfully parsed.",
3680 hdr.pic_parameter_set_id,
3681 )
3682 })?;
3683
3684 let sps = self.get_sps(pps.seq_parameter_set_id).with_context(|| {
3685 format!(
3686 "Broken stream: slice's PPS references SPS {} that has not been successfully parsed.", pps.seq_parameter_set_id
3687 )
3688 })?;
3689
3690 Self::slice_header_set_defaults(&mut hdr, sps, pps);
3691
3692 if !hdr.first_slice_segment_in_pic_flag {
3693 if pps.dependent_slice_segments_enabled_flag {
3694 hdr.dependent_slice_segment_flag = r.read_bit()?;
3695 }
3696
3697 let num_bits = (sps.pic_size_in_ctbs_y as f64).log2().ceil() as _;
3698 hdr.segment_address = r.read_bits(num_bits)?;
3699
3700 if hdr.segment_address > sps.pic_size_in_ctbs_y - 1 {
3701 return Err(anyhow!(
3702 "Invalid slice_segment_address {}",
3703 hdr.segment_address
3704 ));
3705 }
3706 }
3707
3708 if !hdr.dependent_slice_segment_flag {
3709 r.skip_bits(usize::from(pps.num_extra_slice_header_bits))?;
3710
3711 let slice_type: u32 = r.read_ue()?;
3712 hdr.type_ = SliceType::n(slice_type).ok_or(anyhow!("Invalid slice type"))?;
3713
3714 if pps.output_flag_present_flag {
3715 hdr.pic_output_flag = r.read_bit()?;
3716 }
3717
3718 if sps.separate_colour_plane_flag {
3719 hdr.colour_plane_id = r.read_bits(2)?;
3720 }
3721
3722 if !matches!(nalu_header.type_, NaluType::IdrWRadl | NaluType::IdrNLp) {
3723 let num_bits = usize::from(sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
3724 hdr.pic_order_cnt_lsb = r.read_bits(num_bits)?;
3725
3726 if u32::from(hdr.pic_order_cnt_lsb)
3727 > 2u32.pow(u32::from(sps.log2_max_pic_order_cnt_lsb_minus4 + 4))
3728 {
3729 return Err(anyhow!(
3730 "Invalid pic_order_cnt_lsb {}",
3731 hdr.pic_order_cnt_lsb
3732 ));
3733 }
3734
3735 hdr.short_term_ref_pic_set_sps_flag = r.read_bit()?;
3736
3737 if !hdr.short_term_ref_pic_set_sps_flag {
3738 let epb_before = r.num_epb();
3739 let bits_left_before = r.num_bits_left();
3740
3741 let st_rps_idx = sps.num_short_term_ref_pic_sets;
3742
3743 Self::parse_short_term_ref_pic_set(
3744 sps,
3745 &mut hdr.short_term_ref_pic_set,
3746 &mut r,
3747 st_rps_idx,
3748 )?;
3749
3750 hdr.st_rps_bits = ((bits_left_before - r.num_bits_left())
3751 - 8 * (r.num_epb() - epb_before))
3752 as u32;
3753 } else if sps.num_short_term_ref_pic_sets > 1 {
3754 let num_bits = (sps.num_short_term_ref_pic_sets as f64).log2().ceil() as _;
3755 hdr.short_term_ref_pic_set_idx = r.read_bits(num_bits)?;
3756
3757 if hdr.short_term_ref_pic_set_idx > sps.num_short_term_ref_pic_sets - 1 {
3758 return Err(anyhow!(
3759 "Invalid short_term_ref_pic_set_idx {}",
3760 hdr.short_term_ref_pic_set_idx
3761 ));
3762 }
3763 }
3764
3765 if hdr.short_term_ref_pic_set_sps_flag {
3766 hdr.curr_rps_idx = hdr.short_term_ref_pic_set_idx;
3767 }
3768
3769 if sps.long_term_ref_pics_present_flag {
3770 if sps.num_long_term_ref_pics_sps > 0 {
3771 hdr.num_long_term_sps =
3772 r.read_ue_max(u32::from(sps.num_long_term_ref_pics_sps))?;
3773 }
3774
3775 hdr.num_long_term_pics = r.read_ue_max(
3776 MAX_LONG_TERM_REF_PIC_SETS as u32 - u32::from(hdr.num_long_term_sps),
3777 )?;
3778
3779 let num_lt = hdr.num_long_term_sps + hdr.num_long_term_pics;
3780 for i in 0..usize::from(num_lt) {
3781 if i < usize::from(hdr.num_long_term_sps) {
3791 if sps.num_long_term_ref_pics_sps > 1 {
3792 let num_bits =
3793 (sps.num_long_term_ref_pics_sps as f64).log2().ceil() as _;
3794
3795 hdr.lt_idx_sps[i] = r.read_bits(num_bits)?;
3796
3797 if hdr.lt_idx_sps[i] > sps.num_long_term_ref_pics_sps - 1 {
3798 return Err(anyhow!(
3799 "Invalid lt_idx_sps[{}] {}",
3800 i,
3801 hdr.lt_idx_sps[i]
3802 ));
3803 }
3804 }
3805
3806 hdr.poc_lsb_lt[i] =
3807 sps.lt_ref_pic_poc_lsb_sps[usize::from(hdr.lt_idx_sps[i])];
3808 hdr.used_by_curr_pic_lt[i] =
3809 sps.used_by_curr_pic_lt_sps_flag[usize::from(hdr.lt_idx_sps[i])];
3810 } else {
3811 let num_bits = usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4;
3812 hdr.poc_lsb_lt[i] = r.read_bits(num_bits)?;
3813 hdr.used_by_curr_pic_lt[i] = r.read_bit()?;
3814 }
3815
3816 hdr.delta_poc_msb_present_flag[i] = r.read_bit()?;
3817 if hdr.delta_poc_msb_present_flag[i] {
3818 let max =
3824 2u32.pow(32 - u32::from(sps.log2_max_pic_order_cnt_lsb_minus4) - 4);
3825 hdr.delta_poc_msb_cycle_lt[i] = r.read_ue_max(max)?;
3826 }
3827 if i != 0 && i != usize::from(hdr.num_long_term_sps) {
3829 hdr.delta_poc_msb_cycle_lt[i] += hdr.delta_poc_msb_cycle_lt[i - 1];
3830 }
3831 }
3832 }
3833
3834 if sps.temporal_mvp_enabled_flag {
3835 hdr.temporal_mvp_enabled_flag = r.read_bit()?;
3836 }
3837 }
3838
3839 if sps.sample_adaptive_offset_enabled_flag {
3840 hdr.sao_luma_flag = r.read_bit()?;
3841 if sps.chroma_array_type != 0 {
3842 hdr.sao_chroma_flag = r.read_bit()?;
3843 }
3844 }
3845
3846 if hdr.type_.is_p() || hdr.type_.is_b() {
3847 hdr.num_ref_idx_active_override_flag = r.read_bit()?;
3848 if hdr.num_ref_idx_active_override_flag {
3849 hdr.num_ref_idx_l0_active_minus1 = r.read_ue_max(MAX_REF_IDX_ACTIVE - 1)?;
3850 if hdr.type_.is_b() {
3851 hdr.num_ref_idx_l1_active_minus1 = r.read_ue_max(MAX_REF_IDX_ACTIVE - 1)?;
3852 }
3853 } else {
3854 hdr.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1;
3855 hdr.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1;
3856 }
3857
3858 let mut num_pic_total_curr = 0;
3860 let rps = if hdr.short_term_ref_pic_set_sps_flag {
3861 sps.short_term_ref_pic_set
3862 .get(usize::from(hdr.curr_rps_idx))
3863 .ok_or(anyhow!("Invalid RPS"))?
3864 } else {
3865 &hdr.short_term_ref_pic_set
3866 };
3867
3868 for i in 0..usize::from(rps.num_negative_pics) {
3869 if rps.used_by_curr_pic_s0[i] {
3870 num_pic_total_curr += 1;
3871 }
3872 }
3873
3874 for i in 0..usize::from(rps.num_positive_pics) {
3875 if rps.used_by_curr_pic_s1[i] {
3876 num_pic_total_curr += 1;
3877 }
3878 }
3879
3880 for i in 0..usize::from(hdr.num_long_term_sps + hdr.num_long_term_pics) {
3881 if hdr.used_by_curr_pic_lt[i] {
3882 num_pic_total_curr += 1;
3883 }
3884 }
3885
3886 if pps.scc_extension.curr_pic_ref_enabled_flag {
3887 num_pic_total_curr += 1;
3888 }
3889
3890 hdr.num_pic_total_curr = num_pic_total_curr;
3891
3892 if pps.lists_modification_present_flag && hdr.num_pic_total_curr > 1 {
3893 Self::parse_ref_pic_lists_modification(&mut hdr, &mut r)?;
3894 }
3895
3896 if hdr.type_.is_b() {
3897 hdr.mvd_l1_zero_flag = r.read_bit()?;
3898 }
3899
3900 if pps.cabac_init_present_flag {
3901 hdr.cabac_init_flag = r.read_bit()?;
3902 }
3903
3904 if hdr.temporal_mvp_enabled_flag {
3905 if hdr.type_.is_b() {
3906 hdr.collocated_from_l0_flag = r.read_bit()?;
3907 }
3908
3909 if (hdr.collocated_from_l0_flag && hdr.num_ref_idx_l0_active_minus1 > 0)
3910 || (!hdr.collocated_from_l0_flag && hdr.num_ref_idx_l1_active_minus1 > 0)
3911 {
3912 let max = if (hdr.type_.is_p() || hdr.type_.is_b())
3913 && hdr.collocated_from_l0_flag
3914 {
3915 hdr.num_ref_idx_l0_active_minus1
3916 } else if hdr.type_.is_b() && !hdr.collocated_from_l0_flag {
3917 hdr.num_ref_idx_l1_active_minus1
3918 } else {
3919 return Err(anyhow!("Invalid value for collocated_ref_idx"));
3920 };
3921
3922 {
3923 hdr.collocated_ref_idx = r.read_ue_max(u32::from(max))?;
3924 }
3925 }
3926 }
3927
3928 if (pps.weighted_pred_flag && hdr.type_.is_p())
3929 || (pps.weighted_bipred_flag && hdr.type_.is_b())
3930 {
3931 Self::parse_pred_weight_table(&mut hdr, &mut r, sps)?;
3932 }
3933
3934 hdr.five_minus_max_num_merge_cand = r.read_ue()?;
3935
3936 if sps.scc_extension.motion_vector_resolution_control_idc == 2 {
3937 hdr.use_integer_mv_flag = r.read_bit()?;
3938 }
3939 }
3940
3941 hdr.qp_delta = r.read_se_bounded(-87, 77)?;
3942
3943 let slice_qp_y = (26 + pps.init_qp_minus26 + hdr.qp_delta) as i32;
3944 if slice_qp_y < -(pps.qp_bd_offset_y as i32) || slice_qp_y > 51 {
3945 return Err(anyhow!("Invalid slice_qp_delta: {}", hdr.qp_delta));
3946 }
3947
3948 if pps.slice_chroma_qp_offsets_present_flag {
3949 hdr.cb_qp_offset = r.read_se_bounded(-12, 12)?;
3950
3951 let qp_offset = pps.cb_qp_offset + hdr.cb_qp_offset;
3952 if !(-12..=12).contains(&qp_offset) {
3953 return Err(anyhow!(
3954 "Invalid value for slice_cb_qp_offset: {}",
3955 hdr.cb_qp_offset
3956 ));
3957 }
3958
3959 hdr.cr_qp_offset = r.read_se_bounded(-12, 12)?;
3960
3961 let qp_offset = pps.cr_qp_offset + hdr.cr_qp_offset;
3962 if !(-12..=12).contains(&qp_offset) {
3963 return Err(anyhow!(
3964 "Invalid value for slice_cr_qp_offset: {}",
3965 hdr.cr_qp_offset
3966 ));
3967 }
3968 }
3969
3970 if pps.scc_extension.slice_act_qp_offsets_present_flag {
3971 hdr.slice_act_y_qp_offset = r.read_se_bounded(-12, 12)?;
3972 hdr.slice_act_cb_qp_offset = r.read_se_bounded(-12, 12)?;
3973 hdr.slice_act_cr_qp_offset = r.read_se_bounded(-12, 12)?;
3974 }
3975
3976 if pps.range_extension.chroma_qp_offset_list_enabled_flag {
3977 hdr.cu_chroma_qp_offset_enabled_flag = r.read_bit()?;
3978 }
3979
3980 if pps.deblocking_filter_override_enabled_flag {
3981 hdr.deblocking_filter_override_flag = r.read_bit()?;
3982 }
3983
3984 if hdr.deblocking_filter_override_flag {
3985 hdr.deblocking_filter_disabled_flag = r.read_bit()?;
3986 if !hdr.deblocking_filter_disabled_flag {
3987 hdr.beta_offset_div2 = r.read_se_bounded(-6, 6)?;
3988 hdr.tc_offset_div2 = r.read_se_bounded(-6, 6)?;
3989 }
3990 }
3991
3992 if pps.loop_filter_across_slices_enabled_flag
3993 && (hdr.sao_luma_flag
3994 || hdr.sao_chroma_flag
3995 || !hdr.deblocking_filter_disabled_flag)
3996 {
3997 hdr.loop_filter_across_slices_enabled_flag = r.read_bit()?;
3998 }
3999 }
4000
4001 if pps.tiles_enabled_flag || pps.entropy_coding_sync_enabled_flag {
4002 let max = if !pps.tiles_enabled_flag && pps.entropy_coding_sync_enabled_flag {
4003 sps.pic_height_in_ctbs_y - 1
4004 } else if pps.tiles_enabled_flag && !pps.entropy_coding_sync_enabled_flag {
4005 u32::from((pps.num_tile_columns_minus1 + 1) * (pps.num_tile_rows_minus1 + 1) - 1)
4006 } else {
4007 (u32::from(pps.num_tile_columns_minus1) + 1) * sps.pic_height_in_ctbs_y - 1
4008 };
4009
4010 hdr.num_entry_point_offsets = r.read_ue_max(max)?;
4011 if hdr.num_entry_point_offsets > 0 {
4012 hdr.offset_len_minus1 = r.read_ue_max(31)?;
4013 for i in 0..hdr.num_entry_point_offsets as usize {
4014 let num_bits = usize::from(hdr.offset_len_minus1 + 1);
4015 hdr.entry_point_offset_minus1[i] = r.read_bits(num_bits)?;
4016 }
4017 }
4018 }
4019
4020 if pps.slice_segment_header_extension_present_flag {
4021 let segment_header_extension_length = r.read_ue_max(256)?;
4022 for _ in 0..segment_header_extension_length {
4023 r.skip_bits(8)?; }
4025 }
4026
4027 r.skip_bits(1)?; let num_bits = r.num_bits_left() % 8;
4030 r.skip_bits(num_bits)?;
4031
4032 let epb = r.num_epb();
4033 hdr.header_bit_size = ((nalu.size - epb) * 8 - r.num_bits_left()) as u32;
4034
4035 hdr.n_emulation_prevention_bytes = epb as u32;
4036
4037 log::debug!(
4038 "Parsed slice {:?}, NAL size was {}",
4039 nalu_header.type_,
4040 nalu.size
4041 );
4042
4043 Ok(Slice { header: hdr, nalu })
4044 }
4045
4046 pub fn get_vps(&self, vps_id: u8) -> Option<&Vps> {
4048 self.active_vpses.get(&vps_id)
4049 }
4050
4051 pub fn get_sps(&self, sps_id: u8) -> Option<&Sps> {
4053 self.active_spses.get(&sps_id)
4054 }
4055
4056 pub fn get_pps(&self, pps_id: u8) -> Option<&Pps> {
4058 self.active_ppses.get(&pps_id)
4059 }
4060}
4061
4062#[cfg(test)]
4063mod tests {
4064 use std::io::Cursor;
4065
4066 use crate::codec::h264::nalu::Nalu;
4067 use crate::codec::h265::parser::Level;
4068 use crate::codec::h265::parser::NaluHeader;
4069 use crate::codec::h265::parser::NaluType;
4070 use crate::codec::h265::parser::Parser;
4071 use crate::codec::h265::parser::SliceType;
4072
4073 const STREAM_BEAR: &[u8] = include_bytes!("test_data/bear.h265");
4074 const STREAM_BEAR_NUM_NALUS: usize = 35;
4075
4076 const STREAM_BBB: &[u8] = include_bytes!("test_data/bbb.h265");
4077 const STREAM_BBB_NUM_NALUS: usize = 64;
4078
4079 const STREAM_TEST25FPS: &[u8] = include_bytes!("test_data/test-25fps.h265");
4080 const STREAM_TEST25FPS_NUM_NALUS: usize = 254;
4081
4082 const STREAM_TEST_25_FPS_SLICE_0: &[u8] =
4083 include_bytes!("test_data/test-25fps-h265-slice-data-0.bin");
4084 const STREAM_TEST_25_FPS_SLICE_1: &[u8] =
4085 include_bytes!("test_data/test-25fps-h265-slice-data-1.bin");
4086
4087 fn dispatch_parse_call(parser: &mut Parser, nalu: Nalu<NaluHeader>) -> anyhow::Result<()> {
4088 match nalu.header.type_ {
4089 NaluType::TrailN
4090 | NaluType::TrailR
4091 | NaluType::TsaN
4092 | NaluType::TsaR
4093 | NaluType::StsaN
4094 | NaluType::StsaR
4095 | NaluType::RadlN
4096 | NaluType::RadlR
4097 | NaluType::RaslN
4098 | NaluType::RaslR
4099 | NaluType::BlaWLp
4100 | NaluType::BlaWRadl
4101 | NaluType::BlaNLp
4102 | NaluType::IdrWRadl
4103 | NaluType::IdrNLp
4104 | NaluType::CraNut => {
4105 parser.parse_slice_header(nalu).unwrap();
4106 }
4107 NaluType::VpsNut => {
4108 parser.parse_vps(&nalu).unwrap();
4109 }
4110 NaluType::SpsNut => {
4111 parser.parse_sps(&nalu).unwrap();
4112 }
4113 NaluType::PpsNut => {
4114 parser.parse_pps(&nalu).unwrap();
4115 }
4116 _ => { }
4117 }
4118 Ok(())
4119 }
4120
4121 fn find_nalu_by_type(
4122 bitstream: &[u8],
4123 nalu_type: NaluType,
4124 mut nskip: i32,
4125 ) -> Option<Nalu<NaluHeader>> {
4126 let mut cursor = Cursor::new(bitstream);
4127 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4128 if nalu.header.type_ == nalu_type {
4129 if nskip == 0 {
4130 return Some(nalu);
4131 } else {
4132 nskip -= 1;
4133 }
4134 }
4135 }
4136
4137 None
4138 }
4139
4140 #[test]
4142 fn parse_nalus_from_stream_file() {
4143 let mut cursor = Cursor::new(STREAM_BEAR);
4144 let mut num_nalus = 0;
4145 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() {
4146 num_nalus += 1;
4147 }
4148
4149 assert_eq!(num_nalus, STREAM_BEAR_NUM_NALUS);
4150
4151 let mut cursor = Cursor::new(STREAM_BBB);
4152 let mut num_nalus = 0;
4153 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() {
4154 num_nalus += 1;
4155 }
4156
4157 assert_eq!(num_nalus, STREAM_BBB_NUM_NALUS);
4158
4159 let mut cursor = Cursor::new(STREAM_TEST25FPS);
4160 let mut num_nalus = 0;
4161 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() {
4162 num_nalus += 1;
4163 }
4164
4165 assert_eq!(num_nalus, STREAM_TEST25FPS_NUM_NALUS);
4166 }
4167
4168 #[test]
4171 fn parse_syntax_from_nals() {
4172 let mut cursor = Cursor::new(STREAM_BBB);
4173 let mut parser = Parser::default();
4174
4175 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4176 dispatch_parse_call(&mut parser, nalu).unwrap();
4177 }
4178
4179 let mut cursor = Cursor::new(STREAM_BEAR);
4180 let mut parser = Parser::default();
4181
4182 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4183 dispatch_parse_call(&mut parser, nalu).unwrap();
4184 }
4185
4186 let mut cursor = Cursor::new(STREAM_TEST25FPS);
4187 let mut parser = Parser::default();
4188
4189 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4190 dispatch_parse_call(&mut parser, nalu).unwrap();
4191 }
4192 }
4193
4194 #[test]
4196 fn chromium_vps_parsing() {
4197 let mut cursor = Cursor::new(STREAM_BEAR);
4198 let mut parser = Parser::default();
4199
4200 let vps_nalu = Nalu::<NaluHeader>::next(&mut cursor).unwrap();
4201 let vps = parser.parse_vps(&vps_nalu).unwrap();
4202
4203 assert!(vps.base_layer_internal_flag);
4204 assert!(vps.base_layer_available_flag);
4205 assert_eq!(vps.max_layers_minus1, 0);
4206 assert_eq!(vps.max_sub_layers_minus1, 0);
4207 assert!(vps.temporal_id_nesting_flag);
4208 assert_eq!(vps.profile_tier_level.general_profile_idc, 1);
4209 assert_eq!(vps.profile_tier_level.general_level_idc, Level::L2);
4210 assert_eq!(vps.max_dec_pic_buffering_minus1[0], 4);
4211 assert_eq!(vps.max_num_reorder_pics[0], 2);
4212 assert_eq!(vps.max_latency_increase_plus1[0], 0);
4213 for i in 1..7 {
4214 assert_eq!(vps.max_dec_pic_buffering_minus1[i], 0);
4215 assert_eq!(vps.max_num_reorder_pics[i], 0);
4216 assert_eq!(vps.max_latency_increase_plus1[i], 0);
4217 }
4218 assert_eq!(vps.max_layer_id, 0);
4219 assert_eq!(vps.num_layer_sets_minus1, 0);
4220 assert!(!vps.timing_info_present_flag);
4221 }
4222
4223 #[test]
4225 fn chromium_sps_parsing() {
4226 let mut parser = Parser::default();
4227 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap();
4228 let sps = parser.parse_sps(&sps_nalu).unwrap();
4229
4230 assert_eq!(sps.max_sub_layers_minus1, 0);
4231 assert_eq!(sps.profile_tier_level.general_profile_idc, 1);
4232 assert_eq!(sps.profile_tier_level.general_level_idc, Level::L2);
4233 assert_eq!(sps.seq_parameter_set_id, 0);
4234 assert_eq!(sps.chroma_format_idc, 1);
4235 assert!(!sps.separate_colour_plane_flag);
4236 assert_eq!(sps.pic_width_in_luma_samples, 320);
4237 assert_eq!(sps.pic_height_in_luma_samples, 184);
4238 assert_eq!(sps.conf_win_left_offset, 0);
4239 assert_eq!(sps.conf_win_right_offset, 0);
4240 assert_eq!(sps.conf_win_top_offset, 0);
4241 assert_eq!(sps.conf_win_bottom_offset, 2);
4242 assert_eq!(sps.bit_depth_luma_minus8, 0);
4243 assert_eq!(sps.bit_depth_chroma_minus8, 0);
4244 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 4);
4245 assert_eq!(sps.max_dec_pic_buffering_minus1[0], 4);
4246 assert_eq!(sps.max_num_reorder_pics[0], 2);
4247 assert_eq!(sps.max_latency_increase_plus1[0], 0);
4248 for i in 1..7 {
4249 assert_eq!(sps.max_dec_pic_buffering_minus1[i], 0);
4250 assert_eq!(sps.max_num_reorder_pics[i], 0);
4251 assert_eq!(sps.max_latency_increase_plus1[i], 0);
4252 }
4253 assert_eq!(sps.log2_min_luma_coding_block_size_minus3, 0);
4254 assert_eq!(sps.log2_diff_max_min_luma_coding_block_size, 3);
4255 assert_eq!(sps.log2_min_luma_transform_block_size_minus2, 0);
4256 assert_eq!(sps.log2_diff_max_min_luma_transform_block_size, 3);
4257 assert_eq!(sps.max_transform_hierarchy_depth_inter, 0);
4258 assert_eq!(sps.max_transform_hierarchy_depth_intra, 0);
4259 assert!(!sps.scaling_list_enabled_flag);
4260 assert!(!sps.scaling_list_data_present_flag);
4261 assert!(!sps.amp_enabled_flag);
4262 assert!(sps.sample_adaptive_offset_enabled_flag);
4263 assert!(!sps.pcm_enabled_flag);
4264 assert_eq!(sps.pcm_sample_bit_depth_luma_minus1, 0);
4265 assert_eq!(sps.pcm_sample_bit_depth_chroma_minus1, 0);
4266 assert_eq!(sps.log2_min_pcm_luma_coding_block_size_minus3, 0);
4267 assert_eq!(sps.log2_diff_max_min_pcm_luma_coding_block_size, 0);
4268 assert!(!sps.pcm_loop_filter_disabled_flag);
4269 assert_eq!(sps.num_short_term_ref_pic_sets, 0);
4270 assert_eq!(sps.num_long_term_ref_pics_sps, 0);
4271 assert!(sps.temporal_mvp_enabled_flag);
4272 assert!(sps.strong_intra_smoothing_enabled_flag);
4273 assert_eq!(sps.vui_parameters.sar_width, 0);
4274 assert_eq!(sps.vui_parameters.sar_height, 0);
4275 assert!(!sps.vui_parameters.video_full_range_flag);
4276 assert!(!sps.vui_parameters.colour_description_present_flag);
4277
4278 assert_eq!(sps.vui_parameters.colour_primaries, 2);
4281 assert_eq!(sps.vui_parameters.transfer_characteristics, 2);
4282 assert_eq!(sps.vui_parameters.matrix_coeffs, 2);
4283
4284 assert_eq!(sps.vui_parameters.def_disp_win_left_offset, 0);
4285 assert_eq!(sps.vui_parameters.def_disp_win_right_offset, 0);
4286 assert_eq!(sps.vui_parameters.def_disp_win_top_offset, 0);
4287 assert_eq!(sps.vui_parameters.def_disp_win_bottom_offset, 0);
4288 }
4289
4290 #[test]
4292 fn chromium_pps_parsing() {
4293 let mut parser = Parser::default();
4294
4295 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap();
4297 parser.parse_sps(&sps_nalu).unwrap();
4298
4299 let pps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::PpsNut, 0).unwrap();
4300 let pps = parser.parse_pps(&pps_nalu).unwrap();
4301
4302 assert_eq!(pps.pic_parameter_set_id, 0);
4303 assert_eq!(pps.seq_parameter_set_id, 0);
4304 assert!(!pps.dependent_slice_segments_enabled_flag);
4305 assert!(!pps.output_flag_present_flag);
4306 assert_eq!(pps.num_extra_slice_header_bits, 0);
4307 assert!(pps.sign_data_hiding_enabled_flag);
4308 assert!(!pps.cabac_init_present_flag);
4309 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0);
4310 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0);
4311 assert_eq!(pps.init_qp_minus26, 0);
4312 assert!(!pps.constrained_intra_pred_flag);
4313 assert!(!pps.transform_skip_enabled_flag);
4314 assert!(pps.cu_qp_delta_enabled_flag);
4315 assert_eq!(pps.diff_cu_qp_delta_depth, 0);
4316 assert_eq!(pps.cb_qp_offset, 0);
4317 assert_eq!(pps.cr_qp_offset, 0);
4318 assert!(!pps.slice_chroma_qp_offsets_present_flag);
4319 assert!(pps.weighted_pred_flag);
4320 assert!(!pps.weighted_bipred_flag);
4321 assert!(!pps.transquant_bypass_enabled_flag);
4322 assert!(!pps.tiles_enabled_flag);
4323 assert!(pps.entropy_coding_sync_enabled_flag);
4324 assert!(pps.loop_filter_across_tiles_enabled_flag);
4325 assert!(!pps.scaling_list_data_present_flag);
4326 assert!(!pps.lists_modification_present_flag);
4327 assert_eq!(pps.log2_parallel_merge_level_minus2, 0);
4328 assert!(!pps.slice_segment_header_extension_present_flag);
4329 }
4330
4331 #[test]
4333 fn chromium_slice_header_parsing() {
4334 let mut parser = Parser::default();
4335
4336 let vps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::VpsNut, 0).unwrap();
4338 parser.parse_vps(&vps_nalu).unwrap();
4339
4340 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap();
4341 parser.parse_sps(&sps_nalu).unwrap();
4342
4343 let pps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::PpsNut, 0).unwrap();
4344 parser.parse_pps(&pps_nalu).unwrap();
4345
4346 let slice_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::IdrWRadl, 0).unwrap();
4348 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4349 let hdr = &slice.header;
4350 assert!(hdr.first_slice_segment_in_pic_flag);
4351 assert!(!hdr.no_output_of_prior_pics_flag);
4352 assert_eq!(hdr.pic_parameter_set_id, 0);
4353 assert!(!hdr.dependent_slice_segment_flag);
4354 assert_eq!(hdr.type_, SliceType::I);
4355 assert!(hdr.sao_luma_flag);
4356 assert!(hdr.sao_chroma_flag);
4357 assert_eq!(hdr.qp_delta, 8);
4358 assert!(hdr.loop_filter_across_slices_enabled_flag);
4359
4360 let slice_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::TrailR, 0).unwrap();
4361 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4362 let hdr = &slice.header;
4363 assert!(hdr.first_slice_segment_in_pic_flag);
4364 assert_eq!(hdr.pic_parameter_set_id, 0);
4365 assert!(!hdr.dependent_slice_segment_flag);
4366 assert_eq!(hdr.type_, SliceType::P);
4367 assert_eq!(hdr.pic_order_cnt_lsb, 4);
4368 assert!(!hdr.short_term_ref_pic_set_sps_flag);
4369 assert_eq!(hdr.short_term_ref_pic_set.num_negative_pics, 1);
4370 assert_eq!(hdr.short_term_ref_pic_set.num_positive_pics, 0);
4371 assert_eq!(hdr.short_term_ref_pic_set.delta_poc_s0[0], -4);
4372 assert!(hdr.short_term_ref_pic_set.used_by_curr_pic_s0[0]);
4373 assert!(hdr.temporal_mvp_enabled_flag);
4374 assert!(hdr.sao_luma_flag);
4375 assert!(hdr.sao_chroma_flag);
4376 assert!(!hdr.num_ref_idx_active_override_flag);
4377 assert_eq!(hdr.pred_weight_table.luma_log2_weight_denom, 0);
4378 assert_eq!(hdr.pred_weight_table.delta_chroma_log2_weight_denom, 7);
4379 assert_eq!(hdr.pred_weight_table.delta_luma_weight_l0[0], 0);
4380 assert_eq!(hdr.pred_weight_table.luma_offset_l0[0], -2);
4381 assert_eq!(hdr.pred_weight_table.delta_chroma_weight_l0[0][0], -9);
4382 assert_eq!(hdr.pred_weight_table.delta_chroma_weight_l0[0][1], -9);
4383 assert_eq!(hdr.pred_weight_table.delta_chroma_offset_l0[0][0], 0);
4384 assert_eq!(hdr.pred_weight_table.delta_chroma_offset_l0[0][1], 0);
4385 assert_eq!(hdr.five_minus_max_num_merge_cand, 3);
4386 assert_eq!(hdr.qp_delta, 8);
4387 assert!(hdr.loop_filter_across_slices_enabled_flag);
4388 }
4389
4390 #[test]
4393 fn test25fps_vps_header_parsing() {
4394 let mut cursor = Cursor::new(STREAM_TEST25FPS);
4395 let mut parser = Parser::default();
4396
4397 let vps_nalu = Nalu::<NaluHeader>::next(&mut cursor).unwrap();
4398 let vps = parser.parse_vps(&vps_nalu).unwrap();
4399 assert!(vps.base_layer_internal_flag);
4400 assert!(vps.base_layer_available_flag);
4401 assert_eq!(vps.max_layers_minus1, 0);
4402 assert_eq!(vps.max_sub_layers_minus1, 0);
4403 assert!(vps.temporal_id_nesting_flag);
4404 assert_eq!(vps.profile_tier_level.general_profile_space, 0);
4405 assert!(!vps.profile_tier_level.general_tier_flag);
4406 assert_eq!(vps.profile_tier_level.general_profile_idc, 1);
4407 for i in 0..32 {
4408 let val = i == 1 || i == 2;
4409 assert_eq!(
4410 vps.profile_tier_level.general_profile_compatibility_flag[i],
4411 val
4412 );
4413 }
4414 assert!(vps.profile_tier_level.general_progressive_source_flag);
4415 assert!(!vps.profile_tier_level.general_interlaced_source_flag);
4416 assert!(!vps.profile_tier_level.general_non_packed_constraint_flag,);
4417 assert!(vps.profile_tier_level.general_frame_only_constraint_flag,);
4418 assert!(!vps.profile_tier_level.general_max_12bit_constraint_flag,);
4419 assert!(!vps.profile_tier_level.general_max_10bit_constraint_flag,);
4420 assert!(!vps.profile_tier_level.general_max_8bit_constraint_flag,);
4421 assert!(!vps.profile_tier_level.general_max_422chroma_constraint_flag,);
4422 assert!(!vps.profile_tier_level.general_max_420chroma_constraint_flag,);
4423 assert!(
4424 !vps.profile_tier_level
4425 .general_max_monochrome_constraint_flag,
4426 );
4427 assert!(!vps.profile_tier_level.general_intra_constraint_flag);
4428 assert!(
4429 !vps.profile_tier_level
4430 .general_one_picture_only_constraint_flag,
4431 );
4432 assert!(
4433 !vps.profile_tier_level
4434 .general_lower_bit_rate_constraint_flag,
4435 );
4436 assert!(!vps.profile_tier_level.general_max_14bit_constraint_flag,);
4437 assert_eq!(vps.profile_tier_level.general_level_idc, Level::L2);
4438
4439 assert!(vps.sub_layer_ordering_info_present_flag);
4440 assert_eq!(vps.max_dec_pic_buffering_minus1[0], 4);
4441 assert_eq!(vps.max_num_reorder_pics[0], 2);
4442 assert_eq!(vps.max_latency_increase_plus1[0], 5);
4443 for i in 1..7 {
4444 assert_eq!(vps.max_dec_pic_buffering_minus1[i], 0);
4445 assert_eq!(vps.max_num_reorder_pics[i], 0);
4446 assert_eq!(vps.max_latency_increase_plus1[i], 0);
4447 }
4448
4449 assert_eq!(vps.max_layer_id, 0);
4450 assert_eq!(vps.num_layer_sets_minus1, 0);
4451 assert!(!vps.timing_info_present_flag);
4452 assert_eq!(vps.num_units_in_tick, 0);
4453 assert_eq!(vps.time_scale, 0);
4454 assert!(!vps.poc_proportional_to_timing_flag);
4455 assert_eq!(vps.num_ticks_poc_diff_one_minus1, 0);
4456 assert_eq!(vps.num_hrd_parameters, 0);
4457 }
4458
4459 #[test]
4462 fn test25fps_sps_header_parsing() {
4463 let mut parser = Parser::default();
4464
4465 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap();
4466 let sps = parser.parse_sps(&sps_nalu).unwrap();
4467
4468 assert_eq!(sps.max_sub_layers_minus1, 0);
4469
4470 assert_eq!(sps.profile_tier_level.general_profile_space, 0);
4471 assert!(!sps.profile_tier_level.general_tier_flag);
4472 assert_eq!(sps.profile_tier_level.general_profile_idc, 1);
4473 for i in 0..32 {
4474 let val = i == 1 || i == 2;
4475 assert_eq!(
4476 sps.profile_tier_level.general_profile_compatibility_flag[i],
4477 val
4478 );
4479 }
4480 assert!(sps.profile_tier_level.general_progressive_source_flag);
4481 assert!(!sps.profile_tier_level.general_interlaced_source_flag);
4482 assert!(!sps.profile_tier_level.general_non_packed_constraint_flag,);
4483 assert!(sps.profile_tier_level.general_frame_only_constraint_flag,);
4484 assert!(!sps.profile_tier_level.general_max_12bit_constraint_flag,);
4485 assert!(!sps.profile_tier_level.general_max_10bit_constraint_flag,);
4486 assert!(!sps.profile_tier_level.general_max_8bit_constraint_flag,);
4487 assert!(!sps.profile_tier_level.general_max_422chroma_constraint_flag,);
4488 assert!(!sps.profile_tier_level.general_max_420chroma_constraint_flag,);
4489 assert!(
4490 !sps.profile_tier_level
4491 .general_max_monochrome_constraint_flag,
4492 );
4493 assert!(!sps.profile_tier_level.general_intra_constraint_flag);
4494 assert!(
4495 !sps.profile_tier_level
4496 .general_one_picture_only_constraint_flag,
4497 );
4498 assert!(
4499 !sps.profile_tier_level
4500 .general_lower_bit_rate_constraint_flag,
4501 );
4502 assert!(!sps.profile_tier_level.general_max_14bit_constraint_flag,);
4503 assert_eq!(sps.profile_tier_level.general_level_idc, Level::L2);
4504
4505 assert_eq!(sps.seq_parameter_set_id, 0);
4506 assert_eq!(sps.chroma_format_idc, 1);
4507 assert!(!sps.separate_colour_plane_flag);
4508 assert_eq!(sps.pic_width_in_luma_samples, 320);
4509 assert_eq!(sps.pic_height_in_luma_samples, 240);
4510 assert_eq!(sps.conf_win_left_offset, 0);
4511 assert_eq!(sps.conf_win_right_offset, 0);
4512 assert_eq!(sps.conf_win_top_offset, 0);
4513 assert_eq!(sps.conf_win_bottom_offset, 0);
4514 assert_eq!(sps.bit_depth_luma_minus8, 0);
4515 assert_eq!(sps.bit_depth_chroma_minus8, 0);
4516 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 4);
4517 assert!(sps.sub_layer_ordering_info_present_flag);
4518 assert_eq!(sps.max_dec_pic_buffering_minus1[0], 4);
4519 assert_eq!(sps.max_num_reorder_pics[0], 2);
4520 assert_eq!(sps.max_latency_increase_plus1[0], 5);
4521 for i in 1..7 {
4522 assert_eq!(sps.max_dec_pic_buffering_minus1[i], 0);
4523 assert_eq!(sps.max_num_reorder_pics[i], 0);
4524 assert_eq!(sps.max_latency_increase_plus1[i], 0);
4525 }
4526 assert_eq!(sps.log2_min_luma_coding_block_size_minus3, 0);
4527 assert_eq!(sps.log2_diff_max_min_luma_coding_block_size, 3);
4528 assert_eq!(sps.log2_min_luma_transform_block_size_minus2, 0);
4529 assert_eq!(sps.log2_diff_max_min_luma_transform_block_size, 3);
4530 assert_eq!(sps.max_transform_hierarchy_depth_inter, 0);
4531 assert_eq!(sps.max_transform_hierarchy_depth_intra, 0);
4532 assert!(!sps.scaling_list_enabled_flag);
4533 assert!(!sps.scaling_list_data_present_flag);
4534 assert!(!sps.amp_enabled_flag);
4535 assert!(sps.sample_adaptive_offset_enabled_flag);
4536 assert!(!sps.pcm_enabled_flag);
4537 assert_eq!(sps.pcm_sample_bit_depth_luma_minus1, 0);
4538 assert_eq!(sps.pcm_sample_bit_depth_chroma_minus1, 0);
4539 assert_eq!(sps.log2_min_pcm_luma_coding_block_size_minus3, 0);
4540 assert_eq!(sps.log2_diff_max_min_pcm_luma_coding_block_size, 0);
4541 assert!(!sps.pcm_loop_filter_disabled_flag);
4542 assert_eq!(sps.num_short_term_ref_pic_sets, 0);
4543 assert_eq!(sps.num_long_term_ref_pics_sps, 0);
4544 assert!(sps.temporal_mvp_enabled_flag);
4545 assert!(sps.strong_intra_smoothing_enabled_flag);
4546 assert_eq!(sps.vui_parameters.sar_width, 0);
4547 assert_eq!(sps.vui_parameters.sar_height, 0);
4548 assert!(!sps.vui_parameters.video_full_range_flag);
4549 assert!(!sps.vui_parameters.colour_description_present_flag);
4550 assert!(sps.vui_parameters.video_signal_type_present_flag);
4551 assert!(sps.vui_parameters.timing_info_present_flag);
4552 assert_eq!(sps.vui_parameters.num_units_in_tick, 1);
4553 assert_eq!(sps.vui_parameters.time_scale, 25);
4554 assert!(!sps.vui_parameters.poc_proportional_to_timing_flag);
4555 assert_eq!(sps.vui_parameters.num_ticks_poc_diff_one_minus1, 0);
4556 assert!(!sps.vui_parameters.hrd_parameters_present_flag);
4557 assert_eq!(sps.vui_parameters.colour_primaries, 2);
4558 assert_eq!(sps.vui_parameters.transfer_characteristics, 2);
4559 assert_eq!(sps.vui_parameters.matrix_coeffs, 2);
4560 assert_eq!(sps.vui_parameters.def_disp_win_left_offset, 0);
4561 assert_eq!(sps.vui_parameters.def_disp_win_right_offset, 0);
4562 assert_eq!(sps.vui_parameters.def_disp_win_top_offset, 0);
4563 assert_eq!(sps.vui_parameters.def_disp_win_bottom_offset, 0);
4564 }
4565
4566 #[test]
4569 fn test25fps_pps_header_parsing() {
4570 let mut parser = Parser::default();
4571
4572 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap();
4573 parser.parse_sps(&sps_nalu).unwrap();
4574
4575 let pps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::PpsNut, 0).unwrap();
4576 let pps = parser.parse_pps(&pps_nalu).unwrap();
4577
4578 assert!(!pps.dependent_slice_segments_enabled_flag);
4579 assert!(!pps.output_flag_present_flag);
4580 assert_eq!(pps.num_extra_slice_header_bits, 0);
4581 assert!(pps.sign_data_hiding_enabled_flag);
4582 assert!(!pps.cabac_init_present_flag);
4583 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0);
4584 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0);
4585 assert_eq!(pps.init_qp_minus26, 0);
4586 assert!(!pps.constrained_intra_pred_flag);
4587 assert!(!pps.transform_skip_enabled_flag);
4588 assert!(pps.cu_qp_delta_enabled_flag);
4589 assert_eq!(pps.diff_cu_qp_delta_depth, 1);
4590 assert_eq!(pps.cb_qp_offset, 0);
4591 assert_eq!(pps.cr_qp_offset, 0);
4592 assert!(!pps.slice_chroma_qp_offsets_present_flag);
4593 assert!(pps.weighted_pred_flag);
4594 assert!(!pps.weighted_bipred_flag);
4595 assert!(!pps.transquant_bypass_enabled_flag);
4596 assert!(!pps.tiles_enabled_flag);
4597 assert!(pps.entropy_coding_sync_enabled_flag);
4598 assert_eq!(pps.num_tile_rows_minus1, 0);
4599 assert_eq!(pps.num_tile_columns_minus1, 0);
4600 assert!(pps.uniform_spacing_flag);
4601 assert_eq!(pps.column_width_minus1, [0; 19]);
4602 assert_eq!(pps.row_height_minus1, [0; 21]);
4603 assert!(pps.loop_filter_across_slices_enabled_flag);
4604 assert!(pps.loop_filter_across_tiles_enabled_flag);
4605 assert!(!pps.deblocking_filter_control_present_flag);
4606 assert!(!pps.deblocking_filter_override_enabled_flag);
4607 assert!(!pps.deblocking_filter_disabled_flag);
4608 assert_eq!(pps.beta_offset_div2, 0);
4609 assert_eq!(pps.tc_offset_div2, 0);
4610 assert!(!pps.lists_modification_present_flag);
4611 assert_eq!(pps.log2_parallel_merge_level_minus2, 0);
4612 assert!(!pps.slice_segment_header_extension_present_flag);
4613 assert!(!pps.extension_present_flag);
4614 }
4615
4616 #[test]
4619 fn test25fps_slice_header_parsing() {
4620 let mut parser = Parser::default();
4621
4622 let vps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::VpsNut, 0).unwrap();
4624 parser.parse_vps(&vps_nalu).unwrap();
4625
4626 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap();
4627 parser.parse_sps(&sps_nalu).unwrap();
4628
4629 let pps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::PpsNut, 0).unwrap();
4630 parser.parse_pps(&pps_nalu).unwrap();
4631
4632 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::IdrNLp, 0).unwrap();
4633 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4634 let hdr = &slice.header;
4635
4636 assert!(hdr.first_slice_segment_in_pic_flag);
4637 assert!(!hdr.no_output_of_prior_pics_flag);
4638 assert!(!hdr.dependent_slice_segment_flag);
4639 assert_eq!(hdr.type_, SliceType::I);
4640 assert!(hdr.pic_output_flag);
4641 assert_eq!(hdr.colour_plane_id, 0);
4642 assert_eq!(hdr.pic_order_cnt_lsb, 0);
4643 assert!(!hdr.short_term_ref_pic_set_sps_flag);
4644 assert_eq!(hdr.lt_idx_sps, [0; 16]);
4645 assert_eq!(hdr.poc_lsb_lt, [0; 16]);
4646 assert_eq!(hdr.used_by_curr_pic_lt, [false; 16]);
4647 assert_eq!(hdr.delta_poc_msb_cycle_lt, [0; 16]);
4648 assert_eq!(hdr.delta_poc_msb_present_flag, [false; 16]);
4649 assert!(!hdr.temporal_mvp_enabled_flag);
4650 assert!(hdr.sao_luma_flag);
4651 assert!(hdr.sao_chroma_flag);
4652 assert!(!hdr.num_ref_idx_active_override_flag);
4653 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
4654 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
4655 assert!(!hdr.cabac_init_flag);
4656 assert!(hdr.collocated_from_l0_flag);
4657 assert_eq!(hdr.five_minus_max_num_merge_cand, 0);
4658 assert!(!hdr.use_integer_mv_flag);
4659 assert_eq!(hdr.qp_delta, 7);
4660 assert_eq!(hdr.cb_qp_offset, 0);
4661 assert_eq!(hdr.cr_qp_offset, 0);
4662 assert!(!hdr.cu_chroma_qp_offset_enabled_flag);
4663 assert!(!hdr.deblocking_filter_override_flag);
4664 assert!(!hdr.deblocking_filter_override_flag);
4665 assert_eq!(hdr.beta_offset_div2, 0);
4666 assert_eq!(hdr.tc_offset_div2, 0);
4667 assert!(hdr.loop_filter_across_slices_enabled_flag);
4668 assert_eq!(hdr.num_entry_point_offsets, 3);
4669 assert_eq!(hdr.offset_len_minus1, 11);
4670 assert_eq!(hdr.num_pic_total_curr, 0);
4671
4672 assert_eq!(hdr.header_bit_size - 16, 72);
4674
4675 assert_eq!(hdr.n_emulation_prevention_bytes, 0);
4676
4677 assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_0);
4678
4679 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::TrailR, 0).unwrap();
4681 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4682 let hdr = &slice.header;
4683
4684 assert!(hdr.first_slice_segment_in_pic_flag);
4685 assert!(!hdr.no_output_of_prior_pics_flag);
4686 assert!(!hdr.dependent_slice_segment_flag);
4687 assert_eq!(hdr.type_, SliceType::P);
4688 assert!(hdr.pic_output_flag);
4689 assert_eq!(hdr.colour_plane_id, 0);
4690 assert_eq!(hdr.pic_order_cnt_lsb, 3);
4691 assert!(!hdr.short_term_ref_pic_set_sps_flag);
4692 assert_eq!(hdr.short_term_ref_pic_set.num_delta_pocs, 1);
4693 assert_eq!(hdr.short_term_ref_pic_set.num_negative_pics, 1);
4694 assert_eq!(hdr.short_term_ref_pic_set.num_positive_pics, 0);
4695 assert!(hdr.short_term_ref_pic_set.used_by_curr_pic_s0[0]);
4696 assert_eq!(hdr.short_term_ref_pic_set.delta_poc_s0[0], -3);
4697 assert_eq!(hdr.lt_idx_sps, [0; 16]);
4698 assert_eq!(hdr.poc_lsb_lt, [0; 16]);
4699 assert_eq!(hdr.used_by_curr_pic_lt, [false; 16]);
4700 assert_eq!(hdr.delta_poc_msb_cycle_lt, [0; 16]);
4701 assert_eq!(hdr.delta_poc_msb_present_flag, [false; 16]);
4702 assert!(hdr.temporal_mvp_enabled_flag);
4703 assert!(hdr.sao_luma_flag);
4704 assert!(hdr.sao_chroma_flag);
4705 assert!(!hdr.num_ref_idx_active_override_flag);
4706 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
4707 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
4708 assert!(!hdr.cabac_init_flag);
4709 assert!(hdr.collocated_from_l0_flag);
4710 assert_eq!(hdr.pred_weight_table.luma_log2_weight_denom, 7);
4711 assert_eq!(hdr.five_minus_max_num_merge_cand, 2);
4712 assert!(!hdr.use_integer_mv_flag);
4713 assert_eq!(hdr.num_entry_point_offsets, 3);
4714 assert_eq!(hdr.qp_delta, 7);
4715 assert_eq!(hdr.cb_qp_offset, 0);
4716 assert_eq!(hdr.cr_qp_offset, 0);
4717 assert!(!hdr.cu_chroma_qp_offset_enabled_flag);
4718 assert!(!hdr.deblocking_filter_override_flag);
4719 assert!(!hdr.deblocking_filter_override_flag);
4720 assert_eq!(hdr.beta_offset_div2, 0);
4721 assert_eq!(hdr.tc_offset_div2, 0);
4722 assert!(!hdr.loop_filter_across_slices_enabled_flag);
4723 assert_eq!(hdr.num_entry_point_offsets, 3);
4724 assert_eq!(hdr.offset_len_minus1, 10);
4725 assert_eq!(hdr.num_pic_total_curr, 1);
4726
4727 assert_eq!(slice.nalu.size, 2983);
4728 assert_eq!(hdr.header_bit_size - 16, 96);
4730 assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_1);
4731
4732 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::TrailR, 1).unwrap();
4734 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4735 let hdr = &slice.header;
4736
4737 assert_eq!(slice.nalu.size, 290);
4738 assert_eq!(hdr.header_bit_size - 16, 80);
4740 }
4741}