1use std::collections::BTreeMap;
10use std::io::Read;
11use std::io::Seek;
12use std::io::SeekFrom;
13use std::rc::Rc;
14
15use crate::bitstream_utils::BitReader;
16use crate::codec::h264::nalu;
17use crate::codec::h264::nalu::Header;
18use crate::codec::h264::parser::Point;
19use crate::codec::h264::parser::Rect;
20
21const MAX_VPS_COUNT: usize = 16;
23const MAX_SPS_COUNT: usize = 16;
25const MAX_PPS_COUNT: usize = 64;
27const MAX_REF_IDX_ACTIVE: u32 = 15;
29
30const MAX_SHORT_TERM_REF_PIC_SETS: usize = 65;
41
42const MAX_LONG_TERM_REF_PIC_SETS: usize = 32;
44
45const DEFAULT_SCALING_LIST_0: [u8; 16] = [16; 16];
47
48const DEFAULT_SCALING_LIST_1: [u8; 64] = [
50 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
51 21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24, 25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
52 29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70, 65, 88, 88, 115,
53];
54
55const DEFAULT_SCALING_LIST_2: [u8; 64] = [
57 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
58 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
59 28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54, 54, 71, 71, 91,
60];
61
62#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
64pub enum NaluType {
65 #[default]
66 TrailN = 0,
67 TrailR = 1,
68 TsaN = 2,
69 TsaR = 3,
70 StsaN = 4,
71 StsaR = 5,
72 RadlN = 6,
73 RadlR = 7,
74 RaslN = 8,
75 RaslR = 9,
76 RsvVclN10 = 10,
77 RsvVclR11 = 11,
78 RsvVclN12 = 12,
79 RsvVclR13 = 13,
80 RsvVclN14 = 14,
81 RsvVclR15 = 15,
82 BlaWLp = 16,
83 BlaWRadl = 17,
84 BlaNLp = 18,
85 IdrWRadl = 19,
86 IdrNLp = 20,
87 CraNut = 21,
88 RsvIrapVcl22 = 22,
89 RsvIrapVcl23 = 23,
90 RsvVcl24 = 24,
91 RsvVcl25 = 25,
92 RsvVcl26 = 26,
93 RsvVcl27 = 27,
94 RsvVcl28 = 28,
95 RsvVcl29 = 29,
96 RsvVcl30 = 30,
97 RsvVcl31 = 31,
98 VpsNut = 32,
99 SpsNut = 33,
100 PpsNut = 34,
101 AudNut = 35,
102 EosNut = 36,
103 EobNut = 37,
104 FdNut = 38,
105 PrefixSeiNut = 39,
106 SuffixSeiNut = 40,
107 RsvNvcl41 = 41,
108 RsvNvcl42 = 42,
109 RsvNvcl43 = 43,
110 RsvNvcl44 = 44,
111 RsvNvcl45 = 45,
112 RsvNvcl46 = 46,
113 RsvNvcl47 = 47,
114}
115
116impl TryFrom<u32> for NaluType {
117 type Error = String;
118
119 fn try_from(value: u32) -> Result<Self, Self::Error> {
120 match value {
121 0 => Ok(NaluType::TrailN),
122 1 => Ok(NaluType::TrailR),
123 2 => Ok(NaluType::TsaN),
124 3 => Ok(NaluType::TsaR),
125 4 => Ok(NaluType::StsaN),
126 5 => Ok(NaluType::StsaR),
127 6 => Ok(NaluType::RadlN),
128 7 => Ok(NaluType::RadlR),
129 8 => Ok(NaluType::RaslN),
130 9 => Ok(NaluType::RaslR),
131 10 => Ok(NaluType::RsvVclN10),
132 11 => Ok(NaluType::RsvVclR11),
133 12 => Ok(NaluType::RsvVclN12),
134 13 => Ok(NaluType::RsvVclR13),
135 14 => Ok(NaluType::RsvVclN14),
136 15 => Ok(NaluType::RsvVclR15),
137 16 => Ok(NaluType::BlaWLp),
138 17 => Ok(NaluType::BlaWRadl),
139 18 => Ok(NaluType::BlaNLp),
140 19 => Ok(NaluType::IdrWRadl),
141 20 => Ok(NaluType::IdrNLp),
142 21 => Ok(NaluType::CraNut),
143 22 => Ok(NaluType::RsvIrapVcl22),
144 23 => Ok(NaluType::RsvIrapVcl23),
145 24 => Ok(NaluType::RsvVcl24),
146 25 => Ok(NaluType::RsvVcl25),
147 26 => Ok(NaluType::RsvVcl26),
148 27 => Ok(NaluType::RsvVcl27),
149 28 => Ok(NaluType::RsvVcl28),
150 29 => Ok(NaluType::RsvVcl29),
151 30 => Ok(NaluType::RsvVcl30),
152 31 => Ok(NaluType::RsvVcl31),
153 32 => Ok(NaluType::VpsNut),
154 33 => Ok(NaluType::SpsNut),
155 34 => Ok(NaluType::PpsNut),
156 35 => Ok(NaluType::AudNut),
157 36 => Ok(NaluType::EosNut),
158 37 => Ok(NaluType::EobNut),
159 38 => Ok(NaluType::FdNut),
160 39 => Ok(NaluType::PrefixSeiNut),
161 40 => Ok(NaluType::SuffixSeiNut),
162 41 => Ok(NaluType::RsvNvcl41),
163 42 => Ok(NaluType::RsvNvcl42),
164 43 => Ok(NaluType::RsvNvcl43),
165 44 => Ok(NaluType::RsvNvcl44),
166 45 => Ok(NaluType::RsvNvcl45),
167 46 => Ok(NaluType::RsvNvcl46),
168 47 => Ok(NaluType::RsvNvcl47),
169 _ => Err(format!("Invalid NaluType {}", value)),
170 }
171 }
172}
173
174impl NaluType {
175 pub fn is_idr(&self) -> bool {
177 matches!(self, Self::IdrWRadl | Self::IdrNLp)
178 }
179
180 pub fn is_irap(&self) -> bool {
182 let type_ = *self as u32;
183 type_ >= Self::BlaWLp as u32 && type_ <= Self::RsvIrapVcl23 as u32
184 }
185
186 pub fn is_bla(&self) -> bool {
188 let type_ = *self as u32;
189 type_ >= Self::BlaWLp as u32 && type_ <= Self::BlaNLp as u32
190 }
191
192 pub fn is_cra(&self) -> bool {
194 matches!(self, Self::CraNut)
195 }
196
197 pub fn is_radl(&self) -> bool {
199 matches!(self, Self::RadlN | Self::RadlR)
200 }
201
202 pub fn is_rasl(&self) -> bool {
204 matches!(self, Self::RaslN | Self::RaslR)
205 }
206
207 pub fn is_slnr(&self) -> bool {
209 matches!(
215 self,
216 Self::TrailN
217 | Self::TsaN
218 | Self::StsaN
219 | Self::RadlN
220 | Self::RaslN
221 | Self::RsvVclN10
222 | Self::RsvVclN12
223 | Self::RsvVclN14
224 )
225 }
226}
227
228#[derive(Clone, Debug, Default, PartialEq, Eq)]
229pub struct NaluHeader {
230 pub type_: NaluType,
232 pub nuh_layer_id: u8,
235 pub nuh_temporal_id_plus1: u8,
238}
239
240impl NaluHeader {
241 pub fn nuh_temporal_id(&self) -> u8 {
242 self.nuh_temporal_id_plus1.saturating_sub(1)
243 }
244}
245
246impl Header for NaluHeader {
247 fn parse<T: AsRef<[u8]>>(cursor: &mut std::io::Cursor<T>) -> Result<Self, String> {
248 let mut data = [0u8; 2];
249 cursor.read_exact(&mut data).map_err(|_| String::from("Broken Data"))?;
250 let mut r = BitReader::new(&data, false);
251 let _ = cursor.seek(SeekFrom::Current(-1 * data.len() as i64));
252
253 r.skip_bits(1)?;
255
256 Ok(Self {
257 type_: NaluType::try_from(r.read_bits::<u32>(6)?)?,
258 nuh_layer_id: r.read_bits::<u8>(6)?,
259 nuh_temporal_id_plus1: r.read_bits::<u8>(3)?,
260 })
261 }
262
263 fn is_end(&self) -> bool {
264 matches!(self.type_, NaluType::EosNut | NaluType::EobNut)
265 }
266
267 fn len(&self) -> usize {
268 2
270 }
271}
272
273pub type Nalu<'a> = nalu::Nalu<'a, NaluHeader>;
274
275#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
279pub enum Level {
280 #[default]
281 L1 = 30,
282 L2 = 60,
283 L2_1 = 63,
284 L3 = 90,
285 L3_1 = 93,
286 L4 = 120,
287 L4_1 = 123,
288 L5 = 150,
289 L5_1 = 153,
290 L5_2 = 156,
291 L6 = 180,
292 L6_1 = 183,
293 L6_2 = 186,
294}
295
296impl TryFrom<u8> for Level {
297 type Error = String;
298
299 fn try_from(value: u8) -> Result<Self, Self::Error> {
300 match value {
301 30 => Ok(Level::L1),
302 60 => Ok(Level::L2),
303 63 => Ok(Level::L2_1),
304 90 => Ok(Level::L3),
305 93 => Ok(Level::L3_1),
306 120 => Ok(Level::L4),
307 123 => Ok(Level::L4_1),
308 150 => Ok(Level::L5),
309 153 => Ok(Level::L5_1),
310 156 => Ok(Level::L5_2),
311 180 => Ok(Level::L6),
312 183 => Ok(Level::L6_1),
313 186 => Ok(Level::L6_2),
314 _ => Err(format!("Invalid Level {}", value)),
315 }
316 }
317}
318
319#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
321pub enum Profile {
322 #[default]
323 Main = 1,
324 Main10 = 2,
325 MainStill = 3,
326 RangeExtensions = 4,
327 HighThroughput = 5,
328 MultiviewMain = 6,
329 ScalableMain = 7,
330 ThreeDMain = 8,
331 ScreenContentCoding = 9,
332 ScalableRangeExtensions = 10,
333 HighThroughputScreenContentCoding = 11,
334}
335
336impl TryFrom<u8> for Profile {
337 type Error = String;
338
339 fn try_from(value: u8) -> Result<Self, Self::Error> {
340 match value {
341 1 => Ok(Profile::Main),
342 2 => Ok(Profile::Main10),
343 3 => Ok(Profile::MainStill),
344 4 => Ok(Profile::RangeExtensions),
345 5 => Ok(Profile::HighThroughput),
346 6 => Ok(Profile::MultiviewMain),
347 7 => Ok(Profile::ScalableMain),
348 8 => Ok(Profile::ThreeDMain),
349 9 => Ok(Profile::ScreenContentCoding),
350 10 => Ok(Profile::ScalableRangeExtensions),
351 11 => Ok(Profile::HighThroughputScreenContentCoding),
352 _ => Err(format!("Invalid Profile {}", value)),
353 }
354 }
355}
356
357#[derive(Clone, Debug, PartialEq, Eq)]
359pub struct Vps {
360 pub video_parameter_set_id: u8,
362 pub base_layer_internal_flag: bool,
366 pub base_layer_available_flag: bool,
368 pub max_layers_minus1: u8,
371 pub max_sub_layers_minus1: u8,
374 pub temporal_id_nesting_flag: bool,
378 pub profile_tier_level: ProfileTierLevel,
380 pub sub_layer_ordering_info_present_flag: bool,
389 pub max_dec_pic_buffering_minus1: [u32; 7],
393 pub max_num_reorder_pics: [u32; 7],
398 pub max_latency_increase_plus1: [u32; 7],
405 pub max_layer_id: u8,
408 pub num_layer_sets_minus1: u32,
411 pub timing_info_present_flag: bool,
415 pub num_units_in_tick: u32,
425 pub time_scale: u32,
429 pub poc_proportional_to_timing_flag: bool,
438 pub num_ticks_poc_diff_one_minus1: u32,
441 pub num_hrd_parameters: u32,
444 pub hrd_layer_set_idx: Vec<u16>,
448 pub cprms_present_flag: Vec<bool>,
457 pub hrd_parameters: Vec<HrdParams>,
459 pub extension_flag: bool,
467}
468
469impl Default for Vps {
470 fn default() -> Self {
471 Self {
472 video_parameter_set_id: Default::default(),
473 base_layer_internal_flag: Default::default(),
474 base_layer_available_flag: Default::default(),
475 max_layers_minus1: Default::default(),
476 max_sub_layers_minus1: Default::default(),
477 temporal_id_nesting_flag: Default::default(),
478 profile_tier_level: Default::default(),
479 sub_layer_ordering_info_present_flag: Default::default(),
480 max_dec_pic_buffering_minus1: Default::default(),
481 max_num_reorder_pics: Default::default(),
482 max_latency_increase_plus1: Default::default(),
483 max_layer_id: Default::default(),
484 num_layer_sets_minus1: Default::default(),
485 timing_info_present_flag: Default::default(),
486 num_units_in_tick: Default::default(),
487 time_scale: Default::default(),
488 poc_proportional_to_timing_flag: Default::default(),
489 num_ticks_poc_diff_one_minus1: Default::default(),
490 num_hrd_parameters: Default::default(),
491 hrd_layer_set_idx: Default::default(),
492 cprms_present_flag: vec![true],
493 hrd_parameters: Default::default(),
494 extension_flag: Default::default(),
495 }
496 }
497}
498
499#[derive(Clone, Debug, Default, PartialEq, Eq)]
500pub struct ProfileTierLevel {
501 pub general_profile_space: u8,
505 pub general_tier_flag: bool,
508 pub general_profile_idc: u8,
514 pub general_profile_compatibility_flag: [bool; 32],
519 pub general_progressive_source_flag: bool,
539 pub general_interlaced_source_flag: bool,
541 pub general_non_packed_constraint_flag: bool,
550 pub general_frame_only_constraint_flag: bool,
553 pub general_max_12bit_constraint_flag: bool,
555 pub general_max_10bit_constraint_flag: bool,
557 pub general_max_8bit_constraint_flag: bool,
559 pub general_max_422chroma_constraint_flag: bool,
561 pub general_max_420chroma_constraint_flag: bool,
563 pub general_max_monochrome_constraint_flag: bool,
565 pub general_intra_constraint_flag: bool,
567 pub general_lower_bit_rate_constraint_flag: bool,
569 pub general_max_14bit_constraint_flag: bool,
571 pub general_one_picture_only_constraint_flag: bool,
573 pub general_inbld_flag: bool,
579 pub general_level_idc: Level,
581 pub sub_layer_profile_present_flag: [bool; 6],
583 pub sub_layer_level_present_flag: [bool; 6],
585 pub sub_layer_profile_space: [u8; 6],
587 pub sub_layer_tier_flag: [bool; 6],
589 pub sub_layer_profile_idc: [u8; 6],
591 pub sub_layer_profile_compatibility_flag: [[bool; 32]; 6],
593 pub sub_layer_progressive_source_flag: [bool; 6],
595 pub sub_layer_interlaced_source_flag: [bool; 6],
597 pub sub_layer_non_packed_constraint_flag: [bool; 6],
599 pub sub_layer_frame_only_constraint_flag: [bool; 6],
601 pub sub_layer_max_12bit_constraint_flag: [bool; 6],
603 pub sub_layer_max_10bit_constraint_flag: [bool; 6],
605 pub sub_layer_max_8bit_constraint_flag: [bool; 6],
607 pub sub_layer_max_422chroma_constraint_flag: [bool; 6],
609 pub sub_layer_max_420chroma_constraint_flag: [bool; 6],
611 pub sub_layer_max_monochrome_constraint_flag: [bool; 6],
613 pub sub_layer_intra_constraint_flag: [bool; 6],
615 pub sub_layer_one_picture_only_constraint_flag: [bool; 6],
617 pub sub_layer_lower_bit_rate_constraint_flag: [bool; 6],
619 pub sub_layer_max_14bit_constraint_flag: [bool; 6],
621 pub sub_layer_inbld_flag: [bool; 6],
623 pub sub_layer_level_idc: [Level; 6],
625}
626
627impl ProfileTierLevel {
628 pub fn max_luma_ps(&self) -> u32 {
629 match self.general_level_idc {
631 Level::L1 => 36864,
632 Level::L2 => 122880,
633 Level::L2_1 => 245760,
634 Level::L3 => 552960,
635 Level::L3_1 => 983040,
636 Level::L4 | Level::L4_1 => 2228224,
637 Level::L5 | Level::L5_1 | Level::L5_2 => 8912896,
638 _ => 35651584,
639 }
640 }
641
642 pub fn max_dpb_pic_buf(&self) -> u32 {
643 if self.general_profile_idc >= 1 && self.general_profile_idc <= 5 {
644 6
645 } else {
646 7
647 }
648 }
649}
650
651#[derive(Clone, Debug, Default, PartialEq, Eq)]
652pub struct SpsRangeExtension {
653 pub transform_skip_rotation_enabled_flag: bool,
654 pub transform_skip_context_enabled_flag: bool,
655 pub implicit_rdpcm_enabled_flag: bool,
656 pub explicit_rdpcm_enabled_flag: bool,
657 pub extended_precision_processing_flag: bool,
658 pub intra_smoothing_disabled_flag: bool,
659 pub high_precision_offsets_enabled_flag: bool,
660 pub persistent_rice_adaptation_enabled_flag: bool,
661 pub cabac_bypass_alignment_enabled_flag: bool,
662}
663
664#[derive(Clone, Debug, PartialEq, Eq)]
665pub struct SpsSccExtension {
666 pub curr_pic_ref_enabled_flag: bool,
671 pub palette_mode_enabled_flag: bool,
675 pub palette_max_size: u8,
677 pub delta_palette_max_predictor_size: u8,
680 pub palette_predictor_initializers_present_flag: bool,
684 pub num_palette_predictor_initializer_minus1: u8,
687 pub palette_predictor_initializer: [[u32; 128]; 3],
691 pub motion_vector_resolution_control_idc: u8,
694 pub intra_boundary_filtering_disabled_flag: bool,
698}
699
700impl Default for SpsSccExtension {
701 fn default() -> Self {
702 Self {
703 curr_pic_ref_enabled_flag: Default::default(),
704 palette_mode_enabled_flag: Default::default(),
705 palette_max_size: Default::default(),
706 delta_palette_max_predictor_size: Default::default(),
707 palette_predictor_initializers_present_flag: Default::default(),
708 num_palette_predictor_initializer_minus1: Default::default(),
709 palette_predictor_initializer: [[0; 128]; 3],
710 motion_vector_resolution_control_idc: Default::default(),
711 intra_boundary_filtering_disabled_flag: Default::default(),
712 }
713 }
714}
715
716#[derive(Clone, Debug, Default, PartialEq, Eq)]
718pub struct Sps {
719 pub video_parameter_set_id: u8,
721 pub max_sub_layers_minus1: u8,
724 pub temporal_id_nesting_flag: bool,
728 pub profile_tier_level: ProfileTierLevel,
730 pub seq_parameter_set_id: u8,
733 pub chroma_format_idc: u8,
736 pub separate_colour_plane_flag: bool,
740 pub pic_width_in_luma_samples: u16,
742 pub pic_height_in_luma_samples: u16,
744 pub conformance_window_flag: bool,
748 pub conf_win_left_offset: u32,
753 pub conf_win_right_offset: u32,
754 pub conf_win_top_offset: u32,
755 pub conf_win_bottom_offset: u32,
756
757 pub bit_depth_luma_minus8: u8,
760 pub bit_depth_chroma_minus8: u8,
764 pub log2_max_pic_order_cnt_lsb_minus4: u8,
767 pub sub_layer_ordering_info_present_flag: bool,
774 pub max_dec_pic_buffering_minus1: [u8; 7],
778 pub max_num_reorder_pics: [u8; 7],
784 pub max_latency_increase_plus1: [u8; 7],
791 pub log2_min_luma_coding_block_size_minus3: u8,
794 pub log2_diff_max_min_luma_coding_block_size: u8,
797 pub log2_min_luma_transform_block_size_minus2: u8,
800 pub log2_diff_max_min_luma_transform_block_size: u8,
803 pub max_transform_hierarchy_depth_inter: u8,
806 pub max_transform_hierarchy_depth_intra: u8,
809 pub scaling_list_enabled_flag: bool,
813 pub scaling_list_data_present_flag: bool,
818 pub scaling_list: ScalingLists,
820 pub amp_enabled_flag: bool,
825 pub sample_adaptive_offset_enabled_flag: bool,
830 pub pcm_enabled_flag: bool,
837
838 pub pcm_sample_bit_depth_luma_minus1: u8,
840 pub pcm_sample_bit_depth_chroma_minus1: u8,
843 pub log2_min_pcm_luma_coding_block_size_minus3: u8,
846 pub log2_diff_max_min_pcm_luma_coding_block_size: u8,
849 pub pcm_loop_filter_disabled_flag: bool,
861 pub num_short_term_ref_pic_sets: u8,
864 pub short_term_ref_pic_set: Vec<ShortTermRefPicSet>,
866 pub long_term_ref_pics_present_flag: bool,
871
872 pub num_long_term_ref_pics_sps: u8,
876 pub lt_ref_pic_poc_lsb_sps: [u32; MAX_LONG_TERM_REF_PIC_SETS],
880 pub used_by_curr_pic_lt_sps_flag: [bool; MAX_LONG_TERM_REF_PIC_SETS],
886 pub temporal_mvp_enabled_flag: bool,
892 pub strong_intra_smoothing_enabled_flag: bool,
896 pub vui_parameters_present_flag: bool,
901 pub vui_parameters: VuiParams,
903 pub extension_present_flag: bool,
909
910 pub range_extension_flag: bool,
911 pub range_extension: SpsRangeExtension,
913 pub scc_extension_flag: bool,
917 pub scc_extension: SpsSccExtension,
919
920 pub min_cb_log2_size_y: u32,
923 pub ctb_log2_size_y: u32,
925 pub ctb_size_y: u32,
927 pub pic_height_in_ctbs_y: u32,
929 pub pic_width_in_ctbs_y: u32,
931 pub pic_size_in_ctbs_y: u32,
933 pub chroma_array_type: u8,
935 pub wp_offset_half_range_y: u32,
937 pub wp_offset_half_range_c: u32,
939 pub max_tb_log2_size_y: u32,
941 pub pic_size_in_samples_y: u32,
943
944 pub vps: Option<Rc<Vps>>,
946}
947
948impl Sps {
949 pub fn max_dpb_size(&self) -> usize {
950 let max_luma_ps = self.profile_tier_level.max_luma_ps();
951 let max_dpb_pic_buf = self.profile_tier_level.max_dpb_pic_buf();
952
953 let max = if self.pic_size_in_samples_y <= (max_luma_ps >> 2) {
955 std::cmp::min(4 * max_dpb_pic_buf, 16)
956 } else if self.pic_size_in_samples_y <= (max_luma_ps >> 1) {
957 std::cmp::min(2 * max_dpb_pic_buf, 16)
958 } else if self.pic_size_in_samples_y <= ((3 * max_luma_ps) >> 2) {
959 std::cmp::min(4 * max_dpb_pic_buf / 3, 16)
960 } else {
961 max_dpb_pic_buf
962 };
963
964 max as usize
965 }
966
967 pub fn width(&self) -> u16 {
968 self.pic_width_in_luma_samples
969 }
970
971 pub fn height(&self) -> u16 {
972 self.pic_height_in_luma_samples
973 }
974
975 pub fn visible_rectangle(&self) -> Rect<u32> {
976 if !self.conformance_window_flag {
981 return Rect {
982 min: Point { x: 0, y: 0 },
983 max: Point { x: u32::from(self.width()), y: u32::from(self.height()) },
984 };
985 }
986 const SUB_HEIGHT_C: [u32; 5] = [1, 2, 1, 1, 1];
987 const SUB_WIDTH_C: [u32; 5] = [1, 2, 2, 1, 1];
988
989 let crop_unit_y = SUB_HEIGHT_C[usize::from(self.chroma_array_type)];
990 let crop_unit_x = SUB_WIDTH_C[usize::from(self.chroma_array_type)];
991 let crop_left = crop_unit_x * self.conf_win_left_offset;
992 let crop_right = crop_unit_x * self.conf_win_right_offset;
993 let crop_top = crop_unit_y * self.conf_win_top_offset;
994 let crop_bottom = crop_unit_y * self.conf_win_bottom_offset;
995
996 Rect {
997 min: Point { x: crop_left, y: crop_top },
998 max: Point {
999 x: u32::from(self.width()) - crop_left - crop_right,
1000 y: u32::from(self.height()) - crop_top - crop_bottom,
1001 },
1002 }
1003 }
1004}
1005
1006#[derive(Clone, Debug, PartialEq, Eq)]
1007pub struct PpsSccExtension {
1008 pub curr_pic_ref_enabled_flag: bool,
1013 pub residual_adaptive_colour_transform_enabled_flag: bool,
1017 pub slice_act_qp_offsets_present_flag: bool,
1022 pub act_y_qp_offset_plus5: i8,
1024 pub act_cb_qp_offset_plus5: i8,
1026 pub act_cr_qp_offset_plus3: i8,
1028 pub palette_predictor_initializers_present_flag: bool,
1034 pub num_palette_predictor_initializers: u8,
1037 pub monochrome_palette_flag: bool,
1041 pub luma_bit_depth_entry_minus8: u8,
1044 pub chroma_bit_depth_entry_minus8: u8,
1047 pub palette_predictor_initializer: [[u8; 128]; 3],
1051}
1052
1053impl Default for PpsSccExtension {
1054 fn default() -> Self {
1055 Self {
1056 curr_pic_ref_enabled_flag: Default::default(),
1057 residual_adaptive_colour_transform_enabled_flag: Default::default(),
1058 slice_act_qp_offsets_present_flag: Default::default(),
1059 act_y_qp_offset_plus5: Default::default(),
1060 act_cb_qp_offset_plus5: Default::default(),
1061 act_cr_qp_offset_plus3: Default::default(),
1062 palette_predictor_initializers_present_flag: Default::default(),
1063 num_palette_predictor_initializers: Default::default(),
1064 monochrome_palette_flag: Default::default(),
1065 luma_bit_depth_entry_minus8: Default::default(),
1066 chroma_bit_depth_entry_minus8: Default::default(),
1067 palette_predictor_initializer: [[0; 128]; 3],
1068 }
1069 }
1070}
1071
1072#[derive(Clone, Debug, Default, PartialEq, Eq)]
1073pub struct PpsRangeExtension {
1074 pub log2_max_transform_skip_block_size_minus2: u32,
1081 pub cross_component_prediction_enabled_flag: bool,
1087 pub chroma_qp_offset_list_enabled_flag: bool,
1091 pub diff_cu_chroma_qp_offset_depth: u32,
1094 pub chroma_qp_offset_list_len_minus1: u32,
1098 pub cb_qp_offset_list: [i32; 6],
1100 pub cr_qp_offset_list: [i32; 6],
1102 pub log2_sao_offset_scale_luma: u32,
1105 pub log2_sao_offset_scale_chroma: u32,
1108}
1109
1110#[derive(Clone, Debug, PartialEq, Eq)]
1112pub struct Pps {
1113 pub pic_parameter_set_id: u8,
1115 pub seq_parameter_set_id: u8,
1117 pub dependent_slice_segments_enabled_flag: bool,
1123 pub output_flag_present_flag: bool,
1128 pub num_extra_slice_header_bits: u8,
1131 pub sign_data_hiding_enabled_flag: bool,
1134 pub cabac_init_present_flag: bool,
1138 pub num_ref_idx_l0_default_active_minus1: u8,
1141 pub num_ref_idx_l1_default_active_minus1: u8,
1144 pub init_qp_minus26: i8,
1149 pub constrained_intra_pred_flag: bool,
1156 pub transform_skip_enabled_flag: bool,
1160 pub cu_qp_delta_enabled_flag: bool,
1167
1168 pub diff_cu_qp_delta_depth: u8,
1173 pub cb_qp_offset: i8,
1176 pub cr_qp_offset: i8,
1179 pub slice_chroma_qp_offsets_present_flag: bool,
1185 pub weighted_pred_flag: bool,
1189 pub weighted_bipred_flag: bool,
1193 pub transquant_bypass_enabled_flag: bool,
1196 pub tiles_enabled_flag: bool,
1200 pub entropy_coding_sync_enabled_flag: bool,
1219 pub num_tile_columns_minus1: u8,
1222 pub num_tile_rows_minus1: u8,
1225 pub uniform_spacing_flag: bool,
1232 pub column_width_minus1: [u32; 19],
1235 pub row_height_minus1: [u32; 21],
1238 pub loop_filter_across_tiles_enabled_flag: bool,
1245 pub loop_filter_across_slices_enabled_flag: bool,
1252 pub deblocking_filter_control_present_flag: bool,
1256 pub deblocking_filter_override_enabled_flag: bool,
1261 pub deblocking_filter_disabled_flag: bool,
1268 pub beta_offset_div2: i8,
1274 pub tc_offset_div2: i8,
1280 pub scaling_list_data_present_flag: bool,
1287 pub scaling_list: ScalingLists,
1289 pub lists_modification_present_flag: bool,
1294 pub log2_parallel_merge_level_minus2: u8,
1300 pub slice_segment_header_extension_present_flag: bool,
1306 pub extension_present_flag: bool,
1312 pub range_extension_flag: bool,
1316 pub range_extension: PpsRangeExtension,
1318
1319 pub scc_extension_flag: bool,
1320 pub scc_extension: PpsSccExtension,
1322
1323 pub qp_bd_offset_y: u32,
1326
1327 pub sps: Rc<Sps>,
1329}
1330
1331#[derive(Clone, Debug, PartialEq, Eq)]
1332pub struct ScalingLists {
1333 pub scaling_list_dc_coef_minus8_16x16: [i16; 6],
1336 pub scaling_list_dc_coef_minus8_32x32: [i16; 6],
1339 pub scaling_list_4x4: [[u8; 16]; 6],
1341 pub scaling_list_8x8: [[u8; 64]; 6],
1343 pub scaling_list_16x16: [[u8; 64]; 6],
1345 pub scaling_list_32x32: [[u8; 64]; 6],
1347}
1348
1349impl Default for ScalingLists {
1350 fn default() -> Self {
1351 Self {
1352 scaling_list_dc_coef_minus8_16x16: Default::default(),
1353 scaling_list_dc_coef_minus8_32x32: Default::default(),
1354 scaling_list_4x4: Default::default(),
1355 scaling_list_8x8: [[0; 64]; 6],
1356 scaling_list_16x16: [[0; 64]; 6],
1357 scaling_list_32x32: [[0; 64]; 6],
1358 }
1359 }
1360}
1361
1362#[derive(Clone, Debug, Default, PartialEq, Eq)]
1363pub struct RefPicListModification {
1364 pub ref_pic_list_modification_flag_l0: bool,
1368 pub list_entry_l0: Vec<u32>,
1372 pub ref_pic_list_modification_flag_l1: bool,
1376 pub list_entry_l1: Vec<u32>,
1380}
1381
1382#[derive(Clone, Debug, Default, PartialEq, Eq)]
1383pub struct PredWeightTable {
1384 pub luma_log2_weight_denom: u8,
1386 pub delta_chroma_log2_weight_denom: i8,
1389 pub luma_weight_l0_flag: [bool; 15],
1394 pub chroma_weight_l0_flag: [bool; 15],
1399 pub delta_luma_weight_l0: [i8; 15],
1403 pub luma_offset_l0: [i8; 15],
1406 pub delta_chroma_weight_l0: [[i8; 2]; 15],
1410 pub delta_chroma_offset_l0: [[i16; 2]; 15],
1414
1415 pub luma_weight_l1_flag: [bool; 15],
1423 pub chroma_weight_l1_flag: [bool; 15],
1424 pub delta_luma_weight_l1: [i8; 15],
1425 pub luma_offset_l1: [i8; 15],
1426
1427 pub delta_chroma_weight_l1: [[i8; 2]; 15],
1428 pub delta_chroma_offset_l1: [[i16; 2]; 15],
1429
1430 pub chroma_log2_weight_denom: u8,
1433}
1434
1435#[derive(Clone, Debug, PartialEq, Eq)]
1436pub struct ShortTermRefPicSet {
1437 pub inter_ref_pic_set_prediction_flag: bool,
1441 pub delta_idx_minus1: u8,
1445 pub delta_rps_sign: bool,
1448 pub abs_delta_rps_minus1: u16,
1451 pub num_negative_pics: u8,
1455 pub num_positive_pics: u8,
1459 pub used_by_curr_pic_s0: [bool; MAX_SHORT_TERM_REF_PIC_SETS],
1461 pub used_by_curr_pic_s1: [bool; MAX_SHORT_TERM_REF_PIC_SETS],
1463 pub delta_poc_s0: [i32; MAX_SHORT_TERM_REF_PIC_SETS],
1465 pub delta_poc_s1: [i32; MAX_SHORT_TERM_REF_PIC_SETS],
1467 pub num_delta_pocs: u32,
1469}
1470
1471impl Default for ShortTermRefPicSet {
1472 fn default() -> Self {
1473 Self {
1474 inter_ref_pic_set_prediction_flag: Default::default(),
1475 delta_idx_minus1: Default::default(),
1476 delta_rps_sign: Default::default(),
1477 abs_delta_rps_minus1: Default::default(),
1478 num_negative_pics: Default::default(),
1479 num_positive_pics: Default::default(),
1480 used_by_curr_pic_s0: [false; MAX_SHORT_TERM_REF_PIC_SETS],
1481 used_by_curr_pic_s1: [false; MAX_SHORT_TERM_REF_PIC_SETS],
1482 delta_poc_s0: [0; MAX_SHORT_TERM_REF_PIC_SETS],
1483 delta_poc_s1: [0; MAX_SHORT_TERM_REF_PIC_SETS],
1484 num_delta_pocs: Default::default(),
1485 }
1486 }
1487}
1488
1489#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1490pub enum SliceType {
1492 B = 0,
1493 P = 1,
1494 I = 2,
1495}
1496
1497impl TryFrom<u32> for SliceType {
1498 type Error = String;
1499
1500 fn try_from(value: u32) -> Result<Self, Self::Error> {
1501 match value {
1502 0 => Ok(SliceType::B),
1503 1 => Ok(SliceType::P),
1504 2 => Ok(SliceType::I),
1505 _ => Err(format!("Invalid SliceType {}", value)),
1506 }
1507 }
1508}
1509
1510impl SliceType {
1511 pub fn is_p(&self) -> bool {
1513 matches!(self, SliceType::P)
1514 }
1515
1516 pub fn is_b(&self) -> bool {
1518 matches!(self, SliceType::B)
1519 }
1520
1521 pub fn is_i(&self) -> bool {
1523 matches!(self, SliceType::I)
1524 }
1525}
1526
1527impl Default for SliceType {
1528 fn default() -> Self {
1529 Self::P
1530 }
1531}
1532
1533#[derive(Clone, Debug, PartialEq, Eq)]
1534pub struct SliceHeader {
1535 pub first_slice_segment_in_pic_flag: bool,
1539 pub no_output_of_prior_pics_flag: bool,
1543 pub pic_parameter_set_id: u8,
1545 pub dependent_slice_segment_flag: bool,
1549 pub segment_address: u32,
1552 pub type_: SliceType,
1554 pub pic_output_flag: bool,
1557 pub colour_plane_id: u8,
1562 pub pic_order_cnt_lsb: u16,
1566 pub short_term_ref_pic_set_sps_flag: bool,
1574 pub short_term_ref_pic_set: ShortTermRefPicSet,
1576 pub short_term_ref_pic_set_idx: u8,
1581 pub num_long_term_sps: u8,
1585 pub num_long_term_pics: u8,
1588 pub lt_idx_sps: [u8; 16],
1592 pub poc_lsb_lt: [u32; 16],
1594 pub used_by_curr_pic_lt: [bool; 16],
1596 pub delta_poc_msb_present_flag: [bool; 16],
1598 pub delta_poc_msb_cycle_lt: [u32; 16],
1600 pub temporal_mvp_enabled_flag: bool,
1607 pub sao_luma_flag: bool,
1611 pub sao_chroma_flag: bool,
1615 pub num_ref_idx_active_override_flag: bool,
1621 pub num_ref_idx_l0_active_minus1: u8,
1624 pub num_ref_idx_l1_active_minus1: u8,
1627 pub ref_pic_list_modification: RefPicListModification,
1629 pub mvd_l1_zero_flag: bool,
1634 pub cabac_init_flag: bool,
1637 pub collocated_from_l0_flag: bool,
1642 pub collocated_ref_idx: u8,
1645 pub pred_weight_table: PredWeightTable,
1647 pub five_minus_max_num_merge_cand: u8,
1650 pub use_integer_mv_flag: bool,
1656 pub qp_delta: i8,
1660 pub cb_qp_offset: i8,
1663 pub cr_qp_offset: i8,
1666 pub slice_act_y_qp_offset: i8,
1669 pub slice_act_cb_qp_offset: i8,
1672 pub slice_act_cr_qp_offset: i8,
1675 pub cu_chroma_qp_offset_enabled_flag: bool,
1679 pub deblocking_filter_override_flag: bool,
1683 pub deblocking_filter_disabled_flag: bool,
1687 pub beta_offset_div2: i8,
1690 pub tc_offset_div2: i8,
1693 pub loop_filter_across_slices_enabled_flag: bool,
1699 pub num_entry_point_offsets: u32,
1702 pub offset_len_minus1: u8,
1705 pub entry_point_offset_minus1: [u32; 32],
1712 pub num_pic_total_curr: u32,
1714 pub header_bit_size: u32,
1716 pub n_emulation_prevention_bytes: u32,
1718 pub curr_rps_idx: u8,
1720 pub st_rps_bits: u32,
1722}
1723
1724impl Default for SliceHeader {
1725 fn default() -> Self {
1726 Self {
1727 first_slice_segment_in_pic_flag: Default::default(),
1728 no_output_of_prior_pics_flag: Default::default(),
1729 pic_parameter_set_id: Default::default(),
1730 dependent_slice_segment_flag: Default::default(),
1731 segment_address: Default::default(),
1732 type_: Default::default(),
1733 pic_output_flag: true,
1734 colour_plane_id: Default::default(),
1735 pic_order_cnt_lsb: Default::default(),
1736 short_term_ref_pic_set_sps_flag: Default::default(),
1737 short_term_ref_pic_set: Default::default(),
1738 short_term_ref_pic_set_idx: Default::default(),
1739 num_long_term_sps: Default::default(),
1740 num_long_term_pics: Default::default(),
1741 lt_idx_sps: Default::default(),
1742 poc_lsb_lt: Default::default(),
1743 used_by_curr_pic_lt: Default::default(),
1744 delta_poc_msb_present_flag: Default::default(),
1745 delta_poc_msb_cycle_lt: Default::default(),
1746 temporal_mvp_enabled_flag: Default::default(),
1747 sao_luma_flag: Default::default(),
1748 sao_chroma_flag: Default::default(),
1749 num_ref_idx_active_override_flag: Default::default(),
1750 num_ref_idx_l0_active_minus1: Default::default(),
1751 num_ref_idx_l1_active_minus1: Default::default(),
1752 ref_pic_list_modification: Default::default(),
1753 mvd_l1_zero_flag: Default::default(),
1754 cabac_init_flag: Default::default(),
1755 collocated_from_l0_flag: true,
1756 collocated_ref_idx: Default::default(),
1757 pred_weight_table: Default::default(),
1758 five_minus_max_num_merge_cand: Default::default(),
1759 use_integer_mv_flag: Default::default(),
1760 qp_delta: Default::default(),
1761 cb_qp_offset: Default::default(),
1762 cr_qp_offset: Default::default(),
1763 slice_act_y_qp_offset: Default::default(),
1764 slice_act_cb_qp_offset: Default::default(),
1765 slice_act_cr_qp_offset: Default::default(),
1766 cu_chroma_qp_offset_enabled_flag: Default::default(),
1767 deblocking_filter_override_flag: Default::default(),
1768 deblocking_filter_disabled_flag: Default::default(),
1769 beta_offset_div2: Default::default(),
1770 tc_offset_div2: Default::default(),
1771 loop_filter_across_slices_enabled_flag: Default::default(),
1772 num_entry_point_offsets: Default::default(),
1773 offset_len_minus1: Default::default(),
1774 entry_point_offset_minus1: Default::default(),
1775 num_pic_total_curr: Default::default(),
1776 header_bit_size: Default::default(),
1777 n_emulation_prevention_bytes: Default::default(),
1778 curr_rps_idx: Default::default(),
1779 st_rps_bits: Default::default(),
1780 }
1781 }
1782}
1783
1784pub struct Slice<'a> {
1787 pub header: SliceHeader,
1789 pub nalu: Nalu<'a>,
1791}
1792
1793impl<'a> Slice<'a> {
1794 pub fn replace_header(&mut self, header: SliceHeader) -> Result<(), String> {
1797 if !self.header.dependent_slice_segment_flag {
1798 Err("Replacing the slice header is only possible for dependent slices".into())
1799 } else {
1800 let first_slice_segment_in_pic_flag = self.header.first_slice_segment_in_pic_flag;
1801 let no_output_of_prior_pics_flag = self.header.no_output_of_prior_pics_flag;
1802 let pic_parameter_set_id = self.header.pic_parameter_set_id;
1803 let dependent_slice_segment_flag = self.header.dependent_slice_segment_flag;
1804 let segment_address = self.header.segment_address;
1805
1806 let offset_len_minus1 = self.header.offset_len_minus1;
1807 let entry_point_offset_minus1 = self.header.entry_point_offset_minus1;
1808 let num_pic_total_curr = self.header.num_pic_total_curr;
1809 let header_bit_size = self.header.header_bit_size;
1810 let n_emulation_prevention_bytes = self.header.n_emulation_prevention_bytes;
1811 let curr_rps_idx = self.header.curr_rps_idx;
1812 let st_rps_bits = self.header.st_rps_bits;
1813
1814 self.header = header;
1815
1816 self.header.first_slice_segment_in_pic_flag = first_slice_segment_in_pic_flag;
1817 self.header.no_output_of_prior_pics_flag = no_output_of_prior_pics_flag;
1818 self.header.pic_parameter_set_id = pic_parameter_set_id;
1819 self.header.dependent_slice_segment_flag = dependent_slice_segment_flag;
1820 self.header.segment_address = segment_address;
1821 self.header.offset_len_minus1 = offset_len_minus1;
1822 self.header.entry_point_offset_minus1 = entry_point_offset_minus1;
1823 self.header.num_pic_total_curr = num_pic_total_curr;
1824 self.header.header_bit_size = header_bit_size;
1825 self.header.n_emulation_prevention_bytes = n_emulation_prevention_bytes;
1826 self.header.curr_rps_idx = curr_rps_idx;
1827 self.header.st_rps_bits = st_rps_bits;
1828
1829 Ok(())
1830 }
1831 }
1832}
1833
1834#[derive(Clone, Debug, Default, PartialEq, Eq)]
1835pub struct SublayerHrdParameters {
1836 pub bit_rate_value_minus1: [u32; 32],
1842 pub cpb_size_value_minus1: [u32; 32],
1846 pub cpb_size_du_value_minus1: [u32; 32],
1849 pub bit_rate_du_value_minus1: [u32; 32],
1853 pub cbr_flag: [bool; 32],
1856}
1857
1858#[derive(Clone, Debug, PartialEq, Eq)]
1859pub struct HrdParams {
1860 pub nal_hrd_parameters_present_flag: bool,
1865 pub vcl_hrd_parameters_present_flag: bool,
1870 pub sub_pic_hrd_params_present_flag: bool,
1875 pub tick_divisor_minus2: u8,
1879 pub du_cpb_removal_delay_increment_length_minus1: u8,
1885 pub sub_pic_cpb_params_in_pic_timing_sei_flag: bool,
1893 pub dpb_output_delay_du_length_minus1: u8,
1898 pub bit_rate_scale: u8,
1901 pub cpb_size_scale: u8,
1904 pub cpb_size_du_scale: u8,
1907 pub initial_cpb_removal_delay_length_minus1: u8,
1913 pub au_cpb_removal_delay_length_minus1: u8,
1918 pub dpb_output_delay_length_minus1: u8,
1923 pub fixed_pic_rate_general_flag: [bool; 7],
1929 pub fixed_pic_rate_within_cvs_flag: [bool; 7],
1935 pub elemental_duration_in_tc_minus1: [u32; 7],
1940 pub low_delay_hrd_flag: [bool; 7],
1943 pub cpb_cnt_minus1: [u32; 7],
1947 pub nal_hrd: [SublayerHrdParameters; 7],
1949 pub vcl_hrd: [SublayerHrdParameters; 7],
1951}
1952
1953impl Default for HrdParams {
1954 fn default() -> Self {
1955 Self {
1956 initial_cpb_removal_delay_length_minus1: 23,
1957 au_cpb_removal_delay_length_minus1: 23,
1958 dpb_output_delay_du_length_minus1: 23,
1959 nal_hrd_parameters_present_flag: Default::default(),
1960 vcl_hrd_parameters_present_flag: Default::default(),
1961 sub_pic_hrd_params_present_flag: Default::default(),
1962 tick_divisor_minus2: Default::default(),
1963 du_cpb_removal_delay_increment_length_minus1: Default::default(),
1964 sub_pic_cpb_params_in_pic_timing_sei_flag: Default::default(),
1965 bit_rate_scale: Default::default(),
1966 cpb_size_scale: Default::default(),
1967 cpb_size_du_scale: Default::default(),
1968 dpb_output_delay_length_minus1: Default::default(),
1969 fixed_pic_rate_general_flag: Default::default(),
1970 fixed_pic_rate_within_cvs_flag: Default::default(),
1971 elemental_duration_in_tc_minus1: Default::default(),
1972 low_delay_hrd_flag: Default::default(),
1973 cpb_cnt_minus1: Default::default(),
1974 nal_hrd: Default::default(),
1975 vcl_hrd: Default::default(),
1976 }
1977 }
1978}
1979
1980#[derive(Clone, Debug, PartialEq, Eq)]
1981pub struct VuiParams {
1982 pub aspect_ratio_info_present_flag: bool,
1985 pub aspect_ratio_idc: u32,
1987 pub sar_width: u32,
1990 pub sar_height: u32,
1993 pub overscan_info_present_flag: bool,
1997 pub overscan_appropriate_flag: bool,
2004 pub video_signal_type_present_flag: bool,
2009 pub video_format: u8,
2012 pub video_full_range_flag: bool,
2016 pub colour_description_present_flag: bool,
2021 pub colour_primaries: u32,
2025 pub transfer_characteristics: u32,
2027 pub matrix_coeffs: u32,
2031 pub chroma_loc_info_present_flag: bool,
2036 pub chroma_sample_loc_type_top_field: u32,
2038 pub chroma_sample_loc_type_bottom_field: u32,
2040 pub neutral_chroma_indication_flag: bool,
2044 pub field_seq_flag: bool,
2050 pub frame_field_info_present_flag: bool,
2055 pub default_display_window_flag: bool,
2059 pub def_disp_win_left_offset: u32,
2063 pub def_disp_win_right_offset: u32,
2067 pub def_disp_win_top_offset: u32,
2071 pub def_disp_win_bottom_offset: u32,
2075 pub timing_info_present_flag: bool,
2082 pub num_units_in_tick: u32,
2086 pub time_scale: u32,
2090 pub poc_proportional_to_timing_flag: bool,
2099 pub num_ticks_poc_diff_one_minus1: u32,
2103 pub hrd_parameters_present_flag: bool,
2108 pub hrd: HrdParams,
2110 pub bitstream_restriction_flag: bool,
2114 pub tiles_fixed_structure_flag: bool,
2121 pub motion_vectors_over_pic_boundaries_flag: bool,
2128 pub restricted_ref_pic_lists_flag: bool,
2133 pub min_spatial_segmentation_idc: u32,
2136 pub max_bytes_per_pic_denom: u32,
2139 pub max_bits_per_min_cu_denom: u32,
2142 pub log2_max_mv_length_horizontal: u32,
2146 pub log2_max_mv_length_vertical: u32,
2150}
2151
2152impl Default for VuiParams {
2153 fn default() -> Self {
2154 Self {
2155 aspect_ratio_info_present_flag: Default::default(),
2156 aspect_ratio_idc: Default::default(),
2157 sar_width: Default::default(),
2158 sar_height: Default::default(),
2159 overscan_info_present_flag: Default::default(),
2160 overscan_appropriate_flag: Default::default(),
2161 video_signal_type_present_flag: Default::default(),
2162 video_format: 5,
2163 video_full_range_flag: Default::default(),
2164 colour_description_present_flag: Default::default(),
2165 colour_primaries: 2,
2166 transfer_characteristics: 2,
2167 matrix_coeffs: 2,
2168 chroma_loc_info_present_flag: Default::default(),
2169 chroma_sample_loc_type_top_field: Default::default(),
2170 chroma_sample_loc_type_bottom_field: Default::default(),
2171 neutral_chroma_indication_flag: Default::default(),
2172 field_seq_flag: Default::default(),
2173 frame_field_info_present_flag: Default::default(),
2174 default_display_window_flag: Default::default(),
2175 def_disp_win_left_offset: Default::default(),
2176 def_disp_win_right_offset: Default::default(),
2177 def_disp_win_top_offset: Default::default(),
2178 def_disp_win_bottom_offset: Default::default(),
2179 timing_info_present_flag: Default::default(),
2180 num_units_in_tick: Default::default(),
2181 time_scale: Default::default(),
2182 poc_proportional_to_timing_flag: Default::default(),
2183 num_ticks_poc_diff_one_minus1: Default::default(),
2184 hrd_parameters_present_flag: Default::default(),
2185 hrd: Default::default(),
2186 bitstream_restriction_flag: Default::default(),
2187 tiles_fixed_structure_flag: Default::default(),
2188 motion_vectors_over_pic_boundaries_flag: true,
2189 restricted_ref_pic_lists_flag: Default::default(),
2190 min_spatial_segmentation_idc: Default::default(),
2191 max_bytes_per_pic_denom: 2,
2192 max_bits_per_min_cu_denom: 1,
2193 log2_max_mv_length_horizontal: 15,
2194 log2_max_mv_length_vertical: 15,
2195 }
2196 }
2197}
2198
2199#[derive(Clone, Debug, Default)]
2200pub struct Parser {
2201 active_vpses: BTreeMap<u8, Rc<Vps>>,
2202 active_spses: BTreeMap<u8, Rc<Sps>>,
2203 active_ppses: BTreeMap<u8, Rc<Pps>>,
2204}
2205
2206impl Parser {
2207 pub fn parse_vps(&mut self, nalu: &Nalu) -> Result<&Vps, String> {
2209 if !matches!(nalu.header.type_, NaluType::VpsNut) {
2210 return Err(format!(
2211 "Invalid NALU type, expected {:?}, got {:?}",
2212 NaluType::VpsNut,
2213 nalu.header.type_
2214 ));
2215 }
2216
2217 let data = nalu.as_ref();
2218 let header = &nalu.header;
2219 let hdr_len = header.len();
2220 let mut r = BitReader::new(&data[hdr_len..], true);
2222
2223 let mut vps = Vps {
2224 video_parameter_set_id: r.read_bits(4)?,
2225 base_layer_internal_flag: r.read_bit()?,
2226 base_layer_available_flag: r.read_bit()?,
2227 max_layers_minus1: r.read_bits(6)?,
2228 max_sub_layers_minus1: r.read_bits(3)?,
2229 temporal_id_nesting_flag: r.read_bit()?,
2230 ..Default::default()
2231 };
2232
2233 r.skip_bits(16)?; let ptl = &mut vps.profile_tier_level;
2236 Self::parse_profile_tier_level(ptl, &mut r, true, vps.max_sub_layers_minus1)?;
2237
2238 vps.sub_layer_ordering_info_present_flag = r.read_bit()?;
2239
2240 let start =
2241 if vps.sub_layer_ordering_info_present_flag { 0 } else { vps.max_sub_layers_minus1 }
2242 as usize;
2243
2244 for i in start..=usize::from(vps.max_sub_layers_minus1) {
2245 vps.max_dec_pic_buffering_minus1[i] = r.read_ue_max(15)?;
2246 vps.max_num_reorder_pics[i] = r.read_ue_max(vps.max_dec_pic_buffering_minus1[i])?;
2247 vps.max_latency_increase_plus1[i] = r.read_ue()?;
2248
2249 if i > 0 {
2250 if vps.max_dec_pic_buffering_minus1[i] < vps.max_dec_pic_buffering_minus1[i - 1] {
2251 return Err(format!(
2252 "Invalid max_dec_pic_buffering_minus1[{}]: {}",
2253 i, vps.max_dec_pic_buffering_minus1[i]
2254 ));
2255 }
2256
2257 if vps.max_num_reorder_pics[i] < vps.max_num_reorder_pics[i - 1] {
2258 return Err(format!(
2259 "Invalid max_num_reorder_pics[{}]: {}",
2260 i, vps.max_num_reorder_pics[i]
2261 ));
2262 }
2263 }
2264 }
2265
2266 if !vps.sub_layer_ordering_info_present_flag {
2272 let max_num_sublayers = usize::from(vps.max_sub_layers_minus1);
2273 for i in 0..max_num_sublayers {
2274 vps.max_dec_pic_buffering_minus1[i] =
2275 vps.max_dec_pic_buffering_minus1[max_num_sublayers];
2276
2277 vps.max_num_reorder_pics[i] = vps.max_num_reorder_pics[max_num_sublayers];
2278
2279 vps.max_latency_increase_plus1[i] =
2280 vps.max_latency_increase_plus1[max_num_sublayers];
2281 }
2282 }
2283
2284 vps.max_layer_id = r.read_bits(6)?;
2285 if vps.max_layer_id > 62 {
2286 return Err(format!("Invalid max_layer_id {}", vps.max_layer_id));
2287 }
2288
2289 vps.num_layer_sets_minus1 = r.read_ue_max(1023)?;
2290
2291 for _ in 1..=vps.num_layer_sets_minus1 {
2292 for _ in 0..=vps.max_layer_id {
2293 r.skip_bits(1)?;
2295 }
2296 }
2297
2298 vps.timing_info_present_flag = r.read_bit()?;
2299
2300 if vps.timing_info_present_flag {
2301 vps.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
2302 vps.num_units_in_tick |= r.read_bits::<u32>(1)?;
2303
2304 vps.time_scale = r.read_bits::<u32>(31)? << 1;
2305 vps.time_scale |= r.read_bits::<u32>(1)?;
2306
2307 vps.poc_proportional_to_timing_flag = r.read_bit()?;
2308 if vps.poc_proportional_to_timing_flag {
2309 vps.num_ticks_poc_diff_one_minus1 = r.read_ue()?;
2310 }
2311
2312 vps.num_hrd_parameters = r.read_ue()?;
2313
2314 for i in 0..vps.num_hrd_parameters as usize {
2315 vps.hrd_layer_set_idx.push(r.read_ue()?);
2316 if i > 0 {
2317 vps.cprms_present_flag.push(r.read_bit()?);
2318 }
2319
2320 let mut hrd = HrdParams::default();
2321 Self::parse_hrd_parameters(
2322 vps.cprms_present_flag[i],
2323 vps.max_sub_layers_minus1,
2324 &mut hrd,
2325 &mut r,
2326 )?;
2327
2328 vps.hrd_parameters.push(hrd);
2329 }
2330 }
2331
2332 vps.extension_flag = r.read_bit()?;
2333
2334 if self.active_vpses.keys().len() >= MAX_VPS_COUNT {
2335 return Err("Broken data: Number of active VPSs > MAX_VPS_COUNT".into());
2336 }
2337
2338 let key = vps.video_parameter_set_id;
2339 let vps = Rc::new(vps);
2340 self.active_vpses.remove(&key);
2341 Ok(self.active_vpses.entry(key).or_insert(vps))
2342 }
2343
2344 fn parse_profile_tier_level(
2345 ptl: &mut ProfileTierLevel,
2346 r: &mut BitReader,
2347 profile_present_flag: bool,
2348 sps_max_sub_layers_minus_1: u8,
2349 ) -> Result<(), String> {
2350 if profile_present_flag {
2351 ptl.general_profile_space = r.read_bits(2)?;
2352 ptl.general_tier_flag = r.read_bit()?;
2353 ptl.general_profile_idc = r.read_bits(5)?;
2354
2355 for i in 0..32 {
2356 ptl.general_profile_compatibility_flag[i] = r.read_bit()?;
2357 }
2358
2359 ptl.general_progressive_source_flag = r.read_bit()?;
2360 ptl.general_interlaced_source_flag = r.read_bit()?;
2361 ptl.general_non_packed_constraint_flag = r.read_bit()?;
2362 ptl.general_frame_only_constraint_flag = r.read_bit()?;
2363
2364 if ptl.general_profile_idc == 4
2365 || ptl.general_profile_compatibility_flag[4]
2366 || ptl.general_profile_idc == 5
2367 || ptl.general_profile_compatibility_flag[5]
2368 || ptl.general_profile_idc == 6
2369 || ptl.general_profile_compatibility_flag[6]
2370 || ptl.general_profile_idc == 7
2371 || ptl.general_profile_compatibility_flag[7]
2372 || ptl.general_profile_idc == 8
2373 || ptl.general_profile_compatibility_flag[8]
2374 || ptl.general_profile_idc == 9
2375 || ptl.general_profile_compatibility_flag[9]
2376 || ptl.general_profile_idc == 10
2377 || ptl.general_profile_compatibility_flag[10]
2378 || ptl.general_profile_idc == 11
2379 || ptl.general_profile_compatibility_flag[11]
2380 {
2381 ptl.general_max_12bit_constraint_flag = r.read_bit()?;
2382 ptl.general_max_10bit_constraint_flag = r.read_bit()?;
2383 ptl.general_max_8bit_constraint_flag = r.read_bit()?;
2384 ptl.general_max_422chroma_constraint_flag = r.read_bit()?;
2385 ptl.general_max_420chroma_constraint_flag = r.read_bit()?;
2386 ptl.general_max_monochrome_constraint_flag = r.read_bit()?;
2387 ptl.general_intra_constraint_flag = r.read_bit()?;
2388 ptl.general_one_picture_only_constraint_flag = r.read_bit()?;
2389 ptl.general_lower_bit_rate_constraint_flag = r.read_bit()?;
2390 if ptl.general_profile_idc == 5
2391 || ptl.general_profile_compatibility_flag[5]
2392 || ptl.general_profile_idc == 9
2393 || ptl.general_profile_compatibility_flag[9]
2394 || ptl.general_profile_idc == 10
2395 || ptl.general_profile_compatibility_flag[10]
2396 || ptl.general_profile_idc == 11
2397 || ptl.general_profile_compatibility_flag[11]
2398 {
2399 ptl.general_max_14bit_constraint_flag = r.read_bit()?;
2400 r.skip_bits(31)?;
2402 r.skip_bits(2)?;
2403 } else {
2404 r.skip_bits(31)?;
2406 r.skip_bits(3)?;
2407 }
2408 } else if ptl.general_profile_idc == 2 || ptl.general_profile_compatibility_flag[2] {
2409 r.skip_bits(7)?;
2411 ptl.general_one_picture_only_constraint_flag = r.read_bit()?;
2412 r.skip_bits(31)?;
2414 r.skip_bits(4)?;
2415 } else {
2416 r.skip_bits(31)?;
2417 r.skip_bits(12)?;
2418 }
2419
2420 if ptl.general_profile_idc == 1
2421 || ptl.general_profile_compatibility_flag[1]
2422 || ptl.general_profile_idc == 2
2423 || ptl.general_profile_compatibility_flag[2]
2424 || ptl.general_profile_idc == 3
2425 || ptl.general_profile_compatibility_flag[3]
2426 || ptl.general_profile_idc == 4
2427 || ptl.general_profile_compatibility_flag[4]
2428 || ptl.general_profile_idc == 5
2429 || ptl.general_profile_compatibility_flag[5]
2430 || ptl.general_profile_idc == 9
2431 || ptl.general_profile_compatibility_flag[9]
2432 || ptl.general_profile_idc == 11
2433 || ptl.general_profile_compatibility_flag[11]
2434 {
2435 ptl.general_inbld_flag = r.read_bit()?;
2436 } else {
2437 r.skip_bits(1)?;
2438 }
2439 }
2440
2441 let level: u8 = r.read_bits(8)?;
2442 ptl.general_level_idc = Level::try_from(level)?;
2443
2444 for i in 0..sps_max_sub_layers_minus_1 as usize {
2445 ptl.sub_layer_profile_present_flag[i] = r.read_bit()?;
2446 ptl.sub_layer_level_present_flag[i] = r.read_bit()?;
2447 }
2448
2449 if sps_max_sub_layers_minus_1 > 0 {
2450 for _ in sps_max_sub_layers_minus_1..8 {
2451 r.skip_bits(2)?;
2452 }
2453 }
2454
2455 for i in 0..sps_max_sub_layers_minus_1 as usize {
2456 if ptl.sub_layer_level_present_flag[i] {
2457 ptl.sub_layer_profile_space[i] = r.read_bits(2)?;
2458 ptl.sub_layer_tier_flag[i] = r.read_bit()?;
2459 ptl.sub_layer_profile_idc[i] = r.read_bits(5)?;
2460 for j in 0..32 {
2461 ptl.sub_layer_profile_compatibility_flag[i][j] = r.read_bit()?;
2462 }
2463 ptl.sub_layer_progressive_source_flag[i] = r.read_bit()?;
2464 ptl.sub_layer_interlaced_source_flag[i] = r.read_bit()?;
2465 ptl.sub_layer_non_packed_constraint_flag[i] = r.read_bit()?;
2466 ptl.sub_layer_frame_only_constraint_flag[i] = r.read_bit()?;
2467
2468 if ptl.sub_layer_profile_idc[i] == 4
2469 || ptl.sub_layer_profile_compatibility_flag[i][4]
2470 || ptl.sub_layer_profile_idc[i] == 5
2471 || ptl.sub_layer_profile_compatibility_flag[i][5]
2472 || ptl.sub_layer_profile_idc[i] == 6
2473 || ptl.sub_layer_profile_compatibility_flag[i][6]
2474 || ptl.sub_layer_profile_idc[i] == 7
2475 || ptl.sub_layer_profile_compatibility_flag[i][7]
2476 || ptl.sub_layer_profile_idc[i] == 8
2477 || ptl.sub_layer_profile_compatibility_flag[i][8]
2478 || ptl.sub_layer_profile_idc[i] == 9
2479 || ptl.sub_layer_profile_compatibility_flag[i][9]
2480 || ptl.sub_layer_profile_idc[i] == 10
2481 || ptl.sub_layer_profile_compatibility_flag[i][10]
2482 || ptl.sub_layer_profile_idc[i] == 11
2483 || ptl.sub_layer_profile_compatibility_flag[i][11]
2484 {
2485 ptl.sub_layer_max_12bit_constraint_flag[i] = r.read_bit()?;
2486 ptl.sub_layer_max_10bit_constraint_flag[i] = r.read_bit()?;
2487 ptl.sub_layer_max_8bit_constraint_flag[i] = r.read_bit()?;
2488 ptl.sub_layer_max_422chroma_constraint_flag[i] = r.read_bit()?;
2489 ptl.sub_layer_max_420chroma_constraint_flag[i] = r.read_bit()?;
2490 ptl.sub_layer_max_monochrome_constraint_flag[i] = r.read_bit()?;
2491 ptl.sub_layer_intra_constraint_flag[i] = r.read_bit()?;
2492 ptl.sub_layer_one_picture_only_constraint_flag[i] = r.read_bit()?;
2493 ptl.sub_layer_lower_bit_rate_constraint_flag[i] = r.read_bit()?;
2494
2495 if ptl.sub_layer_profile_idc[i] == 5
2496 || ptl.sub_layer_profile_compatibility_flag[i][5]
2497 || ptl.sub_layer_profile_idc[i] == 9
2498 || ptl.sub_layer_profile_compatibility_flag[i][9]
2499 || ptl.sub_layer_profile_idc[i] == 10
2500 || ptl.sub_layer_profile_compatibility_flag[i][10]
2501 || ptl.sub_layer_profile_idc[i] == 11
2502 || ptl.sub_layer_profile_compatibility_flag[i][11]
2503 {
2504 ptl.sub_layer_max_14bit_constraint_flag[i] = r.read_bit()?;
2505 r.skip_bits(33)?;
2506 } else {
2507 r.skip_bits(34)?;
2508 }
2509 } else if ptl.sub_layer_profile_idc[i] == 2
2510 || ptl.sub_layer_profile_compatibility_flag[i][2]
2511 {
2512 r.skip_bits(7)?;
2513 ptl.sub_layer_one_picture_only_constraint_flag[i] = r.read_bit()?;
2514 r.skip_bits(35)?;
2515 } else {
2516 r.skip_bits(43)?;
2517 }
2518
2519 if ptl.sub_layer_profile_idc[i] == 1
2520 || ptl.sub_layer_profile_compatibility_flag[i][1]
2521 || ptl.sub_layer_profile_idc[i] == 2
2522 || ptl.sub_layer_profile_compatibility_flag[i][2]
2523 || ptl.sub_layer_profile_idc[i] == 3
2524 || ptl.sub_layer_profile_compatibility_flag[i][3]
2525 || ptl.sub_layer_profile_idc[i] == 4
2526 || ptl.sub_layer_profile_compatibility_flag[i][4]
2527 || ptl.sub_layer_profile_idc[i] == 5
2528 || ptl.sub_layer_profile_compatibility_flag[i][5]
2529 || ptl.sub_layer_profile_idc[i] == 9
2530 || ptl.sub_layer_profile_compatibility_flag[i][9]
2531 || ptl.sub_layer_profile_idc[i] == 11
2532 || ptl.sub_layer_profile_compatibility_flag[i][11]
2533 {
2534 ptl.sub_layer_inbld_flag[i] = r.read_bit()?;
2535 } else {
2536 r.skip_bits(1)?;
2537 }
2538
2539 if ptl.sub_layer_level_present_flag[i] {
2540 let level: u8 = r.read_bits(8)?;
2541 ptl.sub_layer_level_idc[i] = Level::try_from(level)?;
2542 }
2543 }
2544 }
2545 Ok(())
2546 }
2547
2548 fn fill_default_scaling_list(sl: &mut ScalingLists, size_id: i32, matrix_id: i32) {
2549 if size_id == 0 {
2550 sl.scaling_list_4x4[matrix_id as usize] = DEFAULT_SCALING_LIST_0;
2551 return;
2552 }
2553
2554 let dst = match size_id {
2555 1 => &mut sl.scaling_list_8x8[matrix_id as usize],
2556 2 => &mut sl.scaling_list_16x16[matrix_id as usize],
2557 3 => &mut sl.scaling_list_32x32[matrix_id as usize],
2558 _ => panic!("Invalid size_id {}", size_id),
2559 };
2560
2561 let src = if matrix_id < 3 {
2562 &DEFAULT_SCALING_LIST_1
2563 } else if matrix_id <= 5 {
2564 &DEFAULT_SCALING_LIST_2
2565 } else {
2566 panic!("Invalid matrix_id {}", matrix_id);
2567 };
2568
2569 *dst = *src;
2570
2571 if size_id == 2 {
2581 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] = 8;
2582 } else if size_id == 3 {
2583 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] = 8;
2584 }
2585 }
2586
2587 fn parse_scaling_list_data(sl: &mut ScalingLists, r: &mut BitReader) -> Result<(), String> {
2588 for size_id in 0..4 {
2590 let mut matrix_id = 0;
2591 while matrix_id < 6 {
2592 let scaling_list_pred_mode_flag = r.read_bit()?;
2593 if !scaling_list_pred_mode_flag {
2599 let scaling_list_pred_matrix_id_delta: u32 = r.read_ue()?;
2600 if scaling_list_pred_matrix_id_delta == 0 {
2601 Self::fill_default_scaling_list(sl, size_id, matrix_id);
2602 } else {
2603 let factor = if size_id == 3 { 3 } else { 1 };
2605 let ref_matrix_id =
2606 matrix_id as u32 - scaling_list_pred_matrix_id_delta * factor;
2607 if size_id == 0 {
2608 sl.scaling_list_4x4[matrix_id as usize] =
2609 sl.scaling_list_4x4[ref_matrix_id as usize];
2610 } else {
2611 let src = match size_id {
2612 1 => sl.scaling_list_8x8[ref_matrix_id as usize],
2613 2 => sl.scaling_list_16x16[ref_matrix_id as usize],
2614 3 => sl.scaling_list_32x32[ref_matrix_id as usize],
2615 _ => return Err(format!("Invalid size_id {}", size_id)),
2616 };
2617
2618 let dst = match size_id {
2619 1 => &mut sl.scaling_list_8x8[matrix_id as usize],
2620 2 => &mut sl.scaling_list_16x16[matrix_id as usize],
2621 3 => &mut sl.scaling_list_32x32[matrix_id as usize],
2622 _ => return Err(format!("Invalid size_id {}", size_id)),
2623 };
2624
2625 *dst = src;
2626
2627 if size_id == 2 {
2628 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] =
2629 sl.scaling_list_dc_coef_minus8_16x16[ref_matrix_id as usize];
2630 } else if size_id == 3 {
2631 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] =
2632 sl.scaling_list_dc_coef_minus8_32x32[ref_matrix_id as usize];
2633 }
2634 }
2635 }
2636 } else {
2637 let mut next_coef = 8i32;
2638 let coef_num = std::cmp::min(64, 1 << (4 + (size_id << 1)));
2639
2640 if size_id > 1 {
2641 if size_id == 2 {
2642 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] =
2643 r.read_se_bounded(-7, 247)?;
2644 next_coef =
2645 i32::from(sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize])
2646 + 8;
2647 } else if size_id == 3 {
2648 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] =
2649 r.read_se_bounded(-7, 247)?;
2650 next_coef =
2651 i32::from(sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize])
2652 + 8;
2653 }
2654 }
2655
2656 for i in 0..coef_num as usize {
2657 let scaling_list_delta_coef: i32 = r.read_se_bounded(-128, 127)?;
2658 next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
2659 match size_id {
2660 0 => sl.scaling_list_4x4[matrix_id as usize][i] = next_coef as _,
2661 1 => sl.scaling_list_8x8[matrix_id as usize][i] = next_coef as _,
2662 2 => sl.scaling_list_16x16[matrix_id as usize][i] = next_coef as _,
2663 3 => sl.scaling_list_32x32[matrix_id as usize][i] = next_coef as _,
2664 _ => return Err(format!("Invalid size_id {}", size_id)),
2665 }
2666 }
2667 }
2668 let step = if size_id == 3 { 3 } else { 1 };
2669 matrix_id += step;
2670 }
2671 }
2672 Ok(())
2673 }
2674
2675 fn parse_short_term_ref_pic_set(
2676 sps: &Sps,
2677 st: &mut ShortTermRefPicSet,
2678 r: &mut BitReader,
2679 st_rps_idx: u8,
2680 ) -> Result<(), String> {
2681 if st_rps_idx != 0 {
2682 st.inter_ref_pic_set_prediction_flag = r.read_bit()?;
2683 }
2684
2685 if st.inter_ref_pic_set_prediction_flag {
2687 if st_rps_idx == sps.num_short_term_ref_pic_sets {
2688 st.delta_idx_minus1 = r.read_ue_max(st_rps_idx as u32 - 1)?;
2689 }
2690
2691 st.delta_rps_sign = r.read_bit()?;
2692 st.abs_delta_rps_minus1 = r.read_ue_max(32767)?;
2695
2696 let ref_rps_idx = st_rps_idx - (st.delta_idx_minus1 + 1);
2697 let delta_rps =
2698 (1 - 2 * st.delta_rps_sign as i32) * (st.abs_delta_rps_minus1 as i32 + 1);
2699
2700 let ref_st = sps
2701 .short_term_ref_pic_set
2702 .get(usize::from(ref_rps_idx))
2703 .ok_or::<String>("Invalid ref_rps_idx".into())?;
2704
2705 let mut used_by_curr_pic_flag = [false; 64];
2706
2707 let mut use_delta_flag = [true; 64];
2709
2710 for j in 0..=ref_st.num_delta_pocs as usize {
2711 used_by_curr_pic_flag[j] = r.read_bit()?;
2712 if !used_by_curr_pic_flag[j] {
2713 use_delta_flag[j] = r.read_bit()?;
2714 }
2715 }
2716
2717 let mut i = 0;
2719 for j in (0..=isize::from(ref_st.num_positive_pics) - 1)
2723 .rev()
2724 .take_while(|j| *j >= 0)
2725 .map(|j| j as usize)
2726 {
2727 let d_poc = ref_st.delta_poc_s1[j] + delta_rps;
2728 if d_poc < 0 && use_delta_flag[usize::from(ref_st.num_negative_pics) + j] {
2729 st.delta_poc_s0[i] = d_poc;
2730 st.used_by_curr_pic_s0[i] =
2731 used_by_curr_pic_flag[usize::from(ref_st.num_negative_pics) + j];
2732
2733 i += 1;
2734 }
2735 }
2736
2737 if delta_rps < 0 && use_delta_flag[ref_st.num_delta_pocs as usize] {
2738 st.delta_poc_s0[i] = delta_rps;
2739 st.used_by_curr_pic_s0[i] = used_by_curr_pic_flag[ref_st.num_delta_pocs as usize];
2740
2741 i += 1;
2742 }
2743
2744 #[allow(clippy::needless_range_loop)]
2746 for j in 0..ref_st.num_negative_pics as usize {
2747 let d_poc = ref_st.delta_poc_s0[j] + delta_rps;
2748 if d_poc < 0 && use_delta_flag[j] {
2749 st.delta_poc_s0[i] = d_poc;
2750 st.used_by_curr_pic_s0[i] = used_by_curr_pic_flag[j];
2751
2752 i += 1;
2753 }
2754 }
2755
2756 st.num_negative_pics = i as u8;
2757
2758 let mut i = 0;
2760 for j in (0..=isize::from(ref_st.num_negative_pics) - 1)
2764 .rev()
2765 .take_while(|j| *j >= 0)
2766 .map(|j| j as usize)
2767 {
2768 let d_poc = ref_st.delta_poc_s0[j] + delta_rps;
2769 if d_poc > 0 && use_delta_flag[j] {
2770 st.delta_poc_s1[i] = d_poc;
2771 st.used_by_curr_pic_s1[i] = used_by_curr_pic_flag[j];
2772
2773 i += 1;
2774 }
2775 }
2776
2777 if delta_rps > 0 && use_delta_flag[ref_st.num_delta_pocs as usize] {
2778 st.delta_poc_s1[i] = delta_rps;
2779 st.used_by_curr_pic_s1[i] = used_by_curr_pic_flag[ref_st.num_delta_pocs as usize];
2780
2781 i += 1;
2782 }
2783
2784 for j in 0..usize::from(ref_st.num_positive_pics) {
2785 let d_poc = ref_st.delta_poc_s1[j] + delta_rps;
2786 if d_poc > 0 && use_delta_flag[ref_st.num_negative_pics as usize + j] {
2787 st.delta_poc_s1[i] = d_poc;
2788 st.used_by_curr_pic_s1[i] =
2789 used_by_curr_pic_flag[ref_st.num_negative_pics as usize + j];
2790
2791 i += 1;
2792 }
2793 }
2794
2795 st.num_positive_pics = i as u8;
2796 } else {
2797 st.num_negative_pics = r.read_ue_max(u32::from(
2798 sps.max_dec_pic_buffering_minus1[usize::from(sps.max_sub_layers_minus1)],
2799 ))?;
2800
2801 st.num_positive_pics = r.read_ue_max(u32::from(
2802 sps.max_dec_pic_buffering_minus1[usize::from(sps.max_sub_layers_minus1)]
2803 - st.num_negative_pics,
2804 ))?;
2805
2806 for i in 0..usize::from(st.num_negative_pics) {
2807 let delta_poc_s0_minus1: u32 = r.read_ue_max(32767)?;
2808
2809 if i == 0 {
2810 st.delta_poc_s0[i] = -(delta_poc_s0_minus1 as i32 + 1);
2811 } else {
2812 st.delta_poc_s0[i] = st.delta_poc_s0[i - 1] - (delta_poc_s0_minus1 as i32 + 1);
2813 }
2814
2815 st.used_by_curr_pic_s0[i] = r.read_bit()?;
2816 }
2817
2818 for i in 0..usize::from(st.num_positive_pics) {
2819 let delta_poc_s1_minus1: u32 = r.read_ue_max(32767)?;
2820
2821 if i == 0 {
2822 st.delta_poc_s1[i] = delta_poc_s1_minus1 as i32 + 1;
2823 } else {
2824 st.delta_poc_s1[i] = st.delta_poc_s1[i - 1] + (delta_poc_s1_minus1 as i32 + 1);
2825 }
2826
2827 st.used_by_curr_pic_s1[i] = r.read_bit()?;
2828 }
2829 }
2830
2831 st.num_delta_pocs = u32::from(st.num_negative_pics + st.num_positive_pics);
2832
2833 Ok(())
2834 }
2835
2836 fn parse_sublayer_hrd_parameters(
2837 h: &mut SublayerHrdParameters,
2838 cpb_cnt: u32,
2839 sub_pic_hrd_params_present_flag: bool,
2840 r: &mut BitReader,
2841 ) -> Result<(), String> {
2842 for i in 0..cpb_cnt as usize {
2843 h.bit_rate_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2844 h.cpb_size_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2845 if sub_pic_hrd_params_present_flag {
2846 h.cpb_size_du_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2847 h.bit_rate_du_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2848 }
2849
2850 h.cbr_flag[i] = r.read_bit()?;
2851 }
2852
2853 Ok(())
2854 }
2855
2856 fn parse_hrd_parameters(
2857 common_inf_present_flag: bool,
2858 max_num_sublayers_minus1: u8,
2859 hrd: &mut HrdParams,
2860 r: &mut BitReader,
2861 ) -> Result<(), String> {
2862 if common_inf_present_flag {
2863 hrd.nal_hrd_parameters_present_flag = r.read_bit()?;
2864 hrd.vcl_hrd_parameters_present_flag = r.read_bit()?;
2865 if hrd.nal_hrd_parameters_present_flag || hrd.vcl_hrd_parameters_present_flag {
2866 hrd.sub_pic_hrd_params_present_flag = r.read_bit()?;
2867 if hrd.sub_pic_hrd_params_present_flag {
2868 hrd.tick_divisor_minus2 = r.read_bits(8)?;
2869 hrd.du_cpb_removal_delay_increment_length_minus1 = r.read_bits(5)?;
2870 hrd.sub_pic_cpb_params_in_pic_timing_sei_flag = r.read_bit()?;
2871 hrd.dpb_output_delay_du_length_minus1 = r.read_bits(5)?;
2872 }
2873 hrd.bit_rate_scale = r.read_bits(4)?;
2874 hrd.cpb_size_scale = r.read_bits(4)?;
2875 if hrd.sub_pic_hrd_params_present_flag {
2876 hrd.cpb_size_du_scale = r.read_bits(4)?;
2877 }
2878 hrd.initial_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
2879 hrd.au_cpb_removal_delay_length_minus1 = r.read_bits(5)?;
2880 hrd.dpb_output_delay_length_minus1 = r.read_bits(5)?;
2881 }
2882 }
2883
2884 for i in 0..=max_num_sublayers_minus1 as usize {
2885 hrd.fixed_pic_rate_general_flag[i] = r.read_bit()?;
2886 if !hrd.fixed_pic_rate_general_flag[i] {
2887 hrd.fixed_pic_rate_within_cvs_flag[i] = r.read_bit()?;
2888 }
2889 if hrd.fixed_pic_rate_within_cvs_flag[i] {
2890 hrd.elemental_duration_in_tc_minus1[i] = r.read_ue_max(2047)?;
2891 } else {
2892 hrd.low_delay_hrd_flag[i] = r.read_bit()?;
2893 }
2894
2895 if !hrd.low_delay_hrd_flag[i] {
2896 hrd.cpb_cnt_minus1[i] = r.read_ue_max(31)?;
2897 }
2898
2899 if hrd.nal_hrd_parameters_present_flag {
2900 Self::parse_sublayer_hrd_parameters(
2901 &mut hrd.nal_hrd[i],
2902 hrd.cpb_cnt_minus1[i] + 1,
2903 hrd.sub_pic_hrd_params_present_flag,
2904 r,
2905 )?;
2906 }
2907
2908 if hrd.vcl_hrd_parameters_present_flag {
2909 Self::parse_sublayer_hrd_parameters(
2910 &mut hrd.vcl_hrd[i],
2911 hrd.cpb_cnt_minus1[i] + 1,
2912 hrd.sub_pic_hrd_params_present_flag,
2913 r,
2914 )?;
2915 }
2916 }
2917
2918 Ok(())
2919 }
2920
2921 fn parse_vui_parameters(sps: &mut Sps, r: &mut BitReader) -> Result<(), String> {
2922 let vui = &mut sps.vui_parameters;
2923
2924 vui.aspect_ratio_info_present_flag = r.read_bit()?;
2925 if vui.aspect_ratio_info_present_flag {
2926 vui.aspect_ratio_idc = r.read_bits(8)?;
2927 const EXTENDED_SAR: u32 = 255;
2928 if vui.aspect_ratio_idc == EXTENDED_SAR {
2929 vui.sar_width = r.read_bits(16)?;
2930 vui.sar_height = r.read_bits(16)?;
2931 }
2932 }
2933
2934 vui.overscan_info_present_flag = r.read_bit()?;
2935 if vui.overscan_info_present_flag {
2936 vui.overscan_appropriate_flag = r.read_bit()?;
2937 }
2938
2939 vui.video_signal_type_present_flag = r.read_bit()?;
2940 if vui.video_signal_type_present_flag {
2941 vui.video_format = r.read_bits(3)?;
2942 vui.video_full_range_flag = r.read_bit()?;
2943 vui.colour_description_present_flag = r.read_bit()?;
2944 if vui.colour_description_present_flag {
2945 vui.colour_primaries = r.read_bits(8)?;
2946 vui.transfer_characteristics = r.read_bits(8)?;
2947 vui.matrix_coeffs = r.read_bits(8)?;
2948 }
2949 }
2950
2951 vui.chroma_loc_info_present_flag = r.read_bit()?;
2952 if vui.chroma_loc_info_present_flag {
2953 vui.chroma_sample_loc_type_top_field = r.read_ue_max(5)?;
2954 vui.chroma_sample_loc_type_bottom_field = r.read_ue_max(5)?;
2955 }
2956
2957 vui.neutral_chroma_indication_flag = r.read_bit()?;
2958 vui.field_seq_flag = r.read_bit()?;
2959 vui.frame_field_info_present_flag = r.read_bit()?;
2960 vui.default_display_window_flag = r.read_bit()?;
2961
2962 if vui.default_display_window_flag {
2963 vui.def_disp_win_left_offset = r.read_ue()?;
2964 vui.def_disp_win_right_offset = r.read_ue()?;
2965 vui.def_disp_win_top_offset = r.read_ue()?;
2966 vui.def_disp_win_bottom_offset = r.read_ue()?;
2967 }
2968
2969 vui.timing_info_present_flag = r.read_bit()?;
2970 if vui.timing_info_present_flag {
2971 vui.num_units_in_tick = r.read_bits::<u32>(31)? << 1;
2972 vui.num_units_in_tick |= r.read_bits::<u32>(1)?;
2973
2974 if vui.num_units_in_tick == 0 {
2975 log::warn!("Incompliant value for num_units_in_tick {}", vui.num_units_in_tick);
2976 }
2977
2978 vui.time_scale = r.read_bits::<u32>(31)? << 1;
2979 vui.time_scale |= r.read_bits::<u32>(1)?;
2980
2981 if vui.time_scale == 0 {
2982 log::warn!("Incompliant value for time_scale {}", vui.time_scale);
2983 }
2984
2985 vui.poc_proportional_to_timing_flag = r.read_bit()?;
2986 if vui.poc_proportional_to_timing_flag {
2987 vui.num_ticks_poc_diff_one_minus1 = r.read_ue_max((2u64.pow(32) - 2) as u32)?;
2988 }
2989
2990 vui.hrd_parameters_present_flag = r.read_bit()?;
2991 if vui.hrd_parameters_present_flag {
2992 let sps_max_sub_layers_minus1 = sps.max_sub_layers_minus1;
2993 Self::parse_hrd_parameters(true, sps_max_sub_layers_minus1, &mut vui.hrd, r)?;
2994 }
2995 }
2996
2997 vui.bitstream_restriction_flag = r.read_bit()?;
2998 if vui.bitstream_restriction_flag {
2999 vui.tiles_fixed_structure_flag = r.read_bit()?;
3000 vui.motion_vectors_over_pic_boundaries_flag = r.read_bit()?;
3001 vui.restricted_ref_pic_lists_flag = r.read_bit()?;
3002
3003 vui.min_spatial_segmentation_idc = r.read_ue_max(4095)?;
3004 vui.max_bytes_per_pic_denom = r.read_ue()?;
3005 vui.max_bits_per_min_cu_denom = r.read_ue()?;
3006 vui.log2_max_mv_length_horizontal = r.read_ue_max(16)?;
3007 vui.log2_max_mv_length_vertical = r.read_ue_max(15)?;
3008 }
3009
3010 Ok(())
3011 }
3012
3013 fn parse_sps_scc_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String> {
3014 let scc = &mut sps.scc_extension;
3015
3016 scc.curr_pic_ref_enabled_flag = r.read_bit()?;
3017 scc.palette_mode_enabled_flag = r.read_bit()?;
3018 if scc.palette_mode_enabled_flag {
3019 scc.palette_max_size = r.read_ue_max(64)?;
3020 scc.delta_palette_max_predictor_size =
3021 r.read_ue_max(128 - u32::from(scc.palette_max_size))?;
3022 scc.palette_predictor_initializers_present_flag = r.read_bit()?;
3023 if scc.palette_predictor_initializers_present_flag {
3024 let max =
3025 u32::from(scc.palette_max_size + scc.delta_palette_max_predictor_size - 1);
3026 scc.num_palette_predictor_initializer_minus1 = r.read_ue_max(max)?;
3027
3028 let num_comps = if sps.chroma_format_idc == 0 { 1 } else { 3 };
3029 for comp in 0..num_comps {
3030 for i in 0..=usize::from(scc.num_palette_predictor_initializer_minus1) {
3031 let num_bits = if comp == 0 {
3032 sps.bit_depth_luma_minus8 + 8
3033 } else {
3034 sps.bit_depth_chroma_minus8 + 8
3035 };
3036 scc.palette_predictor_initializer[comp][i] =
3037 r.read_bits(usize::from(num_bits))?;
3038 }
3039 }
3040 }
3041 }
3042
3043 scc.motion_vector_resolution_control_idc = r.read_bits(2)?;
3044 scc.intra_boundary_filtering_disabled_flag = r.read_bit()?;
3045
3046 Ok(())
3047 }
3048
3049 fn parse_sps_range_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String> {
3050 let ext = &mut sps.range_extension;
3051
3052 ext.transform_skip_rotation_enabled_flag = r.read_bit()?;
3053 ext.transform_skip_context_enabled_flag = r.read_bit()?;
3054 ext.implicit_rdpcm_enabled_flag = r.read_bit()?;
3055 ext.explicit_rdpcm_enabled_flag = r.read_bit()?;
3056 ext.extended_precision_processing_flag = r.read_bit()?;
3057 ext.intra_smoothing_disabled_flag = r.read_bit()?;
3058 ext.high_precision_offsets_enabled_flag = r.read_bit()?;
3059 ext.persistent_rice_adaptation_enabled_flag = r.read_bit()?;
3060 ext.cabac_bypass_alignment_enabled_flag = r.read_bit()?;
3061
3062 Ok(())
3063 }
3064
3065 pub fn parse_sps(&mut self, nalu: &Nalu) -> Result<&Sps, String> {
3067 if !matches!(nalu.header.type_, NaluType::SpsNut) {
3068 return Err(format!(
3069 "Invalid NALU type, expected {:?}, got {:?}",
3070 NaluType::SpsNut,
3071 nalu.header.type_
3072 ));
3073 }
3074
3075 let data = nalu.as_ref();
3076 let header = &nalu.header;
3077 let hdr_len = header.len();
3078 let mut r = BitReader::new(&data[hdr_len..], true);
3080
3081 let video_parameter_set_id = r.read_bits(4)?;
3082
3083 let vps = self.get_vps(video_parameter_set_id).cloned();
3085
3086 let mut sps = Sps {
3087 video_parameter_set_id,
3088 max_sub_layers_minus1: r.read_bits(3)?,
3089 temporal_id_nesting_flag: r.read_bit()?,
3090 vps,
3091 ..Default::default()
3092 };
3093
3094 Self::parse_profile_tier_level(
3095 &mut sps.profile_tier_level,
3096 &mut r,
3097 true,
3098 sps.max_sub_layers_minus1,
3099 )?;
3100
3101 sps.seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
3102 sps.chroma_format_idc = r.read_ue_max(3)?;
3103
3104 if sps.chroma_format_idc == 3 {
3105 sps.separate_colour_plane_flag = r.read_bit()?;
3106 }
3107
3108 sps.chroma_array_type =
3109 if sps.separate_colour_plane_flag { 0 } else { sps.chroma_format_idc };
3110
3111 sps.pic_width_in_luma_samples = r.read_ue_bounded(1, 16888)?;
3112 sps.pic_height_in_luma_samples = r.read_ue_bounded(1, 16888)?;
3113
3114 sps.conformance_window_flag = r.read_bit()?;
3115 if sps.conformance_window_flag {
3116 sps.conf_win_left_offset = r.read_ue()?;
3117 sps.conf_win_right_offset = r.read_ue()?;
3118 sps.conf_win_top_offset = r.read_ue()?;
3119 sps.conf_win_bottom_offset = r.read_ue()?;
3120 }
3121
3122 sps.bit_depth_luma_minus8 = r.read_ue_max(6)?;
3123 sps.bit_depth_chroma_minus8 = r.read_ue_max(6)?;
3124 sps.log2_max_pic_order_cnt_lsb_minus4 = r.read_ue_max(12)?;
3125 sps.sub_layer_ordering_info_present_flag = r.read_bit()?;
3126
3127 {
3128 let i = if sps.sub_layer_ordering_info_present_flag {
3129 0
3130 } else {
3131 sps.max_sub_layers_minus1
3132 };
3133
3134 for j in i..=sps.max_sub_layers_minus1 {
3135 sps.max_dec_pic_buffering_minus1[j as usize] = r.read_ue_max(16)?;
3136 sps.max_num_reorder_pics[j as usize] =
3137 r.read_ue_max(sps.max_dec_pic_buffering_minus1[j as usize] as _)?;
3138 sps.max_latency_increase_plus1[j as usize] = r.read_ue_max(u32::MAX - 1)?;
3139 }
3140 }
3141
3142 sps.log2_min_luma_coding_block_size_minus3 = r.read_ue_max(3)?;
3143 sps.log2_diff_max_min_luma_coding_block_size = r.read_ue_max(6)?;
3144 sps.log2_min_luma_transform_block_size_minus2 = r.read_ue_max(3)?;
3145 sps.log2_diff_max_min_luma_transform_block_size = r.read_ue_max(3)?;
3146
3147 sps.min_cb_log2_size_y = u32::from(sps.log2_min_luma_coding_block_size_minus3 + 3);
3149 sps.ctb_log2_size_y =
3151 sps.min_cb_log2_size_y + u32::from(sps.log2_diff_max_min_luma_coding_block_size);
3152 sps.ctb_size_y = 1 << sps.ctb_log2_size_y;
3154 sps.pic_height_in_ctbs_y =
3156 (sps.pic_height_in_luma_samples as f64 / sps.ctb_size_y as f64).ceil() as u32;
3157 sps.pic_width_in_ctbs_y =
3159 (sps.pic_width_in_luma_samples as f64 / sps.ctb_size_y as f64).ceil() as u32;
3160
3161 sps.max_tb_log2_size_y = u32::from(
3162 sps.log2_min_luma_transform_block_size_minus2
3163 + 2
3164 + sps.log2_diff_max_min_luma_transform_block_size,
3165 );
3166
3167 sps.pic_size_in_samples_y =
3168 u32::from(sps.pic_width_in_luma_samples) * u32::from(sps.pic_height_in_luma_samples);
3169
3170 if sps.max_tb_log2_size_y > std::cmp::min(sps.ctb_log2_size_y, 5) {
3171 return Err(format!("Invalid value for MaxTbLog2SizeY: {}", sps.max_tb_log2_size_y));
3172 }
3173
3174 sps.pic_size_in_ctbs_y = sps.pic_width_in_ctbs_y * sps.pic_height_in_ctbs_y;
3175
3176 sps.max_transform_hierarchy_depth_inter = r.read_ue_max(4)?;
3177 sps.max_transform_hierarchy_depth_intra = r.read_ue_max(4)?;
3178
3179 sps.scaling_list_enabled_flag = r.read_bit()?;
3180 if sps.scaling_list_enabled_flag {
3181 sps.scaling_list_data_present_flag = r.read_bit()?;
3182 if sps.scaling_list_data_present_flag {
3183 Self::parse_scaling_list_data(&mut sps.scaling_list, &mut r)?;
3184 }
3185 }
3186
3187 sps.amp_enabled_flag = r.read_bit()?;
3188 sps.sample_adaptive_offset_enabled_flag = r.read_bit()?;
3189
3190 sps.pcm_enabled_flag = r.read_bit()?;
3191 if sps.pcm_enabled_flag {
3192 sps.pcm_sample_bit_depth_luma_minus1 = r.read_bits(4)?;
3193 sps.pcm_sample_bit_depth_chroma_minus1 = r.read_bits(4)?;
3194 sps.log2_min_pcm_luma_coding_block_size_minus3 = r.read_ue_max(2)?;
3195 sps.log2_diff_max_min_pcm_luma_coding_block_size = r.read_ue_max(2)?;
3196 sps.pcm_loop_filter_disabled_flag = r.read_bit()?;
3197 }
3198
3199 sps.num_short_term_ref_pic_sets = r.read_ue_max(64)?;
3200
3201 for i in 0..sps.num_short_term_ref_pic_sets {
3202 let mut st = ShortTermRefPicSet::default();
3203 Self::parse_short_term_ref_pic_set(&sps, &mut st, &mut r, i)?;
3204 sps.short_term_ref_pic_set.push(st);
3205 }
3206
3207 sps.long_term_ref_pics_present_flag = r.read_bit()?;
3208 if sps.long_term_ref_pics_present_flag {
3209 sps.num_long_term_ref_pics_sps = r.read_ue_max(32)?;
3210 for i in 0..usize::from(sps.num_long_term_ref_pics_sps) {
3211 sps.lt_ref_pic_poc_lsb_sps[i] =
3212 r.read_bits(usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4)?;
3213 sps.used_by_curr_pic_lt_sps_flag[i] = r.read_bit()?;
3214 }
3215 }
3216
3217 sps.temporal_mvp_enabled_flag = r.read_bit()?;
3218 sps.strong_intra_smoothing_enabled_flag = r.read_bit()?;
3219
3220 sps.vui_parameters_present_flag = r.read_bit()?;
3221 if sps.vui_parameters_present_flag {
3222 Self::parse_vui_parameters(&mut sps, &mut r)?;
3223 }
3224
3225 sps.extension_present_flag = r.read_bit()?;
3226 if sps.extension_present_flag {
3227 sps.range_extension_flag = r.read_bit()?;
3228 if sps.range_extension_flag {
3229 Self::parse_sps_range_extension(&mut sps, &mut r)?;
3230 }
3231
3232 let multilayer_extension_flag = r.read_bit()?;
3233 if multilayer_extension_flag {
3234 return Err("Multilayer extension not supported.".into());
3235 }
3236
3237 let three_d_extension_flag = r.read_bit()?;
3238 if three_d_extension_flag {
3239 return Err("3D extension not supported.".into());
3240 }
3241
3242 sps.scc_extension_flag = r.read_bit()?;
3243 if sps.scc_extension_flag {
3244 Self::parse_sps_scc_extension(&mut sps, &mut r)?;
3245 }
3246 }
3247
3248 let shift = if sps.range_extension.high_precision_offsets_enabled_flag {
3249 sps.bit_depth_luma_minus8 + 7
3250 } else {
3251 7
3252 };
3253
3254 sps.wp_offset_half_range_y = 1 << shift;
3255
3256 let shift = if sps.range_extension.high_precision_offsets_enabled_flag {
3257 sps.bit_depth_chroma_minus8 + 7
3258 } else {
3259 7
3260 };
3261
3262 sps.wp_offset_half_range_c = 1 << shift;
3263
3264 log::debug!(
3265 "Parsed SPS({}), resolution: ({}, {}): NAL size was {}",
3266 sps.seq_parameter_set_id,
3267 sps.width(),
3268 sps.height(),
3269 nalu.size
3270 );
3271
3272 if self.active_spses.keys().len() >= MAX_SPS_COUNT {
3273 return Err("Broken data: Number of active SPSs > MAX_SPS_COUNT".into());
3274 }
3275
3276 let key = sps.seq_parameter_set_id;
3277 let sps = Rc::new(sps);
3278 self.active_spses.remove(&key);
3279 Ok(self.active_spses.entry(key).or_insert(sps))
3280 }
3281
3282 fn parse_pps_scc_extension(pps: &mut Pps, sps: &Sps, r: &mut BitReader) -> Result<(), String> {
3283 let scc = &mut pps.scc_extension;
3284 scc.curr_pic_ref_enabled_flag = r.read_bit()?;
3285 scc.residual_adaptive_colour_transform_enabled_flag = r.read_bit()?;
3286 if scc.residual_adaptive_colour_transform_enabled_flag {
3287 scc.slice_act_qp_offsets_present_flag = r.read_bit()?;
3288 scc.act_y_qp_offset_plus5 = r.read_se_bounded(-7, 17)?;
3289 scc.act_cb_qp_offset_plus5 = r.read_se_bounded(-7, 17)?;
3290 scc.act_cr_qp_offset_plus3 = r.read_se_bounded(-9, 15)?;
3291 }
3292
3293 scc.palette_predictor_initializers_present_flag = r.read_bit()?;
3294 if scc.palette_predictor_initializers_present_flag {
3295 let max = sps.scc_extension.palette_max_size
3296 + sps.scc_extension.delta_palette_max_predictor_size;
3297 scc.num_palette_predictor_initializers = r.read_ue_max(max.into())?;
3298 if scc.num_palette_predictor_initializers > 0 {
3299 scc.monochrome_palette_flag = r.read_bit()?;
3300 scc.luma_bit_depth_entry_minus8 = r.read_ue_bounded(
3301 sps.bit_depth_luma_minus8.into(),
3302 sps.bit_depth_luma_minus8.into(),
3303 )?;
3304 if !scc.monochrome_palette_flag {
3305 scc.chroma_bit_depth_entry_minus8 = r.read_ue_bounded(
3306 sps.bit_depth_chroma_minus8.into(),
3307 sps.bit_depth_chroma_minus8.into(),
3308 )?;
3309 }
3310
3311 let num_comps = if scc.monochrome_palette_flag { 1 } else { 3 };
3312 for comp in 0..num_comps {
3313 let num_bits = if comp == 0 {
3314 scc.luma_bit_depth_entry_minus8 + 8
3315 } else {
3316 scc.chroma_bit_depth_entry_minus8 + 8
3317 };
3318 for i in 0..usize::from(scc.num_palette_predictor_initializers) {
3319 scc.palette_predictor_initializer[comp][i] =
3320 r.read_bits(num_bits.into())?;
3321 }
3322 }
3323 }
3324 }
3325 Ok(())
3326 }
3327
3328 fn parse_pps_range_extension(
3329 pps: &mut Pps,
3330 sps: &Sps,
3331 r: &mut BitReader,
3332 ) -> Result<(), String> {
3333 let rext = &mut pps.range_extension;
3334
3335 if pps.transform_skip_enabled_flag {
3336 rext.log2_max_transform_skip_block_size_minus2 =
3337 r.read_ue_max(sps.max_tb_log2_size_y - 2)?;
3338 }
3339
3340 rext.cross_component_prediction_enabled_flag = r.read_bit()?;
3341 rext.chroma_qp_offset_list_enabled_flag = r.read_bit()?;
3342 if rext.chroma_qp_offset_list_enabled_flag {
3343 rext.diff_cu_chroma_qp_offset_depth = r.read_ue()?;
3344 rext.chroma_qp_offset_list_len_minus1 = r.read_ue_max(5)?;
3345 for i in 0..=rext.chroma_qp_offset_list_len_minus1 as usize {
3346 rext.cb_qp_offset_list[i] = r.read_se_bounded(-12, 12)?;
3347 rext.cr_qp_offset_list[i] = r.read_se_bounded(-12, 12)?;
3348 }
3349 }
3350
3351 let bit_depth_y = sps.bit_depth_luma_minus8 + 8;
3352 let max = u32::from(std::cmp::max(0, bit_depth_y - 10));
3353
3354 rext.log2_sao_offset_scale_luma = r.read_ue_max(max)?;
3355 rext.log2_sao_offset_scale_chroma = r.read_ue_max(max)?;
3356
3357 Ok(())
3358 }
3359
3360 pub fn parse_pps(&mut self, nalu: &Nalu) -> Result<&Pps, String> {
3362 if !matches!(nalu.header.type_, NaluType::PpsNut) {
3363 return Err(format!(
3364 "Invalid NALU type, expected {:?}, got {:?}",
3365 NaluType::PpsNut,
3366 nalu.header.type_
3367 ));
3368 }
3369
3370 let data = nalu.as_ref();
3371 let header = &nalu.header;
3372 let hdr_len = header.len();
3373 let mut r = BitReader::new(&data[hdr_len..], true);
3375
3376 let pic_parameter_set_id = r.read_ue_max(MAX_PPS_COUNT as u32 - 1)?;
3377 let seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?;
3378
3379 let sps = self.get_sps(seq_parameter_set_id).ok_or::<String>(format!(
3380 "Could not get SPS for seq_parameter_set_id {}",
3381 seq_parameter_set_id
3382 ))?;
3383
3384 let mut pps = Pps {
3385 pic_parameter_set_id,
3386 seq_parameter_set_id,
3387 dependent_slice_segments_enabled_flag: Default::default(),
3388 output_flag_present_flag: Default::default(),
3389 num_extra_slice_header_bits: Default::default(),
3390 sign_data_hiding_enabled_flag: Default::default(),
3391 cabac_init_present_flag: Default::default(),
3392 num_ref_idx_l0_default_active_minus1: Default::default(),
3393 num_ref_idx_l1_default_active_minus1: Default::default(),
3394 init_qp_minus26: Default::default(),
3395 constrained_intra_pred_flag: Default::default(),
3396 transform_skip_enabled_flag: Default::default(),
3397 cu_qp_delta_enabled_flag: Default::default(),
3398 diff_cu_qp_delta_depth: Default::default(),
3399 cb_qp_offset: Default::default(),
3400 cr_qp_offset: Default::default(),
3401 slice_chroma_qp_offsets_present_flag: Default::default(),
3402 weighted_pred_flag: Default::default(),
3403 weighted_bipred_flag: Default::default(),
3404 transquant_bypass_enabled_flag: Default::default(),
3405 tiles_enabled_flag: Default::default(),
3406 entropy_coding_sync_enabled_flag: Default::default(),
3407 num_tile_columns_minus1: Default::default(),
3408 num_tile_rows_minus1: Default::default(),
3409 uniform_spacing_flag: true,
3410 column_width_minus1: Default::default(),
3411 row_height_minus1: Default::default(),
3412 loop_filter_across_tiles_enabled_flag: true,
3413 loop_filter_across_slices_enabled_flag: Default::default(),
3414 deblocking_filter_control_present_flag: Default::default(),
3415 deblocking_filter_override_enabled_flag: Default::default(),
3416 deblocking_filter_disabled_flag: Default::default(),
3417 beta_offset_div2: Default::default(),
3418 tc_offset_div2: Default::default(),
3419 scaling_list_data_present_flag: Default::default(),
3420 scaling_list: Default::default(),
3421 lists_modification_present_flag: Default::default(),
3422 log2_parallel_merge_level_minus2: Default::default(),
3423 slice_segment_header_extension_present_flag: Default::default(),
3424 extension_present_flag: Default::default(),
3425 range_extension_flag: Default::default(),
3426 range_extension: Default::default(),
3427 qp_bd_offset_y: Default::default(),
3428 scc_extension: Default::default(),
3429 scc_extension_flag: Default::default(),
3430 sps: Rc::clone(sps),
3431 };
3432
3433 pps.dependent_slice_segments_enabled_flag = r.read_bit()?;
3434 pps.output_flag_present_flag = r.read_bit()?;
3435 pps.num_extra_slice_header_bits = r.read_bits(3)?;
3436 pps.sign_data_hiding_enabled_flag = r.read_bit()?;
3437 pps.cabac_init_present_flag = r.read_bit()?;
3438
3439 pps.num_ref_idx_l0_default_active_minus1 = r.read_ue_max(14)?;
3441 pps.num_ref_idx_l1_default_active_minus1 = r.read_ue_max(14)?;
3442
3443 let qp_bd_offset_y = 6 * i32::from(sps.bit_depth_luma_minus8);
3445
3446 pps.init_qp_minus26 = r.read_se_bounded(-(26 + qp_bd_offset_y), 25)?;
3447 pps.qp_bd_offset_y = qp_bd_offset_y as u32;
3448 pps.constrained_intra_pred_flag = r.read_bit()?;
3449 pps.transform_skip_enabled_flag = r.read_bit()?;
3450 pps.cu_qp_delta_enabled_flag = r.read_bit()?;
3451
3452 if pps.cu_qp_delta_enabled_flag {
3453 pps.diff_cu_qp_delta_depth =
3454 r.read_ue_max(u32::from(sps.log2_diff_max_min_luma_coding_block_size))?;
3455 }
3456
3457 pps.cb_qp_offset = r.read_se_bounded(-12, 12)?;
3458 pps.cr_qp_offset = r.read_se_bounded(-12, 12)?;
3459
3460 pps.slice_chroma_qp_offsets_present_flag = r.read_bit()?;
3461 pps.weighted_pred_flag = r.read_bit()?;
3462 pps.weighted_bipred_flag = r.read_bit()?;
3463 pps.transquant_bypass_enabled_flag = r.read_bit()?;
3464 pps.tiles_enabled_flag = r.read_bit()?;
3465 pps.entropy_coding_sync_enabled_flag = r.read_bit()?;
3466
3467 if pps.tiles_enabled_flag {
3469 pps.num_tile_columns_minus1 = r.read_ue_max(sps.pic_width_in_ctbs_y - 1)?;
3470 pps.num_tile_rows_minus1 = r.read_ue_max(sps.pic_height_in_ctbs_y - 1)?;
3471 pps.uniform_spacing_flag = r.read_bit()?;
3472 if !pps.uniform_spacing_flag {
3473 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] =
3474 sps.pic_width_in_ctbs_y - 1;
3475
3476 for i in 0..usize::from(pps.num_tile_columns_minus1) {
3477 pps.column_width_minus1[i] = r.read_ue_max(
3478 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] - 1,
3479 )?;
3480 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] -=
3481 pps.column_width_minus1[i] + 1;
3482 }
3483
3484 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] =
3485 sps.pic_height_in_ctbs_y - 1;
3486
3487 for i in 0..usize::from(pps.num_tile_rows_minus1) {
3488 pps.row_height_minus1[i] = r.read_ue_max(
3489 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] - 1,
3490 )?;
3491 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] -=
3492 pps.row_height_minus1[i] + 1;
3493 }
3494 } else {
3495 let nrows = u32::from(pps.num_tile_rows_minus1) + 1;
3496 let ncols = u32::from(pps.num_tile_columns_minus1) + 1;
3497
3498 for j in 0..ncols {
3499 pps.column_width_minus1[j as usize] = ((j + 1) * sps.pic_width_in_ctbs_y)
3500 / ncols
3501 - j * sps.pic_width_in_ctbs_y / ncols
3502 - 1;
3503 }
3504
3505 for j in 0..nrows {
3506 pps.row_height_minus1[j as usize] = ((j + 1) * sps.pic_height_in_ctbs_y)
3507 / nrows
3508 - j * sps.pic_height_in_ctbs_y / nrows
3509 - 1;
3510 }
3511 }
3512
3513 pps.loop_filter_across_tiles_enabled_flag = r.read_bit()?;
3514 }
3515
3516 pps.loop_filter_across_slices_enabled_flag = r.read_bit()?;
3517 pps.deblocking_filter_control_present_flag = r.read_bit()?;
3518
3519 if pps.deblocking_filter_control_present_flag {
3520 pps.deblocking_filter_override_enabled_flag = r.read_bit()?;
3521 pps.deblocking_filter_disabled_flag = r.read_bit()?;
3522 if !pps.deblocking_filter_disabled_flag {
3523 pps.beta_offset_div2 = r.read_se_bounded(-6, 6)?;
3524 pps.tc_offset_div2 = r.read_se_bounded(-6, 6)?;
3525 }
3526 }
3527
3528 pps.scaling_list_data_present_flag = r.read_bit()?;
3529
3530 if pps.scaling_list_data_present_flag {
3531 Self::parse_scaling_list_data(&mut pps.scaling_list, &mut r)?;
3532 } else {
3533 for size_id in 0..4 {
3534 let mut matrix_id = 0;
3535 while matrix_id < 6 {
3536 Self::fill_default_scaling_list(&mut pps.scaling_list, size_id, matrix_id);
3537 let step = if size_id == 3 { 3 } else { 1 };
3538 matrix_id += step;
3539 }
3540 }
3541 }
3542
3543 pps.lists_modification_present_flag = r.read_bit()?;
3544 pps.log2_parallel_merge_level_minus2 = r.read_ue_max(sps.ctb_log2_size_y - 2)?;
3545 pps.slice_segment_header_extension_present_flag = r.read_bit()?;
3546
3547 pps.extension_present_flag = r.read_bit()?;
3548 if pps.extension_present_flag {
3549 pps.range_extension_flag = r.read_bit()?;
3550
3551 if pps.range_extension_flag {
3552 Self::parse_pps_range_extension(&mut pps, sps, &mut r)?;
3553 }
3554
3555 let multilayer_extension_flag = r.read_bit()?;
3556 if multilayer_extension_flag {
3557 return Err("Multilayer extension is not supported".into());
3558 }
3559
3560 let three_d_extension_flag = r.read_bit()?;
3561 if three_d_extension_flag {
3562 return Err("3D extension is not supported".into());
3563 }
3564
3565 pps.scc_extension_flag = r.read_bit()?;
3566 if pps.scc_extension_flag {
3567 Self::parse_pps_scc_extension(&mut pps, sps, &mut r)?;
3568 }
3569
3570 r.skip_bits(4)?; }
3572
3573 log::debug!("Parsed PPS({}), NAL size was {}", pps.pic_parameter_set_id, nalu.size);
3574
3575 if self.active_ppses.keys().len() >= MAX_PPS_COUNT {
3576 return Err("Broken Data: number of active PPSs > MAX_PPS_COUNT".into());
3577 }
3578
3579 let key = pps.pic_parameter_set_id;
3580 let pps = Rc::new(pps);
3581 self.active_ppses.remove(&key);
3582 Ok(self.active_ppses.entry(key).or_insert(pps))
3583 }
3584
3585 fn parse_pred_weight_table(
3586 hdr: &mut SliceHeader,
3587 r: &mut BitReader,
3588 sps: &Sps,
3589 ) -> Result<(), String> {
3590 let pwt = &mut hdr.pred_weight_table;
3591
3592 pwt.luma_log2_weight_denom = r.read_ue_max(7)?;
3593 if sps.chroma_array_type != 0 {
3594 pwt.delta_chroma_log2_weight_denom = r.read_se()?;
3595 pwt.chroma_log2_weight_denom = (pwt.luma_log2_weight_denom as i32
3596 + pwt.delta_chroma_log2_weight_denom as i32)
3597 .try_into()
3598 .map_err(|_| {
3599 String::from("Integer overflow on chroma_log2_weight_denom calculation")
3600 })?;
3601 }
3602
3603 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) {
3604 pwt.luma_weight_l0_flag[i] = r.read_bit()?;
3605 }
3606
3607 if sps.chroma_array_type != 0 {
3608 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) {
3609 pwt.chroma_weight_l0_flag[i] = r.read_bit()?;
3610 }
3611 }
3612
3613 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) {
3614 if pwt.luma_weight_l0_flag[i] {
3615 pwt.delta_luma_weight_l0[i] = r.read_se_bounded(-128, 127)?;
3616 pwt.luma_offset_l0[i] = r.read_se_bounded(-128, 127)?;
3617 }
3618
3619 if pwt.chroma_weight_l0_flag[i] {
3620 for j in 0..2 {
3621 pwt.delta_chroma_weight_l0[i][j] = r.read_se_bounded(-128, 127)?;
3622 pwt.delta_chroma_offset_l0[i][j] = r.read_se_bounded(
3623 -4 * sps.wp_offset_half_range_c as i32,
3624 4 * sps.wp_offset_half_range_c as i32 - 1,
3625 )?;
3626 }
3627 }
3628 }
3629
3630 if hdr.type_.is_b() {
3631 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) {
3632 pwt.luma_weight_l1_flag[i] = r.read_bit()?;
3633 }
3634
3635 if sps.chroma_format_idc != 0 {
3636 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) {
3637 pwt.chroma_weight_l1_flag[i] = r.read_bit()?;
3638 }
3639 }
3640
3641 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) {
3642 if pwt.luma_weight_l1_flag[i] {
3643 pwt.delta_luma_weight_l1[i] = r.read_se_bounded(-128, 127)?;
3644 pwt.luma_offset_l1[i] = r.read_se_bounded(-128, 127)?;
3645 }
3646
3647 if pwt.chroma_weight_l1_flag[i] {
3648 for j in 0..2 {
3649 pwt.delta_chroma_weight_l1[i][j] = r.read_se_bounded(-128, 127)?;
3650 pwt.delta_chroma_offset_l1[i][j] = r.read_se_bounded(
3651 -4 * sps.wp_offset_half_range_c as i32,
3652 4 * sps.wp_offset_half_range_c as i32 - 1,
3653 )?;
3654 }
3655 }
3656 }
3657 }
3658
3659 Ok(())
3660 }
3661
3662 fn parse_ref_pic_lists_modification(
3663 hdr: &mut SliceHeader,
3664 r: &mut BitReader,
3665 ) -> Result<(), String> {
3666 let rplm = &mut hdr.ref_pic_list_modification;
3667
3668 rplm.ref_pic_list_modification_flag_l0 = r.read_bit()?;
3669 if rplm.ref_pic_list_modification_flag_l0 {
3670 for _ in 0..=hdr.num_ref_idx_l0_active_minus1 {
3671 let num_bits = (hdr.num_pic_total_curr as f64).log2().ceil() as _;
3672
3673 let entry = r.read_bits(num_bits)?;
3674
3675 if entry > hdr.num_pic_total_curr - 1 {
3676 return Err(format!(
3677 "Invalid list_entry_l0 {}, expected at max NumPicTotalCurr - 1: {}",
3678 entry,
3679 hdr.num_pic_total_curr - 1
3680 ));
3681 }
3682
3683 rplm.list_entry_l0.push(entry);
3684 }
3685 }
3686
3687 if hdr.type_.is_b() {
3688 rplm.ref_pic_list_modification_flag_l1 = r.read_bit()?;
3689 if rplm.ref_pic_list_modification_flag_l1 {
3690 for _ in 0..=hdr.num_ref_idx_l1_active_minus1 {
3691 let num_bits = (hdr.num_pic_total_curr as f64).log2().ceil() as _;
3692
3693 let entry = r.read_bits(num_bits)?;
3694
3695 if entry > hdr.num_pic_total_curr - 1 {
3696 return Err(format!(
3697 "Invalid list_entry_l1 {}, expected at max NumPicTotalCurr - 1: {}",
3698 entry,
3699 hdr.num_pic_total_curr - 1
3700 ));
3701 }
3702
3703 rplm.list_entry_l1.push(entry);
3704 }
3705 }
3706 }
3707
3708 Ok(())
3709 }
3710
3711 pub fn slice_header_set_defaults(hdr: &mut SliceHeader, sps: &Sps, pps: &Pps) {
3713 hdr.deblocking_filter_disabled_flag = pps.deblocking_filter_disabled_flag;
3715 hdr.beta_offset_div2 = pps.beta_offset_div2;
3716 hdr.tc_offset_div2 = pps.tc_offset_div2;
3717 hdr.loop_filter_across_slices_enabled_flag = pps.loop_filter_across_slices_enabled_flag;
3718 hdr.curr_rps_idx = sps.num_short_term_ref_pic_sets;
3719 hdr.use_integer_mv_flag = sps.scc_extension.motion_vector_resolution_control_idc != 0;
3720 }
3721
3722 pub fn parse_slice_header<'a>(&mut self, nalu: Nalu<'a>) -> Result<Slice<'a>, String> {
3724 if !matches!(
3725 nalu.header.type_,
3726 NaluType::TrailN
3727 | NaluType::TrailR
3728 | NaluType::TsaN
3729 | NaluType::TsaR
3730 | NaluType::StsaN
3731 | NaluType::StsaR
3732 | NaluType::RadlN
3733 | NaluType::RadlR
3734 | NaluType::RaslN
3735 | NaluType::RaslR
3736 | NaluType::BlaWLp
3737 | NaluType::BlaWRadl
3738 | NaluType::BlaNLp
3739 | NaluType::IdrWRadl
3740 | NaluType::IdrNLp
3741 | NaluType::CraNut,
3742 ) {
3743 return Err(format!("Invalid NALU type: {:?} is not a slice NALU", nalu.header.type_));
3744 }
3745
3746 let data = nalu.as_ref();
3747 let nalu_header = &nalu.header;
3748 let hdr_len = nalu_header.len();
3749 let mut r = BitReader::new(&data[hdr_len..], true);
3751
3752 let mut hdr =
3753 SliceHeader { first_slice_segment_in_pic_flag: r.read_bit()?, ..Default::default() };
3754
3755 if nalu.header.type_.is_irap() {
3756 hdr.no_output_of_prior_pics_flag = r.read_bit()?;
3757 }
3758
3759 hdr.pic_parameter_set_id = r.read_ue_max(63)?;
3760
3761 let pps = self.get_pps(hdr.pic_parameter_set_id).ok_or::<String>(format!(
3762 "Could not get PPS for pic_parameter_set_id {}",
3763 hdr.pic_parameter_set_id
3764 ))?;
3765
3766 let sps = &pps.sps;
3767
3768 Self::slice_header_set_defaults(&mut hdr, sps, pps);
3769
3770 if !hdr.first_slice_segment_in_pic_flag {
3771 if pps.dependent_slice_segments_enabled_flag {
3772 hdr.dependent_slice_segment_flag = r.read_bit()?;
3773 }
3774
3775 let num_bits = (sps.pic_size_in_ctbs_y as f64).log2().ceil() as _;
3776 hdr.segment_address = r.read_bits(num_bits)?;
3777
3778 if hdr.segment_address > sps.pic_size_in_ctbs_y - 1 {
3779 return Err(format!("Invalid slice_segment_address {}", hdr.segment_address));
3780 }
3781 }
3782
3783 if !hdr.dependent_slice_segment_flag {
3784 r.skip_bits(usize::from(pps.num_extra_slice_header_bits))?;
3785
3786 let slice_type: u32 = r.read_ue()?;
3787 hdr.type_ = SliceType::try_from(slice_type)?;
3788
3789 if pps.output_flag_present_flag {
3790 hdr.pic_output_flag = r.read_bit()?;
3791 }
3792
3793 if sps.separate_colour_plane_flag {
3794 hdr.colour_plane_id = r.read_bits(2)?;
3795 }
3796
3797 if !matches!(nalu_header.type_, NaluType::IdrWRadl | NaluType::IdrNLp) {
3798 let num_bits = usize::from(sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
3799 hdr.pic_order_cnt_lsb = r.read_bits(num_bits)?;
3800
3801 if u32::from(hdr.pic_order_cnt_lsb)
3802 > 2u32.pow(u32::from(sps.log2_max_pic_order_cnt_lsb_minus4 + 4))
3803 {
3804 return Err(format!("Invalid pic_order_cnt_lsb {}", hdr.pic_order_cnt_lsb));
3805 }
3806
3807 hdr.short_term_ref_pic_set_sps_flag = r.read_bit()?;
3808
3809 if !hdr.short_term_ref_pic_set_sps_flag {
3810 let epb_before = r.num_epb();
3811 let bits_left_before = r.num_bits_left();
3812
3813 let st_rps_idx = sps.num_short_term_ref_pic_sets;
3814
3815 Self::parse_short_term_ref_pic_set(
3816 sps,
3817 &mut hdr.short_term_ref_pic_set,
3818 &mut r,
3819 st_rps_idx,
3820 )?;
3821
3822 hdr.st_rps_bits = ((bits_left_before - r.num_bits_left())
3823 - 8 * (r.num_epb() - epb_before))
3824 as u32;
3825 } else if sps.num_short_term_ref_pic_sets > 1 {
3826 let num_bits = (sps.num_short_term_ref_pic_sets as f64).log2().ceil() as _;
3827 hdr.short_term_ref_pic_set_idx = r.read_bits(num_bits)?;
3828
3829 if hdr.short_term_ref_pic_set_idx > sps.num_short_term_ref_pic_sets - 1 {
3830 return Err(format!(
3831 "Invalid short_term_ref_pic_set_idx {}",
3832 hdr.short_term_ref_pic_set_idx
3833 ));
3834 }
3835 }
3836
3837 if hdr.short_term_ref_pic_set_sps_flag {
3838 hdr.curr_rps_idx = hdr.short_term_ref_pic_set_idx;
3839 }
3840
3841 if sps.long_term_ref_pics_present_flag {
3842 if sps.num_long_term_ref_pics_sps > 0 {
3843 hdr.num_long_term_sps =
3844 r.read_ue_max(u32::from(sps.num_long_term_ref_pics_sps))?;
3845 }
3846
3847 hdr.num_long_term_pics = r.read_ue_max(
3848 MAX_LONG_TERM_REF_PIC_SETS as u32 - u32::from(hdr.num_long_term_sps),
3849 )?;
3850
3851 let num_lt = hdr.num_long_term_sps + hdr.num_long_term_pics;
3852 for i in 0..usize::from(num_lt) {
3853 if i < usize::from(hdr.num_long_term_sps) {
3863 if sps.num_long_term_ref_pics_sps > 1 {
3864 let num_bits =
3865 (sps.num_long_term_ref_pics_sps as f64).log2().ceil() as _;
3866
3867 hdr.lt_idx_sps[i] = r.read_bits(num_bits)?;
3868
3869 if hdr.lt_idx_sps[i] > sps.num_long_term_ref_pics_sps - 1 {
3870 return Err(format!(
3871 "Invalid lt_idx_sps[{}] {}",
3872 i, hdr.lt_idx_sps[i]
3873 ));
3874 }
3875 }
3876
3877 hdr.poc_lsb_lt[i] =
3878 sps.lt_ref_pic_poc_lsb_sps[usize::from(hdr.lt_idx_sps[i])];
3879 hdr.used_by_curr_pic_lt[i] =
3880 sps.used_by_curr_pic_lt_sps_flag[usize::from(hdr.lt_idx_sps[i])];
3881 } else {
3882 let num_bits = usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4;
3883 hdr.poc_lsb_lt[i] = r.read_bits(num_bits)?;
3884 hdr.used_by_curr_pic_lt[i] = r.read_bit()?;
3885 }
3886
3887 hdr.delta_poc_msb_present_flag[i] = r.read_bit()?;
3888 if hdr.delta_poc_msb_present_flag[i] {
3889 let max =
3895 2u32.pow(32 - u32::from(sps.log2_max_pic_order_cnt_lsb_minus4) - 4);
3896 hdr.delta_poc_msb_cycle_lt[i] = r.read_ue_max(max)?;
3897 }
3898 if i != 0 && i != usize::from(hdr.num_long_term_sps) {
3900 hdr.delta_poc_msb_cycle_lt[i] += hdr.delta_poc_msb_cycle_lt[i - 1];
3901 }
3902 }
3903 }
3904
3905 if sps.temporal_mvp_enabled_flag {
3906 hdr.temporal_mvp_enabled_flag = r.read_bit()?;
3907 }
3908 }
3909
3910 if sps.sample_adaptive_offset_enabled_flag {
3911 hdr.sao_luma_flag = r.read_bit()?;
3912 if sps.chroma_array_type != 0 {
3913 hdr.sao_chroma_flag = r.read_bit()?;
3914 }
3915 }
3916
3917 if hdr.type_.is_p() || hdr.type_.is_b() {
3918 hdr.num_ref_idx_active_override_flag = r.read_bit()?;
3919 if hdr.num_ref_idx_active_override_flag {
3920 hdr.num_ref_idx_l0_active_minus1 = r.read_ue_max(MAX_REF_IDX_ACTIVE - 1)?;
3921 if hdr.type_.is_b() {
3922 hdr.num_ref_idx_l1_active_minus1 = r.read_ue_max(MAX_REF_IDX_ACTIVE - 1)?;
3923 }
3924 } else {
3925 hdr.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1;
3926 hdr.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1;
3927 }
3928
3929 let mut num_pic_total_curr = 0;
3931 let rps = if hdr.short_term_ref_pic_set_sps_flag {
3932 sps.short_term_ref_pic_set
3933 .get(usize::from(hdr.curr_rps_idx))
3934 .ok_or::<String>("Invalid RPS".into())?
3935 } else {
3936 &hdr.short_term_ref_pic_set
3937 };
3938
3939 for i in 0..usize::from(rps.num_negative_pics) {
3940 if rps.used_by_curr_pic_s0[i] {
3941 num_pic_total_curr += 1;
3942 }
3943 }
3944
3945 for i in 0..usize::from(rps.num_positive_pics) {
3946 if rps.used_by_curr_pic_s1[i] {
3947 num_pic_total_curr += 1;
3948 }
3949 }
3950
3951 for i in 0..usize::from(hdr.num_long_term_sps + hdr.num_long_term_pics) {
3952 if hdr.used_by_curr_pic_lt[i] {
3953 num_pic_total_curr += 1;
3954 }
3955 }
3956
3957 if pps.scc_extension.curr_pic_ref_enabled_flag {
3958 num_pic_total_curr += 1;
3959 }
3960
3961 hdr.num_pic_total_curr = num_pic_total_curr;
3962
3963 if pps.lists_modification_present_flag && hdr.num_pic_total_curr > 1 {
3964 Self::parse_ref_pic_lists_modification(&mut hdr, &mut r)?;
3965 }
3966
3967 if hdr.type_.is_b() {
3968 hdr.mvd_l1_zero_flag = r.read_bit()?;
3969 }
3970
3971 if pps.cabac_init_present_flag {
3972 hdr.cabac_init_flag = r.read_bit()?;
3973 }
3974
3975 if hdr.temporal_mvp_enabled_flag {
3976 if hdr.type_.is_b() {
3977 hdr.collocated_from_l0_flag = r.read_bit()?;
3978 }
3979
3980 if (hdr.collocated_from_l0_flag && hdr.num_ref_idx_l0_active_minus1 > 0)
3981 || (!hdr.collocated_from_l0_flag && hdr.num_ref_idx_l1_active_minus1 > 0)
3982 {
3983 let max = if (hdr.type_.is_p() || hdr.type_.is_b())
3984 && hdr.collocated_from_l0_flag
3985 {
3986 hdr.num_ref_idx_l0_active_minus1
3987 } else if hdr.type_.is_b() && !hdr.collocated_from_l0_flag {
3988 hdr.num_ref_idx_l1_active_minus1
3989 } else {
3990 return Err("Invalid value for collocated_ref_idx".into());
3991 };
3992
3993 {
3994 hdr.collocated_ref_idx = r.read_ue_max(u32::from(max))?;
3995 }
3996 }
3997 }
3998
3999 if (pps.weighted_pred_flag && hdr.type_.is_p())
4000 || (pps.weighted_bipred_flag && hdr.type_.is_b())
4001 {
4002 Self::parse_pred_weight_table(&mut hdr, &mut r, sps)?;
4003 }
4004
4005 hdr.five_minus_max_num_merge_cand = r.read_ue()?;
4006
4007 if sps.scc_extension.motion_vector_resolution_control_idc == 2 {
4008 hdr.use_integer_mv_flag = r.read_bit()?;
4009 }
4010 }
4011
4012 hdr.qp_delta = r.read_se_bounded(-87, 77)?;
4013
4014 let slice_qp_y = (26 + pps.init_qp_minus26 + hdr.qp_delta) as i32;
4015 if slice_qp_y < -(pps.qp_bd_offset_y as i32) || slice_qp_y > 51 {
4016 return Err(format!("Invalid slice_qp_delta: {}", hdr.qp_delta));
4017 }
4018
4019 if pps.slice_chroma_qp_offsets_present_flag {
4020 hdr.cb_qp_offset = r.read_se_bounded(-12, 12)?;
4021
4022 let qp_offset = pps.cb_qp_offset + hdr.cb_qp_offset;
4023 if !(-12..=12).contains(&qp_offset) {
4024 return Err(format!(
4025 "Invalid value for slice_cb_qp_offset: {}",
4026 hdr.cb_qp_offset
4027 ));
4028 }
4029
4030 hdr.cr_qp_offset = r.read_se_bounded(-12, 12)?;
4031
4032 let qp_offset = pps.cr_qp_offset + hdr.cr_qp_offset;
4033 if !(-12..=12).contains(&qp_offset) {
4034 return Err(format!(
4035 "Invalid value for slice_cr_qp_offset: {}",
4036 hdr.cr_qp_offset
4037 ));
4038 }
4039 }
4040
4041 if pps.scc_extension.slice_act_qp_offsets_present_flag {
4042 hdr.slice_act_y_qp_offset = r.read_se_bounded(-12, 12)?;
4043 hdr.slice_act_cb_qp_offset = r.read_se_bounded(-12, 12)?;
4044 hdr.slice_act_cr_qp_offset = r.read_se_bounded(-12, 12)?;
4045 }
4046
4047 if pps.range_extension.chroma_qp_offset_list_enabled_flag {
4048 hdr.cu_chroma_qp_offset_enabled_flag = r.read_bit()?;
4049 }
4050
4051 if pps.deblocking_filter_override_enabled_flag {
4052 hdr.deblocking_filter_override_flag = r.read_bit()?;
4053 }
4054
4055 if hdr.deblocking_filter_override_flag {
4056 hdr.deblocking_filter_disabled_flag = r.read_bit()?;
4057 if !hdr.deblocking_filter_disabled_flag {
4058 hdr.beta_offset_div2 = r.read_se_bounded(-6, 6)?;
4059 hdr.tc_offset_div2 = r.read_se_bounded(-6, 6)?;
4060 }
4061 }
4062
4063 if pps.loop_filter_across_slices_enabled_flag
4064 && (hdr.sao_luma_flag
4065 || hdr.sao_chroma_flag
4066 || !hdr.deblocking_filter_disabled_flag)
4067 {
4068 hdr.loop_filter_across_slices_enabled_flag = r.read_bit()?;
4069 }
4070 }
4071
4072 if pps.tiles_enabled_flag || pps.entropy_coding_sync_enabled_flag {
4073 let max = if !pps.tiles_enabled_flag && pps.entropy_coding_sync_enabled_flag {
4074 sps.pic_height_in_ctbs_y - 1
4075 } else if pps.tiles_enabled_flag && !pps.entropy_coding_sync_enabled_flag {
4076 u32::from((pps.num_tile_columns_minus1 + 1) * (pps.num_tile_rows_minus1 + 1) - 1)
4077 } else {
4078 (u32::from(pps.num_tile_columns_minus1) + 1) * sps.pic_height_in_ctbs_y - 1
4079 };
4080
4081 hdr.num_entry_point_offsets = r.read_ue_max(max)?;
4082 if hdr.num_entry_point_offsets > 0 {
4083 hdr.offset_len_minus1 = r.read_ue_max(31)?;
4084 for i in 0..hdr.num_entry_point_offsets as usize {
4085 let num_bits = usize::from(hdr.offset_len_minus1 + 1);
4086 hdr.entry_point_offset_minus1[i] = r.read_bits(num_bits)?;
4087 }
4088 }
4089 }
4090
4091 if pps.slice_segment_header_extension_present_flag {
4092 let segment_header_extension_length = r.read_ue_max(256)?;
4093 for _ in 0..segment_header_extension_length {
4094 r.skip_bits(8)?; }
4096 }
4097
4098 r.skip_bits(1)?; let num_bits = r.num_bits_left() % 8;
4101 r.skip_bits(num_bits)?;
4102
4103 let epb = r.num_epb();
4104 hdr.header_bit_size = ((nalu.size - epb) * 8 - r.num_bits_left()) as u32;
4105
4106 hdr.n_emulation_prevention_bytes = epb as u32;
4107
4108 log::debug!("Parsed slice {:?}, NAL size was {}", nalu_header.type_, nalu.size);
4109
4110 Ok(Slice { header: hdr, nalu })
4111 }
4112
4113 pub fn get_vps(&self, vps_id: u8) -> Option<&Rc<Vps>> {
4115 self.active_vpses.get(&vps_id)
4116 }
4117
4118 pub fn get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>> {
4120 self.active_spses.get(&sps_id)
4121 }
4122
4123 pub fn get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>> {
4125 self.active_ppses.get(&pps_id)
4126 }
4127}
4128
4129#[cfg(test)]
4130mod tests {
4131 use std::io::Cursor;
4132
4133 use crate::codec::h264::nalu::Nalu;
4134 use crate::codec::h265::parser::Level;
4135 use crate::codec::h265::parser::NaluHeader;
4136 use crate::codec::h265::parser::NaluType;
4137 use crate::codec::h265::parser::Parser;
4138 use crate::codec::h265::parser::SliceType;
4139
4140 const STREAM_BEAR: &[u8] = include_bytes!("test_data/bear.h265");
4141 const STREAM_BEAR_NUM_NALUS: usize = 35;
4142
4143 const STREAM_BBB: &[u8] = include_bytes!("test_data/bbb.h265");
4144 const STREAM_BBB_NUM_NALUS: usize = 64;
4145
4146 const STREAM_TEST25FPS: &[u8] = include_bytes!("test_data/test-25fps.h265");
4147 const STREAM_TEST25FPS_NUM_NALUS: usize = 254;
4148
4149 const STREAM_TEST_25_FPS_SLICE_0: &[u8] =
4150 include_bytes!("test_data/test-25fps-h265-slice-data-0.bin");
4151 const STREAM_TEST_25_FPS_SLICE_1: &[u8] =
4152 include_bytes!("test_data/test-25fps-h265-slice-data-1.bin");
4153
4154 fn dispatch_parse_call(parser: &mut Parser, nalu: Nalu<NaluHeader>) -> Result<(), String> {
4155 match nalu.header.type_ {
4156 NaluType::TrailN
4157 | NaluType::TrailR
4158 | NaluType::TsaN
4159 | NaluType::TsaR
4160 | NaluType::StsaN
4161 | NaluType::StsaR
4162 | NaluType::RadlN
4163 | NaluType::RadlR
4164 | NaluType::RaslN
4165 | NaluType::RaslR
4166 | NaluType::BlaWLp
4167 | NaluType::BlaWRadl
4168 | NaluType::BlaNLp
4169 | NaluType::IdrWRadl
4170 | NaluType::IdrNLp
4171 | NaluType::CraNut => {
4172 parser.parse_slice_header(nalu).unwrap();
4173 }
4174 NaluType::VpsNut => {
4175 parser.parse_vps(&nalu).unwrap();
4176 }
4177 NaluType::SpsNut => {
4178 parser.parse_sps(&nalu).unwrap();
4179 }
4180 NaluType::PpsNut => {
4181 parser.parse_pps(&nalu).unwrap();
4182 }
4183 _ => { }
4184 }
4185 Ok(())
4186 }
4187
4188 fn find_nalu_by_type(
4189 bitstream: &[u8],
4190 nalu_type: NaluType,
4191 mut nskip: i32,
4192 ) -> Option<Nalu<NaluHeader>> {
4193 let mut cursor = Cursor::new(bitstream);
4194 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4195 if nalu.header.type_ == nalu_type {
4196 if nskip == 0 {
4197 return Some(nalu);
4198 } else {
4199 nskip -= 1;
4200 }
4201 }
4202 }
4203
4204 None
4205 }
4206
4207 #[test]
4209 fn parse_nalus_from_stream_file() {
4210 let mut cursor = Cursor::new(STREAM_BEAR);
4211 let mut num_nalus = 0;
4212 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() {
4213 num_nalus += 1;
4214 }
4215
4216 assert_eq!(num_nalus, STREAM_BEAR_NUM_NALUS);
4217
4218 let mut cursor = Cursor::new(STREAM_BBB);
4219 let mut num_nalus = 0;
4220 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() {
4221 num_nalus += 1;
4222 }
4223
4224 assert_eq!(num_nalus, STREAM_BBB_NUM_NALUS);
4225
4226 let mut cursor = Cursor::new(STREAM_TEST25FPS);
4227 let mut num_nalus = 0;
4228 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() {
4229 num_nalus += 1;
4230 }
4231
4232 assert_eq!(num_nalus, STREAM_TEST25FPS_NUM_NALUS);
4233 }
4234
4235 #[test]
4238 fn parse_syntax_from_nals() {
4239 let mut cursor = Cursor::new(STREAM_BBB);
4240 let mut parser = Parser::default();
4241
4242 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4243 dispatch_parse_call(&mut parser, nalu).unwrap();
4244 }
4245
4246 let mut cursor = Cursor::new(STREAM_BEAR);
4247 let mut parser = Parser::default();
4248
4249 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4250 dispatch_parse_call(&mut parser, nalu).unwrap();
4251 }
4252
4253 let mut cursor = Cursor::new(STREAM_TEST25FPS);
4254 let mut parser = Parser::default();
4255
4256 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) {
4257 dispatch_parse_call(&mut parser, nalu).unwrap();
4258 }
4259 }
4260
4261 #[test]
4263 fn chromium_vps_parsing() {
4264 let mut cursor = Cursor::new(STREAM_BEAR);
4265 let mut parser = Parser::default();
4266
4267 let vps_nalu = Nalu::<NaluHeader>::next(&mut cursor).unwrap();
4268 let vps = parser.parse_vps(&vps_nalu).unwrap();
4269
4270 assert!(vps.base_layer_internal_flag);
4271 assert!(vps.base_layer_available_flag);
4272 assert_eq!(vps.max_layers_minus1, 0);
4273 assert_eq!(vps.max_sub_layers_minus1, 0);
4274 assert!(vps.temporal_id_nesting_flag);
4275 assert_eq!(vps.profile_tier_level.general_profile_idc, 1);
4276 assert_eq!(vps.profile_tier_level.general_level_idc, Level::L2);
4277 assert_eq!(vps.max_dec_pic_buffering_minus1[0], 4);
4278 assert_eq!(vps.max_num_reorder_pics[0], 2);
4279 assert_eq!(vps.max_latency_increase_plus1[0], 0);
4280 for i in 1..7 {
4281 assert_eq!(vps.max_dec_pic_buffering_minus1[i], 0);
4282 assert_eq!(vps.max_num_reorder_pics[i], 0);
4283 assert_eq!(vps.max_latency_increase_plus1[i], 0);
4284 }
4285 assert_eq!(vps.max_layer_id, 0);
4286 assert_eq!(vps.num_layer_sets_minus1, 0);
4287 assert!(!vps.timing_info_present_flag);
4288 }
4289
4290 #[test]
4292 fn chromium_sps_parsing() {
4293 let mut parser = Parser::default();
4294 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap();
4295 let sps = parser.parse_sps(&sps_nalu).unwrap();
4296
4297 assert_eq!(sps.max_sub_layers_minus1, 0);
4298 assert_eq!(sps.profile_tier_level.general_profile_idc, 1);
4299 assert_eq!(sps.profile_tier_level.general_level_idc, Level::L2);
4300 assert_eq!(sps.seq_parameter_set_id, 0);
4301 assert_eq!(sps.chroma_format_idc, 1);
4302 assert!(!sps.separate_colour_plane_flag);
4303 assert_eq!(sps.pic_width_in_luma_samples, 320);
4304 assert_eq!(sps.pic_height_in_luma_samples, 184);
4305 assert_eq!(sps.conf_win_left_offset, 0);
4306 assert_eq!(sps.conf_win_right_offset, 0);
4307 assert_eq!(sps.conf_win_top_offset, 0);
4308 assert_eq!(sps.conf_win_bottom_offset, 2);
4309 assert_eq!(sps.bit_depth_luma_minus8, 0);
4310 assert_eq!(sps.bit_depth_chroma_minus8, 0);
4311 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 4);
4312 assert_eq!(sps.max_dec_pic_buffering_minus1[0], 4);
4313 assert_eq!(sps.max_num_reorder_pics[0], 2);
4314 assert_eq!(sps.max_latency_increase_plus1[0], 0);
4315 for i in 1..7 {
4316 assert_eq!(sps.max_dec_pic_buffering_minus1[i], 0);
4317 assert_eq!(sps.max_num_reorder_pics[i], 0);
4318 assert_eq!(sps.max_latency_increase_plus1[i], 0);
4319 }
4320 assert_eq!(sps.log2_min_luma_coding_block_size_minus3, 0);
4321 assert_eq!(sps.log2_diff_max_min_luma_coding_block_size, 3);
4322 assert_eq!(sps.log2_min_luma_transform_block_size_minus2, 0);
4323 assert_eq!(sps.log2_diff_max_min_luma_transform_block_size, 3);
4324 assert_eq!(sps.max_transform_hierarchy_depth_inter, 0);
4325 assert_eq!(sps.max_transform_hierarchy_depth_intra, 0);
4326 assert!(!sps.scaling_list_enabled_flag);
4327 assert!(!sps.scaling_list_data_present_flag);
4328 assert!(!sps.amp_enabled_flag);
4329 assert!(sps.sample_adaptive_offset_enabled_flag);
4330 assert!(!sps.pcm_enabled_flag);
4331 assert_eq!(sps.pcm_sample_bit_depth_luma_minus1, 0);
4332 assert_eq!(sps.pcm_sample_bit_depth_chroma_minus1, 0);
4333 assert_eq!(sps.log2_min_pcm_luma_coding_block_size_minus3, 0);
4334 assert_eq!(sps.log2_diff_max_min_pcm_luma_coding_block_size, 0);
4335 assert!(!sps.pcm_loop_filter_disabled_flag);
4336 assert_eq!(sps.num_short_term_ref_pic_sets, 0);
4337 assert_eq!(sps.num_long_term_ref_pics_sps, 0);
4338 assert!(sps.temporal_mvp_enabled_flag);
4339 assert!(sps.strong_intra_smoothing_enabled_flag);
4340 assert_eq!(sps.vui_parameters.sar_width, 0);
4341 assert_eq!(sps.vui_parameters.sar_height, 0);
4342 assert!(!sps.vui_parameters.video_full_range_flag);
4343 assert!(!sps.vui_parameters.colour_description_present_flag);
4344
4345 assert_eq!(sps.vui_parameters.colour_primaries, 2);
4348 assert_eq!(sps.vui_parameters.transfer_characteristics, 2);
4349 assert_eq!(sps.vui_parameters.matrix_coeffs, 2);
4350
4351 assert_eq!(sps.vui_parameters.def_disp_win_left_offset, 0);
4352 assert_eq!(sps.vui_parameters.def_disp_win_right_offset, 0);
4353 assert_eq!(sps.vui_parameters.def_disp_win_top_offset, 0);
4354 assert_eq!(sps.vui_parameters.def_disp_win_bottom_offset, 0);
4355 }
4356
4357 #[test]
4359 fn chromium_pps_parsing() {
4360 let mut parser = Parser::default();
4361
4362 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap();
4364 parser.parse_sps(&sps_nalu).unwrap();
4365
4366 let pps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::PpsNut, 0).unwrap();
4367 let pps = parser.parse_pps(&pps_nalu).unwrap();
4368
4369 assert_eq!(pps.pic_parameter_set_id, 0);
4370 assert_eq!(pps.seq_parameter_set_id, 0);
4371 assert!(!pps.dependent_slice_segments_enabled_flag);
4372 assert!(!pps.output_flag_present_flag);
4373 assert_eq!(pps.num_extra_slice_header_bits, 0);
4374 assert!(pps.sign_data_hiding_enabled_flag);
4375 assert!(!pps.cabac_init_present_flag);
4376 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0);
4377 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0);
4378 assert_eq!(pps.init_qp_minus26, 0);
4379 assert!(!pps.constrained_intra_pred_flag);
4380 assert!(!pps.transform_skip_enabled_flag);
4381 assert!(pps.cu_qp_delta_enabled_flag);
4382 assert_eq!(pps.diff_cu_qp_delta_depth, 0);
4383 assert_eq!(pps.cb_qp_offset, 0);
4384 assert_eq!(pps.cr_qp_offset, 0);
4385 assert!(!pps.slice_chroma_qp_offsets_present_flag);
4386 assert!(pps.weighted_pred_flag);
4387 assert!(!pps.weighted_bipred_flag);
4388 assert!(!pps.transquant_bypass_enabled_flag);
4389 assert!(!pps.tiles_enabled_flag);
4390 assert!(pps.entropy_coding_sync_enabled_flag);
4391 assert!(pps.loop_filter_across_tiles_enabled_flag);
4392 assert!(!pps.scaling_list_data_present_flag);
4393 assert!(!pps.lists_modification_present_flag);
4394 assert_eq!(pps.log2_parallel_merge_level_minus2, 0);
4395 assert!(!pps.slice_segment_header_extension_present_flag);
4396 }
4397
4398 #[test]
4400 fn chromium_slice_header_parsing() {
4401 let mut parser = Parser::default();
4402
4403 let vps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::VpsNut, 0).unwrap();
4405 parser.parse_vps(&vps_nalu).unwrap();
4406
4407 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap();
4408 parser.parse_sps(&sps_nalu).unwrap();
4409
4410 let pps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::PpsNut, 0).unwrap();
4411 parser.parse_pps(&pps_nalu).unwrap();
4412
4413 let slice_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::IdrWRadl, 0).unwrap();
4415 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4416 let hdr = &slice.header;
4417 assert!(hdr.first_slice_segment_in_pic_flag);
4418 assert!(!hdr.no_output_of_prior_pics_flag);
4419 assert_eq!(hdr.pic_parameter_set_id, 0);
4420 assert!(!hdr.dependent_slice_segment_flag);
4421 assert_eq!(hdr.type_, SliceType::I);
4422 assert!(hdr.sao_luma_flag);
4423 assert!(hdr.sao_chroma_flag);
4424 assert_eq!(hdr.qp_delta, 8);
4425 assert!(hdr.loop_filter_across_slices_enabled_flag);
4426
4427 let slice_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::TrailR, 0).unwrap();
4428 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4429 let hdr = &slice.header;
4430 assert!(hdr.first_slice_segment_in_pic_flag);
4431 assert_eq!(hdr.pic_parameter_set_id, 0);
4432 assert!(!hdr.dependent_slice_segment_flag);
4433 assert_eq!(hdr.type_, SliceType::P);
4434 assert_eq!(hdr.pic_order_cnt_lsb, 4);
4435 assert!(!hdr.short_term_ref_pic_set_sps_flag);
4436 assert_eq!(hdr.short_term_ref_pic_set.num_negative_pics, 1);
4437 assert_eq!(hdr.short_term_ref_pic_set.num_positive_pics, 0);
4438 assert_eq!(hdr.short_term_ref_pic_set.delta_poc_s0[0], -4);
4439 assert!(hdr.short_term_ref_pic_set.used_by_curr_pic_s0[0]);
4440 assert!(hdr.temporal_mvp_enabled_flag);
4441 assert!(hdr.sao_luma_flag);
4442 assert!(hdr.sao_chroma_flag);
4443 assert!(!hdr.num_ref_idx_active_override_flag);
4444 assert_eq!(hdr.pred_weight_table.luma_log2_weight_denom, 0);
4445 assert_eq!(hdr.pred_weight_table.delta_chroma_log2_weight_denom, 7);
4446 assert_eq!(hdr.pred_weight_table.delta_luma_weight_l0[0], 0);
4447 assert_eq!(hdr.pred_weight_table.luma_offset_l0[0], -2);
4448 assert_eq!(hdr.pred_weight_table.delta_chroma_weight_l0[0][0], -9);
4449 assert_eq!(hdr.pred_weight_table.delta_chroma_weight_l0[0][1], -9);
4450 assert_eq!(hdr.pred_weight_table.delta_chroma_offset_l0[0][0], 0);
4451 assert_eq!(hdr.pred_weight_table.delta_chroma_offset_l0[0][1], 0);
4452 assert_eq!(hdr.five_minus_max_num_merge_cand, 3);
4453 assert_eq!(hdr.qp_delta, 8);
4454 assert!(hdr.loop_filter_across_slices_enabled_flag);
4455 }
4456
4457 #[test]
4460 fn test25fps_vps_header_parsing() {
4461 let mut cursor = Cursor::new(STREAM_TEST25FPS);
4462 let mut parser = Parser::default();
4463
4464 let vps_nalu = Nalu::<NaluHeader>::next(&mut cursor).unwrap();
4465 let vps = parser.parse_vps(&vps_nalu).unwrap();
4466 assert!(vps.base_layer_internal_flag);
4467 assert!(vps.base_layer_available_flag);
4468 assert_eq!(vps.max_layers_minus1, 0);
4469 assert_eq!(vps.max_sub_layers_minus1, 0);
4470 assert!(vps.temporal_id_nesting_flag);
4471 assert_eq!(vps.profile_tier_level.general_profile_space, 0);
4472 assert!(!vps.profile_tier_level.general_tier_flag);
4473 assert_eq!(vps.profile_tier_level.general_profile_idc, 1);
4474 for i in 0..32 {
4475 let val = i == 1 || i == 2;
4476 assert_eq!(vps.profile_tier_level.general_profile_compatibility_flag[i], val);
4477 }
4478 assert!(vps.profile_tier_level.general_progressive_source_flag);
4479 assert!(!vps.profile_tier_level.general_interlaced_source_flag);
4480 assert!(!vps.profile_tier_level.general_non_packed_constraint_flag,);
4481 assert!(vps.profile_tier_level.general_frame_only_constraint_flag,);
4482 assert!(!vps.profile_tier_level.general_max_12bit_constraint_flag,);
4483 assert!(!vps.profile_tier_level.general_max_10bit_constraint_flag,);
4484 assert!(!vps.profile_tier_level.general_max_8bit_constraint_flag,);
4485 assert!(!vps.profile_tier_level.general_max_422chroma_constraint_flag,);
4486 assert!(!vps.profile_tier_level.general_max_420chroma_constraint_flag,);
4487 assert!(!vps.profile_tier_level.general_max_monochrome_constraint_flag,);
4488 assert!(!vps.profile_tier_level.general_intra_constraint_flag);
4489 assert!(!vps.profile_tier_level.general_one_picture_only_constraint_flag,);
4490 assert!(!vps.profile_tier_level.general_lower_bit_rate_constraint_flag,);
4491 assert!(!vps.profile_tier_level.general_max_14bit_constraint_flag,);
4492 assert_eq!(vps.profile_tier_level.general_level_idc, Level::L2);
4493
4494 assert!(vps.sub_layer_ordering_info_present_flag);
4495 assert_eq!(vps.max_dec_pic_buffering_minus1[0], 4);
4496 assert_eq!(vps.max_num_reorder_pics[0], 2);
4497 assert_eq!(vps.max_latency_increase_plus1[0], 5);
4498 for i in 1..7 {
4499 assert_eq!(vps.max_dec_pic_buffering_minus1[i], 0);
4500 assert_eq!(vps.max_num_reorder_pics[i], 0);
4501 assert_eq!(vps.max_latency_increase_plus1[i], 0);
4502 }
4503
4504 assert_eq!(vps.max_layer_id, 0);
4505 assert_eq!(vps.num_layer_sets_minus1, 0);
4506 assert!(!vps.timing_info_present_flag);
4507 assert_eq!(vps.num_units_in_tick, 0);
4508 assert_eq!(vps.time_scale, 0);
4509 assert!(!vps.poc_proportional_to_timing_flag);
4510 assert_eq!(vps.num_ticks_poc_diff_one_minus1, 0);
4511 assert_eq!(vps.num_hrd_parameters, 0);
4512 }
4513
4514 #[test]
4517 fn test25fps_sps_header_parsing() {
4518 let mut parser = Parser::default();
4519
4520 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap();
4521 let sps = parser.parse_sps(&sps_nalu).unwrap();
4522
4523 assert_eq!(sps.max_sub_layers_minus1, 0);
4524
4525 assert_eq!(sps.profile_tier_level.general_profile_space, 0);
4526 assert!(!sps.profile_tier_level.general_tier_flag);
4527 assert_eq!(sps.profile_tier_level.general_profile_idc, 1);
4528 for i in 0..32 {
4529 let val = i == 1 || i == 2;
4530 assert_eq!(sps.profile_tier_level.general_profile_compatibility_flag[i], val);
4531 }
4532 assert!(sps.profile_tier_level.general_progressive_source_flag);
4533 assert!(!sps.profile_tier_level.general_interlaced_source_flag);
4534 assert!(!sps.profile_tier_level.general_non_packed_constraint_flag,);
4535 assert!(sps.profile_tier_level.general_frame_only_constraint_flag,);
4536 assert!(!sps.profile_tier_level.general_max_12bit_constraint_flag,);
4537 assert!(!sps.profile_tier_level.general_max_10bit_constraint_flag,);
4538 assert!(!sps.profile_tier_level.general_max_8bit_constraint_flag,);
4539 assert!(!sps.profile_tier_level.general_max_422chroma_constraint_flag,);
4540 assert!(!sps.profile_tier_level.general_max_420chroma_constraint_flag,);
4541 assert!(!sps.profile_tier_level.general_max_monochrome_constraint_flag,);
4542 assert!(!sps.profile_tier_level.general_intra_constraint_flag);
4543 assert!(!sps.profile_tier_level.general_one_picture_only_constraint_flag,);
4544 assert!(!sps.profile_tier_level.general_lower_bit_rate_constraint_flag,);
4545 assert!(!sps.profile_tier_level.general_max_14bit_constraint_flag,);
4546 assert_eq!(sps.profile_tier_level.general_level_idc, Level::L2);
4547
4548 assert_eq!(sps.seq_parameter_set_id, 0);
4549 assert_eq!(sps.chroma_format_idc, 1);
4550 assert!(!sps.separate_colour_plane_flag);
4551 assert_eq!(sps.pic_width_in_luma_samples, 320);
4552 assert_eq!(sps.pic_height_in_luma_samples, 240);
4553 assert_eq!(sps.conf_win_left_offset, 0);
4554 assert_eq!(sps.conf_win_right_offset, 0);
4555 assert_eq!(sps.conf_win_top_offset, 0);
4556 assert_eq!(sps.conf_win_bottom_offset, 0);
4557 assert_eq!(sps.bit_depth_luma_minus8, 0);
4558 assert_eq!(sps.bit_depth_chroma_minus8, 0);
4559 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 4);
4560 assert!(sps.sub_layer_ordering_info_present_flag);
4561 assert_eq!(sps.max_dec_pic_buffering_minus1[0], 4);
4562 assert_eq!(sps.max_num_reorder_pics[0], 2);
4563 assert_eq!(sps.max_latency_increase_plus1[0], 5);
4564 for i in 1..7 {
4565 assert_eq!(sps.max_dec_pic_buffering_minus1[i], 0);
4566 assert_eq!(sps.max_num_reorder_pics[i], 0);
4567 assert_eq!(sps.max_latency_increase_plus1[i], 0);
4568 }
4569 assert_eq!(sps.log2_min_luma_coding_block_size_minus3, 0);
4570 assert_eq!(sps.log2_diff_max_min_luma_coding_block_size, 3);
4571 assert_eq!(sps.log2_min_luma_transform_block_size_minus2, 0);
4572 assert_eq!(sps.log2_diff_max_min_luma_transform_block_size, 3);
4573 assert_eq!(sps.max_transform_hierarchy_depth_inter, 0);
4574 assert_eq!(sps.max_transform_hierarchy_depth_intra, 0);
4575 assert!(!sps.scaling_list_enabled_flag);
4576 assert!(!sps.scaling_list_data_present_flag);
4577 assert!(!sps.amp_enabled_flag);
4578 assert!(sps.sample_adaptive_offset_enabled_flag);
4579 assert!(!sps.pcm_enabled_flag);
4580 assert_eq!(sps.pcm_sample_bit_depth_luma_minus1, 0);
4581 assert_eq!(sps.pcm_sample_bit_depth_chroma_minus1, 0);
4582 assert_eq!(sps.log2_min_pcm_luma_coding_block_size_minus3, 0);
4583 assert_eq!(sps.log2_diff_max_min_pcm_luma_coding_block_size, 0);
4584 assert!(!sps.pcm_loop_filter_disabled_flag);
4585 assert_eq!(sps.num_short_term_ref_pic_sets, 0);
4586 assert_eq!(sps.num_long_term_ref_pics_sps, 0);
4587 assert!(sps.temporal_mvp_enabled_flag);
4588 assert!(sps.strong_intra_smoothing_enabled_flag);
4589 assert_eq!(sps.vui_parameters.sar_width, 0);
4590 assert_eq!(sps.vui_parameters.sar_height, 0);
4591 assert!(!sps.vui_parameters.video_full_range_flag);
4592 assert!(!sps.vui_parameters.colour_description_present_flag);
4593 assert!(sps.vui_parameters.video_signal_type_present_flag);
4594 assert!(sps.vui_parameters.timing_info_present_flag);
4595 assert_eq!(sps.vui_parameters.num_units_in_tick, 1);
4596 assert_eq!(sps.vui_parameters.time_scale, 25);
4597 assert!(!sps.vui_parameters.poc_proportional_to_timing_flag);
4598 assert_eq!(sps.vui_parameters.num_ticks_poc_diff_one_minus1, 0);
4599 assert!(!sps.vui_parameters.hrd_parameters_present_flag);
4600 assert_eq!(sps.vui_parameters.colour_primaries, 2);
4601 assert_eq!(sps.vui_parameters.transfer_characteristics, 2);
4602 assert_eq!(sps.vui_parameters.matrix_coeffs, 2);
4603 assert_eq!(sps.vui_parameters.def_disp_win_left_offset, 0);
4604 assert_eq!(sps.vui_parameters.def_disp_win_right_offset, 0);
4605 assert_eq!(sps.vui_parameters.def_disp_win_top_offset, 0);
4606 assert_eq!(sps.vui_parameters.def_disp_win_bottom_offset, 0);
4607 }
4608
4609 #[test]
4612 fn test25fps_pps_header_parsing() {
4613 let mut parser = Parser::default();
4614
4615 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap();
4616 parser.parse_sps(&sps_nalu).unwrap();
4617
4618 let pps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::PpsNut, 0).unwrap();
4619 let pps = parser.parse_pps(&pps_nalu).unwrap();
4620
4621 assert!(!pps.dependent_slice_segments_enabled_flag);
4622 assert!(!pps.output_flag_present_flag);
4623 assert_eq!(pps.num_extra_slice_header_bits, 0);
4624 assert!(pps.sign_data_hiding_enabled_flag);
4625 assert!(!pps.cabac_init_present_flag);
4626 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0);
4627 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0);
4628 assert_eq!(pps.init_qp_minus26, 0);
4629 assert!(!pps.constrained_intra_pred_flag);
4630 assert!(!pps.transform_skip_enabled_flag);
4631 assert!(pps.cu_qp_delta_enabled_flag);
4632 assert_eq!(pps.diff_cu_qp_delta_depth, 1);
4633 assert_eq!(pps.cb_qp_offset, 0);
4634 assert_eq!(pps.cr_qp_offset, 0);
4635 assert!(!pps.slice_chroma_qp_offsets_present_flag);
4636 assert!(pps.weighted_pred_flag);
4637 assert!(!pps.weighted_bipred_flag);
4638 assert!(!pps.transquant_bypass_enabled_flag);
4639 assert!(!pps.tiles_enabled_flag);
4640 assert!(pps.entropy_coding_sync_enabled_flag);
4641 assert_eq!(pps.num_tile_rows_minus1, 0);
4642 assert_eq!(pps.num_tile_columns_minus1, 0);
4643 assert!(pps.uniform_spacing_flag);
4644 assert_eq!(pps.column_width_minus1, [0; 19]);
4645 assert_eq!(pps.row_height_minus1, [0; 21]);
4646 assert!(pps.loop_filter_across_slices_enabled_flag);
4647 assert!(pps.loop_filter_across_tiles_enabled_flag);
4648 assert!(!pps.deblocking_filter_control_present_flag);
4649 assert!(!pps.deblocking_filter_override_enabled_flag);
4650 assert!(!pps.deblocking_filter_disabled_flag);
4651 assert_eq!(pps.beta_offset_div2, 0);
4652 assert_eq!(pps.tc_offset_div2, 0);
4653 assert!(!pps.lists_modification_present_flag);
4654 assert_eq!(pps.log2_parallel_merge_level_minus2, 0);
4655 assert!(!pps.slice_segment_header_extension_present_flag);
4656 assert!(!pps.extension_present_flag);
4657 }
4658
4659 #[test]
4662 fn test25fps_slice_header_parsing() {
4663 let mut parser = Parser::default();
4664
4665 let vps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::VpsNut, 0).unwrap();
4667 parser.parse_vps(&vps_nalu).unwrap();
4668
4669 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap();
4670 parser.parse_sps(&sps_nalu).unwrap();
4671
4672 let pps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::PpsNut, 0).unwrap();
4673 parser.parse_pps(&pps_nalu).unwrap();
4674
4675 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::IdrNLp, 0).unwrap();
4676 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4677 let hdr = &slice.header;
4678
4679 assert!(hdr.first_slice_segment_in_pic_flag);
4680 assert!(!hdr.no_output_of_prior_pics_flag);
4681 assert!(!hdr.dependent_slice_segment_flag);
4682 assert_eq!(hdr.type_, SliceType::I);
4683 assert!(hdr.pic_output_flag);
4684 assert_eq!(hdr.colour_plane_id, 0);
4685 assert_eq!(hdr.pic_order_cnt_lsb, 0);
4686 assert!(!hdr.short_term_ref_pic_set_sps_flag);
4687 assert_eq!(hdr.lt_idx_sps, [0; 16]);
4688 assert_eq!(hdr.poc_lsb_lt, [0; 16]);
4689 assert_eq!(hdr.used_by_curr_pic_lt, [false; 16]);
4690 assert_eq!(hdr.delta_poc_msb_cycle_lt, [0; 16]);
4691 assert_eq!(hdr.delta_poc_msb_present_flag, [false; 16]);
4692 assert!(!hdr.temporal_mvp_enabled_flag);
4693 assert!(hdr.sao_luma_flag);
4694 assert!(hdr.sao_chroma_flag);
4695 assert!(!hdr.num_ref_idx_active_override_flag);
4696 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
4697 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
4698 assert!(!hdr.cabac_init_flag);
4699 assert!(hdr.collocated_from_l0_flag);
4700 assert_eq!(hdr.five_minus_max_num_merge_cand, 0);
4701 assert!(!hdr.use_integer_mv_flag);
4702 assert_eq!(hdr.qp_delta, 7);
4703 assert_eq!(hdr.cb_qp_offset, 0);
4704 assert_eq!(hdr.cr_qp_offset, 0);
4705 assert!(!hdr.cu_chroma_qp_offset_enabled_flag);
4706 assert!(!hdr.deblocking_filter_override_flag);
4707 assert!(!hdr.deblocking_filter_override_flag);
4708 assert_eq!(hdr.beta_offset_div2, 0);
4709 assert_eq!(hdr.tc_offset_div2, 0);
4710 assert!(hdr.loop_filter_across_slices_enabled_flag);
4711 assert_eq!(hdr.num_entry_point_offsets, 3);
4712 assert_eq!(hdr.offset_len_minus1, 11);
4713 assert_eq!(hdr.num_pic_total_curr, 0);
4714
4715 assert_eq!(hdr.header_bit_size - 16, 72);
4717
4718 assert_eq!(hdr.n_emulation_prevention_bytes, 0);
4719
4720 assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_0);
4721
4722 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::TrailR, 0).unwrap();
4724 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4725 let hdr = &slice.header;
4726
4727 assert!(hdr.first_slice_segment_in_pic_flag);
4728 assert!(!hdr.no_output_of_prior_pics_flag);
4729 assert!(!hdr.dependent_slice_segment_flag);
4730 assert_eq!(hdr.type_, SliceType::P);
4731 assert!(hdr.pic_output_flag);
4732 assert_eq!(hdr.colour_plane_id, 0);
4733 assert_eq!(hdr.pic_order_cnt_lsb, 3);
4734 assert!(!hdr.short_term_ref_pic_set_sps_flag);
4735 assert_eq!(hdr.short_term_ref_pic_set.num_delta_pocs, 1);
4736 assert_eq!(hdr.short_term_ref_pic_set.num_negative_pics, 1);
4737 assert_eq!(hdr.short_term_ref_pic_set.num_positive_pics, 0);
4738 assert!(hdr.short_term_ref_pic_set.used_by_curr_pic_s0[0]);
4739 assert_eq!(hdr.short_term_ref_pic_set.delta_poc_s0[0], -3);
4740 assert_eq!(hdr.lt_idx_sps, [0; 16]);
4741 assert_eq!(hdr.poc_lsb_lt, [0; 16]);
4742 assert_eq!(hdr.used_by_curr_pic_lt, [false; 16]);
4743 assert_eq!(hdr.delta_poc_msb_cycle_lt, [0; 16]);
4744 assert_eq!(hdr.delta_poc_msb_present_flag, [false; 16]);
4745 assert!(hdr.temporal_mvp_enabled_flag);
4746 assert!(hdr.sao_luma_flag);
4747 assert!(hdr.sao_chroma_flag);
4748 assert!(!hdr.num_ref_idx_active_override_flag);
4749 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0);
4750 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0);
4751 assert!(!hdr.cabac_init_flag);
4752 assert!(hdr.collocated_from_l0_flag);
4753 assert_eq!(hdr.pred_weight_table.luma_log2_weight_denom, 7);
4754 assert_eq!(hdr.five_minus_max_num_merge_cand, 2);
4755 assert!(!hdr.use_integer_mv_flag);
4756 assert_eq!(hdr.num_entry_point_offsets, 3);
4757 assert_eq!(hdr.qp_delta, 7);
4758 assert_eq!(hdr.cb_qp_offset, 0);
4759 assert_eq!(hdr.cr_qp_offset, 0);
4760 assert!(!hdr.cu_chroma_qp_offset_enabled_flag);
4761 assert!(!hdr.deblocking_filter_override_flag);
4762 assert!(!hdr.deblocking_filter_override_flag);
4763 assert_eq!(hdr.beta_offset_div2, 0);
4764 assert_eq!(hdr.tc_offset_div2, 0);
4765 assert!(!hdr.loop_filter_across_slices_enabled_flag);
4766 assert_eq!(hdr.num_entry_point_offsets, 3);
4767 assert_eq!(hdr.offset_len_minus1, 10);
4768 assert_eq!(hdr.num_pic_total_curr, 1);
4769
4770 assert_eq!(slice.nalu.size, 2983);
4771 assert_eq!(hdr.header_bit_size - 16, 96);
4773 assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_1);
4774
4775 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::TrailR, 1).unwrap();
4777 let slice = parser.parse_slice_header(slice_nalu).unwrap();
4778 let hdr = &slice.header;
4779
4780 assert_eq!(slice.nalu.size, 290);
4781 assert_eq!(hdr.header_bit_size - 16, 80);
4783 }
4784}