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