• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use crate::bitstream_utils::BitReader;
6 use crate::codec::vp9::lookups::AC_QLOOKUP;
7 use crate::codec::vp9::lookups::AC_QLOOKUP_10;
8 use crate::codec::vp9::lookups::AC_QLOOKUP_12;
9 use crate::codec::vp9::lookups::DC_QLOOKUP;
10 use crate::codec::vp9::lookups::DC_QLOOKUP_10;
11 use crate::codec::vp9::lookups::DC_QLOOKUP_12;
12 
13 pub const REFS_PER_FRAME: usize = 3;
14 
15 pub const MAX_REF_LF_DELTAS: usize = 4;
16 pub const MAX_MODE_LF_DELTAS: usize = 2;
17 
18 pub const INTRA_FRAME: usize = 0;
19 pub const LAST_FRAME: usize = 1;
20 pub const GOLDEN_FRAME: usize = 2;
21 pub const ALTREF_FRAME: usize = 3;
22 pub const MAX_REF_FRAMES: usize = 4;
23 
24 pub const MAX_SEGMENTS: usize = 8;
25 pub const SEG_TREE_PROBS: usize = MAX_SEGMENTS - 1;
26 pub const PREDICTION_PROBS: usize = 3;
27 
28 /// Valid segment features values.
29 #[repr(u8)]
30 pub enum SegLvl {
31     AltQ = 0,
32     AltL = 1,
33     RefFrame = 2,
34     LvlSkip = 3,
35 }
36 pub const SEG_LVL_MAX: usize = 4;
37 
38 pub const MAX_LOOP_FILTER: u32 = 63;
39 
40 pub const REF_FRAMES_LOG2: usize = 3;
41 pub const REF_FRAMES: usize = 1 << REF_FRAMES_LOG2;
42 
43 pub const SUPERFRAME_MARKER: u32 = 0x06;
44 pub const MAX_FRAMES_IN_SUPERFRAME: usize = 8;
45 
46 pub const FRAME_MARKER: u32 = 0x02;
47 pub const SYNC_CODE: u32 = 0x498342;
48 
49 pub const MIN_TILE_WIDTH_B64: u32 = 4;
50 pub const MAX_TILE_WIDTH_B64: u32 = 64;
51 
52 /// The number of pictures in the DPB
53 pub const NUM_REF_FRAMES: usize = 8;
54 
55 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
56 pub enum InterpolationFilter {
57     #[default]
58     EightTap = 0,
59     EightTapSmooth = 1,
60     EightTapSharp = 2,
61     Bilinear = 3,
62     Switchable = 4,
63 }
64 
65 impl TryFrom<u32> for InterpolationFilter {
66     type Error = String;
67 
try_from(value: u32) -> Result<Self, Self::Error>68     fn try_from(value: u32) -> Result<Self, Self::Error> {
69         match value {
70             0 => Ok(InterpolationFilter::EightTap),
71             1 => Ok(InterpolationFilter::EightTapSmooth),
72             2 => Ok(InterpolationFilter::EightTapSharp),
73             3 => Ok(InterpolationFilter::Bilinear),
74             4 => Ok(InterpolationFilter::Switchable),
75             _ => Err(format!("Invalid InterpolationFilter {}", value)),
76         }
77     }
78 }
79 
80 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
81 pub enum ReferenceFrameType {
82     Intra = 0,
83     Last = 1,
84     Golden = 2,
85     AltRef = 3,
86 }
87 
88 impl TryFrom<u32> for ReferenceFrameType {
89     type Error = String;
90 
try_from(value: u32) -> Result<Self, Self::Error>91     fn try_from(value: u32) -> Result<Self, Self::Error> {
92         match value {
93             0 => Ok(ReferenceFrameType::Intra),
94             1 => Ok(ReferenceFrameType::Last),
95             2 => Ok(ReferenceFrameType::Golden),
96             3 => Ok(ReferenceFrameType::AltRef),
97             _ => Err(format!("Invalid ReferenceFrameType {}", value)),
98         }
99     }
100 }
101 
102 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
103 pub enum FrameType {
104     #[default]
105     KeyFrame = 0,
106     InterFrame = 1,
107 }
108 
109 impl TryFrom<u8> for FrameType {
110     type Error = String;
111 
try_from(value: u8) -> Result<Self, Self::Error>112     fn try_from(value: u8) -> Result<Self, Self::Error> {
113         match value {
114             0 => Ok(FrameType::KeyFrame),
115             1 => Ok(FrameType::InterFrame),
116             _ => Err(format!("Invalid FrameType {}", value)),
117         }
118     }
119 }
120 
121 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
122 pub enum Profile {
123     #[default]
124     Profile0 = 0,
125     Profile1 = 1,
126     Profile2 = 2,
127     Profile3 = 3,
128 }
129 
130 impl TryFrom<u32> for Profile {
131     type Error = String;
132 
try_from(value: u32) -> Result<Self, Self::Error>133     fn try_from(value: u32) -> Result<Self, Self::Error> {
134         match value {
135             0 => Ok(Profile::Profile0),
136             1 => Ok(Profile::Profile1),
137             2 => Ok(Profile::Profile2),
138             3 => Ok(Profile::Profile3),
139             _ => Err(format!("Invalid Profile {}", value)),
140         }
141     }
142 }
143 
144 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
145 pub enum BitDepth {
146     #[default]
147     Depth8 = 8,
148     Depth10 = 10,
149     Depth12 = 12,
150 }
151 
152 impl TryFrom<u32> for BitDepth {
153     type Error = String;
154 
try_from(value: u32) -> Result<Self, Self::Error>155     fn try_from(value: u32) -> Result<Self, Self::Error> {
156         match value {
157             8 => Ok(BitDepth::Depth8),
158             10 => Ok(BitDepth::Depth10),
159             12 => Ok(BitDepth::Depth12),
160             _ => Err(format!("Invalid BitDepth {}", value)),
161         }
162     }
163 }
164 
165 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
166 pub enum ColorSpace {
167     #[default]
168     Unknown = 0,
169     Bt601 = 1,
170     Bt709 = 2,
171     Smpte170 = 3,
172     Smpte240 = 4,
173     Bt2020 = 5,
174     Reserved2 = 6,
175     CsSrgb = 7,
176 }
177 
178 impl TryFrom<u32> for ColorSpace {
179     type Error = String;
180 
try_from(value: u32) -> Result<Self, Self::Error>181     fn try_from(value: u32) -> Result<Self, Self::Error> {
182         match value {
183             0 => Ok(ColorSpace::Unknown),
184             1 => Ok(ColorSpace::Bt601),
185             2 => Ok(ColorSpace::Bt709),
186             3 => Ok(ColorSpace::Smpte170),
187             4 => Ok(ColorSpace::Smpte240),
188             5 => Ok(ColorSpace::Bt2020),
189             6 => Ok(ColorSpace::Reserved2),
190             7 => Ok(ColorSpace::CsSrgb),
191             _ => Err(format!("Invalid ColorSpace {}", value)),
192         }
193     }
194 }
195 
196 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
197 pub enum ColorRange {
198     #[default]
199     StudioSwing = 0,
200     FullSwing = 1,
201 }
202 
203 impl TryFrom<u32> for ColorRange {
204     type Error = String;
205 
try_from(value: u32) -> Result<Self, Self::Error>206     fn try_from(value: u32) -> Result<Self, Self::Error> {
207         match value {
208             0 => Ok(ColorRange::StudioSwing),
209             1 => Ok(ColorRange::FullSwing),
210             _ => Err(format!("Invalid ColorRange {}", value)),
211         }
212     }
213 }
214 
215 #[derive(Clone, Debug, Default, PartialEq, Eq)]
216 pub struct LoopFilterParams {
217     /// Indicates the loop filter strength.
218     pub level: u8,
219     /// Indicates the sharpness level. The loop filter level and loop
220     /// filter_sharpness together determine when a block edge is filtered, and
221     /// by how much the filtering can change the sample values.
222     pub sharpness: u8,
223     /// If set, means that the filter level depends on the mode and reference
224     /// frame used to predict a block. If unset, means that the filter level
225     /// does not depend on the mode and reference frame.
226     pub delta_enabled: bool,
227     /// If set, means that the bitstream contains additional syntax elements
228     /// that specify which mode and reference frame deltas are to be updated. If
229     /// unset, means that these syntax elements are not present.
230     pub delta_update: bool,
231     /// If set, means that the bitstream contains additional syntax elements
232     /// that specify which mode and reference frame deltas are to be updated. If
233     /// unset, means that these syntax elements are not present.
234     pub update_ref_delta: [bool; MAX_REF_LF_DELTAS],
235     /// Contains the adjustment needed for the filter level based on the chosen
236     /// reference frame. If this syntax element is not present in the bitstream,
237     /// it maintains its previous value.
238     pub ref_deltas: [i8; MAX_REF_LF_DELTAS],
239     ///  If set, means that the bitstream contains the syntax element
240     ///  loop_filter_mode_deltas. If unset, means that the bitstream does not
241     ///  contain this syntax element.
242     pub update_mode_delta: [bool; MAX_MODE_LF_DELTAS],
243     /// Contains the adjustment needed for the filter level based on the chosen
244     /// mode. If this syntax element is not present in the bitstream, it
245     /// maintains its previous value.
246     pub mode_deltas: [i8; MAX_MODE_LF_DELTAS],
247 }
248 
249 #[derive(Clone, Debug, Default, PartialEq, Eq)]
250 pub struct QuantizationParams {
251     /// Indicates the base frame qindex. This is used for Y AC coefficients and
252     /// as the base value for the other quantizers.
253     pub base_q_idx: u8,
254     /// Indicates the Y DC quantizer relative to base_q_idx.
255     pub delta_q_y_dc: i8,
256     /// Indicates the UV DC quantizer relative to base_q_idx.
257     pub delta_q_uv_dc: i8,
258     /// Indicates the UV AC quantizer relative to base_q_idx.
259     pub delta_q_uv_ac: i8,
260 }
261 
262 #[derive(Clone, Debug, Default, PartialEq, Eq)]
263 pub struct SegmentationParams {
264     ///  If set, indicates that this frame makes use of the segmentation tool.
265     ///  If unset, indicates that the frame does not use segmentation.
266     pub enabled: bool,
267     /// If set, indicates that the segmentation map should be updated during
268     /// the decoding of this frame. If unset, means that the segmentation map
269     /// from the previous frame is used.
270     pub update_map: bool,
271     /// Specify the probability values to be used when decoding segment_id.
272     pub tree_probs: [u8; SEG_TREE_PROBS],
273     /// Specify the probability values to be used when decoding seg_id_predicted.
274     pub pred_probs: [u8; PREDICTION_PROBS],
275     /// If set, indicates that the updates to the segmentation map are coded
276     /// relative to the existing segmentation map. If unset,
277     /// indicates that the new segmentation map is coded without
278     /// reference to the existing segmentation map.
279     pub temporal_update: bool,
280     /// If set, indicates that new parameters are about to be specified for each
281     /// segment. If unset, indicates that the segmentation parameters should
282     /// keep their existing values.
283     pub update_data: bool,
284     /// If unset, indicates that the segmentation parameters represent
285     /// adjustments relative to the standard values. If set, indicates that the
286     /// segmentation parameters represent the actual values to be used.
287     pub abs_or_delta_update: bool,
288     /// If unset, indicates that the corresponding feature is unused and has
289     /// value equal to 0. if set, indicates that the feature value is coded in
290     /// the bitstream.
291     pub feature_enabled: [[bool; SEG_LVL_MAX]; MAX_SEGMENTS],
292     /// Specifies the magnitude of the feature data for a segment feature.
293     pub feature_data: [[i16; SEG_LVL_MAX]; MAX_SEGMENTS],
294 }
295 
296 impl SegmentationParams {
297     /// Returns whether `feature` is enabled for `segment_id`.
is_feature_enabled(&self, segment_id: u8, feature: SegLvl) -> bool298     fn is_feature_enabled(&self, segment_id: u8, feature: SegLvl) -> bool {
299         self.feature_enabled[segment_id as usize][feature as usize]
300     }
301 
302     /// An implementation of seg_feature_active as per "6.4.9 Segmentation feature active syntax"
is_feature_active(&self, segment_id: u8, feature: SegLvl) -> bool303     fn is_feature_active(&self, segment_id: u8, feature: SegLvl) -> bool {
304         self.enabled && self.is_feature_enabled(segment_id, feature)
305     }
306 
307     /// Returns the data for `feature` on `segment_id`.
feature_data(&self, segment_id: u8, feature: SegLvl) -> i16308     fn feature_data(&self, segment_id: u8, feature: SegLvl) -> i16 {
309         self.feature_data[segment_id as usize][feature as usize]
310     }
311 }
312 
313 #[derive(Clone, Debug, Default, PartialEq, Eq)]
314 pub struct Segmentation {
315     /// Loop filter level
316     pub lvl_lookup: [[u8; MAX_MODE_LF_DELTAS]; MAX_REF_FRAMES],
317 
318     /// AC quant scale for luma component
319     pub luma_ac_quant_scale: i16,
320     /// DC quant scale for luma component
321     pub luma_dc_quant_scale: i16,
322     /// AC quant scale for chroma component
323     pub chroma_ac_quant_scale: i16,
324     /// DC quant scale for chroma component
325     pub chroma_dc_quant_scale: i16,
326 
327     /// Whether the alternate reference frame segment feature is enabled (SEG_LVL_REF_FRAME)
328     pub reference_frame_enabled: bool,
329     /// The feature data for the reference frame featire
330     pub reference_frame: i16,
331     /// Whether the skip segment feature is enabled (SEG_LVL_SKIP)
332     pub reference_skip_enabled: bool,
333 }
334 
335 impl Segmentation {
336     /// Update the state of the segmentation parameters after seeing a frame
update_segmentation(segmentation: &mut [Segmentation; MAX_SEGMENTS], hdr: &Header)337     pub fn update_segmentation(segmentation: &mut [Segmentation; MAX_SEGMENTS], hdr: &Header) {
338         let lf = &hdr.lf;
339         let seg = &hdr.seg;
340 
341         let n_shift = lf.level >> 5;
342 
343         for segment_id in 0..MAX_SEGMENTS as u8 {
344             let luma_dc_quant_scale = hdr.get_dc_quant(segment_id, true);
345             let luma_ac_quant_scale = hdr.get_ac_quant(segment_id, true);
346             let chroma_dc_quant_scale = hdr.get_dc_quant(segment_id, false);
347             let chroma_ac_quant_scale = hdr.get_ac_quant(segment_id, false);
348 
349             let mut lvl_lookup: [[u8; MAX_MODE_LF_DELTAS]; MAX_REF_FRAMES];
350 
351             if lf.level == 0 {
352                 lvl_lookup = Default::default()
353             } else {
354                 let mut lvl_seg = i32::from(lf.level);
355 
356                 // 8.8.1 Loop filter frame init process
357                 if hdr.seg.is_feature_active(segment_id, SegLvl::AltL) {
358                     if seg.abs_or_delta_update {
359                         lvl_seg = i32::from(seg.feature_data(segment_id, SegLvl::AltL));
360                     } else {
361                         lvl_seg += i32::from(seg.feature_data(segment_id, SegLvl::AltL));
362                     }
363                 }
364 
365                 let lvl_seg = lvl_seg.clamp(0, MAX_LOOP_FILTER as i32) as u8;
366 
367                 if !lf.delta_enabled {
368                     lvl_lookup = [[lvl_seg; MAX_MODE_LF_DELTAS]; MAX_REF_FRAMES]
369                 } else {
370                     let intra_delta = lf.ref_deltas[INTRA_FRAME] as i32;
371                     let mut intra_lvl = lvl_seg as i32 + (intra_delta << n_shift);
372 
373                     lvl_lookup = segmentation[segment_id as usize].lvl_lookup;
374                     lvl_lookup[INTRA_FRAME][0] = intra_lvl.clamp(0, MAX_LOOP_FILTER as i32) as u8;
375 
376                     // Note, this array has the [0] element unspecified/unused in
377                     // VP9. Confusing, but we do start to index from 1.
378                     #[allow(clippy::needless_range_loop)]
379                     for ref_ in LAST_FRAME..MAX_REF_FRAMES {
380                         for mode in 0..MAX_MODE_LF_DELTAS {
381                             let ref_delta = lf.ref_deltas[ref_] as i32;
382                             let mode_delta = lf.mode_deltas[mode] as i32;
383 
384                             intra_lvl =
385                                 lvl_seg as i32 + (ref_delta << n_shift) + (mode_delta << n_shift);
386 
387                             lvl_lookup[ref_][mode] =
388                                 intra_lvl.clamp(0, MAX_LOOP_FILTER as i32) as u8;
389                         }
390                     }
391                 }
392             }
393 
394             segmentation[usize::from(segment_id)] = Segmentation {
395                 lvl_lookup,
396                 luma_ac_quant_scale,
397                 luma_dc_quant_scale,
398                 chroma_ac_quant_scale,
399                 chroma_dc_quant_scale,
400                 reference_frame_enabled: seg.is_feature_enabled(segment_id, SegLvl::RefFrame),
401                 reference_frame: seg.feature_data(segment_id, SegLvl::RefFrame),
402                 reference_skip_enabled: seg.is_feature_enabled(segment_id, SegLvl::LvlSkip),
403             }
404         }
405     }
406 }
407 
408 #[derive(Clone, Debug, Default, PartialEq, Eq)]
409 struct FrameSize {
410     width: u32,
411     height: u32,
412 }
413 
414 pub struct Frame<'a> {
415     /// The bitstream data for this frame.
416     bitstream: &'a [u8],
417     /// The frame header.
418     pub header: Header,
419     /// The offset into T
420     offset: usize,
421     /// The size of the data in T
422     size: usize,
423 }
424 
425 impl<'a> Frame<'a> {
new(bitstream: &'a [u8], header: Header, offset: usize, size: usize) -> Self426     pub fn new(bitstream: &'a [u8], header: Header, offset: usize, size: usize) -> Self {
427         Self { bitstream, header, offset, size }
428     }
429 }
430 
431 impl<'a> AsRef<[u8]> for Frame<'a> {
as_ref(&self) -> &[u8]432     fn as_ref(&self) -> &[u8] {
433         let data = self.bitstream;
434         &data[self.offset..self.offset + self.size]
435     }
436 }
437 
438 /// A VP9 frame header.
439 #[derive(Clone, Debug, Default, PartialEq, Eq)]
440 pub struct Header {
441     /// A subset of syntax, semantics and algorithms defined in a part.
442     pub profile: Profile,
443     /// The bit depth of the frame.
444     pub bit_depth: BitDepth,
445     /// Specifies the chroma subsampling format.
446     pub subsampling_x: bool,
447     /// Specifies the chroma subsampling format.
448     pub subsampling_y: bool,
449     /// Specifies the color space of the stream.
450     pub color_space: ColorSpace,
451     /// Specifies the black level and range of the luma and chroma signals as
452     /// specified in Rec. ITU-R BT.709-6 and Rec. ITU-R BT.2020-2
453     pub color_range: ColorRange,
454     /// Indicates the frame indexed by frame_to_show_map_idx is to be displayed.
455     /// If unset, indicates that further processing is required.
456     pub show_existing_frame: bool,
457     /// Specifies the frame to be displayed. It is only available if
458     /// show_existing_frame is set.
459     pub frame_to_show_map_idx: u8,
460     /// Indicates whether a frame is a key frame.
461     pub frame_type: FrameType,
462     /// Whether this frame should be displayed.
463     pub show_frame: bool,
464     /// Whether error resilient mode is enabled.
465     pub error_resilient_mode: bool,
466     /// The width of the frame in pixels.
467     pub width: u32,
468     /// The height of the frame in pixels.
469     pub height: u32,
470     /// If unset, means that the render width and height are inferred from the
471     /// frame width and height. If set, means that the render width and height
472     /// are explicitly coded in the bitstream.
473     pub render_and_frame_size_different: bool,
474     /// The render width of the frame in pixels.
475     pub render_width: u32,
476     /// The render height of the frame in pixels.
477     pub render_height: u32,
478     /// If set, indicates that this frame is an intra-only frame. If unset,
479     /// indicates that this frame is a inter frame.
480     pub intra_only: bool,
481     /// Specifies whether the frame context should be reset to default values.
482     pub reset_frame_context: u8,
483     /// Contains a bitmask that specifies which reference frame slots will be
484     /// updated with the current frame after it is decoded.
485     pub refresh_frame_flags: u8,
486     /// Specifies which reference frames are used by inter frames. It is a
487     /// requirement of bitstream conformance that the selected reference frames
488     /// match the current frame in bit depth, profile, chroma subsampling, and
489     /// color space.
490     pub ref_frame_idx: [u8; REFS_PER_FRAME],
491     /// Specifies the intended direction of the motion vector in time for each
492     /// reference frame. A sign bias equal to 0 indicates that the reference
493     /// frame is a backwards reference; a sign bias equal to 1 indicates that
494     /// the reference frame is a forwards reference
495     pub ref_frame_sign_bias: [u8; 4],
496     /// If unset, specifies that motion vectors are specified to quarter pel
497     /// precision. If set, specifies that motion vectors are specified to eighth
498     /// pel precision.
499     pub allow_high_precision_mv: bool,
500     /// The interpolation filter parameters.
501     pub interpolation_filter: InterpolationFilter,
502     /// If set, indicates that the probabilities computed for this frame (after
503     /// adapting to the observed frequencies if adaption is enabled) should be
504     /// stored for reference by future frames. If unset, indicates that the
505     /// probabilities should be discarded at the end of the frame.
506     pub refresh_frame_context: bool,
507     /// Whether parallel decoding mode is enabled.
508     pub frame_parallel_decoding_mode: bool,
509     /// Indicates the frame context to use.
510     pub frame_context_idx: u8,
511     /// The loop filter parameters
512     pub lf: LoopFilterParams,
513     /// The quantization parameters.
514     pub quant: QuantizationParams,
515     /// The segmentation parameters
516     pub seg: SegmentationParams,
517     /// Specifies the base 2 logarithm of the width of each tile (where the
518     /// width is measured in units of 8x8 blocks). It is a requirement of
519     /// bitstream conformance that tile_cols_log2 is less than or equal to 6.
520     pub tile_cols_log2: u8,
521     /// Specifies the base 2 logarithm of the height of each tile (where the
522     /// height is measured in units of 8x8 blocks).
523     pub tile_rows_log2: u8,
524     /// Computed from the syntax elements. If set, indicates that the frame is
525     /// coded using a special 4x4 transform designed for encoding frames that
526     /// are bit-identical with the original frames.
527     pub lossless: bool,
528     /// Indicates the size of the compressed header in bytes.
529     pub header_size_in_bytes: u16,
530     /// Indicates the size of the uncompressed header in bytes.
531     pub uncompressed_header_size_in_bytes: u16,
532 }
533 
534 impl Header {
535     /// An implementation of get_qindex as per "8.6.1 Dequantization functions"
get_qindex(&self, segment_id: u8) -> u8536     fn get_qindex(&self, segment_id: u8) -> u8 {
537         let base_q_idx = self.quant.base_q_idx;
538 
539         if self.seg.is_feature_active(segment_id, SegLvl::AltQ) {
540             let mut data = self.seg.feature_data(segment_id, SegLvl::AltQ) as i32;
541 
542             if !self.seg.abs_or_delta_update {
543                 data += base_q_idx as i32;
544             }
545 
546             data.clamp(0, 255) as u8
547         } else {
548             base_q_idx
549         }
550     }
551 
552     /// An implementation of get_dc_quant as per "8.6.1 Dequantization functions"
get_dc_quant(&self, segment_id: u8, luma: bool) -> i16553     fn get_dc_quant(&self, segment_id: u8, luma: bool) -> i16 {
554         let delta_q_dc =
555             if luma { self.quant.delta_q_y_dc } else { self.quant.delta_q_uv_dc } as i32;
556         let qindex = self.get_qindex(segment_id);
557         let q_table_idx = (qindex as i32 + delta_q_dc).clamp(0, 255) as u8;
558 
559         let table = match self.bit_depth {
560             BitDepth::Depth8 => &DC_QLOOKUP,
561             BitDepth::Depth10 => &DC_QLOOKUP_10,
562             BitDepth::Depth12 => &DC_QLOOKUP_12,
563         };
564 
565         table[q_table_idx as usize]
566     }
567 
568     /// An implementation of get_ac_quant as per "8.6.1 Dequantization functions"
get_ac_quant(&self, segment_id: u8, luma: bool) -> i16569     fn get_ac_quant(&self, segment_id: u8, luma: bool) -> i16 {
570         let delta_q_ac = if luma { 0 } else { self.quant.delta_q_uv_ac } as i32;
571         let qindex = self.get_qindex(segment_id);
572         let q_table_idx = (qindex as i32 + delta_q_ac).clamp(0, 255) as u8;
573 
574         let table = match self.bit_depth {
575             BitDepth::Depth8 => &AC_QLOOKUP,
576             BitDepth::Depth10 => &AC_QLOOKUP_10,
577             BitDepth::Depth12 => &AC_QLOOKUP_12,
578         };
579 
580         table[q_table_idx as usize]
581     }
582 }
583 
584 /// The VP9 superframe header as per Annex B, B.2.1, B.2.2
585 struct SuperframeHeader {
586     /// Indicates the number of frames within this superframe. NOTE - It is
587     /// legal for a superframe to contain just a single frame and have NumFrames
588     /// equal to 1.
589     frames_in_superframe: u32,
590     /// Specifies the size in bytes of frame number i (zero indexed) within this
591     /// superframe.
592     frame_sizes: Vec<usize>,
593 }
594 
595 /// A VP9 bitstream parser.
596 #[derive(Clone, Debug, Default, PartialEq, Eq)]
597 pub struct Parser {
598     bit_depth: BitDepth,
599     subsampling_x: bool,
600     subsampling_y: bool,
601     color_space: ColorSpace,
602     color_range: ColorRange,
603 
604     mi_cols: u32,
605     mi_rows: u32,
606     sb64_cols: u32,
607     sb64_rows: u32,
608 
609     lf: LoopFilterParams,
610     seg: SegmentationParams,
611 
612     reference_frame_sz: [FrameSize; REF_FRAMES],
613 }
614 
615 impl Parser {
parse_superframe_hdr(resource: impl AsRef<[u8]>) -> Result<SuperframeHeader, String>616     fn parse_superframe_hdr(resource: impl AsRef<[u8]>) -> Result<SuperframeHeader, String> {
617         let bitstream = resource.as_ref();
618 
619         // Skip to the end of the chunk.
620         let mut reader = BitReader::new(&bitstream[bitstream.len() - 1..], false);
621 
622         // Try reading a superframe marker.
623         let marker = reader.read_bits::<u32>(3)?;
624 
625         if marker != SUPERFRAME_MARKER {
626             // Not a superframe
627             return Ok(SuperframeHeader {
628                 frames_in_superframe: 1,
629                 frame_sizes: vec![bitstream.len()],
630             });
631         }
632 
633         let bytes_per_framesize = reader.read_bits::<u32>(2)? + 1;
634         let frames_in_superframe = reader.read_bits::<u32>(3)? + 1;
635 
636         if frames_in_superframe > MAX_FRAMES_IN_SUPERFRAME as u32 {
637             return Err(format!(
638                 "Broken stream: too many frames in superframe, expected a maximum of {:?}, found {:?}",
639                 MAX_FRAMES_IN_SUPERFRAME,
640                 frames_in_superframe
641             ));
642         }
643 
644         let sz_index = 2 + frames_in_superframe * bytes_per_framesize;
645 
646         let data = resource.as_ref();
647         let index_offset = data.len() - sz_index as usize;
648         let first_byte = data[index_offset];
649         let last_byte = *data.last().ok_or_else(|| String::from("superframe header is empty"))?;
650 
651         if first_byte != last_byte {
652             // Also not a superframe, we must pass both tests as per the specification.
653             return Ok(SuperframeHeader {
654                 frames_in_superframe: 1,
655                 frame_sizes: vec![bitstream.len()],
656             });
657         }
658 
659         let mut frame_sizes = vec![];
660         let mut reader = BitReader::new(&bitstream[index_offset..], false);
661 
662         // Skip the superframe header.
663         let _ = reader.read_bits::<u32>(8)?;
664 
665         for _ in 0..frames_in_superframe {
666             let mut frame_size = 0;
667 
668             for j in 0..bytes_per_framesize {
669                 frame_size |= reader.read_bits::<u32>(8)? << (j * 8);
670             }
671 
672             frame_sizes.push(frame_size as usize);
673         }
674 
675         Ok(SuperframeHeader { frames_in_superframe, frame_sizes })
676     }
677 
read_signed_8(r: &mut BitReader, nbits: u8) -> Result<i8, String>678     fn read_signed_8(r: &mut BitReader, nbits: u8) -> Result<i8, String> {
679         let value = r.read_bits::<u8>(nbits as usize)?;
680         let negative = r.read_bit()?;
681 
682         if negative {
683             Ok(-(value as i8))
684         } else {
685             Ok(value as i8)
686         }
687     }
688 
parse_frame_marker(r: &mut BitReader) -> Result<(), String>689     fn parse_frame_marker(r: &mut BitReader) -> Result<(), String> {
690         let marker = r.read_bits::<u32>(2)?;
691 
692         if marker != FRAME_MARKER {
693             return Err(format!("Broken stream: expected frame marker, found {:?}", marker));
694         }
695 
696         Ok(())
697     }
698 
parse_profile(r: &mut BitReader) -> Result<Profile, String>699     fn parse_profile(r: &mut BitReader) -> Result<Profile, String> {
700         let low = r.read_bits::<u32>(1)?;
701         let high = r.read_bits::<u32>(1)?;
702 
703         let profile = (high << 1) | low;
704 
705         if profile == 3 {
706             // Skip the reserved bit
707             let _ = r.read_bit()?;
708         }
709 
710         Profile::try_from(profile)
711     }
712 
parse_frame_sync_code(r: &mut BitReader) -> Result<(), String>713     fn parse_frame_sync_code(r: &mut BitReader) -> Result<(), String> {
714         let sync_code = r.read_bits::<u32>(24)?;
715 
716         if sync_code != SYNC_CODE {
717             return Err(format!(
718                 "Broken stream: expected sync code == {:?}, found {:?}",
719                 SYNC_CODE, sync_code
720             ));
721         }
722 
723         Ok(())
724     }
725 
parse_color_config(&mut self, r: &mut BitReader, hdr: &mut Header) -> Result<(), String>726     fn parse_color_config(&mut self, r: &mut BitReader, hdr: &mut Header) -> Result<(), String> {
727         if matches!(hdr.profile, Profile::Profile2 | Profile::Profile3) {
728             let ten_or_twelve_bit = r.read_bit()?;
729             if ten_or_twelve_bit {
730                 hdr.bit_depth = BitDepth::Depth12;
731             } else {
732                 hdr.bit_depth = BitDepth::Depth10
733             }
734         } else {
735             hdr.bit_depth = BitDepth::Depth8;
736         }
737 
738         let color_space = r.read_bits::<u32>(3)?;
739         hdr.color_space = ColorSpace::try_from(color_space)?;
740 
741         if !matches!(hdr.color_space, ColorSpace::CsSrgb) {
742             let color_range = r.read_bits::<u32>(1)?;
743 
744             hdr.color_range = ColorRange::try_from(color_range)?;
745 
746             if matches!(hdr.profile, Profile::Profile1 | Profile::Profile3) {
747                 hdr.subsampling_x = r.read_bit()?;
748                 hdr.subsampling_y = r.read_bit()?;
749 
750                 // Skip the reserved bit
751                 let _ = r.read_bit()?;
752             } else {
753                 hdr.subsampling_x = true;
754                 hdr.subsampling_y = true;
755             }
756         } else {
757             hdr.color_range = ColorRange::FullSwing;
758             if matches!(hdr.profile, Profile::Profile1 | Profile::Profile3) {
759                 hdr.subsampling_x = false;
760                 hdr.subsampling_y = false;
761 
762                 // Skip the reserved bit
763                 let _ = r.read_bit()?;
764             }
765         }
766 
767         self.bit_depth = hdr.bit_depth;
768         self.color_space = hdr.color_space;
769         self.subsampling_x = hdr.subsampling_x;
770         self.subsampling_y = hdr.subsampling_y;
771         self.color_range = hdr.color_range;
772 
773         Ok(())
774     }
775 
compute_image_size(&mut self, width: u32, height: u32)776     fn compute_image_size(&mut self, width: u32, height: u32) {
777         self.mi_cols = (width + 7) >> 3;
778         self.mi_rows = (height + 7) >> 3;
779         self.sb64_cols = (self.mi_cols + 7) >> 3;
780         self.sb64_rows = (self.mi_rows + 7) >> 3;
781     }
782 
parse_frame_size(&mut self, r: &mut BitReader, hdr: &mut Header) -> Result<(), String>783     fn parse_frame_size(&mut self, r: &mut BitReader, hdr: &mut Header) -> Result<(), String> {
784         hdr.width = r.read_bits::<u32>(16)? + 1;
785         hdr.height = r.read_bits::<u32>(16)? + 1;
786         self.compute_image_size(hdr.width, hdr.height);
787         Ok(())
788     }
789 
parse_render_size(r: &mut BitReader, hdr: &mut Header) -> Result<(), String>790     fn parse_render_size(r: &mut BitReader, hdr: &mut Header) -> Result<(), String> {
791         hdr.render_and_frame_size_different = r.read_bit()?;
792         if hdr.render_and_frame_size_different {
793             hdr.render_width = r.read_bits::<u32>(16)? + 1;
794             hdr.render_height = r.read_bits::<u32>(16)? + 1;
795         } else {
796             hdr.render_width = hdr.width;
797             hdr.render_height = hdr.height;
798         }
799 
800         Ok(())
801     }
802 
parse_frame_size_with_refs( &mut self, r: &mut BitReader, hdr: &mut Header, ) -> Result<(), String>803     fn parse_frame_size_with_refs(
804         &mut self,
805         r: &mut BitReader,
806         hdr: &mut Header,
807     ) -> Result<(), String> {
808         let mut found_ref = false;
809 
810         for i in 0..REFS_PER_FRAME {
811             found_ref = r.read_bit()?;
812 
813             if found_ref {
814                 let idx = hdr.ref_frame_idx[i] as usize;
815                 hdr.width = self.reference_frame_sz[idx].width;
816                 hdr.height = self.reference_frame_sz[idx].height;
817                 break;
818             }
819         }
820 
821         if !found_ref {
822             self.parse_frame_size(r, hdr)?;
823         } else {
824             self.compute_image_size(hdr.width, hdr.height)
825         }
826 
827         Self::parse_render_size(r, hdr)
828     }
829 
read_interpolation_filter(r: &mut BitReader) -> Result<InterpolationFilter, String>830     fn read_interpolation_filter(r: &mut BitReader) -> Result<InterpolationFilter, String> {
831         const LITERAL_TO_TYPE: [InterpolationFilter; 4] = [
832             InterpolationFilter::EightTapSmooth,
833             InterpolationFilter::EightTap,
834             InterpolationFilter::EightTapSharp,
835             InterpolationFilter::Bilinear,
836         ];
837 
838         let is_filter_switchable = r.read_bit()?;
839 
840         Ok(if is_filter_switchable {
841             InterpolationFilter::Switchable
842         } else {
843             let raw_interpolation_filter = r.read_bits::<u32>(2)?;
844             LITERAL_TO_TYPE[raw_interpolation_filter as usize]
845         })
846     }
847 
setup_past_independence(&mut self, hdr: &mut Header)848     fn setup_past_independence(&mut self, hdr: &mut Header) {
849         self.seg.feature_enabled = Default::default();
850         self.seg.feature_data = Default::default();
851         self.seg.abs_or_delta_update = false;
852 
853         self.lf.delta_enabled = true;
854         self.lf.ref_deltas[ReferenceFrameType::Intra as usize] = 1;
855         self.lf.ref_deltas[ReferenceFrameType::Last as usize] = 0;
856         self.lf.ref_deltas[ReferenceFrameType::Golden as usize] = -1;
857         self.lf.ref_deltas[ReferenceFrameType::AltRef as usize] = -1;
858 
859         self.lf.mode_deltas = Default::default();
860         hdr.ref_frame_sign_bias = Default::default();
861     }
862 
parse_loop_filter_params( r: &mut BitReader, lf: &mut LoopFilterParams, ) -> Result<(), String>863     fn parse_loop_filter_params(
864         r: &mut BitReader,
865         lf: &mut LoopFilterParams,
866     ) -> Result<(), String> {
867         lf.level = r.read_bits::<u8>(6)?;
868         lf.sharpness = r.read_bits::<u8>(3)?;
869         lf.delta_enabled = r.read_bit()?;
870 
871         if lf.delta_enabled {
872             lf.delta_update = r.read_bit()?;
873             if lf.delta_update {
874                 for i in 0..MAX_REF_LF_DELTAS {
875                     lf.update_ref_delta[i] = r.read_bit()?;
876                     if lf.update_ref_delta[i] {
877                         lf.ref_deltas[i] = Self::read_signed_8(r, 6)?;
878                     }
879                 }
880 
881                 for i in 0..MAX_MODE_LF_DELTAS {
882                     lf.update_mode_delta[i] = r.read_bit()?;
883                     if lf.update_mode_delta[i] {
884                         lf.mode_deltas[i] = Self::read_signed_8(r, 6)?;
885                     }
886                 }
887             }
888         }
889 
890         Ok(())
891     }
892 
read_delta_q(r: &mut BitReader, value: &mut i8) -> Result<(), String>893     fn read_delta_q(r: &mut BitReader, value: &mut i8) -> Result<(), String> {
894         let delta_coded = r.read_bit()?;
895 
896         if delta_coded {
897             *value = Self::read_signed_8(r, 4)?;
898         } else {
899             *value = 0;
900         }
901 
902         Ok(())
903     }
904 
parse_quantization_params(r: &mut BitReader, hdr: &mut Header) -> Result<(), String>905     fn parse_quantization_params(r: &mut BitReader, hdr: &mut Header) -> Result<(), String> {
906         let quant = &mut hdr.quant;
907 
908         quant.base_q_idx = r.read_bits::<u8>(8)?;
909 
910         Self::read_delta_q(r, &mut quant.delta_q_y_dc)?;
911         Self::read_delta_q(r, &mut quant.delta_q_uv_dc)?;
912         Self::read_delta_q(r, &mut quant.delta_q_uv_ac)?;
913 
914         hdr.lossless = quant.base_q_idx == 0
915             && quant.delta_q_y_dc == 0
916             && quant.delta_q_uv_dc == 0
917             && quant.delta_q_uv_ac == 0;
918 
919         Ok(())
920     }
921 
read_prob(r: &mut BitReader) -> Result<u8, String>922     fn read_prob(r: &mut BitReader) -> Result<u8, String> {
923         let prob_coded = r.read_bit()?;
924 
925         let prob = if prob_coded { r.read_bits::<u8>(8)? } else { 255 };
926 
927         Ok(prob)
928     }
929 
parse_segmentation_params( r: &mut BitReader, seg: &mut SegmentationParams, ) -> Result<(), String>930     fn parse_segmentation_params(
931         r: &mut BitReader,
932         seg: &mut SegmentationParams,
933     ) -> Result<(), String> {
934         const SEGMENTATION_FEATURE_BITS: [u8; SEG_LVL_MAX] = [8, 6, 2, 0];
935         const SEGMENTATION_FEATURE_SIGNED: [bool; SEG_LVL_MAX] = [true, true, false, false];
936 
937         seg.update_map = false;
938         seg.update_data = false;
939 
940         seg.enabled = r.read_bit()?;
941 
942         if !seg.enabled {
943             return Ok(());
944         }
945 
946         seg.update_map = r.read_bit()?;
947 
948         if seg.update_map {
949             for i in 0..SEG_TREE_PROBS {
950                 seg.tree_probs[i] = Self::read_prob(r)?;
951             }
952 
953             seg.temporal_update = r.read_bit()?;
954 
955             for i in 0..PREDICTION_PROBS {
956                 seg.pred_probs[i] = if seg.temporal_update { Self::read_prob(r)? } else { 255 };
957             }
958         }
959 
960         seg.update_data = r.read_bit()?;
961 
962         if seg.update_data {
963             seg.abs_or_delta_update = r.read_bit()?;
964             for i in 0..MAX_SEGMENTS {
965                 for j in 0..SEG_LVL_MAX {
966                     seg.feature_enabled[i][j] = r.read_bit()?;
967                     if seg.feature_enabled[i][j] {
968                         let bits_to_read = SEGMENTATION_FEATURE_BITS[j];
969                         let mut feature_value = r.read_bits_signed::<i16>(bits_to_read as usize)?;
970 
971                         if SEGMENTATION_FEATURE_SIGNED[j] {
972                             let feature_sign = r.read_bit()?;
973 
974                             if feature_sign {
975                                 feature_value = -feature_value;
976                             }
977                         }
978 
979                         seg.feature_data[i][j] = feature_value;
980                     }
981                 }
982             }
983         }
984 
985         Ok(())
986     }
987 
calc_min_log2_tile_cols(sb64_cols: u32) -> u8988     fn calc_min_log2_tile_cols(sb64_cols: u32) -> u8 {
989         let mut min_log2 = 0;
990 
991         while (MAX_TILE_WIDTH_B64 << min_log2) < sb64_cols {
992             min_log2 += 1;
993         }
994 
995         min_log2
996     }
997 
calc_max_log2_tile_cols(sb64_cols: u32) -> u8998     fn calc_max_log2_tile_cols(sb64_cols: u32) -> u8 {
999         let mut max_log2 = 1;
1000 
1001         while (sb64_cols >> max_log2) >= MIN_TILE_WIDTH_B64 {
1002             max_log2 += 1;
1003         }
1004 
1005         max_log2 - 1
1006     }
1007 
parse_tile_info(&self, r: &mut BitReader, hdr: &mut Header) -> Result<(), String>1008     fn parse_tile_info(&self, r: &mut BitReader, hdr: &mut Header) -> Result<(), String> {
1009         let max_log2_tile_cols = Self::calc_max_log2_tile_cols(self.sb64_cols);
1010 
1011         hdr.tile_cols_log2 = Self::calc_min_log2_tile_cols(self.sb64_cols);
1012 
1013         while hdr.tile_cols_log2 < max_log2_tile_cols {
1014             let increment_tile_cols_log2 = r.read_bit()?;
1015 
1016             if increment_tile_cols_log2 {
1017                 hdr.tile_cols_log2 += 1;
1018             } else {
1019                 break;
1020             }
1021         }
1022 
1023         hdr.tile_rows_log2 = r.read_bits::<u8>(1)?;
1024 
1025         if hdr.tile_rows_log2 > 0 {
1026             let increment_tile_rows_log2 = r.read_bit()?;
1027             hdr.tile_rows_log2 += increment_tile_rows_log2 as u8;
1028         }
1029 
1030         Ok(())
1031     }
1032 
parse_frame_header( &mut self, resource: impl AsRef<[u8]>, offset: usize, ) -> Result<Header, String>1033     fn parse_frame_header(
1034         &mut self,
1035         resource: impl AsRef<[u8]>,
1036         offset: usize,
1037     ) -> Result<Header, String> {
1038         let data = &resource.as_ref()[offset..];
1039         let mut r = BitReader::new(data, false);
1040         let mut hdr = Header::default();
1041 
1042         Self::parse_frame_marker(&mut r)?;
1043         hdr.profile = Self::parse_profile(&mut r)?;
1044 
1045         hdr.show_existing_frame = r.read_bit()?;
1046 
1047         if hdr.show_existing_frame {
1048             hdr.frame_to_show_map_idx = r.read_bits::<u8>(3)?;
1049             return Ok(hdr);
1050         }
1051 
1052         hdr.frame_type = FrameType::try_from(r.read_bits::<u8>(1)?)?;
1053 
1054         hdr.show_frame = r.read_bit()?;
1055         hdr.error_resilient_mode = r.read_bit()?;
1056 
1057         let frame_is_intra;
1058 
1059         if matches!(hdr.frame_type, FrameType::KeyFrame) {
1060             Self::parse_frame_sync_code(&mut r)?;
1061             self.parse_color_config(&mut r, &mut hdr)?;
1062             self.parse_frame_size(&mut r, &mut hdr)?;
1063             Self::parse_render_size(&mut r, &mut hdr)?;
1064             hdr.refresh_frame_flags = 0xff;
1065             frame_is_intra = true;
1066         } else {
1067             if !hdr.show_frame {
1068                 hdr.intra_only = r.read_bit()?;
1069             }
1070 
1071             frame_is_intra = hdr.intra_only;
1072 
1073             if !hdr.error_resilient_mode {
1074                 hdr.reset_frame_context = r.read_bits::<u8>(2)?;
1075             } else {
1076                 hdr.reset_frame_context = 0;
1077             }
1078 
1079             if hdr.intra_only {
1080                 Self::parse_frame_sync_code(&mut r)?;
1081 
1082                 if !matches!(hdr.profile, Profile::Profile0) {
1083                     self.parse_color_config(&mut r, &mut hdr)?;
1084                 } else {
1085                     hdr.color_space = ColorSpace::Bt601;
1086                     hdr.subsampling_x = true;
1087                     hdr.subsampling_y = true;
1088                     hdr.bit_depth = BitDepth::Depth8;
1089 
1090                     self.color_space = hdr.color_space;
1091                     self.subsampling_x = hdr.subsampling_x;
1092                     self.subsampling_y = hdr.subsampling_y;
1093                     self.bit_depth = hdr.bit_depth;
1094                 }
1095 
1096                 hdr.refresh_frame_flags = r.read_bits::<u8>(8)?;
1097                 self.parse_frame_size(&mut r, &mut hdr)?;
1098                 Self::parse_render_size(&mut r, &mut hdr)?;
1099             } else {
1100                 // Copy from our cached version
1101                 hdr.color_space = self.color_space;
1102                 hdr.color_range = self.color_range;
1103                 hdr.subsampling_x = self.subsampling_x;
1104                 hdr.subsampling_y = self.subsampling_y;
1105                 hdr.bit_depth = self.bit_depth;
1106 
1107                 hdr.refresh_frame_flags = r.read_bits::<u8>(8)?;
1108 
1109                 for i in 0..REFS_PER_FRAME {
1110                     hdr.ref_frame_idx[i] = r.read_bits::<u8>(3)?;
1111                     hdr.ref_frame_sign_bias[ReferenceFrameType::Last as usize + i] =
1112                         r.read_bits::<u8>(1)?;
1113                 }
1114 
1115                 self.parse_frame_size_with_refs(&mut r, &mut hdr)?;
1116                 hdr.allow_high_precision_mv = r.read_bit()?;
1117                 hdr.interpolation_filter = Self::read_interpolation_filter(&mut r)?;
1118             }
1119         }
1120 
1121         if !hdr.error_resilient_mode {
1122             hdr.refresh_frame_context = r.read_bit()?;
1123             hdr.frame_parallel_decoding_mode = r.read_bit()?;
1124         } else {
1125             hdr.refresh_frame_context = false;
1126             hdr.frame_parallel_decoding_mode = true;
1127         }
1128 
1129         hdr.frame_context_idx = r.read_bits::<u8>(2)?;
1130 
1131         if frame_is_intra || hdr.error_resilient_mode {
1132             self.setup_past_independence(&mut hdr);
1133         }
1134 
1135         Self::parse_loop_filter_params(&mut r, &mut self.lf)?;
1136         Self::parse_quantization_params(&mut r, &mut hdr)?;
1137         Self::parse_segmentation_params(&mut r, &mut self.seg)?;
1138         self.parse_tile_info(&mut r, &mut hdr)?;
1139 
1140         hdr.header_size_in_bytes = r.read_bits::<u16>(16)?;
1141 
1142         hdr.lf = self.lf.clone();
1143         hdr.seg = self.seg.clone();
1144 
1145         for i in 0..REF_FRAMES {
1146             let flag = 1 << i;
1147             if hdr.refresh_frame_flags & flag != 0 {
1148                 self.reference_frame_sz[i].width = hdr.width;
1149                 self.reference_frame_sz[i].height = hdr.height;
1150             }
1151         }
1152 
1153         hdr.uncompressed_header_size_in_bytes = (r.position() as u16 + 7) / 8;
1154 
1155         Ok(hdr)
1156     }
1157 
1158     /// Parse a single VP9 frame.
parse_frame<'a>( &mut self, bitstream: &'a [u8], offset: usize, size: usize, ) -> Result<Frame<'a>, String>1159     pub fn parse_frame<'a>(
1160         &mut self,
1161         bitstream: &'a [u8],
1162         offset: usize,
1163         size: usize,
1164     ) -> Result<Frame<'a>, String> {
1165         let header = self.parse_frame_header(bitstream, offset)?;
1166 
1167         Ok(Frame { header, bitstream, offset, size })
1168     }
1169 
1170     /// Parses VP9 frames from the data in `resource`. This can result in more than one frame if the
1171     /// data passed in contains a VP9 superframe.
parse_chunk<'a>(&mut self, resource: &'a [u8]) -> Result<Vec<Frame<'a>>, String>1172     pub fn parse_chunk<'a>(&mut self, resource: &'a [u8]) -> Result<Vec<Frame<'a>>, String> {
1173         let superframe_hdr = Parser::parse_superframe_hdr(resource)?;
1174         let mut offset = 0;
1175 
1176         let mut frames = vec![];
1177 
1178         for i in 0..superframe_hdr.frames_in_superframe {
1179             let frame_sz = superframe_hdr.frame_sizes[i as usize];
1180             let frame = self.parse_frame(resource, offset, frame_sz)?;
1181             offset += frame_sz;
1182             frames.push(frame);
1183         }
1184 
1185         Ok(frames)
1186     }
1187 }
1188 
1189 #[cfg(test)]
1190 mod tests {
1191     use crate::bitstream_utils::IvfIterator;
1192     use crate::codec::vp9::parser::BitDepth;
1193     use crate::codec::vp9::parser::ColorSpace;
1194     use crate::codec::vp9::parser::FrameType;
1195     use crate::codec::vp9::parser::InterpolationFilter;
1196     use crate::codec::vp9::parser::Parser;
1197     use crate::codec::vp9::parser::Profile;
1198     use crate::codec::vp9::parser::MAX_SEGMENTS;
1199     use crate::codec::vp9::parser::SEG_LVL_MAX;
1200 
1201     #[test]
test_parse_superframe()1202     fn test_parse_superframe() {
1203         // Demuxed, raw vp9 superframe
1204         const VP9_TEST_SUPERFRAME: &[u8] = include_bytes!("test_data/vp9-superframe.bin");
1205 
1206         let mut parser = Parser::default();
1207         let frames = parser.parse_chunk(VP9_TEST_SUPERFRAME).expect("Parsing a superframe failed");
1208 
1209         assert_eq!(frames.len(), 2);
1210         assert_eq!(frames[0].offset, 0);
1211         assert_eq!(frames[0].size, 1333);
1212         assert_eq!(frames[1].offset, 1333);
1213         assert_eq!(frames[1].size, 214);
1214     }
1215 
1216     #[test]
test_parse_test25fps()1217     fn test_parse_test25fps() {
1218         // Muxed as IVF
1219         const TEST_STREAM: &[u8] = include_bytes!("test_data/test-25fps.vp9");
1220 
1221         let mut parser = Parser::default();
1222         let ivf_iter = IvfIterator::new(TEST_STREAM);
1223 
1224         for (frame_n, packet) in ivf_iter.enumerate() {
1225             let frames = parser.parse_chunk(packet.as_ref()).expect("Parsing a superframe failed");
1226 
1227             if frame_n == 0 {
1228                 assert_eq!(frames.len(), 1);
1229                 let h = &frames[0].header;
1230 
1231                 assert!(matches!(h.profile, Profile::Profile0));
1232                 assert!(matches!(h.bit_depth, BitDepth::Depth8));
1233 
1234                 assert!(h.subsampling_x);
1235                 assert!(h.subsampling_y);
1236 
1237                 assert!(matches!(h.color_space, ColorSpace::Unknown));
1238                 assert!(matches!(
1239                     h.color_range,
1240                     crate::codec::vp9::parser::ColorRange::StudioSwing
1241                 ));
1242 
1243                 assert!(!h.show_existing_frame);
1244                 assert_eq!(h.frame_to_show_map_idx, 0);
1245 
1246                 assert!(matches!(h.frame_type, FrameType::KeyFrame));
1247                 assert!(h.show_frame);
1248                 assert!(!h.error_resilient_mode);
1249 
1250                 assert_eq!(h.width, 320);
1251                 assert_eq!(h.height, 240);
1252 
1253                 assert!(!h.render_and_frame_size_different);
1254 
1255                 assert_eq!(h.render_width, 320);
1256                 assert_eq!(h.render_height, 240);
1257 
1258                 assert!(!h.intra_only);
1259                 assert_eq!(h.reset_frame_context, 0);
1260 
1261                 assert_eq!(h.refresh_frame_flags, 0xff);
1262                 assert_eq!(h.ref_frame_idx, [0, 0, 0]);
1263                 assert_eq!(h.ref_frame_sign_bias, [0, 0, 0, 0]);
1264 
1265                 assert!(!h.allow_high_precision_mv);
1266                 assert!(matches!(h.interpolation_filter, InterpolationFilter::EightTap));
1267 
1268                 assert!(h.refresh_frame_context);
1269                 assert!(h.frame_parallel_decoding_mode);
1270                 assert_eq!(h.frame_context_idx, 0);
1271 
1272                 let lf = &h.lf;
1273                 assert_eq!(lf.level, 9);
1274                 assert_eq!(lf.sharpness, 0);
1275 
1276                 assert!(lf.delta_enabled);
1277                 assert!(lf.delta_update);
1278 
1279                 assert_eq!(lf.update_ref_delta, [true, false, true, true]);
1280                 assert_eq!(lf.ref_deltas, [1, 0, -1, -1]);
1281 
1282                 assert_eq!(lf.update_mode_delta, [false, false]);
1283 
1284                 let q = &h.quant;
1285 
1286                 assert_eq!(q.base_q_idx, 65);
1287                 assert_eq!(q.delta_q_y_dc, 0);
1288                 assert_eq!(q.delta_q_uv_dc, 0);
1289                 assert_eq!(q.delta_q_uv_ac, 0);
1290 
1291                 let s = &h.seg;
1292 
1293                 assert!(!s.enabled);
1294                 assert!(!s.update_map);
1295                 assert_eq!(s.tree_probs, [0, 0, 0, 0, 0, 0, 0]);
1296                 assert_eq!(s.pred_probs, [0, 0, 0]);
1297                 assert!(!s.temporal_update);
1298                 assert!(!s.update_data);
1299                 assert!(!s.abs_or_delta_update);
1300                 assert_eq!(s.feature_enabled, [[false; SEG_LVL_MAX]; MAX_SEGMENTS]);
1301                 assert_eq!(s.feature_data, [[0; SEG_LVL_MAX]; MAX_SEGMENTS]);
1302 
1303                 assert_eq!(h.tile_cols_log2, 0);
1304                 assert_eq!(h.tile_rows_log2, 0);
1305                 assert_eq!(h.header_size_in_bytes, 120);
1306 
1307                 assert!(!h.lossless);
1308             } else if frame_n == 1 {
1309                 assert_eq!(frames.len(), 2);
1310 
1311                 assert_eq!(frames[0].offset, 0);
1312                 assert_eq!(frames[0].size, 2390);
1313                 assert_eq!(frames[1].offset, 2390);
1314                 assert_eq!(frames[1].size, 108);
1315 
1316                 let h = &frames[0].header;
1317 
1318                 assert!(matches!(h.profile, Profile::Profile0));
1319                 assert!(matches!(h.bit_depth, BitDepth::Depth8));
1320 
1321                 assert!(h.subsampling_x);
1322                 assert!(h.subsampling_y);
1323 
1324                 assert!(matches!(h.color_space, ColorSpace::Unknown));
1325                 assert!(matches!(
1326                     h.color_range,
1327                     crate::codec::vp9::parser::ColorRange::StudioSwing
1328                 ));
1329 
1330                 assert!(!h.show_existing_frame);
1331                 assert_eq!(h.frame_to_show_map_idx, 0);
1332 
1333                 assert!(matches!(h.frame_type, FrameType::InterFrame));
1334                 assert!(!h.show_frame);
1335                 assert!(!h.error_resilient_mode);
1336 
1337                 assert_eq!(h.width, 320);
1338                 assert_eq!(h.height, 240);
1339 
1340                 assert!(!h.render_and_frame_size_different);
1341 
1342                 assert_eq!(h.render_width, 320);
1343                 assert_eq!(h.render_height, 240);
1344 
1345                 assert!(!h.intra_only);
1346                 assert_eq!(h.reset_frame_context, 0);
1347 
1348                 assert_eq!(h.refresh_frame_flags, 4);
1349                 assert_eq!(h.ref_frame_idx, [0, 1, 2]);
1350                 assert_eq!(h.ref_frame_sign_bias, [0, 0, 0, 0]);
1351 
1352                 assert!(h.allow_high_precision_mv);
1353                 assert!(matches!(h.interpolation_filter, InterpolationFilter::EightTap));
1354 
1355                 assert!(h.refresh_frame_context);
1356                 assert!(h.frame_parallel_decoding_mode);
1357                 assert_eq!(h.frame_context_idx, 1);
1358 
1359                 let lf = &h.lf;
1360                 assert_eq!(lf.level, 15);
1361                 assert_eq!(lf.sharpness, 0);
1362 
1363                 assert!(lf.delta_enabled);
1364                 assert!(!lf.delta_update);
1365 
1366                 assert_eq!(lf.update_ref_delta, [true, false, true, true]);
1367                 assert_eq!(lf.ref_deltas, [1, 0, -1, -1]);
1368 
1369                 assert_eq!(lf.update_mode_delta, [false, false]);
1370 
1371                 let q = &h.quant;
1372 
1373                 assert_eq!(q.base_q_idx, 112);
1374                 assert_eq!(q.delta_q_y_dc, 0);
1375                 assert_eq!(q.delta_q_uv_dc, 0);
1376                 assert_eq!(q.delta_q_uv_ac, 0);
1377 
1378                 let s = &h.seg;
1379 
1380                 assert!(!s.enabled);
1381                 assert!(!s.update_map);
1382                 assert_eq!(s.tree_probs, [0, 0, 0, 0, 0, 0, 0]);
1383                 assert_eq!(s.pred_probs, [0, 0, 0]);
1384                 assert!(!s.temporal_update);
1385                 assert!(!s.update_data);
1386                 assert!(!s.abs_or_delta_update);
1387                 assert_eq!(s.feature_enabled, [[false; SEG_LVL_MAX]; MAX_SEGMENTS]);
1388                 assert_eq!(s.feature_data, [[0; SEG_LVL_MAX]; MAX_SEGMENTS]);
1389 
1390                 assert_eq!(h.tile_cols_log2, 0);
1391                 assert_eq!(h.tile_rows_log2, 0);
1392                 assert_eq!(h.header_size_in_bytes, 48);
1393 
1394                 assert!(!h.lossless);
1395 
1396                 let h = &frames[1].header;
1397 
1398                 assert!(matches!(h.profile, Profile::Profile0));
1399                 assert!(matches!(h.bit_depth, BitDepth::Depth8));
1400 
1401                 assert!(h.subsampling_x);
1402                 assert!(h.subsampling_y);
1403 
1404                 assert!(matches!(h.color_space, ColorSpace::Unknown));
1405                 assert!(matches!(
1406                     h.color_range,
1407                     crate::codec::vp9::parser::ColorRange::StudioSwing
1408                 ));
1409 
1410                 assert!(!h.show_existing_frame);
1411                 assert_eq!(h.frame_to_show_map_idx, 0);
1412 
1413                 assert!(matches!(h.frame_type, FrameType::InterFrame));
1414                 assert!(h.show_frame);
1415                 assert!(!h.error_resilient_mode);
1416 
1417                 assert_eq!(h.width, 320);
1418                 assert_eq!(h.height, 240);
1419 
1420                 assert!(!h.render_and_frame_size_different);
1421 
1422                 assert_eq!(h.render_width, 320);
1423                 assert_eq!(h.render_height, 240);
1424 
1425                 assert!(!h.intra_only);
1426                 assert_eq!(h.reset_frame_context, 0);
1427 
1428                 assert_eq!(h.refresh_frame_flags, 1);
1429                 assert_eq!(h.ref_frame_idx, [0, 1, 2]);
1430                 assert_eq!(h.ref_frame_sign_bias, [0, 0, 0, 1]);
1431 
1432                 assert!(!h.allow_high_precision_mv);
1433                 assert!(matches!(h.interpolation_filter, InterpolationFilter::EightTap));
1434 
1435                 assert!(h.refresh_frame_context);
1436                 assert!(h.frame_parallel_decoding_mode);
1437                 assert_eq!(h.frame_context_idx, 0);
1438 
1439                 let lf = &h.lf;
1440                 assert_eq!(lf.level, 36);
1441                 assert_eq!(lf.sharpness, 0);
1442 
1443                 assert!(lf.delta_enabled);
1444                 assert!(!lf.delta_update);
1445 
1446                 assert_eq!(lf.update_ref_delta, [true, false, true, true]);
1447                 assert_eq!(lf.ref_deltas, [1, 0, -1, -1]);
1448 
1449                 assert_eq!(lf.update_mode_delta, [false, false]);
1450 
1451                 let q = &h.quant;
1452 
1453                 assert_eq!(q.base_q_idx, 216);
1454                 assert_eq!(q.delta_q_y_dc, 0);
1455                 assert_eq!(q.delta_q_uv_dc, 0);
1456                 assert_eq!(q.delta_q_uv_ac, 0);
1457 
1458                 let s = &h.seg;
1459 
1460                 assert!(!s.enabled);
1461                 assert!(!s.update_map);
1462                 assert_eq!(s.tree_probs, [0, 0, 0, 0, 0, 0, 0]);
1463                 assert_eq!(s.pred_probs, [0, 0, 0]);
1464                 assert!(!s.temporal_update);
1465                 assert!(!s.update_data);
1466                 assert!(!s.abs_or_delta_update);
1467                 assert_eq!(s.feature_enabled, [[false; SEG_LVL_MAX]; MAX_SEGMENTS]);
1468                 assert_eq!(s.feature_data, [[0; SEG_LVL_MAX]; MAX_SEGMENTS]);
1469 
1470                 assert_eq!(h.tile_cols_log2, 0);
1471                 assert_eq!(h.tile_rows_log2, 0);
1472                 assert_eq!(h.header_size_in_bytes, 9);
1473 
1474                 assert!(!h.lossless);
1475             }
1476         }
1477     }
1478 }
1479