• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! An Annex B h.265 parser.
6 //!
7 //! Parses VPSs, SPSs, PPSs and Slices from NALUs.
8 
9 use std::collections::BTreeMap;
10 use std::io::Read;
11 use std::io::Seek;
12 use std::io::SeekFrom;
13 use std::rc::Rc;
14 
15 use crate::bitstream_utils::BitReader;
16 use crate::codec::h264::nalu;
17 use crate::codec::h264::nalu::Header;
18 use crate::codec::h264::parser::Point;
19 use crate::codec::h264::parser::Rect;
20 
21 // Given the max VPS id.
22 const MAX_VPS_COUNT: usize = 16;
23 // Given the max SPS id.
24 const MAX_SPS_COUNT: usize = 16;
25 // Given the max PPS id.
26 const MAX_PPS_COUNT: usize = 64;
27 // 7.4.7.1
28 const MAX_REF_IDX_ACTIVE: u32 = 15;
29 
30 // 7.4.3.2.1:
31 // num_short_term_ref_pic_sets specifies the number of st_ref_pic_set( ) syntax
32 // structures included in the SPS. The value of num_short_term_ref_pic_sets
33 // shall be in the range of 0 to 64, inclusive.
34 // NOTE 5 – A decoder should allocate memory for a total number of
35 // num_short_term_ref_pic_sets + 1 st_ref_pic_set( ) syntax structures since
36 // there may be a st_ref_pic_set( ) syntax structure directly signalled in the
37 // slice headers of a current picture. A st_ref_pic_set( ) syntax structure
38 // directly signalled in the slice headers of a current picture has an index
39 // equal to num_short_term_ref_pic_sets.
40 const MAX_SHORT_TERM_REF_PIC_SETS: usize = 65;
41 
42 // 7.4.3.2.1:
43 const MAX_LONG_TERM_REF_PIC_SETS: usize = 32;
44 
45 // From table 7-5.
46 const DEFAULT_SCALING_LIST_0: [u8; 16] = [16; 16];
47 
48 // From Table 7-6.
49 const 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 
55 // From Table 7-6.
56 const 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 /// Table 7-1 – NAL unit type codes and NAL unit type classes
63 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
64 pub 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 
116 impl TryFrom<u32> for NaluType {
117     type Error = String;
118 
try_from(value: u32) -> Result<Self, Self::Error>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 
174 impl NaluType {
175     /// Whether this is an IDR NALU.
is_idr(&self) -> bool176     pub fn is_idr(&self) -> bool {
177         matches!(self, Self::IdrWRadl | Self::IdrNLp)
178     }
179 
180     /// Whether this is an IRAP NALU.
is_irap(&self) -> bool181     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     /// Whether this is a BLA NALU.
is_bla(&self) -> bool187     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     /// Whether this is a CRA NALU.
is_cra(&self) -> bool193     pub fn is_cra(&self) -> bool {
194         matches!(self, Self::CraNut)
195     }
196 
197     /// Whether this is a RADL NALU.
is_radl(&self) -> bool198     pub fn is_radl(&self) -> bool {
199         matches!(self, Self::RadlN | Self::RadlR)
200     }
201 
202     /// Whether this is a RASL NALU.
is_rasl(&self) -> bool203     pub fn is_rasl(&self) -> bool {
204         matches!(self, Self::RaslN | Self::RaslR)
205     }
206 
207     //// Whether this is a SLNR NALU.
is_slnr(&self) -> bool208     pub fn is_slnr(&self) -> bool {
209         // From the specification:
210         // If a picture has nal_unit_type equal to TRAIL_N, TSA_N, STSA_N,
211         // RADL_N, RASL_N, RSV_VCL_N10, RSV_VCL_N12 or RSV_VCL_N14, the picture
212         // is an SLNR picture. Otherwise, the picture is a sub-layer reference
213         // picture.
214         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)]
229 pub struct NaluHeader {
230     /// The NALU type.
231     pub type_: NaluType,
232     /// Specifies the identifier of the layer to which a VCL NAL unit belongs or
233     /// the identifier of a layer to which a non-VCL NAL unit applies.
234     pub nuh_layer_id: u8,
235     /// Minus 1 specifies a temporal identifier for the NAL unit. The value of
236     /// nuh_temporal_id_plus1 shall not be equal to 0.
237     pub nuh_temporal_id_plus1: u8,
238 }
239 
240 impl NaluHeader {
nuh_temporal_id(&self) -> u8241     pub fn nuh_temporal_id(&self) -> u8 {
242         self.nuh_temporal_id_plus1.saturating_sub(1)
243     }
244 }
245 
246 impl Header for NaluHeader {
parse<T: AsRef<[u8]>>(cursor: &mut std::io::Cursor<T>) -> Result<Self, String>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         // Skip forbidden_zero_bit
254         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 
is_end(&self) -> bool263     fn is_end(&self) -> bool {
264         matches!(self.type_, NaluType::EosNut | NaluType::EobNut)
265     }
266 
len(&self) -> usize267     fn len(&self) -> usize {
268         // 7.3.1.2
269         2
270     }
271 }
272 
273 pub type Nalu<'a> = nalu::Nalu<'a, NaluHeader>;
274 
275 /// H265 levels as defined by table A.8.
276 /// `general_level_idc` and `sub_layer_level_idc[ OpTid ]` shall be set equal to a
277 /// value of 30 times the level number specified in Table A.8
278 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
279 pub 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 
296 impl TryFrom<u8> for Level {
297     type Error = String;
298 
try_from(value: u8) -> Result<Self, Self::Error>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 /// H265 profiles. See A.3.
320 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
321 pub 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 
336 impl TryFrom<u8> for Profile {
337     type Error = String;
338 
try_from(value: u8) -> Result<Self, Self::Error>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 /// A H.265 Video Parameter Set.
358 #[derive(Clone, Debug, PartialEq, Eq)]
359 pub struct Vps {
360     /// Identifies the VPS for reference by other syntax elements.
361     pub video_parameter_set_id: u8,
362     /// If vps_base_layer_internal_flag is equal to 1 and
363     /// vps_base_layer_available_flag is equal to 1, the base layer is present
364     /// in the bitstream.
365     pub base_layer_internal_flag: bool,
366     /// See `base_layer_internal_flag`.
367     pub base_layer_available_flag: bool,
368     /// Plus 1 specifies the maximum allowed number of layers in each CVS
369     /// referring to the VPS.
370     pub max_layers_minus1: u8,
371     /// Plus 1 specifies the maximum number of temporal sub-layers that may be
372     /// present in each CVS referring to the VPS.
373     pub max_sub_layers_minus1: u8,
374     /// When vps_max_sub_layers_minus1 is greater than 0, specifies whether
375     /// inter prediction is additionally restricted for CVSs referring to the
376     /// VPS.
377     pub temporal_id_nesting_flag: bool,
378     /// ProfileTierLevel() data.
379     pub profile_tier_level: ProfileTierLevel,
380     /// When true, specifies that `vps_max_dec_pic_buffering_minus1[ i ]`,
381     /// `vps_max_num_reorder_pics[ i ]` and `vps_max_latency_increase_plus1[ i ]`
382     /// are present for vps_max_sub_layers_ minus1 + 1 sub-layers.
383     /// vps_sub_layer_ordering_info_present_flag equal to 0 specifies that the
384     /// values of `vps_max_dec_pic_buffering_minus1[ vps_max_sub_layers_minus1 ]`,
385     /// vps_max_num_reorder_pics[ vps_max_sub_ layers_minus1 ] and
386     /// `vps_max_latency_increase_plus1[ vps_max_sub_layers_minus1 ]` apply to all
387     /// sub-layers
388     pub sub_layer_ordering_info_present_flag: bool,
389     /// `max_dec_pic_buffering_minus1[i]` plus 1 specifies the maximum required
390     /// size of the decoded picture buffer for the CVS in units of picture
391     /// storage buffers when HighestTid is equal to i.
392     pub max_dec_pic_buffering_minus1: [u32; 7],
393     /// Indicates the maximum allowed number of pictures with PicOutputFlag
394     /// equal to 1 that can precede any picture with PicOutputFlag equal to 1 in
395     /// the CVS in decoding order and follow that picture with PicOutputFlag
396     /// equal to 1 in output order when HighestTid is equal to i.
397     pub max_num_reorder_pics: [u32; 7],
398     /// When true, `max_latency_increase_plus1[i]` is used to compute the value of
399     /// `VpsMaxLatencyPictures[ i ]`, which specifies the maximum number of
400     /// pictures with PicOutputFlag equal to 1 that can precede any picture with
401     /// PicOutputFlag equal to 1 in the CVS in output order and follow that
402     /// picture with PicOutputFlag equal to 1 in decoding order when HighestTid
403     /// is equal to i.
404     pub max_latency_increase_plus1: [u32; 7],
405     /// Specifies the maximum allowed value of nuh_layer_id of all NAL units in
406     /// each CVS referring to the VPS.
407     pub max_layer_id: u8,
408     /// num_layer_sets_minus1 plus 1 specifies the number of layer sets that are
409     /// specified by the VPS.
410     pub num_layer_sets_minus1: u32,
411     /// When true, specifies that num_units_in_tick, time_scale,
412     /// poc_proportional_to_timing_flag and num_hrd_parameters are present in
413     /// the VPS.
414     pub timing_info_present_flag: bool,
415     /// The number of time units of a clock operating at the frequency
416     /// vps_time_scale Hz that corresponds to one increment (called a clock
417     /// tick) of a clock tick counter. The value of vps_num_units_in_tick shall
418     /// be greater than 0. A clock tick, in units of seconds, is equal to the
419     /// quotient of vps_num_units_in_tick divided by vps_time_scale. For
420     /// example, when the picture rate of a video signal is 25 Hz,
421     /// vps_time_scale may be equal to 27 000 000 and vps_num_units_in_tick may
422     /// be equal to 1 080 000, and consequently a clock tick may be 0.04
423     /// seconds.
424     pub num_units_in_tick: u32,
425     /// The number of time units that pass in one second. For example, a time
426     /// coordinate system that measures time using a 27 MHz clock has a
427     /// vps_time_scale of 27 000 000.
428     pub time_scale: u32,
429     /// When true, indicates that the picture order count value for each picture
430     /// in the CVS that is not the first picture in the CVS, in decoding order,
431     /// is proportional to the output time of the picture relative to the output
432     /// time of the first picture in the CVS.  When false, indicates that the
433     /// picture order count value for each picture in the CVS that is not the
434     /// first picture in the CVS, in decoding order, may or may not be
435     /// proportional to the output time of the picture relative to the output
436     /// time of the first picture in the CVS.
437     pub poc_proportional_to_timing_flag: bool,
438     /// num_ticks_poc_diff_one_minus1 plus 1 specifies the number of clock ticks
439     /// corresponding to a difference of picture order count values equal to 1.
440     pub num_ticks_poc_diff_one_minus1: u32,
441     /// Specifies the number of hrd_parameters( ) syntax structures present in
442     /// the VPS RBSP before the vps_extension_flag syntax element.
443     pub num_hrd_parameters: u32,
444     /// `hrd_layer_set_idx[ i ]` specifies the index, into the list of layer sets
445     /// specified by the VPS, of the layer set to which the i-th hrd_parameters(
446     /// ) syntax structure in the VPS applies.
447     pub hrd_layer_set_idx: Vec<u16>,
448     /// `cprms_present_flag[ i ]` equal to true specifies that the HRD parameters
449     /// that are common for all sub-layers are present in the i-th
450     /// hrd_parameters( ) syntax structure in the VPS. `cprms_present_flag[ i ]`
451     /// equal to false specifies that the HRD parameters that are common for all
452     /// sub-layers are not present in the i-th hrd_parameters( ) syntax
453     /// structure in the VPS and are derived to be the same as the ( i − 1 )-th
454     /// hrd_parameters( ) syntax structure in the VPS. `cprms_present_flag[ 0 ]`
455     /// is inferred to be equal to true.
456     pub cprms_present_flag: Vec<bool>,
457     /// The hrd_parameters() data.
458     pub hrd_parameters: Vec<HrdParams>,
459     /// When false, specifies that no vps_extension_data_flag syntax elements
460     /// are present in the VPS RBSP syntax structure. When true, specifies that
461     /// there are vps_extension_data_flag syntax elements present in the VPS
462     /// RBSP syntax structure. Decoders conforming to a profile specified in
463     /// Annex A but not supporting the INBLD capability specified in Annex F
464     /// shall ignore all data that follow the value 1 for vps_extension_flag in
465     /// a VPS NAL unit.
466     pub extension_flag: bool,
467 }
468 
469 impl Default for Vps {
default() -> Self470     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)]
500 pub struct ProfileTierLevel {
501     /// Specifies the context for the interpretation of general_profile_idc and
502     /// `general_profile_compatibility_flag[ j ]` for all values of j in the range
503     /// of 0 to 31, inclusive.
504     pub general_profile_space: u8,
505     /// Specifies the tier context for the interpretation of general_level_idc
506     /// as specified in Annex A.
507     pub general_tier_flag: bool,
508     /// When general_profile_space is equal to 0, indicates a profile to which
509     /// the CVS conforms as specified in Annex A. Bitstreams shall not contain
510     /// values of general_profile_idc other than those specified in Annex A.
511     /// Other values of general_profile_idc are reserved for future use by ITU-T
512     /// | ISO/IEC.
513     pub general_profile_idc: u8,
514     /// `general_profile_compatibility_flag[ j ]` equal to true, when
515     /// general_profile_space is false, indicates that the CVS conforms to the
516     /// profile indicated by general_profile_idc equal to j as specified in
517     /// Annex A.
518     pub general_profile_compatibility_flag: [bool; 32],
519     /// general_progressive_source_flag and general_interlaced_source_flag are
520     /// interpreted as follows:
521     ///
522     /// –If general_progressive_source_flag is true and
523     /// general_interlaced_source_flag is false, the source scan type of the
524     /// pictures in the CVS should be interpreted as progressive only.
525     ///
526     /// –Otherwise, if general_progressive_source_flag is false and
527     /// general_interlaced_source_flag is true, the source scan type of the
528     /// pictures in the CVS should be interpreted as interlaced only.
529     ///
530     /// –Otherwise, if general_progressive_source_flag is false and
531     /// general_interlaced_source_flag is false, the source scan type of the
532     /// pictures in the CVS should be interpreted as unknown or unspecified.
533     ///
534     /// –Otherwise (general_progressive_source_flag is true and
535     /// general_interlaced_source_flag is true), the source scan type of each
536     /// picture in the CVS is indicated at the picture level using the syntax
537     /// element source_scan_type in a picture timing SEI message.
538     pub general_progressive_source_flag: bool,
539     /// See `general_progressive_source_flag`.
540     pub general_interlaced_source_flag: bool,
541     /// If true, specifies that there are no frame packing arrangement SEI
542     /// messages, segmented rectangular frame packing arrangement SEI messages,
543     /// equirectangular projection SEI messages, or cubemap projection SEI
544     /// messages present in the CVS. If false, indicates that there may or may
545     /// not be one or more frame packing arrangement SEI messages, segmented
546     /// rectangular frame packing arrangement SEI messages, equirectangular
547     /// projection SEI messages, or cubemap projection SEI messages present in
548     /// the CVS.
549     pub general_non_packed_constraint_flag: bool,
550     /// When true, specifies that field_seq_flag is false. When false, indicates
551     /// that field_seq_flag may or may not be false.
552     pub general_frame_only_constraint_flag: bool,
553     /// See Annex A.
554     pub general_max_12bit_constraint_flag: bool,
555     /// See Annex A.
556     pub general_max_10bit_constraint_flag: bool,
557     /// See Annex A.
558     pub general_max_8bit_constraint_flag: bool,
559     /// See Annex A.
560     pub general_max_422chroma_constraint_flag: bool,
561     /// See Annex A.
562     pub general_max_420chroma_constraint_flag: bool,
563     /// See Annex A.
564     pub general_max_monochrome_constraint_flag: bool,
565     /// See Annex A.
566     pub general_intra_constraint_flag: bool,
567     /// See Annex A.
568     pub general_lower_bit_rate_constraint_flag: bool,
569     /// See Annex A.
570     pub general_max_14bit_constraint_flag: bool,
571     /// See Annex A.
572     pub general_one_picture_only_constraint_flag: bool,
573     /// When true, specifies that the INBLD capability as specified in Annex F
574     /// is required for decoding of the layer to which the profile_tier_level( )
575     /// syntax structure applies. When false, specifies that the INBLD
576     /// capability as specified in Annex F is not required for decoding of the
577     /// layer to which the profile_tier_level( ) syntax structure applies.
578     pub general_inbld_flag: bool,
579     /// Indicates a level to which the CVS conforms as specified in Annex A.
580     pub general_level_idc: Level,
581     /// Sub-layer syntax element.
582     pub sub_layer_profile_present_flag: [bool; 6],
583     /// Sub-layer syntax element.
584     pub sub_layer_level_present_flag: [bool; 6],
585     /// Sub-layer syntax element.
586     pub sub_layer_profile_space: [u8; 6],
587     /// Sub-layer syntax element.
588     pub sub_layer_tier_flag: [bool; 6],
589     /// Sub-layer syntax element.
590     pub sub_layer_profile_idc: [u8; 6],
591     /// Sub-layer syntax element.
592     pub sub_layer_profile_compatibility_flag: [[bool; 32]; 6],
593     /// Sub-layer syntax element.
594     pub sub_layer_progressive_source_flag: [bool; 6],
595     /// Sub-layer syntax element.
596     pub sub_layer_interlaced_source_flag: [bool; 6],
597     /// Sub-layer syntax element.
598     pub sub_layer_non_packed_constraint_flag: [bool; 6],
599     /// Sub-layer syntax element.
600     pub sub_layer_frame_only_constraint_flag: [bool; 6],
601     /// Sub-layer syntax element.
602     pub sub_layer_max_12bit_constraint_flag: [bool; 6],
603     /// Sub-layer syntax element.
604     pub sub_layer_max_10bit_constraint_flag: [bool; 6],
605     /// Sub-layer syntax element.
606     pub sub_layer_max_8bit_constraint_flag: [bool; 6],
607     /// Sub-layer syntax element.
608     pub sub_layer_max_422chroma_constraint_flag: [bool; 6],
609     /// Sub-layer syntax element.
610     pub sub_layer_max_420chroma_constraint_flag: [bool; 6],
611     /// Sub-layer syntax element.
612     pub sub_layer_max_monochrome_constraint_flag: [bool; 6],
613     /// Sub-layer syntax element.
614     pub sub_layer_intra_constraint_flag: [bool; 6],
615     /// Sub-layer syntax element.
616     pub sub_layer_one_picture_only_constraint_flag: [bool; 6],
617     /// Sub-layer syntax element.
618     pub sub_layer_lower_bit_rate_constraint_flag: [bool; 6],
619     /// Sub-layer syntax element.
620     pub sub_layer_max_14bit_constraint_flag: [bool; 6],
621     /// Sub-layer syntax element.
622     pub sub_layer_inbld_flag: [bool; 6],
623     /// Sub-layer syntax element.
624     pub sub_layer_level_idc: [Level; 6],
625 }
626 
627 impl ProfileTierLevel {
max_luma_ps(&self) -> u32628     pub fn max_luma_ps(&self) -> u32 {
629         // See Table A.8.
630         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 
max_dpb_pic_buf(&self) -> u32642     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)]
652 pub 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)]
665 pub struct SpsSccExtension {
666     /// When set, specifies that a picture in the CVS may be included in a
667     /// reference picture list of a slice of the picture itself.  When not set,
668     /// specifies that a picture in the CVS is never included in a reference
669     /// picture list of a slice of the picture itself.
670     pub curr_pic_ref_enabled_flag: bool,
671     /// When set, specifies that the decoding process for palette mode may be
672     /// used for intra blocks. When not set, specifies that the decoding process
673     /// for palette mode is not applied.
674     pub palette_mode_enabled_flag: bool,
675     /// Specifies the maximum allowed palette size.
676     pub palette_max_size: u8,
677     /// Specifies the difference between the maximum allowed palette predictor
678     /// size and the maximum allowed palette size.
679     pub delta_palette_max_predictor_size: u8,
680     /// When set, specifies that the sequence palette predictors are initialized
681     /// using the sps_palette_predictor_initializers. When not set, specifies
682     /// that the entries in the sequence palette predictor are initialized to 0.
683     pub palette_predictor_initializers_present_flag: bool,
684     /// num_palette_predictor_initializers_minus1 plus 1 specifies the number of
685     /// entries in the sequence palette predictor initializer.
686     pub num_palette_predictor_initializer_minus1: u8,
687     /// `palette_predictor_initializer[ comp ][ i ]` specifies the value of the
688     /// comp-th component of the i-th palette entry in the SPS that is used to
689     /// initialize the array PredictorPaletteEntries.
690     pub palette_predictor_initializer: [[u32; 128]; 3],
691     /// Controls the presence and inference of the use_integer_mv_flag that
692     /// specifies the resolution of motion vectors for inter prediction.
693     pub motion_vector_resolution_control_idc: u8,
694     /// When set, specifies that the intra boundary filtering process is
695     /// unconditionally disabled for intra prediction.  If not set, specifies
696     /// that the intra boundary filtering process may be used.
697     pub intra_boundary_filtering_disabled_flag: bool,
698 }
699 
700 impl Default for SpsSccExtension {
default() -> Self701     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 /// A H.265 Sequence Parameter Set.
717 #[derive(Clone, Debug, Default, PartialEq, Eq)]
718 pub struct Sps {
719     /// Specifies the value of the vps_video_parameter_set_id of the active VPS.
720     pub video_parameter_set_id: u8,
721     /// `max_sub_layers_minus1` plus 1 specifies the maximum number of temporal
722     /// sub-layers that may be present in each CVS referring to the SPS.
723     pub max_sub_layers_minus1: u8,
724     /// When sps_max_sub_layers_minus1 is greater than 0, specifies whether
725     /// inter prediction is additionally restricted for CVSs referring to the
726     /// SPS.
727     pub temporal_id_nesting_flag: bool,
728     /// profile_tier_level() data.
729     pub profile_tier_level: ProfileTierLevel,
730     /// Provides an identifier for the SPS for reference by other syntax
731     /// elements.
732     pub seq_parameter_set_id: u8,
733     /// Specifies the chroma sampling relative to the luma sampling as specified
734     /// in clause 6.2.
735     pub chroma_format_idc: u8,
736     /// When true, specifies that the three colour components of the 4:4:4
737     /// chroma format are coded separately. When false, specifies that the
738     /// colour components are not coded separately.
739     pub separate_colour_plane_flag: bool,
740     /// Specifies the width of each decoded picture in units of luma samples.
741     pub pic_width_in_luma_samples: u16,
742     /// Specifies the height of each decoded picture in units of luma samples.
743     pub pic_height_in_luma_samples: u16,
744     /// When true, indicates that the conformance cropping window offset
745     /// parameters follow next in the SPS. When false, indicates that the
746     /// conformance cropping window offset parameters are not present.
747     pub conformance_window_flag: bool,
748     /* if conformance_window_flag */
749     /// Specify the samples of the pictures in the CVS that are output from the
750     /// decoding process, in terms of a rectangular region specified in picture
751     /// coordinates for output.
752     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     /// Specifies the bit depth of the samples of the luma array BitDepthY and
758     /// the value of the luma quantization parameter range offset QpBdOffsetY.
759     pub bit_depth_luma_minus8: u8,
760     /// Specifies the bit depth of the samples of the chroma arrays BitDepthC
761     /// and the value of the chroma quantization parameter range offset
762     /// QpBdOffsetC.
763     pub bit_depth_chroma_minus8: u8,
764     /// Specifies the value of the variable MaxPicOrderCntLsb that is used in
765     /// the decoding process for picture order count.
766     pub log2_max_pic_order_cnt_lsb_minus4: u8,
767     /// When true, specifies that `max_dec_pic_buffering_minus1[ i ]`,
768     /// `max_num_reorder_pics[ i ]` and `max_latency_increase_plus1[ i ]` are
769     /// present for max_sub_layers_minus1 + 1 sub- layers. When false, specifies
770     /// that the values of `max_dec_pic_ buffering_minus1[ max_sub_layers_minus1
771     /// ]`, `max_num_reorder_pics[ max_sub_layers_minus1 ]` and max_
772     /// `latency_increase_plus1[ max_sub_layers_minus1 ]` apply to all sub-layers.
773     pub sub_layer_ordering_info_present_flag: bool,
774     /// `max_dec_pic_buffering_minus1[ i ]` plus 1 specifies the maximum required
775     /// size of the decoded picture buffer for the CVS in units of picture
776     /// storage buffers when HighestTid is equal to i.
777     pub max_dec_pic_buffering_minus1: [u8; 7],
778     /// `max_num_reorder_pics[ i ]` indicates the maximum allowed number of
779     /// pictures with PicOutputFlag equal to 1 that can precede any picture with
780     /// PicOutputFlag equal to 1 in the CVS in decoding order and follow that
781     /// picture with PicOutputFlag equal to 1 in output order when HighestTid is
782     /// equal to i.
783     pub max_num_reorder_pics: [u8; 7],
784     /// `max_latency_increase_plus1[ i ]` not equal to 0 is used to compute the
785     /// value of `SpsMaxLatencyPictures[ i ]`, which specifies the maximum number
786     /// of pictures with PicOutputFlag equal to 1 that can precede any picture
787     /// with PicOutputFlag equal to 1 in the CVS in output order and follow that
788     /// picture with PicOutputFlag equal to 1 in decoding order when HighestTid
789     /// is equal to i.
790     pub max_latency_increase_plus1: [u8; 7],
791     /// min_luma_coding_block_size_minus3 plus 3 specifies the minimum luma
792     /// coding block size.
793     pub log2_min_luma_coding_block_size_minus3: u8,
794     /// Specifies the difference between the maximum and minimum luma coding
795     /// block size.
796     pub log2_diff_max_min_luma_coding_block_size: u8,
797     /// min_luma_transform_block_size_minus2 plus 2 specifies the minimum luma
798     /// transform block size.
799     pub log2_min_luma_transform_block_size_minus2: u8,
800     /// Specifies the difference between the maximum and minimum luma transform
801     /// block size.
802     pub log2_diff_max_min_luma_transform_block_size: u8,
803     /// Specifies the maximum hierarchy depth for transform units of coding
804     /// units coded in inter prediction mode.
805     pub max_transform_hierarchy_depth_inter: u8,
806     /// Specifies the maximum hierarchy depth for transform units of coding
807     /// units coded in intra prediction mode.
808     pub max_transform_hierarchy_depth_intra: u8,
809     /// When true, specifies that a scaling list is used for the scaling process
810     /// for transform coefficients. When false, specifies that scaling list is
811     /// not used for the scaling process for transform coefficients.
812     pub scaling_list_enabled_flag: bool,
813     /* if scaling_list_enabled_flag */
814     /// When true, specifies that the scaling_list_data( ) syntax structure is
815     /// present in the SPS. When false, specifies that the scaling_list_data( )
816     /// syntax structure is not present in the SPS.
817     pub scaling_list_data_present_flag: bool,
818     /// The scaling_list_data() syntax data.
819     pub scaling_list: ScalingLists,
820     /// When true, specifies that asymmetric motion partitions, i.e., PartMode
821     /// equal to PART_2NxnU, PART_2NxnD, PART_nLx2N or PART_nRx2N, may be used
822     /// in CTBs. When false, specifies that asymmetric motion partitions cannot
823     /// be used in CTBs.
824     pub amp_enabled_flag: bool,
825     /// When true, specifies that the sample adaptive offset process is applied
826     /// to the reconstructed picture after the deblocking filter process.  When
827     /// false, specifies that the sample adaptive offset process is not applied
828     /// to the reconstructed picture after the deblocking filter process.
829     pub sample_adaptive_offset_enabled_flag: bool,
830     /// When false, specifies that PCM-related syntax
831     /// (pcm_sample_bit_depth_luma_minus1, pcm_sample_ bit_depth_chroma_minus1,
832     /// log2_min_pcm_luma_coding_block_size_minus3, log2_diff_max_min_pcm_luma_
833     /// coding_block_size, pcm_loop_filter_disabled_flag, pcm_flag,
834     /// pcm_alignment_zero_bit syntax elements and pcm_sample( ) syntax
835     /// structure) is not present in the CVS.
836     pub pcm_enabled_flag: bool,
837 
838     /* if pcm_enabled_flag */
839     pub pcm_sample_bit_depth_luma_minus1: u8,
840     /// Specifies the number of bits used to represent each of PCM sample values
841     /// of the luma component.
842     pub pcm_sample_bit_depth_chroma_minus1: u8,
843     /// Specifies the number of bits used to represent each of PCM sample values
844     /// of the chroma components.
845     pub log2_min_pcm_luma_coding_block_size_minus3: u8,
846     /// Specifies the difference between the maximum and minimum size of coding
847     /// blocks with pcm_flag equal to true.
848     pub log2_diff_max_min_pcm_luma_coding_block_size: u8,
849     /// Specifies whether the loop filter process is disabled on reconstructed
850     /// samples in a coding unit with pcm_flag equal to true as follows:
851     ///
852     /// – If pcm_loop_filter_disabled_flag is set, the deblocking filter and
853     /// sample adaptive offset filter processes on the reconstructed samples in
854     /// a coding unit with pcm_flag set are disabled.
855     ///
856     /// – Otherwise (pcm_loop_filter_disabled_flag value is not set), the
857     /// deblocking filter and sample adaptive offset filter processes on the
858     /// reconstructed samples in a coding unit with pcm_flag set are not
859     /// disabled.
860     pub pcm_loop_filter_disabled_flag: bool,
861     /// Specifies the number of st_ref_pic_set( ) syntax structures included in
862     /// the SPS.
863     pub num_short_term_ref_pic_sets: u8,
864     /// the st_ref_pic_set() data.
865     pub short_term_ref_pic_set: Vec<ShortTermRefPicSet>,
866     /// If unset, specifies that no long-term reference picture is used for
867     /// inter prediction of any coded picture in the CVS.
868     /// If set, specifies that long-term reference pictures may be used for
869     /// inter prediction of one or more coded pictures in the CVS.
870     pub long_term_ref_pics_present_flag: bool,
871 
872     /* if long_term_ref_pics_present_flag */
873     /// Specifies the number of candidate long-term reference pictures that are
874     /// specified in the SPS.
875     pub num_long_term_ref_pics_sps: u8,
876     /// `lt_ref_pic_poc_lsb_sps[ i ]` specifies the picture order count modulo
877     /// MaxPicOrderCntLsb of the i-th candidate long-term reference picture
878     /// specified in the SPS.
879     pub lt_ref_pic_poc_lsb_sps: [u32; MAX_LONG_TERM_REF_PIC_SETS],
880     /// `used_by_curr_pic_lt_sps_flag[ i ]` equal to false specifies that the i-th
881     /// candidate long-term reference picture specified in the SPS is not used
882     /// for reference by a picture that includes in its long-term reference
883     /// picture set (RPS) the i-th candidate long-term reference picture
884     /// specified in the SPS.
885     pub used_by_curr_pic_lt_sps_flag: [bool; MAX_LONG_TERM_REF_PIC_SETS],
886     /// When set, specifies that slice_temporal_mvp_enabled_flag is present in
887     /// the slice headers of non-IDR pictures in the CVS. When not set,
888     /// specifies that slice_temporal_mvp_enabled_flag is not present in slice
889     /// headers and that temporal motion vector predictors are not used in the
890     /// CVS.
891     pub temporal_mvp_enabled_flag: bool,
892     /// When set, specifies that bi-linear interpolation is conditionally used
893     /// in the intraprediction filtering process in the CVS as specified in
894     /// clause 8.4.4.2.3.
895     pub strong_intra_smoothing_enabled_flag: bool,
896     /// When set, specifies that the vui_parameters( ) syntax structure as
897     /// specified in Annex E is present. When not set, specifies that the
898     /// vui_parameters( ) syntax structure as specified in Annex E is not
899     /// present.
900     pub vui_parameters_present_flag: bool,
901     /// The vui_parameters() data.
902     pub vui_parameters: VuiParams,
903     /// When set, specifies that the syntax elements sps_range_extension_flag,
904     /// sps_multilayer_extension_flag, sps_3d_extension_flag,
905     /// sps_scc_extension_flag, and sps_extension_4bits are present in the SPS
906     /// RBSP syntax structure. When not set, specifies that these syntax
907     /// elements are not present.
908     pub extension_present_flag: bool,
909 
910     pub range_extension_flag: bool,
911     /// The sps_range_extension() data.
912     pub range_extension: SpsRangeExtension,
913     /// When set, specifies that the sps_scc_extension( ) syntax structure is
914     /// present in the SPS RBSP syntax structure. When not set, specifies that
915     /// this syntax structure is not present
916     pub scc_extension_flag: bool,
917     /// The sps_scc_extension() data.
918     pub scc_extension: SpsSccExtension,
919 
920     // Internal H265 variables. Computed from the bitstream.
921     /// Equivalent to MinCbLog2SizeY in the specification.
922     pub min_cb_log2_size_y: u32,
923     /// Equivalent to CtbLog2SizeY in the specification.
924     pub ctb_log2_size_y: u32,
925     /// Equivalent to CtbSizeY in the specification.
926     pub ctb_size_y: u32,
927     /// Equivalent to PicHeightInCtbsY in the specification.
928     pub pic_height_in_ctbs_y: u32,
929     /// Equivalent to PicWidthInCtbsY in the specification.
930     pub pic_width_in_ctbs_y: u32,
931     /// Equivalent to PicSizeInCtbsY in the specification.
932     pub pic_size_in_ctbs_y: u32,
933     /// Equivalent to ChromaArrayType in the specification.
934     pub chroma_array_type: u8,
935     /// Equivalent to WpOffsetHalfRangeY in the specification.
936     pub wp_offset_half_range_y: u32,
937     /// Equivalent to WpOffsetHalfRangeC in the specification.
938     pub wp_offset_half_range_c: u32,
939     /// Equivalent to MaxTbLog2SizeY in the specification.
940     pub max_tb_log2_size_y: u32,
941     /// Equivalent to PicSizeInSamplesY in the specification.
942     pub pic_size_in_samples_y: u32,
943 
944     /// The VPS referenced by this SPS, if any.
945     pub vps: Option<Rc<Vps>>,
946 }
947 
948 impl Sps {
max_dpb_size(&self) -> usize949     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         // Equation A-2
954         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 
width(&self) -> u16967     pub fn width(&self) -> u16 {
968         self.pic_width_in_luma_samples
969     }
970 
height(&self) -> u16971     pub fn height(&self) -> u16 {
972         self.pic_height_in_luma_samples
973     }
974 
visible_rectangle(&self) -> Rect<u32>975     pub fn visible_rectangle(&self) -> Rect<u32> {
976         // From the specification:
977         // NOTE 3 – The conformance cropping window offset parameters are
978         // only applied at the output. All internal decoding processes are
979         // applied to the uncropped picture size.
980         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)]
1007 pub struct PpsSccExtension {
1008     /// When set, specifies that a picture referring to the PPS may be included
1009     /// in a reference picture list of a slice of the picture itself.  If not
1010     /// set, specifies that a picture referring to the PPS is never included in
1011     /// a reference picture list of a slice of the picture itself.
1012     pub curr_pic_ref_enabled_flag: bool,
1013     /// When set, specifies that an adaptive colour transform may be applied to
1014     /// the residual in the decoding process. When not set, specifies that
1015     /// adaptive colour transform is not applied to the residual.
1016     pub residual_adaptive_colour_transform_enabled_flag: bool,
1017     /// When set, specifies that slice_act_y_qp_offset, slice_act_cb_qp_offset,
1018     /// slice_act_cr_qp_offset are present in the slice header.  When not set,
1019     /// specifies that slice_act_y_qp_offset, slice_act_cb_qp_offset,
1020     /// slice_act_cr_qp_offset are not present in the slice header.
1021     pub slice_act_qp_offsets_present_flag: bool,
1022     /// See the specificartion for more details.
1023     pub act_y_qp_offset_plus5: i8,
1024     /// See the specificartion for more details.
1025     pub act_cb_qp_offset_plus5: i8,
1026     /// See the specificartion for more details.
1027     pub act_cr_qp_offset_plus3: i8,
1028     /// When set, specifies that the palette predictor initializers used for the
1029     /// pictures referring to the PPS are derived based on the palette predictor
1030     /// initializers specified by the PPS. If not set, specifies that the
1031     /// palette predictor initializers used for the pictures referring to the
1032     /// PPS are inferred to be equal to those specified by the active SPS.
1033     pub palette_predictor_initializers_present_flag: bool,
1034     /// Specifies the number of entries in the picture palette predictor
1035     /// initializer.
1036     pub num_palette_predictor_initializers: u8,
1037     /// When set, specifies that the pictures that refer to this PPS are
1038     /// monochrome. If not set, specifies that the pictures that refer to this
1039     /// PPS have multiple components.
1040     pub monochrome_palette_flag: bool,
1041     /// luma_bit_depth_entry_minus8 plus 8 specifies the bit depth of the luma
1042     /// component of the entries of the palette predictor initializer.
1043     pub luma_bit_depth_entry_minus8: u8,
1044     /// chroma_bit_depth_entry_minus8 plus 8 specifies the bit depth of the
1045     /// chroma components of the entries of the palette predictor initializer.
1046     pub chroma_bit_depth_entry_minus8: u8,
1047     /// `pps_palette_predictor_initializer[ comp ][ i ]` specifies the value of
1048     /// the comp-th component of the i-th palette entry in the PPS that is used
1049     /// to initialize the array PredictorPaletteEntries.
1050     pub palette_predictor_initializer: [[u8; 128]; 3],
1051 }
1052 
1053 impl Default for PpsSccExtension {
default() -> Self1054     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)]
1073 pub struct PpsRangeExtension {
1074     /// log2_max_transform_skip_block_size_minus2 plus 2 specifies the maximum
1075     /// transform block size for which transform_skip_flag may be present in
1076     /// coded pictures referring to the PPS. When not present, the value of
1077     /// log2_max_transform_skip_block_size_minus2 is inferred to be equal to 0.
1078     /// When present, the value of log2_max_transform_skip_block_size_minus2
1079     /// shall be less than or equal to MaxTbLog2SizeY − 2.
1080     pub log2_max_transform_skip_block_size_minus2: u32,
1081     /// When set, specifies that log2_res_scale_abs_plus1 and
1082     /// res_scale_sign_flag may be present in the transform unit syntax for
1083     /// pictures referring to the PPS. When not set, specifies that
1084     /// log2_res_scale_abs_plus1 and res_scale_sign_flag are not present for
1085     /// pictures referring to the PPS.
1086     pub cross_component_prediction_enabled_flag: bool,
1087     /// When set, specifies that the cu_chroma_qp_offset_flag may be present in
1088     /// the transform unit syntax. When not set, specifies that the
1089     /// cu_chroma_qp_offset_flag is not present in the transform unit syntax.
1090     pub chroma_qp_offset_list_enabled_flag: bool,
1091     /// Specifies the difference between the luma CTB size and the minimum luma
1092     /// coding block size of coding units that convey cu_chroma_qp_offset_flag.
1093     pub diff_cu_chroma_qp_offset_depth: u32,
1094     /// chroma_qp_offset_list_len_minus1 plus 1 specifies the number of
1095     /// `cb_qp_offset_list[ i ]` and `cr_qp_offset_list[ i ]` syntax elements that
1096     /// are present in the PPS.
1097     pub chroma_qp_offset_list_len_minus1: u32,
1098     /// Specify offsets used in the derivation of Qp′Cb and Qp′Cr, respectively.
1099     pub cb_qp_offset_list: [i32; 6],
1100     /// Specify offsets used in the derivation of Qp′Cb and Qp′Cr, respectively.
1101     pub cr_qp_offset_list: [i32; 6],
1102     /// The base 2 logarithm of the scaling parameter that is used to scale
1103     /// sample adaptive offset (SAO) offset values for luma samples.
1104     pub log2_sao_offset_scale_luma: u32,
1105     /// The base 2 logarithm of the scaling parameter that is used to scale SAO
1106     /// offset values for chroma samples.
1107     pub log2_sao_offset_scale_chroma: u32,
1108 }
1109 
1110 /// A H.265 Picture Parameter Set.
1111 #[derive(Clone, Debug, PartialEq, Eq)]
1112 pub struct Pps {
1113     /// Identifies the PPS for reference by other syntax elements.
1114     pub pic_parameter_set_id: u8,
1115     /// Specifies the value of sps_seq_parameter_set_id for the active SPS.
1116     pub seq_parameter_set_id: u8,
1117     /// When set, specifies the presence of the syntax element
1118     /// dependent_slice_segment_flag in the slice segment headers for coded
1119     /// pictures referring to the PPS. When not set, specifies the absence of
1120     /// the syntax element dependent_slice_segment_flag in the slice segment
1121     /// headers for coded pictures referring to the PPS.
1122     pub dependent_slice_segments_enabled_flag: bool,
1123     /// When set, indicates that the pic_output_flag syntax element is present
1124     /// in the associated slice headers. When not set, indicates that the
1125     /// pic_output_flag syntax element is not present in the associated slice
1126     /// headers.
1127     pub output_flag_present_flag: bool,
1128     /// Specifies the number of extra slice header bits that are present in the
1129     /// slice header RBSP for coded pictures referring to the PPS.
1130     pub num_extra_slice_header_bits: u8,
1131     /// When not set, specifies that sign bit hiding is disabled. Whens set,
1132     /// specifies that sign bit hiding is enabled.
1133     pub sign_data_hiding_enabled_flag: bool,
1134     /// When set, specifies that cabac_init_flag is present in slice headers
1135     /// referring to the PPS. When not set, specifies that cabac_init_flag is
1136     /// not present in slice headers referring to the PPS.
1137     pub cabac_init_present_flag: bool,
1138     /// Specifies the inferred value of num_ref_idx_l0_active_minus1 for P and B
1139     /// slices with num_ref_idx_active_override_flag not set.
1140     pub num_ref_idx_l0_default_active_minus1: u8,
1141     /// Specifies the inferred value of num_ref_idx_l1_active_minus1 for B
1142     /// slices with num_ref_idx_active_override_flag not set.
1143     pub num_ref_idx_l1_default_active_minus1: u8,
1144     /// init_qp_minus26 plus 26 specifies the initial value of SliceQpY for each
1145     /// slice referring to the PPS. The initial value of SliceQpY is modified at
1146     /// the slice segment layer when a non-zero value of slice_qp_delta is
1147     /// decoded.
1148     pub init_qp_minus26: i8,
1149     /// When not set, specifies that intra prediction allows usage of residual
1150     /// data and decoded samples of neighbouring coding blocks coded using
1151     /// either intra or inter prediction modes. When set, specifies constrained
1152     /// intra prediction, in which case intra prediction only uses residual data
1153     /// and decoded samples from neighbouring coding blocks coded using intra
1154     /// prediction modes.
1155     pub constrained_intra_pred_flag: bool,
1156     /// When set, specifies that transform_skip_flag may be present in the
1157     /// residual coding syntax. When not set, specifies that transform_skip_flag
1158     /// is not present in the residual coding syntax.
1159     pub transform_skip_enabled_flag: bool,
1160     /// When set, specifies that the diff_cu_qp_delta_depth syntax element is
1161     /// present in the PPS and that cu_qp_delta_abs may be present in the
1162     /// transform unit syntax and the palette syntax. When not set, specifies
1163     /// that the diff_cu_qp_delta_depth syntax element is not present in the PPS
1164     /// and that cu_qp_delta_abs is not present in the transform unit syntax and
1165     /// the palette syntax.
1166     pub cu_qp_delta_enabled_flag: bool,
1167 
1168     /*if cu_qp_delta_enabled_flag */
1169     /// Specifies the difference between the luma CTB size and the minimum luma
1170     /// coding block size of coding units that convey cu_qp_delta_abs and
1171     /// cu_qp_delta_sign_flag.
1172     pub diff_cu_qp_delta_depth: u8,
1173     /// Specifies the offsets to the luma quantization parameter Qp′Y used for
1174     /// deriving Qp′Cb and Qp′Cr, respectively.
1175     pub cb_qp_offset: i8,
1176     /// Specifies the offsets to the luma quantization parameter Qp′Y used for
1177     /// deriving Qp′Cb and Qp′Cr, respectively.
1178     pub cr_qp_offset: i8,
1179     /// When set, indicates that the slice_cb_qp_offset and slice_cr_qp_offset
1180     /// syntax elements are present in the associated slice headers.  When not
1181     /// set, indicates that these syntax elements are not present in the
1182     /// associated slice headers. When ChromaArrayType is equal to 0,
1183     /// pps_slice_chroma_qp_offsets_present_flag shall be equal to 0
1184     pub slice_chroma_qp_offsets_present_flag: bool,
1185     /// When not set, specifies that weighted prediction is not applied to P
1186     /// slices. When set, specifies that weighted prediction is applied to P
1187     /// slices.
1188     pub weighted_pred_flag: bool,
1189     /// When not set, specifies that the default weighted prediction is applied
1190     /// to B slices. When set, specifies that weighted prediction is applied to
1191     /// B slices.
1192     pub weighted_bipred_flag: bool,
1193     /// When set, specifies that `cu_transquant_bypass_flag` is present, When
1194     /// not set, specifies that `cu_transquant_bypass_flag` is not present.
1195     pub transquant_bypass_enabled_flag: bool,
1196     /// When set, specifies that there is more than one tile in each picture
1197     /// referring to the PPS. When not set, specifies that there is only one
1198     /// tile in each picture referring to the PPS.
1199     pub tiles_enabled_flag: bool,
1200     /// When set, specifies that a specific synchronization process for context
1201     /// variables, and when applicable, Rice parameter initialization states and
1202     /// palette predictor variables, is invoked before decoding the CTU which
1203     /// includes the first CTB of a row of CTBs in each tile in each picture
1204     /// referring to the PPS, and a specific storage process for context
1205     /// variables, and when applicable, Rice parameter initialization states and
1206     /// palette predictor variables, is invoked after decoding the CTU which
1207     /// includes the second CTB of a row of CTBs in each tile in each picture
1208     /// referring to the PPS. When not set, specifies that no specific
1209     /// synchronization process for context variables, and when applicable, Rice
1210     /// parameter initialization states and palette predictor variables, is
1211     /// required to be invoked before decoding the CTU which includes the first
1212     /// CTB of a row of CTBs in each tile in each picture referring to the PPS,
1213     /// and no specific storage process for context variables, and when
1214     /// applicable, Rice parameter initialization states and palette predictor
1215     /// variables, is required to be invoked after decoding the CTU which
1216     /// includes the second CTB of a row of CTBs in each tile in each picture
1217     /// referring to the PPS.
1218     pub entropy_coding_sync_enabled_flag: bool,
1219     /// num_tile_columns_minus1 plus 1 specifies the number of tile columns
1220     /// partitioning the picture.
1221     pub num_tile_columns_minus1: u8,
1222     /// num_tile_rows_minus1 plus 1 specifies the number of tile rows
1223     /// partitioning the picture.
1224     pub num_tile_rows_minus1: u8,
1225     /// When set, specifies that tile column boundaries and likewise tile row
1226     /// boundaries are distributed uniformly across the picture.  When not set,
1227     /// specifies that tile column boundaries and likewise tile row boundaries
1228     /// are not distributed uniformly across the picture but signalled
1229     /// explicitly using the syntax elements `column_width_minus1[ i ]` and
1230     /// `row_height_minus1[ i ]`.
1231     pub uniform_spacing_flag: bool,
1232     /// `column_width_minus1[ i ]` plus 1 specifies the width of the i-th tile
1233     /// column in units of CTBs.
1234     pub column_width_minus1: [u32; 19],
1235     /// `row_height_minus1[ i ]` plus 1 specifies the height of the i-th tile row
1236     /// in units of CTBs.
1237     pub row_height_minus1: [u32; 21],
1238     /// When set, specifies that in-loop filtering operations may be performed
1239     /// across tile boundaries in pictures referring to the PPS.  When not set,
1240     /// specifies that in-loop filtering operations are not performed across
1241     /// tile boundaries in pictures referring to the PPS. The in-loop filtering
1242     /// operations include the deblocking filter and sample adaptive offset
1243     /// filter operations.
1244     pub loop_filter_across_tiles_enabled_flag: bool,
1245     /// When set, specifies that in-loop filtering operations may be performed
1246     /// across left and upper boundaries of slices referring to the PPS.  When
1247     /// not set, specifies that in-loop filtering operations are not performed
1248     /// across left and upper boundaries of slices referring to the PPS. The in-
1249     /// loop filtering operations include the deblocking filter and sample
1250     /// adaptive offset filter operations.
1251     pub loop_filter_across_slices_enabled_flag: bool,
1252     /// When set, specifies the presence of deblocking filter control syntax
1253     /// elements in the PPS. When not set, specifies the absence of deblocking
1254     /// filter control syntax elements in the PPS.
1255     pub deblocking_filter_control_present_flag: bool,
1256     /// When set, specifies the presence of deblocking_filter_override_flag in
1257     /// the slice headers for pictures referring to the PPS.  When not set,
1258     /// specifies the absence of deblocking_filter_override_flag in the slice
1259     /// headers for pictures referring to the PPS.
1260     pub deblocking_filter_override_enabled_flag: bool,
1261     /// When set, specifies that the operation of deblocking filter is not
1262     /// applied for slices referring to the PPS in which
1263     /// slice_deblocking_filter_disabled_flag is not present.  When not set,
1264     /// specifies that the operation of the deblocking filter is applied for
1265     /// slices referring to the PPS in which
1266     /// slice_deblocking_filter_disabled_flag is not present.
1267     pub deblocking_filter_disabled_flag: bool,
1268     /// Specify the default deblocking parameter offsets for β and tC (divided
1269     /// by 2) that are applied for slices referring to the PPS, unless the
1270     /// default deblocking parameter offsets are overridden by the deblocking
1271     /// parameter offsets present in the slice headers of the slices referring
1272     /// to the PPS.
1273     pub beta_offset_div2: i8,
1274     /// Specify the default deblocking parameter offsets for β and tC (divided
1275     /// by 2) that are applied for slices referring to the PPS, unless the
1276     /// default deblocking parameter offsets are overridden by the deblocking
1277     /// parameter offsets present in the slice headers of the slices referring
1278     /// to the PPS.
1279     pub tc_offset_div2: i8,
1280     /// When set, specifies that the scaling list data used for the pictures
1281     /// referring to the PPS are derived based on the scaling lists specified by
1282     /// the active SPS and the scaling lists specified by the PPS.
1283     /// pps_scaling_list_data_present_flag equal to 0 specifies that the scaling
1284     /// list data used for the pictures referring to the PPS are inferred to be
1285     /// equal to those specified by the active SPS.
1286     pub scaling_list_data_present_flag: bool,
1287     /// The scaling list data.
1288     pub scaling_list: ScalingLists,
1289     /// When set, specifies that the syntax structure
1290     /// ref_pic_lists_modification( ) is present in the slice segment header.
1291     /// When not set, specifies that the syntax structure
1292     /// ref_pic_lists_modification( ) is not present in the slice segment header
1293     pub lists_modification_present_flag: bool,
1294     /// log2_parallel_merge_level_minus2 plus 2 specifies the value of the
1295     /// variable Log2ParMrgLevel, which is used in the derivation process for
1296     /// luma motion vectors for merge mode as specified in clause 8.5.3.2.2 and
1297     /// the derivation process for spatial merging candidates as specified in
1298     /// clause 8.5.3.2.3.
1299     pub log2_parallel_merge_level_minus2: u8,
1300     /// When not set, specifies that no slice segment header extension syntax
1301     /// elements are present in the slice segment headers for coded pictures
1302     /// referring to the PPS. When set, specifies that slice segment header
1303     /// extension syntax elements are present in the slice segment headers for
1304     /// coded pictures referring to the PPS.
1305     pub slice_segment_header_extension_present_flag: bool,
1306     /// When set, specifies that the syntax elements pps_range_extension_flag,
1307     /// pps_multilayer_extension_flag, pps_3d_extension_flag,
1308     /// pps_scc_extension_flag, and pps_extension_4bits are present in the
1309     /// picture parameter set RBSP syntax structure. When not set, specifies
1310     /// that these syntax elements are not present.
1311     pub extension_present_flag: bool,
1312     /// When setspecifies that the pps_range_extension( ) syntax structure is
1313     /// present in the PPS RBSP syntax structure. When not set, specifies that
1314     /// this syntax structure is not present.
1315     pub range_extension_flag: bool,
1316     /// The range extension data.
1317     pub range_extension: PpsRangeExtension,
1318 
1319     pub scc_extension_flag: bool,
1320     /// The SCC extension data.
1321     pub scc_extension: PpsSccExtension,
1322 
1323     // Internal variables.
1324     /// Equivalent to QpBdOffsetY in the specification.
1325     pub qp_bd_offset_y: u32,
1326 
1327     /// The SPS referenced by this PPS.
1328     pub sps: Rc<Sps>,
1329 }
1330 
1331 #[derive(Clone, Debug, PartialEq, Eq)]
1332 pub struct ScalingLists {
1333     /// plus 8 specifies the value of the variable `ScalingFactor[ 2 ][ matrixId
1334     /// ] [ 0 ][ 0 ]` for the scaling list for the 16x16 size.
1335     pub scaling_list_dc_coef_minus8_16x16: [i16; 6],
1336     /// plus 8 specifies the value of the variable `ScalingFactor[ 3 ][ matrixId
1337     /// ][ 0 ][ 0 ]` for the scaling list for the 32x32 size.
1338     pub scaling_list_dc_coef_minus8_32x32: [i16; 6],
1339     /// The 4x4 scaling list.
1340     pub scaling_list_4x4: [[u8; 16]; 6],
1341     /// The 8x8 scaling list.
1342     pub scaling_list_8x8: [[u8; 64]; 6],
1343     /// The 16x16 scaling list.
1344     pub scaling_list_16x16: [[u8; 64]; 6],
1345     /// The 32x32 scaling list.
1346     pub scaling_list_32x32: [[u8; 64]; 6],
1347 }
1348 
1349 impl Default for ScalingLists {
default() -> Self1350     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)]
1363 pub struct RefPicListModification {
1364     /// Whenset, indicates that reference picture list 0 is specified explicitly
1365     /// by a list of `list_entry_l0[ i ]` values.  When not set, indicates that
1366     /// reference picture list 0 is determined implicitly.
1367     pub ref_pic_list_modification_flag_l0: bool,
1368     /// `list_entry_l0[ i ]` specifies the index of the reference picture in
1369     /// RefPicListTemp0 to be placed at the current position of reference
1370     /// picture list 0.
1371     pub list_entry_l0: Vec<u32>,
1372     /// Whenset, indicates that reference picture list 1 is specified explicitly
1373     /// by a list of `list_entry_l1[ i ]` values.  When not set, indicates that
1374     /// reference picture list 1 is determined implicitly.
1375     pub ref_pic_list_modification_flag_l1: bool,
1376     /// `list_entry_l1[ i ]` specifies the index of the reference picture in
1377     /// RefPicListTemp1 to be placed at the current position of reference
1378     /// picture list 1.
1379     pub list_entry_l1: Vec<u32>,
1380 }
1381 
1382 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1383 pub struct PredWeightTable {
1384     /// The base 2 logarithm of the denominator for all luma weighting factors.
1385     pub luma_log2_weight_denom: u8,
1386     /// The difference of the base 2 logarithm of the denominator for all chroma
1387     /// weighting factors.
1388     pub delta_chroma_log2_weight_denom: i8,
1389     /// `luma_weight_l0_flag[ i ]` set specifies that weighting factors for the
1390     /// luma component of list 0 prediction using `RefPicList0[ i ]` are present.
1391     /// `luma_weight_l0_flag[ i ]` not set specifies that these weighting factors
1392     /// are not present.
1393     pub luma_weight_l0_flag: [bool; 15],
1394     /// `chroma_weight_l0_flag[ i ]` set specifies that weighting factors for the
1395     /// chroma prediction values of list 0 prediction using `RefPicList0[ i ]` are
1396     /// present. `chroma_weight_l0_flag[ i ]` not set specifies that these
1397     /// weighting factors are not present.
1398     pub chroma_weight_l0_flag: [bool; 15],
1399     /// `delta_luma_weight_l0[ i ]` is the difference of the weighting factor
1400     /// applied to the luma prediction value for list 0 prediction using
1401     /// `RefPicList0[ i ]`.
1402     pub delta_luma_weight_l0: [i8; 15],
1403     /// `luma_offset_l0[ i ]` is the additive offset applied to the luma
1404     /// prediction value for list 0 prediction using `RefPicList0[ i ]`.
1405     pub luma_offset_l0: [i8; 15],
1406     /// `delta_chroma_weight_l0[ i ][ j ]` is the difference of the weighting
1407     /// factor applied to the chroma prediction values for list 0 prediction
1408     /// using `RefPicList0[ i ]` with j equal to 0 for Cb and j equal to 1 for Cr.
1409     pub delta_chroma_weight_l0: [[i8; 2]; 15],
1410     /// `delta_chroma_offset_l0[ i ][ j ]` is the difference of the additive
1411     /// offset applied to the chroma prediction values for list 0 prediction
1412     /// using `RefPicList0[ i ]` with j equal to 0 for Cb and j equal to 1 for Cr.
1413     pub delta_chroma_offset_l0: [[i16; 2]; 15],
1414 
1415     // `luma_weight_l1_flag[ i ]`, `chroma_weight_l1_flag[ i ]`,
1416     // `delta_luma_weight_l1[ i ]`, `luma_offset_l1[ i ]`, delta_chroma_weight_l1[ i
1417     // `][ j ]` and `delta_chroma_offset_l1[ i ]`[ j ] have the same
1418     // `semanticsasluma_weight_l0_flag[ i ]`, `chroma_weight_l0_flag[ i ]`,
1419     // `delta_luma_weight_l0[ i ]`, `luma_offset_l0[ i ]`, `delta_chroma_weight_l0[ i
1420     // ][ j ]` and `delta_chroma_offset_l0[ i ][ j ]`, respectively, with `l0`, `L0`,
1421     // `list 0` and `List0` replaced by `l1`, `L1`, `list 1` and `List1`, respectively.
1422     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     // Calculated.
1431     /// Same as ChromaLog2WeightDenom in the specification.
1432     pub chroma_log2_weight_denom: u8,
1433 }
1434 
1435 #[derive(Clone, Debug, PartialEq, Eq)]
1436 pub struct ShortTermRefPicSet {
1437     /// When set, specifies that the stRpsIdx-th candidate short-term RPS is
1438     /// predicted from another candidate short-term RPS, which is referred to as
1439     /// the source candidate short-term RPS.
1440     pub inter_ref_pic_set_prediction_flag: bool,
1441     /// delta_idx_minus1 plus 1 specifies the difference between the value of
1442     /// stRpsIdx and the index, into the list of the candidate short-term RPSs
1443     /// specified in the SPS, of the source candidate short-term RPS.
1444     pub delta_idx_minus1: u8,
1445     /// delta_rps_sign and abs_delta_rps_minus1 together specify the value of
1446     /// the variable deltaRps.
1447     pub delta_rps_sign: bool,
1448     /// delta_rps_sign and abs_delta_rps_minus1 together specify the value of
1449     /// the variable deltaRps.
1450     pub abs_delta_rps_minus1: u16,
1451     /// specifies the number of entries in the stRpsIdx-th candidate short-term
1452     /// RPS that have picture order count values less than the picture order
1453     /// count value of the current picture.
1454     pub num_negative_pics: u8,
1455     /// specifies the number of entries in the stRpsIdx-th candidate short-term
1456     /// RPS that have picture order count values greater than the picture order
1457     /// count value of the current picture.
1458     pub num_positive_pics: u8,
1459     /// Same as UsedByCurrPicS0 in the specification.
1460     pub used_by_curr_pic_s0: [bool; MAX_SHORT_TERM_REF_PIC_SETS],
1461     /// Same as UsedByCurrPicS1 in the specification.
1462     pub used_by_curr_pic_s1: [bool; MAX_SHORT_TERM_REF_PIC_SETS],
1463     /// Same as DeltaPocS0 in the specification.
1464     pub delta_poc_s0: [i32; MAX_SHORT_TERM_REF_PIC_SETS],
1465     /// Same as DeltaPocS1 in the specification.
1466     pub delta_poc_s1: [i32; MAX_SHORT_TERM_REF_PIC_SETS],
1467     /// Same as NumDeltaPocs in the specification.
1468     pub num_delta_pocs: u32,
1469 }
1470 
1471 impl Default for ShortTermRefPicSet {
default() -> Self1472     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)]
1490 /// See table 7-7 in the specification.
1491 pub enum SliceType {
1492     B = 0,
1493     P = 1,
1494     I = 2,
1495 }
1496 
1497 impl TryFrom<u32> for SliceType {
1498     type Error = String;
1499 
try_from(value: u32) -> Result<Self, Self::Error>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 
1510 impl SliceType {
1511     /// Whether this is a P slice. See table 7-7 in the specification.
is_p(&self) -> bool1512     pub fn is_p(&self) -> bool {
1513         matches!(self, SliceType::P)
1514     }
1515 
1516     /// Whether this is a B slice. See table 7-7 in the specification.
is_b(&self) -> bool1517     pub fn is_b(&self) -> bool {
1518         matches!(self, SliceType::B)
1519     }
1520 
1521     /// Whether this is an I slice. See table 7-7 in the specification.
is_i(&self) -> bool1522     pub fn is_i(&self) -> bool {
1523         matches!(self, SliceType::I)
1524     }
1525 }
1526 
1527 impl Default for SliceType {
default() -> Self1528     fn default() -> Self {
1529         Self::P
1530     }
1531 }
1532 
1533 #[derive(Clone, Debug, PartialEq, Eq)]
1534 pub struct SliceHeader {
1535     /// When set, specifies that the slice segment is the first slice segment of
1536     /// the picture in decoding order. When not set, specifies that the slice
1537     /// segment is not the first slice segment of the picture in decoding order.
1538     pub first_slice_segment_in_pic_flag: bool,
1539     /// Affects the output of previously-decoded pictures in the decoded picture
1540     /// buffer after the decoding of an IDR or a BLA picture that is not the
1541     /// first picture in the bitstream as specified in Annex C.
1542     pub no_output_of_prior_pics_flag: bool,
1543     /// Specifies the value of pps_pic_parameter_set_id for the PPS in use.
1544     pub pic_parameter_set_id: u8,
1545     /// When set, specifies that the value of each slice segment header syntax
1546     /// element that is not present is inferred to be equal to the value of the
1547     /// corresponding slice segment header syntax element in the slice header.
1548     pub dependent_slice_segment_flag: bool,
1549     /// Specifies the address of the first CTB in the slice segment, in CTB
1550     /// raster scan of a picture.
1551     pub segment_address: u32,
1552     /// Specifies the coding type of the slice according to Table 7-7.
1553     pub type_: SliceType,
1554     /// Affects the decoded picture output and removal processes as specified in
1555     /// Annex C.
1556     pub pic_output_flag: bool,
1557     /// Specifies the colour plane associated with the current slice RBSP when
1558     /// separate_colour_plane_flag is set. The value of colour_plane_id shall be
1559     /// in the range of 0 to 2, inclusive. colour_plane_id values 0, 1 and 2
1560     /// correspond to the Y, Cb and Cr planes, respectively.
1561     pub colour_plane_id: u8,
1562     /// Specifies the picture order count modulo MaxPicOrderCntLsb for the
1563     /// current picture. The length of the slice_pic_order_cnt_lsb syntax
1564     /// element is log2_max_pic_order_cnt_lsb_minus4 + 4 bits.
1565     pub pic_order_cnt_lsb: u16,
1566     /// When set, specifies that the short-term RPS of the current picture is
1567     /// derived based on one of the st_ref_pic_set( ) syntax structures in the
1568     /// active SPS that is identified by the syntax element
1569     /// short_term_ref_pic_set_idx in the slice header.  When not set, specifies
1570     /// that the short-term RPS of the current picture is derived based on the
1571     /// st_ref_pic_set( ) syntax structure that is directly included in the
1572     /// slice headers of the current picture.
1573     pub short_term_ref_pic_set_sps_flag: bool,
1574     /// The st_ref_pic_set() data.
1575     pub short_term_ref_pic_set: ShortTermRefPicSet,
1576     /// Specifies the index, into the list of the st_ref_pic_set( ) syntax
1577     /// structures included in the active SPS, of the st_ref_pic_set( ) syntax
1578     /// structure that is used for derivation of the short-term RPS of the
1579     /// current picture.
1580     pub short_term_ref_pic_set_idx: u8,
1581     /// Specifies the number of entries in the long-term RPS of the current
1582     /// picture that are derived based on the candidate long-term reference
1583     /// pictures specified in the active SPS.
1584     pub num_long_term_sps: u8,
1585     /// Specifies the number of entries in the long-term RPS of the current
1586     /// picture that are directly signalled in the slice header.
1587     pub num_long_term_pics: u8,
1588     /// `lt_idx_sps[ i ]` specifies an index, into the list of candidate long-term
1589     /// reference pictures specified in the active SPS, of the i-th entry in the
1590     /// long-term RPS of the current picture.
1591     pub lt_idx_sps: [u8; 16],
1592     /// Same as PocLsbLt in the specification.
1593     pub poc_lsb_lt: [u32; 16],
1594     /// Same as UsedByCurrPicLt in the specification.
1595     pub used_by_curr_pic_lt: [bool; 16],
1596     /// When set, specifies that that `delta_poc_msb_cycle_lt[i]` is present.
1597     pub delta_poc_msb_present_flag: [bool; 16],
1598     /// Same as DeltaPocMsbCycleLt in the specification.
1599     pub delta_poc_msb_cycle_lt: [u32; 16],
1600     /// Specifies whether temporal motion vector predictors can be used for
1601     /// inter prediction. If slice_temporal_mvp_enabled_flag is not set, the
1602     /// syntax elements of the current picture shall be constrained such that no
1603     /// temporal motion vector predictor is used in decoding of the current
1604     /// picture. Otherwise (slice_temporal_mvp_enabled_flag is set), temporal
1605     /// motion vector predictors may be used in decoding of the current picture.
1606     pub temporal_mvp_enabled_flag: bool,
1607     /// When set, specifies that SAO is enabled for the luma component in the
1608     /// current slice; slice_sao_luma_flag not set specifies that SAO is
1609     /// disabled for the luma component in the current slice.
1610     pub sao_luma_flag: bool,
1611     /// When set, specifies that SAO is enabled for the chroma component in the
1612     /// current slice; When not set, specifies that SAO is disabled for the
1613     /// chroma component in the current slice.
1614     pub sao_chroma_flag: bool,
1615     /// When set, specifies that the syntax element num_ref_idx_l0_active_minus1
1616     /// is present for P and B slices and that the syntax element
1617     /// num_ref_idx_l1_active_minus1 is present for B slices. When not set,
1618     /// specifies that the syntax elements num_ref_idx_l0_active_minus1 and
1619     /// num_ref_idx_l1_active_minus1 are not present.
1620     pub num_ref_idx_active_override_flag: bool,
1621     /// Specifies the maximum reference index for
1622     /// reference picture list 0 that may be used to decode the slice.
1623     pub num_ref_idx_l0_active_minus1: u8,
1624     /// Specifies the maximum reference index for reference picture list 1 that
1625     /// may be used to decode the slice.
1626     pub num_ref_idx_l1_active_minus1: u8,
1627     /// The RefPicListModification data.
1628     pub ref_pic_list_modification: RefPicListModification,
1629     /// When set, indicates that the mvd_coding( x0, y0, 1 ) syntax structure is
1630     /// not parsed and `MvdL1[ x0 ]`[ y0 `][ compIdx ]` is set equal to 0 for
1631     /// compIdx = 0..1. When not set, indicates that the mvd_coding( x0, y0, 1 )
1632     /// syntax structure is parsed.
1633     pub mvd_l1_zero_flag: bool,
1634     /// Specifies the method for determining the initialization table used in
1635     /// the initialization process for context variables.
1636     pub cabac_init_flag: bool,
1637     /// When set, specifies that the collocated picture used for temporal motion
1638     /// vector prediction is derived from reference picture list 0.  When not
1639     /// set, specifies that the collocated picture used for temporal motion
1640     /// vector prediction is derived from reference picture list 1.
1641     pub collocated_from_l0_flag: bool,
1642     /// Specifies the reference index of the collocated picture used for
1643     /// temporal motion vector prediction.
1644     pub collocated_ref_idx: u8,
1645     /// The PredWeightTable data.
1646     pub pred_weight_table: PredWeightTable,
1647     /// Specifies the maximum number of merging motion vector prediction (MVP)
1648     /// candidates supported in the slice subtracted from 5.
1649     pub five_minus_max_num_merge_cand: u8,
1650     /// Specifies that the resolution of motion vectors for inter prediction in
1651     /// the current slice is integer. When not set, specifies
1652     /// that the resolution of motion vectors for inter prediction in the
1653     /// current slice that refer to pictures other than the current picture is
1654     /// fractional with quarter-sample precision in units of luma samples.
1655     pub use_integer_mv_flag: bool,
1656     /// Specifies the initial value of QpY to be used for the coding blocks in
1657     /// the slice until modified by the value of CuQpDeltaVal in the coding unit
1658     /// layer.
1659     pub qp_delta: i8,
1660     /// Specifies a difference to be added to the value of pps_cb_qp_offset when
1661     /// determining the value of the Qp′Cb quantization parameter.
1662     pub cb_qp_offset: i8,
1663     /// Specifies a difference to be added to the value of pps_cb_qr_offset when
1664     /// determining the value of the Qp′Cr quantization parameter.
1665     pub cr_qp_offset: i8,
1666     /// Specifies offsets to the quantization parameter values qP derived in
1667     /// clause 8.6.2 for luma, Cb, and Cr components, respectively.
1668     pub slice_act_y_qp_offset: i8,
1669     /// Specifies offsets to the quantization parameter values qP derived in
1670     /// clause 8.6.2 for luma, Cb, and Cr components, respectively.
1671     pub slice_act_cb_qp_offset: i8,
1672     /// Specifies offsets to the quantization parameter values qP derived in
1673     /// clause 8.6.2 for luma, Cb, and Cr components, respectively.
1674     pub slice_act_cr_qp_offset: i8,
1675     /// When set, specifies that the cu_chroma_qp_offset_flag may be present in
1676     /// the transform unit syntax. When not set, specifies that the
1677     /// cu_chroma_qp_offset_flag is not present in the transform unit syntax.
1678     pub cu_chroma_qp_offset_enabled_flag: bool,
1679     /// When set, specifies that deblocking parameters are present in the slice
1680     /// header. When not set, specifies that deblocking parameters are not
1681     /// present in the slice header.
1682     pub deblocking_filter_override_flag: bool,
1683     /// When set, specifies that the operation of the deblocking filter is not
1684     /// applied for the current slice. When not set, specifies that the
1685     /// operation of the deblocking filter is applied for the current slice.
1686     pub deblocking_filter_disabled_flag: bool,
1687     /// Specifies the deblocking parameter offsets for β and tC (divided by 2)
1688     /// for the current slice.
1689     pub beta_offset_div2: i8,
1690     /// Specifies the deblocking parameter offsets for β and tC (divided by 2)
1691     /// for the current slice.
1692     pub tc_offset_div2: i8,
1693     /// When set, specifies that in-loop filtering operations may be performed
1694     /// across the left and upper boundaries of the current slice.  When not
1695     /// set, specifies that in-loop operations are not performed across left and
1696     /// upper boundaries of the current slice. The in-loop filtering operations
1697     /// include the deblocking filter and sample adaptive offset filter.
1698     pub loop_filter_across_slices_enabled_flag: bool,
1699     /// Specifies the number of `entry_point_offset_minus1[ i ]` syntax elements
1700     /// in the slice header.
1701     pub num_entry_point_offsets: u32,
1702     /// offset_len_minus1 plus 1 specifies the length, in bits, of the
1703     /// `entry_point_offset_minus1[ i ]` syntax elements.
1704     pub offset_len_minus1: u8,
1705     /// `entry_point_offset_minus1[ i ]` plus 1 specifies the i-th entry point
1706     /// offset in bytes, and is represented by offset_len_minus1 plus 1 bits.
1707     /// The slice segment data that follow the slice segment header consists of
1708     /// num_entry_point_offsets + 1 subsets, with subset index values ranging
1709     /// from 0 to num_entry_point_offsets, inclusive. See the specification for
1710     /// more details.
1711     pub entry_point_offset_minus1: [u32; 32],
1712     /// Same as NumPicTotalCurr in the specification.
1713     pub num_pic_total_curr: u32,
1714     // Size of slice_header() in bits.
1715     pub header_bit_size: u32,
1716     // Number of emulation prevention bytes (EPB) in this slice_header().
1717     pub n_emulation_prevention_bytes: u32,
1718     /// Same as CurrRpsIdx in the specification.
1719     pub curr_rps_idx: u8,
1720     /// Number of bits taken by st_ref_pic_set minus Emulation Prevention Bytes.
1721     pub st_rps_bits: u32,
1722 }
1723 
1724 impl Default for SliceHeader {
default() -> Self1725     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 
1784 /// A H265 slice. An integer number of macroblocks or macroblock pairs ordered
1785 /// consecutively in the raster scan within a particular slice group
1786 pub struct Slice<'a> {
1787     /// The slice header.
1788     pub header: SliceHeader,
1789     /// The NAL unit backing this slice.
1790     pub nalu: Nalu<'a>,
1791 }
1792 
1793 impl<'a> Slice<'a> {
1794     /// Sets the header for dependent slices by copying from an independent
1795     /// slice.
replace_header(&mut self, header: SliceHeader) -> Result<(), String>1796     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)]
1835 pub struct SublayerHrdParameters {
1836     // NOTE: The value of CpbCnt is cpb_cnt_minus1[i] + 1, and cpb_cnt_minus1
1837     // ranges from 0..=31
1838     /// `bit_rate_value_minus1[ i ]` (together with bit_rate_scale) specifies the
1839     /// maximum input bit rate for the i-th CPB when the CPB operates at the
1840     /// access unit level
1841     pub bit_rate_value_minus1: [u32; 32],
1842     /// `cpb_size_value_minus1[ i ]` is used together with cpb_size_scale to
1843     /// specify the i-th CPB size when the CPB operates at the access unit
1844     /// level.
1845     pub cpb_size_value_minus1: [u32; 32],
1846     /// `cpb_size_du_value_minus1[ i ]` is used together with cpb_size_du_scale to
1847     /// specify the i-th CPB size when the CPB operates at sub-picture level.
1848     pub cpb_size_du_value_minus1: [u32; 32],
1849     /// `bit_rate_du_value_minus1[ i ]` (together with bit_rate_scale) specifies
1850     /// the maximum input bit rate for the i-th CPB when the CPB operates at the
1851     /// sub-picture level.
1852     pub bit_rate_du_value_minus1: [u32; 32],
1853     /// `cbr_flag[ i ]` not set specifies that to decode this CVS by the HRD using
1854     /// the i-th CPB specification.
1855     pub cbr_flag: [bool; 32],
1856 }
1857 
1858 #[derive(Clone, Debug, PartialEq, Eq)]
1859 pub struct HrdParams {
1860     /// When set, specifies that NAL HRD parameters (pertaining to the Type II
1861     /// bitstream conformance point) are present in the hrd_parameters( ) syntax
1862     /// structure. When not set, specifies that NAL HRD parameters are not
1863     /// present in the hrd_parameters( ) syntax structure.
1864     pub nal_hrd_parameters_present_flag: bool,
1865     /// When set, specifies that VCL HRD parameters (pertaining to the Type I
1866     /// bitstream conformance point) are present in the hrd_parameters( ) syntax
1867     /// structure. When not set, specifies that VCL HRD parameters are not
1868     /// present in the hrd_parameters( ) syntax structure.
1869     pub vcl_hrd_parameters_present_flag: bool,
1870     /// When set, specifies that sub-picture level HRD parameters are present
1871     /// and the HRD may operate at access unit level or sub-picture level. When
1872     /// not set, specifies that sub-picture level HRD parameters are not present
1873     /// and the HRD operates at access unit level.
1874     pub sub_pic_hrd_params_present_flag: bool,
1875     /// Used to specify the clock sub-tick. A clock sub-tick is the minimum
1876     /// interval of time that can be represented in the coded data when
1877     /// sub_pic_hrd_params_present_flag is set.
1878     pub tick_divisor_minus2: u8,
1879     /// du_cpb_removal_delay_increment_length_minus1 plus 1 specifies the
1880     /// length, in bits, of the `du_cpb_removal_delay_increment_minus1[ i ]` and
1881     /// du_common_cpb_removal_delay_increment_minus1 syntax elements of the
1882     /// picture timing SEI message and the du_spt_cpb_removal_delay_increment
1883     /// syntax element in the decoding unit information SEI message.
1884     pub du_cpb_removal_delay_increment_length_minus1: u8,
1885     /// When set, specifies that sub-picture level CPB removal delay parameters
1886     /// are present in picture timing SEI messages and no decoding unit
1887     /// information SEI message is available (in the CVS or provided through
1888     /// external means not specified in this Specification).  When not set,
1889     /// specifies that sub-picture level CPB removal delay parameters are
1890     /// present in decoding unit information SEI messages and picture timing SEI
1891     /// messages do not include sub-picture level CPB removal delay parameters.
1892     pub sub_pic_cpb_params_in_pic_timing_sei_flag: bool,
1893     /// dpb_output_delay_du_length_minus1 plus 1 specifies the length, in bits,
1894     /// of the pic_dpb_output_du_delay syntax element in the picture timing SEI
1895     /// message and the pic_spt_dpb_output_du_delay syntax element in the
1896     /// decoding unit information SEI message.
1897     pub dpb_output_delay_du_length_minus1: u8,
1898     /// Together with `bit_rate_value_minus1[ i ]`, specifies the maximum input
1899     /// bit rate of the i-th CPB.
1900     pub bit_rate_scale: u8,
1901     /// Together with `cpb_size_du_value_minus1[ i ]`, specifies the CPB size of
1902     /// the i-th CPB when the CPB operates at sub-picture level.
1903     pub cpb_size_scale: u8,
1904     /// Together with `cpb_size_du_value_minus1[ i ]`, specifies the CPB size of
1905     /// the i-th CPB when the CPB operates at sub-picture level.
1906     pub cpb_size_du_scale: u8,
1907     /// initial_cpb_removal_delay_length_minus1 plus 1 specifies the length, in
1908     /// bits, of the `nal_initial_cpb_removal_delay[ i ]`,
1909     /// `nal_initial_cpb_removal_offset[ i ]`, `vcl_initial_cpb_removal_delay[ i ]`
1910     /// and `vcl_initial_cpb_removal_offset[ i ]` syntax elements of the buffering
1911     /// period SEI message.
1912     pub initial_cpb_removal_delay_length_minus1: u8,
1913     /// au_cpb_removal_delay_length_minus1 plus 1 specifies the length, in bits,
1914     /// of the cpb_delay_offset syntax element in the buffering period SEI
1915     /// message and the au_cpb_removal_delay_minus1 syntax element in the
1916     /// picture timing SEI message.
1917     pub au_cpb_removal_delay_length_minus1: u8,
1918     /// dpb_output_delay_length_minus1 plus 1 specifies the length, in bits, of
1919     /// the dpb_delay_offset syntax element in the buffering period SEI message
1920     /// and the pic_dpb_output_delay syntax element in the picture timing SEI
1921     /// message.
1922     pub dpb_output_delay_length_minus1: u8,
1923     /// `fixed_pic_rate_general_flag[ i ]` set indicates that, when HighestTid is
1924     /// equal to i, the temporal distance between the HRD output times of
1925     /// consecutive pictures in output order is constrained as specified in the
1926     /// specification. `fixed_pic_rate_general_flag[ i ]` not set indicates that
1927     /// this constraint may not apply.
1928     pub fixed_pic_rate_general_flag: [bool; 7],
1929     /// `fixed_pic_rate_within_cvs_flag[ i ]` set indicates that, when HighestTid
1930     /// is equal to i, the temporal distance between the HRD output times of
1931     /// consecutive pictures in output order is constrained as specified in the
1932     /// specification. `fixed_pic_rate_within_cvs_flag[ i ]` not set indicates
1933     /// that this constraint may not apply.
1934     pub fixed_pic_rate_within_cvs_flag: [bool; 7],
1935     /// `elemental_duration_in_tc_minus1[ i ]` plus 1 (when present) specifies,
1936     /// when HighestTid is equal to i, the temporal distance, in clock ticks,
1937     /// between the elemental units that specify the HRD output times of
1938     /// consecutive pictures in output order as specified in the specification.
1939     pub elemental_duration_in_tc_minus1: [u32; 7],
1940     /// `low_delay_hrd_flag[ i ]` specifies the HRD operational mode, when
1941     /// HighestTid is equal to i, as specified in Annex C or clause F.13.
1942     pub low_delay_hrd_flag: [bool; 7],
1943     /// `cpb_cnt_minus1[ i ]` plus 1 specifies the number of alternative CPB
1944     /// specifications in the bitstream of the CVS when HighestTid is equal to
1945     /// i.
1946     pub cpb_cnt_minus1: [u32; 7],
1947     /// The NAL HRD data.
1948     pub nal_hrd: [SublayerHrdParameters; 7],
1949     /// The VCL HRD data.
1950     pub vcl_hrd: [SublayerHrdParameters; 7],
1951 }
1952 
1953 impl Default for HrdParams {
default() -> Self1954     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)]
1981 pub struct VuiParams {
1982     /// When set, specifies that aspect_ratio_idc is present.  When not set,
1983     /// specifies that aspect_ratio_idc is not present.
1984     pub aspect_ratio_info_present_flag: bool,
1985     /// Specifies the value of the sample aspect ratio of the luma samples.
1986     pub aspect_ratio_idc: u32,
1987     /// Indicates the horizontal size of the sample aspect ratio (in arbitrary
1988     /// units).
1989     pub sar_width: u32,
1990     /// Indicates the vertical size of the sample aspect ratio (in arbitrary
1991     /// units).
1992     pub sar_height: u32,
1993     /// When set, specifies that the overscan_appropriate_flag is present. When
1994     /// not set, the preferred display method for the video signal is
1995     /// unspecified.
1996     pub overscan_info_present_flag: bool,
1997     /// When set indicates that the cropped decoded pictures output are suitable
1998     /// for display using overscan. When not set, indicates that the cropped
1999     /// decoded pictures output contain visually important information in the
2000     /// entire region out to the edges of the conformance cropping window of the
2001     /// picture, such that the cropped decoded pictures output should not be
2002     /// displayed using overscan.
2003     pub overscan_appropriate_flag: bool,
2004     /// When set, specifies that video_format, video_full_range_flag and
2005     /// colour_description_present_flag are present.  When not set, specify that
2006     /// video_format, video_full_range_flag and colour_description_present_flag
2007     /// are not present.
2008     pub video_signal_type_present_flag: bool,
2009     /// Indicates the representation of the pictures as specified in Table E.2,
2010     /// before being coded in accordance with this Specification.
2011     pub video_format: u8,
2012     /// Indicates the black level and range of the luma and chroma signals as
2013     /// derived from E′Y, E′PB, and E′PR or E′R, E′G, and E′B real-valued
2014     /// component signals.
2015     pub video_full_range_flag: bool,
2016     /// When set, specifies that colour_primaries, transfer_characteristics, and
2017     /// matrix_coeffs are present. When not set, specifies that
2018     /// colour_primaries, transfer_characteristics, and matrix_coeffs are not
2019     /// present.
2020     pub colour_description_present_flag: bool,
2021     /// Indicates the chromaticity coordinates of the source primaries as
2022     /// specified in Table E.3 in terms of the CIE 1931 definition of x and y as
2023     /// specified in ISO 11664-1.
2024     pub colour_primaries: u32,
2025     /// See table E.4 in the specification.
2026     pub transfer_characteristics: u32,
2027     /// Describes the matrix coefficients used in deriving luma and chroma
2028     /// signals from the green, blue, and red, or Y, Z, and X primaries, as
2029     /// specified in Table E.5.
2030     pub matrix_coeffs: u32,
2031     /// When true, specifies that chroma_sample_loc_type_top_field and
2032     /// chroma_sample_loc_type_bottom_field are present. When false, specifies
2033     /// that chroma_sample_loc_type_top_field and
2034     /// chroma_sample_loc_type_bottom_field are not present.
2035     pub chroma_loc_info_present_flag: bool,
2036     /// See the specification for more details.
2037     pub chroma_sample_loc_type_top_field: u32,
2038     /// See the specification for more details.
2039     pub chroma_sample_loc_type_bottom_field: u32,
2040     /// When true, indicates that the value of all decoded chroma samples is
2041     /// equal to 1 << ( BitDepthC − 1 ). When false, provides no indication of
2042     /// decoded chroma sample values.
2043     pub neutral_chroma_indication_flag: bool,
2044     /// When true, indicates that the CVS conveys pictures that represent
2045     /// fields, and specifies that a picture timing SEI message shall be present
2046     /// in every access unit of the current CVS. When false, indicates that the
2047     /// CVS conveys pictures that represent frames and that a picture timing SEI
2048     /// message may or may not be present in any access unit of the current CVS.
2049     pub field_seq_flag: bool,
2050     /// When true, specifies that picture timing SEI messages are present for
2051     /// every picture and include the pic_struct, source_scan_type and
2052     /// duplicate_flag syntax elements. When false, specifies that the
2053     /// pic_struct syntax element is not present in picture timing SEI messages.
2054     pub frame_field_info_present_flag: bool,
2055     /// When true, indicates that the default display window parameters follow
2056     /// next in the VUI. When false, indicates that the default display window
2057     /// parameters are not present.
2058     pub default_display_window_flag: bool,
2059     /// Specifies the samples of the pictures in the CVS that are within the
2060     /// default display window, in terms of a rectangular region specified in
2061     /// picture coordinates for display.
2062     pub def_disp_win_left_offset: u32,
2063     /// Specifies the samples of the pictures in the CVS that are within the
2064     /// default display window, in terms of a rectangular region specified in
2065     /// picture coordinates for display.
2066     pub def_disp_win_right_offset: u32,
2067     /// Specifies the samples of the pictures in the CVS that are within the
2068     /// default display window, in terms of a rectangular region specified in
2069     /// picture coordinates for display.
2070     pub def_disp_win_top_offset: u32,
2071     /// Specifies the samples of the pictures in the CVS that are within the
2072     /// default display window, in terms of a rectangular region specified in
2073     /// picture coordinates for display.
2074     pub def_disp_win_bottom_offset: u32,
2075     /// When set, specifies that vui_num_units_in_tick, vui_time_scale,
2076     /// vui_poc_proportional_to_timing_flag and vui_hrd_parameters_present_flag
2077     /// are present in the vui_parameters( ) syntax structure.  When not set,
2078     /// specifies that vui_num_units_in_tick, vui_time_scale,
2079     /// vui_poc_proportional_to_timing_flag and vui_hrd_parameters_present_flag
2080     /// are not present in the vui_parameters( ) syntax structure
2081     pub timing_info_present_flag: bool,
2082     /// The number of time units of a clock operating at the frequency
2083     /// vui_time_scale Hz that corresponds to one increment (called a clock
2084     /// tick) of a clock tick counter.
2085     pub num_units_in_tick: u32,
2086     /// Is the number of time units that pass in one second. For example, a time
2087     /// coordinate system that measures time using a 27 MHz clock has a
2088     /// vui_time_scale of 27 000 000.
2089     pub time_scale: u32,
2090     /// When set, indicates that the picture order count value for each picture
2091     /// in the CVS that is not the first picture in the CVS, in decoding order,
2092     /// is proportional to the output time of the picture relative to the output
2093     /// time of the first picture in the CVS.  When not set, indicates that the
2094     /// picture order count value for each picture in the CVS that is not the
2095     /// first picture in the CVS, in decoding order, may or may not be
2096     /// proportional to the output time of the picture relative to the output
2097     /// time of the first picture in the CVS.
2098     pub poc_proportional_to_timing_flag: bool,
2099     /// vui_num_ticks_poc_diff_one_minus1 plus 1 specifies the number of clock
2100     /// ticks corresponding to a difference of picture order count values equal
2101     /// to 1.
2102     pub num_ticks_poc_diff_one_minus1: u32,
2103     /// When set, specifies that the syntax structure hrd_parameters( ) is
2104     /// present in the vui_parameters( ) syntax structure.  When not set,
2105     /// specifies that the syntax structure hrd_parameters( ) is not present in
2106     /// the vui_parameters( ) syntax structure.
2107     pub hrd_parameters_present_flag: bool,
2108     /// The hrd_parameters() data.
2109     pub hrd: HrdParams,
2110     /// When set, specifies that the bitstream restriction parameters for the
2111     /// CVS are present. When not set, specifies that the bitstream restriction
2112     /// parameters for the CVS are not present.
2113     pub bitstream_restriction_flag: bool,
2114     /// When set, indicates that each PPS that is active in the CVS has the same
2115     /// value of the syntax elements num_tile_columns_minus1,
2116     /// num_tile_rows_minus1, uniform_spacing_flag, `column_width_minus1[ i ]`,
2117     /// `row_height_minus1[ i ]` and loop_filter_across_tiles_enabled_flag, when
2118     /// present. When not set, indicates that tiles syntax elements in different
2119     /// PPSs may or may not have the same value
2120     pub tiles_fixed_structure_flag: bool,
2121     /// When not set, indicates that no sample outside the picture boundaries
2122     /// and no sample at a fractional sample position for which the sample value
2123     /// is derived using one or more samples outside the picture boundaries is
2124     /// used for inter prediction of any sample.  When set, indicates that one
2125     /// or more samples outside the picture boundaries may be used in inter
2126     /// prediction.
2127     pub motion_vectors_over_pic_boundaries_flag: bool,
2128     /// When set, indicates that all P and B slices (when present) that belong
2129     /// to the same picture have an identical reference picture list 0 and that
2130     /// all B slices (when present) that belong to the same picture have an
2131     /// identical reference picture list 1.
2132     pub restricted_ref_pic_lists_flag: bool,
2133     /// When not equal to 0, establishes a bound on the maximum possible size of
2134     /// distinct coded spatial segmentation regions in the pictures of the CVS.
2135     pub min_spatial_segmentation_idc: u32,
2136     /// Indicates a number of bytes not exceeded by the sum of the sizes of the
2137     /// VCL NAL units associated with any coded picture in the CVS.
2138     pub max_bytes_per_pic_denom: u32,
2139     /// Indicates an upper bound for the number of coded bits of coding_unit( )
2140     /// data for anycoding block in any picture of the CVS.
2141     pub max_bits_per_min_cu_denom: u32,
2142     /// Indicate the maximum absolute value of a decoded horizontal and vertical
2143     /// motion vector component, respectively, in quarter luma sample units, for
2144     /// all pictures in the CVS.
2145     pub log2_max_mv_length_horizontal: u32,
2146     /// Indicate the maximum absolute value of a decoded horizontal and vertical
2147     /// motion vector component, respectively, in quarter luma sample units, for
2148     /// all pictures in the CVS.
2149     pub log2_max_mv_length_vertical: u32,
2150 }
2151 
2152 impl Default for VuiParams {
default() -> Self2153     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)]
2200 pub 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 
2206 impl Parser {
2207     /// Parse a VPS NALU.
parse_vps(&mut self, nalu: &Nalu) -> Result<&Vps, String>2208     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         // Skip the header
2221         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)?; // vps_reserved_0xffff_16bits
2234 
2235         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         // vps_sub_layer_ordering_info_present_flag equal to 0 specifies that
2267         // the values of vps_max_dec_pic_buffering_minus1[
2268         // vps_max_sub_layers_minus1 ], vps_max_num_reorder_pics[ vps_max_sub_
2269         // layers_minus1 ] and vps_max_latency_increase_plus1[
2270         // vps_max_sub_layers_minus1 ] apply to all sub-layers
2271         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                 // Skip layer_id_included_flag[i][j] for now.
2294                 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 
parse_profile_tier_level( ptl: &mut ProfileTierLevel, r: &mut BitReader, profile_present_flag: bool, sps_max_sub_layers_minus_1: u8, ) -> Result<(), String>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                     // Skip general_reserved_zero_33bits
2401                     r.skip_bits(31)?;
2402                     r.skip_bits(2)?;
2403                 } else {
2404                     // Skip general_reserved_zero_34bits
2405                     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                 // Skip general_reserved_zero_7bits
2410                 r.skip_bits(7)?;
2411                 ptl.general_one_picture_only_constraint_flag = r.read_bit()?;
2412                 // Skip general_reserved_zero_35bits
2413                 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 
fill_default_scaling_list(sl: &mut ScalingLists, size_id: i32, matrix_id: i32)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         //  When `scaling_list_pred_mode_flag[ sizeId ]`[ matrixId ] is equal to
2572         //  0, scaling_list_pred_matrix_id_ `delta[ sizeId ]`[ matrixId ] is equal
2573         //  to 0 and sizeId is greater than 1, the value of
2574         //  scaling_list_dc_coef_minus8[ sizeId − 2 `][ matrixId ]` is inferred to
2575         //  be equal to 8.
2576         //
2577         // Since we are using a slightly different layout here, with two
2578         // different field names (i.e. 16x16, and 32x32), we must differentiate
2579         // between size_id == 2 or size_id == 3.
2580         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 
parse_scaling_list_data(sl: &mut ScalingLists, r: &mut BitReader) -> Result<(), String>2587     fn parse_scaling_list_data(sl: &mut ScalingLists, r: &mut BitReader) -> Result<(), String> {
2588         // 7.4.5
2589         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_matrix_id_delta[ sizeId ]`[ matrixId ] is
2594                 // equal to 0, the scaling list is inferred from the default
2595                 // scaling list `ScalingList[ sizeId ]`[ matrixId `][ i ]` as specified
2596                 // in Table 7-5 and Table 7-6 for i = 0..Min( 63, ( 1 << ( 4 + (
2597                 // sizeId << 1 ) ) ) − 1 ).
2598                 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                         // Equation 7-42
2604                         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 
parse_short_term_ref_pic_set( sps: &Sps, st: &mut ShortTermRefPicSet, r: &mut BitReader, st_rps_idx: u8, ) -> Result<(), String>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         // (7-59)
2686         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             // The value of abs_delta_rps_minus1 shall be in the range of 0 to
2693             // 2^15 − 1, inclusive.
2694             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             // 7.4.8 - defaults to 1 if not present
2708             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             // (7-61)
2718             let mut i = 0;
2719             // Ranges are [a,b[, but the real loop is [b, a], i.e.
2720             // [num_positive_pics - 1, 0]. Use ..= so that b is included when
2721             // rev() is called.
2722             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             // Let's *not* change the original algorithm in any way.
2745             #[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             // (7-62)
2759             let mut i = 0;
2760             // Ranges are [a,b[, but the real loop is [b, a], i.e.
2761             // [num_negative_pics - 1, 0]. Use ..= so that b is included when
2762             // rev() is called.
2763             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 
parse_sublayer_hrd_parameters( h: &mut SublayerHrdParameters, cpb_cnt: u32, sub_pic_hrd_params_present_flag: bool, r: &mut BitReader, ) -> Result<(), String>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 
parse_hrd_parameters( common_inf_present_flag: bool, max_num_sublayers_minus1: u8, hrd: &mut HrdParams, r: &mut BitReader, ) -> Result<(), String>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 
parse_vui_parameters(sps: &mut Sps, r: &mut BitReader) -> Result<(), String>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 
parse_sps_scc_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String>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 
parse_sps_range_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String>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     /// Parse a SPS NALU.
parse_sps(&mut self, nalu: &Nalu) -> Result<&Sps, String>3066     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         // Skip the header
3079         let mut r = BitReader::new(&data[hdr_len..], true);
3080 
3081         let video_parameter_set_id = r.read_bits(4)?;
3082 
3083         // A non-existing VPS means the SPS is not using any VPS.
3084         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         // (7-10)
3148         sps.min_cb_log2_size_y = u32::from(sps.log2_min_luma_coding_block_size_minus3 + 3);
3149         // (7-11)
3150         sps.ctb_log2_size_y =
3151             sps.min_cb_log2_size_y + u32::from(sps.log2_diff_max_min_luma_coding_block_size);
3152         // (7-12)
3153         sps.ctb_size_y = 1 << sps.ctb_log2_size_y;
3154         // (7-17)
3155         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         // (7-15)
3158         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 
parse_pps_scc_extension(pps: &mut Pps, sps: &Sps, r: &mut BitReader) -> Result<(), String>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 
parse_pps_range_extension( pps: &mut Pps, sps: &Sps, r: &mut BitReader, ) -> Result<(), String>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     /// Parse a PPS NALU.
parse_pps(&mut self, nalu: &Nalu) -> Result<&Pps, String>3361     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         // Skip the header
3374         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         // 7.4.7.1
3440         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         // (7-5)
3444         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         // A mix of the rbsp data and the algorithm in 6.5.1
3468         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)?; // pps_extension_4bits
3571         }
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 
parse_pred_weight_table( hdr: &mut SliceHeader, r: &mut BitReader, sps: &Sps, ) -> Result<(), String>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 
parse_ref_pic_lists_modification( hdr: &mut SliceHeader, r: &mut BitReader, ) -> Result<(), String>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     /// Further sets default values given `sps` and `pps`.
slice_header_set_defaults(hdr: &mut SliceHeader, sps: &Sps, pps: &Pps)3712     pub fn slice_header_set_defaults(hdr: &mut SliceHeader, sps: &Sps, pps: &Pps) {
3713         // Set some defaults that can't be defined in Default::default().
3714         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     /// Parses a slice header from a slice NALU.
parse_slice_header<'a>(&mut self, nalu: Nalu<'a>) -> Result<Slice<'a>, String>3723     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         // Skip the header
3750         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                         // The variables `PocLsbLt[ i ]` and `UsedByCurrPicLt[ i ]` are derived as follows:
3854                         //
3855                         // – If i is less than num_long_term_sps, `PocLsbLt[ i ]` is set equal to
3856                         // lt_ref_pic_poc_lsb_sps[ `lt_idx_sps[ i ]` ] and `UsedByCurrPicLt[ i ]` is set equal
3857                         // to used_by_curr_pic_lt_sps_flag[ `lt_idx_sps[ i ]` ].
3858                         //
3859                         // – Otherwise, `PocLsbLt[ i ]`
3860                         // is set equal to `poc_lsb_lt[ i ]` and `UsedByCurrPicLt[ i ]` is set equal to
3861                         // `used_by_curr_pic_lt_flag[ i ]`.
3862                         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                             // The value of `delta_poc_msb_cycle_lt[ i ]` shall be
3890                             // in the range of 0 to 2(32 −
3891                             // log2_max_pic_order_cnt_lsb_minus4 − 4 ),
3892                             // inclusive. When `delta_poc_msb_cycle_lt[ i ]` is
3893                             // not present, it is inferred to be equal to 0.
3894                             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                         // Equation 7-52 (simplified)
3899                         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                 // 7-57
3930                 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)?; // slice_segment_header_extension_data_byte[i]
4095             }
4096         }
4097 
4098         // byte_alignment()
4099         r.skip_bits(1)?; // Alignment bit
4100         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     /// Returns a previously parsed vps given `vps_id`, if any.
get_vps(&self, vps_id: u8) -> Option<&Rc<Vps>>4114     pub fn get_vps(&self, vps_id: u8) -> Option<&Rc<Vps>> {
4115         self.active_vpses.get(&vps_id)
4116     }
4117 
4118     /// Returns a previously parsed sps given `sps_id`, if any.
get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>>4119     pub fn get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>> {
4120         self.active_spses.get(&sps_id)
4121     }
4122 
4123     /// Returns a previously parsed pps given `pps_id`, if any.
get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>>4124     pub fn get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>> {
4125         self.active_ppses.get(&pps_id)
4126     }
4127 }
4128 
4129 #[cfg(test)]
4130 mod 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 
dispatch_parse_call(parser: &mut Parser, nalu: Nalu<NaluHeader>) -> Result<(), String>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             _ => { /* ignore */ }
4184         }
4185         Ok(())
4186     }
4187 
find_nalu_by_type( bitstream: &[u8], nalu_type: NaluType, mut nskip: i32, ) -> Option<Nalu<NaluHeader>>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     /// This test is adapted from chromium, available at media/video/h265_parser_unittest.cc
4208     #[test]
parse_nalus_from_stream_file()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     /// Parse the syntax, making sure we can parse the files without crashing.
4236     /// Does not check whether the parsed values are correct.
4237     #[test]
parse_syntax_from_nals()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     /// Adapted from Chromium (media/video/h265_parser_unittest.cc::VpsParsing())
4262     #[test]
chromium_vps_parsing()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     /// Adapted from Chromium (media/video/h265_parser_unittest.cc::SpsParsing())
4291     #[test]
chromium_sps_parsing()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         // Note: the original test has 0 for the three variables below, but they
4346         // have valid defaults in the spec (i.e.: 2).
4347         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     /// Adapted from Chromium (media/video/h265_parser_unittest.cc::PpsParsing())
4358     #[test]
chromium_pps_parsing()4359     fn chromium_pps_parsing() {
4360         let mut parser = Parser::default();
4361 
4362         // Have to parse the SPS to set up the parser's internal state.
4363         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     /// Adapted from Chromium (media/video/h265_parser_unittest.cc::SliceHeaderParsing())
4399     #[test]
chromium_slice_header_parsing()4400     fn chromium_slice_header_parsing() {
4401         let mut parser = Parser::default();
4402 
4403         // Have to parse the SPS/VPS/PPS to set up the parser's internal state.
4404         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         // Just like the Chromium test, do an IDR slice, then a non IDR slice.
4414         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     /// A custom test for VPS parsing with data manually extracted from
4458     /// GStreamer using GDB.
4459     #[test]
test25fps_vps_header_parsing()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     /// A custom test for SPS parsing with data manually extracted from
4515     /// GStreamer using GDB.
4516     #[test]
test25fps_sps_header_parsing()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     /// A custom test for PPS parsing with data manually extracted from
4610     /// GStreamer using GDB.
4611     #[test]
test25fps_pps_header_parsing()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     /// A custom test for slice header parsing with data manually extracted from
4660     /// GStreamer using GDB.
4661     #[test]
test25fps_slice_header_parsing()4662     fn test25fps_slice_header_parsing() {
4663         let mut parser = Parser::default();
4664 
4665         // Have to parse the SPS/VPS/PPS to set up the parser's internal state.
4666         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         // Remove the 2 bytes from the NALU header.
4716         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         // Next slice
4723         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         // Subtract 2 bytes to account for the header size.
4772         assert_eq!(hdr.header_bit_size - 16, 96);
4773         assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_1);
4774 
4775         // Next slice
4776         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         // Subtract 2 bytes to account for the header size.
4782         assert_eq!(hdr.header_bit_size - 16, 80);
4783     }
4784 }
4785