1use std::borrow::Cow;
6use std::rc::Rc;
7
8use crate::codec::av1::helpers;
9use crate::codec::av1::reader::Reader;
10
11pub const TOTAL_REFS_PER_FRAME: usize = 8;
12pub const NUM_REF_FRAMES: usize = 8;
13pub const REFS_PER_FRAME: usize = 7;
14pub const MAX_SEGMENTS: usize = 8;
15pub const SEG_LVL_ALT_Q: usize = 0;
16pub const SEG_LVL_ALT_LF_Y_V: usize = 1;
17pub const SEG_LVL_REF_FRAME: usize = 5;
18pub const SEG_LVL_SKIP: usize = 6;
19pub const SEG_LVL_GLOBAL_MV: usize = 7;
20pub const SEG_LVL_MAX: usize = 8;
21pub const MAX_TILE_COLS: usize = 64;
22pub const MAX_TILE_ROWS: usize = 64;
23pub const CDEF_MAX: usize = 1 << 3;
24pub const MAX_NUM_PLANES: usize = 3;
25pub const MAX_NUM_Y_POINTS: usize = 16;
26pub const MAX_NUM_CB_POINTS: usize = 16;
27pub const MAX_NUM_CR_POINTS: usize = 16;
28pub const MAX_NUM_POS_LUMA: usize = 25;
29pub const MAX_NUM_SPATIAL_LAYERS: usize = 4;
30pub const MAX_NUM_TEMPORAL_LAYERS: usize = 8;
31pub const MAX_NUM_OPERATING_POINTS: usize = MAX_NUM_SPATIAL_LAYERS * MAX_NUM_TEMPORAL_LAYERS;
32pub const SELECT_SCREEN_CONTENT_TOOLS: usize = 2;
33pub const SELECT_INTEGER_MV: usize = 2;
34pub const PRIMARY_REF_NONE: u32 = 7;
35pub const SUPERRES_DENOM_BITS: usize = 3;
36pub const SUPERRES_DENOM_MIN: usize = 9;
37pub const SUPERRES_NUM: usize = 8;
38pub const MAX_TILE_WIDTH: u32 = 4096;
39pub const MAX_TILE_HEIGHT: u32 = 2304;
40pub const MAX_TILE_AREA: u32 = MAX_TILE_WIDTH * MAX_TILE_HEIGHT;
41pub const RESTORATION_TILESIZE_MAX: u16 = 256;
42pub const WARPEDMODEL_PREC_BITS: u32 = 16;
43pub const WARP_PARAM_REDUCE_BITS: u32 = 6;
44pub const GM_ABS_ALPHA_BITS: u32 = 12;
45pub const GM_ALPHA_PREC_BITS: u32 = 15;
46pub const GM_ABS_TRANS_ONLY_BITS: u32 = 9;
47pub const GM_TRANS_ONLY_PREC_BITS: u32 = 3;
48pub const GM_ABS_TRANS_BITS: u32 = 12;
49pub const GM_TRANS_PREC_BITS: u32 = 6;
50
51pub const FEATURE_BITS: [u8; SEG_LVL_MAX] = [8, 6, 6, 6, 6, 3, 0, 0];
53pub const FEATURE_SIGNED: [bool; SEG_LVL_MAX] = [true, true, true, true, true, false, false, false];
55pub const FEATURE_MAX: [i32; SEG_LVL_MAX] = [255, 63, 63, 63, 63, 7, 0, 0];
57
58pub enum ObuAction<'a> {
60 Process(Obu<'a>),
62 Drop(u32),
65}
66
67#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
68pub 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
88impl TryFrom<u32> for ObuType {
89 type Error = String;
90
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)]
115pub enum Profile {
116 #[default]
117 Profile0 = 0,
118 Profile1 = 1,
119 Profile2 = 2,
120}
121
122impl TryFrom<u32> for Profile {
123 type Error = String;
124
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)]
136pub 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
144impl ObuHeader {
145 #[allow(clippy::len_without_is_empty)]
147 pub fn len(&self) -> usize {
148 if self.extension_flag {
149 2
150 } else {
151 1
152 }
153 }
154}
155
156#[derive(Clone, Debug, Default, PartialEq, Eq)]
158pub struct Obu<'a> {
159 pub header: ObuHeader,
161 pub bytes_used: usize,
163 data: Cow<'a, [u8]>,
165}
166
167impl<'a> AsRef<[u8]> for Obu<'a> {
168 fn as_ref(&self) -> &[u8] {
169 self.data.as_ref()
170 }
171}
172
173pub 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
193impl<'a> ParsedObu<'a> {
194 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)]
217pub struct Tile {
218 pub tile_offset: u32,
220 pub tile_size: u32,
222 pub tile_row: u32,
224 pub tile_col: u32,
226 pub mi_row_start: u32,
228 pub mi_row_end: u32,
230 pub mi_col_start: u32,
232 pub mi_col_end: u32,
234}
235
236#[derive(Clone, Debug, Default, PartialEq, Eq)]
237pub struct TileGroupObu<'a> {
238 pub obu: Obu<'a>,
240 pub tile_start_and_end_present_flag: bool,
243 pub tg_start: u32,
246 pub tg_end: u32,
249 pub tiles: Vec<Tile>,
254}
255
256#[derive(Clone, Debug, Default, PartialEq, Eq)]
257pub struct OperatingPoint {
258 pub seq_level_idx: u8,
261 pub seq_tier: u8,
264 pub idc: u16,
267 pub decoder_model_present_for_this_op: bool,
271 pub decoder_buffer_delay: u32,
277 pub encoder_buffer_delay: u32,
282 pub low_delay_mode_flag: bool,
287 pub initial_display_delay_present_for_this_op: bool,
291 pub initial_display_delay_minus_1: u32,
298}
299
300#[derive(Clone, Debug, Default, PartialEq, Eq)]
301pub struct TimingInfo {
302 pub num_units_in_display_tick: u32,
307 pub time_scale: u32,
309 pub equal_picture_interval: bool,
315 pub num_ticks_per_picture_minus_1: u32,
318}
319
320#[derive(Clone, Debug, Default, PartialEq, Eq)]
321pub struct DecoderModelInfo {
322 pub buffer_delay_length_minus_1: u8,
325 pub num_units_in_decoding_tick: u32,
328 pub buffer_removal_time_length_minus_1: u8,
331 pub frame_presentation_time_length_minus_1: u32,
334}
335
336#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
339pub 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
355impl TryFrom<u32> for ColorPrimaries {
356 type Error = String;
357
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)]
378pub 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
401impl TryFrom<u32> for TransferCharacteristics {
402 type Error = String;
403
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)]
431pub enum BitDepth {
432 #[default]
433 Depth8 = 0,
434 Depth10 = 1,
435 Depth12 = 2,
436}
437
438impl TryFrom<u32> for BitDepth {
439 type Error = String;
440
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)]
452pub 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
471impl TryFrom<u32> for MatrixCoefficients {
472 type Error = String;
473
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)]
497pub enum ChromaSamplePosition {
498 #[default]
499 Unknown = 0,
500 Vertical = 1,
501 Colocated = 2,
502 Reserved = 3,
503}
504
505impl TryFrom<u32> for ChromaSamplePosition {
506 type Error = String;
507
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)]
520pub struct ColorConfig {
521 pub high_bitdepth: bool,
524 pub twelve_bit: bool,
527 pub mono_chrome: bool,
530 pub color_description_present_flag: bool,
535 pub color_primaries: ColorPrimaries,
537 pub transfer_characteristics: TransferCharacteristics,
540 pub matrix_coefficients: MatrixCoefficients,
543 pub color_range: bool,
549 pub subsampling_x: bool,
551 pub subsampling_y: bool,
553 pub chroma_sample_position: ChromaSamplePosition,
555 pub separate_uv_delta_q: bool,
559}
560
561#[derive(Clone, Debug, Default, PartialEq, Eq)]
562pub struct SequenceHeaderObu {
563 pub obu_header: ObuHeader,
565 pub seq_profile: Profile,
567 pub still_picture: bool,
571 pub reduced_still_picture_header: bool,
574 pub frame_width_bits_minus_1: u8,
577 pub frame_height_bits_minus_1: u8,
580 pub max_frame_width_minus_1: u16,
583 pub max_frame_height_minus_1: u16,
586 pub frame_id_numbers_present_flag: bool,
589 pub delta_frame_id_length_minus_2: u32,
592 pub additional_frame_id_length_minus_1: u32,
595 pub use_128x128_superblock: bool,
600 pub enable_filter_intra: bool,
604 pub enable_intra_edge_filter: bool,
606 pub enable_interintra_compound: bool,
610 pub enable_masked_compound: bool,
614 pub enable_warped_motion: bool,
618 pub enable_order_hint: bool,
622 pub enable_dual_filter: bool,
627 pub enable_jnt_comp: bool,
630 pub enable_ref_frame_mvs: bool,
634 pub seq_choose_screen_content_tools: bool,
639 pub seq_force_screen_content_tools: u32,
644 pub seq_choose_integer_mv: bool,
648 pub seq_force_integer_mv: u32,
653 pub order_hint_bits_minus_1: i32,
655 pub order_hint_bits: i32,
657 pub enable_superres: bool,
662 pub enable_cdef: bool,
665 pub enable_restoration: bool,
668 pub film_grain_params_present: bool,
671 pub operating_points_cnt_minus_1: u32,
675 pub operating_points: [OperatingPoint; MAX_NUM_OPERATING_POINTS],
677 pub decoder_model_info_present_flag: bool,
680 pub decoder_model_info: DecoderModelInfo,
682 pub initial_display_delay_present_flag: bool,
685 pub timing_info_present_flag: bool,
687 pub timing_info: TimingInfo,
689 pub color_config: ColorConfig,
691
692 pub bit_depth: BitDepth,
694 pub num_planes: u32,
695}
696
697#[derive(Clone, Debug, Default, PartialEq, Eq)]
698pub struct StreamInfo {
699 pub seq_header: Rc<SequenceHeaderObu>,
700 pub render_width: u32,
701 pub render_height: u32,
702}
703
704#[derive(Clone, Debug, Default, PartialEq, Eq)]
706pub struct TemporalDelimiterObu {
707 pub obu_header: ObuHeader,
708}
709
710#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
711pub enum InterpolationFilter {
712 #[default]
713 EightTap = 0,
714 EightTapSmooth = 1,
715 EightTapSharp = 2,
716 Bilinear = 3,
717 Switchable = 4,
718}
719
720impl TryFrom<u32> for InterpolationFilter {
721 type Error = String;
722
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)]
736pub enum TxModes {
737 #[default]
738 Only4x4 = 0,
739 Largest = 1,
740 Select = 2,
741}
742
743impl TryFrom<u32> for TxModes {
744 type Error = String;
745
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)]
757pub enum FrameRestorationType {
758 #[default]
759 None = 0,
760 Wiener = 1,
761 Sgrproj = 2,
762 Switchable = 3,
763}
764
765impl TryFrom<u32> for FrameRestorationType {
766 type Error = String;
767
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)]
780pub 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
792impl TryFrom<u32> for ReferenceFrameType {
793 type Error = String;
794
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)]
811pub enum WarpModelType {
812 #[default]
813 Identity = 0,
814 Translation = 1,
815 RotZoom = 2,
816 Affine = 3,
817}
818
819impl TryFrom<u32> for WarpModelType {
820 type Error = String;
821
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)]
834pub enum FrameType {
835 #[default]
836 KeyFrame = 0,
837 InterFrame = 1,
838 IntraOnlyFrame = 2,
839 SwitchFrame = 3,
840}
841
842impl TryFrom<u32> for FrameType {
843 type Error = String;
844
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)]
857pub enum TxMode {
858 #[default]
859 Only4x4 = 0,
860 Largest = 1,
861 Select = 2,
862}
863
864impl TryFrom<u32> for TxMode {
865 type Error = String;
866
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)]
878pub struct FrameObu<'a> {
879 pub header: FrameHeaderObu,
880 pub tile_group: TileGroupObu<'a>,
881}
882
883#[derive(Clone, Debug, Default, PartialEq, Eq)]
885pub struct FrameHeaderObu {
886 pub obu_header: ObuHeader,
889 pub show_existing_frame: bool,
892 pub frame_to_show_map_idx: u8,
895 pub frame_presentation_time: u32,
898 pub display_frame_id: u32,
900 pub frame_type: FrameType,
902 pub show_frame: bool,
907 pub showable_frame: bool,
911 pub error_resilient_mode: bool,
915 pub disable_cdf_update: bool,
918 pub allow_screen_content_tools: u32,
921 pub force_integer_mv: u32,
924 pub current_frame_id: u32,
929 pub frame_size_override_flag: bool,
934 pub order_hint: u32,
937 pub primary_ref_frame: u32,
940 pub buffer_removal_time_present_flag: bool,
943 pub buffer_removal_time: Vec<u32>,
949 pub refresh_frame_flags: u32,
952 pub ref_order_hint: [u32; NUM_REF_FRAMES],
954 pub allow_intrabc: bool,
957 pub frame_refs_short_signaling: bool,
961 pub last_frame_idx: u8,
963 pub gold_frame_idx: u8,
965 pub ref_frame_idx: [u8; REFS_PER_FRAME],
967 pub allow_high_precision_mv: bool,
971 pub is_motion_mode_switchable: bool,
973 pub use_ref_frame_mvs: bool,
977 pub disable_frame_end_update_cdf: bool,
980 pub allow_warped_motion: bool,
984 pub reduced_tx_set: bool,
987 pub render_and_frame_size_different: bool,
991 pub use_superres: bool,
994 pub is_filter_switchable: bool,
998 pub interpolation_filter: InterpolationFilter,
1000 pub loop_filter_params: LoopFilterParams,
1002 pub quantization_params: QuantizationParams,
1004 pub segmentation_params: SegmentationParams,
1006 pub tile_info: TileInfo,
1008 pub cdef_params: CdefParams,
1010 pub loop_restoration_params: LoopRestorationParams,
1012 pub tx_mode_select: u32,
1014 pub skip_mode_present: bool,
1017 pub reference_select: bool,
1022 pub global_motion_params: GlobalMotionParams,
1024 pub film_grain_params: FilmGrainParams,
1026
1027 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)]
1049pub struct LoopFilterParams {
1050 pub loop_filter_level: [u8; 4],
1055 pub loop_filter_sharpness: u8,
1059 pub loop_filter_delta_enabled: bool,
1063 pub loop_filter_delta_update: bool,
1068 pub loop_filter_ref_deltas: [i8; TOTAL_REFS_PER_FRAME],
1072 pub loop_filter_mode_deltas: [i8; 2],
1076 pub delta_lf_present: bool,
1078 pub delta_lf_res: u8,
1081 pub delta_lf_multi: bool,
1086}
1087
1088#[derive(Clone, Debug, Default, PartialEq, Eq)]
1089pub struct QuantizationParams {
1090 pub base_q_idx: u32,
1093 pub diff_uv_delta: bool,
1096 pub using_qmatrix: bool,
1098 pub qm_y: u32,
1101 pub qm_u: u32,
1104 pub qm_v: u32,
1107 pub delta_q_present: bool,
1109 pub delta_q_res: u32,
1112 pub delta_q_y_dc: i32,
1114 pub delta_q_u_dc: i32,
1116 pub delta_q_u_ac: i32,
1118 pub delta_q_v_dc: i32,
1120 pub delta_q_v_ac: i32,
1122}
1123
1124#[derive(Clone, Debug, Default, PartialEq, Eq)]
1125pub struct SegmentationParams {
1126 pub segmentation_enabled: bool,
1129 pub segmentation_update_map: bool,
1133 pub segmentation_temporal_update: bool,
1138 pub segmentation_update_data: bool,
1142 pub feature_enabled: [[bool; SEG_LVL_MAX]; MAX_SEGMENTS],
1145 pub feature_data: [[i16; SEG_LVL_MAX]; MAX_SEGMENTS],
1147 pub seg_id_pre_skip: bool,
1149 pub last_active_seg_id: u8,
1151}
1152
1153#[derive(Clone, Debug, PartialEq, Eq)]
1154pub struct TileInfo {
1155 pub uniform_tile_spacing_flag: bool,
1160 pub increment_tile_rows_log2: u32,
1162 pub width_in_sbs_minus_1: [u32; MAX_TILE_COLS],
1164 pub height_in_sbs_minus_1: [u32; MAX_TILE_ROWS],
1166 pub context_update_tile_id: u32,
1168 pub mi_col_starts: [u32; MAX_TILE_COLS + 1],
1171 pub mi_row_starts: [u32; MAX_TILE_ROWS + 1],
1174 pub tile_cols_log2: u32,
1177 pub tile_cols: u32,
1179 pub tile_rows_log2: u32,
1182 pub tile_rows: u32,
1184 pub tile_size_bytes: u32,
1186}
1187
1188impl Default for TileInfo {
1189 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)]
1208pub struct CdefParams {
1209 pub cdef_damping: u32,
1211 pub cdef_bits: u32,
1214 pub cdef_y_pri_strength: [u32; CDEF_MAX],
1216 pub cdef_y_sec_strength: [u32; CDEF_MAX],
1218 pub cdef_uv_pri_strength: [u32; CDEF_MAX],
1220 pub cdef_uv_sec_strength: [u32; CDEF_MAX],
1222}
1223
1224#[derive(Clone, Debug, Default, PartialEq, Eq)]
1225pub struct LoopRestorationParams {
1226 pub lr_unit_shift: u8,
1228 pub lr_uv_shift: u8,
1231 pub frame_restoration_type: [FrameRestorationType; MAX_NUM_PLANES],
1233 pub loop_restoration_size: [u16; MAX_NUM_PLANES],
1235 pub uses_lr: bool,
1237 pub uses_chroma_lr: bool,
1239}
1240
1241#[derive(Clone, Debug, Default, PartialEq, Eq)]
1242pub struct GlobalMotionParams {
1243 pub is_global: [bool; NUM_REF_FRAMES],
1246 pub is_rot_zoom: [bool; NUM_REF_FRAMES],
1249 pub is_translation: [bool; NUM_REF_FRAMES],
1252 pub gm_params: [[i32; 6]; NUM_REF_FRAMES],
1256 pub warp_valid: [bool; NUM_REF_FRAMES],
1258 pub gm_type: [WarpModelType; NUM_REF_FRAMES],
1260}
1261
1262#[derive(Clone, Debug, Default, PartialEq, Eq)]
1263pub struct FilmGrainParams {
1264 pub apply_grain: bool,
1267 pub grain_seed: u16,
1270 pub update_grain: bool,
1273 pub film_grain_params_ref_idx: u8,
1276 pub num_y_points: u8,
1279 pub point_y_value: [u8; MAX_NUM_Y_POINTS],
1285 pub point_y_scaling: [u8; MAX_NUM_Y_POINTS],
1288 pub chroma_scaling_from_luma: bool,
1290 pub num_cb_points: u8,
1293 pub point_cb_value: [u8; MAX_NUM_CB_POINTS],
1297 pub point_cb_scaling: [u8; MAX_NUM_CB_POINTS],
1300 pub num_cr_points: u8,
1303 pub point_cr_value: [u8; MAX_NUM_CR_POINTS],
1307 pub point_cr_scaling: [u8; MAX_NUM_CR_POINTS],
1310 pub grain_scaling_minus_8: u8,
1314 pub ar_coeff_lag: u32,
1316 pub ar_coeffs_y_plus_128: [u8; MAX_NUM_POS_LUMA],
1318 pub ar_coeffs_cb_plus_128: [u8; MAX_NUM_POS_LUMA],
1320 pub ar_coeffs_cr_plus_128: [u8; MAX_NUM_POS_LUMA],
1322 pub ar_coeff_shift_minus_6: u8,
1326 pub grain_scale_shift: u8,
1329 pub cb_mult: u8,
1332 pub cb_luma_mult: u8,
1335 pub cb_offset: u16,
1338 pub cr_mult: u8,
1341 pub cr_luma_mult: u8,
1344 pub cr_offset: u16,
1347 pub overlap_flag: bool,
1351 pub clip_to_restricted_range: bool,
1357}
1358
1359#[derive(Clone, Debug, Default, PartialEq, Eq)]
1362struct ReferenceFrameInfo {
1363 ref_valid: bool,
1369 ref_frame_id: u32,
1371 ref_upscaled_width: u32,
1373 ref_frame_width: u32,
1375 ref_frame_height: u32,
1377 ref_render_width: u32,
1379 ref_render_height: u32,
1381 ref_mi_cols: u32,
1383 ref_mi_rows: u32,
1385 ref_frame_type: FrameType,
1387 ref_subsampling_x: bool,
1389 ref_subsampling_y: bool,
1391 ref_bit_depth: BitDepth,
1393 ref_order_hint: u32,
1395 segmentation_params: SegmentationParams,
1397 global_motion_params: GlobalMotionParams,
1399 loop_filter_params: LoopFilterParams,
1401 film_grain_params: FilmGrainParams,
1403 tile_info: TileInfo,
1405 display_frame_id: u32,
1406 showable_frame: bool,
1407}
1408
1409#[derive(Clone, Debug, Default)]
1410pub 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)]
1418enum StreamFormat {
1419 LowOverhead,
1420 AnnexB(AnnexBState),
1421}
1422
1423#[derive(Debug)]
1424pub struct Parser {
1425 stream_format: StreamFormat,
1426 operating_point: u32,
1427 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 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 pub last_frame_header: Option<FrameHeaderObu>,
1450 pub sequence_header: Option<Rc<SequenceHeaderObu>>,
1452}
1453
1454impl Parser {
1455 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 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 let header = Self::parse_obu_header(&mut r.clone())?;
1482 if !matches!(header.obu_type, ObuType::TemporalDelimiter) {
1483 return Ok(false);
1484 }
1485
1486 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 return Ok(true);
1510 }
1511
1512 if num_bytes_read >= frame_unit_size {
1513 return Ok(false);
1516 }
1517 }
1518 }
1519
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 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 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 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
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
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 fn skip_and_check_trailing_bits(r: &mut Reader, obu: &Obu) -> Result<(), String> {
1744 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
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); 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 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 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 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 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 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
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
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
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
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 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
2009 fn parse_temporal_delimiter_obu(&mut self) -> Result<(), String> {
2010 self.seen_frame_header = false;
2011 Ok(())
2012 }
2013
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 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 s.max_frame_width_minus_1 =
2094 r.0.read_bits::<u32>(s.frame_width_bits_minus_1 as usize + 1)? as u16;
2095 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 self.choose_operating_point(0)?;
2182
2183 Ok(rc)
2184 }
2185
2186 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 let seq = self.sequence()?;
2196
2197 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 if fh.frame_type == FrameType::KeyFrame {
2207 fh.current_frame_id = rf.ref_frame_id;
2208 fh.mi_cols = rf.ref_mi_cols;
2210 fh.mi_rows = rf.ref_mi_rows;
2211 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
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
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 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 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
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
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
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
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 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
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
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
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
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
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
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
2866 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
2870 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
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 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
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
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 if fh.primary_ref_frame == PRIMARY_REF_NONE {
2997 #[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 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
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 *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
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
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 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 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 fh.film_grain_params =
3366 self.ref_info[fh.frame_to_show_map_idx as usize].film_grain_params.clone();
3367 }
3368
3369 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 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 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 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 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 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 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 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 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 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 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
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 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 self.seen_frame_header = false;
3854 }
3855
3856 Ok(tg)
3857 }
3858
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
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 self.seen_frame_header = true;
3898 self.last_frame_header = Some(header.clone());
3899 }
3900
3901 Ok(header)
3902 }
3903 }
3904
3905 pub fn ref_frame_update(&mut self, fh: &FrameHeaderObu) -> Result<(), String> {
3908 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
3958 pub fn highest_operating_point(&self) -> Option<u32> {
3959 if self.operating_point_idc == 0 {
3960 None
3962 } else {
3963 Some(helpers::floor_log2((self.operating_point_idc >> 8) as u32))
3964 }
3965 }
3966
3967 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
3994impl Default for Parser {
3995 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
4021impl Clone for Parser {
4022 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)]
4051mod tests {
4052 use crate::bitstream_utils::IvfIterator;
4053 use crate::codec::av1::parser::{ObuAction, Parser, StreamFormat};
4054
4055 use super::ObuType;
4056
4057 const STREAM_TEST_25_FPS: &[u8] = include_bytes!("test_data/test-25fps.ivf.av1");
4059
4060 const STREAM_ANNEXB: &[u8] = include_bytes!("test_data/av1-annexb.ivf.av1");
4070
4071 #[test]
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 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 assert_eq!(num_obus, 525);
4098 }
4099
4100 #[test]
4101 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 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 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 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]
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 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}