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