• 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 use std::borrow::Cow;
6 use std::rc::Rc;
7 
8 use crate::codec::av1::helpers;
9 use crate::codec::av1::reader::Reader;
10 
11 pub const TOTAL_REFS_PER_FRAME: usize = 8;
12 pub const NUM_REF_FRAMES: usize = 8;
13 pub const REFS_PER_FRAME: usize = 7;
14 pub const MAX_SEGMENTS: usize = 8;
15 pub const SEG_LVL_ALT_Q: usize = 0;
16 pub const SEG_LVL_ALT_LF_Y_V: usize = 1;
17 pub const SEG_LVL_REF_FRAME: usize = 5;
18 pub const SEG_LVL_SKIP: usize = 6;
19 pub const SEG_LVL_GLOBAL_MV: usize = 7;
20 pub const SEG_LVL_MAX: usize = 8;
21 pub const MAX_TILE_COLS: usize = 64;
22 pub const MAX_TILE_ROWS: usize = 64;
23 pub const CDEF_MAX: usize = 1 << 3;
24 pub const MAX_NUM_PLANES: usize = 3;
25 pub const MAX_NUM_Y_POINTS: usize = 16;
26 pub const MAX_NUM_CB_POINTS: usize = 16;
27 pub const MAX_NUM_CR_POINTS: usize = 16;
28 pub const MAX_NUM_POS_LUMA: usize = 25;
29 pub const MAX_NUM_SPATIAL_LAYERS: usize = 4;
30 pub const MAX_NUM_TEMPORAL_LAYERS: usize = 8;
31 pub const MAX_NUM_OPERATING_POINTS: usize = MAX_NUM_SPATIAL_LAYERS * MAX_NUM_TEMPORAL_LAYERS;
32 pub const SELECT_SCREEN_CONTENT_TOOLS: usize = 2;
33 pub const SELECT_INTEGER_MV: usize = 2;
34 pub const PRIMARY_REF_NONE: u32 = 7;
35 pub const SUPERRES_DENOM_BITS: usize = 3;
36 pub const SUPERRES_DENOM_MIN: usize = 9;
37 pub const SUPERRES_NUM: usize = 8;
38 pub const MAX_TILE_WIDTH: u32 = 4096;
39 pub const MAX_TILE_HEIGHT: u32 = 2304;
40 pub const MAX_TILE_AREA: u32 = MAX_TILE_WIDTH * MAX_TILE_HEIGHT;
41 pub const RESTORATION_TILESIZE_MAX: u16 = 256;
42 pub const WARPEDMODEL_PREC_BITS: u32 = 16;
43 pub const WARP_PARAM_REDUCE_BITS: u32 = 6;
44 pub const GM_ABS_ALPHA_BITS: u32 = 12;
45 pub const GM_ALPHA_PREC_BITS: u32 = 15;
46 pub const GM_ABS_TRANS_ONLY_BITS: u32 = 9;
47 pub const GM_TRANS_ONLY_PREC_BITS: u32 = 3;
48 pub const GM_ABS_TRANS_BITS: u32 = 12;
49 pub const GM_TRANS_PREC_BITS: u32 = 6;
50 
51 // Same as Segmentation_Feature_Bits in the specification. See 5.9.14
52 pub const FEATURE_BITS: [u8; SEG_LVL_MAX] = [8, 6, 6, 6, 6, 3, 0, 0];
53 // Same as Segmentation_Feature_Signed in the specification. See 5.9.14
54 pub const FEATURE_SIGNED: [bool; SEG_LVL_MAX] = [true, true, true, true, true, false, false, false];
55 // Same as Segmentation_Feature_Max in the specification. See 5.9.14
56 pub const FEATURE_MAX: [i32; SEG_LVL_MAX] = [255, 63, 63, 63, 63, 7, 0, 0];
57 
58 /// Tells what should be done with the OBU after [`Parser::read_obu`] is called.
59 pub enum ObuAction<'a> {
60     /// We should process the OBU normally.
61     Process(Obu<'a>),
62     /// We should drop this OBU and advance to the next one. The u32 is how much
63     /// we should advance.
64     Drop(u32),
65 }
66 
67 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
68 pub enum ObuType {
69     #[default]
70     Reserved = 0,
71     SequenceHeader = 1,
72     TemporalDelimiter = 2,
73     FrameHeader = 3,
74     TileGroup = 4,
75     Metadata = 5,
76     Frame = 6,
77     RedundantFrameHeader = 7,
78     TileList = 8,
79     Reserved2 = 9,
80     Reserved3 = 10,
81     Reserved4 = 11,
82     Reserved5 = 12,
83     Reserved6 = 13,
84     Reserved7 = 14,
85     Padding = 15,
86 }
87 
88 impl TryFrom<u32> for ObuType {
89     type Error = String;
90 
try_from(value: u32) -> Result<Self, Self::Error>91     fn try_from(value: u32) -> Result<Self, Self::Error> {
92         match value {
93             0 => Ok(ObuType::Reserved),
94             1 => Ok(ObuType::SequenceHeader),
95             2 => Ok(ObuType::TemporalDelimiter),
96             3 => Ok(ObuType::FrameHeader),
97             4 => Ok(ObuType::TileGroup),
98             5 => Ok(ObuType::Metadata),
99             6 => Ok(ObuType::Frame),
100             7 => Ok(ObuType::RedundantFrameHeader),
101             8 => Ok(ObuType::TileList),
102             9 => Ok(ObuType::Reserved2),
103             10 => Ok(ObuType::Reserved3),
104             11 => Ok(ObuType::Reserved4),
105             12 => Ok(ObuType::Reserved5),
106             13 => Ok(ObuType::Reserved6),
107             14 => Ok(ObuType::Reserved7),
108             15 => Ok(ObuType::Padding),
109             _ => Err(format!("Invalid ObuType {}", value)),
110         }
111     }
112 }
113 
114 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
115 pub enum Profile {
116     #[default]
117     Profile0 = 0,
118     Profile1 = 1,
119     Profile2 = 2,
120 }
121 
122 impl TryFrom<u32> for Profile {
123     type Error = String;
124 
try_from(value: u32) -> Result<Self, Self::Error>125     fn try_from(value: u32) -> Result<Self, Self::Error> {
126         match value {
127             0 => Ok(Profile::Profile0),
128             1 => Ok(Profile::Profile1),
129             2 => Ok(Profile::Profile2),
130             _ => Err(format!("Invalid Profile {}", value)),
131         }
132     }
133 }
134 
135 #[derive(Clone, Debug, Default, PartialEq, Eq)]
136 pub struct ObuHeader {
137     pub obu_type: ObuType,
138     pub extension_flag: bool,
139     pub has_size_field: bool,
140     pub temporal_id: u32,
141     pub spatial_id: u32,
142 }
143 
144 impl ObuHeader {
145     /// Length in bytes
146     #[allow(clippy::len_without_is_empty)]
len(&self) -> usize147     pub fn len(&self) -> usize {
148         if self.extension_flag {
149             2
150         } else {
151             1
152         }
153     }
154 }
155 
156 /// Contains the OBU header and a reference to its data. The OBU itself hasn't been parsed yet.
157 #[derive(Clone, Debug, Default, PartialEq, Eq)]
158 pub struct Obu<'a> {
159     /// The OBU header.
160     pub header: ObuHeader,
161     /// Amount of bytes from the input consumed to parse this OBU.
162     pub bytes_used: usize,
163     /// The slice backing the OBU.
164     data: Cow<'a, [u8]>,
165 }
166 
167 impl<'a> AsRef<[u8]> for Obu<'a> {
as_ref(&self) -> &[u8]168     fn as_ref(&self) -> &[u8] {
169         self.data.as_ref()
170     }
171 }
172 
173 /// A fully parsed OBU, with additional data when relevant.
174 pub enum ParsedObu<'a> {
175     Reserved,
176     SequenceHeader(Rc<SequenceHeaderObu>),
177     TemporalDelimiter,
178     FrameHeader(FrameHeaderObu),
179     TileGroup(TileGroupObu<'a>),
180     Metadata,
181     Frame(FrameObu<'a>),
182     RedundantFrameHeader,
183     TileList,
184     Reserved2,
185     Reserved3,
186     Reserved4,
187     Reserved5,
188     Reserved6,
189     Reserved7,
190     Padding,
191 }
192 
193 impl<'a> ParsedObu<'a> {
obu_type(&self) -> ObuType194     pub fn obu_type(&self) -> ObuType {
195         match self {
196             ParsedObu::Reserved => ObuType::Reserved,
197             ParsedObu::SequenceHeader(_) => ObuType::SequenceHeader,
198             ParsedObu::TemporalDelimiter => ObuType::TemporalDelimiter,
199             ParsedObu::FrameHeader(_) => ObuType::FrameHeader,
200             ParsedObu::TileGroup(_) => ObuType::TileGroup,
201             ParsedObu::Metadata => ObuType::Metadata,
202             ParsedObu::Frame(_) => ObuType::Frame,
203             ParsedObu::RedundantFrameHeader => ObuType::RedundantFrameHeader,
204             ParsedObu::TileList => ObuType::TileList,
205             ParsedObu::Reserved2 => ObuType::Reserved2,
206             ParsedObu::Reserved3 => ObuType::Reserved3,
207             ParsedObu::Reserved4 => ObuType::Reserved4,
208             ParsedObu::Reserved5 => ObuType::Reserved5,
209             ParsedObu::Reserved6 => ObuType::Reserved6,
210             ParsedObu::Reserved7 => ObuType::Reserved7,
211             ParsedObu::Padding => ObuType::Padding,
212         }
213     }
214 }
215 
216 #[derive(Clone, Debug, Default, PartialEq, Eq)]
217 pub struct Tile {
218     /// Same as TileOffset in the specification.
219     pub tile_offset: u32,
220     /// Same as TileSize in the specification.
221     pub tile_size: u32,
222     /// Same as TileRow in the specification.
223     pub tile_row: u32,
224     /// Same as TileCol in the specification.
225     pub tile_col: u32,
226     // Same as MiRowStart in the specification.
227     pub mi_row_start: u32,
228     // Same as MiRowEnd in the specification.
229     pub mi_row_end: u32,
230     // Same as MiColStart in the specification.
231     pub mi_col_start: u32,
232     // Same as MiColEnd in the specification.
233     pub mi_col_end: u32,
234 }
235 
236 #[derive(Clone, Debug, Default, PartialEq, Eq)]
237 pub struct TileGroupObu<'a> {
238     /// The OBU backing this tile group.
239     pub obu: Obu<'a>,
240     /// Specifies whether tg_start and tg_end are present. If tg_start and
241     /// tg_end are not present, this tile group covers the entire frame.
242     pub tile_start_and_end_present_flag: bool,
243     /// Specifies the zero-based index of the first tile in the current tile
244     /// group.
245     pub tg_start: u32,
246     /// Specifies the zero-based index of the last tile in the current tile
247     /// group.
248     pub tg_end: u32,
249     /// Contains the tiles in this tile group. Use `tile_offset`to index into
250     /// the OBU data.
251     ///
252     /// The tiles in the Vec span from tg_start to tg_end.
253     pub tiles: Vec<Tile>,
254 }
255 
256 #[derive(Clone, Debug, Default, PartialEq, Eq)]
257 pub struct OperatingPoint {
258     /// Specifies the level that the coded video sequence conforms to when
259     /// operating point i is selected.
260     pub seq_level_idx: u8,
261     /// Specifies the tier that the coded video sequence conforms to when
262     /// operating point i is selected.
263     pub seq_tier: u8,
264     /// Specifies the value of operating_point_idc for the selected operating
265     /// point.
266     pub idc: u16,
267     /// If set, indicates that there is a decoder model associated with
268     /// operating point i. If not set, indicates that there is not a decoder
269     /// model associated with operating point i.
270     pub decoder_model_present_for_this_op: bool,
271     /// Specifies the time interval between the arrival of the first bit in the
272     /// smoothing buffer and the subsequent removal of the data that belongs to
273     /// the first coded frame for operating point op, measured in units of
274     /// 1/90000 seconds. The length of decoder_buffer_delay is specified by
275     /// buffer_delay_length_minus_1 + 1, in bits.
276     pub decoder_buffer_delay: u32,
277     /// Specifies, in combination with decoder_buffer_delay\[ op \] syntax
278     /// element, the first bit arrival time of frames to be decoded to the
279     /// smoothing buffer. encoder_buffer_delay is measured in units of 1/90000
280     /// seconds.
281     pub encoder_buffer_delay: u32,
282     /// If set, indicates that the smoothing buffer operates in low-delay mode
283     /// for operating point op. In low-delay mode late decode times and buffer
284     /// underflow are both permitted. If not set, indicates that the smoothing
285     /// buffer operates in strict mode, where buffer underflow is not allowed.
286     pub low_delay_mode_flag: bool,
287     /// If set, indicates that initial_display_delay_minus_1 is specified for
288     /// operating point i. If not set, indicates that
289     /// initial_display_delay_minus_1 is not specified for operating point i.
290     pub initial_display_delay_present_for_this_op: bool,
291     /// Plus 1 specifies, for operating point i, the number of decoded frames
292     /// that should be present in the buffer pool before the first presentable
293     /// frame is displayed. This will ensure that all presentable frames in the
294     /// sequence can be decoded at or before the time that they are scheduled
295     /// for display. If not signaled then initial_display_delay_minus_1\[ i \] =
296     /// BUFFER_POOL_MAX_SIZE - 1.
297     pub initial_display_delay_minus_1: u32,
298 }
299 
300 #[derive(Clone, Debug, Default, PartialEq, Eq)]
301 pub struct TimingInfo {
302     /// The number of time units of a clock operating at the frequency
303     /// time_scale Hz that corresponds to one increment of a clock tick counter.
304     /// A display clock tick, in seconds, is equal to num_units_in_display_tick
305     /// divided by time_scale:
306     pub num_units_in_display_tick: u32,
307     /// The number of time units that pass in one second.
308     pub time_scale: u32,
309     /// If set, indicates that pictures should be displayed according to their
310     /// output order with the number of ticks between two consecutive pictures
311     /// (without dropping frames) specified by num_ticks_per_picture_minus_1 +
312     /// 1. If not set, indicates that the interval between two consecutive
313     /// pictures is not specified.
314     pub equal_picture_interval: bool,
315     /// Plus 1 specifies the number of clock ticks corresponding to output time
316     /// between two consecutive pictures in the output order.
317     pub num_ticks_per_picture_minus_1: u32,
318 }
319 
320 #[derive(Clone, Debug, Default, PartialEq, Eq)]
321 pub struct DecoderModelInfo {
322     /// Plus 1 specifies the length of the decoder_buffer_delay and the
323     /// encoder_buffer_delay syntax elements, in bits.
324     pub buffer_delay_length_minus_1: u8,
325     /// The number of time units of a decoding clock operating at the frequency
326     /// time_scale Hz that corresponds to one increment of a clock tick counter:
327     pub num_units_in_decoding_tick: u32,
328     /// Plus 1 specifies the length of the buffer_removal_time syntax element,
329     /// in bits.
330     pub buffer_removal_time_length_minus_1: u8,
331     /// Plus 1 specifies the length of the frame_presentation_time syntax
332     /// element, in bits.
333     pub frame_presentation_time_length_minus_1: u32,
334 }
335 
336 /// Defined by the “Color primaries” section of ISO/IEC 23091-4/ITU-T H.273
337 /// See 6.4.2
338 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
339 pub enum ColorPrimaries {
340     Bt709 = 1,
341     #[default]
342     Unspecified = 2,
343     Bt470M = 4,
344     Bt470bg = 5,
345     Bt601 = 6,
346     Smpte240 = 7,
347     GenericFilm = 8,
348     Bt2020 = 9,
349     Xyz = 10,
350     Smpte431 = 11,
351     Smpte432 = 12,
352     Ebu3213 = 22,
353 }
354 
355 impl TryFrom<u32> for ColorPrimaries {
356     type Error = String;
357 
try_from(value: u32) -> Result<Self, Self::Error>358     fn try_from(value: u32) -> Result<Self, Self::Error> {
359         match value {
360             1 => Ok(ColorPrimaries::Bt709),
361             2 => Ok(ColorPrimaries::Unspecified),
362             4 => Ok(ColorPrimaries::Bt470M),
363             5 => Ok(ColorPrimaries::Bt470bg),
364             6 => Ok(ColorPrimaries::Bt601),
365             7 => Ok(ColorPrimaries::Smpte240),
366             8 => Ok(ColorPrimaries::GenericFilm),
367             9 => Ok(ColorPrimaries::Bt2020),
368             10 => Ok(ColorPrimaries::Xyz),
369             11 => Ok(ColorPrimaries::Smpte431),
370             12 => Ok(ColorPrimaries::Smpte432),
371             22 => Ok(ColorPrimaries::Ebu3213),
372             _ => Err(format!("Invalid ColorPrimaries {}", value)),
373         }
374     }
375 }
376 
377 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
378 pub enum TransferCharacteristics {
379     Reserved0 = 0,
380     Bt709 = 1,
381     #[default]
382     Unspecified = 2,
383     Reserved3 = 3,
384     Bt470m = 4,
385     Bt470bg = 5,
386     Bt601 = 6,
387     Smpte240 = 7,
388     Linear = 8,
389     Log100 = 9,
390     Log100Sqrt10 = 10,
391     Iec61966 = 11,
392     Bt1361 = 12,
393     Srgb = 13,
394     Bt202010Bit = 14,
395     Bt202012Bit = 15,
396     Smpte2084 = 16,
397     Smpte428 = 17,
398     Hlg = 18,
399 }
400 
401 impl TryFrom<u32> for TransferCharacteristics {
402     type Error = String;
403 
try_from(value: u32) -> Result<Self, Self::Error>404     fn try_from(value: u32) -> Result<Self, Self::Error> {
405         match value {
406             0 => Ok(TransferCharacteristics::Reserved0),
407             1 => Ok(TransferCharacteristics::Bt709),
408             2 => Ok(TransferCharacteristics::Unspecified),
409             3 => Ok(TransferCharacteristics::Reserved3),
410             4 => Ok(TransferCharacteristics::Bt470m),
411             5 => Ok(TransferCharacteristics::Bt470bg),
412             6 => Ok(TransferCharacteristics::Bt601),
413             7 => Ok(TransferCharacteristics::Smpte240),
414             8 => Ok(TransferCharacteristics::Linear),
415             9 => Ok(TransferCharacteristics::Log100),
416             10 => Ok(TransferCharacteristics::Log100Sqrt10),
417             11 => Ok(TransferCharacteristics::Iec61966),
418             12 => Ok(TransferCharacteristics::Bt1361),
419             13 => Ok(TransferCharacteristics::Srgb),
420             14 => Ok(TransferCharacteristics::Bt202010Bit),
421             15 => Ok(TransferCharacteristics::Bt202012Bit),
422             16 => Ok(TransferCharacteristics::Smpte2084),
423             17 => Ok(TransferCharacteristics::Smpte428),
424             18 => Ok(TransferCharacteristics::Hlg),
425             _ => Err(format!("Invalid TransferCharacteristics {}", value)),
426         }
427     }
428 }
429 
430 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
431 pub enum BitDepth {
432     #[default]
433     Depth8 = 0,
434     Depth10 = 1,
435     Depth12 = 2,
436 }
437 
438 impl TryFrom<u32> for BitDepth {
439     type Error = String;
440 
try_from(value: u32) -> Result<Self, Self::Error>441     fn try_from(value: u32) -> Result<Self, Self::Error> {
442         match value {
443             0 => Ok(BitDepth::Depth8),
444             1 => Ok(BitDepth::Depth10),
445             2 => Ok(BitDepth::Depth12),
446             _ => Err(format!("Invalid BitDepth {}", value)),
447         }
448     }
449 }
450 
451 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
452 pub enum MatrixCoefficients {
453     Identity = 0,
454     Bt709 = 1,
455     #[default]
456     Unspecified = 2,
457     Reserved3 = 3,
458     Fcc = 4,
459     Bt470bg = 5,
460     Bt601 = 6,
461     Smpte240 = 7,
462     Ycgco = 8,
463     Bt2020Ncl = 9,
464     Bt2020Cl = 10,
465     Smpte2085 = 11,
466     ChromaDerivedNcl = 12,
467     ChromaDerivedCl = 13,
468     Ictcp = 14,
469 }
470 
471 impl TryFrom<u32> for MatrixCoefficients {
472     type Error = String;
473 
try_from(value: u32) -> Result<Self, Self::Error>474     fn try_from(value: u32) -> Result<Self, Self::Error> {
475         match value {
476             0 => Ok(MatrixCoefficients::Identity),
477             1 => Ok(MatrixCoefficients::Bt709),
478             2 => Ok(MatrixCoefficients::Unspecified),
479             3 => Ok(MatrixCoefficients::Reserved3),
480             4 => Ok(MatrixCoefficients::Fcc),
481             5 => Ok(MatrixCoefficients::Bt470bg),
482             6 => Ok(MatrixCoefficients::Bt601),
483             7 => Ok(MatrixCoefficients::Smpte240),
484             8 => Ok(MatrixCoefficients::Ycgco),
485             9 => Ok(MatrixCoefficients::Bt2020Ncl),
486             10 => Ok(MatrixCoefficients::Bt2020Cl),
487             11 => Ok(MatrixCoefficients::Smpte2085),
488             12 => Ok(MatrixCoefficients::ChromaDerivedNcl),
489             13 => Ok(MatrixCoefficients::ChromaDerivedCl),
490             14 => Ok(MatrixCoefficients::Ictcp),
491             _ => Err(format!("Invalid MatrixCoefficients {}", value)),
492         }
493     }
494 }
495 
496 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
497 pub enum ChromaSamplePosition {
498     #[default]
499     Unknown = 0,
500     Vertical = 1,
501     Colocated = 2,
502     Reserved = 3,
503 }
504 
505 impl TryFrom<u32> for ChromaSamplePosition {
506     type Error = String;
507 
try_from(value: u32) -> Result<Self, Self::Error>508     fn try_from(value: u32) -> Result<Self, Self::Error> {
509         match value {
510             0 => Ok(ChromaSamplePosition::Unknown),
511             1 => Ok(ChromaSamplePosition::Vertical),
512             2 => Ok(ChromaSamplePosition::Colocated),
513             3 => Ok(ChromaSamplePosition::Reserved),
514             _ => Err(format!("Invalid ChromaSamplePosition {}", value)),
515         }
516     }
517 }
518 
519 #[derive(Clone, Debug, Default, PartialEq, Eq)]
520 pub struct ColorConfig {
521     /// Syntax elements which, together with seq_profile, determine the bit
522     /// depth.
523     pub high_bitdepth: bool,
524     /// Syntax elements which, together with seq_profile, determine the bit
525     /// depth.
526     pub twelve_bit: bool,
527     /// If set, indicates that the video does not contain U and V color planes.
528     /// If not set, indicates that the video contains Y, U, and V color planes.
529     pub mono_chrome: bool,
530     /// If set, specifies that color_primaries, transfer_characteristics, and
531     /// matrix_coefficients are present. If not set, specifies that
532     /// color_primaries, transfer_characteristics and matrix_coefficients are
533     /// not present.
534     pub color_description_present_flag: bool,
535     /// Defined by the “Color primaries” section of ISO/IEC 23091-4/ITU-T H.273.
536     pub color_primaries: ColorPrimaries,
537     /// Defined by the “Transfer characteristics” section of ISO/IEC
538     /// 23091-4/ITU-T H.273.
539     pub transfer_characteristics: TransferCharacteristics,
540     /// Defined by the “Matrix coefficients” section of ISO/IEC 23091-4/ITU-T
541     /// H.273.
542     pub matrix_coefficients: MatrixCoefficients,
543     /// Binary value that is associated with the VideoFullRangeFlag variable
544     /// specified in ISO/IEC 23091-4/ITU- T H.273. color range equal to 0 shall
545     /// be referred to as the studio swing representation and color range equal
546     /// to 1 shall be referred to as the full swing representation for all
547     /// intents relating to this specification.
548     pub color_range: bool,
549     /// Specify the chroma subsampling format
550     pub subsampling_x: bool,
551     /// Specify the chroma subsampling format
552     pub subsampling_y: bool,
553     /// Specifies the sample position for subsampled streams
554     pub chroma_sample_position: ChromaSamplePosition,
555     /// If set, indicates that the U and V planes may have separate delta
556     /// quantizer values. If not set, indicates that the U and V planes will
557     /// share the same delta quantizer value.
558     pub separate_uv_delta_q: bool,
559 }
560 
561 #[derive(Clone, Debug, Default, PartialEq, Eq)]
562 pub struct SequenceHeaderObu {
563     /// The OBU header from the OBU that generated this sequence.
564     pub obu_header: ObuHeader,
565     /// Specifies the features that can be used in the coded video sequence.
566     pub seq_profile: Profile,
567     /// If set, specifies that the coded video sequence contains only one coded
568     /// frame. If not set, specifies that the coded video sequence contains one
569     /// or more coded frames.
570     pub still_picture: bool,
571     /// Specifies that the syntax elements not needed by a still picture are
572     /// omitted.
573     pub reduced_still_picture_header: bool,
574     /// Specifies the number of bits minus 1 used for transmitting the frame
575     /// width syntax elements.
576     pub frame_width_bits_minus_1: u8,
577     /// Specifies the number of bits minus 1 used for transmitting the frame
578     /// height syntax elements.
579     pub frame_height_bits_minus_1: u8,
580     /// Specifies the maximum frame width minus 1 for the frames represented by
581     /// this sequence header.
582     pub max_frame_width_minus_1: u16,
583     /// Specifies the maximum frame height minus 1 for the frames represented by
584     /// this sequence header.
585     pub max_frame_height_minus_1: u16,
586     /// Specifies whether frame id numbers are present in the coded video
587     /// sequence.
588     pub frame_id_numbers_present_flag: bool,
589     /// Specifies the number of bits minus 2 used to encode delta_frame_id
590     /// syntax elements.
591     pub delta_frame_id_length_minus_2: u32,
592     /// Used to calculate the number of bits used to encode the frame_id syntax
593     /// element.
594     pub additional_frame_id_length_minus_1: u32,
595     /// When set, indicates that superblocks contain 128x128 luma samples. When
596     /// not set, it indicates that superblocks contain 64x64 luma samples. (The
597     /// number of contained chroma samples depends on subsampling_x and
598     /// subsampling_y.)
599     pub use_128x128_superblock: bool,
600     /// When set, specifies that the use_filter_intra syntax element may be
601     /// present. When not set, specifies that the use_filter_intra syntax
602     /// element will not be present.
603     pub enable_filter_intra: bool,
604     /// Specifies whether the intra edge filtering process should be enabled.
605     pub enable_intra_edge_filter: bool,
606     /// When set, specifies that the mode info for inter blocks may contain the
607     /// syntax element interintra. If not set, specifies that the syntax element
608     /// interintra will not be present.
609     pub enable_interintra_compound: bool,
610     /// When set, specifies that the mode info for inter blocks may contain the
611     /// syntax element compound_type. When not set, specifies that the syntax
612     /// element compound_type will not be present.
613     pub enable_masked_compound: bool,
614     /// When set, indicates that the allow_warped_motion syntax element may be
615     /// present. When not set, indicates that the allow_warped_motion syntax
616     /// element will not be present.
617     pub enable_warped_motion: bool,
618     /// When set, indicates that tools based on the values of order hints may be
619     /// used. When not set, indicates that tools based on order hints are
620     /// disabled.
621     pub enable_order_hint: bool,
622     /// When set, indicates that the inter prediction filter type may be
623     /// specified independently in the horizontal and vertical directions. If
624     /// the flag is not set, only one filter type may be specified, which is
625     /// then used in both directions.
626     pub enable_dual_filter: bool,
627     /// If set, indicates that the distance weights process may be used for
628     /// inter prediction.
629     pub enable_jnt_comp: bool,
630     /// If set, indicates that the use_ref_frame_mvs syntax element may be
631     /// present. If not set, indicates that the use_ref_frame_mvs syntax element
632     /// will not be present.
633     pub enable_ref_frame_mvs: bool,
634     /// If not set, indicates that the seq_force_screen_content_tools syntax
635     /// element will be present. If set, indicates that
636     /// seq_force_screen_content_tools should be set equal to
637     /// SELECT_SCREEN_CONTENT_TOOLS.
638     pub seq_choose_screen_content_tools: bool,
639     /// Equal to SELECT_SCREEN_CONTENT_TOOLS indicates that the
640     /// allow_screen_content_tools syntax element will be present in the frame
641     /// header. Otherwise, seq_force_screen_content_tools contains the value for
642     /// allow_screen_content_tools.
643     pub seq_force_screen_content_tools: u32,
644     /// If not set, indicates that the seq_force_integer_mv syntax element will
645     /// be present. If set, indicates that seq_force_integer_mv should be set
646     /// equal to SELECT_INTEGER_MV.
647     pub seq_choose_integer_mv: bool,
648     /// Equal to SELECT_INTEGER_MV indicates that the force_integer_mv syntax
649     /// element will be present in the frame header (providing
650     /// allow_screen_content_tools is equal to 1). Otherwise,
651     /// seq_force_integer_mv contains the value for force_integer_mv.
652     pub seq_force_integer_mv: u32,
653     /// Used to compute OrderHintBits.
654     pub order_hint_bits_minus_1: i32,
655     /// Specifies the number of bits used for the order_hint syntax element.
656     pub order_hint_bits: i32,
657     /// If set, specifies that the use_superres syntax element will be present
658     /// in the uncompressed header. If not set, specifies that the use_superres
659     /// syntax element will not be present (instead use_superres will be set to
660     /// 0 in the uncompressed header without being read).
661     pub enable_superres: bool,
662     /// If set, specifies that cdef filtering may be enabled. If not set,
663     /// specifies that cdef filtering is disabled.
664     pub enable_cdef: bool,
665     /// If set, specifies that loop restoration filtering may be enabled. If
666     /// not set, specifies that loop restoration filtering is disabled.
667     pub enable_restoration: bool,
668     /// Specifies whether film grain parameters are present in the coded video
669     /// sequence.
670     pub film_grain_params_present: bool,
671     /// Indicates the number of operating points minus 1 present in the coded
672     /// video sequence. An operating point specifies which spatial and temporal
673     /// layers should be decoded.
674     pub operating_points_cnt_minus_1: u32,
675     /// The set of operating points.
676     pub operating_points: [OperatingPoint; MAX_NUM_OPERATING_POINTS],
677     /// Specifies whether decoder model information is present in the coded
678     /// video sequence.
679     pub decoder_model_info_present_flag: bool,
680     /// The decoder model info.
681     pub decoder_model_info: DecoderModelInfo,
682     /// Specifies whether initial display delay information is present in the
683     /// coded video sequence.
684     pub initial_display_delay_present_flag: bool,
685     /// Specifies whether timing info is present in the coded video sequence.
686     pub timing_info_present_flag: bool,
687     /// The timing info.
688     pub timing_info: TimingInfo,
689     /// The color config.
690     pub color_config: ColorConfig,
691 
692     /* CamelCase variables in the specification */
693     pub bit_depth: BitDepth,
694     pub num_planes: u32,
695 }
696 
697 #[derive(Clone, Debug, Default, PartialEq, Eq)]
698 pub struct StreamInfo {
699     pub seq_header: Rc<SequenceHeaderObu>,
700     pub render_width: u32,
701     pub render_height: u32,
702 }
703 
704 /// A TemporalDelimiterOBU
705 #[derive(Clone, Debug, Default, PartialEq, Eq)]
706 pub struct TemporalDelimiterObu {
707     pub obu_header: ObuHeader,
708 }
709 
710 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
711 pub enum InterpolationFilter {
712     #[default]
713     EightTap = 0,
714     EightTapSmooth = 1,
715     EightTapSharp = 2,
716     Bilinear = 3,
717     Switchable = 4,
718 }
719 
720 impl TryFrom<u32> for InterpolationFilter {
721     type Error = String;
722 
try_from(value: u32) -> Result<Self, Self::Error>723     fn try_from(value: u32) -> Result<Self, Self::Error> {
724         match value {
725             0 => Ok(InterpolationFilter::EightTap),
726             1 => Ok(InterpolationFilter::EightTapSmooth),
727             2 => Ok(InterpolationFilter::EightTapSharp),
728             3 => Ok(InterpolationFilter::Bilinear),
729             4 => Ok(InterpolationFilter::Switchable),
730             _ => Err(format!("Invalid InterpolationFilter {}", value)),
731         }
732     }
733 }
734 
735 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
736 pub enum TxModes {
737     #[default]
738     Only4x4 = 0,
739     Largest = 1,
740     Select = 2,
741 }
742 
743 impl TryFrom<u32> for TxModes {
744     type Error = String;
745 
try_from(value: u32) -> Result<Self, Self::Error>746     fn try_from(value: u32) -> Result<Self, Self::Error> {
747         match value {
748             0 => Ok(TxModes::Only4x4),
749             1 => Ok(TxModes::Largest),
750             2 => Ok(TxModes::Select),
751             _ => Err(format!("Invalid TxModes {}", value)),
752         }
753     }
754 }
755 
756 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
757 pub enum FrameRestorationType {
758     #[default]
759     None = 0,
760     Wiener = 1,
761     Sgrproj = 2,
762     Switchable = 3,
763 }
764 
765 impl TryFrom<u32> for FrameRestorationType {
766     type Error = String;
767 
try_from(value: u32) -> Result<Self, Self::Error>768     fn try_from(value: u32) -> Result<Self, Self::Error> {
769         match value {
770             0 => Ok(FrameRestorationType::None),
771             1 => Ok(FrameRestorationType::Wiener),
772             2 => Ok(FrameRestorationType::Sgrproj),
773             3 => Ok(FrameRestorationType::Switchable),
774             _ => Err(format!("Invalid FrameRestorationType {}", value)),
775         }
776     }
777 }
778 
779 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
780 pub enum ReferenceFrameType {
781     #[default]
782     Intra = 0,
783     Last = 1,
784     Last2 = 2,
785     Last3 = 3,
786     Golden = 4,
787     BwdRef = 5,
788     AltRef2 = 6,
789     AltRef = 7,
790 }
791 
792 impl TryFrom<u32> for ReferenceFrameType {
793     type Error = String;
794 
try_from(value: u32) -> Result<Self, Self::Error>795     fn try_from(value: u32) -> Result<Self, Self::Error> {
796         match value {
797             0 => Ok(ReferenceFrameType::Intra),
798             1 => Ok(ReferenceFrameType::Last),
799             2 => Ok(ReferenceFrameType::Last2),
800             3 => Ok(ReferenceFrameType::Last3),
801             4 => Ok(ReferenceFrameType::Golden),
802             5 => Ok(ReferenceFrameType::BwdRef),
803             6 => Ok(ReferenceFrameType::AltRef2),
804             7 => Ok(ReferenceFrameType::AltRef),
805             _ => Err(format!("Invalid ReferenceFrameType {}", value)),
806         }
807     }
808 }
809 
810 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
811 pub enum WarpModelType {
812     #[default]
813     Identity = 0,
814     Translation = 1,
815     RotZoom = 2,
816     Affine = 3,
817 }
818 
819 impl TryFrom<u32> for WarpModelType {
820     type Error = String;
821 
try_from(value: u32) -> Result<Self, Self::Error>822     fn try_from(value: u32) -> Result<Self, Self::Error> {
823         match value {
824             0 => Ok(WarpModelType::Identity),
825             1 => Ok(WarpModelType::Translation),
826             2 => Ok(WarpModelType::RotZoom),
827             3 => Ok(WarpModelType::Affine),
828             _ => Err(format!("Invalid WarpModelType {}", value)),
829         }
830     }
831 }
832 
833 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
834 pub enum FrameType {
835     #[default]
836     KeyFrame = 0,
837     InterFrame = 1,
838     IntraOnlyFrame = 2,
839     SwitchFrame = 3,
840 }
841 
842 impl TryFrom<u32> for FrameType {
843     type Error = String;
844 
try_from(value: u32) -> Result<Self, Self::Error>845     fn try_from(value: u32) -> Result<Self, Self::Error> {
846         match value {
847             0 => Ok(FrameType::KeyFrame),
848             1 => Ok(FrameType::InterFrame),
849             2 => Ok(FrameType::IntraOnlyFrame),
850             3 => Ok(FrameType::SwitchFrame),
851             _ => Err(format!("Invalid FrameType {}", value)),
852         }
853     }
854 }
855 
856 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
857 pub enum TxMode {
858     #[default]
859     Only4x4 = 0,
860     Largest = 1,
861     Select = 2,
862 }
863 
864 impl TryFrom<u32> for TxMode {
865     type Error = String;
866 
try_from(value: u32) -> Result<Self, Self::Error>867     fn try_from(value: u32) -> Result<Self, Self::Error> {
868         match value {
869             0 => Ok(TxMode::Only4x4),
870             1 => Ok(TxMode::Largest),
871             2 => Ok(TxMode::Select),
872             _ => Err(format!("Invalid TxMode {}", value)),
873         }
874     }
875 }
876 
877 #[derive(Clone, Debug, Default, PartialEq, Eq)]
878 pub struct FrameObu<'a> {
879     pub header: FrameHeaderObu,
880     pub tile_group: TileGroupObu<'a>,
881 }
882 
883 /// A FrameHeaderOBU
884 #[derive(Clone, Debug, Default, PartialEq, Eq)]
885 pub struct FrameHeaderObu {
886     /// The original OBU header. This may be from a FrameOBU or a FrameHeaderOBU
887     /// directly.
888     pub obu_header: ObuHeader,
889     /// If set, indicates the frame indexed by frame_to_show_map_idx is to be
890     /// output; If not set, indicates that further processing is required.
891     pub show_existing_frame: bool,
892     /// Specifies the frame to be output. It is only available if
893     /// show_existing_frame is set.
894     pub frame_to_show_map_idx: u8,
895     /// Specifies the length of the frame_presentation_time syntax element, in
896     /// bits.
897     pub frame_presentation_time: u32,
898     /// Provides the frame id number for the frame to output.
899     pub display_frame_id: u32,
900     /// Specifies the type of the frame
901     pub frame_type: FrameType,
902     /// If set, specifies that this frame should be immediately output once
903     /// decoded. If not set specifies that this frame should not be
904     /// immediately output. (It may be output later if a later uncompressed
905     /// header uses show_existing_frame is set).
906     pub show_frame: bool,
907     /// When set, specifies that the frame may be output using the
908     /// show_existing_frame mechanism. When not set, specifies that this frame
909     /// will not be output using the show_existing_frame mechanism.
910     pub showable_frame: bool,
911     /// If set, indicates that error resilient mode is enabled;
912     /// error_resilient_mode equal to 0 indicates that error resilient mode is
913     /// disabled.
914     pub error_resilient_mode: bool,
915     /// Specifies whether the CDF update in the symbol decoding process should
916     /// be disabled.
917     pub disable_cdf_update: bool,
918     /// When set, indicates that intra blocks may use palette encoding; When not
919     /// set, indicates that palette encoding is never used.
920     pub allow_screen_content_tools: u32,
921     /// If set, specifies that motion vectors will always be integers. If not
922     /// set, specifies that motion vectors can contain fractional bits.
923     pub force_integer_mv: u32,
924     /// Specifies the frame id number for the current frame. Frame id numbers
925     /// are additional information that do not affect the decoding process, but
926     /// provide decoders with a way of detecting missing reference frames so
927     /// that appropriate action can be taken.
928     pub current_frame_id: u32,
929     /// If not set, specifies that the frame size is equal to the size in the
930     /// sequence header. If set, specifies that the frame size will either be
931     /// specified as the size of one of the reference frames, or computed from
932     /// the frame_width_minus_1 and frame_height_minus_1 syntax elements.
933     pub frame_size_override_flag: bool,
934     /// Specifies OrderHintBits least significant bits of the expected output
935     /// order for this frame.
936     pub order_hint: u32,
937     /// Specifies which reference frame contains the CDF values and other state
938     /// that should be loaded at the start of the frame.
939     pub primary_ref_frame: u32,
940     /// If set, specifies that buffer_removal_time is present.  If not set,
941     /// specifies that buffer_removal_time is not present.
942     pub buffer_removal_time_present_flag: bool,
943     /// Specifies the frame removal time in units of DecCT clock ticks counted
944     /// from the removal time of the last random access point for operating
945     /// point opNum. buffer_removal_time is signaled as a fixed length unsigned
946     /// integer with a length in bits given by
947     /// buffer_removal_time_length_minus_1 + 1.
948     pub buffer_removal_time: Vec<u32>,
949     /// Contains a bitmask that specifies which reference frame slots will be
950     /// updated with the current frame after it is decoded.
951     pub refresh_frame_flags: u32,
952     /// Specifies the expected output order hint for each reference frame.
953     pub ref_order_hint: [u32; NUM_REF_FRAMES],
954     /// If set, indicates that intra block copy may be used in this frame. If
955     /// not set indicates that intra block copy is not allowed in this frame.
956     pub allow_intrabc: bool,
957     /// If set, indicates that only two reference frames are explicitly
958     /// signaled. If not set, indicates that all reference frames are explicitly
959     /// signaled.
960     pub frame_refs_short_signaling: bool,
961     /// Specifies the reference frame to use for LAST_FRAME.
962     pub last_frame_idx: u8,
963     /// Specifies the reference frame to use for GOLDEN_FRAME.
964     pub gold_frame_idx: u8,
965     /// Specifies which reference frames are used by inter frames
966     pub ref_frame_idx: [u8; REFS_PER_FRAME],
967     /// If not set, specifies that motion vectors are specified to quarter pel
968     /// precision; If set, specifies that motion vectors are specified to eighth
969     /// pel precision.
970     pub allow_high_precision_mv: bool,
971     /// If not set, specifies that only the SIMPLE motion mode will be used.
972     pub is_motion_mode_switchable: bool,
973     /// If set, specifies that motion vector information from a previous frame
974     /// can be used when decoding the current frame. If not set, specifies that
975     /// this information will not be used.
976     pub use_ref_frame_mvs: bool,
977     /// If set, indicates that the end of frame CDF update is disabled; If not
978     /// set, indicates that the end of frame CDF update is enabled.
979     pub disable_frame_end_update_cdf: bool,
980     /// If set, indicates that the syntax element motion_mode may be present.
981     /// If not set, indicates that the syntax element motion_mode will not be
982     /// present
983     pub allow_warped_motion: bool,
984     /// If set, specifies that the frame is restricted to a reduced subset of
985     /// the full set of transform types.
986     pub reduced_tx_set: bool,
987     /// If not set, means that the render width and height are inferred from the
988     /// frame width and height. If set, means that the render width and height
989     /// are explicitly coded.
990     pub render_and_frame_size_different: bool,
991     /// If not set, indicates that no upscaling is needed. If set, indicates
992     /// that upscaling is needed.
993     pub use_superres: bool,
994     /// If set indicates that the filter selection is signaled at the block
995     /// level; If not set, indicates that the filter selection is signaled at
996     /// the frame level.
997     pub is_filter_switchable: bool,
998     /// The interpolation filter parameters.
999     pub interpolation_filter: InterpolationFilter,
1000     /// The loop filter parameters.
1001     pub loop_filter_params: LoopFilterParams,
1002     /// The quantization parameters.
1003     pub quantization_params: QuantizationParams,
1004     /// The segmentation parameters.
1005     pub segmentation_params: SegmentationParams,
1006     /// The tile info.
1007     pub tile_info: TileInfo,
1008     /// The CDEF parameters.
1009     pub cdef_params: CdefParams,
1010     /// The loop restoration parameters.
1011     pub loop_restoration_params: LoopRestorationParams,
1012     /// Used to compute TxMode.
1013     pub tx_mode_select: u32,
1014     /// If set specifies that the syntax element skip_mode will be present.  If
1015     /// not set, specifies that skip_mode will not be used for this frame.
1016     pub skip_mode_present: bool,
1017     /// If set, specifies that the mode info for inter blocks contains the
1018     /// syntax element comp_mode that indicates whether to use single or
1019     /// compound reference prediction. If not set, specifies that all inter
1020     /// blocks will use single prediction.
1021     pub reference_select: bool,
1022     /// The global motion parameters.
1023     pub global_motion_params: GlobalMotionParams,
1024     /// The film grain parameters.
1025     pub film_grain_params: FilmGrainParams,
1026 
1027     /* CamelCase variables */
1028     pub superres_denom: u32,
1029     pub frame_is_intra: bool,
1030     pub order_hints: [u32; NUM_REF_FRAMES],
1031     pub ref_frame_sign_bias: [bool; NUM_REF_FRAMES],
1032     pub coded_lossless: bool,
1033     pub all_lossless: bool,
1034     pub lossless_array: [bool; MAX_SEGMENTS],
1035     pub seg_qm_level: [[u32; MAX_SEGMENTS]; 3],
1036     pub upscaled_width: u32,
1037     pub frame_width: u32,
1038     pub frame_height: u32,
1039     pub render_width: u32,
1040     pub render_height: u32,
1041     pub tx_mode: TxMode,
1042     pub skip_mode_frame: [u32; 2],
1043     pub mi_cols: u32,
1044     pub mi_rows: u32,
1045     pub header_bytes: usize,
1046 }
1047 
1048 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1049 pub struct LoopFilterParams {
1050     /// An array containing loop filter strength values. Different loop filter
1051     /// strength values from the array are used depending on the image plane
1052     /// being filtered, and the edge direction (vertical or horizontal) being
1053     /// filtered.
1054     pub loop_filter_level: [u8; 4],
1055     /// Indicates the sharpness level. The loop_filter_level and
1056     /// loop_filter_sharpness together determine when a block edge is filtered,
1057     /// and by how much the filtering can change the sample values.
1058     pub loop_filter_sharpness: u8,
1059     /// If set, means that the filter level depends on the mode and reference
1060     /// frame used to predict a block. If not set, means that the filter level
1061     /// does not depend on the mode and reference frame.
1062     pub loop_filter_delta_enabled: bool,
1063     /// If set, means that additional syntax elements are present that specify
1064     /// which mode and reference frame deltas are to be updated.
1065     /// loop_filter_delta_update equal to 0 means that these syntax elements are
1066     /// not present.
1067     pub loop_filter_delta_update: bool,
1068     /// Contains the adjustment needed for the filter level based on the chosen
1069     /// reference frame. If this syntax element is not present, it maintains
1070     /// its previous value.
1071     pub loop_filter_ref_deltas: [i8; TOTAL_REFS_PER_FRAME],
1072     /// Contains the adjustment needed for the filter level based on the chosen
1073     /// mode. If this syntax element is not present in the, it maintains its
1074     /// previous value.
1075     pub loop_filter_mode_deltas: [i8; 2],
1076     /// Specifies whether loop filter delta values are present.
1077     pub delta_lf_present: bool,
1078     /// Specifies the left shift which should be applied to decoded loop filter
1079     /// delta values.
1080     pub delta_lf_res: u8,
1081     /// If set, specifies that separate loop filter deltas are sent for
1082     /// horizontal luma edges, vertical luma edges, the U edges, and the V
1083     /// edges. If not set, specifies that the same loop filter delta is used for
1084     /// all edges.
1085     pub delta_lf_multi: bool,
1086 }
1087 
1088 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1089 pub struct QuantizationParams {
1090     /// Indicates the base frame qindex. This is used for Y AC coefficients and
1091     /// as the base value for the other quantizers.
1092     pub base_q_idx: u32,
1093     /// Indicates the base frame qindex. This is used for Y AC coefficients and
1094     /// as the base value for the other quantizers.
1095     pub diff_uv_delta: bool,
1096     /// Specifies that the quantizer matrix will be used to compute quantizers.
1097     pub using_qmatrix: bool,
1098     /// Specifies the level in the quantizer matrix that should be used for luma
1099     /// plane decoding.
1100     pub qm_y: u32,
1101     /// Specifies the level in the quantizer matrix that should be used for
1102     /// chroma U plane decoding.
1103     pub qm_u: u32,
1104     /// Specifies the level in the quantizer matrix that should be used for
1105     /// chroma V plane decoding.
1106     pub qm_v: u32,
1107     /// Specifies whether quantizer index delta values are present.
1108     pub delta_q_present: bool,
1109     /// Specifies the left shift which should be applied to decoded quantizer
1110     /// index delta values.
1111     pub delta_q_res: u32,
1112     /// Same as DeltaQYDc
1113     pub delta_q_y_dc: i32,
1114     /// Same as DeltaQUDc
1115     pub delta_q_u_dc: i32,
1116     /// Same as DeltaQUAc
1117     pub delta_q_u_ac: i32,
1118     /// Same as DeltaQVDc
1119     pub delta_q_v_dc: i32,
1120     /// Same as DeltaQVAc
1121     pub delta_q_v_ac: i32,
1122 }
1123 
1124 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1125 pub struct SegmentationParams {
1126     /// If set, indicates that this frame makes use of the segmentation tool; If
1127     /// not set, indicates that the frame does not use segmentation.
1128     pub segmentation_enabled: bool,
1129     /// If set, indicates that the segmentation map are updated during the
1130     /// decoding of this frame. If not set, means that the segmentation map from
1131     /// the previous frame is used.
1132     pub segmentation_update_map: bool,
1133     /// If set, indicates that the updates to the segmentation map are coded
1134     /// relative to the existing segmentation map. If not set, indicates that
1135     /// the new segmentation map is coded without reference to the existing
1136     /// segmentation map.
1137     pub segmentation_temporal_update: bool,
1138     /// If set, indicates that new parameters are about to be specified for each
1139     /// segment. If not set, indicates that the segmentation parameters should
1140     /// keep their existing values.
1141     pub segmentation_update_data: bool,
1142     /// If not set, indicates that the corresponding feature is unused and has
1143     /// value equal to 0. If set, indicates that the feature value is coded.
1144     pub feature_enabled: [[bool; SEG_LVL_MAX]; MAX_SEGMENTS],
1145     /// Specifies the feature data for a segment feature.
1146     pub feature_data: [[i16; SEG_LVL_MAX]; MAX_SEGMENTS],
1147     /// Same as SegIdPreSkip
1148     pub seg_id_pre_skip: bool,
1149     /// Same as LastActiveSegId
1150     pub last_active_seg_id: u8,
1151 }
1152 
1153 #[derive(Clone, Debug, PartialEq, Eq)]
1154 pub struct TileInfo {
1155     /// If set, means that the tiles are uniformly spaced across the frame. (In
1156     /// other words, all tiles are the same size except for the ones at the
1157     /// right and bottom edge which can be smaller.) If not set, means that the
1158     /// tile sizes are coded.
1159     pub uniform_tile_spacing_flag: bool,
1160     /// Used to compute TileColsLog2.
1161     pub increment_tile_rows_log2: u32,
1162     /// Specifies the width of a tile minus 1 in units of superblocks.
1163     pub width_in_sbs_minus_1: [u32; MAX_TILE_COLS],
1164     /// Specifies the height of a tile minus 1 in units of superblocks.
1165     pub height_in_sbs_minus_1: [u32; MAX_TILE_ROWS],
1166     /// Specifies which tile to use for the CDF update
1167     pub context_update_tile_id: u32,
1168     /// An array specifying the start column (in units of 4x4 luma samples) for
1169     /// each tile across the image.
1170     pub mi_col_starts: [u32; MAX_TILE_COLS + 1],
1171     /// An array specifying the start row (in units of 4x4 luma samples) for
1172     /// each tile down the image.
1173     pub mi_row_starts: [u32; MAX_TILE_ROWS + 1],
1174     /// Specifies the base 2 logarithm of the desired number of tiles down the
1175     /// frame.
1176     pub tile_cols_log2: u32,
1177     /// Specifies the number of tiles across the frame.
1178     pub tile_cols: u32,
1179     /// Specifies the base 2 logarithm of the desired number of tiles down the
1180     /// frame.
1181     pub tile_rows_log2: u32,
1182     /// Secifies the number of tiles down the frame
1183     pub tile_rows: u32,
1184     /// Specifies the number of bytes needed to code each tile size.
1185     pub tile_size_bytes: u32,
1186 }
1187 
1188 impl Default for TileInfo {
default() -> Self1189     fn default() -> Self {
1190         Self {
1191             uniform_tile_spacing_flag: Default::default(),
1192             increment_tile_rows_log2: Default::default(),
1193             width_in_sbs_minus_1: [0; MAX_TILE_COLS],
1194             height_in_sbs_minus_1: [0; MAX_TILE_ROWS],
1195             context_update_tile_id: Default::default(),
1196             mi_col_starts: [0; MAX_TILE_COLS + 1],
1197             mi_row_starts: [0; MAX_TILE_ROWS + 1],
1198             tile_cols_log2: Default::default(),
1199             tile_cols: Default::default(),
1200             tile_rows_log2: Default::default(),
1201             tile_rows: Default::default(),
1202             tile_size_bytes: Default::default(),
1203         }
1204     }
1205 }
1206 
1207 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1208 pub struct CdefParams {
1209     /// Controls the amount of damping in the deringing filter.
1210     pub cdef_damping: u32,
1211     /// Specifies the number of bits needed to specify which CDEF filter to
1212     /// apply.
1213     pub cdef_bits: u32,
1214     /// Specify the strength of the primary filter.
1215     pub cdef_y_pri_strength: [u32; CDEF_MAX],
1216     /// Specify the strength of the secondary filter.
1217     pub cdef_y_sec_strength: [u32; CDEF_MAX],
1218     /// Specify the strength of the primary filter.
1219     pub cdef_uv_pri_strength: [u32; CDEF_MAX],
1220     /// Specify the strength of the secondary filter.
1221     pub cdef_uv_sec_strength: [u32; CDEF_MAX],
1222 }
1223 
1224 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1225 pub struct LoopRestorationParams {
1226     /// Specifies if the luma restoration size should be halved.
1227     pub lr_unit_shift: u8,
1228     /// Only present for 4:2:0 formats and specifies if the chroma size should
1229     /// be half the luma size.
1230     pub lr_uv_shift: u8,
1231     /// Same as FrameRestorationType in the specification.
1232     pub frame_restoration_type: [FrameRestorationType; MAX_NUM_PLANES],
1233     /// Same as LoopRestorationSize in the specification.
1234     pub loop_restoration_size: [u16; MAX_NUM_PLANES],
1235     /// Same as UsesLr in the specification.
1236     pub uses_lr: bool,
1237     /// Same as UsesChromaLr in the specification.
1238     pub uses_chroma_lr: bool,
1239 }
1240 
1241 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1242 pub struct GlobalMotionParams {
1243     /// Specifies whether global motion parameters are present for a particular
1244     /// reference frame.
1245     pub is_global: [bool; NUM_REF_FRAMES],
1246     /// Specifies whether a particular reference frame uses rotation and zoom
1247     /// global motion.
1248     pub is_rot_zoom: [bool; NUM_REF_FRAMES],
1249     /// Specifies whether a particular reference frame uses translation global
1250     /// motion.
1251     pub is_translation: [bool; NUM_REF_FRAMES],
1252     /// gm_params\[ ref \]\[ j \] is set equal to SavedGmParams\[
1253     /// frame_to_show_map_idx \]\[ ref \]\[ j \] for ref = LAST_FRAME..ALTREF_FRAME,
1254     /// for j = 0..5.
1255     pub gm_params: [[i32; 6]; NUM_REF_FRAMES],
1256     /// Whether the parameters are valid (see warpValid and section 7.11.3.6)
1257     pub warp_valid: [bool; NUM_REF_FRAMES],
1258     /// Same as GmType.
1259     pub gm_type: [WarpModelType; NUM_REF_FRAMES],
1260 }
1261 
1262 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1263 pub struct FilmGrainParams {
1264     /// If set, specifies that film grain should be added to this frame. If not
1265     /// set, specifies that film grain should not be added.
1266     pub apply_grain: bool,
1267     /// Specifies the starting value for the pseudo-random numbers used during
1268     /// film grain synthesis.
1269     pub grain_seed: u16,
1270     /// If set means that a new set of parameters should be sent.  If not set,
1271     /// means that the previous set of parameters should be used.
1272     pub update_grain: bool,
1273     /// Indicates which reference frame contains the film grain parameters to be
1274     /// used for this frame.
1275     pub film_grain_params_ref_idx: u8,
1276     /// Specifies the number of points for the piece-wise linear scaling
1277     /// function of the luma component.
1278     pub num_y_points: u8,
1279     /// Represents the x (luma value) coordinate for the i-th point of the
1280     /// piecewise linear scaling function for luma component. The values are
1281     /// signaled on the scale of 0..255. (In case of 10 bit video, these values
1282     /// correspond to luma values divided by 4. In case of 12 bit video, these
1283     /// values correspond to luma values divided by 16.)
1284     pub point_y_value: [u8; MAX_NUM_Y_POINTS],
1285     /// Pepresents the scaling (output) value for the i-th point of the
1286     /// piecewise linear scaling function for luma component.
1287     pub point_y_scaling: [u8; MAX_NUM_Y_POINTS],
1288     /// Specifies that the chroma scaling is inferred from the luma scaling.
1289     pub chroma_scaling_from_luma: bool,
1290     /// Specifies the number of points for the piece-wise linear scaling
1291     /// function of the cb component.
1292     pub num_cb_points: u8,
1293     /// Represents the x coordinate for the i-th point of the piece-wise linear
1294     /// scaling function for cb component. The values are signaled on the scale
1295     /// of 0..255.
1296     pub point_cb_value: [u8; MAX_NUM_CB_POINTS],
1297     /// Represents the scaling (output) value for the i-th point of the
1298     /// piecewise linear scaling function for cb component.
1299     pub point_cb_scaling: [u8; MAX_NUM_CB_POINTS],
1300     /// Specifies represents the number of points for the piece-wise linear
1301     /// scaling function of the cr component.
1302     pub num_cr_points: u8,
1303     /// Represents the x coordinate for the i-th point of the piece-wise linear
1304     /// scaling function for cr component. The values are signaled on the scale
1305     /// of 0..255.
1306     pub point_cr_value: [u8; MAX_NUM_CR_POINTS],
1307     /// Represents the scaling (output) value for the i-th point of the
1308     /// piecewise linear scaling function for cr component.
1309     pub point_cr_scaling: [u8; MAX_NUM_CR_POINTS],
1310     /// Represents the shift – 8 applied to the values of the chroma component.
1311     /// The grain_scaling_minus_8 can take values of 0..3 and determines the
1312     /// range and quantization step of the standard deviation of film grain.
1313     pub grain_scaling_minus_8: u8,
1314     /// Specifies the number of auto-regressive coefficients for luma and chroma.
1315     pub ar_coeff_lag: u32,
1316     /// Specifies auto-regressive coefficients used for the Y plane.
1317     pub ar_coeffs_y_plus_128: [u8; MAX_NUM_POS_LUMA],
1318     /// Specifies auto-regressive coefficients used for the U plane.
1319     pub ar_coeffs_cb_plus_128: [u8; MAX_NUM_POS_LUMA],
1320     /// Specifies auto-regressive coefficients used for the V plane.
1321     pub ar_coeffs_cr_plus_128: [u8; MAX_NUM_POS_LUMA],
1322     /// Specifies the range of the auto-regressive coefficients. Values of 0, 1,
1323     /// 2, and 3 correspond to the ranges for auto-regressive coefficients of
1324     /// [-2, 2), [-1, 1), [-0.5, 0.5) and [-0.25, 0.25) respectively.
1325     pub ar_coeff_shift_minus_6: u8,
1326     /// Specifies how much the Gaussian random numbers should be scaled down
1327     /// during the grain synthesis process.
1328     pub grain_scale_shift: u8,
1329     /// Represents a multiplier for the cb component used in derivation of the
1330     /// input index to the cb component scaling function.
1331     pub cb_mult: u8,
1332     /// Represents a multiplier for the average luma component used in
1333     /// derivation of the input index to the cb component scaling function.
1334     pub cb_luma_mult: u8,
1335     /// Represents an offset used in derivation of the input index to the cb
1336     /// component scaling function.
1337     pub cb_offset: u16,
1338     /// Represents a multiplier for the cr component used in derivation of the
1339     /// input index to the cr component scaling function.
1340     pub cr_mult: u8,
1341     /// Represents a multiplier for the average luma component used in
1342     /// derivation of the input index to the cr component scaling function.
1343     pub cr_luma_mult: u8,
1344     /// Represents an offset used in derivation of the input index to the cr
1345     /// component scaling function.
1346     pub cr_offset: u16,
1347     /// If set, indicates that the overlap between film grain blocks shall be
1348     /// applied. If not set, indicates that the overlap between film grain
1349     /// blocks shall not be applied.
1350     pub overlap_flag: bool,
1351     /// If set, indicates that clipping to the restricted (studio) range shall
1352     /// be applied to the sample values after adding the film grain (see the
1353     /// semantics for color_range for an explanation of studio swing).  If not
1354     /// set, indicates that clipping to the full range shall be applied to the
1355     /// sample values after adding the film grain.
1356     pub clip_to_restricted_range: bool,
1357 }
1358 
1359 /// Keeps track of the state of the reference frames in the parser. All
1360 /// variables are CamelCase.
1361 #[derive(Clone, Debug, Default, PartialEq, Eq)]
1362 struct ReferenceFrameInfo {
1363     /// An array which is indexed by a reference picture slot number. A value of
1364     /// true in the array signifies that the corresponding reference picture
1365     /// slot is valid for use as a reference picture, while a value of false
1366     /// signifies that the corresponding reference picture slot is not valid for
1367     /// use as a reference picture.
1368     ref_valid: bool,
1369     /// Specifies the frame id for each reference frame.
1370     ref_frame_id: u32,
1371     /// See 7.20 Reference Frame Update Process.
1372     ref_upscaled_width: u32,
1373     /// See 7.20 Reference Frame Update Process.
1374     ref_frame_width: u32,
1375     /// See 7.20 Reference Frame Update Process.
1376     ref_frame_height: u32,
1377     /// See 7.20 Reference Frame Update Process.
1378     ref_render_width: u32,
1379     /// See 7.20 Reference Frame Update Process.
1380     ref_render_height: u32,
1381     /// See 7.20 Reference Frame Update Process.
1382     ref_mi_cols: u32,
1383     /// See 7.20 Reference Frame Update Process.
1384     ref_mi_rows: u32,
1385     /// See 7.20 Reference Frame Update Process.
1386     ref_frame_type: FrameType,
1387     /// See 7.20 Reference Frame Update Process.
1388     ref_subsampling_x: bool,
1389     /// See 7.20 Reference Frame Update Process.
1390     ref_subsampling_y: bool,
1391     /// See 7.20 Reference Frame Update Process.
1392     ref_bit_depth: BitDepth,
1393     /// See 7.20 Reference Frame Update Process.
1394     ref_order_hint: u32,
1395     /// The saved segmentation parameters.
1396     segmentation_params: SegmentationParams,
1397     /// The saved global motion parameters.
1398     global_motion_params: GlobalMotionParams,
1399     /// The saved loop filter parameters.
1400     loop_filter_params: LoopFilterParams,
1401     /// The saved film grain parameters.
1402     film_grain_params: FilmGrainParams,
1403     /// The saved tile info parameters.
1404     tile_info: TileInfo,
1405     display_frame_id: u32,
1406     showable_frame: bool,
1407 }
1408 
1409 #[derive(Clone, Debug, Default)]
1410 pub struct AnnexBState {
1411     pub temporal_unit_size: u32,
1412     pub frame_unit_size: u32,
1413     pub temporal_unit_consumed: u32,
1414     pub frame_unit_consumed: u32,
1415 }
1416 
1417 #[derive(Clone, Debug)]
1418 enum StreamFormat {
1419     LowOverhead,
1420     AnnexB(AnnexBState),
1421 }
1422 
1423 #[derive(Debug)]
1424 pub struct Parser {
1425     stream_format: StreamFormat,
1426     operating_point: u32,
1427     /// Same as SeenFrameHeader in the specification
1428     seen_frame_header: bool,
1429     operating_point_idc: u16,
1430     should_probe_for_annexb: bool,
1431     is_first_frame: bool,
1432     ref_info: [ReferenceFrameInfo; NUM_REF_FRAMES],
1433 
1434     /* CamelCase variables */
1435     mi_cols: u32,
1436     mi_rows: u32,
1437     prev_frame_id: u32,
1438     current_frame_id: u32,
1439     mi_col_starts: [u32; MAX_TILE_COLS + 1],
1440     mi_row_starts: [u32; MAX_TILE_ROWS + 1],
1441     tile_cols_log2: u32,
1442     tile_cols: u32,
1443     tile_rows_log2: u32,
1444     tile_rows: u32,
1445     tile_size_bytes: u32,
1446 
1447     /// We keep this to implement frame_header_copy() in the specification, and to fill in
1448     /// StreamInfo render_width and render_height.
1449     pub last_frame_header: Option<FrameHeaderObu>,
1450     /// The last SequenceHeaderObu parsed.
1451     pub sequence_header: Option<Rc<SequenceHeaderObu>>,
1452 }
1453 
1454 impl Parser {
1455     /// Probes the input data for the Annex B format. Anything other than
1456     /// Ok(true) refers to data in "low-overhead" format instead, as we are trying to parse
annexb_probe(data: &[u8]) -> Result<bool, String>1457     fn annexb_probe(data: &[u8]) -> Result<bool, String> {
1458         let mut r = Reader::new(data);
1459         let mut seen_sequence = false;
1460         let mut seen_frame = false;
1461 
1462         // Try reading the first TU and frame unit size
1463         let temporal_unit_size = r.read_leb128()?;
1464         if temporal_unit_size == 0 {
1465             return Ok(false);
1466         }
1467 
1468         let frame_unit_size = r.read_leb128()?;
1469         if frame_unit_size == 0 || frame_unit_size > temporal_unit_size {
1470             return Ok(false);
1471         }
1472 
1473         let obu_length = r.read_leb128()?;
1474         if obu_length == 0 || obu_length > frame_unit_size {
1475             return Ok(false);
1476         }
1477 
1478         // The first OBU in the first frame_unit of each temporal_unit must
1479         // be a temporal delimiter OBU (and this is the only place temporal
1480         // delimiter OBUs can appear)
1481         let header = Self::parse_obu_header(&mut r.clone())?;
1482         if !matches!(header.obu_type, ObuType::TemporalDelimiter) {
1483             return Ok(false);
1484         }
1485 
1486         // Try identifying a sequence and a frame.
1487         r.0.skip_bits(obu_length as usize * 8)?;
1488         let mut num_bytes_read = 0;
1489 
1490         loop {
1491             let obu_length = r.read_leb128()?;
1492             let mut obu_reader = r.clone();
1493 
1494             r.0.skip_bits(obu_length as usize * 8)?;
1495             num_bytes_read += obu_length;
1496 
1497             if !seen_sequence {
1498                 let header = Self::parse_obu_header(&mut obu_reader)?;
1499                 seen_sequence = matches!(header.obu_type, ObuType::SequenceHeader);
1500             }
1501 
1502             if !seen_frame {
1503                 let header = Self::parse_obu_header(&mut obu_reader)?;
1504                 seen_frame = matches!(header.obu_type, ObuType::Frame | ObuType::FrameHeader);
1505             }
1506 
1507             if seen_sequence && seen_frame {
1508                 // OK, enough evidence of Annex B format.
1509                 return Ok(true);
1510             }
1511 
1512             if num_bytes_read >= frame_unit_size {
1513                 // We read what we've identified as the first frame and yet no
1514                 // sequence and no actual frames were found.
1515                 return Ok(false);
1516             }
1517         }
1518     }
1519 
compute_image_size(&mut self, fh: &mut FrameHeaderObu)1520     fn compute_image_size(&mut self, fh: &mut FrameHeaderObu) {
1521         fh.mi_cols = 2 * ((fh.frame_width + 7) >> 3);
1522         fh.mi_rows = 2 * ((fh.frame_height + 7) >> 3);
1523         self.mi_cols = fh.mi_cols;
1524         self.mi_rows = fh.mi_rows;
1525     }
1526 
1527     // 5.9.8
parse_superres_params( fh: &mut FrameHeaderObu, r: &mut Reader, seq: &SequenceHeaderObu, ) -> Result<(), String>1528     fn parse_superres_params(
1529         fh: &mut FrameHeaderObu,
1530         r: &mut Reader,
1531         seq: &SequenceHeaderObu,
1532     ) -> Result<(), String> {
1533         if seq.enable_superres {
1534             fh.use_superres = r.0.read_bit()?;
1535         } else {
1536             fh.use_superres = false;
1537         }
1538 
1539         if fh.use_superres {
1540             fh.superres_denom =
1541                 r.0.read_bits::<u32>(SUPERRES_DENOM_BITS)? + SUPERRES_DENOM_MIN as u32;
1542         } else {
1543             fh.superres_denom = SUPERRES_NUM as u32;
1544         }
1545 
1546         fh.upscaled_width = fh.frame_width;
1547         fh.frame_width =
1548             (fh.upscaled_width * SUPERRES_NUM as u32 + (fh.superres_denom / 2)) / fh.superres_denom;
1549 
1550         Ok(())
1551     }
1552 
1553     // 7.8 verbatim.
set_frame_refs( &self, fh: &mut FrameHeaderObu, ref_order_hint: &[u32; NUM_REF_FRAMES], ) -> Result<(), String>1554     fn set_frame_refs(
1555         &self,
1556         fh: &mut FrameHeaderObu,
1557         ref_order_hint: &[u32; NUM_REF_FRAMES],
1558     ) -> Result<(), String> {
1559         let seq = self.sequence()?;
1560         let mut ref_frame_idx = [-1i32; REFS_PER_FRAME];
1561 
1562         ref_frame_idx[0] = fh.last_frame_idx.into();
1563         ref_frame_idx[ReferenceFrameType::Golden as usize - ReferenceFrameType::Last as usize] =
1564             fh.gold_frame_idx.into();
1565 
1566         let mut used_frame = [false; NUM_REF_FRAMES];
1567         used_frame[fh.last_frame_idx as usize] = true;
1568         used_frame[fh.gold_frame_idx as usize] = true;
1569 
1570         let cur_frame_hint = 1 << (seq.order_hint_bits - 1);
1571         let mut shifted_order_hints = [0; NUM_REF_FRAMES];
1572         for i in 0..NUM_REF_FRAMES {
1573             shifted_order_hints[i] = cur_frame_hint
1574                 + helpers::get_relative_dist(
1575                     seq.enable_order_hint,
1576                     seq.order_hint_bits,
1577                     ref_order_hint[i].try_into().unwrap(),
1578                     fh.order_hint.try_into().unwrap(),
1579                 );
1580         }
1581 
1582         let mut latest_order_hint = shifted_order_hints[fh.last_frame_idx as usize];
1583         if latest_order_hint >= cur_frame_hint {
1584             return Err("It is a requirement of bitstream conformance that last_order_hint < cur_frame_hint".into());
1585         }
1586 
1587         let mut earliest_order_hint = shifted_order_hints[fh.gold_frame_idx as usize];
1588         if earliest_order_hint >= cur_frame_hint {
1589             return Err("It is a requirement of bitstream conformance that gold_order_hint < cur_frame_hint".into());
1590         }
1591 
1592         let ref_ = helpers::find_latest_backward(
1593             &shifted_order_hints,
1594             &used_frame,
1595             cur_frame_hint,
1596             &mut latest_order_hint,
1597         );
1598 
1599         if ref_ >= 0 {
1600             ref_frame_idx
1601                 [ReferenceFrameType::AltRef as usize - ReferenceFrameType::Last as usize] = ref_;
1602             used_frame[ref_ as usize] = true;
1603         }
1604 
1605         let ref_ = helpers::find_earliest_backward(
1606             &shifted_order_hints,
1607             &used_frame,
1608             cur_frame_hint,
1609             &mut earliest_order_hint,
1610         );
1611 
1612         if ref_ >= 0 {
1613             ref_frame_idx
1614                 [ReferenceFrameType::BwdRef as usize - ReferenceFrameType::Last as usize] = ref_;
1615             used_frame[ref_ as usize] = true;
1616         }
1617 
1618         let ref_ = helpers::find_earliest_backward(
1619             &shifted_order_hints,
1620             &used_frame,
1621             cur_frame_hint,
1622             &mut earliest_order_hint,
1623         );
1624 
1625         if ref_ >= 0 {
1626             ref_frame_idx
1627                 [ReferenceFrameType::AltRef2 as usize - ReferenceFrameType::Last as usize] = ref_;
1628             used_frame[ref_ as usize] = true;
1629         }
1630 
1631         const REF_FRAME_LIST: [usize; 5] = [
1632             ReferenceFrameType::Last2 as usize - ReferenceFrameType::Last as usize,
1633             ReferenceFrameType::Last3 as usize - ReferenceFrameType::Last as usize,
1634             ReferenceFrameType::BwdRef as usize - ReferenceFrameType::Last as usize,
1635             ReferenceFrameType::AltRef2 as usize - ReferenceFrameType::Last as usize,
1636             ReferenceFrameType::AltRef as usize - ReferenceFrameType::Last as usize,
1637         ];
1638 
1639         #[allow(clippy::needless_range_loop)]
1640         for i in 0..REFS_PER_FRAME - 2 {
1641             let ref_frame = REF_FRAME_LIST[i];
1642 
1643             if ref_frame_idx[ref_frame] < 0 {
1644                 let ref_ = helpers::find_latest_forward(
1645                     &shifted_order_hints,
1646                     &used_frame,
1647                     cur_frame_hint,
1648                     &mut latest_order_hint,
1649                 );
1650 
1651                 if ref_ >= 0 {
1652                     ref_frame_idx[ref_frame] = ref_;
1653                     used_frame[ref_ as usize] = true;
1654                 }
1655             }
1656         }
1657 
1658         let mut ref_ = 0;
1659         earliest_order_hint = shifted_order_hints[0];
1660         #[allow(clippy::needless_range_loop)]
1661         for i in 1..NUM_REF_FRAMES {
1662             let hint = shifted_order_hints[i];
1663             if hint < earliest_order_hint {
1664                 ref_ = i as u8;
1665                 earliest_order_hint = hint;
1666             }
1667         }
1668 
1669         fh.ref_frame_idx
1670             .iter_mut()
1671             .zip(ref_frame_idx.iter().copied())
1672             .for_each(|(dest, src)| *dest = if src < 0 { ref_ } else { src as u8 });
1673 
1674         Ok(())
1675     }
1676 
1677     // 5.9.5.
parse_frame_size(&mut self, fh: &mut FrameHeaderObu, r: &mut Reader) -> Result<(), String>1678     fn parse_frame_size(&mut self, fh: &mut FrameHeaderObu, r: &mut Reader) -> Result<(), String> {
1679         let seq = self.sequence()?;
1680         if fh.frame_size_override_flag {
1681             let n = seq.frame_width_bits_minus_1 + 1;
1682             fh.frame_width = r.0.read_bits::<u32>(n as usize)? + 1;
1683 
1684             let n = seq.frame_height_bits_minus_1 + 1;
1685             fh.frame_height = r.0.read_bits::<u32>(n as usize)? + 1;
1686         } else {
1687             fh.frame_width = seq.max_frame_width_minus_1 as u32 + 1;
1688             fh.frame_height = seq.max_frame_height_minus_1 as u32 + 1;
1689         }
1690 
1691         Self::parse_superres_params(fh, r, seq)?;
1692         self.compute_image_size(fh);
1693 
1694         Ok(())
1695     }
1696 
parse_render_size(fh: &mut FrameHeaderObu, r: &mut Reader) -> Result<(), String>1697     fn parse_render_size(fh: &mut FrameHeaderObu, r: &mut Reader) -> Result<(), String> {
1698         fh.render_and_frame_size_different = r.0.read_bit()?;
1699         if fh.render_and_frame_size_different {
1700             fh.render_width = r.0.read_bits::<u32>(16)? + 1;
1701             fh.render_height = r.0.read_bits::<u32>(16)? + 1;
1702         } else {
1703             fh.render_width = fh.upscaled_width;
1704             fh.render_height = fh.frame_height;
1705         }
1706         Ok(())
1707     }
1708 
frame_size_with_refs( &mut self, fh: &mut FrameHeaderObu, r: &mut Reader, ) -> Result<(), String>1709     fn frame_size_with_refs(
1710         &mut self,
1711         fh: &mut FrameHeaderObu,
1712         r: &mut Reader,
1713     ) -> Result<(), String> {
1714         let mut found_ref = false;
1715         let seq = self.sequence()?;
1716 
1717         for i in 0..REFS_PER_FRAME {
1718             found_ref = r.0.read_bit()?;
1719 
1720             if found_ref {
1721                 let rf = &self.ref_info[fh.ref_frame_idx[i] as usize];
1722                 fh.upscaled_width = rf.ref_upscaled_width;
1723                 fh.frame_width = fh.upscaled_width;
1724                 fh.frame_height = rf.ref_frame_height;
1725                 fh.render_width = rf.ref_render_width;
1726                 fh.render_height = rf.ref_render_height;
1727                 break;
1728             }
1729         }
1730 
1731         if !found_ref {
1732             self.parse_frame_size(fh, r)?;
1733             Self::parse_render_size(fh, r)?;
1734         } else {
1735             Self::parse_superres_params(fh, r, seq)?;
1736             self.compute_image_size(fh);
1737         }
1738 
1739         Ok(())
1740     }
1741 
1742     /// Skip the padding bits, ensuring that they actually make sense.
skip_and_check_trailing_bits(r: &mut Reader, obu: &Obu) -> Result<(), String>1743     fn skip_and_check_trailing_bits(r: &mut Reader, obu: &Obu) -> Result<(), String> {
1744         // We can't have that in parse_obu as per the spec, because the reader
1745         // is not initialized on our design at that point, so move the check to
1746         // inside this function.
1747         if obu.data.len() == 0
1748             || matches!(
1749                 obu.header.obu_type,
1750                 ObuType::TileList | ObuType::TileGroup | ObuType::Frame
1751             )
1752         {
1753             return Ok(());
1754         }
1755         let num_trailing = obu.as_ref().len() as u64 * 8 - r.0.position();
1756         r.read_trailing_bits(num_trailing)?;
1757         Ok(())
1758     }
1759 
parse_obu_header(r: &mut Reader) -> Result<ObuHeader, String>1760     fn parse_obu_header(r: &mut Reader) -> Result<ObuHeader, String> {
1761         let _obu_forbidden_bit = r.0.read_bit()?;
1762 
1763         let mut header = ObuHeader {
1764             obu_type: ObuType::try_from(r.0.read_bits::<u32>(4)?)?,
1765             extension_flag: r.0.read_bit()?,
1766             has_size_field: r.0.read_bit()?,
1767             temporal_id: Default::default(),
1768             spatial_id: Default::default(),
1769         };
1770 
1771         let obu_reserved_1bit = r.0.read_bit()?;
1772         assert!(!obu_reserved_1bit); // Must be set to zero as per spec.
1773 
1774         if header.extension_flag {
1775             header.temporal_id = r.0.read_bits::<u32>(3)?;
1776             header.spatial_id = r.0.read_bits::<u32>(2)?;
1777             let _ = r.0.read_bits::<u32>(3)?;
1778         }
1779 
1780         Ok(header)
1781     }
1782 
1783     /// Parses one OBU from `data`, which can be in Annex B or low-overhead
1784     /// format.
1785     ///
1786     /// `None` may eventually be returned if the OBU is to be dropped.
read_obu<'a>(&mut self, data: &'a [u8]) -> Result<ObuAction<'a>, String>1787     pub fn read_obu<'a>(&mut self, data: &'a [u8]) -> Result<ObuAction<'a>, String> {
1788         if data.is_empty() {
1789             return Err("Empty data".into());
1790         }
1791 
1792         let mut reader = Reader::new(data);
1793 
1794         if self.should_probe_for_annexb {
1795             // Try probing for Annex B data.
1796             self.stream_format = if matches!(Self::annexb_probe(data), Ok(true)) {
1797                 log::debug!("Parsing an Annex B stream");
1798                 StreamFormat::AnnexB(AnnexBState::default())
1799             } else {
1800                 log::debug!("Parsing a low-overhead stream");
1801                 StreamFormat::LowOverhead
1802             };
1803 
1804             self.should_probe_for_annexb = false;
1805         }
1806 
1807         let obu_length: usize = if let StreamFormat::AnnexB(annexb_state) = &mut self.stream_format
1808         {
1809             // Read the length to skip to the start of the open_bitstream_unit()
1810             // syntax element.
1811             let obu_length = reader.current_annexb_obu_length(annexb_state)?;
1812             match obu_length {
1813                 Some(length) => length,
1814                 None => return Ok(ObuAction::Drop(reader.consumed(0))),
1815             }
1816         } else {
1817             0
1818         };
1819 
1820         let start_pos = reader.consumed(0);
1821 
1822         // Both "low-overhead" and Annex B are now at the same point, i.e.: a
1823         // open_bitstream_unit() follows.
1824         let header = Self::parse_obu_header(&mut reader)?;
1825         if matches!(self.stream_format, StreamFormat::LowOverhead) {
1826             assert!(header.has_size_field);
1827         }
1828 
1829         let obu_size: usize = if header.has_size_field {
1830             reader.read_leb128()? as usize
1831         } else {
1832             /* trap any bugs when computing the final length */
1833             obu_length
1834                 .checked_sub(1)
1835                 .ok_or::<String>("obu_length must be greater than 0".into())?
1836                 .checked_sub(usize::from(header.extension_flag))
1837                 .ok_or::<String>("obu_length too short".into())?
1838         };
1839 
1840         let consumed = reader.consumed(start_pos);
1841 
1842         if let StreamFormat::AnnexB(annexb_state) = &mut self.stream_format {
1843             annexb_state.temporal_unit_consumed += consumed;
1844             annexb_state.frame_unit_consumed += consumed;
1845 
1846             annexb_state.temporal_unit_consumed += u32::try_from(obu_size).unwrap();
1847             annexb_state.frame_unit_consumed += u32::try_from(obu_size).unwrap();
1848         }
1849 
1850         assert!(reader.0.position() % 8 == 0);
1851         let start_offset: usize = (reader.0.position() / 8).try_into().unwrap();
1852 
1853         log::debug!(
1854             "Identified OBU type {:?}, data size: {}, obu_size: {}",
1855             header.obu_type,
1856             start_offset + obu_size,
1857             obu_size
1858         );
1859 
1860         if header.obu_type != ObuType::SequenceHeader
1861             && header.obu_type != ObuType::TemporalDelimiter
1862             && self.operating_point_idc != 0
1863             && header.extension_flag
1864         {
1865             let in_temporal_layer = ((self.operating_point_idc >> header.temporal_id) & 1) != 0;
1866             let in_spatial_layer = ((self.operating_point_idc >> (header.spatial_id + 8)) & 1) != 0;
1867             if !in_temporal_layer || !in_spatial_layer {
1868                 log::debug!("Dropping obu as per drop_obu() in the specification",);
1869                 return Ok(ObuAction::Drop(reader.consumed(0)));
1870             }
1871         }
1872 
1873         Ok(ObuAction::Process(Obu {
1874             header,
1875             data: Cow::from(&data[start_offset..start_offset + obu_size]),
1876             bytes_used: start_offset + obu_size,
1877         }))
1878     }
1879 
parse_color_config(s: &mut SequenceHeaderObu, r: &mut Reader) -> Result<(), String>1880     fn parse_color_config(s: &mut SequenceHeaderObu, r: &mut Reader) -> Result<(), String> {
1881         let cc = &mut s.color_config;
1882 
1883         cc.high_bitdepth = r.0.read_bit()?;
1884         if s.seq_profile as u32 == 2 && cc.high_bitdepth {
1885             cc.twelve_bit = r.0.read_bit()?;
1886             if cc.twelve_bit {
1887                 s.bit_depth = BitDepth::Depth12;
1888             } else {
1889                 s.bit_depth = BitDepth::Depth10;
1890             }
1891         } else if s.seq_profile as u32 <= 2 {
1892             s.bit_depth = if cc.high_bitdepth { BitDepth::Depth10 } else { BitDepth::Depth8 };
1893         }
1894 
1895         if s.seq_profile as u32 == 1 {
1896             cc.mono_chrome = false;
1897         } else {
1898             cc.mono_chrome = r.0.read_bit()?;
1899         }
1900 
1901         if cc.mono_chrome {
1902             s.num_planes = 1;
1903         } else {
1904             s.num_planes = 3;
1905         }
1906 
1907         cc.color_description_present_flag = r.0.read_bit()?;
1908         if cc.color_description_present_flag {
1909             cc.color_primaries = ColorPrimaries::try_from(r.0.read_bits::<u32>(8)?)?;
1910             cc.transfer_characteristics =
1911                 TransferCharacteristics::try_from(r.0.read_bits::<u32>(8)?)?;
1912             cc.matrix_coefficients = MatrixCoefficients::try_from(r.0.read_bits::<u32>(8)?)?;
1913         } else {
1914             cc.color_primaries = ColorPrimaries::Unspecified;
1915             cc.transfer_characteristics = TransferCharacteristics::Unspecified;
1916             cc.matrix_coefficients = MatrixCoefficients::Unspecified;
1917         }
1918 
1919         if cc.mono_chrome {
1920             cc.color_range = r.0.read_bit()?;
1921             cc.subsampling_x = true;
1922             cc.subsampling_y = true;
1923             cc.chroma_sample_position = ChromaSamplePosition::Unknown;
1924             cc.separate_uv_delta_q = false;
1925             return Ok(());
1926         } else if matches!(cc.color_primaries, ColorPrimaries::Bt709)
1927             && matches!(cc.transfer_characteristics, TransferCharacteristics::Srgb)
1928             && matches!(cc.matrix_coefficients, MatrixCoefficients::Identity)
1929         {
1930             cc.color_range = true;
1931             cc.subsampling_x = false;
1932             cc.subsampling_y = false;
1933         } else {
1934             cc.color_range = r.0.read_bit()?;
1935             if s.seq_profile as u32 == 0 {
1936                 cc.subsampling_x = true;
1937                 cc.subsampling_y = true;
1938             } else if s.seq_profile as u32 == 1 {
1939                 cc.subsampling_x = false;
1940                 cc.subsampling_y = false;
1941             } else if matches!(s.bit_depth, BitDepth::Depth12) {
1942                 cc.subsampling_x = r.0.read_bit()?;
1943                 if cc.subsampling_x {
1944                     cc.subsampling_y = r.0.read_bit()?;
1945                 } else {
1946                     cc.subsampling_y = false;
1947                 }
1948             } else {
1949                 cc.subsampling_x = true;
1950                 cc.subsampling_y = false;
1951             }
1952 
1953             if cc.subsampling_x && cc.subsampling_y {
1954                 cc.chroma_sample_position =
1955                     ChromaSamplePosition::try_from(r.0.read_bits::<u32>(2)?)?;
1956             }
1957         }
1958 
1959         cc.separate_uv_delta_q = r.0.read_bit()?;
1960 
1961         Ok(())
1962     }
1963 
parse_operating_parameters_info( opi: &mut OperatingPoint, r: &mut Reader, buffer_delay_length_minus_1: u8, ) -> Result<(), String>1964     fn parse_operating_parameters_info(
1965         opi: &mut OperatingPoint,
1966         r: &mut Reader,
1967         buffer_delay_length_minus_1: u8,
1968     ) -> Result<(), String> {
1969         let n = buffer_delay_length_minus_1 + 1;
1970         opi.decoder_buffer_delay = r.0.read_bits::<u32>(n as usize)?;
1971         opi.encoder_buffer_delay = r.0.read_bits::<u32>(n as usize)?;
1972         opi.low_delay_mode_flag = r.0.read_bit()?;
1973         Ok(())
1974     }
1975 
parse_decoder_model_info(dmi: &mut DecoderModelInfo, r: &mut Reader) -> Result<(), String>1976     fn parse_decoder_model_info(dmi: &mut DecoderModelInfo, r: &mut Reader) -> Result<(), String> {
1977         dmi.buffer_delay_length_minus_1 = r.0.read_bits::<u32>(5)? as u8;
1978         dmi.num_units_in_decoding_tick = r.0.read_bits::<u32>(32)?;
1979         dmi.buffer_removal_time_length_minus_1 = r.0.read_bits::<u32>(5)? as u8;
1980         dmi.frame_presentation_time_length_minus_1 = r.0.read_bits::<u32>(5)?;
1981         Ok(())
1982     }
1983 
parse_timing_info(ti: &mut TimingInfo, r: &mut Reader) -> Result<(), String>1984     fn parse_timing_info(ti: &mut TimingInfo, r: &mut Reader) -> Result<(), String> {
1985         ti.num_units_in_display_tick = r.0.read_bits::<u32>(32)?;
1986         ti.time_scale = r.0.read_bits::<u32>(32)?;
1987         ti.equal_picture_interval = r.0.read_bit()?;
1988         if ti.equal_picture_interval {
1989             ti.num_ticks_per_picture_minus_1 = r.read_uvlc()?;
1990         }
1991         Ok(())
1992     }
1993 
1994     /// Selects an operating point. Only call this after the Sequence OBU for
1995     /// which the operating point should apply has been parsed.
choose_operating_point(&mut self, operating_point: u32) -> Result<(), String>1996     pub fn choose_operating_point(&mut self, operating_point: u32) -> Result<(), String> {
1997         if operating_point > self.sequence()?.operating_points_cnt_minus_1 {
1998             return Err(format!(
1999                 "Invalid operating point {} (max {})",
2000                 operating_point,
2001                 self.sequence()?.operating_points_cnt_minus_1
2002             ));
2003         }
2004         self.operating_point = operating_point;
2005         self.operating_point_idc = self.sequence()?.operating_points[operating_point as usize].idc;
2006         Ok(())
2007     }
2008 
parse_temporal_delimiter_obu(&mut self) -> Result<(), String>2009     fn parse_temporal_delimiter_obu(&mut self) -> Result<(), String> {
2010         self.seen_frame_header = false;
2011         Ok(())
2012     }
2013 
parse_sequence_header_obu(&mut self, obu: &Obu) -> Result<Rc<SequenceHeaderObu>, String>2014     fn parse_sequence_header_obu(&mut self, obu: &Obu) -> Result<Rc<SequenceHeaderObu>, String> {
2015         let mut s = SequenceHeaderObu { obu_header: obu.header.clone(), ..Default::default() };
2016 
2017         let mut r = Reader::new(obu.as_ref());
2018         let profile = r.0.read_bits::<u32>(3)?;
2019 
2020         s.seq_profile = Profile::try_from(profile)?;
2021         s.still_picture = r.0.read_bit()?;
2022         s.reduced_still_picture_header = r.0.read_bit()?;
2023 
2024         if s.reduced_still_picture_header {
2025             /* Default::default() already ensures a lot of this, but lets go verbatim */
2026             s.timing_info_present_flag = false;
2027             s.decoder_model_info_present_flag = false;
2028             s.initial_display_delay_present_flag = false;
2029             s.operating_points_cnt_minus_1 = 0;
2030             s.operating_points[0].idc = 0;
2031             s.operating_points[0].seq_level_idx = r.0.read_bits::<u32>(5)? as u8;
2032             s.operating_points[0].seq_tier = 0;
2033             s.operating_points[0].decoder_model_present_for_this_op = false;
2034             s.operating_points[0].initial_display_delay_present_for_this_op = false;
2035         } else {
2036             s.timing_info_present_flag = r.0.read_bit()?;
2037             if s.timing_info_present_flag {
2038                 Self::parse_timing_info(&mut s.timing_info, &mut r)?;
2039                 s.decoder_model_info_present_flag = r.0.read_bit()?;
2040                 if s.decoder_model_info_present_flag {
2041                     Self::parse_decoder_model_info(&mut s.decoder_model_info, &mut r)?;
2042                 }
2043             } else {
2044                 s.decoder_model_info_present_flag = false;
2045             }
2046 
2047             s.initial_display_delay_present_flag = r.0.read_bit()?;
2048             s.operating_points_cnt_minus_1 = r.0.read_bits::<u32>(5)?;
2049             if s.operating_points_cnt_minus_1 > MAX_NUM_OPERATING_POINTS as u32 {
2050                 return Err(format!(
2051                     "Invalid operating_points_cnt_minus_1 {}",
2052                     s.operating_points_cnt_minus_1
2053                 ));
2054             }
2055 
2056             for i in 0..=s.operating_points_cnt_minus_1 as usize {
2057                 s.operating_points[i].idc = r.0.read_bits::<u32>(12)? as u16;
2058                 s.operating_points[i].seq_level_idx = r.0.read_bits::<u32>(5)? as u8;
2059                 if s.operating_points[i].seq_level_idx > 7 {
2060                     s.operating_points[i].seq_tier = r.0.read_bit()? as u8;
2061                 } else {
2062                     s.operating_points[i].seq_tier = 0;
2063                 }
2064                 if s.decoder_model_info_present_flag {
2065                     s.operating_points[i].decoder_model_present_for_this_op = r.0.read_bit()?;
2066                     if s.operating_points[i].decoder_model_present_for_this_op {
2067                         let buffer_delay_length_minus_1 =
2068                             s.decoder_model_info.buffer_delay_length_minus_1;
2069                         Self::parse_operating_parameters_info(
2070                             &mut s.operating_points[i],
2071                             &mut r,
2072                             buffer_delay_length_minus_1,
2073                         )?;
2074                     }
2075                 } else {
2076                     s.operating_points[i].decoder_model_present_for_this_op = false;
2077                 }
2078 
2079                 if s.initial_display_delay_present_flag {
2080                     s.operating_points[i].initial_display_delay_present_for_this_op =
2081                         r.0.read_bit()?;
2082                     if s.operating_points[i].initial_display_delay_present_for_this_op {
2083                         s.operating_points[i].initial_display_delay_minus_1 =
2084                             r.0.read_bits::<u32>(4)?;
2085                     }
2086                 }
2087             }
2088         }
2089 
2090         s.frame_width_bits_minus_1 = r.0.read_bits::<u32>(4)? as u8;
2091         s.frame_height_bits_minus_1 = r.0.read_bits::<u32>(4)? as u8;
2092         // frame_width_bits_minus_1 has been read from 4 bits, meaning we can read 16 bits at most.
2093         s.max_frame_width_minus_1 =
2094             r.0.read_bits::<u32>(s.frame_width_bits_minus_1 as usize + 1)? as u16;
2095         // frame_height_bits_minus_1 has been read from 4 bits, meaning we can read 16 bits at most.
2096         s.max_frame_height_minus_1 =
2097             r.0.read_bits::<u32>(s.frame_height_bits_minus_1 as usize + 1)? as u16;
2098         if s.reduced_still_picture_header {
2099             s.frame_id_numbers_present_flag = false;
2100         } else {
2101             s.frame_id_numbers_present_flag = r.0.read_bit()?;
2102         }
2103         if s.frame_id_numbers_present_flag {
2104             s.delta_frame_id_length_minus_2 = r.0.read_bits::<u32>(4)?;
2105             s.additional_frame_id_length_minus_1 = r.0.read_bits::<u32>(3)?;
2106             let frame_id_length =
2107                 s.additional_frame_id_length_minus_1 + s.delta_frame_id_length_minus_2 + 3;
2108             if frame_id_length > 16 {
2109                 return Err(format!("Invalid frame_id_length {}", frame_id_length));
2110             }
2111         }
2112 
2113         s.use_128x128_superblock = r.0.read_bit()?;
2114         s.enable_filter_intra = r.0.read_bit()?;
2115         s.enable_intra_edge_filter = r.0.read_bit()?;
2116         if s.reduced_still_picture_header {
2117             s.enable_interintra_compound = false;
2118             s.enable_masked_compound = false;
2119             s.enable_warped_motion = false;
2120             s.enable_dual_filter = false;
2121             s.enable_order_hint = false;
2122             s.enable_jnt_comp = false;
2123             s.enable_ref_frame_mvs = false;
2124             s.seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS as _;
2125             s.seq_force_integer_mv = SELECT_INTEGER_MV as _;
2126             s.order_hint_bits = 0;
2127             s.order_hint_bits_minus_1 = -1;
2128         } else {
2129             s.enable_interintra_compound = r.0.read_bit()?;
2130             s.enable_masked_compound = r.0.read_bit()?;
2131             s.enable_warped_motion = r.0.read_bit()?;
2132             s.enable_dual_filter = r.0.read_bit()?;
2133             s.enable_order_hint = r.0.read_bit()?;
2134             if s.enable_order_hint {
2135                 s.enable_jnt_comp = r.0.read_bit()?;
2136                 s.enable_ref_frame_mvs = r.0.read_bit()?;
2137             } else {
2138                 s.enable_jnt_comp = false;
2139                 s.enable_ref_frame_mvs = false;
2140             }
2141             s.seq_choose_screen_content_tools = r.0.read_bit()?;
2142             if s.seq_choose_screen_content_tools {
2143                 s.seq_force_screen_content_tools = SELECT_SCREEN_CONTENT_TOOLS as _;
2144             } else {
2145                 s.seq_force_screen_content_tools = r.0.read_bit()? as _;
2146             }
2147             if s.seq_force_screen_content_tools > 0 {
2148                 s.seq_choose_integer_mv = r.0.read_bit()?;
2149                 if s.seq_choose_integer_mv {
2150                     s.seq_force_integer_mv = SELECT_INTEGER_MV as _;
2151                 } else {
2152                     s.seq_force_integer_mv = r.0.read_bit()? as _;
2153                 }
2154             } else {
2155                 s.seq_force_integer_mv = SELECT_INTEGER_MV as _;
2156             }
2157 
2158             if s.enable_order_hint {
2159                 s.order_hint_bits_minus_1 = r.0.read_bits::<u32>(3)?.try_into().unwrap();
2160                 s.order_hint_bits = s.order_hint_bits_minus_1 + 1;
2161             } else {
2162                 s.order_hint_bits_minus_1 = -1;
2163                 s.order_hint_bits = 0;
2164             }
2165         }
2166 
2167         s.enable_superres = r.0.read_bit()?;
2168         s.enable_cdef = r.0.read_bit()?;
2169         s.enable_restoration = r.0.read_bit()?;
2170 
2171         Self::parse_color_config(&mut s, &mut r)?;
2172 
2173         s.film_grain_params_present = r.0.read_bit()?;
2174 
2175         Self::skip_and_check_trailing_bits(&mut r, obu)?;
2176         let rc = Rc::new(s);
2177         self.sequence_header = Some(rc.clone());
2178 
2179         /* Client is supposed to set the operating point through external means,
2180          * here we just set 0 as default. */
2181         self.choose_operating_point(0)?;
2182 
2183         Ok(rc)
2184     }
2185 
2186     /// Implements 7.21. Note that 7.20 will use the information from the
2187     /// header, so we must save them now, as they will not be parsed from the
2188     /// bitstream. We also save some internal parser state which will be useful
2189     /// later.
load_reference_frame(&self, fh: &mut FrameHeaderObu) -> Result<(), String>2190     fn load_reference_frame(&self, fh: &mut FrameHeaderObu) -> Result<(), String> {
2191         let rf = &self.ref_info[fh.frame_to_show_map_idx as usize];
2192 
2193         // Section 6.8.1: It is a requirement of bitstream conformance that a
2194         // sequence header OBU has been received before a frame header OBU.
2195         let seq = self.sequence()?;
2196 
2197         /* at least save the sizes and for both kf and non-kf */
2198         fh.frame_type = rf.ref_frame_type;
2199         fh.upscaled_width = rf.ref_upscaled_width;
2200         fh.frame_width = rf.ref_frame_width;
2201         fh.frame_height = rf.ref_frame_height;
2202         fh.render_width = rf.ref_render_width;
2203         fh.render_height = rf.ref_render_height;
2204 
2205         /* Save into the frame header */
2206         if fh.frame_type == FrameType::KeyFrame {
2207             fh.current_frame_id = rf.ref_frame_id;
2208             /* We don't keep track of sequence information at the frame level */
2209             fh.mi_cols = rf.ref_mi_cols;
2210             fh.mi_rows = rf.ref_mi_rows;
2211             /* The accelerator is keeping track of CDF values, so that is skipped too */
2212             fh.global_motion_params = rf.global_motion_params.clone();
2213 
2214             if seq.film_grain_params_present {
2215                 fh.film_grain_params = rf.film_grain_params.clone();
2216             }
2217             fh.loop_filter_params = rf.loop_filter_params.clone();
2218             fh.segmentation_params = rf.segmentation_params.clone();
2219         }
2220 
2221         Ok(())
2222     }
2223 
setup_past_independence(fh: &mut FrameHeaderObu)2224     fn setup_past_independence(fh: &mut FrameHeaderObu) {
2225         fh.segmentation_params.feature_enabled = Default::default();
2226         fh.segmentation_params.feature_data = Default::default();
2227 
2228         for i in ReferenceFrameType::Last as usize..ReferenceFrameType::AltRef as usize {
2229             fh.global_motion_params.gm_type[i] = WarpModelType::Identity;
2230         }
2231 
2232         fh.loop_filter_params.loop_filter_delta_enabled = true;
2233         fh.loop_filter_params.loop_filter_ref_deltas = [1, 0, 0, 0, -1, 0, -1, -1];
2234         fh.loop_filter_params.loop_filter_mode_deltas = Default::default();
2235     }
2236 
parse_tile_info(&mut self, r: &mut Reader, ti: &mut TileInfo) -> Result<(), String>2237     fn parse_tile_info(&mut self, r: &mut Reader, ti: &mut TileInfo) -> Result<(), String> {
2238         let seq = self.sequence()?;
2239 
2240         let sb_cols = if seq.use_128x128_superblock {
2241             (self.mi_cols + 31) >> 5
2242         } else {
2243             (self.mi_cols + 15) >> 4
2244         };
2245 
2246         let sb_rows = if seq.use_128x128_superblock {
2247             (self.mi_rows + 31) >> 5
2248         } else {
2249             (self.mi_rows + 15) >> 4
2250         };
2251 
2252         let sb_shift = if seq.use_128x128_superblock { 5 } else { 4 };
2253         let sb_size = sb_shift + 2;
2254 
2255         let max_tile_width_sb = MAX_TILE_WIDTH >> sb_size;
2256         let mut max_tile_area_sb = MAX_TILE_AREA >> (2 * sb_size);
2257 
2258         let min_log2_tile_cols = helpers::tile_log2(max_tile_width_sb, sb_cols);
2259 
2260         let max_log2_tile_cols =
2261             helpers::tile_log2(1, std::cmp::min(sb_cols, MAX_TILE_COLS as u32));
2262 
2263         let max_log2_tile_rows =
2264             helpers::tile_log2(1, std::cmp::min(sb_rows, MAX_TILE_ROWS as u32));
2265 
2266         let min_log2_tiles = std::cmp::max(
2267             min_log2_tile_cols,
2268             helpers::tile_log2(max_tile_area_sb, sb_rows * sb_cols),
2269         );
2270 
2271         ti.uniform_tile_spacing_flag = r.0.read_bit()?;
2272 
2273         if ti.uniform_tile_spacing_flag {
2274             self.tile_cols_log2 = min_log2_tile_cols;
2275             while self.tile_cols_log2 < max_log2_tile_cols {
2276                 let increment_tile_cols_log_2 = r.0.read_bit()?;
2277                 if increment_tile_cols_log_2 {
2278                     self.tile_cols_log2 += 1;
2279                 } else {
2280                     break;
2281                 }
2282             }
2283 
2284             let tile_width_sb = (sb_cols + (1 << self.tile_cols_log2) - 1) >> self.tile_cols_log2;
2285 
2286             let mut i = 0;
2287             let mut start_sb = 0;
2288 
2289             while start_sb < sb_cols {
2290                 self.mi_col_starts[i] = start_sb << sb_shift;
2291                 i += 1;
2292                 start_sb += tile_width_sb;
2293             }
2294 
2295             self.mi_col_starts[i] = self.mi_cols;
2296             self.tile_cols = i as _;
2297 
2298             if self.tile_cols > MAX_TILE_COLS as u32 {
2299                 return Err(format!("Invalid tile_cols {}", self.tile_cols));
2300             }
2301 
2302             /* compute this anyways */
2303             while i >= 1 {
2304                 ti.width_in_sbs_minus_1[i - 1] =
2305                     ((self.mi_col_starts[i] - self.mi_col_starts[i - 1] + ((1 << sb_shift) - 1))
2306                         >> sb_shift)
2307                         - 1;
2308                 i -= 1;
2309             }
2310 
2311             let min_log2_tile_rows =
2312                 std::cmp::max(min_log2_tiles.saturating_sub(self.tile_cols_log2), 0);
2313             self.tile_rows_log2 = min_log2_tile_rows;
2314 
2315             while self.tile_rows_log2 < max_log2_tile_rows {
2316                 let increment_tile_rows_log_2 = r.0.read_bit()?;
2317 
2318                 if increment_tile_rows_log_2 {
2319                     self.tile_rows_log2 += 1;
2320                 } else {
2321                     break;
2322                 }
2323             }
2324 
2325             let tile_height_sb = (sb_rows + (1 << self.tile_rows_log2) - 1) >> self.tile_rows_log2;
2326 
2327             let mut i = 0;
2328             let mut start_sb = 0;
2329 
2330             while start_sb < sb_rows {
2331                 self.mi_row_starts[i] = start_sb << sb_shift;
2332                 i += 1;
2333                 start_sb += tile_height_sb;
2334             }
2335 
2336             self.mi_row_starts[i] = self.mi_rows;
2337             self.tile_rows = i as _;
2338 
2339             if self.tile_rows > MAX_TILE_ROWS as u32 {
2340                 return Err(format!("Invalid tile_rows {}", self.tile_cols));
2341             }
2342 
2343             /* compute this anyways */
2344             while i >= 1 {
2345                 ti.height_in_sbs_minus_1[i - 1] =
2346                     ((self.mi_row_starts[i] - self.mi_row_starts[i - 1] + ((1 << sb_shift) - 1))
2347                         >> sb_shift)
2348                         - 1;
2349                 i -= 1;
2350             }
2351         } else {
2352             let mut widest_tile_sb = 0;
2353             let mut start_sb = 0;
2354             let mut i = 0;
2355 
2356             while start_sb < sb_cols {
2357                 self.mi_col_starts[i] = start_sb << sb_shift;
2358 
2359                 let max_width = std::cmp::min(sb_cols - start_sb, max_tile_width_sb);
2360                 ti.width_in_sbs_minus_1[i] = r.read_ns(max_width.try_into().unwrap())?;
2361 
2362                 let size_sb = ti.width_in_sbs_minus_1[i] + 1;
2363                 widest_tile_sb = std::cmp::max(size_sb, widest_tile_sb);
2364 
2365                 start_sb += size_sb;
2366                 i += 1;
2367             }
2368 
2369             self.mi_col_starts[i] = self.mi_cols;
2370             self.tile_cols = i as _;
2371             self.tile_cols_log2 = helpers::tile_log2(1, self.tile_cols);
2372 
2373             if min_log2_tiles > 0 {
2374                 max_tile_area_sb = (sb_rows * sb_cols) >> (min_log2_tiles + 1);
2375             } else {
2376                 max_tile_area_sb = sb_rows * sb_cols;
2377             }
2378 
2379             let max_tile_height_sb = std::cmp::max(max_tile_area_sb / widest_tile_sb, 1);
2380             let mut start_sb = 0;
2381             let mut i = 0;
2382             while start_sb < sb_rows {
2383                 self.mi_row_starts[i] = start_sb << sb_shift;
2384                 let max_height = std::cmp::min(sb_rows - start_sb, max_tile_height_sb);
2385                 ti.height_in_sbs_minus_1[i] = r.read_ns(max_height.try_into().unwrap())?;
2386 
2387                 let size_sb = ti.height_in_sbs_minus_1[i] + 1;
2388                 start_sb += size_sb;
2389                 i += 1;
2390             }
2391 
2392             self.mi_row_starts[i] = self.mi_rows;
2393             self.tile_rows = i as _;
2394             self.tile_rows_log2 = helpers::tile_log2(1, self.tile_rows);
2395         }
2396 
2397         if self.tile_cols_log2 > 0 || self.tile_rows_log2 > 0 {
2398             let num_bits: usize = (self.tile_rows_log2 + self.tile_cols_log2).try_into().unwrap();
2399             ti.context_update_tile_id = r.0.read_bits::<u32>(num_bits)?;
2400 
2401             if ti.context_update_tile_id >= self.tile_rows * self.tile_cols {
2402                 return Err(format!(
2403                     "Invalid context_update_tile_id {}",
2404                     ti.context_update_tile_id
2405                 ));
2406             }
2407             self.tile_size_bytes = r.0.read_bits::<u32>(2)? + 1;
2408         } else {
2409             ti.context_update_tile_id = 0;
2410         }
2411 
2412         ti.mi_col_starts = self.mi_col_starts;
2413         ti.mi_row_starts = self.mi_row_starts;
2414         ti.tile_cols_log2 = self.tile_cols_log2;
2415         ti.tile_cols = self.tile_cols;
2416         ti.tile_rows_log2 = self.tile_rows_log2;
2417         ti.tile_rows = self.tile_rows;
2418         ti.tile_size_bytes = self.tile_size_bytes;
2419 
2420         Ok(())
2421     }
2422 
parse_quantization_params( r: &mut Reader, q: &mut QuantizationParams, num_planes: u32, separate_uv_delta_q: bool, ) -> Result<(), String>2423     fn parse_quantization_params(
2424         r: &mut Reader,
2425         q: &mut QuantizationParams,
2426         num_planes: u32,
2427         separate_uv_delta_q: bool,
2428     ) -> Result<(), String> {
2429         q.base_q_idx = r.0.read_bits::<u32>(8)?;
2430         q.delta_q_y_dc = r.read_delta_q()?;
2431         if num_planes > 1 {
2432             if separate_uv_delta_q {
2433                 q.diff_uv_delta = r.0.read_bit()?;
2434             } else {
2435                 q.diff_uv_delta = false;
2436             }
2437 
2438             q.delta_q_u_dc = r.read_delta_q()?;
2439             q.delta_q_u_ac = r.read_delta_q()?;
2440             if q.diff_uv_delta {
2441                 q.delta_q_v_dc = r.read_delta_q()?;
2442                 q.delta_q_v_ac = r.read_delta_q()?;
2443             } else {
2444                 q.delta_q_v_dc = q.delta_q_u_dc;
2445                 q.delta_q_v_ac = q.delta_q_u_ac;
2446             }
2447         } else {
2448             q.delta_q_u_dc = 0;
2449             q.delta_q_u_ac = 0;
2450             q.delta_q_v_dc = 0;
2451             q.delta_q_v_ac = 0;
2452         }
2453 
2454         q.using_qmatrix = r.0.read_bit()?;
2455         if q.using_qmatrix {
2456             q.qm_y = r.0.read_bits::<u32>(4)?;
2457             q.qm_u = r.0.read_bits::<u32>(4)?;
2458             if !separate_uv_delta_q {
2459                 q.qm_v = q.qm_u;
2460             } else {
2461                 q.qm_v = r.0.read_bits::<u32>(4)?;
2462             }
2463         }
2464         Ok(())
2465     }
2466 
parse_delta_q_params(r: &mut Reader, q: &mut QuantizationParams) -> Result<(), String>2467     fn parse_delta_q_params(r: &mut Reader, q: &mut QuantizationParams) -> Result<(), String> {
2468         q.delta_q_res = 0;
2469         q.delta_q_present = false;
2470         if q.base_q_idx > 0 {
2471             q.delta_q_present = r.0.read_bit()?;
2472         }
2473         if q.delta_q_present {
2474             q.delta_q_res = r.0.read_bits::<u32>(2)?;
2475         }
2476 
2477         Ok(())
2478     }
2479 
parse_delta_lf_params( r: &mut Reader, lf: &mut LoopFilterParams, delta_q_present: bool, allow_intrabc: bool, ) -> Result<(), String>2480     fn parse_delta_lf_params(
2481         r: &mut Reader,
2482         lf: &mut LoopFilterParams,
2483         delta_q_present: bool,
2484         allow_intrabc: bool,
2485     ) -> Result<(), String> {
2486         lf.delta_lf_present = false;
2487         lf.delta_lf_res = 0;
2488         lf.delta_lf_multi = false;
2489         if delta_q_present {
2490             if !allow_intrabc {
2491                 lf.delta_lf_present = r.0.read_bit()?;
2492             }
2493             if lf.delta_lf_present {
2494                 lf.delta_lf_res = r.0.read_bits::<u32>(2)? as u8;
2495                 lf.delta_lf_multi = r.0.read_bit()?;
2496             }
2497         }
2498         Ok(())
2499     }
2500 
parse_segmentation_params( &self, r: &mut Reader, fh: &mut FrameHeaderObu, ) -> Result<(), String>2501     fn parse_segmentation_params(
2502         &self,
2503         r: &mut Reader,
2504         fh: &mut FrameHeaderObu,
2505     ) -> Result<(), String> {
2506         let s = &mut fh.segmentation_params;
2507         s.segmentation_enabled = r.0.read_bit()?;
2508         if s.segmentation_enabled {
2509             if fh.primary_ref_frame == PRIMARY_REF_NONE {
2510                 s.segmentation_update_map = true;
2511                 s.segmentation_temporal_update = false;
2512                 s.segmentation_update_data = true;
2513             } else {
2514                 s.segmentation_update_map = r.0.read_bit()?;
2515                 if s.segmentation_update_map {
2516                     s.segmentation_temporal_update = r.0.read_bit()?;
2517                 }
2518                 s.segmentation_update_data = r.0.read_bit()?;
2519             }
2520             if s.segmentation_update_data {
2521                 for i in 0..MAX_SEGMENTS {
2522                     for j in 0..SEG_LVL_MAX {
2523                         let feature_enabled = r.0.read_bit()?;
2524                         s.feature_enabled[i][j] = feature_enabled;
2525                         if feature_enabled {
2526                             let bits_to_read = FEATURE_BITS[j];
2527                             let limit = FEATURE_MAX[j];
2528                             let signed = FEATURE_SIGNED[j];
2529 
2530                             if signed {
2531                                 let feature_value = r.read_su(1 + bits_to_read as usize)?;
2532                                 let clipped_value = helpers::clip3(-limit, limit, feature_value);
2533                                 s.feature_data[i][j] = clipped_value as _;
2534                             } else {
2535                                 let feature_value = r.0.read_bits::<u32>(bits_to_read as usize)?;
2536                                 let clipped_value = helpers::clip3(
2537                                     0,
2538                                     limit,
2539                                     feature_value
2540                                         .try_into()
2541                                         .map_err(|_| "Invalid feature_value")?,
2542                                 );
2543                                 s.feature_data[i][j] = clipped_value as _;
2544                             }
2545                         }
2546                     }
2547                 }
2548             } else {
2549                 /* copy from prev_frame */
2550                 let prev_frame =
2551                     &self.ref_info[fh.ref_frame_idx[fh.primary_ref_frame as usize] as usize];
2552 
2553                 if !prev_frame.ref_valid {
2554                     return Err("Reference is invalid".into());
2555                 }
2556 
2557                 s.feature_enabled = prev_frame.segmentation_params.feature_enabled;
2558                 s.feature_data = prev_frame.segmentation_params.feature_data;
2559             }
2560         } else {
2561             for i in 0..MAX_SEGMENTS {
2562                 for j in 0..SEG_LVL_MAX {
2563                     s.feature_enabled[i][j] = false;
2564                     s.feature_data[i][j] = 0;
2565                 }
2566             }
2567         }
2568 
2569         s.seg_id_pre_skip = false;
2570         s.last_active_seg_id = 0;
2571         for i in 0..MAX_SEGMENTS {
2572             for j in 0..SEG_LVL_MAX {
2573                 if s.feature_enabled[i][j] {
2574                     s.last_active_seg_id = i as u8;
2575                     if j >= SEG_LVL_REF_FRAME {
2576                         s.seg_id_pre_skip = true;
2577                     }
2578                 }
2579             }
2580         }
2581 
2582         Ok(())
2583     }
2584 
parse_loop_filter_parameters( r: &mut Reader, fh: &mut FrameHeaderObu, num_planes: u32, ) -> Result<(), String>2585     fn parse_loop_filter_parameters(
2586         r: &mut Reader,
2587         fh: &mut FrameHeaderObu,
2588         num_planes: u32,
2589     ) -> Result<(), String> {
2590         let lf = &mut fh.loop_filter_params;
2591         if fh.coded_lossless || fh.allow_intrabc {
2592             lf.loop_filter_level[0] = 0;
2593             lf.loop_filter_level[1] = 0;
2594             lf.loop_filter_ref_deltas = [1, 0, 0, 0, -1, 0, -1, -1];
2595 
2596             lf.loop_filter_mode_deltas = Default::default();
2597 
2598             return Ok(());
2599         }
2600 
2601         lf.loop_filter_level[0] = r.0.read_bits::<u32>(6)? as u8;
2602         lf.loop_filter_level[1] = r.0.read_bits::<u32>(6)? as u8;
2603         if num_planes > 1 && (lf.loop_filter_level[0] > 0 || lf.loop_filter_level[1] > 0) {
2604             lf.loop_filter_level[2] = r.0.read_bits::<u32>(6)? as u8;
2605             lf.loop_filter_level[3] = r.0.read_bits::<u32>(6)? as u8;
2606         }
2607 
2608         lf.loop_filter_sharpness = r.0.read_bits::<u32>(3)? as u8;
2609         lf.loop_filter_delta_enabled = r.0.read_bit()?;
2610         if lf.loop_filter_delta_enabled {
2611             lf.loop_filter_delta_update = r.0.read_bit()?;
2612             if lf.loop_filter_delta_update {
2613                 for i in 0..TOTAL_REFS_PER_FRAME {
2614                     let update_ref_delta = r.0.read_bit()?;
2615                     if update_ref_delta {
2616                         lf.loop_filter_ref_deltas[i] = r.read_su(7)? as i8;
2617                     }
2618                 }
2619 
2620                 for i in 0..2 {
2621                     let update_mode_delta = r.0.read_bit()?;
2622                     if update_mode_delta {
2623                         lf.loop_filter_mode_deltas[i] = r.read_su(7)? as i8;
2624                     }
2625                 }
2626             }
2627         }
2628 
2629         Ok(())
2630     }
2631 
parse_cdef_params( r: &mut Reader, fh: &mut FrameHeaderObu, enable_cdef: bool, num_planes: u32, ) -> Result<(), String>2632     fn parse_cdef_params(
2633         r: &mut Reader,
2634         fh: &mut FrameHeaderObu,
2635         enable_cdef: bool,
2636         num_planes: u32,
2637     ) -> Result<(), String> {
2638         let cdef = &mut fh.cdef_params;
2639 
2640         if fh.coded_lossless || fh.allow_intrabc || !enable_cdef {
2641             cdef.cdef_bits = 0;
2642             cdef.cdef_y_pri_strength[0] = 0;
2643             cdef.cdef_y_sec_strength[0] = 0;
2644             cdef.cdef_uv_pri_strength[0] = 0;
2645             cdef.cdef_uv_sec_strength[0] = 0;
2646             cdef.cdef_damping = 3;
2647             return Ok(());
2648         }
2649 
2650         cdef.cdef_damping = r.0.read_bits::<u32>(2)? + 3;
2651         cdef.cdef_bits = r.0.read_bits::<u32>(2)?;
2652         for i in 0..(1 << cdef.cdef_bits) as usize {
2653             cdef.cdef_y_pri_strength[i] = r.0.read_bits::<u32>(4)?;
2654             cdef.cdef_y_sec_strength[i] = r.0.read_bits::<u32>(2)?;
2655             if cdef.cdef_y_sec_strength[i] == 3 {
2656                 cdef.cdef_y_sec_strength[i] += 1;
2657             }
2658             if num_planes > 1 {
2659                 cdef.cdef_uv_pri_strength[i] = r.0.read_bits::<u32>(4)?;
2660                 cdef.cdef_uv_sec_strength[i] = r.0.read_bits::<u32>(2)?;
2661                 if cdef.cdef_uv_sec_strength[i] == 3 {
2662                     cdef.cdef_uv_sec_strength[i] += 1;
2663                 }
2664             }
2665         }
2666 
2667         Ok(())
2668     }
2669 
parse_loop_restoration_params( r: &mut Reader, fh: &mut FrameHeaderObu, enable_restoration: bool, num_planes: u32, use_128x128_superblock: bool, subsampling_x: bool, subsampling_y: bool, ) -> Result<(), String>2670     fn parse_loop_restoration_params(
2671         r: &mut Reader,
2672         fh: &mut FrameHeaderObu,
2673         enable_restoration: bool,
2674         num_planes: u32,
2675         use_128x128_superblock: bool,
2676         subsampling_x: bool,
2677         subsampling_y: bool,
2678     ) -> Result<(), String> {
2679         let lr = &mut fh.loop_restoration_params;
2680 
2681         if fh.all_lossless || fh.allow_intrabc || !enable_restoration {
2682             lr.frame_restoration_type[0] = FrameRestorationType::None;
2683             lr.frame_restoration_type[1] = FrameRestorationType::None;
2684             lr.frame_restoration_type[2] = FrameRestorationType::None;
2685             lr.uses_lr = false;
2686             return Ok(());
2687         }
2688 
2689         lr.uses_lr = false;
2690         lr.uses_chroma_lr = false;
2691 
2692         const REMAP_LR_TYPE: [FrameRestorationType; 4] = [
2693             FrameRestorationType::None,
2694             FrameRestorationType::Switchable,
2695             FrameRestorationType::Wiener,
2696             FrameRestorationType::Sgrproj,
2697         ];
2698 
2699         for i in 0..num_planes as usize {
2700             let lr_type = r.0.read_bits::<u32>(2)?;
2701             lr.frame_restoration_type[i] = REMAP_LR_TYPE[lr_type as usize];
2702             if lr.frame_restoration_type[i] != FrameRestorationType::None {
2703                 lr.uses_lr = true;
2704                 if i > 0 {
2705                     lr.uses_chroma_lr = true;
2706                 }
2707             }
2708         }
2709 
2710         if lr.uses_lr {
2711             if use_128x128_superblock {
2712                 lr.lr_unit_shift = r.0.read_bits::<u32>(1)? as u8 + 1;
2713             } else {
2714                 lr.lr_unit_shift = r.0.read_bits::<u32>(1)? as u8;
2715                 if lr.lr_unit_shift > 0 {
2716                     lr.lr_unit_shift += r.0.read_bits::<u32>(1)? as u8;
2717                 }
2718             }
2719 
2720             lr.loop_restoration_size[0] = RESTORATION_TILESIZE_MAX >> (2 - lr.lr_unit_shift);
2721             if subsampling_x && subsampling_y && lr.uses_chroma_lr {
2722                 lr.lr_uv_shift = r.0.read_bits::<u32>(1)? as u8;
2723             } else {
2724                 lr.lr_uv_shift = 0;
2725             }
2726 
2727             lr.loop_restoration_size[1] = lr.loop_restoration_size[0] >> lr.lr_uv_shift;
2728             lr.loop_restoration_size[2] = lr.loop_restoration_size[0] >> lr.lr_uv_shift;
2729         }
2730 
2731         Ok(())
2732     }
2733 
read_tx_mode(r: &mut Reader, fh: &mut FrameHeaderObu) -> Result<(), String>2734     fn read_tx_mode(r: &mut Reader, fh: &mut FrameHeaderObu) -> Result<(), String> {
2735         if fh.coded_lossless {
2736             fh.tx_mode = TxMode::Only4x4;
2737         } else {
2738             let tx_mode_select = r.0.read_bit()?;
2739 
2740             if tx_mode_select {
2741                 fh.tx_mode = TxMode::Select;
2742             } else {
2743                 fh.tx_mode = TxMode::Largest;
2744             }
2745         }
2746 
2747         Ok(())
2748     }
2749 
parse_skip_mode_params( &self, r: &mut Reader, fh: &mut FrameHeaderObu, enable_order_hint: bool, order_hint_bits: i32, ) -> Result<(), String>2750     fn parse_skip_mode_params(
2751         &self,
2752         r: &mut Reader,
2753         fh: &mut FrameHeaderObu,
2754         enable_order_hint: bool,
2755         order_hint_bits: i32,
2756     ) -> Result<(), String> {
2757         let skip_mode_allowed;
2758 
2759         if fh.frame_is_intra || !fh.reference_select || !enable_order_hint {
2760             skip_mode_allowed = false;
2761         } else {
2762             let mut forward_idx = -1;
2763             let mut backward_idx = -1;
2764             let mut forward_hint = 0;
2765             let mut backward_hint = 0;
2766             for i in 0..REFS_PER_FRAME {
2767                 let ref_hint = self.ref_info[fh.ref_frame_idx[i] as usize].ref_order_hint;
2768                 if helpers::get_relative_dist(
2769                     enable_order_hint,
2770                     order_hint_bits,
2771                     ref_hint.try_into().unwrap(),
2772                     fh.order_hint.try_into().unwrap(),
2773                 ) < 0
2774                     && (forward_idx < 0
2775                         || helpers::get_relative_dist(
2776                             enable_order_hint,
2777                             order_hint_bits,
2778                             ref_hint.try_into().unwrap(),
2779                             forward_hint,
2780                         ) > 0)
2781                 {
2782                     forward_idx = i32::try_from(i).unwrap();
2783                     forward_hint = ref_hint.try_into().unwrap();
2784                 } else if helpers::get_relative_dist(
2785                     enable_order_hint,
2786                     order_hint_bits,
2787                     ref_hint.try_into().unwrap(),
2788                     fh.order_hint.try_into().unwrap(),
2789                 ) > 0
2790                     && (backward_idx < 0 || {
2791                         helpers::get_relative_dist(
2792                             enable_order_hint,
2793                             order_hint_bits,
2794                             ref_hint.try_into().unwrap(),
2795                             backward_hint,
2796                         ) < 0
2797                     })
2798                 {
2799                     backward_idx = i32::try_from(i).unwrap();
2800                     backward_hint = ref_hint.try_into().unwrap();
2801                 }
2802             }
2803 
2804             if forward_idx < 0 {
2805                 skip_mode_allowed = false;
2806             } else if backward_idx >= 0 {
2807                 skip_mode_allowed = true;
2808                 fh.skip_mode_frame[0] = ReferenceFrameType::Last as u32
2809                     + u32::try_from(std::cmp::min(forward_idx, backward_idx)).unwrap();
2810                 fh.skip_mode_frame[1] = ReferenceFrameType::Last as u32
2811                     + u32::try_from(std::cmp::max(forward_idx, backward_idx)).unwrap();
2812             } else {
2813                 let mut second_forward_idx = -1;
2814                 let mut second_forward_hint = 0;
2815                 for i in 0..REFS_PER_FRAME {
2816                     let ref_hint = self.ref_info[fh.ref_frame_idx[i] as usize].ref_order_hint;
2817                     if helpers::get_relative_dist(
2818                         enable_order_hint,
2819                         order_hint_bits,
2820                         ref_hint.try_into().unwrap(),
2821                         forward_hint,
2822                     ) < 0
2823                         && (second_forward_idx < 0
2824                             || helpers::get_relative_dist(
2825                                 enable_order_hint,
2826                                 order_hint_bits,
2827                                 ref_hint.try_into().unwrap(),
2828                                 second_forward_hint,
2829                             ) > 0)
2830                     {
2831                         second_forward_idx = i32::try_from(i).unwrap();
2832                         second_forward_hint = ref_hint.try_into().unwrap();
2833                     }
2834                 }
2835 
2836                 if second_forward_idx < 0 {
2837                     skip_mode_allowed = false;
2838                 } else {
2839                     skip_mode_allowed = true;
2840                     fh.skip_mode_frame[0] = ReferenceFrameType::Last as u32
2841                         + u32::try_from(std::cmp::min(forward_idx, second_forward_idx)).unwrap();
2842                     fh.skip_mode_frame[1] = ReferenceFrameType::Last as u32
2843                         + u32::try_from(std::cmp::max(forward_idx, second_forward_idx)).unwrap();
2844                 }
2845             }
2846         }
2847 
2848         if skip_mode_allowed {
2849             fh.skip_mode_present = r.0.read_bit()?;
2850         } else {
2851             fh.skip_mode_present = false;
2852         }
2853 
2854         Ok(())
2855     }
2856 
parse_frame_reference_mode(r: &mut Reader, fh: &mut FrameHeaderObu) -> Result<(), String>2857     fn parse_frame_reference_mode(r: &mut Reader, fh: &mut FrameHeaderObu) -> Result<(), String> {
2858         if fh.frame_is_intra {
2859             fh.reference_select = false;
2860         } else {
2861             fh.reference_select = r.0.read_bit()?;
2862         }
2863         Ok(())
2864     }
2865 
seg_feature_active_idx(seg: &SegmentationParams, idx: u32, feature: u32) -> bool2866     fn seg_feature_active_idx(seg: &SegmentationParams, idx: u32, feature: u32) -> bool {
2867         seg.segmentation_enabled && seg.feature_enabled[idx as usize][feature as usize]
2868     }
2869 
get_qindex(fh: &FrameHeaderObu, ignore_deltaq: bool, segment_id: u32) -> i322870     fn get_qindex(fh: &FrameHeaderObu, ignore_deltaq: bool, segment_id: u32) -> i32 {
2871         let base_q_idx = i32::try_from(fh.quantization_params.base_q_idx).unwrap();
2872         if Self::seg_feature_active_idx(&fh.segmentation_params, segment_id, SEG_LVL_ALT_Q as u32) {
2873             let data = fh.segmentation_params.feature_data[segment_id as usize][SEG_LVL_ALT_Q];
2874             let mut qindex = base_q_idx + i32::from(data);
2875             if !ignore_deltaq && fh.quantization_params.delta_q_present {
2876                 qindex += i32::try_from(fh.quantization_params.delta_q_res).unwrap();
2877             }
2878             helpers::clip3(0, 255, qindex)
2879         } else {
2880             base_q_idx
2881         }
2882     }
2883 
setup_shear(warp_params: &[i32; 6]) -> Result<bool, String>2884     fn setup_shear(warp_params: &[i32; 6]) -> Result<bool, String> {
2885         let mut default = true;
2886         for (i, param) in warp_params.iter().enumerate() {
2887             let default_value = if i % 3 == 2 { 1 << WARPEDMODEL_PREC_BITS } else { 0 };
2888             if *param != default_value {
2889                 default = false;
2890                 break;
2891             }
2892         }
2893 
2894         /* assume the default params to be valid */
2895         if default {
2896             return Ok(true);
2897         }
2898 
2899         let alpha0 = helpers::clip3(-32768, 32767, warp_params[2] - (1 << WARPEDMODEL_PREC_BITS));
2900         let beta0 = helpers::clip3(-32768, 32767, warp_params[3]);
2901 
2902         let (div_shift, div_factor) = helpers::resolve_divisor(warp_params[2])?;
2903 
2904         let v = i64::from(warp_params[4] << WARPEDMODEL_PREC_BITS);
2905         let v = (v * i64::from(div_factor)) as i32;
2906         let gamma0 = helpers::clip3(-32678, 32767, helpers::round2signed(v, div_shift)?);
2907 
2908         let w = warp_params[3] * warp_params[4];
2909 
2910         let delta0 = helpers::clip3(
2911             -32768,
2912             32767,
2913             warp_params[5]
2914                 - helpers::round2signed(w * div_factor, div_shift)?
2915                 - (1 << WARPEDMODEL_PREC_BITS),
2916         );
2917 
2918         let alpha =
2919             helpers::round2signed(alpha0, WARP_PARAM_REDUCE_BITS)? << WARP_PARAM_REDUCE_BITS;
2920         let beta = helpers::round2signed(beta0, WARP_PARAM_REDUCE_BITS)? << WARP_PARAM_REDUCE_BITS;
2921         let gamma =
2922             helpers::round2signed(gamma0, WARP_PARAM_REDUCE_BITS)? << WARP_PARAM_REDUCE_BITS;
2923         let delta =
2924             helpers::round2signed(delta0, WARP_PARAM_REDUCE_BITS)? << WARP_PARAM_REDUCE_BITS;
2925 
2926         #[allow(clippy::needless_bool)]
2927         let warp_valid = if 4 * alpha.abs() + 7 * beta.abs() >= (1 << WARPEDMODEL_PREC_BITS)
2928             || 4 * gamma.abs() + 4 * delta.abs() >= (1 << WARPEDMODEL_PREC_BITS)
2929         {
2930             false
2931         } else {
2932             true
2933         };
2934 
2935         Ok(warp_valid)
2936     }
2937 
read_global_param( reader: &mut Reader, type_: WarpModelType, ref_frame: usize, idx: usize, allow_high_precision_mv: bool, prev_gm_params: &[[i32; 6]; NUM_REF_FRAMES], gm_params: &mut [[i32; 6]; NUM_REF_FRAMES], ) -> Result<(), String>2938     fn read_global_param(
2939         reader: &mut Reader,
2940         type_: WarpModelType,
2941         ref_frame: usize,
2942         idx: usize,
2943         allow_high_precision_mv: bool,
2944         prev_gm_params: &[[i32; 6]; NUM_REF_FRAMES],
2945         gm_params: &mut [[i32; 6]; NUM_REF_FRAMES],
2946     ) -> Result<(), String> {
2947         let mut abs_bits = GM_ABS_ALPHA_BITS;
2948         let mut prec_bits = GM_ALPHA_PREC_BITS;
2949         if idx < 2 {
2950             if type_ == WarpModelType::Translation {
2951                 abs_bits = GM_ABS_TRANS_ONLY_BITS - !allow_high_precision_mv as u32;
2952                 prec_bits = GM_TRANS_ONLY_PREC_BITS - !allow_high_precision_mv as u32;
2953             } else {
2954                 abs_bits = GM_ABS_TRANS_BITS;
2955                 prec_bits = GM_TRANS_PREC_BITS;
2956             }
2957         }
2958 
2959         let prec_diff = WARPEDMODEL_PREC_BITS - prec_bits;
2960 
2961         let (round, sub) =
2962             if (idx % 3) == 2 { (1 << WARPEDMODEL_PREC_BITS, 1 << prec_bits) } else { (0, 0) };
2963 
2964         let mx = 1 << abs_bits;
2965         let r = (prev_gm_params[ref_frame][idx] >> prec_diff) - sub;
2966         gm_params[ref_frame][idx] =
2967             (reader.decode_signed_subexp_with_ref(-mx, mx + 1, r)? << prec_diff) + round;
2968 
2969         Ok(())
2970     }
2971 
parse_global_motion_params( &mut self, r: &mut Reader, fh: &mut FrameHeaderObu, ) -> Result<(), String>2972     fn parse_global_motion_params(
2973         &mut self,
2974         r: &mut Reader,
2975         fh: &mut FrameHeaderObu,
2976     ) -> Result<(), String> {
2977         let gm = &mut fh.global_motion_params;
2978         let mut type_;
2979         let mut prev_gm_params: [[i32; 6]; NUM_REF_FRAMES] = Default::default();
2980 
2981         for ref_frame in ReferenceFrameType::Last as usize..=ReferenceFrameType::AltRef as usize {
2982             gm.gm_type[ref_frame] = WarpModelType::Identity;
2983             for i in 0..6 {
2984                 gm.gm_params[ref_frame][i] = if i % 3 == 2 { 1 << WARPEDMODEL_PREC_BITS } else { 0 }
2985             }
2986             gm.warp_valid[ref_frame] = true;
2987         }
2988 
2989         if fh.frame_is_intra {
2990             return Ok(());
2991         }
2992 
2993         // Following libgav1: implement part of setup_past_independence() and
2994         // load_previous(), i.e.: the parts that refer to the global motion
2995         // parameters.
2996         if fh.primary_ref_frame == PRIMARY_REF_NONE {
2997             // setup_past_independence()
2998             #[allow(clippy::needless_range_loop)]
2999             for ref_frame in ReferenceFrameType::Last as usize..ReferenceFrameType::AltRef as usize
3000             {
3001                 for i in 0..5 {
3002                     prev_gm_params[ref_frame][i] =
3003                         if i % 3 == 2 { 1 << WARPEDMODEL_PREC_BITS } else { 0 }
3004                 }
3005             }
3006         } else {
3007             // load_previous():
3008             // 1. The variable prevFrame is set equal to ref_frame_idx[ primary_ref_frame ].
3009             // 2. PrevGmParams is set equal to SavedGmParams[ prevFrame ].
3010             let prev_frame = fh.ref_frame_idx[fh.primary_ref_frame as usize];
3011             prev_gm_params = self.ref_info[prev_frame as usize].global_motion_params.gm_params;
3012         }
3013 
3014         for ref_frame in ReferenceFrameType::Last as usize..=ReferenceFrameType::AltRef as usize {
3015             gm.is_global[ref_frame] = r.0.read_bit()?;
3016             if gm.is_global[ref_frame] {
3017                 gm.is_rot_zoom[ref_frame] = r.0.read_bit()?;
3018                 if gm.is_rot_zoom[ref_frame] {
3019                     type_ = WarpModelType::RotZoom;
3020                 } else {
3021                     gm.is_translation[ref_frame] = r.0.read_bit()?;
3022                     if gm.is_translation[ref_frame] {
3023                         type_ = WarpModelType::Translation;
3024                     } else {
3025                         type_ = WarpModelType::Affine;
3026                     }
3027                 }
3028             } else {
3029                 type_ = WarpModelType::Identity;
3030             }
3031 
3032             gm.gm_type[ref_frame] = type_;
3033             if gm.gm_type[ref_frame] as u32 >= WarpModelType::RotZoom as u32 {
3034                 Self::read_global_param(
3035                     r,
3036                     type_,
3037                     ref_frame,
3038                     2,
3039                     fh.allow_high_precision_mv,
3040                     &prev_gm_params,
3041                     &mut gm.gm_params,
3042                 )?;
3043 
3044                 Self::read_global_param(
3045                     r,
3046                     type_,
3047                     ref_frame,
3048                     3,
3049                     fh.allow_high_precision_mv,
3050                     &prev_gm_params,
3051                     &mut gm.gm_params,
3052                 )?;
3053 
3054                 if type_ == WarpModelType::Affine {
3055                     Self::read_global_param(
3056                         r,
3057                         type_,
3058                         ref_frame,
3059                         4,
3060                         fh.allow_high_precision_mv,
3061                         &prev_gm_params,
3062                         &mut gm.gm_params,
3063                     )?;
3064 
3065                     Self::read_global_param(
3066                         r,
3067                         type_,
3068                         ref_frame,
3069                         5,
3070                         fh.allow_high_precision_mv,
3071                         &prev_gm_params,
3072                         &mut gm.gm_params,
3073                     )?;
3074                 } else {
3075                     gm.gm_params[ref_frame][4] = -gm.gm_params[ref_frame][3];
3076                     gm.gm_params[ref_frame][5] = gm.gm_params[ref_frame][2];
3077                 }
3078             }
3079 
3080             if gm.gm_type[ref_frame] as u32 >= WarpModelType::Translation as u32 {
3081                 Self::read_global_param(
3082                     r,
3083                     type_,
3084                     ref_frame,
3085                     0,
3086                     fh.allow_high_precision_mv,
3087                     &prev_gm_params,
3088                     &mut gm.gm_params,
3089                 )?;
3090 
3091                 Self::read_global_param(
3092                     r,
3093                     type_,
3094                     ref_frame,
3095                     1,
3096                     fh.allow_high_precision_mv,
3097                     &prev_gm_params,
3098                     &mut gm.gm_params,
3099                 )?;
3100             }
3101 
3102             gm.warp_valid[ref_frame] = Self::setup_shear(&gm.gm_params[ref_frame])?;
3103         }
3104 
3105         Ok(())
3106     }
3107 
parse_film_grain_parameters( &self, r: &mut Reader, fh: &mut FrameHeaderObu, film_grain_params_present: bool, mono_chrome: bool, subsampling_x: bool, subsampling_y: bool, ) -> Result<(), String>3108     fn parse_film_grain_parameters(
3109         &self,
3110         r: &mut Reader,
3111         fh: &mut FrameHeaderObu,
3112         film_grain_params_present: bool,
3113         mono_chrome: bool,
3114         subsampling_x: bool,
3115         subsampling_y: bool,
3116     ) -> Result<(), String> {
3117         let fg = &mut fh.film_grain_params;
3118 
3119         if !film_grain_params_present || (!fh.show_frame && !fh.showable_frame) {
3120             *fg = Default::default();
3121             return Ok(());
3122         }
3123 
3124         fg.apply_grain = r.0.read_bit()?;
3125         if !fg.apply_grain {
3126             *fg = Default::default();
3127             return Ok(());
3128         }
3129 
3130         fg.grain_seed = r.0.read_bits::<u32>(16)? as u16;
3131         if fh.frame_type == FrameType::InterFrame {
3132             fg.update_grain = r.0.read_bit()?;
3133         } else {
3134             fg.update_grain = true;
3135         }
3136 
3137         if !fg.update_grain {
3138             fg.film_grain_params_ref_idx = r.0.read_bits::<u32>(3)? as u8;
3139             let temp_grain_seed = fg.grain_seed;
3140 
3141             if !fh
3142                 .ref_frame_idx
3143                 .iter()
3144                 .any(|&ref_frame_idx| ref_frame_idx == fg.film_grain_params_ref_idx)
3145             {
3146                 return Err("Invalid film_grain_params_ref_idx".into());
3147             }
3148 
3149             // load_grain_params()
3150             *fg = self.ref_info[fg.film_grain_params_ref_idx as usize].film_grain_params.clone();
3151 
3152             fg.grain_seed = temp_grain_seed;
3153 
3154             return Ok(());
3155         }
3156 
3157         fg.num_y_points = r.0.read_bits::<u32>(4)? as u8;
3158         fg.point_y_value
3159             .iter_mut()
3160             .zip(fg.point_y_scaling.iter_mut())
3161             .take(fg.num_y_points as usize)
3162             .try_for_each(|(point_y_value, point_y_scaling)| {
3163                 *point_y_value = r.0.read_bits::<u32>(8)? as u8;
3164                 *point_y_scaling = r.0.read_bits::<u32>(8)? as u8;
3165                 Ok::<_, String>(())
3166             })?;
3167 
3168         if mono_chrome {
3169             fg.chroma_scaling_from_luma = false;
3170         } else {
3171             fg.chroma_scaling_from_luma = r.0.read_bit()?;
3172         }
3173 
3174         if mono_chrome
3175             || fg.chroma_scaling_from_luma
3176             || (subsampling_x && subsampling_y && fg.num_y_points == 0)
3177         {
3178             fg.num_cb_points = 0;
3179             fg.num_cr_points = 0;
3180         } else {
3181             fg.num_cb_points = r.0.read_bits::<u32>(4)? as u8;
3182             if fg.num_cb_points > 10 {
3183                 return Err(format!("Invalid num_cb_points {}", fg.num_cb_points));
3184             }
3185 
3186             for i in 0..fg.num_cb_points as usize {
3187                 fg.point_cb_value[i] = r.0.read_bits::<u32>(8)? as u8;
3188                 if i > 0 && fg.point_cb_value[i - 1] >= fg.point_cb_value[i] {
3189                     return Err(format!("Invalid point_cb_value[{}] {}", i, fg.point_cb_value[i]));
3190                 }
3191                 fg.point_cb_scaling[i] = r.0.read_bits::<u32>(8)? as u8;
3192             }
3193 
3194             fg.num_cr_points = r.0.read_bits::<u32>(4)? as u8;
3195             for i in 0..fg.num_cr_points as usize {
3196                 fg.point_cr_value[i] = r.0.read_bits::<u32>(8)? as u8;
3197                 if i > 0 && fg.point_cr_value[i - 1] >= fg.point_cr_value[i] {
3198                     return Err(format!("Invalid point_cr_value[{}] {}", i, fg.point_cr_value[i]));
3199                 }
3200                 fg.point_cr_scaling[i] = r.0.read_bits::<u32>(8)? as u8;
3201             }
3202         }
3203 
3204         fg.grain_scaling_minus_8 = r.0.read_bits::<u32>(2)? as u8;
3205         fg.ar_coeff_lag = r.0.read_bits::<u32>(2)?;
3206 
3207         let num_pos_luma = 2 * fg.ar_coeff_lag * (fg.ar_coeff_lag + 1);
3208         let num_pos_chroma = if fg.num_y_points > 0 {
3209             for i in 0..num_pos_luma as usize {
3210                 fg.ar_coeffs_y_plus_128[i] = r.0.read_bits::<u32>(8)? as u8;
3211             }
3212             num_pos_luma + 1
3213         } else {
3214             num_pos_luma
3215         };
3216 
3217         if fg.chroma_scaling_from_luma || fg.num_cb_points > 0 {
3218             for i in 0..num_pos_chroma as usize {
3219                 fg.ar_coeffs_cb_plus_128[i] = r.0.read_bits::<u32>(8)? as u8;
3220             }
3221         }
3222 
3223         if fg.chroma_scaling_from_luma || fg.num_cr_points > 0 {
3224             for i in 0..num_pos_chroma as usize {
3225                 fg.ar_coeffs_cr_plus_128[i] = r.0.read_bits::<u32>(8)? as u8;
3226             }
3227         }
3228 
3229         fg.ar_coeff_shift_minus_6 = r.0.read_bits::<u32>(2)? as u8;
3230         fg.grain_scale_shift = r.0.read_bits::<u32>(2)? as u8;
3231 
3232         if fg.num_cb_points > 0 {
3233             fg.cb_mult = r.0.read_bits::<u32>(8)? as u8;
3234             fg.cb_luma_mult = r.0.read_bits::<u32>(8)? as u8;
3235             fg.cb_offset = r.0.read_bits::<u32>(9)? as u16;
3236         }
3237 
3238         if fg.num_cr_points > 0 {
3239             fg.cr_mult = r.0.read_bits::<u32>(8)? as u8;
3240             fg.cr_luma_mult = r.0.read_bits::<u32>(8)? as u8;
3241             fg.cr_offset = r.0.read_bits::<u32>(9)? as u16;
3242         }
3243 
3244         fg.overlap_flag = r.0.read_bit()?;
3245         fg.clip_to_restricted_range = r.0.read_bit()?;
3246 
3247         Ok(())
3248     }
3249 
sequence(&self) -> Result<&SequenceHeaderObu, String>3250     fn sequence(&self) -> Result<&SequenceHeaderObu, String> {
3251         let Some(seq) = self.sequence_header.as_ref() else {
3252             return Err("No sequence header parsed yet".into());
3253         };
3254 
3255         Ok(seq)
3256     }
3257 
parse_uncompressed_frame_header(&mut self, obu: &Obu) -> Result<FrameHeaderObu, String>3258     fn parse_uncompressed_frame_header(&mut self, obu: &Obu) -> Result<FrameHeaderObu, String> {
3259         let mut r = Reader::new(obu.as_ref());
3260 
3261         let mut fh = FrameHeaderObu { obu_header: obu.header.clone(), ..Default::default() };
3262 
3263         // Section 6.8.1: It is a requirement of bitstream conformance that a
3264         // sequence header OBU has been received before a frame header OBU.
3265         let &SequenceHeaderObu {
3266             operating_points_cnt_minus_1,
3267             seq_force_integer_mv,
3268             additional_frame_id_length_minus_1,
3269             delta_frame_id_length_minus_2,
3270             decoder_model_info_present_flag,
3271             reduced_still_picture_header,
3272             frame_id_numbers_present_flag,
3273             use_128x128_superblock,
3274             enable_order_hint,
3275             seq_force_screen_content_tools,
3276             order_hint_bits,
3277             enable_cdef,
3278             enable_restoration,
3279             enable_warped_motion,
3280             color_config:
3281                 ColorConfig { subsampling_x, subsampling_y, separate_uv_delta_q, mono_chrome, .. },
3282             timing_info: TimingInfo { equal_picture_interval, .. },
3283             decoder_model_info:
3284                 DecoderModelInfo {
3285                     frame_presentation_time_length_minus_1,
3286                     buffer_removal_time_length_minus_1,
3287                     ..
3288                 },
3289             num_planes,
3290             film_grain_params_present,
3291             ..
3292         } = self.sequence()?;
3293 
3294         let mut id_len = 0;
3295 
3296         if frame_id_numbers_present_flag {
3297             id_len = additional_frame_id_length_minus_1 + delta_frame_id_length_minus_2 + 3;
3298         }
3299 
3300         const ALL_FRAMES: u32 = (1 << NUM_REF_FRAMES) - 1;
3301 
3302         if reduced_still_picture_header {
3303             fh.show_existing_frame = false;
3304             fh.frame_type = FrameType::KeyFrame;
3305             fh.frame_is_intra = true;
3306             fh.show_frame = true;
3307             fh.showable_frame = false;
3308         } else {
3309             fh.show_existing_frame = r.0.read_bit()?;
3310             if matches!(obu.header.obu_type, ObuType::Frame) && fh.show_existing_frame {
3311                 return Err("If obu_type is equal to OBU_FRAME, it is a requirement of bitstream conformance that show_existing_frame is equal to 0.".into());
3312             }
3313             if fh.show_existing_frame {
3314                 fh.frame_to_show_map_idx = r.0.read_bits::<u32>(3)? as u8;
3315 
3316                 if decoder_model_info_present_flag && !equal_picture_interval {
3317                     fh.frame_presentation_time =
3318                         r.0.read_bits::<u32>(frame_presentation_time_length_minus_1 as usize + 1)?;
3319                 }
3320 
3321                 let ref_frame = &self.ref_info[fh.frame_to_show_map_idx as usize];
3322 
3323                 fh.refresh_frame_flags = 0;
3324                 if frame_id_numbers_present_flag {
3325                     if id_len == 0 {
3326                         return Err(format!("Invalid id_len {}", id_len));
3327                     }
3328                     fh.display_frame_id = r.0.read_bits::<u32>(id_len.try_into().unwrap())?;
3329                     if ref_frame.display_frame_id != fh.display_frame_id || !ref_frame.ref_valid {
3330                         return Err("Invalid display_frame_id".into());
3331                     }
3332                 }
3333 
3334                 if !ref_frame.showable_frame {
3335                     return Err("Invalid bitstream: can't show this past frame".into());
3336                 }
3337 
3338                 // In decode_frame_wrapup():
3339                 //
3340                 // Otherwise (show_existing_frame is equal to 1), if frame_type
3341                 // is equal to KEY_FRAME, the reference frame loading process as
3342                 // specified in section 7.21 is invoked (this process loads
3343                 // frame state from the reference frames into the current frame
3344                 // state variables)
3345                 //
3346                 // The following ordered steps now apply:
3347                 //
3348                 // 1. The reference frame update process as specified in section
3349                 // 7.20 is invoked (this process saves the current frame state
3350                 // into the reference frames).
3351                 //
3352                 // 2. If show_frame is equal to 1 or show_existing_frame is
3353                 // equal to 1, the output process as specified in section 7.18
3354                 // is invoked (this will output the current frame or a saved
3355                 // frame).
3356                 //
3357                 // We implement 1. here while 2. is left to the actual decoder
3358                 self.load_reference_frame(&mut fh)?;
3359                 if fh.frame_type == FrameType::KeyFrame {
3360                     fh.refresh_frame_flags = ALL_FRAMES;
3361                 }
3362 
3363                 if film_grain_params_present {
3364                     // load_grain_params()
3365                     fh.film_grain_params =
3366                         self.ref_info[fh.frame_to_show_map_idx as usize].film_grain_params.clone();
3367                 }
3368 
3369                 // See 5.10.
3370                 if matches!(obu.header.obu_type, ObuType::Frame) {
3371                     r.byte_alignment()?;
3372                 }
3373 
3374                 fh.header_bytes = usize::try_from(r.0.position() / 8).unwrap();
3375                 return Ok(fh);
3376             }
3377 
3378             fh.frame_type = FrameType::try_from(r.0.read_bits::<u32>(2)?)?;
3379             fh.frame_is_intra =
3380                 matches!(fh.frame_type, FrameType::IntraOnlyFrame | FrameType::KeyFrame);
3381 
3382             fh.show_frame = r.0.read_bit()?;
3383 
3384             if fh.show_frame && decoder_model_info_present_flag && equal_picture_interval {
3385                 fh.frame_presentation_time =
3386                     r.0.read_bits::<u32>(frame_presentation_time_length_minus_1 as usize + 1)?;
3387             }
3388 
3389             if fh.show_frame {
3390                 fh.showable_frame = !matches!(fh.frame_type, FrameType::KeyFrame);
3391             } else {
3392                 fh.showable_frame = r.0.read_bit()?;
3393             }
3394 
3395             if fh.frame_type == FrameType::SwitchFrame
3396                 || (fh.frame_type == FrameType::KeyFrame && fh.show_frame)
3397             {
3398                 fh.error_resilient_mode = true;
3399             } else {
3400                 fh.error_resilient_mode = r.0.read_bit()?;
3401             }
3402         }
3403 
3404         if fh.frame_type == FrameType::KeyFrame && fh.show_frame {
3405             for i in 0..NUM_REF_FRAMES {
3406                 self.ref_info[i].ref_valid = false;
3407                 self.ref_info[i].ref_order_hint = 0;
3408             }
3409             for i in 0..REFS_PER_FRAME {
3410                 fh.order_hints[ReferenceFrameType::Last as usize + i] = 0;
3411             }
3412         }
3413 
3414         fh.disable_cdf_update = r.0.read_bit()?;
3415         if seq_force_screen_content_tools == SELECT_SCREEN_CONTENT_TOOLS as u32 {
3416             fh.allow_screen_content_tools = r.0.read_bit()? as u32;
3417         } else {
3418             fh.allow_screen_content_tools = seq_force_screen_content_tools;
3419         }
3420 
3421         if fh.allow_screen_content_tools > 0 {
3422             if seq_force_integer_mv == SELECT_INTEGER_MV as u32 {
3423                 fh.force_integer_mv = r.0.read_bit()? as u32;
3424             } else {
3425                 fh.force_integer_mv = seq_force_integer_mv;
3426             }
3427         } else {
3428             fh.force_integer_mv = 0;
3429         }
3430 
3431         if fh.frame_is_intra {
3432             fh.force_integer_mv = 1;
3433         }
3434 
3435         if frame_id_numbers_present_flag {
3436             self.prev_frame_id = self.current_frame_id;
3437             self.current_frame_id = r.0.read_bits::<u32>(id_len.try_into().unwrap())?;
3438             fh.current_frame_id = self.current_frame_id;
3439 
3440             /* conformance checking, as per aom */
3441             let have_prev_frame_id =
3442                 !(self.is_first_frame || fh.frame_type == FrameType::KeyFrame && fh.show_frame);
3443 
3444             if have_prev_frame_id {
3445                 let frame_id_length =
3446                     additional_frame_id_length_minus_1 + delta_frame_id_length_minus_2 + 3;
3447 
3448                 let diff_frame_id = if self.current_frame_id > self.prev_frame_id {
3449                     self.current_frame_id - self.prev_frame_id
3450                 } else {
3451                     if frame_id_length > 16 {
3452                         return Err(format!("Invalid frame_id_length {}", frame_id_length));
3453                     }
3454                     (1 << frame_id_length) + self.current_frame_id - self.prev_frame_id
3455                 };
3456 
3457                 if self.prev_frame_id == self.current_frame_id
3458                     || diff_frame_id >= (1 << (frame_id_length - 1))
3459                 {
3460                     return Err(format!(
3461                         "Invalid frame_id: prev_frame_id = {}, current_frame_id = {}",
3462                         self.prev_frame_id, self.current_frame_id
3463                     ));
3464                 }
3465             }
3466 
3467             /* mark_ref_frames (idLen) */
3468             let diff_len = delta_frame_id_length_minus_2 + 2;
3469             let shifted_diff_len = 1 << diff_len;
3470             let shifted_id_len = 1 << id_len;
3471 
3472             for i in 0..NUM_REF_FRAMES {
3473                 if self.current_frame_id > shifted_diff_len {
3474                     if self.ref_info[i].ref_frame_id > self.current_frame_id
3475                         || self.ref_info[i].ref_frame_id
3476                             < (self.current_frame_id - shifted_diff_len)
3477                     {
3478                         self.ref_info[i].ref_valid = false;
3479                     }
3480                 } else if self.ref_info[i].ref_frame_id > self.current_frame_id
3481                     && self.ref_info[i].ref_frame_id
3482                         < shifted_id_len + self.current_frame_id - shifted_diff_len
3483                 {
3484                     self.ref_info[i].ref_valid = false;
3485                 }
3486             }
3487         } else {
3488             self.current_frame_id = 0;
3489             self.prev_frame_id = self.current_frame_id;
3490             fh.current_frame_id = self.current_frame_id;
3491         }
3492 
3493         if fh.frame_type == FrameType::SwitchFrame {
3494             fh.frame_size_override_flag = true;
3495         } else if reduced_still_picture_header {
3496             fh.frame_size_override_flag = false;
3497         } else {
3498             fh.frame_size_override_flag = r.0.read_bit()?;
3499         }
3500 
3501         fh.order_hint = r.0.read_bits::<u32>(order_hint_bits.try_into().unwrap())?;
3502 
3503         if fh.frame_is_intra || fh.error_resilient_mode {
3504             fh.primary_ref_frame = PRIMARY_REF_NONE;
3505         } else {
3506             fh.primary_ref_frame = r.0.read_bits::<u32>(3)?;
3507         }
3508 
3509         let operating_points = &self.sequence()?.operating_points;
3510         if decoder_model_info_present_flag {
3511             fh.buffer_removal_time_present_flag = r.0.read_bit()?;
3512             if fh.buffer_removal_time_present_flag {
3513                 #[allow(clippy::needless_range_loop)]
3514                 for op_num in 0..=operating_points_cnt_minus_1 as usize {
3515                     if operating_points[op_num].decoder_model_present_for_this_op {
3516                         let op_pt_idc = operating_points[op_num].idc;
3517                         let in_temporal_layer = (op_pt_idc >> fh.obu_header.temporal_id) & 1 != 0;
3518                         let in_spatial_layer =
3519                             (op_pt_idc >> (fh.obu_header.spatial_id + 8)) & 1 != 0;
3520 
3521                         if op_pt_idc == 0 || (in_temporal_layer && in_spatial_layer) {
3522                             let n = buffer_removal_time_length_minus_1 + 1;
3523                             fh.buffer_removal_time[op_num] = r.0.read_bits::<u32>(n as usize)?;
3524                         }
3525                     }
3526                 }
3527             }
3528         }
3529 
3530         fh.allow_high_precision_mv = false;
3531         fh.use_ref_frame_mvs = false;
3532         fh.allow_intrabc = false;
3533         if fh.frame_type == FrameType::SwitchFrame
3534             || (fh.frame_type == FrameType::KeyFrame && fh.show_frame)
3535         {
3536             fh.refresh_frame_flags = ALL_FRAMES;
3537         } else {
3538             fh.refresh_frame_flags = r.0.read_bits::<u32>(8)?;
3539         }
3540 
3541         /* equivalent boolean expression */
3542         if (!fh.frame_is_intra || fh.refresh_frame_flags != ALL_FRAMES)
3543             && fh.error_resilient_mode
3544             && enable_order_hint
3545         {
3546             for i in 0..NUM_REF_FRAMES {
3547                 fh.ref_order_hint[i] = r.0.read_bits::<u32>(order_hint_bits.try_into().unwrap())?;
3548                 if fh.ref_order_hint[i] != self.ref_info[i].ref_order_hint {
3549                     self.ref_info[i].ref_valid = false;
3550                 }
3551             }
3552         }
3553 
3554         if fh.frame_is_intra {
3555             self.parse_frame_size(&mut fh, &mut r)?;
3556             Self::parse_render_size(&mut fh, &mut r)?;
3557             if fh.allow_screen_content_tools > 0 && fh.upscaled_width == fh.frame_width {
3558                 fh.allow_intrabc = r.0.read_bit()?;
3559             }
3560         } else {
3561             if !enable_order_hint {
3562                 fh.frame_refs_short_signaling = false;
3563             } else {
3564                 fh.frame_refs_short_signaling = r.0.read_bit()?;
3565                 if fh.frame_refs_short_signaling {
3566                     fh.last_frame_idx = r.0.read_bits::<u32>(3)? as u8;
3567                     fh.gold_frame_idx = r.0.read_bits::<u32>(3)? as u8;
3568                     let ref_order_hints = self
3569                         .ref_info
3570                         .iter()
3571                         .map(|i| i.ref_order_hint)
3572                         .collect::<Vec<_>>()
3573                         .try_into()
3574                         .unwrap();
3575                     self.set_frame_refs(&mut fh, &ref_order_hints)?;
3576                 }
3577             }
3578 
3579             let mut expected_frame_id = [0; REFS_PER_FRAME];
3580             #[allow(clippy::needless_range_loop)]
3581             for i in 0..REFS_PER_FRAME {
3582                 if !fh.frame_refs_short_signaling {
3583                     fh.ref_frame_idx[i] = r.0.read_bits::<u32>(3)?.try_into().unwrap();
3584                 }
3585 
3586                 if frame_id_numbers_present_flag {
3587                     /* DeltaFrameId */
3588                     let delta_frame_id =
3589                         r.0.read_bits::<u32>(delta_frame_id_length_minus_2 as usize + 2)? + 1;
3590 
3591                     if id_len == 0 {
3592                         return Err(format!("Invalid id_len {}", id_len));
3593                     }
3594 
3595                     let shifted_id_len = 1 << id_len;
3596 
3597                     expected_frame_id[i] =
3598                         (self.current_frame_id + shifted_id_len - delta_frame_id) % shifted_id_len;
3599 
3600                     let actual_frame_id = self.ref_info[fh.ref_frame_idx[i] as usize].ref_frame_id;
3601 
3602                     if expected_frame_id[i] != actual_frame_id {
3603                         return Err(format!(
3604                             "Invalid frame id, expected {} got {}",
3605                             expected_frame_id[i], actual_frame_id
3606                         ));
3607                     }
3608                 }
3609             }
3610 
3611             if fh.frame_size_override_flag && !fh.error_resilient_mode {
3612                 self.frame_size_with_refs(&mut fh, &mut r)?;
3613             } else {
3614                 self.parse_frame_size(&mut fh, &mut r)?;
3615                 Self::parse_render_size(&mut fh, &mut r)?;
3616             }
3617 
3618             if fh.force_integer_mv > 0 {
3619                 fh.allow_high_precision_mv = false;
3620             } else {
3621                 fh.allow_high_precision_mv = r.0.read_bit()?;
3622             }
3623 
3624             /* read_interpolation_filter */
3625             fh.is_filter_switchable = r.0.read_bit()?;
3626             if fh.is_filter_switchable {
3627                 fh.interpolation_filter = InterpolationFilter::Switchable;
3628             } else {
3629                 fh.interpolation_filter = InterpolationFilter::try_from(r.0.read_bits::<u32>(2)?)?;
3630             }
3631 
3632             fh.is_motion_mode_switchable = r.0.read_bit()?;
3633 
3634             if fh.error_resilient_mode || !self.sequence()?.enable_ref_frame_mvs {
3635                 fh.use_ref_frame_mvs = false;
3636             } else {
3637                 fh.use_ref_frame_mvs = r.0.read_bit()?;
3638             }
3639 
3640             for i in 0..REFS_PER_FRAME {
3641                 let ref_frame = ReferenceFrameType::Last as usize + i;
3642                 let hint = self.ref_info[fh.ref_frame_idx[i] as usize].ref_order_hint;
3643                 fh.order_hints[ref_frame] = hint;
3644 
3645                 if !enable_order_hint {
3646                     fh.ref_frame_sign_bias[i] = false;
3647                 } else {
3648                     fh.ref_frame_sign_bias[i] = helpers::get_relative_dist(
3649                         enable_order_hint,
3650                         order_hint_bits,
3651                         hint.try_into().unwrap(),
3652                         fh.order_hint.try_into().unwrap(),
3653                     ) > 0;
3654                 }
3655             }
3656         }
3657 
3658         if reduced_still_picture_header || fh.disable_cdf_update {
3659             fh.disable_frame_end_update_cdf = true;
3660         } else {
3661             fh.disable_frame_end_update_cdf = r.0.read_bit()?;
3662         }
3663 
3664         if fh.primary_ref_frame == PRIMARY_REF_NONE {
3665             Self::setup_past_independence(&mut fh);
3666         } else {
3667             /* load from the past reference */
3668             let prev_frame =
3669                 &self.ref_info[fh.ref_frame_idx[fh.primary_ref_frame as usize] as usize];
3670 
3671             if !prev_frame.ref_valid {
3672                 return Err("Reference is invalid".into());
3673             }
3674 
3675             /* load_loop_filter_params: load ref_deltas and mode_deltas */
3676             fh.loop_filter_params.loop_filter_ref_deltas =
3677                 prev_frame.loop_filter_params.loop_filter_ref_deltas;
3678             fh.loop_filter_params.loop_filter_mode_deltas =
3679                 prev_frame.loop_filter_params.loop_filter_mode_deltas;
3680 
3681             /* load_segmentation_params: load feature_enabled and feature_data */
3682             fh.segmentation_params.feature_enabled = prev_frame.segmentation_params.feature_enabled;
3683             fh.segmentation_params.feature_data = prev_frame.segmentation_params.feature_data;
3684         }
3685 
3686         // TODO: we can live without this for now.
3687         // if fh.use_ref_frame_mvs {
3688         //     // motion_field_estimators()
3689         // }
3690 
3691         self.parse_tile_info(&mut r, &mut fh.tile_info)?;
3692         Self::parse_quantization_params(
3693             &mut r,
3694             &mut fh.quantization_params,
3695             num_planes,
3696             separate_uv_delta_q,
3697         )?;
3698         self.parse_segmentation_params(&mut r, &mut fh)?;
3699         Self::parse_delta_q_params(&mut r, &mut fh.quantization_params)?;
3700         Self::parse_delta_lf_params(
3701             &mut r,
3702             &mut fh.loop_filter_params,
3703             fh.quantization_params.delta_q_present,
3704             fh.allow_intrabc,
3705         )?;
3706 
3707         fh.coded_lossless = true;
3708         for segment_id in 0..MAX_SEGMENTS {
3709             let q_index = Self::get_qindex(&fh, true, segment_id as _);
3710             let q = &fh.quantization_params;
3711             fh.lossless_array[segment_id] = q_index == 0
3712                 && q.delta_q_y_dc == 0
3713                 && q.delta_q_u_ac == 0
3714                 && q.delta_q_u_dc == 0
3715                 && q.delta_q_v_ac == 0
3716                 && q.delta_q_v_dc == 0;
3717             if !fh.lossless_array[segment_id] {
3718                 fh.coded_lossless = false;
3719             }
3720             if q.using_qmatrix {
3721                 if fh.lossless_array[segment_id] {
3722                     fh.seg_qm_level[0][segment_id] = 15;
3723                     fh.seg_qm_level[1][segment_id] = 15;
3724                     fh.seg_qm_level[2][segment_id] = 15;
3725                 } else {
3726                     fh.seg_qm_level[0][segment_id] = q.qm_y;
3727                     fh.seg_qm_level[1][segment_id] = q.qm_u;
3728                     fh.seg_qm_level[2][segment_id] = q.qm_v;
3729                 }
3730             }
3731         }
3732 
3733         fh.all_lossless = fh.coded_lossless && fh.frame_width == fh.upscaled_width;
3734         Self::parse_loop_filter_parameters(&mut r, &mut fh, num_planes)?;
3735         Self::parse_cdef_params(&mut r, &mut fh, enable_cdef, num_planes)?;
3736         Self::parse_loop_restoration_params(
3737             &mut r,
3738             &mut fh,
3739             enable_restoration,
3740             num_planes,
3741             use_128x128_superblock,
3742             subsampling_x,
3743             subsampling_y,
3744         )?;
3745         Self::read_tx_mode(&mut r, &mut fh)?;
3746         Self::parse_frame_reference_mode(&mut r, &mut fh)?;
3747         self.parse_skip_mode_params(&mut r, &mut fh, enable_order_hint, order_hint_bits)?;
3748 
3749         if fh.frame_is_intra || fh.error_resilient_mode || !enable_warped_motion {
3750             fh.allow_warped_motion = false;
3751         } else {
3752             fh.allow_warped_motion = r.0.read_bit()?;
3753         }
3754 
3755         fh.reduced_tx_set = r.0.read_bit()?;
3756         self.parse_global_motion_params(&mut r, &mut fh)?;
3757         self.parse_film_grain_parameters(
3758             &mut r,
3759             &mut fh,
3760             film_grain_params_present,
3761             mono_chrome,
3762             subsampling_x,
3763             subsampling_y,
3764         )?;
3765 
3766         Self::skip_and_check_trailing_bits(&mut r, obu)?;
3767 
3768         // See 5.10
3769         if matches!(obu.header.obu_type, ObuType::Frame) {
3770             r.byte_alignment()?;
3771         }
3772 
3773         fh.header_bytes = usize::try_from(r.0.position() / 8).unwrap();
3774         Ok(fh)
3775     }
3776 
parse_tile_group_obu<'a>(&mut self, obu: Obu<'a>) -> Result<TileGroupObu<'a>, String>3777     fn parse_tile_group_obu<'a>(&mut self, obu: Obu<'a>) -> Result<TileGroupObu<'a>, String> {
3778         let mut tg = TileGroupObu { obu, ..Default::default() };
3779 
3780         let mut r = Reader::new(tg.obu.as_ref());
3781 
3782         if r.0.num_bits_left() % 8 != 0 {
3783             return Err("Bitstream is not byte aligned".into());
3784         }
3785 
3786         let mut sz: u64 = r.0.num_bits_left() as u64 / 8;
3787 
3788         let num_tiles = self.tile_rows * self.tile_cols;
3789         let start_bit_pos = r.0.position();
3790 
3791         if num_tiles > 1 {
3792             tg.tile_start_and_end_present_flag = r.0.read_bit()?;
3793         }
3794 
3795         if num_tiles == 1 || !tg.tile_start_and_end_present_flag {
3796             tg.tg_start = 0;
3797             tg.tg_end = num_tiles - 1;
3798         } else {
3799             let tile_bits = (self.tile_cols_log2 + self.tile_rows_log2) as usize;
3800             tg.tg_start = r.0.read_bits::<u32>(tile_bits)?;
3801             tg.tg_end = r.0.read_bits::<u32>(tile_bits)?;
3802         }
3803 
3804         r.byte_alignment()?;
3805 
3806         let end_bit_pos = r.0.position();
3807         let header_bytes = (end_bit_pos - start_bit_pos) / 8;
3808         sz -= header_bytes;
3809 
3810         let mut tile_num = tg.tg_start;
3811         while tile_num <= tg.tg_end {
3812             let tile_row = tile_num / self.tile_cols;
3813             let tile_col = tile_num % self.tile_cols;
3814             let last_tile = tile_num == tg.tg_end;
3815             let tile_size;
3816 
3817             if last_tile {
3818                 tile_size = u32::try_from(sz).unwrap();
3819             } else {
3820                 tile_size = r.0.read_le::<u32>(self.tile_size_bytes.try_into().unwrap())? + 1;
3821                 sz -= u64::from(tile_size + self.tile_size_bytes);
3822             }
3823 
3824             let tile = Tile {
3825                 tile_offset: u32::try_from(r.0.position()).unwrap() / 8,
3826                 tile_size,
3827                 tile_row,
3828                 tile_col,
3829                 mi_row_start: self.mi_row_starts[tile_row as usize],
3830                 mi_row_end: self.mi_row_starts[tile_row as usize + 1],
3831                 mi_col_start: self.mi_row_starts[tile_col as usize],
3832                 mi_col_end: self.mi_row_starts[tile_col as usize + 1],
3833             };
3834 
3835             tg.tiles.push(tile);
3836 
3837             // init_symbol, decode_tile() and exit_symbol() left to the accelerator.
3838 
3839             // Skip the actual tile data
3840             if tile_num < tg.tg_end {
3841                 r.0.skip_bits(tile_size as usize * 8)?;
3842             }
3843 
3844             tile_num += 1;
3845         }
3846 
3847         if tg.tg_end == num_tiles - 1 {
3848             // left to the accelerator:
3849             // if ( !disable_frame_end_update_cdf ) {
3850             //  frame_end_update_cdf( )
3851             // }
3852             // decode_frame_wrapup( )
3853             self.seen_frame_header = false;
3854         }
3855 
3856         Ok(tg)
3857     }
3858 
parse_frame_obu<'a>(&mut self, obu: Obu<'a>) -> Result<FrameObu<'a>, String>3859     fn parse_frame_obu<'a>(&mut self, obu: Obu<'a>) -> Result<FrameObu<'a>, String> {
3860         if !matches!(obu.header.obu_type, ObuType::Frame) {
3861             return Err(format!("Expected a FrameOBU, got {:?}", obu.header.obu_type));
3862         }
3863 
3864         let frame_header_obu = self.parse_frame_header_obu(&obu)?;
3865         let obu = Obu {
3866             header: obu.header,
3867             data: match obu.data {
3868                 Cow::Borrowed(d) => Cow::Borrowed(&d[frame_header_obu.header_bytes..]),
3869                 Cow::Owned(d) => Cow::Owned(d[frame_header_obu.header_bytes..].to_owned()),
3870             },
3871             bytes_used: obu.bytes_used,
3872         };
3873         let tile_group_obu = self.parse_tile_group_obu(obu)?;
3874 
3875         Ok(FrameObu { header: frame_header_obu, tile_group: tile_group_obu })
3876     }
3877 
parse_frame_header_obu(&mut self, obu: &Obu) -> Result<FrameHeaderObu, String>3878     pub fn parse_frame_header_obu(&mut self, obu: &Obu) -> Result<FrameHeaderObu, String> {
3879         if !matches!(obu.header.obu_type, ObuType::FrameHeader | ObuType::Frame) {
3880             return Err(format!("Expected a FrameHeaderOBU, got {:?}", obu.header.obu_type));
3881         }
3882 
3883         if self.seen_frame_header {
3884             Ok(self
3885                 .last_frame_header
3886                 .clone()
3887                 .take()
3888                 .ok_or::<String>("Broken stream: no previous frame header to copy".into())?)
3889         } else {
3890             self.seen_frame_header = true;
3891             let header = self.parse_uncompressed_frame_header(obu)?;
3892             if header.show_existing_frame {
3893                 self.last_frame_header = None;
3894                 self.seen_frame_header = false;
3895             } else {
3896                 /* TileNum = 0 */
3897                 self.seen_frame_header = true;
3898                 self.last_frame_header = Some(header.clone());
3899             }
3900 
3901             Ok(header)
3902         }
3903     }
3904 
3905     /// Implements 7.20. This function should be called right after decoding a
3906     /// frame.
ref_frame_update(&mut self, fh: &FrameHeaderObu) -> Result<(), String>3907     pub fn ref_frame_update(&mut self, fh: &FrameHeaderObu) -> Result<(), String> {
3908         // This was found as a bug otherwise by Nicolas Dufresne in GStreamer's
3909         // av1parse.
3910         if fh.show_existing_frame && !matches!(fh.frame_type, FrameType::KeyFrame) {
3911             return Ok(());
3912         }
3913 
3914         if matches!(fh.frame_type, FrameType::IntraOnlyFrame) && fh.refresh_frame_flags == 0xff {
3915             return Err("Intra-only frames cannot refresh all of the DPB as per the spec.".into());
3916         }
3917 
3918         let &SequenceHeaderObu {
3919             color_config: ColorConfig { subsampling_x, subsampling_y, .. },
3920             film_grain_params_present,
3921             bit_depth,
3922             ..
3923         } = self.sequence()?;
3924 
3925         for (i, ref_info) in self.ref_info.iter_mut().enumerate() {
3926             if ((fh.refresh_frame_flags >> i) & 1) != 0 {
3927                 ref_info.ref_valid = true;
3928 
3929                 ref_info.ref_frame_id = fh.current_frame_id;
3930                 ref_info.ref_frame_type = fh.frame_type;
3931                 ref_info.ref_upscaled_width = fh.upscaled_width;
3932                 ref_info.ref_frame_width = fh.frame_width;
3933                 ref_info.ref_frame_height = fh.frame_height;
3934                 ref_info.ref_render_width = fh.render_width;
3935                 ref_info.ref_render_height = fh.render_height;
3936                 ref_info.ref_order_hint = fh.order_hint;
3937                 ref_info.ref_mi_cols = self.mi_cols;
3938                 ref_info.ref_mi_rows = self.mi_rows;
3939                 ref_info.ref_subsampling_x = subsampling_x;
3940                 ref_info.ref_subsampling_y = subsampling_y;
3941                 ref_info.ref_bit_depth = bit_depth;
3942                 ref_info.segmentation_params = fh.segmentation_params.clone();
3943                 ref_info.global_motion_params = fh.global_motion_params.clone();
3944                 ref_info.loop_filter_params = fh.loop_filter_params.clone();
3945                 ref_info.tile_info = fh.tile_info.clone();
3946                 ref_info.display_frame_id = fh.display_frame_id;
3947                 ref_info.showable_frame = fh.showable_frame;
3948 
3949                 if film_grain_params_present {
3950                     ref_info.film_grain_params = fh.film_grain_params.clone();
3951                 }
3952             }
3953         }
3954 
3955         Ok(())
3956     }
3957 
highest_operating_point(&self) -> Option<u32>3958     pub fn highest_operating_point(&self) -> Option<u32> {
3959         if self.operating_point_idc == 0 {
3960             /* No scalability information, all OBUs must be decoded */
3961             None
3962         } else {
3963             Some(helpers::floor_log2((self.operating_point_idc >> 8) as u32))
3964         }
3965     }
3966 
3967     /// Fully parse an OBU.
parse_obu<'a>(&mut self, obu: Obu<'a>) -> Result<ParsedObu<'a>, String>3968     pub fn parse_obu<'a>(&mut self, obu: Obu<'a>) -> Result<ParsedObu<'a>, String> {
3969         match obu.header.obu_type {
3970             ObuType::Reserved => Ok(ParsedObu::Reserved),
3971             ObuType::SequenceHeader => {
3972                 self.parse_sequence_header_obu(&obu).map(ParsedObu::SequenceHeader)
3973             }
3974             ObuType::TemporalDelimiter => {
3975                 self.parse_temporal_delimiter_obu().map(|_| ParsedObu::TemporalDelimiter)
3976             }
3977             ObuType::FrameHeader => self.parse_frame_header_obu(&obu).map(ParsedObu::FrameHeader),
3978             ObuType::TileGroup => self.parse_tile_group_obu(obu).map(ParsedObu::TileGroup),
3979             ObuType::Metadata => Ok(ParsedObu::Metadata),
3980             ObuType::Frame => self.parse_frame_obu(obu).map(ParsedObu::Frame),
3981             ObuType::RedundantFrameHeader => Ok(ParsedObu::RedundantFrameHeader),
3982             ObuType::TileList => Ok(ParsedObu::TileList),
3983             ObuType::Reserved2 => Ok(ParsedObu::Reserved2),
3984             ObuType::Reserved3 => Ok(ParsedObu::Reserved3),
3985             ObuType::Reserved4 => Ok(ParsedObu::Reserved4),
3986             ObuType::Reserved5 => Ok(ParsedObu::Reserved5),
3987             ObuType::Reserved6 => Ok(ParsedObu::Reserved6),
3988             ObuType::Reserved7 => Ok(ParsedObu::Reserved7),
3989             ObuType::Padding => Ok(ParsedObu::Padding),
3990         }
3991     }
3992 }
3993 
3994 impl Default for Parser {
default() -> Self3995     fn default() -> Self {
3996         Self {
3997             stream_format: StreamFormat::LowOverhead,
3998             operating_point: Default::default(),
3999             seen_frame_header: Default::default(),
4000             last_frame_header: Default::default(),
4001             operating_point_idc: Default::default(),
4002             should_probe_for_annexb: true,
4003             is_first_frame: Default::default(),
4004             mi_cols: Default::default(),
4005             mi_rows: Default::default(),
4006             prev_frame_id: Default::default(),
4007             current_frame_id: Default::default(),
4008             ref_info: Default::default(),
4009             mi_col_starts: [0; MAX_TILE_COLS + 1],
4010             mi_row_starts: [0; MAX_TILE_ROWS + 1],
4011             tile_cols_log2: Default::default(),
4012             tile_cols: Default::default(),
4013             tile_rows_log2: Default::default(),
4014             tile_rows: Default::default(),
4015             tile_size_bytes: Default::default(),
4016             sequence_header: Default::default(),
4017         }
4018     }
4019 }
4020 
4021 impl Clone for Parser {
clone(&self) -> Self4022     fn clone(&self) -> Self {
4023         let sequence_header = self.sequence_header.as_ref().map(|s| Rc::new((**s).clone()));
4024 
4025         Self {
4026             stream_format: self.stream_format.clone(),
4027             operating_point: self.operating_point,
4028             seen_frame_header: self.seen_frame_header,
4029             last_frame_header: self.last_frame_header.clone(),
4030             operating_point_idc: self.operating_point_idc,
4031             should_probe_for_annexb: self.should_probe_for_annexb,
4032             is_first_frame: self.is_first_frame,
4033             ref_info: self.ref_info.clone(),
4034             mi_cols: self.mi_cols,
4035             mi_rows: self.mi_rows,
4036             prev_frame_id: self.prev_frame_id,
4037             current_frame_id: self.current_frame_id,
4038             mi_col_starts: self.mi_col_starts,
4039             mi_row_starts: self.mi_row_starts,
4040             tile_cols_log2: self.tile_cols_log2,
4041             tile_cols: self.tile_cols,
4042             tile_rows_log2: self.tile_rows_log2,
4043             tile_rows: self.tile_rows,
4044             tile_size_bytes: self.tile_size_bytes,
4045             sequence_header,
4046         }
4047     }
4048 }
4049 
4050 #[cfg(test)]
4051 mod tests {
4052     use crate::bitstream_utils::IvfIterator;
4053     use crate::codec::av1::parser::{ObuAction, Parser, StreamFormat};
4054 
4055     use super::ObuType;
4056 
4057     /// Same as test-25fps.av1.ivf from Chromium
4058     const STREAM_TEST_25_FPS: &[u8] = include_bytes!("test_data/test-25fps.ivf.av1");
4059 
4060     /// Encoded with
4061     ///
4062     /// gst-launch-1.0 videotestsrc num-buffers=1 !
4063     /// video/x-raw,format=I420,width=64,height=64 ! filesink
4064     /// location=aom_input.yuv
4065     ///
4066     /// And:
4067     ///
4068     /// aomenc -p 1 --ivf -w 64 -h 64 -o av1-annexb.ivf.av1 aom_input.yuv --annexb=1
4069     const STREAM_ANNEXB: &[u8] = include_bytes!("test_data/av1-annexb.ivf.av1");
4070 
4071     #[test]
parse_test25fps()4072     fn parse_test25fps() {
4073         let mut parser = Parser::default();
4074         let ivf_iter = IvfIterator::new(STREAM_TEST_25_FPS);
4075         let mut num_obus = 0;
4076 
4077         for packet in ivf_iter {
4078             let mut consumed = 0;
4079 
4080             while let Ok(obu) = parser.read_obu(&packet[consumed..]) {
4081                 let obu = match obu {
4082                     ObuAction::Process(obu) => obu,
4083                     // This OBU should be dropped.
4084                     ObuAction::Drop(length) => {
4085                         consumed += usize::try_from(length).unwrap();
4086                         continue;
4087                     }
4088                 };
4089                 consumed += obu.bytes_used;
4090                 num_obus += 1;
4091             }
4092         }
4093 
4094         // Manually checked with GStreamer under GDB by using a hitcount on
4095         // "gst_av1_parse_identify_one_obu" *after* the stream format has been
4096         // detected.
4097         assert_eq!(num_obus, 525);
4098     }
4099 
4100     #[test]
4101     /// Test that we can correctly identify streams in both "low-overhead" and
4102     /// Annex B formats.
parse_annexb()4103     fn parse_annexb() {
4104         let mut parser = Parser::default();
4105         let mut ivf_iter = IvfIterator::new(STREAM_TEST_25_FPS);
4106         let packet = ivf_iter.next().unwrap();
4107 
4108         parser.read_obu(packet).unwrap();
4109         assert!(matches!(parser.stream_format, StreamFormat::LowOverhead));
4110 
4111         let mut parser = Parser::default();
4112         let mut ivf_iter = IvfIterator::new(STREAM_ANNEXB);
4113         let packet = ivf_iter.next().unwrap();
4114 
4115         parser.read_obu(packet).unwrap();
4116         assert!(matches!(parser.stream_format, StreamFormat::AnnexB { .. }));
4117     }
4118 
4119     #[test]
4120     /// Test that we can correctly identify streams in both "low-overhead" and
4121     /// Annex B formats and identify all the OBUs in the stream until the end.
parse_annexb_full()4122     fn parse_annexb_full() {
4123         let mut parser = Parser::default();
4124         let ivf_iter = IvfIterator::new(STREAM_TEST_25_FPS);
4125 
4126         for packet in ivf_iter {
4127             let mut consumed = 0;
4128 
4129             while let Ok(obu) = parser.read_obu(&packet[consumed..]) {
4130                 let obu = match obu {
4131                     ObuAction::Process(obu) => obu,
4132                     // This OBU should be dropped.
4133                     ObuAction::Drop(length) => {
4134                         consumed += usize::try_from(length).unwrap();
4135                         continue;
4136                     }
4137                 };
4138                 assert!(matches!(parser.stream_format, StreamFormat::LowOverhead));
4139                 consumed += obu.bytes_used;
4140             }
4141         }
4142 
4143         let mut parser = Parser::default();
4144         let ivf_iter = IvfIterator::new(STREAM_ANNEXB);
4145         let mut num_obus = 0;
4146 
4147         for packet in ivf_iter {
4148             let mut consumed = 0;
4149 
4150             while let Ok(obu) = parser.read_obu(&packet[consumed..]) {
4151                 let obu = match obu {
4152                     ObuAction::Process(obu) => obu,
4153                     // This OBU should be dropped.
4154                     ObuAction::Drop(length) => {
4155                         consumed += usize::try_from(length).unwrap();
4156                         continue;
4157                     }
4158                 };
4159                 assert!(matches!(parser.stream_format, StreamFormat::AnnexB { .. }));
4160                 consumed += obu.bytes_used;
4161                 num_obus += 1;
4162             }
4163         }
4164 
4165         assert_eq!(num_obus, 3);
4166         let annexb_state = match parser.stream_format {
4167             StreamFormat::AnnexB(annexb_state) => annexb_state,
4168             _ => panic!("Wrong StreamFormat, expected AnnexB"),
4169         };
4170         assert_eq!(annexb_state.temporal_unit_consumed, annexb_state.temporal_unit_size);
4171         assert_eq!(annexb_state.frame_unit_consumed, annexb_state.frame_unit_size);
4172     }
4173 
4174     #[test]
parse_test25fps_obus()4175     fn parse_test25fps_obus() {
4176         let mut parser = Parser::default();
4177         let ivf_iter = IvfIterator::new(STREAM_TEST_25_FPS);
4178 
4179         for packet in ivf_iter {
4180             let mut consumed = 0;
4181 
4182             while let Ok(obu) = parser.read_obu(&packet[consumed..]) {
4183                 let obu = match obu {
4184                     ObuAction::Process(obu) => obu,
4185                     // This OBU should be dropped.
4186                     ObuAction::Drop(length) => {
4187                         consumed += usize::try_from(length).unwrap();
4188                         continue;
4189                     }
4190                 };
4191 
4192                 let data_len = obu.bytes_used;
4193 
4194                 match obu.header.obu_type {
4195                     ObuType::SequenceHeader => {
4196                         parser.parse_sequence_header_obu(&obu).unwrap();
4197                     }
4198                     ObuType::FrameHeader | ObuType::RedundantFrameHeader => {
4199                         let fh = parser.parse_frame_header_obu(&obu).unwrap();
4200                         parser.ref_frame_update(&fh).unwrap();
4201                     }
4202                     ObuType::TileGroup => {
4203                         parser.parse_tile_group_obu(obu).unwrap();
4204                     }
4205                     ObuType::Frame => {
4206                         let frame = parser.parse_frame_obu(obu).unwrap();
4207                         parser.ref_frame_update(&frame.header).unwrap();
4208                     }
4209                     _ => {}
4210                 };
4211 
4212                 consumed += data_len;
4213             }
4214         }
4215     }
4216 }
4217