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 //! An Annex B h.265 parser. 6 //! 7 //! Parses VPSs, SPSs, PPSs and Slices from NALUs. 8 9 use std::collections::BTreeMap; 10 use std::io::Read; 11 use std::io::Seek; 12 use std::io::SeekFrom; 13 use std::rc::Rc; 14 15 use crate::bitstream_utils::BitReader; 16 use crate::codec::h264::nalu; 17 use crate::codec::h264::nalu::Header; 18 use crate::codec::h264::parser::Point; 19 use crate::codec::h264::parser::Rect; 20 21 // Given the max VPS id. 22 const MAX_VPS_COUNT: usize = 16; 23 // Given the max SPS id. 24 const MAX_SPS_COUNT: usize = 16; 25 // Given the max PPS id. 26 const MAX_PPS_COUNT: usize = 64; 27 // 7.4.7.1 28 const MAX_REF_IDX_ACTIVE: u32 = 15; 29 30 // 7.4.3.2.1: 31 // num_short_term_ref_pic_sets specifies the number of st_ref_pic_set( ) syntax 32 // structures included in the SPS. The value of num_short_term_ref_pic_sets 33 // shall be in the range of 0 to 64, inclusive. 34 // NOTE 5 – A decoder should allocate memory for a total number of 35 // num_short_term_ref_pic_sets + 1 st_ref_pic_set( ) syntax structures since 36 // there may be a st_ref_pic_set( ) syntax structure directly signalled in the 37 // slice headers of a current picture. A st_ref_pic_set( ) syntax structure 38 // directly signalled in the slice headers of a current picture has an index 39 // equal to num_short_term_ref_pic_sets. 40 const MAX_SHORT_TERM_REF_PIC_SETS: usize = 65; 41 42 // 7.4.3.2.1: 43 const MAX_LONG_TERM_REF_PIC_SETS: usize = 32; 44 45 // From table 7-5. 46 const DEFAULT_SCALING_LIST_0: [u8; 16] = [16; 16]; 47 48 // From Table 7-6. 49 const DEFAULT_SCALING_LIST_1: [u8; 64] = [ 50 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20, 51 21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24, 25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31, 52 29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70, 65, 88, 88, 115, 53 ]; 54 55 // From Table 7-6. 56 const DEFAULT_SCALING_LIST_2: [u8; 64] = [ 57 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20, 58 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28, 59 28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54, 54, 71, 71, 91, 60 ]; 61 62 /// Table 7-1 – NAL unit type codes and NAL unit type classes 63 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] 64 pub enum NaluType { 65 #[default] 66 TrailN = 0, 67 TrailR = 1, 68 TsaN = 2, 69 TsaR = 3, 70 StsaN = 4, 71 StsaR = 5, 72 RadlN = 6, 73 RadlR = 7, 74 RaslN = 8, 75 RaslR = 9, 76 RsvVclN10 = 10, 77 RsvVclR11 = 11, 78 RsvVclN12 = 12, 79 RsvVclR13 = 13, 80 RsvVclN14 = 14, 81 RsvVclR15 = 15, 82 BlaWLp = 16, 83 BlaWRadl = 17, 84 BlaNLp = 18, 85 IdrWRadl = 19, 86 IdrNLp = 20, 87 CraNut = 21, 88 RsvIrapVcl22 = 22, 89 RsvIrapVcl23 = 23, 90 RsvVcl24 = 24, 91 RsvVcl25 = 25, 92 RsvVcl26 = 26, 93 RsvVcl27 = 27, 94 RsvVcl28 = 28, 95 RsvVcl29 = 29, 96 RsvVcl30 = 30, 97 RsvVcl31 = 31, 98 VpsNut = 32, 99 SpsNut = 33, 100 PpsNut = 34, 101 AudNut = 35, 102 EosNut = 36, 103 EobNut = 37, 104 FdNut = 38, 105 PrefixSeiNut = 39, 106 SuffixSeiNut = 40, 107 RsvNvcl41 = 41, 108 RsvNvcl42 = 42, 109 RsvNvcl43 = 43, 110 RsvNvcl44 = 44, 111 RsvNvcl45 = 45, 112 RsvNvcl46 = 46, 113 RsvNvcl47 = 47, 114 } 115 116 impl TryFrom<u32> for NaluType { 117 type Error = String; 118 try_from(value: u32) -> Result<Self, Self::Error>119 fn try_from(value: u32) -> Result<Self, Self::Error> { 120 match value { 121 0 => Ok(NaluType::TrailN), 122 1 => Ok(NaluType::TrailR), 123 2 => Ok(NaluType::TsaN), 124 3 => Ok(NaluType::TsaR), 125 4 => Ok(NaluType::StsaN), 126 5 => Ok(NaluType::StsaR), 127 6 => Ok(NaluType::RadlN), 128 7 => Ok(NaluType::RadlR), 129 8 => Ok(NaluType::RaslN), 130 9 => Ok(NaluType::RaslR), 131 10 => Ok(NaluType::RsvVclN10), 132 11 => Ok(NaluType::RsvVclR11), 133 12 => Ok(NaluType::RsvVclN12), 134 13 => Ok(NaluType::RsvVclR13), 135 14 => Ok(NaluType::RsvVclN14), 136 15 => Ok(NaluType::RsvVclR15), 137 16 => Ok(NaluType::BlaWLp), 138 17 => Ok(NaluType::BlaWRadl), 139 18 => Ok(NaluType::BlaNLp), 140 19 => Ok(NaluType::IdrWRadl), 141 20 => Ok(NaluType::IdrNLp), 142 21 => Ok(NaluType::CraNut), 143 22 => Ok(NaluType::RsvIrapVcl22), 144 23 => Ok(NaluType::RsvIrapVcl23), 145 24 => Ok(NaluType::RsvVcl24), 146 25 => Ok(NaluType::RsvVcl25), 147 26 => Ok(NaluType::RsvVcl26), 148 27 => Ok(NaluType::RsvVcl27), 149 28 => Ok(NaluType::RsvVcl28), 150 29 => Ok(NaluType::RsvVcl29), 151 30 => Ok(NaluType::RsvVcl30), 152 31 => Ok(NaluType::RsvVcl31), 153 32 => Ok(NaluType::VpsNut), 154 33 => Ok(NaluType::SpsNut), 155 34 => Ok(NaluType::PpsNut), 156 35 => Ok(NaluType::AudNut), 157 36 => Ok(NaluType::EosNut), 158 37 => Ok(NaluType::EobNut), 159 38 => Ok(NaluType::FdNut), 160 39 => Ok(NaluType::PrefixSeiNut), 161 40 => Ok(NaluType::SuffixSeiNut), 162 41 => Ok(NaluType::RsvNvcl41), 163 42 => Ok(NaluType::RsvNvcl42), 164 43 => Ok(NaluType::RsvNvcl43), 165 44 => Ok(NaluType::RsvNvcl44), 166 45 => Ok(NaluType::RsvNvcl45), 167 46 => Ok(NaluType::RsvNvcl46), 168 47 => Ok(NaluType::RsvNvcl47), 169 _ => Err(format!("Invalid NaluType {}", value)), 170 } 171 } 172 } 173 174 impl NaluType { 175 /// Whether this is an IDR NALU. is_idr(&self) -> bool176 pub fn is_idr(&self) -> bool { 177 matches!(self, Self::IdrWRadl | Self::IdrNLp) 178 } 179 180 /// Whether this is an IRAP NALU. is_irap(&self) -> bool181 pub fn is_irap(&self) -> bool { 182 let type_ = *self as u32; 183 type_ >= Self::BlaWLp as u32 && type_ <= Self::RsvIrapVcl23 as u32 184 } 185 186 /// Whether this is a BLA NALU. is_bla(&self) -> bool187 pub fn is_bla(&self) -> bool { 188 let type_ = *self as u32; 189 type_ >= Self::BlaWLp as u32 && type_ <= Self::BlaNLp as u32 190 } 191 192 /// Whether this is a CRA NALU. is_cra(&self) -> bool193 pub fn is_cra(&self) -> bool { 194 matches!(self, Self::CraNut) 195 } 196 197 /// Whether this is a RADL NALU. is_radl(&self) -> bool198 pub fn is_radl(&self) -> bool { 199 matches!(self, Self::RadlN | Self::RadlR) 200 } 201 202 /// Whether this is a RASL NALU. is_rasl(&self) -> bool203 pub fn is_rasl(&self) -> bool { 204 matches!(self, Self::RaslN | Self::RaslR) 205 } 206 207 //// Whether this is a SLNR NALU. is_slnr(&self) -> bool208 pub fn is_slnr(&self) -> bool { 209 // From the specification: 210 // If a picture has nal_unit_type equal to TRAIL_N, TSA_N, STSA_N, 211 // RADL_N, RASL_N, RSV_VCL_N10, RSV_VCL_N12 or RSV_VCL_N14, the picture 212 // is an SLNR picture. Otherwise, the picture is a sub-layer reference 213 // picture. 214 matches!( 215 self, 216 Self::TrailN 217 | Self::TsaN 218 | Self::StsaN 219 | Self::RadlN 220 | Self::RaslN 221 | Self::RsvVclN10 222 | Self::RsvVclN12 223 | Self::RsvVclN14 224 ) 225 } 226 } 227 228 #[derive(Clone, Debug, Default, PartialEq, Eq)] 229 pub struct NaluHeader { 230 /// The NALU type. 231 pub type_: NaluType, 232 /// Specifies the identifier of the layer to which a VCL NAL unit belongs or 233 /// the identifier of a layer to which a non-VCL NAL unit applies. 234 pub nuh_layer_id: u8, 235 /// Minus 1 specifies a temporal identifier for the NAL unit. The value of 236 /// nuh_temporal_id_plus1 shall not be equal to 0. 237 pub nuh_temporal_id_plus1: u8, 238 } 239 240 impl NaluHeader { nuh_temporal_id(&self) -> u8241 pub fn nuh_temporal_id(&self) -> u8 { 242 self.nuh_temporal_id_plus1.saturating_sub(1) 243 } 244 } 245 246 impl Header for NaluHeader { parse<T: AsRef<[u8]>>(cursor: &mut std::io::Cursor<T>) -> Result<Self, String>247 fn parse<T: AsRef<[u8]>>(cursor: &mut std::io::Cursor<T>) -> Result<Self, String> { 248 let mut data = [0u8; 2]; 249 cursor.read_exact(&mut data).map_err(|_| String::from("Broken Data"))?; 250 let mut r = BitReader::new(&data, false); 251 let _ = cursor.seek(SeekFrom::Current(-1 * data.len() as i64)); 252 253 // Skip forbidden_zero_bit 254 r.skip_bits(1)?; 255 256 Ok(Self { 257 type_: NaluType::try_from(r.read_bits::<u32>(6)?)?, 258 nuh_layer_id: r.read_bits::<u8>(6)?, 259 nuh_temporal_id_plus1: r.read_bits::<u8>(3)?, 260 }) 261 } 262 is_end(&self) -> bool263 fn is_end(&self) -> bool { 264 matches!(self.type_, NaluType::EosNut | NaluType::EobNut) 265 } 266 len(&self) -> usize267 fn len(&self) -> usize { 268 // 7.3.1.2 269 2 270 } 271 } 272 273 pub type Nalu<'a> = nalu::Nalu<'a, NaluHeader>; 274 275 /// H265 levels as defined by table A.8. 276 /// `general_level_idc` and `sub_layer_level_idc[ OpTid ]` shall be set equal to a 277 /// value of 30 times the level number specified in Table A.8 278 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] 279 pub enum Level { 280 #[default] 281 L1 = 30, 282 L2 = 60, 283 L2_1 = 63, 284 L3 = 90, 285 L3_1 = 93, 286 L4 = 120, 287 L4_1 = 123, 288 L5 = 150, 289 L5_1 = 153, 290 L5_2 = 156, 291 L6 = 180, 292 L6_1 = 183, 293 L6_2 = 186, 294 } 295 296 impl TryFrom<u8> for Level { 297 type Error = String; 298 try_from(value: u8) -> Result<Self, Self::Error>299 fn try_from(value: u8) -> Result<Self, Self::Error> { 300 match value { 301 30 => Ok(Level::L1), 302 60 => Ok(Level::L2), 303 63 => Ok(Level::L2_1), 304 90 => Ok(Level::L3), 305 93 => Ok(Level::L3_1), 306 120 => Ok(Level::L4), 307 123 => Ok(Level::L4_1), 308 150 => Ok(Level::L5), 309 153 => Ok(Level::L5_1), 310 156 => Ok(Level::L5_2), 311 180 => Ok(Level::L6), 312 183 => Ok(Level::L6_1), 313 186 => Ok(Level::L6_2), 314 _ => Err(format!("Invalid Level {}", value)), 315 } 316 } 317 } 318 319 /// H265 profiles. See A.3. 320 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] 321 pub enum Profile { 322 #[default] 323 Main = 1, 324 Main10 = 2, 325 MainStill = 3, 326 RangeExtensions = 4, 327 HighThroughput = 5, 328 MultiviewMain = 6, 329 ScalableMain = 7, 330 ThreeDMain = 8, 331 ScreenContentCoding = 9, 332 ScalableRangeExtensions = 10, 333 HighThroughputScreenContentCoding = 11, 334 } 335 336 impl TryFrom<u8> for Profile { 337 type Error = String; 338 try_from(value: u8) -> Result<Self, Self::Error>339 fn try_from(value: u8) -> Result<Self, Self::Error> { 340 match value { 341 1 => Ok(Profile::Main), 342 2 => Ok(Profile::Main10), 343 3 => Ok(Profile::MainStill), 344 4 => Ok(Profile::RangeExtensions), 345 5 => Ok(Profile::HighThroughput), 346 6 => Ok(Profile::MultiviewMain), 347 7 => Ok(Profile::ScalableMain), 348 8 => Ok(Profile::ThreeDMain), 349 9 => Ok(Profile::ScreenContentCoding), 350 10 => Ok(Profile::ScalableRangeExtensions), 351 11 => Ok(Profile::HighThroughputScreenContentCoding), 352 _ => Err(format!("Invalid Profile {}", value)), 353 } 354 } 355 } 356 357 /// A H.265 Video Parameter Set. 358 #[derive(Clone, Debug, PartialEq, Eq)] 359 pub struct Vps { 360 /// Identifies the VPS for reference by other syntax elements. 361 pub video_parameter_set_id: u8, 362 /// If vps_base_layer_internal_flag is equal to 1 and 363 /// vps_base_layer_available_flag is equal to 1, the base layer is present 364 /// in the bitstream. 365 pub base_layer_internal_flag: bool, 366 /// See `base_layer_internal_flag`. 367 pub base_layer_available_flag: bool, 368 /// Plus 1 specifies the maximum allowed number of layers in each CVS 369 /// referring to the VPS. 370 pub max_layers_minus1: u8, 371 /// Plus 1 specifies the maximum number of temporal sub-layers that may be 372 /// present in each CVS referring to the VPS. 373 pub max_sub_layers_minus1: u8, 374 /// When vps_max_sub_layers_minus1 is greater than 0, specifies whether 375 /// inter prediction is additionally restricted for CVSs referring to the 376 /// VPS. 377 pub temporal_id_nesting_flag: bool, 378 /// ProfileTierLevel() data. 379 pub profile_tier_level: ProfileTierLevel, 380 /// When true, specifies that `vps_max_dec_pic_buffering_minus1[ i ]`, 381 /// `vps_max_num_reorder_pics[ i ]` and `vps_max_latency_increase_plus1[ i ]` 382 /// are present for vps_max_sub_layers_ minus1 + 1 sub-layers. 383 /// vps_sub_layer_ordering_info_present_flag equal to 0 specifies that the 384 /// values of `vps_max_dec_pic_buffering_minus1[ vps_max_sub_layers_minus1 ]`, 385 /// vps_max_num_reorder_pics[ vps_max_sub_ layers_minus1 ] and 386 /// `vps_max_latency_increase_plus1[ vps_max_sub_layers_minus1 ]` apply to all 387 /// sub-layers 388 pub sub_layer_ordering_info_present_flag: bool, 389 /// `max_dec_pic_buffering_minus1[i]` plus 1 specifies the maximum required 390 /// size of the decoded picture buffer for the CVS in units of picture 391 /// storage buffers when HighestTid is equal to i. 392 pub max_dec_pic_buffering_minus1: [u32; 7], 393 /// Indicates the maximum allowed number of pictures with PicOutputFlag 394 /// equal to 1 that can precede any picture with PicOutputFlag equal to 1 in 395 /// the CVS in decoding order and follow that picture with PicOutputFlag 396 /// equal to 1 in output order when HighestTid is equal to i. 397 pub max_num_reorder_pics: [u32; 7], 398 /// When true, `max_latency_increase_plus1[i]` is used to compute the value of 399 /// `VpsMaxLatencyPictures[ i ]`, which specifies the maximum number of 400 /// pictures with PicOutputFlag equal to 1 that can precede any picture with 401 /// PicOutputFlag equal to 1 in the CVS in output order and follow that 402 /// picture with PicOutputFlag equal to 1 in decoding order when HighestTid 403 /// is equal to i. 404 pub max_latency_increase_plus1: [u32; 7], 405 /// Specifies the maximum allowed value of nuh_layer_id of all NAL units in 406 /// each CVS referring to the VPS. 407 pub max_layer_id: u8, 408 /// num_layer_sets_minus1 plus 1 specifies the number of layer sets that are 409 /// specified by the VPS. 410 pub num_layer_sets_minus1: u32, 411 /// When true, specifies that num_units_in_tick, time_scale, 412 /// poc_proportional_to_timing_flag and num_hrd_parameters are present in 413 /// the VPS. 414 pub timing_info_present_flag: bool, 415 /// The number of time units of a clock operating at the frequency 416 /// vps_time_scale Hz that corresponds to one increment (called a clock 417 /// tick) of a clock tick counter. The value of vps_num_units_in_tick shall 418 /// be greater than 0. A clock tick, in units of seconds, is equal to the 419 /// quotient of vps_num_units_in_tick divided by vps_time_scale. For 420 /// example, when the picture rate of a video signal is 25 Hz, 421 /// vps_time_scale may be equal to 27 000 000 and vps_num_units_in_tick may 422 /// be equal to 1 080 000, and consequently a clock tick may be 0.04 423 /// seconds. 424 pub num_units_in_tick: u32, 425 /// The number of time units that pass in one second. For example, a time 426 /// coordinate system that measures time using a 27 MHz clock has a 427 /// vps_time_scale of 27 000 000. 428 pub time_scale: u32, 429 /// When true, indicates that the picture order count value for each picture 430 /// in the CVS that is not the first picture in the CVS, in decoding order, 431 /// is proportional to the output time of the picture relative to the output 432 /// time of the first picture in the CVS. When false, indicates that the 433 /// picture order count value for each picture in the CVS that is not the 434 /// first picture in the CVS, in decoding order, may or may not be 435 /// proportional to the output time of the picture relative to the output 436 /// time of the first picture in the CVS. 437 pub poc_proportional_to_timing_flag: bool, 438 /// num_ticks_poc_diff_one_minus1 plus 1 specifies the number of clock ticks 439 /// corresponding to a difference of picture order count values equal to 1. 440 pub num_ticks_poc_diff_one_minus1: u32, 441 /// Specifies the number of hrd_parameters( ) syntax structures present in 442 /// the VPS RBSP before the vps_extension_flag syntax element. 443 pub num_hrd_parameters: u32, 444 /// `hrd_layer_set_idx[ i ]` specifies the index, into the list of layer sets 445 /// specified by the VPS, of the layer set to which the i-th hrd_parameters( 446 /// ) syntax structure in the VPS applies. 447 pub hrd_layer_set_idx: Vec<u16>, 448 /// `cprms_present_flag[ i ]` equal to true specifies that the HRD parameters 449 /// that are common for all sub-layers are present in the i-th 450 /// hrd_parameters( ) syntax structure in the VPS. `cprms_present_flag[ i ]` 451 /// equal to false specifies that the HRD parameters that are common for all 452 /// sub-layers are not present in the i-th hrd_parameters( ) syntax 453 /// structure in the VPS and are derived to be the same as the ( i − 1 )-th 454 /// hrd_parameters( ) syntax structure in the VPS. `cprms_present_flag[ 0 ]` 455 /// is inferred to be equal to true. 456 pub cprms_present_flag: Vec<bool>, 457 /// The hrd_parameters() data. 458 pub hrd_parameters: Vec<HrdParams>, 459 /// When false, specifies that no vps_extension_data_flag syntax elements 460 /// are present in the VPS RBSP syntax structure. When true, specifies that 461 /// there are vps_extension_data_flag syntax elements present in the VPS 462 /// RBSP syntax structure. Decoders conforming to a profile specified in 463 /// Annex A but not supporting the INBLD capability specified in Annex F 464 /// shall ignore all data that follow the value 1 for vps_extension_flag in 465 /// a VPS NAL unit. 466 pub extension_flag: bool, 467 } 468 469 impl Default for Vps { default() -> Self470 fn default() -> Self { 471 Self { 472 video_parameter_set_id: Default::default(), 473 base_layer_internal_flag: Default::default(), 474 base_layer_available_flag: Default::default(), 475 max_layers_minus1: Default::default(), 476 max_sub_layers_minus1: Default::default(), 477 temporal_id_nesting_flag: Default::default(), 478 profile_tier_level: Default::default(), 479 sub_layer_ordering_info_present_flag: Default::default(), 480 max_dec_pic_buffering_minus1: Default::default(), 481 max_num_reorder_pics: Default::default(), 482 max_latency_increase_plus1: Default::default(), 483 max_layer_id: Default::default(), 484 num_layer_sets_minus1: Default::default(), 485 timing_info_present_flag: Default::default(), 486 num_units_in_tick: Default::default(), 487 time_scale: Default::default(), 488 poc_proportional_to_timing_flag: Default::default(), 489 num_ticks_poc_diff_one_minus1: Default::default(), 490 num_hrd_parameters: Default::default(), 491 hrd_layer_set_idx: Default::default(), 492 cprms_present_flag: vec![true], 493 hrd_parameters: Default::default(), 494 extension_flag: Default::default(), 495 } 496 } 497 } 498 499 #[derive(Clone, Debug, Default, PartialEq, Eq)] 500 pub struct ProfileTierLevel { 501 /// Specifies the context for the interpretation of general_profile_idc and 502 /// `general_profile_compatibility_flag[ j ]` for all values of j in the range 503 /// of 0 to 31, inclusive. 504 pub general_profile_space: u8, 505 /// Specifies the tier context for the interpretation of general_level_idc 506 /// as specified in Annex A. 507 pub general_tier_flag: bool, 508 /// When general_profile_space is equal to 0, indicates a profile to which 509 /// the CVS conforms as specified in Annex A. Bitstreams shall not contain 510 /// values of general_profile_idc other than those specified in Annex A. 511 /// Other values of general_profile_idc are reserved for future use by ITU-T 512 /// | ISO/IEC. 513 pub general_profile_idc: u8, 514 /// `general_profile_compatibility_flag[ j ]` equal to true, when 515 /// general_profile_space is false, indicates that the CVS conforms to the 516 /// profile indicated by general_profile_idc equal to j as specified in 517 /// Annex A. 518 pub general_profile_compatibility_flag: [bool; 32], 519 /// general_progressive_source_flag and general_interlaced_source_flag are 520 /// interpreted as follows: 521 /// 522 /// –If general_progressive_source_flag is true and 523 /// general_interlaced_source_flag is false, the source scan type of the 524 /// pictures in the CVS should be interpreted as progressive only. 525 /// 526 /// –Otherwise, if general_progressive_source_flag is false and 527 /// general_interlaced_source_flag is true, the source scan type of the 528 /// pictures in the CVS should be interpreted as interlaced only. 529 /// 530 /// –Otherwise, if general_progressive_source_flag is false and 531 /// general_interlaced_source_flag is false, the source scan type of the 532 /// pictures in the CVS should be interpreted as unknown or unspecified. 533 /// 534 /// –Otherwise (general_progressive_source_flag is true and 535 /// general_interlaced_source_flag is true), the source scan type of each 536 /// picture in the CVS is indicated at the picture level using the syntax 537 /// element source_scan_type in a picture timing SEI message. 538 pub general_progressive_source_flag: bool, 539 /// See `general_progressive_source_flag`. 540 pub general_interlaced_source_flag: bool, 541 /// If true, specifies that there are no frame packing arrangement SEI 542 /// messages, segmented rectangular frame packing arrangement SEI messages, 543 /// equirectangular projection SEI messages, or cubemap projection SEI 544 /// messages present in the CVS. If false, indicates that there may or may 545 /// not be one or more frame packing arrangement SEI messages, segmented 546 /// rectangular frame packing arrangement SEI messages, equirectangular 547 /// projection SEI messages, or cubemap projection SEI messages present in 548 /// the CVS. 549 pub general_non_packed_constraint_flag: bool, 550 /// When true, specifies that field_seq_flag is false. When false, indicates 551 /// that field_seq_flag may or may not be false. 552 pub general_frame_only_constraint_flag: bool, 553 /// See Annex A. 554 pub general_max_12bit_constraint_flag: bool, 555 /// See Annex A. 556 pub general_max_10bit_constraint_flag: bool, 557 /// See Annex A. 558 pub general_max_8bit_constraint_flag: bool, 559 /// See Annex A. 560 pub general_max_422chroma_constraint_flag: bool, 561 /// See Annex A. 562 pub general_max_420chroma_constraint_flag: bool, 563 /// See Annex A. 564 pub general_max_monochrome_constraint_flag: bool, 565 /// See Annex A. 566 pub general_intra_constraint_flag: bool, 567 /// See Annex A. 568 pub general_lower_bit_rate_constraint_flag: bool, 569 /// See Annex A. 570 pub general_max_14bit_constraint_flag: bool, 571 /// See Annex A. 572 pub general_one_picture_only_constraint_flag: bool, 573 /// When true, specifies that the INBLD capability as specified in Annex F 574 /// is required for decoding of the layer to which the profile_tier_level( ) 575 /// syntax structure applies. When false, specifies that the INBLD 576 /// capability as specified in Annex F is not required for decoding of the 577 /// layer to which the profile_tier_level( ) syntax structure applies. 578 pub general_inbld_flag: bool, 579 /// Indicates a level to which the CVS conforms as specified in Annex A. 580 pub general_level_idc: Level, 581 /// Sub-layer syntax element. 582 pub sub_layer_profile_present_flag: [bool; 6], 583 /// Sub-layer syntax element. 584 pub sub_layer_level_present_flag: [bool; 6], 585 /// Sub-layer syntax element. 586 pub sub_layer_profile_space: [u8; 6], 587 /// Sub-layer syntax element. 588 pub sub_layer_tier_flag: [bool; 6], 589 /// Sub-layer syntax element. 590 pub sub_layer_profile_idc: [u8; 6], 591 /// Sub-layer syntax element. 592 pub sub_layer_profile_compatibility_flag: [[bool; 32]; 6], 593 /// Sub-layer syntax element. 594 pub sub_layer_progressive_source_flag: [bool; 6], 595 /// Sub-layer syntax element. 596 pub sub_layer_interlaced_source_flag: [bool; 6], 597 /// Sub-layer syntax element. 598 pub sub_layer_non_packed_constraint_flag: [bool; 6], 599 /// Sub-layer syntax element. 600 pub sub_layer_frame_only_constraint_flag: [bool; 6], 601 /// Sub-layer syntax element. 602 pub sub_layer_max_12bit_constraint_flag: [bool; 6], 603 /// Sub-layer syntax element. 604 pub sub_layer_max_10bit_constraint_flag: [bool; 6], 605 /// Sub-layer syntax element. 606 pub sub_layer_max_8bit_constraint_flag: [bool; 6], 607 /// Sub-layer syntax element. 608 pub sub_layer_max_422chroma_constraint_flag: [bool; 6], 609 /// Sub-layer syntax element. 610 pub sub_layer_max_420chroma_constraint_flag: [bool; 6], 611 /// Sub-layer syntax element. 612 pub sub_layer_max_monochrome_constraint_flag: [bool; 6], 613 /// Sub-layer syntax element. 614 pub sub_layer_intra_constraint_flag: [bool; 6], 615 /// Sub-layer syntax element. 616 pub sub_layer_one_picture_only_constraint_flag: [bool; 6], 617 /// Sub-layer syntax element. 618 pub sub_layer_lower_bit_rate_constraint_flag: [bool; 6], 619 /// Sub-layer syntax element. 620 pub sub_layer_max_14bit_constraint_flag: [bool; 6], 621 /// Sub-layer syntax element. 622 pub sub_layer_inbld_flag: [bool; 6], 623 /// Sub-layer syntax element. 624 pub sub_layer_level_idc: [Level; 6], 625 } 626 627 impl ProfileTierLevel { max_luma_ps(&self) -> u32628 pub fn max_luma_ps(&self) -> u32 { 629 // See Table A.8. 630 match self.general_level_idc { 631 Level::L1 => 36864, 632 Level::L2 => 122880, 633 Level::L2_1 => 245760, 634 Level::L3 => 552960, 635 Level::L3_1 => 983040, 636 Level::L4 | Level::L4_1 => 2228224, 637 Level::L5 | Level::L5_1 | Level::L5_2 => 8912896, 638 _ => 35651584, 639 } 640 } 641 max_dpb_pic_buf(&self) -> u32642 pub fn max_dpb_pic_buf(&self) -> u32 { 643 if self.general_profile_idc >= 1 && self.general_profile_idc <= 5 { 644 6 645 } else { 646 7 647 } 648 } 649 } 650 651 #[derive(Clone, Debug, Default, PartialEq, Eq)] 652 pub struct SpsRangeExtension { 653 pub transform_skip_rotation_enabled_flag: bool, 654 pub transform_skip_context_enabled_flag: bool, 655 pub implicit_rdpcm_enabled_flag: bool, 656 pub explicit_rdpcm_enabled_flag: bool, 657 pub extended_precision_processing_flag: bool, 658 pub intra_smoothing_disabled_flag: bool, 659 pub high_precision_offsets_enabled_flag: bool, 660 pub persistent_rice_adaptation_enabled_flag: bool, 661 pub cabac_bypass_alignment_enabled_flag: bool, 662 } 663 664 #[derive(Clone, Debug, PartialEq, Eq)] 665 pub struct SpsSccExtension { 666 /// When set, specifies that a picture in the CVS may be included in a 667 /// reference picture list of a slice of the picture itself. When not set, 668 /// specifies that a picture in the CVS is never included in a reference 669 /// picture list of a slice of the picture itself. 670 pub curr_pic_ref_enabled_flag: bool, 671 /// When set, specifies that the decoding process for palette mode may be 672 /// used for intra blocks. When not set, specifies that the decoding process 673 /// for palette mode is not applied. 674 pub palette_mode_enabled_flag: bool, 675 /// Specifies the maximum allowed palette size. 676 pub palette_max_size: u8, 677 /// Specifies the difference between the maximum allowed palette predictor 678 /// size and the maximum allowed palette size. 679 pub delta_palette_max_predictor_size: u8, 680 /// When set, specifies that the sequence palette predictors are initialized 681 /// using the sps_palette_predictor_initializers. When not set, specifies 682 /// that the entries in the sequence palette predictor are initialized to 0. 683 pub palette_predictor_initializers_present_flag: bool, 684 /// num_palette_predictor_initializers_minus1 plus 1 specifies the number of 685 /// entries in the sequence palette predictor initializer. 686 pub num_palette_predictor_initializer_minus1: u8, 687 /// `palette_predictor_initializer[ comp ][ i ]` specifies the value of the 688 /// comp-th component of the i-th palette entry in the SPS that is used to 689 /// initialize the array PredictorPaletteEntries. 690 pub palette_predictor_initializer: [[u32; 128]; 3], 691 /// Controls the presence and inference of the use_integer_mv_flag that 692 /// specifies the resolution of motion vectors for inter prediction. 693 pub motion_vector_resolution_control_idc: u8, 694 /// When set, specifies that the intra boundary filtering process is 695 /// unconditionally disabled for intra prediction. If not set, specifies 696 /// that the intra boundary filtering process may be used. 697 pub intra_boundary_filtering_disabled_flag: bool, 698 } 699 700 impl Default for SpsSccExtension { default() -> Self701 fn default() -> Self { 702 Self { 703 curr_pic_ref_enabled_flag: Default::default(), 704 palette_mode_enabled_flag: Default::default(), 705 palette_max_size: Default::default(), 706 delta_palette_max_predictor_size: Default::default(), 707 palette_predictor_initializers_present_flag: Default::default(), 708 num_palette_predictor_initializer_minus1: Default::default(), 709 palette_predictor_initializer: [[0; 128]; 3], 710 motion_vector_resolution_control_idc: Default::default(), 711 intra_boundary_filtering_disabled_flag: Default::default(), 712 } 713 } 714 } 715 716 /// A H.265 Sequence Parameter Set. 717 #[derive(Clone, Debug, Default, PartialEq, Eq)] 718 pub struct Sps { 719 /// Specifies the value of the vps_video_parameter_set_id of the active VPS. 720 pub video_parameter_set_id: u8, 721 /// `max_sub_layers_minus1` plus 1 specifies the maximum number of temporal 722 /// sub-layers that may be present in each CVS referring to the SPS. 723 pub max_sub_layers_minus1: u8, 724 /// When sps_max_sub_layers_minus1 is greater than 0, specifies whether 725 /// inter prediction is additionally restricted for CVSs referring to the 726 /// SPS. 727 pub temporal_id_nesting_flag: bool, 728 /// profile_tier_level() data. 729 pub profile_tier_level: ProfileTierLevel, 730 /// Provides an identifier for the SPS for reference by other syntax 731 /// elements. 732 pub seq_parameter_set_id: u8, 733 /// Specifies the chroma sampling relative to the luma sampling as specified 734 /// in clause 6.2. 735 pub chroma_format_idc: u8, 736 /// When true, specifies that the three colour components of the 4:4:4 737 /// chroma format are coded separately. When false, specifies that the 738 /// colour components are not coded separately. 739 pub separate_colour_plane_flag: bool, 740 /// Specifies the width of each decoded picture in units of luma samples. 741 pub pic_width_in_luma_samples: u16, 742 /// Specifies the height of each decoded picture in units of luma samples. 743 pub pic_height_in_luma_samples: u16, 744 /// When true, indicates that the conformance cropping window offset 745 /// parameters follow next in the SPS. When false, indicates that the 746 /// conformance cropping window offset parameters are not present. 747 pub conformance_window_flag: bool, 748 /* if conformance_window_flag */ 749 /// Specify the samples of the pictures in the CVS that are output from the 750 /// decoding process, in terms of a rectangular region specified in picture 751 /// coordinates for output. 752 pub conf_win_left_offset: u32, 753 pub conf_win_right_offset: u32, 754 pub conf_win_top_offset: u32, 755 pub conf_win_bottom_offset: u32, 756 757 /// Specifies the bit depth of the samples of the luma array BitDepthY and 758 /// the value of the luma quantization parameter range offset QpBdOffsetY. 759 pub bit_depth_luma_minus8: u8, 760 /// Specifies the bit depth of the samples of the chroma arrays BitDepthC 761 /// and the value of the chroma quantization parameter range offset 762 /// QpBdOffsetC. 763 pub bit_depth_chroma_minus8: u8, 764 /// Specifies the value of the variable MaxPicOrderCntLsb that is used in 765 /// the decoding process for picture order count. 766 pub log2_max_pic_order_cnt_lsb_minus4: u8, 767 /// When true, specifies that `max_dec_pic_buffering_minus1[ i ]`, 768 /// `max_num_reorder_pics[ i ]` and `max_latency_increase_plus1[ i ]` are 769 /// present for max_sub_layers_minus1 + 1 sub- layers. When false, specifies 770 /// that the values of `max_dec_pic_ buffering_minus1[ max_sub_layers_minus1 771 /// ]`, `max_num_reorder_pics[ max_sub_layers_minus1 ]` and max_ 772 /// `latency_increase_plus1[ max_sub_layers_minus1 ]` apply to all sub-layers. 773 pub sub_layer_ordering_info_present_flag: bool, 774 /// `max_dec_pic_buffering_minus1[ i ]` plus 1 specifies the maximum required 775 /// size of the decoded picture buffer for the CVS in units of picture 776 /// storage buffers when HighestTid is equal to i. 777 pub max_dec_pic_buffering_minus1: [u8; 7], 778 /// `max_num_reorder_pics[ i ]` indicates the maximum allowed number of 779 /// pictures with PicOutputFlag equal to 1 that can precede any picture with 780 /// PicOutputFlag equal to 1 in the CVS in decoding order and follow that 781 /// picture with PicOutputFlag equal to 1 in output order when HighestTid is 782 /// equal to i. 783 pub max_num_reorder_pics: [u8; 7], 784 /// `max_latency_increase_plus1[ i ]` not equal to 0 is used to compute the 785 /// value of `SpsMaxLatencyPictures[ i ]`, which specifies the maximum number 786 /// of pictures with PicOutputFlag equal to 1 that can precede any picture 787 /// with PicOutputFlag equal to 1 in the CVS in output order and follow that 788 /// picture with PicOutputFlag equal to 1 in decoding order when HighestTid 789 /// is equal to i. 790 pub max_latency_increase_plus1: [u8; 7], 791 /// min_luma_coding_block_size_minus3 plus 3 specifies the minimum luma 792 /// coding block size. 793 pub log2_min_luma_coding_block_size_minus3: u8, 794 /// Specifies the difference between the maximum and minimum luma coding 795 /// block size. 796 pub log2_diff_max_min_luma_coding_block_size: u8, 797 /// min_luma_transform_block_size_minus2 plus 2 specifies the minimum luma 798 /// transform block size. 799 pub log2_min_luma_transform_block_size_minus2: u8, 800 /// Specifies the difference between the maximum and minimum luma transform 801 /// block size. 802 pub log2_diff_max_min_luma_transform_block_size: u8, 803 /// Specifies the maximum hierarchy depth for transform units of coding 804 /// units coded in inter prediction mode. 805 pub max_transform_hierarchy_depth_inter: u8, 806 /// Specifies the maximum hierarchy depth for transform units of coding 807 /// units coded in intra prediction mode. 808 pub max_transform_hierarchy_depth_intra: u8, 809 /// When true, specifies that a scaling list is used for the scaling process 810 /// for transform coefficients. When false, specifies that scaling list is 811 /// not used for the scaling process for transform coefficients. 812 pub scaling_list_enabled_flag: bool, 813 /* if scaling_list_enabled_flag */ 814 /// When true, specifies that the scaling_list_data( ) syntax structure is 815 /// present in the SPS. When false, specifies that the scaling_list_data( ) 816 /// syntax structure is not present in the SPS. 817 pub scaling_list_data_present_flag: bool, 818 /// The scaling_list_data() syntax data. 819 pub scaling_list: ScalingLists, 820 /// When true, specifies that asymmetric motion partitions, i.e., PartMode 821 /// equal to PART_2NxnU, PART_2NxnD, PART_nLx2N or PART_nRx2N, may be used 822 /// in CTBs. When false, specifies that asymmetric motion partitions cannot 823 /// be used in CTBs. 824 pub amp_enabled_flag: bool, 825 /// When true, specifies that the sample adaptive offset process is applied 826 /// to the reconstructed picture after the deblocking filter process. When 827 /// false, specifies that the sample adaptive offset process is not applied 828 /// to the reconstructed picture after the deblocking filter process. 829 pub sample_adaptive_offset_enabled_flag: bool, 830 /// When false, specifies that PCM-related syntax 831 /// (pcm_sample_bit_depth_luma_minus1, pcm_sample_ bit_depth_chroma_minus1, 832 /// log2_min_pcm_luma_coding_block_size_minus3, log2_diff_max_min_pcm_luma_ 833 /// coding_block_size, pcm_loop_filter_disabled_flag, pcm_flag, 834 /// pcm_alignment_zero_bit syntax elements and pcm_sample( ) syntax 835 /// structure) is not present in the CVS. 836 pub pcm_enabled_flag: bool, 837 838 /* if pcm_enabled_flag */ 839 pub pcm_sample_bit_depth_luma_minus1: u8, 840 /// Specifies the number of bits used to represent each of PCM sample values 841 /// of the luma component. 842 pub pcm_sample_bit_depth_chroma_minus1: u8, 843 /// Specifies the number of bits used to represent each of PCM sample values 844 /// of the chroma components. 845 pub log2_min_pcm_luma_coding_block_size_minus3: u8, 846 /// Specifies the difference between the maximum and minimum size of coding 847 /// blocks with pcm_flag equal to true. 848 pub log2_diff_max_min_pcm_luma_coding_block_size: u8, 849 /// Specifies whether the loop filter process is disabled on reconstructed 850 /// samples in a coding unit with pcm_flag equal to true as follows: 851 /// 852 /// – If pcm_loop_filter_disabled_flag is set, the deblocking filter and 853 /// sample adaptive offset filter processes on the reconstructed samples in 854 /// a coding unit with pcm_flag set are disabled. 855 /// 856 /// – Otherwise (pcm_loop_filter_disabled_flag value is not set), the 857 /// deblocking filter and sample adaptive offset filter processes on the 858 /// reconstructed samples in a coding unit with pcm_flag set are not 859 /// disabled. 860 pub pcm_loop_filter_disabled_flag: bool, 861 /// Specifies the number of st_ref_pic_set( ) syntax structures included in 862 /// the SPS. 863 pub num_short_term_ref_pic_sets: u8, 864 /// the st_ref_pic_set() data. 865 pub short_term_ref_pic_set: Vec<ShortTermRefPicSet>, 866 /// If unset, specifies that no long-term reference picture is used for 867 /// inter prediction of any coded picture in the CVS. 868 /// If set, specifies that long-term reference pictures may be used for 869 /// inter prediction of one or more coded pictures in the CVS. 870 pub long_term_ref_pics_present_flag: bool, 871 872 /* if long_term_ref_pics_present_flag */ 873 /// Specifies the number of candidate long-term reference pictures that are 874 /// specified in the SPS. 875 pub num_long_term_ref_pics_sps: u8, 876 /// `lt_ref_pic_poc_lsb_sps[ i ]` specifies the picture order count modulo 877 /// MaxPicOrderCntLsb of the i-th candidate long-term reference picture 878 /// specified in the SPS. 879 pub lt_ref_pic_poc_lsb_sps: [u32; MAX_LONG_TERM_REF_PIC_SETS], 880 /// `used_by_curr_pic_lt_sps_flag[ i ]` equal to false specifies that the i-th 881 /// candidate long-term reference picture specified in the SPS is not used 882 /// for reference by a picture that includes in its long-term reference 883 /// picture set (RPS) the i-th candidate long-term reference picture 884 /// specified in the SPS. 885 pub used_by_curr_pic_lt_sps_flag: [bool; MAX_LONG_TERM_REF_PIC_SETS], 886 /// When set, specifies that slice_temporal_mvp_enabled_flag is present in 887 /// the slice headers of non-IDR pictures in the CVS. When not set, 888 /// specifies that slice_temporal_mvp_enabled_flag is not present in slice 889 /// headers and that temporal motion vector predictors are not used in the 890 /// CVS. 891 pub temporal_mvp_enabled_flag: bool, 892 /// When set, specifies that bi-linear interpolation is conditionally used 893 /// in the intraprediction filtering process in the CVS as specified in 894 /// clause 8.4.4.2.3. 895 pub strong_intra_smoothing_enabled_flag: bool, 896 /// When set, specifies that the vui_parameters( ) syntax structure as 897 /// specified in Annex E is present. When not set, specifies that the 898 /// vui_parameters( ) syntax structure as specified in Annex E is not 899 /// present. 900 pub vui_parameters_present_flag: bool, 901 /// The vui_parameters() data. 902 pub vui_parameters: VuiParams, 903 /// When set, specifies that the syntax elements sps_range_extension_flag, 904 /// sps_multilayer_extension_flag, sps_3d_extension_flag, 905 /// sps_scc_extension_flag, and sps_extension_4bits are present in the SPS 906 /// RBSP syntax structure. When not set, specifies that these syntax 907 /// elements are not present. 908 pub extension_present_flag: bool, 909 910 pub range_extension_flag: bool, 911 /// The sps_range_extension() data. 912 pub range_extension: SpsRangeExtension, 913 /// When set, specifies that the sps_scc_extension( ) syntax structure is 914 /// present in the SPS RBSP syntax structure. When not set, specifies that 915 /// this syntax structure is not present 916 pub scc_extension_flag: bool, 917 /// The sps_scc_extension() data. 918 pub scc_extension: SpsSccExtension, 919 920 // Internal H265 variables. Computed from the bitstream. 921 /// Equivalent to MinCbLog2SizeY in the specification. 922 pub min_cb_log2_size_y: u32, 923 /// Equivalent to CtbLog2SizeY in the specification. 924 pub ctb_log2_size_y: u32, 925 /// Equivalent to CtbSizeY in the specification. 926 pub ctb_size_y: u32, 927 /// Equivalent to PicHeightInCtbsY in the specification. 928 pub pic_height_in_ctbs_y: u32, 929 /// Equivalent to PicWidthInCtbsY in the specification. 930 pub pic_width_in_ctbs_y: u32, 931 /// Equivalent to PicSizeInCtbsY in the specification. 932 pub pic_size_in_ctbs_y: u32, 933 /// Equivalent to ChromaArrayType in the specification. 934 pub chroma_array_type: u8, 935 /// Equivalent to WpOffsetHalfRangeY in the specification. 936 pub wp_offset_half_range_y: u32, 937 /// Equivalent to WpOffsetHalfRangeC in the specification. 938 pub wp_offset_half_range_c: u32, 939 /// Equivalent to MaxTbLog2SizeY in the specification. 940 pub max_tb_log2_size_y: u32, 941 /// Equivalent to PicSizeInSamplesY in the specification. 942 pub pic_size_in_samples_y: u32, 943 944 /// The VPS referenced by this SPS, if any. 945 pub vps: Option<Rc<Vps>>, 946 } 947 948 impl Sps { max_dpb_size(&self) -> usize949 pub fn max_dpb_size(&self) -> usize { 950 let max_luma_ps = self.profile_tier_level.max_luma_ps(); 951 let max_dpb_pic_buf = self.profile_tier_level.max_dpb_pic_buf(); 952 953 // Equation A-2 954 let max = if self.pic_size_in_samples_y <= (max_luma_ps >> 2) { 955 std::cmp::min(4 * max_dpb_pic_buf, 16) 956 } else if self.pic_size_in_samples_y <= (max_luma_ps >> 1) { 957 std::cmp::min(2 * max_dpb_pic_buf, 16) 958 } else if self.pic_size_in_samples_y <= ((3 * max_luma_ps) >> 2) { 959 std::cmp::min(4 * max_dpb_pic_buf / 3, 16) 960 } else { 961 max_dpb_pic_buf 962 }; 963 964 max as usize 965 } 966 width(&self) -> u16967 pub fn width(&self) -> u16 { 968 self.pic_width_in_luma_samples 969 } 970 height(&self) -> u16971 pub fn height(&self) -> u16 { 972 self.pic_height_in_luma_samples 973 } 974 visible_rectangle(&self) -> Rect<u32>975 pub fn visible_rectangle(&self) -> Rect<u32> { 976 // From the specification: 977 // NOTE 3 – The conformance cropping window offset parameters are 978 // only applied at the output. All internal decoding processes are 979 // applied to the uncropped picture size. 980 if !self.conformance_window_flag { 981 return Rect { 982 min: Point { x: 0, y: 0 }, 983 max: Point { x: u32::from(self.width()), y: u32::from(self.height()) }, 984 }; 985 } 986 const SUB_HEIGHT_C: [u32; 5] = [1, 2, 1, 1, 1]; 987 const SUB_WIDTH_C: [u32; 5] = [1, 2, 2, 1, 1]; 988 989 let crop_unit_y = SUB_HEIGHT_C[usize::from(self.chroma_array_type)]; 990 let crop_unit_x = SUB_WIDTH_C[usize::from(self.chroma_array_type)]; 991 let crop_left = crop_unit_x * self.conf_win_left_offset; 992 let crop_right = crop_unit_x * self.conf_win_right_offset; 993 let crop_top = crop_unit_y * self.conf_win_top_offset; 994 let crop_bottom = crop_unit_y * self.conf_win_bottom_offset; 995 996 Rect { 997 min: Point { x: crop_left, y: crop_top }, 998 max: Point { 999 x: u32::from(self.width()) - crop_left - crop_right, 1000 y: u32::from(self.height()) - crop_top - crop_bottom, 1001 }, 1002 } 1003 } 1004 } 1005 1006 #[derive(Clone, Debug, PartialEq, Eq)] 1007 pub struct PpsSccExtension { 1008 /// When set, specifies that a picture referring to the PPS may be included 1009 /// in a reference picture list of a slice of the picture itself. If not 1010 /// set, specifies that a picture referring to the PPS is never included in 1011 /// a reference picture list of a slice of the picture itself. 1012 pub curr_pic_ref_enabled_flag: bool, 1013 /// When set, specifies that an adaptive colour transform may be applied to 1014 /// the residual in the decoding process. When not set, specifies that 1015 /// adaptive colour transform is not applied to the residual. 1016 pub residual_adaptive_colour_transform_enabled_flag: bool, 1017 /// When set, specifies that slice_act_y_qp_offset, slice_act_cb_qp_offset, 1018 /// slice_act_cr_qp_offset are present in the slice header. When not set, 1019 /// specifies that slice_act_y_qp_offset, slice_act_cb_qp_offset, 1020 /// slice_act_cr_qp_offset are not present in the slice header. 1021 pub slice_act_qp_offsets_present_flag: bool, 1022 /// See the specificartion for more details. 1023 pub act_y_qp_offset_plus5: i8, 1024 /// See the specificartion for more details. 1025 pub act_cb_qp_offset_plus5: i8, 1026 /// See the specificartion for more details. 1027 pub act_cr_qp_offset_plus3: i8, 1028 /// When set, specifies that the palette predictor initializers used for the 1029 /// pictures referring to the PPS are derived based on the palette predictor 1030 /// initializers specified by the PPS. If not set, specifies that the 1031 /// palette predictor initializers used for the pictures referring to the 1032 /// PPS are inferred to be equal to those specified by the active SPS. 1033 pub palette_predictor_initializers_present_flag: bool, 1034 /// Specifies the number of entries in the picture palette predictor 1035 /// initializer. 1036 pub num_palette_predictor_initializers: u8, 1037 /// When set, specifies that the pictures that refer to this PPS are 1038 /// monochrome. If not set, specifies that the pictures that refer to this 1039 /// PPS have multiple components. 1040 pub monochrome_palette_flag: bool, 1041 /// luma_bit_depth_entry_minus8 plus 8 specifies the bit depth of the luma 1042 /// component of the entries of the palette predictor initializer. 1043 pub luma_bit_depth_entry_minus8: u8, 1044 /// chroma_bit_depth_entry_minus8 plus 8 specifies the bit depth of the 1045 /// chroma components of the entries of the palette predictor initializer. 1046 pub chroma_bit_depth_entry_minus8: u8, 1047 /// `pps_palette_predictor_initializer[ comp ][ i ]` specifies the value of 1048 /// the comp-th component of the i-th palette entry in the PPS that is used 1049 /// to initialize the array PredictorPaletteEntries. 1050 pub palette_predictor_initializer: [[u8; 128]; 3], 1051 } 1052 1053 impl Default for PpsSccExtension { default() -> Self1054 fn default() -> Self { 1055 Self { 1056 curr_pic_ref_enabled_flag: Default::default(), 1057 residual_adaptive_colour_transform_enabled_flag: Default::default(), 1058 slice_act_qp_offsets_present_flag: Default::default(), 1059 act_y_qp_offset_plus5: Default::default(), 1060 act_cb_qp_offset_plus5: Default::default(), 1061 act_cr_qp_offset_plus3: Default::default(), 1062 palette_predictor_initializers_present_flag: Default::default(), 1063 num_palette_predictor_initializers: Default::default(), 1064 monochrome_palette_flag: Default::default(), 1065 luma_bit_depth_entry_minus8: Default::default(), 1066 chroma_bit_depth_entry_minus8: Default::default(), 1067 palette_predictor_initializer: [[0; 128]; 3], 1068 } 1069 } 1070 } 1071 1072 #[derive(Clone, Debug, Default, PartialEq, Eq)] 1073 pub struct PpsRangeExtension { 1074 /// log2_max_transform_skip_block_size_minus2 plus 2 specifies the maximum 1075 /// transform block size for which transform_skip_flag may be present in 1076 /// coded pictures referring to the PPS. When not present, the value of 1077 /// log2_max_transform_skip_block_size_minus2 is inferred to be equal to 0. 1078 /// When present, the value of log2_max_transform_skip_block_size_minus2 1079 /// shall be less than or equal to MaxTbLog2SizeY − 2. 1080 pub log2_max_transform_skip_block_size_minus2: u32, 1081 /// When set, specifies that log2_res_scale_abs_plus1 and 1082 /// res_scale_sign_flag may be present in the transform unit syntax for 1083 /// pictures referring to the PPS. When not set, specifies that 1084 /// log2_res_scale_abs_plus1 and res_scale_sign_flag are not present for 1085 /// pictures referring to the PPS. 1086 pub cross_component_prediction_enabled_flag: bool, 1087 /// When set, specifies that the cu_chroma_qp_offset_flag may be present in 1088 /// the transform unit syntax. When not set, specifies that the 1089 /// cu_chroma_qp_offset_flag is not present in the transform unit syntax. 1090 pub chroma_qp_offset_list_enabled_flag: bool, 1091 /// Specifies the difference between the luma CTB size and the minimum luma 1092 /// coding block size of coding units that convey cu_chroma_qp_offset_flag. 1093 pub diff_cu_chroma_qp_offset_depth: u32, 1094 /// chroma_qp_offset_list_len_minus1 plus 1 specifies the number of 1095 /// `cb_qp_offset_list[ i ]` and `cr_qp_offset_list[ i ]` syntax elements that 1096 /// are present in the PPS. 1097 pub chroma_qp_offset_list_len_minus1: u32, 1098 /// Specify offsets used in the derivation of Qp′Cb and Qp′Cr, respectively. 1099 pub cb_qp_offset_list: [i32; 6], 1100 /// Specify offsets used in the derivation of Qp′Cb and Qp′Cr, respectively. 1101 pub cr_qp_offset_list: [i32; 6], 1102 /// The base 2 logarithm of the scaling parameter that is used to scale 1103 /// sample adaptive offset (SAO) offset values for luma samples. 1104 pub log2_sao_offset_scale_luma: u32, 1105 /// The base 2 logarithm of the scaling parameter that is used to scale SAO 1106 /// offset values for chroma samples. 1107 pub log2_sao_offset_scale_chroma: u32, 1108 } 1109 1110 /// A H.265 Picture Parameter Set. 1111 #[derive(Clone, Debug, PartialEq, Eq)] 1112 pub struct Pps { 1113 /// Identifies the PPS for reference by other syntax elements. 1114 pub pic_parameter_set_id: u8, 1115 /// Specifies the value of sps_seq_parameter_set_id for the active SPS. 1116 pub seq_parameter_set_id: u8, 1117 /// When set, specifies the presence of the syntax element 1118 /// dependent_slice_segment_flag in the slice segment headers for coded 1119 /// pictures referring to the PPS. When not set, specifies the absence of 1120 /// the syntax element dependent_slice_segment_flag in the slice segment 1121 /// headers for coded pictures referring to the PPS. 1122 pub dependent_slice_segments_enabled_flag: bool, 1123 /// When set, indicates that the pic_output_flag syntax element is present 1124 /// in the associated slice headers. When not set, indicates that the 1125 /// pic_output_flag syntax element is not present in the associated slice 1126 /// headers. 1127 pub output_flag_present_flag: bool, 1128 /// Specifies the number of extra slice header bits that are present in the 1129 /// slice header RBSP for coded pictures referring to the PPS. 1130 pub num_extra_slice_header_bits: u8, 1131 /// When not set, specifies that sign bit hiding is disabled. Whens set, 1132 /// specifies that sign bit hiding is enabled. 1133 pub sign_data_hiding_enabled_flag: bool, 1134 /// When set, specifies that cabac_init_flag is present in slice headers 1135 /// referring to the PPS. When not set, specifies that cabac_init_flag is 1136 /// not present in slice headers referring to the PPS. 1137 pub cabac_init_present_flag: bool, 1138 /// Specifies the inferred value of num_ref_idx_l0_active_minus1 for P and B 1139 /// slices with num_ref_idx_active_override_flag not set. 1140 pub num_ref_idx_l0_default_active_minus1: u8, 1141 /// Specifies the inferred value of num_ref_idx_l1_active_minus1 for B 1142 /// slices with num_ref_idx_active_override_flag not set. 1143 pub num_ref_idx_l1_default_active_minus1: u8, 1144 /// init_qp_minus26 plus 26 specifies the initial value of SliceQpY for each 1145 /// slice referring to the PPS. The initial value of SliceQpY is modified at 1146 /// the slice segment layer when a non-zero value of slice_qp_delta is 1147 /// decoded. 1148 pub init_qp_minus26: i8, 1149 /// When not set, specifies that intra prediction allows usage of residual 1150 /// data and decoded samples of neighbouring coding blocks coded using 1151 /// either intra or inter prediction modes. When set, specifies constrained 1152 /// intra prediction, in which case intra prediction only uses residual data 1153 /// and decoded samples from neighbouring coding blocks coded using intra 1154 /// prediction modes. 1155 pub constrained_intra_pred_flag: bool, 1156 /// When set, specifies that transform_skip_flag may be present in the 1157 /// residual coding syntax. When not set, specifies that transform_skip_flag 1158 /// is not present in the residual coding syntax. 1159 pub transform_skip_enabled_flag: bool, 1160 /// When set, specifies that the diff_cu_qp_delta_depth syntax element is 1161 /// present in the PPS and that cu_qp_delta_abs may be present in the 1162 /// transform unit syntax and the palette syntax. When not set, specifies 1163 /// that the diff_cu_qp_delta_depth syntax element is not present in the PPS 1164 /// and that cu_qp_delta_abs is not present in the transform unit syntax and 1165 /// the palette syntax. 1166 pub cu_qp_delta_enabled_flag: bool, 1167 1168 /*if cu_qp_delta_enabled_flag */ 1169 /// Specifies the difference between the luma CTB size and the minimum luma 1170 /// coding block size of coding units that convey cu_qp_delta_abs and 1171 /// cu_qp_delta_sign_flag. 1172 pub diff_cu_qp_delta_depth: u8, 1173 /// Specifies the offsets to the luma quantization parameter Qp′Y used for 1174 /// deriving Qp′Cb and Qp′Cr, respectively. 1175 pub cb_qp_offset: i8, 1176 /// Specifies the offsets to the luma quantization parameter Qp′Y used for 1177 /// deriving Qp′Cb and Qp′Cr, respectively. 1178 pub cr_qp_offset: i8, 1179 /// When set, indicates that the slice_cb_qp_offset and slice_cr_qp_offset 1180 /// syntax elements are present in the associated slice headers. When not 1181 /// set, indicates that these syntax elements are not present in the 1182 /// associated slice headers. When ChromaArrayType is equal to 0, 1183 /// pps_slice_chroma_qp_offsets_present_flag shall be equal to 0 1184 pub slice_chroma_qp_offsets_present_flag: bool, 1185 /// When not set, specifies that weighted prediction is not applied to P 1186 /// slices. When set, specifies that weighted prediction is applied to P 1187 /// slices. 1188 pub weighted_pred_flag: bool, 1189 /// When not set, specifies that the default weighted prediction is applied 1190 /// to B slices. When set, specifies that weighted prediction is applied to 1191 /// B slices. 1192 pub weighted_bipred_flag: bool, 1193 /// When set, specifies that `cu_transquant_bypass_flag` is present, When 1194 /// not set, specifies that `cu_transquant_bypass_flag` is not present. 1195 pub transquant_bypass_enabled_flag: bool, 1196 /// When set, specifies that there is more than one tile in each picture 1197 /// referring to the PPS. When not set, specifies that there is only one 1198 /// tile in each picture referring to the PPS. 1199 pub tiles_enabled_flag: bool, 1200 /// When set, specifies that a specific synchronization process for context 1201 /// variables, and when applicable, Rice parameter initialization states and 1202 /// palette predictor variables, is invoked before decoding the CTU which 1203 /// includes the first CTB of a row of CTBs in each tile in each picture 1204 /// referring to the PPS, and a specific storage process for context 1205 /// variables, and when applicable, Rice parameter initialization states and 1206 /// palette predictor variables, is invoked after decoding the CTU which 1207 /// includes the second CTB of a row of CTBs in each tile in each picture 1208 /// referring to the PPS. When not set, specifies that no specific 1209 /// synchronization process for context variables, and when applicable, Rice 1210 /// parameter initialization states and palette predictor variables, is 1211 /// required to be invoked before decoding the CTU which includes the first 1212 /// CTB of a row of CTBs in each tile in each picture referring to the PPS, 1213 /// and no specific storage process for context variables, and when 1214 /// applicable, Rice parameter initialization states and palette predictor 1215 /// variables, is required to be invoked after decoding the CTU which 1216 /// includes the second CTB of a row of CTBs in each tile in each picture 1217 /// referring to the PPS. 1218 pub entropy_coding_sync_enabled_flag: bool, 1219 /// num_tile_columns_minus1 plus 1 specifies the number of tile columns 1220 /// partitioning the picture. 1221 pub num_tile_columns_minus1: u8, 1222 /// num_tile_rows_minus1 plus 1 specifies the number of tile rows 1223 /// partitioning the picture. 1224 pub num_tile_rows_minus1: u8, 1225 /// When set, specifies that tile column boundaries and likewise tile row 1226 /// boundaries are distributed uniformly across the picture. When not set, 1227 /// specifies that tile column boundaries and likewise tile row boundaries 1228 /// are not distributed uniformly across the picture but signalled 1229 /// explicitly using the syntax elements `column_width_minus1[ i ]` and 1230 /// `row_height_minus1[ i ]`. 1231 pub uniform_spacing_flag: bool, 1232 /// `column_width_minus1[ i ]` plus 1 specifies the width of the i-th tile 1233 /// column in units of CTBs. 1234 pub column_width_minus1: [u32; 19], 1235 /// `row_height_minus1[ i ]` plus 1 specifies the height of the i-th tile row 1236 /// in units of CTBs. 1237 pub row_height_minus1: [u32; 21], 1238 /// When set, specifies that in-loop filtering operations may be performed 1239 /// across tile boundaries in pictures referring to the PPS. When not set, 1240 /// specifies that in-loop filtering operations are not performed across 1241 /// tile boundaries in pictures referring to the PPS. The in-loop filtering 1242 /// operations include the deblocking filter and sample adaptive offset 1243 /// filter operations. 1244 pub loop_filter_across_tiles_enabled_flag: bool, 1245 /// When set, specifies that in-loop filtering operations may be performed 1246 /// across left and upper boundaries of slices referring to the PPS. When 1247 /// not set, specifies that in-loop filtering operations are not performed 1248 /// across left and upper boundaries of slices referring to the PPS. The in- 1249 /// loop filtering operations include the deblocking filter and sample 1250 /// adaptive offset filter operations. 1251 pub loop_filter_across_slices_enabled_flag: bool, 1252 /// When set, specifies the presence of deblocking filter control syntax 1253 /// elements in the PPS. When not set, specifies the absence of deblocking 1254 /// filter control syntax elements in the PPS. 1255 pub deblocking_filter_control_present_flag: bool, 1256 /// When set, specifies the presence of deblocking_filter_override_flag in 1257 /// the slice headers for pictures referring to the PPS. When not set, 1258 /// specifies the absence of deblocking_filter_override_flag in the slice 1259 /// headers for pictures referring to the PPS. 1260 pub deblocking_filter_override_enabled_flag: bool, 1261 /// When set, specifies that the operation of deblocking filter is not 1262 /// applied for slices referring to the PPS in which 1263 /// slice_deblocking_filter_disabled_flag is not present. When not set, 1264 /// specifies that the operation of the deblocking filter is applied for 1265 /// slices referring to the PPS in which 1266 /// slice_deblocking_filter_disabled_flag is not present. 1267 pub deblocking_filter_disabled_flag: bool, 1268 /// Specify the default deblocking parameter offsets for β and tC (divided 1269 /// by 2) that are applied for slices referring to the PPS, unless the 1270 /// default deblocking parameter offsets are overridden by the deblocking 1271 /// parameter offsets present in the slice headers of the slices referring 1272 /// to the PPS. 1273 pub beta_offset_div2: i8, 1274 /// Specify the default deblocking parameter offsets for β and tC (divided 1275 /// by 2) that are applied for slices referring to the PPS, unless the 1276 /// default deblocking parameter offsets are overridden by the deblocking 1277 /// parameter offsets present in the slice headers of the slices referring 1278 /// to the PPS. 1279 pub tc_offset_div2: i8, 1280 /// When set, specifies that the scaling list data used for the pictures 1281 /// referring to the PPS are derived based on the scaling lists specified by 1282 /// the active SPS and the scaling lists specified by the PPS. 1283 /// pps_scaling_list_data_present_flag equal to 0 specifies that the scaling 1284 /// list data used for the pictures referring to the PPS are inferred to be 1285 /// equal to those specified by the active SPS. 1286 pub scaling_list_data_present_flag: bool, 1287 /// The scaling list data. 1288 pub scaling_list: ScalingLists, 1289 /// When set, specifies that the syntax structure 1290 /// ref_pic_lists_modification( ) is present in the slice segment header. 1291 /// When not set, specifies that the syntax structure 1292 /// ref_pic_lists_modification( ) is not present in the slice segment header 1293 pub lists_modification_present_flag: bool, 1294 /// log2_parallel_merge_level_minus2 plus 2 specifies the value of the 1295 /// variable Log2ParMrgLevel, which is used in the derivation process for 1296 /// luma motion vectors for merge mode as specified in clause 8.5.3.2.2 and 1297 /// the derivation process for spatial merging candidates as specified in 1298 /// clause 8.5.3.2.3. 1299 pub log2_parallel_merge_level_minus2: u8, 1300 /// When not set, specifies that no slice segment header extension syntax 1301 /// elements are present in the slice segment headers for coded pictures 1302 /// referring to the PPS. When set, specifies that slice segment header 1303 /// extension syntax elements are present in the slice segment headers for 1304 /// coded pictures referring to the PPS. 1305 pub slice_segment_header_extension_present_flag: bool, 1306 /// When set, specifies that the syntax elements pps_range_extension_flag, 1307 /// pps_multilayer_extension_flag, pps_3d_extension_flag, 1308 /// pps_scc_extension_flag, and pps_extension_4bits are present in the 1309 /// picture parameter set RBSP syntax structure. When not set, specifies 1310 /// that these syntax elements are not present. 1311 pub extension_present_flag: bool, 1312 /// When setspecifies that the pps_range_extension( ) syntax structure is 1313 /// present in the PPS RBSP syntax structure. When not set, specifies that 1314 /// this syntax structure is not present. 1315 pub range_extension_flag: bool, 1316 /// The range extension data. 1317 pub range_extension: PpsRangeExtension, 1318 1319 pub scc_extension_flag: bool, 1320 /// The SCC extension data. 1321 pub scc_extension: PpsSccExtension, 1322 1323 // Internal variables. 1324 /// Equivalent to QpBdOffsetY in the specification. 1325 pub qp_bd_offset_y: u32, 1326 1327 /// The SPS referenced by this PPS. 1328 pub sps: Rc<Sps>, 1329 } 1330 1331 #[derive(Clone, Debug, PartialEq, Eq)] 1332 pub struct ScalingLists { 1333 /// plus 8 specifies the value of the variable `ScalingFactor[ 2 ][ matrixId 1334 /// ] [ 0 ][ 0 ]` for the scaling list for the 16x16 size. 1335 pub scaling_list_dc_coef_minus8_16x16: [i16; 6], 1336 /// plus 8 specifies the value of the variable `ScalingFactor[ 3 ][ matrixId 1337 /// ][ 0 ][ 0 ]` for the scaling list for the 32x32 size. 1338 pub scaling_list_dc_coef_minus8_32x32: [i16; 6], 1339 /// The 4x4 scaling list. 1340 pub scaling_list_4x4: [[u8; 16]; 6], 1341 /// The 8x8 scaling list. 1342 pub scaling_list_8x8: [[u8; 64]; 6], 1343 /// The 16x16 scaling list. 1344 pub scaling_list_16x16: [[u8; 64]; 6], 1345 /// The 32x32 scaling list. 1346 pub scaling_list_32x32: [[u8; 64]; 6], 1347 } 1348 1349 impl Default for ScalingLists { default() -> Self1350 fn default() -> Self { 1351 Self { 1352 scaling_list_dc_coef_minus8_16x16: Default::default(), 1353 scaling_list_dc_coef_minus8_32x32: Default::default(), 1354 scaling_list_4x4: Default::default(), 1355 scaling_list_8x8: [[0; 64]; 6], 1356 scaling_list_16x16: [[0; 64]; 6], 1357 scaling_list_32x32: [[0; 64]; 6], 1358 } 1359 } 1360 } 1361 1362 #[derive(Clone, Debug, Default, PartialEq, Eq)] 1363 pub struct RefPicListModification { 1364 /// Whenset, indicates that reference picture list 0 is specified explicitly 1365 /// by a list of `list_entry_l0[ i ]` values. When not set, indicates that 1366 /// reference picture list 0 is determined implicitly. 1367 pub ref_pic_list_modification_flag_l0: bool, 1368 /// `list_entry_l0[ i ]` specifies the index of the reference picture in 1369 /// RefPicListTemp0 to be placed at the current position of reference 1370 /// picture list 0. 1371 pub list_entry_l0: Vec<u32>, 1372 /// Whenset, indicates that reference picture list 1 is specified explicitly 1373 /// by a list of `list_entry_l1[ i ]` values. When not set, indicates that 1374 /// reference picture list 1 is determined implicitly. 1375 pub ref_pic_list_modification_flag_l1: bool, 1376 /// `list_entry_l1[ i ]` specifies the index of the reference picture in 1377 /// RefPicListTemp1 to be placed at the current position of reference 1378 /// picture list 1. 1379 pub list_entry_l1: Vec<u32>, 1380 } 1381 1382 #[derive(Clone, Debug, Default, PartialEq, Eq)] 1383 pub struct PredWeightTable { 1384 /// The base 2 logarithm of the denominator for all luma weighting factors. 1385 pub luma_log2_weight_denom: u8, 1386 /// The difference of the base 2 logarithm of the denominator for all chroma 1387 /// weighting factors. 1388 pub delta_chroma_log2_weight_denom: i8, 1389 /// `luma_weight_l0_flag[ i ]` set specifies that weighting factors for the 1390 /// luma component of list 0 prediction using `RefPicList0[ i ]` are present. 1391 /// `luma_weight_l0_flag[ i ]` not set specifies that these weighting factors 1392 /// are not present. 1393 pub luma_weight_l0_flag: [bool; 15], 1394 /// `chroma_weight_l0_flag[ i ]` set specifies that weighting factors for the 1395 /// chroma prediction values of list 0 prediction using `RefPicList0[ i ]` are 1396 /// present. `chroma_weight_l0_flag[ i ]` not set specifies that these 1397 /// weighting factors are not present. 1398 pub chroma_weight_l0_flag: [bool; 15], 1399 /// `delta_luma_weight_l0[ i ]` is the difference of the weighting factor 1400 /// applied to the luma prediction value for list 0 prediction using 1401 /// `RefPicList0[ i ]`. 1402 pub delta_luma_weight_l0: [i8; 15], 1403 /// `luma_offset_l0[ i ]` is the additive offset applied to the luma 1404 /// prediction value for list 0 prediction using `RefPicList0[ i ]`. 1405 pub luma_offset_l0: [i8; 15], 1406 /// `delta_chroma_weight_l0[ i ][ j ]` is the difference of the weighting 1407 /// factor applied to the chroma prediction values for list 0 prediction 1408 /// using `RefPicList0[ i ]` with j equal to 0 for Cb and j equal to 1 for Cr. 1409 pub delta_chroma_weight_l0: [[i8; 2]; 15], 1410 /// `delta_chroma_offset_l0[ i ][ j ]` is the difference of the additive 1411 /// offset applied to the chroma prediction values for list 0 prediction 1412 /// using `RefPicList0[ i ]` with j equal to 0 for Cb and j equal to 1 for Cr. 1413 pub delta_chroma_offset_l0: [[i16; 2]; 15], 1414 1415 // `luma_weight_l1_flag[ i ]`, `chroma_weight_l1_flag[ i ]`, 1416 // `delta_luma_weight_l1[ i ]`, `luma_offset_l1[ i ]`, delta_chroma_weight_l1[ i 1417 // `][ j ]` and `delta_chroma_offset_l1[ i ]`[ j ] have the same 1418 // `semanticsasluma_weight_l0_flag[ i ]`, `chroma_weight_l0_flag[ i ]`, 1419 // `delta_luma_weight_l0[ i ]`, `luma_offset_l0[ i ]`, `delta_chroma_weight_l0[ i 1420 // ][ j ]` and `delta_chroma_offset_l0[ i ][ j ]`, respectively, with `l0`, `L0`, 1421 // `list 0` and `List0` replaced by `l1`, `L1`, `list 1` and `List1`, respectively. 1422 pub luma_weight_l1_flag: [bool; 15], 1423 pub chroma_weight_l1_flag: [bool; 15], 1424 pub delta_luma_weight_l1: [i8; 15], 1425 pub luma_offset_l1: [i8; 15], 1426 1427 pub delta_chroma_weight_l1: [[i8; 2]; 15], 1428 pub delta_chroma_offset_l1: [[i16; 2]; 15], 1429 1430 // Calculated. 1431 /// Same as ChromaLog2WeightDenom in the specification. 1432 pub chroma_log2_weight_denom: u8, 1433 } 1434 1435 #[derive(Clone, Debug, PartialEq, Eq)] 1436 pub struct ShortTermRefPicSet { 1437 /// When set, specifies that the stRpsIdx-th candidate short-term RPS is 1438 /// predicted from another candidate short-term RPS, which is referred to as 1439 /// the source candidate short-term RPS. 1440 pub inter_ref_pic_set_prediction_flag: bool, 1441 /// delta_idx_minus1 plus 1 specifies the difference between the value of 1442 /// stRpsIdx and the index, into the list of the candidate short-term RPSs 1443 /// specified in the SPS, of the source candidate short-term RPS. 1444 pub delta_idx_minus1: u8, 1445 /// delta_rps_sign and abs_delta_rps_minus1 together specify the value of 1446 /// the variable deltaRps. 1447 pub delta_rps_sign: bool, 1448 /// delta_rps_sign and abs_delta_rps_minus1 together specify the value of 1449 /// the variable deltaRps. 1450 pub abs_delta_rps_minus1: u16, 1451 /// specifies the number of entries in the stRpsIdx-th candidate short-term 1452 /// RPS that have picture order count values less than the picture order 1453 /// count value of the current picture. 1454 pub num_negative_pics: u8, 1455 /// specifies the number of entries in the stRpsIdx-th candidate short-term 1456 /// RPS that have picture order count values greater than the picture order 1457 /// count value of the current picture. 1458 pub num_positive_pics: u8, 1459 /// Same as UsedByCurrPicS0 in the specification. 1460 pub used_by_curr_pic_s0: [bool; MAX_SHORT_TERM_REF_PIC_SETS], 1461 /// Same as UsedByCurrPicS1 in the specification. 1462 pub used_by_curr_pic_s1: [bool; MAX_SHORT_TERM_REF_PIC_SETS], 1463 /// Same as DeltaPocS0 in the specification. 1464 pub delta_poc_s0: [i32; MAX_SHORT_TERM_REF_PIC_SETS], 1465 /// Same as DeltaPocS1 in the specification. 1466 pub delta_poc_s1: [i32; MAX_SHORT_TERM_REF_PIC_SETS], 1467 /// Same as NumDeltaPocs in the specification. 1468 pub num_delta_pocs: u32, 1469 } 1470 1471 impl Default for ShortTermRefPicSet { default() -> Self1472 fn default() -> Self { 1473 Self { 1474 inter_ref_pic_set_prediction_flag: Default::default(), 1475 delta_idx_minus1: Default::default(), 1476 delta_rps_sign: Default::default(), 1477 abs_delta_rps_minus1: Default::default(), 1478 num_negative_pics: Default::default(), 1479 num_positive_pics: Default::default(), 1480 used_by_curr_pic_s0: [false; MAX_SHORT_TERM_REF_PIC_SETS], 1481 used_by_curr_pic_s1: [false; MAX_SHORT_TERM_REF_PIC_SETS], 1482 delta_poc_s0: [0; MAX_SHORT_TERM_REF_PIC_SETS], 1483 delta_poc_s1: [0; MAX_SHORT_TERM_REF_PIC_SETS], 1484 num_delta_pocs: Default::default(), 1485 } 1486 } 1487 } 1488 1489 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 1490 /// See table 7-7 in the specification. 1491 pub enum SliceType { 1492 B = 0, 1493 P = 1, 1494 I = 2, 1495 } 1496 1497 impl TryFrom<u32> for SliceType { 1498 type Error = String; 1499 try_from(value: u32) -> Result<Self, Self::Error>1500 fn try_from(value: u32) -> Result<Self, Self::Error> { 1501 match value { 1502 0 => Ok(SliceType::B), 1503 1 => Ok(SliceType::P), 1504 2 => Ok(SliceType::I), 1505 _ => Err(format!("Invalid SliceType {}", value)), 1506 } 1507 } 1508 } 1509 1510 impl SliceType { 1511 /// Whether this is a P slice. See table 7-7 in the specification. is_p(&self) -> bool1512 pub fn is_p(&self) -> bool { 1513 matches!(self, SliceType::P) 1514 } 1515 1516 /// Whether this is a B slice. See table 7-7 in the specification. is_b(&self) -> bool1517 pub fn is_b(&self) -> bool { 1518 matches!(self, SliceType::B) 1519 } 1520 1521 /// Whether this is an I slice. See table 7-7 in the specification. is_i(&self) -> bool1522 pub fn is_i(&self) -> bool { 1523 matches!(self, SliceType::I) 1524 } 1525 } 1526 1527 impl Default for SliceType { default() -> Self1528 fn default() -> Self { 1529 Self::P 1530 } 1531 } 1532 1533 #[derive(Clone, Debug, PartialEq, Eq)] 1534 pub struct SliceHeader { 1535 /// When set, specifies that the slice segment is the first slice segment of 1536 /// the picture in decoding order. When not set, specifies that the slice 1537 /// segment is not the first slice segment of the picture in decoding order. 1538 pub first_slice_segment_in_pic_flag: bool, 1539 /// Affects the output of previously-decoded pictures in the decoded picture 1540 /// buffer after the decoding of an IDR or a BLA picture that is not the 1541 /// first picture in the bitstream as specified in Annex C. 1542 pub no_output_of_prior_pics_flag: bool, 1543 /// Specifies the value of pps_pic_parameter_set_id for the PPS in use. 1544 pub pic_parameter_set_id: u8, 1545 /// When set, specifies that the value of each slice segment header syntax 1546 /// element that is not present is inferred to be equal to the value of the 1547 /// corresponding slice segment header syntax element in the slice header. 1548 pub dependent_slice_segment_flag: bool, 1549 /// Specifies the address of the first CTB in the slice segment, in CTB 1550 /// raster scan of a picture. 1551 pub segment_address: u32, 1552 /// Specifies the coding type of the slice according to Table 7-7. 1553 pub type_: SliceType, 1554 /// Affects the decoded picture output and removal processes as specified in 1555 /// Annex C. 1556 pub pic_output_flag: bool, 1557 /// Specifies the colour plane associated with the current slice RBSP when 1558 /// separate_colour_plane_flag is set. The value of colour_plane_id shall be 1559 /// in the range of 0 to 2, inclusive. colour_plane_id values 0, 1 and 2 1560 /// correspond to the Y, Cb and Cr planes, respectively. 1561 pub colour_plane_id: u8, 1562 /// Specifies the picture order count modulo MaxPicOrderCntLsb for the 1563 /// current picture. The length of the slice_pic_order_cnt_lsb syntax 1564 /// element is log2_max_pic_order_cnt_lsb_minus4 + 4 bits. 1565 pub pic_order_cnt_lsb: u16, 1566 /// When set, specifies that the short-term RPS of the current picture is 1567 /// derived based on one of the st_ref_pic_set( ) syntax structures in the 1568 /// active SPS that is identified by the syntax element 1569 /// short_term_ref_pic_set_idx in the slice header. When not set, specifies 1570 /// that the short-term RPS of the current picture is derived based on the 1571 /// st_ref_pic_set( ) syntax structure that is directly included in the 1572 /// slice headers of the current picture. 1573 pub short_term_ref_pic_set_sps_flag: bool, 1574 /// The st_ref_pic_set() data. 1575 pub short_term_ref_pic_set: ShortTermRefPicSet, 1576 /// Specifies the index, into the list of the st_ref_pic_set( ) syntax 1577 /// structures included in the active SPS, of the st_ref_pic_set( ) syntax 1578 /// structure that is used for derivation of the short-term RPS of the 1579 /// current picture. 1580 pub short_term_ref_pic_set_idx: u8, 1581 /// Specifies the number of entries in the long-term RPS of the current 1582 /// picture that are derived based on the candidate long-term reference 1583 /// pictures specified in the active SPS. 1584 pub num_long_term_sps: u8, 1585 /// Specifies the number of entries in the long-term RPS of the current 1586 /// picture that are directly signalled in the slice header. 1587 pub num_long_term_pics: u8, 1588 /// `lt_idx_sps[ i ]` specifies an index, into the list of candidate long-term 1589 /// reference pictures specified in the active SPS, of the i-th entry in the 1590 /// long-term RPS of the current picture. 1591 pub lt_idx_sps: [u8; 16], 1592 /// Same as PocLsbLt in the specification. 1593 pub poc_lsb_lt: [u32; 16], 1594 /// Same as UsedByCurrPicLt in the specification. 1595 pub used_by_curr_pic_lt: [bool; 16], 1596 /// When set, specifies that that `delta_poc_msb_cycle_lt[i]` is present. 1597 pub delta_poc_msb_present_flag: [bool; 16], 1598 /// Same as DeltaPocMsbCycleLt in the specification. 1599 pub delta_poc_msb_cycle_lt: [u32; 16], 1600 /// Specifies whether temporal motion vector predictors can be used for 1601 /// inter prediction. If slice_temporal_mvp_enabled_flag is not set, the 1602 /// syntax elements of the current picture shall be constrained such that no 1603 /// temporal motion vector predictor is used in decoding of the current 1604 /// picture. Otherwise (slice_temporal_mvp_enabled_flag is set), temporal 1605 /// motion vector predictors may be used in decoding of the current picture. 1606 pub temporal_mvp_enabled_flag: bool, 1607 /// When set, specifies that SAO is enabled for the luma component in the 1608 /// current slice; slice_sao_luma_flag not set specifies that SAO is 1609 /// disabled for the luma component in the current slice. 1610 pub sao_luma_flag: bool, 1611 /// When set, specifies that SAO is enabled for the chroma component in the 1612 /// current slice; When not set, specifies that SAO is disabled for the 1613 /// chroma component in the current slice. 1614 pub sao_chroma_flag: bool, 1615 /// When set, specifies that the syntax element num_ref_idx_l0_active_minus1 1616 /// is present for P and B slices and that the syntax element 1617 /// num_ref_idx_l1_active_minus1 is present for B slices. When not set, 1618 /// specifies that the syntax elements num_ref_idx_l0_active_minus1 and 1619 /// num_ref_idx_l1_active_minus1 are not present. 1620 pub num_ref_idx_active_override_flag: bool, 1621 /// Specifies the maximum reference index for 1622 /// reference picture list 0 that may be used to decode the slice. 1623 pub num_ref_idx_l0_active_minus1: u8, 1624 /// Specifies the maximum reference index for reference picture list 1 that 1625 /// may be used to decode the slice. 1626 pub num_ref_idx_l1_active_minus1: u8, 1627 /// The RefPicListModification data. 1628 pub ref_pic_list_modification: RefPicListModification, 1629 /// When set, indicates that the mvd_coding( x0, y0, 1 ) syntax structure is 1630 /// not parsed and `MvdL1[ x0 ]`[ y0 `][ compIdx ]` is set equal to 0 for 1631 /// compIdx = 0..1. When not set, indicates that the mvd_coding( x0, y0, 1 ) 1632 /// syntax structure is parsed. 1633 pub mvd_l1_zero_flag: bool, 1634 /// Specifies the method for determining the initialization table used in 1635 /// the initialization process for context variables. 1636 pub cabac_init_flag: bool, 1637 /// When set, specifies that the collocated picture used for temporal motion 1638 /// vector prediction is derived from reference picture list 0. When not 1639 /// set, specifies that the collocated picture used for temporal motion 1640 /// vector prediction is derived from reference picture list 1. 1641 pub collocated_from_l0_flag: bool, 1642 /// Specifies the reference index of the collocated picture used for 1643 /// temporal motion vector prediction. 1644 pub collocated_ref_idx: u8, 1645 /// The PredWeightTable data. 1646 pub pred_weight_table: PredWeightTable, 1647 /// Specifies the maximum number of merging motion vector prediction (MVP) 1648 /// candidates supported in the slice subtracted from 5. 1649 pub five_minus_max_num_merge_cand: u8, 1650 /// Specifies that the resolution of motion vectors for inter prediction in 1651 /// the current slice is integer. When not set, specifies 1652 /// that the resolution of motion vectors for inter prediction in the 1653 /// current slice that refer to pictures other than the current picture is 1654 /// fractional with quarter-sample precision in units of luma samples. 1655 pub use_integer_mv_flag: bool, 1656 /// Specifies the initial value of QpY to be used for the coding blocks in 1657 /// the slice until modified by the value of CuQpDeltaVal in the coding unit 1658 /// layer. 1659 pub qp_delta: i8, 1660 /// Specifies a difference to be added to the value of pps_cb_qp_offset when 1661 /// determining the value of the Qp′Cb quantization parameter. 1662 pub cb_qp_offset: i8, 1663 /// Specifies a difference to be added to the value of pps_cb_qr_offset when 1664 /// determining the value of the Qp′Cr quantization parameter. 1665 pub cr_qp_offset: i8, 1666 /// Specifies offsets to the quantization parameter values qP derived in 1667 /// clause 8.6.2 for luma, Cb, and Cr components, respectively. 1668 pub slice_act_y_qp_offset: i8, 1669 /// Specifies offsets to the quantization parameter values qP derived in 1670 /// clause 8.6.2 for luma, Cb, and Cr components, respectively. 1671 pub slice_act_cb_qp_offset: i8, 1672 /// Specifies offsets to the quantization parameter values qP derived in 1673 /// clause 8.6.2 for luma, Cb, and Cr components, respectively. 1674 pub slice_act_cr_qp_offset: i8, 1675 /// When set, specifies that the cu_chroma_qp_offset_flag may be present in 1676 /// the transform unit syntax. When not set, specifies that the 1677 /// cu_chroma_qp_offset_flag is not present in the transform unit syntax. 1678 pub cu_chroma_qp_offset_enabled_flag: bool, 1679 /// When set, specifies that deblocking parameters are present in the slice 1680 /// header. When not set, specifies that deblocking parameters are not 1681 /// present in the slice header. 1682 pub deblocking_filter_override_flag: bool, 1683 /// When set, specifies that the operation of the deblocking filter is not 1684 /// applied for the current slice. When not set, specifies that the 1685 /// operation of the deblocking filter is applied for the current slice. 1686 pub deblocking_filter_disabled_flag: bool, 1687 /// Specifies the deblocking parameter offsets for β and tC (divided by 2) 1688 /// for the current slice. 1689 pub beta_offset_div2: i8, 1690 /// Specifies the deblocking parameter offsets for β and tC (divided by 2) 1691 /// for the current slice. 1692 pub tc_offset_div2: i8, 1693 /// When set, specifies that in-loop filtering operations may be performed 1694 /// across the left and upper boundaries of the current slice. When not 1695 /// set, specifies that in-loop operations are not performed across left and 1696 /// upper boundaries of the current slice. The in-loop filtering operations 1697 /// include the deblocking filter and sample adaptive offset filter. 1698 pub loop_filter_across_slices_enabled_flag: bool, 1699 /// Specifies the number of `entry_point_offset_minus1[ i ]` syntax elements 1700 /// in the slice header. 1701 pub num_entry_point_offsets: u32, 1702 /// offset_len_minus1 plus 1 specifies the length, in bits, of the 1703 /// `entry_point_offset_minus1[ i ]` syntax elements. 1704 pub offset_len_minus1: u8, 1705 /// `entry_point_offset_minus1[ i ]` plus 1 specifies the i-th entry point 1706 /// offset in bytes, and is represented by offset_len_minus1 plus 1 bits. 1707 /// The slice segment data that follow the slice segment header consists of 1708 /// num_entry_point_offsets + 1 subsets, with subset index values ranging 1709 /// from 0 to num_entry_point_offsets, inclusive. See the specification for 1710 /// more details. 1711 pub entry_point_offset_minus1: [u32; 32], 1712 /// Same as NumPicTotalCurr in the specification. 1713 pub num_pic_total_curr: u32, 1714 // Size of slice_header() in bits. 1715 pub header_bit_size: u32, 1716 // Number of emulation prevention bytes (EPB) in this slice_header(). 1717 pub n_emulation_prevention_bytes: u32, 1718 /// Same as CurrRpsIdx in the specification. 1719 pub curr_rps_idx: u8, 1720 /// Number of bits taken by st_ref_pic_set minus Emulation Prevention Bytes. 1721 pub st_rps_bits: u32, 1722 } 1723 1724 impl Default for SliceHeader { default() -> Self1725 fn default() -> Self { 1726 Self { 1727 first_slice_segment_in_pic_flag: Default::default(), 1728 no_output_of_prior_pics_flag: Default::default(), 1729 pic_parameter_set_id: Default::default(), 1730 dependent_slice_segment_flag: Default::default(), 1731 segment_address: Default::default(), 1732 type_: Default::default(), 1733 pic_output_flag: true, 1734 colour_plane_id: Default::default(), 1735 pic_order_cnt_lsb: Default::default(), 1736 short_term_ref_pic_set_sps_flag: Default::default(), 1737 short_term_ref_pic_set: Default::default(), 1738 short_term_ref_pic_set_idx: Default::default(), 1739 num_long_term_sps: Default::default(), 1740 num_long_term_pics: Default::default(), 1741 lt_idx_sps: Default::default(), 1742 poc_lsb_lt: Default::default(), 1743 used_by_curr_pic_lt: Default::default(), 1744 delta_poc_msb_present_flag: Default::default(), 1745 delta_poc_msb_cycle_lt: Default::default(), 1746 temporal_mvp_enabled_flag: Default::default(), 1747 sao_luma_flag: Default::default(), 1748 sao_chroma_flag: Default::default(), 1749 num_ref_idx_active_override_flag: Default::default(), 1750 num_ref_idx_l0_active_minus1: Default::default(), 1751 num_ref_idx_l1_active_minus1: Default::default(), 1752 ref_pic_list_modification: Default::default(), 1753 mvd_l1_zero_flag: Default::default(), 1754 cabac_init_flag: Default::default(), 1755 collocated_from_l0_flag: true, 1756 collocated_ref_idx: Default::default(), 1757 pred_weight_table: Default::default(), 1758 five_minus_max_num_merge_cand: Default::default(), 1759 use_integer_mv_flag: Default::default(), 1760 qp_delta: Default::default(), 1761 cb_qp_offset: Default::default(), 1762 cr_qp_offset: Default::default(), 1763 slice_act_y_qp_offset: Default::default(), 1764 slice_act_cb_qp_offset: Default::default(), 1765 slice_act_cr_qp_offset: Default::default(), 1766 cu_chroma_qp_offset_enabled_flag: Default::default(), 1767 deblocking_filter_override_flag: Default::default(), 1768 deblocking_filter_disabled_flag: Default::default(), 1769 beta_offset_div2: Default::default(), 1770 tc_offset_div2: Default::default(), 1771 loop_filter_across_slices_enabled_flag: Default::default(), 1772 num_entry_point_offsets: Default::default(), 1773 offset_len_minus1: Default::default(), 1774 entry_point_offset_minus1: Default::default(), 1775 num_pic_total_curr: Default::default(), 1776 header_bit_size: Default::default(), 1777 n_emulation_prevention_bytes: Default::default(), 1778 curr_rps_idx: Default::default(), 1779 st_rps_bits: Default::default(), 1780 } 1781 } 1782 } 1783 1784 /// A H265 slice. An integer number of macroblocks or macroblock pairs ordered 1785 /// consecutively in the raster scan within a particular slice group 1786 pub struct Slice<'a> { 1787 /// The slice header. 1788 pub header: SliceHeader, 1789 /// The NAL unit backing this slice. 1790 pub nalu: Nalu<'a>, 1791 } 1792 1793 impl<'a> Slice<'a> { 1794 /// Sets the header for dependent slices by copying from an independent 1795 /// slice. replace_header(&mut self, header: SliceHeader) -> Result<(), String>1796 pub fn replace_header(&mut self, header: SliceHeader) -> Result<(), String> { 1797 if !self.header.dependent_slice_segment_flag { 1798 Err("Replacing the slice header is only possible for dependent slices".into()) 1799 } else { 1800 let first_slice_segment_in_pic_flag = self.header.first_slice_segment_in_pic_flag; 1801 let no_output_of_prior_pics_flag = self.header.no_output_of_prior_pics_flag; 1802 let pic_parameter_set_id = self.header.pic_parameter_set_id; 1803 let dependent_slice_segment_flag = self.header.dependent_slice_segment_flag; 1804 let segment_address = self.header.segment_address; 1805 1806 let offset_len_minus1 = self.header.offset_len_minus1; 1807 let entry_point_offset_minus1 = self.header.entry_point_offset_minus1; 1808 let num_pic_total_curr = self.header.num_pic_total_curr; 1809 let header_bit_size = self.header.header_bit_size; 1810 let n_emulation_prevention_bytes = self.header.n_emulation_prevention_bytes; 1811 let curr_rps_idx = self.header.curr_rps_idx; 1812 let st_rps_bits = self.header.st_rps_bits; 1813 1814 self.header = header; 1815 1816 self.header.first_slice_segment_in_pic_flag = first_slice_segment_in_pic_flag; 1817 self.header.no_output_of_prior_pics_flag = no_output_of_prior_pics_flag; 1818 self.header.pic_parameter_set_id = pic_parameter_set_id; 1819 self.header.dependent_slice_segment_flag = dependent_slice_segment_flag; 1820 self.header.segment_address = segment_address; 1821 self.header.offset_len_minus1 = offset_len_minus1; 1822 self.header.entry_point_offset_minus1 = entry_point_offset_minus1; 1823 self.header.num_pic_total_curr = num_pic_total_curr; 1824 self.header.header_bit_size = header_bit_size; 1825 self.header.n_emulation_prevention_bytes = n_emulation_prevention_bytes; 1826 self.header.curr_rps_idx = curr_rps_idx; 1827 self.header.st_rps_bits = st_rps_bits; 1828 1829 Ok(()) 1830 } 1831 } 1832 } 1833 1834 #[derive(Clone, Debug, Default, PartialEq, Eq)] 1835 pub struct SublayerHrdParameters { 1836 // NOTE: The value of CpbCnt is cpb_cnt_minus1[i] + 1, and cpb_cnt_minus1 1837 // ranges from 0..=31 1838 /// `bit_rate_value_minus1[ i ]` (together with bit_rate_scale) specifies the 1839 /// maximum input bit rate for the i-th CPB when the CPB operates at the 1840 /// access unit level 1841 pub bit_rate_value_minus1: [u32; 32], 1842 /// `cpb_size_value_minus1[ i ]` is used together with cpb_size_scale to 1843 /// specify the i-th CPB size when the CPB operates at the access unit 1844 /// level. 1845 pub cpb_size_value_minus1: [u32; 32], 1846 /// `cpb_size_du_value_minus1[ i ]` is used together with cpb_size_du_scale to 1847 /// specify the i-th CPB size when the CPB operates at sub-picture level. 1848 pub cpb_size_du_value_minus1: [u32; 32], 1849 /// `bit_rate_du_value_minus1[ i ]` (together with bit_rate_scale) specifies 1850 /// the maximum input bit rate for the i-th CPB when the CPB operates at the 1851 /// sub-picture level. 1852 pub bit_rate_du_value_minus1: [u32; 32], 1853 /// `cbr_flag[ i ]` not set specifies that to decode this CVS by the HRD using 1854 /// the i-th CPB specification. 1855 pub cbr_flag: [bool; 32], 1856 } 1857 1858 #[derive(Clone, Debug, PartialEq, Eq)] 1859 pub struct HrdParams { 1860 /// When set, specifies that NAL HRD parameters (pertaining to the Type II 1861 /// bitstream conformance point) are present in the hrd_parameters( ) syntax 1862 /// structure. When not set, specifies that NAL HRD parameters are not 1863 /// present in the hrd_parameters( ) syntax structure. 1864 pub nal_hrd_parameters_present_flag: bool, 1865 /// When set, specifies that VCL HRD parameters (pertaining to the Type I 1866 /// bitstream conformance point) are present in the hrd_parameters( ) syntax 1867 /// structure. When not set, specifies that VCL HRD parameters are not 1868 /// present in the hrd_parameters( ) syntax structure. 1869 pub vcl_hrd_parameters_present_flag: bool, 1870 /// When set, specifies that sub-picture level HRD parameters are present 1871 /// and the HRD may operate at access unit level or sub-picture level. When 1872 /// not set, specifies that sub-picture level HRD parameters are not present 1873 /// and the HRD operates at access unit level. 1874 pub sub_pic_hrd_params_present_flag: bool, 1875 /// Used to specify the clock sub-tick. A clock sub-tick is the minimum 1876 /// interval of time that can be represented in the coded data when 1877 /// sub_pic_hrd_params_present_flag is set. 1878 pub tick_divisor_minus2: u8, 1879 /// du_cpb_removal_delay_increment_length_minus1 plus 1 specifies the 1880 /// length, in bits, of the `du_cpb_removal_delay_increment_minus1[ i ]` and 1881 /// du_common_cpb_removal_delay_increment_minus1 syntax elements of the 1882 /// picture timing SEI message and the du_spt_cpb_removal_delay_increment 1883 /// syntax element in the decoding unit information SEI message. 1884 pub du_cpb_removal_delay_increment_length_minus1: u8, 1885 /// When set, specifies that sub-picture level CPB removal delay parameters 1886 /// are present in picture timing SEI messages and no decoding unit 1887 /// information SEI message is available (in the CVS or provided through 1888 /// external means not specified in this Specification). When not set, 1889 /// specifies that sub-picture level CPB removal delay parameters are 1890 /// present in decoding unit information SEI messages and picture timing SEI 1891 /// messages do not include sub-picture level CPB removal delay parameters. 1892 pub sub_pic_cpb_params_in_pic_timing_sei_flag: bool, 1893 /// dpb_output_delay_du_length_minus1 plus 1 specifies the length, in bits, 1894 /// of the pic_dpb_output_du_delay syntax element in the picture timing SEI 1895 /// message and the pic_spt_dpb_output_du_delay syntax element in the 1896 /// decoding unit information SEI message. 1897 pub dpb_output_delay_du_length_minus1: u8, 1898 /// Together with `bit_rate_value_minus1[ i ]`, specifies the maximum input 1899 /// bit rate of the i-th CPB. 1900 pub bit_rate_scale: u8, 1901 /// Together with `cpb_size_du_value_minus1[ i ]`, specifies the CPB size of 1902 /// the i-th CPB when the CPB operates at sub-picture level. 1903 pub cpb_size_scale: u8, 1904 /// Together with `cpb_size_du_value_minus1[ i ]`, specifies the CPB size of 1905 /// the i-th CPB when the CPB operates at sub-picture level. 1906 pub cpb_size_du_scale: u8, 1907 /// initial_cpb_removal_delay_length_minus1 plus 1 specifies the length, in 1908 /// bits, of the `nal_initial_cpb_removal_delay[ i ]`, 1909 /// `nal_initial_cpb_removal_offset[ i ]`, `vcl_initial_cpb_removal_delay[ i ]` 1910 /// and `vcl_initial_cpb_removal_offset[ i ]` syntax elements of the buffering 1911 /// period SEI message. 1912 pub initial_cpb_removal_delay_length_minus1: u8, 1913 /// au_cpb_removal_delay_length_minus1 plus 1 specifies the length, in bits, 1914 /// of the cpb_delay_offset syntax element in the buffering period SEI 1915 /// message and the au_cpb_removal_delay_minus1 syntax element in the 1916 /// picture timing SEI message. 1917 pub au_cpb_removal_delay_length_minus1: u8, 1918 /// dpb_output_delay_length_minus1 plus 1 specifies the length, in bits, of 1919 /// the dpb_delay_offset syntax element in the buffering period SEI message 1920 /// and the pic_dpb_output_delay syntax element in the picture timing SEI 1921 /// message. 1922 pub dpb_output_delay_length_minus1: u8, 1923 /// `fixed_pic_rate_general_flag[ i ]` set indicates that, when HighestTid is 1924 /// equal to i, the temporal distance between the HRD output times of 1925 /// consecutive pictures in output order is constrained as specified in the 1926 /// specification. `fixed_pic_rate_general_flag[ i ]` not set indicates that 1927 /// this constraint may not apply. 1928 pub fixed_pic_rate_general_flag: [bool; 7], 1929 /// `fixed_pic_rate_within_cvs_flag[ i ]` set indicates that, when HighestTid 1930 /// is equal to i, the temporal distance between the HRD output times of 1931 /// consecutive pictures in output order is constrained as specified in the 1932 /// specification. `fixed_pic_rate_within_cvs_flag[ i ]` not set indicates 1933 /// that this constraint may not apply. 1934 pub fixed_pic_rate_within_cvs_flag: [bool; 7], 1935 /// `elemental_duration_in_tc_minus1[ i ]` plus 1 (when present) specifies, 1936 /// when HighestTid is equal to i, the temporal distance, in clock ticks, 1937 /// between the elemental units that specify the HRD output times of 1938 /// consecutive pictures in output order as specified in the specification. 1939 pub elemental_duration_in_tc_minus1: [u32; 7], 1940 /// `low_delay_hrd_flag[ i ]` specifies the HRD operational mode, when 1941 /// HighestTid is equal to i, as specified in Annex C or clause F.13. 1942 pub low_delay_hrd_flag: [bool; 7], 1943 /// `cpb_cnt_minus1[ i ]` plus 1 specifies the number of alternative CPB 1944 /// specifications in the bitstream of the CVS when HighestTid is equal to 1945 /// i. 1946 pub cpb_cnt_minus1: [u32; 7], 1947 /// The NAL HRD data. 1948 pub nal_hrd: [SublayerHrdParameters; 7], 1949 /// The VCL HRD data. 1950 pub vcl_hrd: [SublayerHrdParameters; 7], 1951 } 1952 1953 impl Default for HrdParams { default() -> Self1954 fn default() -> Self { 1955 Self { 1956 initial_cpb_removal_delay_length_minus1: 23, 1957 au_cpb_removal_delay_length_minus1: 23, 1958 dpb_output_delay_du_length_minus1: 23, 1959 nal_hrd_parameters_present_flag: Default::default(), 1960 vcl_hrd_parameters_present_flag: Default::default(), 1961 sub_pic_hrd_params_present_flag: Default::default(), 1962 tick_divisor_minus2: Default::default(), 1963 du_cpb_removal_delay_increment_length_minus1: Default::default(), 1964 sub_pic_cpb_params_in_pic_timing_sei_flag: Default::default(), 1965 bit_rate_scale: Default::default(), 1966 cpb_size_scale: Default::default(), 1967 cpb_size_du_scale: Default::default(), 1968 dpb_output_delay_length_minus1: Default::default(), 1969 fixed_pic_rate_general_flag: Default::default(), 1970 fixed_pic_rate_within_cvs_flag: Default::default(), 1971 elemental_duration_in_tc_minus1: Default::default(), 1972 low_delay_hrd_flag: Default::default(), 1973 cpb_cnt_minus1: Default::default(), 1974 nal_hrd: Default::default(), 1975 vcl_hrd: Default::default(), 1976 } 1977 } 1978 } 1979 1980 #[derive(Clone, Debug, PartialEq, Eq)] 1981 pub struct VuiParams { 1982 /// When set, specifies that aspect_ratio_idc is present. When not set, 1983 /// specifies that aspect_ratio_idc is not present. 1984 pub aspect_ratio_info_present_flag: bool, 1985 /// Specifies the value of the sample aspect ratio of the luma samples. 1986 pub aspect_ratio_idc: u32, 1987 /// Indicates the horizontal size of the sample aspect ratio (in arbitrary 1988 /// units). 1989 pub sar_width: u32, 1990 /// Indicates the vertical size of the sample aspect ratio (in arbitrary 1991 /// units). 1992 pub sar_height: u32, 1993 /// When set, specifies that the overscan_appropriate_flag is present. When 1994 /// not set, the preferred display method for the video signal is 1995 /// unspecified. 1996 pub overscan_info_present_flag: bool, 1997 /// When set indicates that the cropped decoded pictures output are suitable 1998 /// for display using overscan. When not set, indicates that the cropped 1999 /// decoded pictures output contain visually important information in the 2000 /// entire region out to the edges of the conformance cropping window of the 2001 /// picture, such that the cropped decoded pictures output should not be 2002 /// displayed using overscan. 2003 pub overscan_appropriate_flag: bool, 2004 /// When set, specifies that video_format, video_full_range_flag and 2005 /// colour_description_present_flag are present. When not set, specify that 2006 /// video_format, video_full_range_flag and colour_description_present_flag 2007 /// are not present. 2008 pub video_signal_type_present_flag: bool, 2009 /// Indicates the representation of the pictures as specified in Table E.2, 2010 /// before being coded in accordance with this Specification. 2011 pub video_format: u8, 2012 /// Indicates the black level and range of the luma and chroma signals as 2013 /// derived from E′Y, E′PB, and E′PR or E′R, E′G, and E′B real-valued 2014 /// component signals. 2015 pub video_full_range_flag: bool, 2016 /// When set, specifies that colour_primaries, transfer_characteristics, and 2017 /// matrix_coeffs are present. When not set, specifies that 2018 /// colour_primaries, transfer_characteristics, and matrix_coeffs are not 2019 /// present. 2020 pub colour_description_present_flag: bool, 2021 /// Indicates the chromaticity coordinates of the source primaries as 2022 /// specified in Table E.3 in terms of the CIE 1931 definition of x and y as 2023 /// specified in ISO 11664-1. 2024 pub colour_primaries: u32, 2025 /// See table E.4 in the specification. 2026 pub transfer_characteristics: u32, 2027 /// Describes the matrix coefficients used in deriving luma and chroma 2028 /// signals from the green, blue, and red, or Y, Z, and X primaries, as 2029 /// specified in Table E.5. 2030 pub matrix_coeffs: u32, 2031 /// When true, specifies that chroma_sample_loc_type_top_field and 2032 /// chroma_sample_loc_type_bottom_field are present. When false, specifies 2033 /// that chroma_sample_loc_type_top_field and 2034 /// chroma_sample_loc_type_bottom_field are not present. 2035 pub chroma_loc_info_present_flag: bool, 2036 /// See the specification for more details. 2037 pub chroma_sample_loc_type_top_field: u32, 2038 /// See the specification for more details. 2039 pub chroma_sample_loc_type_bottom_field: u32, 2040 /// When true, indicates that the value of all decoded chroma samples is 2041 /// equal to 1 << ( BitDepthC − 1 ). When false, provides no indication of 2042 /// decoded chroma sample values. 2043 pub neutral_chroma_indication_flag: bool, 2044 /// When true, indicates that the CVS conveys pictures that represent 2045 /// fields, and specifies that a picture timing SEI message shall be present 2046 /// in every access unit of the current CVS. When false, indicates that the 2047 /// CVS conveys pictures that represent frames and that a picture timing SEI 2048 /// message may or may not be present in any access unit of the current CVS. 2049 pub field_seq_flag: bool, 2050 /// When true, specifies that picture timing SEI messages are present for 2051 /// every picture and include the pic_struct, source_scan_type and 2052 /// duplicate_flag syntax elements. When false, specifies that the 2053 /// pic_struct syntax element is not present in picture timing SEI messages. 2054 pub frame_field_info_present_flag: bool, 2055 /// When true, indicates that the default display window parameters follow 2056 /// next in the VUI. When false, indicates that the default display window 2057 /// parameters are not present. 2058 pub default_display_window_flag: bool, 2059 /// Specifies the samples of the pictures in the CVS that are within the 2060 /// default display window, in terms of a rectangular region specified in 2061 /// picture coordinates for display. 2062 pub def_disp_win_left_offset: u32, 2063 /// Specifies the samples of the pictures in the CVS that are within the 2064 /// default display window, in terms of a rectangular region specified in 2065 /// picture coordinates for display. 2066 pub def_disp_win_right_offset: u32, 2067 /// Specifies the samples of the pictures in the CVS that are within the 2068 /// default display window, in terms of a rectangular region specified in 2069 /// picture coordinates for display. 2070 pub def_disp_win_top_offset: u32, 2071 /// Specifies the samples of the pictures in the CVS that are within the 2072 /// default display window, in terms of a rectangular region specified in 2073 /// picture coordinates for display. 2074 pub def_disp_win_bottom_offset: u32, 2075 /// When set, specifies that vui_num_units_in_tick, vui_time_scale, 2076 /// vui_poc_proportional_to_timing_flag and vui_hrd_parameters_present_flag 2077 /// are present in the vui_parameters( ) syntax structure. When not set, 2078 /// specifies that vui_num_units_in_tick, vui_time_scale, 2079 /// vui_poc_proportional_to_timing_flag and vui_hrd_parameters_present_flag 2080 /// are not present in the vui_parameters( ) syntax structure 2081 pub timing_info_present_flag: bool, 2082 /// The number of time units of a clock operating at the frequency 2083 /// vui_time_scale Hz that corresponds to one increment (called a clock 2084 /// tick) of a clock tick counter. 2085 pub num_units_in_tick: u32, 2086 /// Is the number of time units that pass in one second. For example, a time 2087 /// coordinate system that measures time using a 27 MHz clock has a 2088 /// vui_time_scale of 27 000 000. 2089 pub time_scale: u32, 2090 /// When set, indicates that the picture order count value for each picture 2091 /// in the CVS that is not the first picture in the CVS, in decoding order, 2092 /// is proportional to the output time of the picture relative to the output 2093 /// time of the first picture in the CVS. When not set, indicates that the 2094 /// picture order count value for each picture in the CVS that is not the 2095 /// first picture in the CVS, in decoding order, may or may not be 2096 /// proportional to the output time of the picture relative to the output 2097 /// time of the first picture in the CVS. 2098 pub poc_proportional_to_timing_flag: bool, 2099 /// vui_num_ticks_poc_diff_one_minus1 plus 1 specifies the number of clock 2100 /// ticks corresponding to a difference of picture order count values equal 2101 /// to 1. 2102 pub num_ticks_poc_diff_one_minus1: u32, 2103 /// When set, specifies that the syntax structure hrd_parameters( ) is 2104 /// present in the vui_parameters( ) syntax structure. When not set, 2105 /// specifies that the syntax structure hrd_parameters( ) is not present in 2106 /// the vui_parameters( ) syntax structure. 2107 pub hrd_parameters_present_flag: bool, 2108 /// The hrd_parameters() data. 2109 pub hrd: HrdParams, 2110 /// When set, specifies that the bitstream restriction parameters for the 2111 /// CVS are present. When not set, specifies that the bitstream restriction 2112 /// parameters for the CVS are not present. 2113 pub bitstream_restriction_flag: bool, 2114 /// When set, indicates that each PPS that is active in the CVS has the same 2115 /// value of the syntax elements num_tile_columns_minus1, 2116 /// num_tile_rows_minus1, uniform_spacing_flag, `column_width_minus1[ i ]`, 2117 /// `row_height_minus1[ i ]` and loop_filter_across_tiles_enabled_flag, when 2118 /// present. When not set, indicates that tiles syntax elements in different 2119 /// PPSs may or may not have the same value 2120 pub tiles_fixed_structure_flag: bool, 2121 /// When not set, indicates that no sample outside the picture boundaries 2122 /// and no sample at a fractional sample position for which the sample value 2123 /// is derived using one or more samples outside the picture boundaries is 2124 /// used for inter prediction of any sample. When set, indicates that one 2125 /// or more samples outside the picture boundaries may be used in inter 2126 /// prediction. 2127 pub motion_vectors_over_pic_boundaries_flag: bool, 2128 /// When set, indicates that all P and B slices (when present) that belong 2129 /// to the same picture have an identical reference picture list 0 and that 2130 /// all B slices (when present) that belong to the same picture have an 2131 /// identical reference picture list 1. 2132 pub restricted_ref_pic_lists_flag: bool, 2133 /// When not equal to 0, establishes a bound on the maximum possible size of 2134 /// distinct coded spatial segmentation regions in the pictures of the CVS. 2135 pub min_spatial_segmentation_idc: u32, 2136 /// Indicates a number of bytes not exceeded by the sum of the sizes of the 2137 /// VCL NAL units associated with any coded picture in the CVS. 2138 pub max_bytes_per_pic_denom: u32, 2139 /// Indicates an upper bound for the number of coded bits of coding_unit( ) 2140 /// data for anycoding block in any picture of the CVS. 2141 pub max_bits_per_min_cu_denom: u32, 2142 /// Indicate the maximum absolute value of a decoded horizontal and vertical 2143 /// motion vector component, respectively, in quarter luma sample units, for 2144 /// all pictures in the CVS. 2145 pub log2_max_mv_length_horizontal: u32, 2146 /// Indicate the maximum absolute value of a decoded horizontal and vertical 2147 /// motion vector component, respectively, in quarter luma sample units, for 2148 /// all pictures in the CVS. 2149 pub log2_max_mv_length_vertical: u32, 2150 } 2151 2152 impl Default for VuiParams { default() -> Self2153 fn default() -> Self { 2154 Self { 2155 aspect_ratio_info_present_flag: Default::default(), 2156 aspect_ratio_idc: Default::default(), 2157 sar_width: Default::default(), 2158 sar_height: Default::default(), 2159 overscan_info_present_flag: Default::default(), 2160 overscan_appropriate_flag: Default::default(), 2161 video_signal_type_present_flag: Default::default(), 2162 video_format: 5, 2163 video_full_range_flag: Default::default(), 2164 colour_description_present_flag: Default::default(), 2165 colour_primaries: 2, 2166 transfer_characteristics: 2, 2167 matrix_coeffs: 2, 2168 chroma_loc_info_present_flag: Default::default(), 2169 chroma_sample_loc_type_top_field: Default::default(), 2170 chroma_sample_loc_type_bottom_field: Default::default(), 2171 neutral_chroma_indication_flag: Default::default(), 2172 field_seq_flag: Default::default(), 2173 frame_field_info_present_flag: Default::default(), 2174 default_display_window_flag: Default::default(), 2175 def_disp_win_left_offset: Default::default(), 2176 def_disp_win_right_offset: Default::default(), 2177 def_disp_win_top_offset: Default::default(), 2178 def_disp_win_bottom_offset: Default::default(), 2179 timing_info_present_flag: Default::default(), 2180 num_units_in_tick: Default::default(), 2181 time_scale: Default::default(), 2182 poc_proportional_to_timing_flag: Default::default(), 2183 num_ticks_poc_diff_one_minus1: Default::default(), 2184 hrd_parameters_present_flag: Default::default(), 2185 hrd: Default::default(), 2186 bitstream_restriction_flag: Default::default(), 2187 tiles_fixed_structure_flag: Default::default(), 2188 motion_vectors_over_pic_boundaries_flag: true, 2189 restricted_ref_pic_lists_flag: Default::default(), 2190 min_spatial_segmentation_idc: Default::default(), 2191 max_bytes_per_pic_denom: 2, 2192 max_bits_per_min_cu_denom: 1, 2193 log2_max_mv_length_horizontal: 15, 2194 log2_max_mv_length_vertical: 15, 2195 } 2196 } 2197 } 2198 2199 #[derive(Clone, Debug, Default)] 2200 pub struct Parser { 2201 active_vpses: BTreeMap<u8, Rc<Vps>>, 2202 active_spses: BTreeMap<u8, Rc<Sps>>, 2203 active_ppses: BTreeMap<u8, Rc<Pps>>, 2204 } 2205 2206 impl Parser { 2207 /// Parse a VPS NALU. parse_vps(&mut self, nalu: &Nalu) -> Result<&Vps, String>2208 pub fn parse_vps(&mut self, nalu: &Nalu) -> Result<&Vps, String> { 2209 if !matches!(nalu.header.type_, NaluType::VpsNut) { 2210 return Err(format!( 2211 "Invalid NALU type, expected {:?}, got {:?}", 2212 NaluType::VpsNut, 2213 nalu.header.type_ 2214 )); 2215 } 2216 2217 let data = nalu.as_ref(); 2218 let header = &nalu.header; 2219 let hdr_len = header.len(); 2220 // Skip the header 2221 let mut r = BitReader::new(&data[hdr_len..], true); 2222 2223 let mut vps = Vps { 2224 video_parameter_set_id: r.read_bits(4)?, 2225 base_layer_internal_flag: r.read_bit()?, 2226 base_layer_available_flag: r.read_bit()?, 2227 max_layers_minus1: r.read_bits(6)?, 2228 max_sub_layers_minus1: r.read_bits(3)?, 2229 temporal_id_nesting_flag: r.read_bit()?, 2230 ..Default::default() 2231 }; 2232 2233 r.skip_bits(16)?; // vps_reserved_0xffff_16bits 2234 2235 let ptl = &mut vps.profile_tier_level; 2236 Self::parse_profile_tier_level(ptl, &mut r, true, vps.max_sub_layers_minus1)?; 2237 2238 vps.sub_layer_ordering_info_present_flag = r.read_bit()?; 2239 2240 let start = 2241 if vps.sub_layer_ordering_info_present_flag { 0 } else { vps.max_sub_layers_minus1 } 2242 as usize; 2243 2244 for i in start..=usize::from(vps.max_sub_layers_minus1) { 2245 vps.max_dec_pic_buffering_minus1[i] = r.read_ue_max(15)?; 2246 vps.max_num_reorder_pics[i] = r.read_ue_max(vps.max_dec_pic_buffering_minus1[i])?; 2247 vps.max_latency_increase_plus1[i] = r.read_ue()?; 2248 2249 if i > 0 { 2250 if vps.max_dec_pic_buffering_minus1[i] < vps.max_dec_pic_buffering_minus1[i - 1] { 2251 return Err(format!( 2252 "Invalid max_dec_pic_buffering_minus1[{}]: {}", 2253 i, vps.max_dec_pic_buffering_minus1[i] 2254 )); 2255 } 2256 2257 if vps.max_num_reorder_pics[i] < vps.max_num_reorder_pics[i - 1] { 2258 return Err(format!( 2259 "Invalid max_num_reorder_pics[{}]: {}", 2260 i, vps.max_num_reorder_pics[i] 2261 )); 2262 } 2263 } 2264 } 2265 2266 // vps_sub_layer_ordering_info_present_flag equal to 0 specifies that 2267 // the values of vps_max_dec_pic_buffering_minus1[ 2268 // vps_max_sub_layers_minus1 ], vps_max_num_reorder_pics[ vps_max_sub_ 2269 // layers_minus1 ] and vps_max_latency_increase_plus1[ 2270 // vps_max_sub_layers_minus1 ] apply to all sub-layers 2271 if !vps.sub_layer_ordering_info_present_flag { 2272 let max_num_sublayers = usize::from(vps.max_sub_layers_minus1); 2273 for i in 0..max_num_sublayers { 2274 vps.max_dec_pic_buffering_minus1[i] = 2275 vps.max_dec_pic_buffering_minus1[max_num_sublayers]; 2276 2277 vps.max_num_reorder_pics[i] = vps.max_num_reorder_pics[max_num_sublayers]; 2278 2279 vps.max_latency_increase_plus1[i] = 2280 vps.max_latency_increase_plus1[max_num_sublayers]; 2281 } 2282 } 2283 2284 vps.max_layer_id = r.read_bits(6)?; 2285 if vps.max_layer_id > 62 { 2286 return Err(format!("Invalid max_layer_id {}", vps.max_layer_id)); 2287 } 2288 2289 vps.num_layer_sets_minus1 = r.read_ue_max(1023)?; 2290 2291 for _ in 1..=vps.num_layer_sets_minus1 { 2292 for _ in 0..=vps.max_layer_id { 2293 // Skip layer_id_included_flag[i][j] for now. 2294 r.skip_bits(1)?; 2295 } 2296 } 2297 2298 vps.timing_info_present_flag = r.read_bit()?; 2299 2300 if vps.timing_info_present_flag { 2301 vps.num_units_in_tick = r.read_bits::<u32>(31)? << 1; 2302 vps.num_units_in_tick |= r.read_bits::<u32>(1)?; 2303 2304 vps.time_scale = r.read_bits::<u32>(31)? << 1; 2305 vps.time_scale |= r.read_bits::<u32>(1)?; 2306 2307 vps.poc_proportional_to_timing_flag = r.read_bit()?; 2308 if vps.poc_proportional_to_timing_flag { 2309 vps.num_ticks_poc_diff_one_minus1 = r.read_ue()?; 2310 } 2311 2312 vps.num_hrd_parameters = r.read_ue()?; 2313 2314 for i in 0..vps.num_hrd_parameters as usize { 2315 vps.hrd_layer_set_idx.push(r.read_ue()?); 2316 if i > 0 { 2317 vps.cprms_present_flag.push(r.read_bit()?); 2318 } 2319 2320 let mut hrd = HrdParams::default(); 2321 Self::parse_hrd_parameters( 2322 vps.cprms_present_flag[i], 2323 vps.max_sub_layers_minus1, 2324 &mut hrd, 2325 &mut r, 2326 )?; 2327 2328 vps.hrd_parameters.push(hrd); 2329 } 2330 } 2331 2332 vps.extension_flag = r.read_bit()?; 2333 2334 if self.active_vpses.keys().len() >= MAX_VPS_COUNT { 2335 return Err("Broken data: Number of active VPSs > MAX_VPS_COUNT".into()); 2336 } 2337 2338 let key = vps.video_parameter_set_id; 2339 let vps = Rc::new(vps); 2340 self.active_vpses.remove(&key); 2341 Ok(self.active_vpses.entry(key).or_insert(vps)) 2342 } 2343 parse_profile_tier_level( ptl: &mut ProfileTierLevel, r: &mut BitReader, profile_present_flag: bool, sps_max_sub_layers_minus_1: u8, ) -> Result<(), String>2344 fn parse_profile_tier_level( 2345 ptl: &mut ProfileTierLevel, 2346 r: &mut BitReader, 2347 profile_present_flag: bool, 2348 sps_max_sub_layers_minus_1: u8, 2349 ) -> Result<(), String> { 2350 if profile_present_flag { 2351 ptl.general_profile_space = r.read_bits(2)?; 2352 ptl.general_tier_flag = r.read_bit()?; 2353 ptl.general_profile_idc = r.read_bits(5)?; 2354 2355 for i in 0..32 { 2356 ptl.general_profile_compatibility_flag[i] = r.read_bit()?; 2357 } 2358 2359 ptl.general_progressive_source_flag = r.read_bit()?; 2360 ptl.general_interlaced_source_flag = r.read_bit()?; 2361 ptl.general_non_packed_constraint_flag = r.read_bit()?; 2362 ptl.general_frame_only_constraint_flag = r.read_bit()?; 2363 2364 if ptl.general_profile_idc == 4 2365 || ptl.general_profile_compatibility_flag[4] 2366 || ptl.general_profile_idc == 5 2367 || ptl.general_profile_compatibility_flag[5] 2368 || ptl.general_profile_idc == 6 2369 || ptl.general_profile_compatibility_flag[6] 2370 || ptl.general_profile_idc == 7 2371 || ptl.general_profile_compatibility_flag[7] 2372 || ptl.general_profile_idc == 8 2373 || ptl.general_profile_compatibility_flag[8] 2374 || ptl.general_profile_idc == 9 2375 || ptl.general_profile_compatibility_flag[9] 2376 || ptl.general_profile_idc == 10 2377 || ptl.general_profile_compatibility_flag[10] 2378 || ptl.general_profile_idc == 11 2379 || ptl.general_profile_compatibility_flag[11] 2380 { 2381 ptl.general_max_12bit_constraint_flag = r.read_bit()?; 2382 ptl.general_max_10bit_constraint_flag = r.read_bit()?; 2383 ptl.general_max_8bit_constraint_flag = r.read_bit()?; 2384 ptl.general_max_422chroma_constraint_flag = r.read_bit()?; 2385 ptl.general_max_420chroma_constraint_flag = r.read_bit()?; 2386 ptl.general_max_monochrome_constraint_flag = r.read_bit()?; 2387 ptl.general_intra_constraint_flag = r.read_bit()?; 2388 ptl.general_one_picture_only_constraint_flag = r.read_bit()?; 2389 ptl.general_lower_bit_rate_constraint_flag = r.read_bit()?; 2390 if ptl.general_profile_idc == 5 2391 || ptl.general_profile_compatibility_flag[5] 2392 || ptl.general_profile_idc == 9 2393 || ptl.general_profile_compatibility_flag[9] 2394 || ptl.general_profile_idc == 10 2395 || ptl.general_profile_compatibility_flag[10] 2396 || ptl.general_profile_idc == 11 2397 || ptl.general_profile_compatibility_flag[11] 2398 { 2399 ptl.general_max_14bit_constraint_flag = r.read_bit()?; 2400 // Skip general_reserved_zero_33bits 2401 r.skip_bits(31)?; 2402 r.skip_bits(2)?; 2403 } else { 2404 // Skip general_reserved_zero_34bits 2405 r.skip_bits(31)?; 2406 r.skip_bits(3)?; 2407 } 2408 } else if ptl.general_profile_idc == 2 || ptl.general_profile_compatibility_flag[2] { 2409 // Skip general_reserved_zero_7bits 2410 r.skip_bits(7)?; 2411 ptl.general_one_picture_only_constraint_flag = r.read_bit()?; 2412 // Skip general_reserved_zero_35bits 2413 r.skip_bits(31)?; 2414 r.skip_bits(4)?; 2415 } else { 2416 r.skip_bits(31)?; 2417 r.skip_bits(12)?; 2418 } 2419 2420 if ptl.general_profile_idc == 1 2421 || ptl.general_profile_compatibility_flag[1] 2422 || ptl.general_profile_idc == 2 2423 || ptl.general_profile_compatibility_flag[2] 2424 || ptl.general_profile_idc == 3 2425 || ptl.general_profile_compatibility_flag[3] 2426 || ptl.general_profile_idc == 4 2427 || ptl.general_profile_compatibility_flag[4] 2428 || ptl.general_profile_idc == 5 2429 || ptl.general_profile_compatibility_flag[5] 2430 || ptl.general_profile_idc == 9 2431 || ptl.general_profile_compatibility_flag[9] 2432 || ptl.general_profile_idc == 11 2433 || ptl.general_profile_compatibility_flag[11] 2434 { 2435 ptl.general_inbld_flag = r.read_bit()?; 2436 } else { 2437 r.skip_bits(1)?; 2438 } 2439 } 2440 2441 let level: u8 = r.read_bits(8)?; 2442 ptl.general_level_idc = Level::try_from(level)?; 2443 2444 for i in 0..sps_max_sub_layers_minus_1 as usize { 2445 ptl.sub_layer_profile_present_flag[i] = r.read_bit()?; 2446 ptl.sub_layer_level_present_flag[i] = r.read_bit()?; 2447 } 2448 2449 if sps_max_sub_layers_minus_1 > 0 { 2450 for _ in sps_max_sub_layers_minus_1..8 { 2451 r.skip_bits(2)?; 2452 } 2453 } 2454 2455 for i in 0..sps_max_sub_layers_minus_1 as usize { 2456 if ptl.sub_layer_level_present_flag[i] { 2457 ptl.sub_layer_profile_space[i] = r.read_bits(2)?; 2458 ptl.sub_layer_tier_flag[i] = r.read_bit()?; 2459 ptl.sub_layer_profile_idc[i] = r.read_bits(5)?; 2460 for j in 0..32 { 2461 ptl.sub_layer_profile_compatibility_flag[i][j] = r.read_bit()?; 2462 } 2463 ptl.sub_layer_progressive_source_flag[i] = r.read_bit()?; 2464 ptl.sub_layer_interlaced_source_flag[i] = r.read_bit()?; 2465 ptl.sub_layer_non_packed_constraint_flag[i] = r.read_bit()?; 2466 ptl.sub_layer_frame_only_constraint_flag[i] = r.read_bit()?; 2467 2468 if ptl.sub_layer_profile_idc[i] == 4 2469 || ptl.sub_layer_profile_compatibility_flag[i][4] 2470 || ptl.sub_layer_profile_idc[i] == 5 2471 || ptl.sub_layer_profile_compatibility_flag[i][5] 2472 || ptl.sub_layer_profile_idc[i] == 6 2473 || ptl.sub_layer_profile_compatibility_flag[i][6] 2474 || ptl.sub_layer_profile_idc[i] == 7 2475 || ptl.sub_layer_profile_compatibility_flag[i][7] 2476 || ptl.sub_layer_profile_idc[i] == 8 2477 || ptl.sub_layer_profile_compatibility_flag[i][8] 2478 || ptl.sub_layer_profile_idc[i] == 9 2479 || ptl.sub_layer_profile_compatibility_flag[i][9] 2480 || ptl.sub_layer_profile_idc[i] == 10 2481 || ptl.sub_layer_profile_compatibility_flag[i][10] 2482 || ptl.sub_layer_profile_idc[i] == 11 2483 || ptl.sub_layer_profile_compatibility_flag[i][11] 2484 { 2485 ptl.sub_layer_max_12bit_constraint_flag[i] = r.read_bit()?; 2486 ptl.sub_layer_max_10bit_constraint_flag[i] = r.read_bit()?; 2487 ptl.sub_layer_max_8bit_constraint_flag[i] = r.read_bit()?; 2488 ptl.sub_layer_max_422chroma_constraint_flag[i] = r.read_bit()?; 2489 ptl.sub_layer_max_420chroma_constraint_flag[i] = r.read_bit()?; 2490 ptl.sub_layer_max_monochrome_constraint_flag[i] = r.read_bit()?; 2491 ptl.sub_layer_intra_constraint_flag[i] = r.read_bit()?; 2492 ptl.sub_layer_one_picture_only_constraint_flag[i] = r.read_bit()?; 2493 ptl.sub_layer_lower_bit_rate_constraint_flag[i] = r.read_bit()?; 2494 2495 if ptl.sub_layer_profile_idc[i] == 5 2496 || ptl.sub_layer_profile_compatibility_flag[i][5] 2497 || ptl.sub_layer_profile_idc[i] == 9 2498 || ptl.sub_layer_profile_compatibility_flag[i][9] 2499 || ptl.sub_layer_profile_idc[i] == 10 2500 || ptl.sub_layer_profile_compatibility_flag[i][10] 2501 || ptl.sub_layer_profile_idc[i] == 11 2502 || ptl.sub_layer_profile_compatibility_flag[i][11] 2503 { 2504 ptl.sub_layer_max_14bit_constraint_flag[i] = r.read_bit()?; 2505 r.skip_bits(33)?; 2506 } else { 2507 r.skip_bits(34)?; 2508 } 2509 } else if ptl.sub_layer_profile_idc[i] == 2 2510 || ptl.sub_layer_profile_compatibility_flag[i][2] 2511 { 2512 r.skip_bits(7)?; 2513 ptl.sub_layer_one_picture_only_constraint_flag[i] = r.read_bit()?; 2514 r.skip_bits(35)?; 2515 } else { 2516 r.skip_bits(43)?; 2517 } 2518 2519 if ptl.sub_layer_profile_idc[i] == 1 2520 || ptl.sub_layer_profile_compatibility_flag[i][1] 2521 || ptl.sub_layer_profile_idc[i] == 2 2522 || ptl.sub_layer_profile_compatibility_flag[i][2] 2523 || ptl.sub_layer_profile_idc[i] == 3 2524 || ptl.sub_layer_profile_compatibility_flag[i][3] 2525 || ptl.sub_layer_profile_idc[i] == 4 2526 || ptl.sub_layer_profile_compatibility_flag[i][4] 2527 || ptl.sub_layer_profile_idc[i] == 5 2528 || ptl.sub_layer_profile_compatibility_flag[i][5] 2529 || ptl.sub_layer_profile_idc[i] == 9 2530 || ptl.sub_layer_profile_compatibility_flag[i][9] 2531 || ptl.sub_layer_profile_idc[i] == 11 2532 || ptl.sub_layer_profile_compatibility_flag[i][11] 2533 { 2534 ptl.sub_layer_inbld_flag[i] = r.read_bit()?; 2535 } else { 2536 r.skip_bits(1)?; 2537 } 2538 2539 if ptl.sub_layer_level_present_flag[i] { 2540 let level: u8 = r.read_bits(8)?; 2541 ptl.sub_layer_level_idc[i] = Level::try_from(level)?; 2542 } 2543 } 2544 } 2545 Ok(()) 2546 } 2547 fill_default_scaling_list(sl: &mut ScalingLists, size_id: i32, matrix_id: i32)2548 fn fill_default_scaling_list(sl: &mut ScalingLists, size_id: i32, matrix_id: i32) { 2549 if size_id == 0 { 2550 sl.scaling_list_4x4[matrix_id as usize] = DEFAULT_SCALING_LIST_0; 2551 return; 2552 } 2553 2554 let dst = match size_id { 2555 1 => &mut sl.scaling_list_8x8[matrix_id as usize], 2556 2 => &mut sl.scaling_list_16x16[matrix_id as usize], 2557 3 => &mut sl.scaling_list_32x32[matrix_id as usize], 2558 _ => panic!("Invalid size_id {}", size_id), 2559 }; 2560 2561 let src = if matrix_id < 3 { 2562 &DEFAULT_SCALING_LIST_1 2563 } else if matrix_id <= 5 { 2564 &DEFAULT_SCALING_LIST_2 2565 } else { 2566 panic!("Invalid matrix_id {}", matrix_id); 2567 }; 2568 2569 *dst = *src; 2570 2571 // When `scaling_list_pred_mode_flag[ sizeId ]`[ matrixId ] is equal to 2572 // 0, scaling_list_pred_matrix_id_ `delta[ sizeId ]`[ matrixId ] is equal 2573 // to 0 and sizeId is greater than 1, the value of 2574 // scaling_list_dc_coef_minus8[ sizeId − 2 `][ matrixId ]` is inferred to 2575 // be equal to 8. 2576 // 2577 // Since we are using a slightly different layout here, with two 2578 // different field names (i.e. 16x16, and 32x32), we must differentiate 2579 // between size_id == 2 or size_id == 3. 2580 if size_id == 2 { 2581 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] = 8; 2582 } else if size_id == 3 { 2583 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] = 8; 2584 } 2585 } 2586 parse_scaling_list_data(sl: &mut ScalingLists, r: &mut BitReader) -> Result<(), String>2587 fn parse_scaling_list_data(sl: &mut ScalingLists, r: &mut BitReader) -> Result<(), String> { 2588 // 7.4.5 2589 for size_id in 0..4 { 2590 let mut matrix_id = 0; 2591 while matrix_id < 6 { 2592 let scaling_list_pred_mode_flag = r.read_bit()?; 2593 // If `scaling_list_pred_matrix_id_delta[ sizeId ]`[ matrixId ] is 2594 // equal to 0, the scaling list is inferred from the default 2595 // scaling list `ScalingList[ sizeId ]`[ matrixId `][ i ]` as specified 2596 // in Table 7-5 and Table 7-6 for i = 0..Min( 63, ( 1 << ( 4 + ( 2597 // sizeId << 1 ) ) ) − 1 ). 2598 if !scaling_list_pred_mode_flag { 2599 let scaling_list_pred_matrix_id_delta: u32 = r.read_ue()?; 2600 if scaling_list_pred_matrix_id_delta == 0 { 2601 Self::fill_default_scaling_list(sl, size_id, matrix_id); 2602 } else { 2603 // Equation 7-42 2604 let factor = if size_id == 3 { 3 } else { 1 }; 2605 let ref_matrix_id = 2606 matrix_id as u32 - scaling_list_pred_matrix_id_delta * factor; 2607 if size_id == 0 { 2608 sl.scaling_list_4x4[matrix_id as usize] = 2609 sl.scaling_list_4x4[ref_matrix_id as usize]; 2610 } else { 2611 let src = match size_id { 2612 1 => sl.scaling_list_8x8[ref_matrix_id as usize], 2613 2 => sl.scaling_list_16x16[ref_matrix_id as usize], 2614 3 => sl.scaling_list_32x32[ref_matrix_id as usize], 2615 _ => return Err(format!("Invalid size_id {}", size_id)), 2616 }; 2617 2618 let dst = match size_id { 2619 1 => &mut sl.scaling_list_8x8[matrix_id as usize], 2620 2 => &mut sl.scaling_list_16x16[matrix_id as usize], 2621 3 => &mut sl.scaling_list_32x32[matrix_id as usize], 2622 _ => return Err(format!("Invalid size_id {}", size_id)), 2623 }; 2624 2625 *dst = src; 2626 2627 if size_id == 2 { 2628 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] = 2629 sl.scaling_list_dc_coef_minus8_16x16[ref_matrix_id as usize]; 2630 } else if size_id == 3 { 2631 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] = 2632 sl.scaling_list_dc_coef_minus8_32x32[ref_matrix_id as usize]; 2633 } 2634 } 2635 } 2636 } else { 2637 let mut next_coef = 8i32; 2638 let coef_num = std::cmp::min(64, 1 << (4 + (size_id << 1))); 2639 2640 if size_id > 1 { 2641 if size_id == 2 { 2642 sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize] = 2643 r.read_se_bounded(-7, 247)?; 2644 next_coef = 2645 i32::from(sl.scaling_list_dc_coef_minus8_16x16[matrix_id as usize]) 2646 + 8; 2647 } else if size_id == 3 { 2648 sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize] = 2649 r.read_se_bounded(-7, 247)?; 2650 next_coef = 2651 i32::from(sl.scaling_list_dc_coef_minus8_32x32[matrix_id as usize]) 2652 + 8; 2653 } 2654 } 2655 2656 for i in 0..coef_num as usize { 2657 let scaling_list_delta_coef: i32 = r.read_se_bounded(-128, 127)?; 2658 next_coef = (next_coef + scaling_list_delta_coef + 256) % 256; 2659 match size_id { 2660 0 => sl.scaling_list_4x4[matrix_id as usize][i] = next_coef as _, 2661 1 => sl.scaling_list_8x8[matrix_id as usize][i] = next_coef as _, 2662 2 => sl.scaling_list_16x16[matrix_id as usize][i] = next_coef as _, 2663 3 => sl.scaling_list_32x32[matrix_id as usize][i] = next_coef as _, 2664 _ => return Err(format!("Invalid size_id {}", size_id)), 2665 } 2666 } 2667 } 2668 let step = if size_id == 3 { 3 } else { 1 }; 2669 matrix_id += step; 2670 } 2671 } 2672 Ok(()) 2673 } 2674 parse_short_term_ref_pic_set( sps: &Sps, st: &mut ShortTermRefPicSet, r: &mut BitReader, st_rps_idx: u8, ) -> Result<(), String>2675 fn parse_short_term_ref_pic_set( 2676 sps: &Sps, 2677 st: &mut ShortTermRefPicSet, 2678 r: &mut BitReader, 2679 st_rps_idx: u8, 2680 ) -> Result<(), String> { 2681 if st_rps_idx != 0 { 2682 st.inter_ref_pic_set_prediction_flag = r.read_bit()?; 2683 } 2684 2685 // (7-59) 2686 if st.inter_ref_pic_set_prediction_flag { 2687 if st_rps_idx == sps.num_short_term_ref_pic_sets { 2688 st.delta_idx_minus1 = r.read_ue_max(st_rps_idx as u32 - 1)?; 2689 } 2690 2691 st.delta_rps_sign = r.read_bit()?; 2692 // The value of abs_delta_rps_minus1 shall be in the range of 0 to 2693 // 2^15 − 1, inclusive. 2694 st.abs_delta_rps_minus1 = r.read_ue_max(32767)?; 2695 2696 let ref_rps_idx = st_rps_idx - (st.delta_idx_minus1 + 1); 2697 let delta_rps = 2698 (1 - 2 * st.delta_rps_sign as i32) * (st.abs_delta_rps_minus1 as i32 + 1); 2699 2700 let ref_st = sps 2701 .short_term_ref_pic_set 2702 .get(usize::from(ref_rps_idx)) 2703 .ok_or::<String>("Invalid ref_rps_idx".into())?; 2704 2705 let mut used_by_curr_pic_flag = [false; 64]; 2706 2707 // 7.4.8 - defaults to 1 if not present 2708 let mut use_delta_flag = [true; 64]; 2709 2710 for j in 0..=ref_st.num_delta_pocs as usize { 2711 used_by_curr_pic_flag[j] = r.read_bit()?; 2712 if !used_by_curr_pic_flag[j] { 2713 use_delta_flag[j] = r.read_bit()?; 2714 } 2715 } 2716 2717 // (7-61) 2718 let mut i = 0; 2719 // Ranges are [a,b[, but the real loop is [b, a], i.e. 2720 // [num_positive_pics - 1, 0]. Use ..= so that b is included when 2721 // rev() is called. 2722 for j in (0..=isize::from(ref_st.num_positive_pics) - 1) 2723 .rev() 2724 .take_while(|j| *j >= 0) 2725 .map(|j| j as usize) 2726 { 2727 let d_poc = ref_st.delta_poc_s1[j] + delta_rps; 2728 if d_poc < 0 && use_delta_flag[usize::from(ref_st.num_negative_pics) + j] { 2729 st.delta_poc_s0[i] = d_poc; 2730 st.used_by_curr_pic_s0[i] = 2731 used_by_curr_pic_flag[usize::from(ref_st.num_negative_pics) + j]; 2732 2733 i += 1; 2734 } 2735 } 2736 2737 if delta_rps < 0 && use_delta_flag[ref_st.num_delta_pocs as usize] { 2738 st.delta_poc_s0[i] = delta_rps; 2739 st.used_by_curr_pic_s0[i] = used_by_curr_pic_flag[ref_st.num_delta_pocs as usize]; 2740 2741 i += 1; 2742 } 2743 2744 // Let's *not* change the original algorithm in any way. 2745 #[allow(clippy::needless_range_loop)] 2746 for j in 0..ref_st.num_negative_pics as usize { 2747 let d_poc = ref_st.delta_poc_s0[j] + delta_rps; 2748 if d_poc < 0 && use_delta_flag[j] { 2749 st.delta_poc_s0[i] = d_poc; 2750 st.used_by_curr_pic_s0[i] = used_by_curr_pic_flag[j]; 2751 2752 i += 1; 2753 } 2754 } 2755 2756 st.num_negative_pics = i as u8; 2757 2758 // (7-62) 2759 let mut i = 0; 2760 // Ranges are [a,b[, but the real loop is [b, a], i.e. 2761 // [num_negative_pics - 1, 0]. Use ..= so that b is included when 2762 // rev() is called. 2763 for j in (0..=isize::from(ref_st.num_negative_pics) - 1) 2764 .rev() 2765 .take_while(|j| *j >= 0) 2766 .map(|j| j as usize) 2767 { 2768 let d_poc = ref_st.delta_poc_s0[j] + delta_rps; 2769 if d_poc > 0 && use_delta_flag[j] { 2770 st.delta_poc_s1[i] = d_poc; 2771 st.used_by_curr_pic_s1[i] = used_by_curr_pic_flag[j]; 2772 2773 i += 1; 2774 } 2775 } 2776 2777 if delta_rps > 0 && use_delta_flag[ref_st.num_delta_pocs as usize] { 2778 st.delta_poc_s1[i] = delta_rps; 2779 st.used_by_curr_pic_s1[i] = used_by_curr_pic_flag[ref_st.num_delta_pocs as usize]; 2780 2781 i += 1; 2782 } 2783 2784 for j in 0..usize::from(ref_st.num_positive_pics) { 2785 let d_poc = ref_st.delta_poc_s1[j] + delta_rps; 2786 if d_poc > 0 && use_delta_flag[ref_st.num_negative_pics as usize + j] { 2787 st.delta_poc_s1[i] = d_poc; 2788 st.used_by_curr_pic_s1[i] = 2789 used_by_curr_pic_flag[ref_st.num_negative_pics as usize + j]; 2790 2791 i += 1; 2792 } 2793 } 2794 2795 st.num_positive_pics = i as u8; 2796 } else { 2797 st.num_negative_pics = r.read_ue_max(u32::from( 2798 sps.max_dec_pic_buffering_minus1[usize::from(sps.max_sub_layers_minus1)], 2799 ))?; 2800 2801 st.num_positive_pics = r.read_ue_max(u32::from( 2802 sps.max_dec_pic_buffering_minus1[usize::from(sps.max_sub_layers_minus1)] 2803 - st.num_negative_pics, 2804 ))?; 2805 2806 for i in 0..usize::from(st.num_negative_pics) { 2807 let delta_poc_s0_minus1: u32 = r.read_ue_max(32767)?; 2808 2809 if i == 0 { 2810 st.delta_poc_s0[i] = -(delta_poc_s0_minus1 as i32 + 1); 2811 } else { 2812 st.delta_poc_s0[i] = st.delta_poc_s0[i - 1] - (delta_poc_s0_minus1 as i32 + 1); 2813 } 2814 2815 st.used_by_curr_pic_s0[i] = r.read_bit()?; 2816 } 2817 2818 for i in 0..usize::from(st.num_positive_pics) { 2819 let delta_poc_s1_minus1: u32 = r.read_ue_max(32767)?; 2820 2821 if i == 0 { 2822 st.delta_poc_s1[i] = delta_poc_s1_minus1 as i32 + 1; 2823 } else { 2824 st.delta_poc_s1[i] = st.delta_poc_s1[i - 1] + (delta_poc_s1_minus1 as i32 + 1); 2825 } 2826 2827 st.used_by_curr_pic_s1[i] = r.read_bit()?; 2828 } 2829 } 2830 2831 st.num_delta_pocs = u32::from(st.num_negative_pics + st.num_positive_pics); 2832 2833 Ok(()) 2834 } 2835 parse_sublayer_hrd_parameters( h: &mut SublayerHrdParameters, cpb_cnt: u32, sub_pic_hrd_params_present_flag: bool, r: &mut BitReader, ) -> Result<(), String>2836 fn parse_sublayer_hrd_parameters( 2837 h: &mut SublayerHrdParameters, 2838 cpb_cnt: u32, 2839 sub_pic_hrd_params_present_flag: bool, 2840 r: &mut BitReader, 2841 ) -> Result<(), String> { 2842 for i in 0..cpb_cnt as usize { 2843 h.bit_rate_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?; 2844 h.cpb_size_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?; 2845 if sub_pic_hrd_params_present_flag { 2846 h.cpb_size_du_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?; 2847 h.bit_rate_du_value_minus1[i] = r.read_ue_max((2u64.pow(32) - 2) as u32)?; 2848 } 2849 2850 h.cbr_flag[i] = r.read_bit()?; 2851 } 2852 2853 Ok(()) 2854 } 2855 parse_hrd_parameters( common_inf_present_flag: bool, max_num_sublayers_minus1: u8, hrd: &mut HrdParams, r: &mut BitReader, ) -> Result<(), String>2856 fn parse_hrd_parameters( 2857 common_inf_present_flag: bool, 2858 max_num_sublayers_minus1: u8, 2859 hrd: &mut HrdParams, 2860 r: &mut BitReader, 2861 ) -> Result<(), String> { 2862 if common_inf_present_flag { 2863 hrd.nal_hrd_parameters_present_flag = r.read_bit()?; 2864 hrd.vcl_hrd_parameters_present_flag = r.read_bit()?; 2865 if hrd.nal_hrd_parameters_present_flag || hrd.vcl_hrd_parameters_present_flag { 2866 hrd.sub_pic_hrd_params_present_flag = r.read_bit()?; 2867 if hrd.sub_pic_hrd_params_present_flag { 2868 hrd.tick_divisor_minus2 = r.read_bits(8)?; 2869 hrd.du_cpb_removal_delay_increment_length_minus1 = r.read_bits(5)?; 2870 hrd.sub_pic_cpb_params_in_pic_timing_sei_flag = r.read_bit()?; 2871 hrd.dpb_output_delay_du_length_minus1 = r.read_bits(5)?; 2872 } 2873 hrd.bit_rate_scale = r.read_bits(4)?; 2874 hrd.cpb_size_scale = r.read_bits(4)?; 2875 if hrd.sub_pic_hrd_params_present_flag { 2876 hrd.cpb_size_du_scale = r.read_bits(4)?; 2877 } 2878 hrd.initial_cpb_removal_delay_length_minus1 = r.read_bits(5)?; 2879 hrd.au_cpb_removal_delay_length_minus1 = r.read_bits(5)?; 2880 hrd.dpb_output_delay_length_minus1 = r.read_bits(5)?; 2881 } 2882 } 2883 2884 for i in 0..=max_num_sublayers_minus1 as usize { 2885 hrd.fixed_pic_rate_general_flag[i] = r.read_bit()?; 2886 if !hrd.fixed_pic_rate_general_flag[i] { 2887 hrd.fixed_pic_rate_within_cvs_flag[i] = r.read_bit()?; 2888 } 2889 if hrd.fixed_pic_rate_within_cvs_flag[i] { 2890 hrd.elemental_duration_in_tc_minus1[i] = r.read_ue_max(2047)?; 2891 } else { 2892 hrd.low_delay_hrd_flag[i] = r.read_bit()?; 2893 } 2894 2895 if !hrd.low_delay_hrd_flag[i] { 2896 hrd.cpb_cnt_minus1[i] = r.read_ue_max(31)?; 2897 } 2898 2899 if hrd.nal_hrd_parameters_present_flag { 2900 Self::parse_sublayer_hrd_parameters( 2901 &mut hrd.nal_hrd[i], 2902 hrd.cpb_cnt_minus1[i] + 1, 2903 hrd.sub_pic_hrd_params_present_flag, 2904 r, 2905 )?; 2906 } 2907 2908 if hrd.vcl_hrd_parameters_present_flag { 2909 Self::parse_sublayer_hrd_parameters( 2910 &mut hrd.vcl_hrd[i], 2911 hrd.cpb_cnt_minus1[i] + 1, 2912 hrd.sub_pic_hrd_params_present_flag, 2913 r, 2914 )?; 2915 } 2916 } 2917 2918 Ok(()) 2919 } 2920 parse_vui_parameters(sps: &mut Sps, r: &mut BitReader) -> Result<(), String>2921 fn parse_vui_parameters(sps: &mut Sps, r: &mut BitReader) -> Result<(), String> { 2922 let vui = &mut sps.vui_parameters; 2923 2924 vui.aspect_ratio_info_present_flag = r.read_bit()?; 2925 if vui.aspect_ratio_info_present_flag { 2926 vui.aspect_ratio_idc = r.read_bits(8)?; 2927 const EXTENDED_SAR: u32 = 255; 2928 if vui.aspect_ratio_idc == EXTENDED_SAR { 2929 vui.sar_width = r.read_bits(16)?; 2930 vui.sar_height = r.read_bits(16)?; 2931 } 2932 } 2933 2934 vui.overscan_info_present_flag = r.read_bit()?; 2935 if vui.overscan_info_present_flag { 2936 vui.overscan_appropriate_flag = r.read_bit()?; 2937 } 2938 2939 vui.video_signal_type_present_flag = r.read_bit()?; 2940 if vui.video_signal_type_present_flag { 2941 vui.video_format = r.read_bits(3)?; 2942 vui.video_full_range_flag = r.read_bit()?; 2943 vui.colour_description_present_flag = r.read_bit()?; 2944 if vui.colour_description_present_flag { 2945 vui.colour_primaries = r.read_bits(8)?; 2946 vui.transfer_characteristics = r.read_bits(8)?; 2947 vui.matrix_coeffs = r.read_bits(8)?; 2948 } 2949 } 2950 2951 vui.chroma_loc_info_present_flag = r.read_bit()?; 2952 if vui.chroma_loc_info_present_flag { 2953 vui.chroma_sample_loc_type_top_field = r.read_ue_max(5)?; 2954 vui.chroma_sample_loc_type_bottom_field = r.read_ue_max(5)?; 2955 } 2956 2957 vui.neutral_chroma_indication_flag = r.read_bit()?; 2958 vui.field_seq_flag = r.read_bit()?; 2959 vui.frame_field_info_present_flag = r.read_bit()?; 2960 vui.default_display_window_flag = r.read_bit()?; 2961 2962 if vui.default_display_window_flag { 2963 vui.def_disp_win_left_offset = r.read_ue()?; 2964 vui.def_disp_win_right_offset = r.read_ue()?; 2965 vui.def_disp_win_top_offset = r.read_ue()?; 2966 vui.def_disp_win_bottom_offset = r.read_ue()?; 2967 } 2968 2969 vui.timing_info_present_flag = r.read_bit()?; 2970 if vui.timing_info_present_flag { 2971 vui.num_units_in_tick = r.read_bits::<u32>(31)? << 1; 2972 vui.num_units_in_tick |= r.read_bits::<u32>(1)?; 2973 2974 if vui.num_units_in_tick == 0 { 2975 log::warn!("Incompliant value for num_units_in_tick {}", vui.num_units_in_tick); 2976 } 2977 2978 vui.time_scale = r.read_bits::<u32>(31)? << 1; 2979 vui.time_scale |= r.read_bits::<u32>(1)?; 2980 2981 if vui.time_scale == 0 { 2982 log::warn!("Incompliant value for time_scale {}", vui.time_scale); 2983 } 2984 2985 vui.poc_proportional_to_timing_flag = r.read_bit()?; 2986 if vui.poc_proportional_to_timing_flag { 2987 vui.num_ticks_poc_diff_one_minus1 = r.read_ue_max((2u64.pow(32) - 2) as u32)?; 2988 } 2989 2990 vui.hrd_parameters_present_flag = r.read_bit()?; 2991 if vui.hrd_parameters_present_flag { 2992 let sps_max_sub_layers_minus1 = sps.max_sub_layers_minus1; 2993 Self::parse_hrd_parameters(true, sps_max_sub_layers_minus1, &mut vui.hrd, r)?; 2994 } 2995 } 2996 2997 vui.bitstream_restriction_flag = r.read_bit()?; 2998 if vui.bitstream_restriction_flag { 2999 vui.tiles_fixed_structure_flag = r.read_bit()?; 3000 vui.motion_vectors_over_pic_boundaries_flag = r.read_bit()?; 3001 vui.restricted_ref_pic_lists_flag = r.read_bit()?; 3002 3003 vui.min_spatial_segmentation_idc = r.read_ue_max(4095)?; 3004 vui.max_bytes_per_pic_denom = r.read_ue()?; 3005 vui.max_bits_per_min_cu_denom = r.read_ue()?; 3006 vui.log2_max_mv_length_horizontal = r.read_ue_max(16)?; 3007 vui.log2_max_mv_length_vertical = r.read_ue_max(15)?; 3008 } 3009 3010 Ok(()) 3011 } 3012 parse_sps_scc_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String>3013 fn parse_sps_scc_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String> { 3014 let scc = &mut sps.scc_extension; 3015 3016 scc.curr_pic_ref_enabled_flag = r.read_bit()?; 3017 scc.palette_mode_enabled_flag = r.read_bit()?; 3018 if scc.palette_mode_enabled_flag { 3019 scc.palette_max_size = r.read_ue_max(64)?; 3020 scc.delta_palette_max_predictor_size = 3021 r.read_ue_max(128 - u32::from(scc.palette_max_size))?; 3022 scc.palette_predictor_initializers_present_flag = r.read_bit()?; 3023 if scc.palette_predictor_initializers_present_flag { 3024 let max = 3025 u32::from(scc.palette_max_size + scc.delta_palette_max_predictor_size - 1); 3026 scc.num_palette_predictor_initializer_minus1 = r.read_ue_max(max)?; 3027 3028 let num_comps = if sps.chroma_format_idc == 0 { 1 } else { 3 }; 3029 for comp in 0..num_comps { 3030 for i in 0..=usize::from(scc.num_palette_predictor_initializer_minus1) { 3031 let num_bits = if comp == 0 { 3032 sps.bit_depth_luma_minus8 + 8 3033 } else { 3034 sps.bit_depth_chroma_minus8 + 8 3035 }; 3036 scc.palette_predictor_initializer[comp][i] = 3037 r.read_bits(usize::from(num_bits))?; 3038 } 3039 } 3040 } 3041 } 3042 3043 scc.motion_vector_resolution_control_idc = r.read_bits(2)?; 3044 scc.intra_boundary_filtering_disabled_flag = r.read_bit()?; 3045 3046 Ok(()) 3047 } 3048 parse_sps_range_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String>3049 fn parse_sps_range_extension(sps: &mut Sps, r: &mut BitReader) -> Result<(), String> { 3050 let ext = &mut sps.range_extension; 3051 3052 ext.transform_skip_rotation_enabled_flag = r.read_bit()?; 3053 ext.transform_skip_context_enabled_flag = r.read_bit()?; 3054 ext.implicit_rdpcm_enabled_flag = r.read_bit()?; 3055 ext.explicit_rdpcm_enabled_flag = r.read_bit()?; 3056 ext.extended_precision_processing_flag = r.read_bit()?; 3057 ext.intra_smoothing_disabled_flag = r.read_bit()?; 3058 ext.high_precision_offsets_enabled_flag = r.read_bit()?; 3059 ext.persistent_rice_adaptation_enabled_flag = r.read_bit()?; 3060 ext.cabac_bypass_alignment_enabled_flag = r.read_bit()?; 3061 3062 Ok(()) 3063 } 3064 3065 /// Parse a SPS NALU. parse_sps(&mut self, nalu: &Nalu) -> Result<&Sps, String>3066 pub fn parse_sps(&mut self, nalu: &Nalu) -> Result<&Sps, String> { 3067 if !matches!(nalu.header.type_, NaluType::SpsNut) { 3068 return Err(format!( 3069 "Invalid NALU type, expected {:?}, got {:?}", 3070 NaluType::SpsNut, 3071 nalu.header.type_ 3072 )); 3073 } 3074 3075 let data = nalu.as_ref(); 3076 let header = &nalu.header; 3077 let hdr_len = header.len(); 3078 // Skip the header 3079 let mut r = BitReader::new(&data[hdr_len..], true); 3080 3081 let video_parameter_set_id = r.read_bits(4)?; 3082 3083 // A non-existing VPS means the SPS is not using any VPS. 3084 let vps = self.get_vps(video_parameter_set_id).cloned(); 3085 3086 let mut sps = Sps { 3087 video_parameter_set_id, 3088 max_sub_layers_minus1: r.read_bits(3)?, 3089 temporal_id_nesting_flag: r.read_bit()?, 3090 vps, 3091 ..Default::default() 3092 }; 3093 3094 Self::parse_profile_tier_level( 3095 &mut sps.profile_tier_level, 3096 &mut r, 3097 true, 3098 sps.max_sub_layers_minus1, 3099 )?; 3100 3101 sps.seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?; 3102 sps.chroma_format_idc = r.read_ue_max(3)?; 3103 3104 if sps.chroma_format_idc == 3 { 3105 sps.separate_colour_plane_flag = r.read_bit()?; 3106 } 3107 3108 sps.chroma_array_type = 3109 if sps.separate_colour_plane_flag { 0 } else { sps.chroma_format_idc }; 3110 3111 sps.pic_width_in_luma_samples = r.read_ue_bounded(1, 16888)?; 3112 sps.pic_height_in_luma_samples = r.read_ue_bounded(1, 16888)?; 3113 3114 sps.conformance_window_flag = r.read_bit()?; 3115 if sps.conformance_window_flag { 3116 sps.conf_win_left_offset = r.read_ue()?; 3117 sps.conf_win_right_offset = r.read_ue()?; 3118 sps.conf_win_top_offset = r.read_ue()?; 3119 sps.conf_win_bottom_offset = r.read_ue()?; 3120 } 3121 3122 sps.bit_depth_luma_minus8 = r.read_ue_max(6)?; 3123 sps.bit_depth_chroma_minus8 = r.read_ue_max(6)?; 3124 sps.log2_max_pic_order_cnt_lsb_minus4 = r.read_ue_max(12)?; 3125 sps.sub_layer_ordering_info_present_flag = r.read_bit()?; 3126 3127 { 3128 let i = if sps.sub_layer_ordering_info_present_flag { 3129 0 3130 } else { 3131 sps.max_sub_layers_minus1 3132 }; 3133 3134 for j in i..=sps.max_sub_layers_minus1 { 3135 sps.max_dec_pic_buffering_minus1[j as usize] = r.read_ue_max(16)?; 3136 sps.max_num_reorder_pics[j as usize] = 3137 r.read_ue_max(sps.max_dec_pic_buffering_minus1[j as usize] as _)?; 3138 sps.max_latency_increase_plus1[j as usize] = r.read_ue_max(u32::MAX - 1)?; 3139 } 3140 } 3141 3142 sps.log2_min_luma_coding_block_size_minus3 = r.read_ue_max(3)?; 3143 sps.log2_diff_max_min_luma_coding_block_size = r.read_ue_max(6)?; 3144 sps.log2_min_luma_transform_block_size_minus2 = r.read_ue_max(3)?; 3145 sps.log2_diff_max_min_luma_transform_block_size = r.read_ue_max(3)?; 3146 3147 // (7-10) 3148 sps.min_cb_log2_size_y = u32::from(sps.log2_min_luma_coding_block_size_minus3 + 3); 3149 // (7-11) 3150 sps.ctb_log2_size_y = 3151 sps.min_cb_log2_size_y + u32::from(sps.log2_diff_max_min_luma_coding_block_size); 3152 // (7-12) 3153 sps.ctb_size_y = 1 << sps.ctb_log2_size_y; 3154 // (7-17) 3155 sps.pic_height_in_ctbs_y = 3156 (sps.pic_height_in_luma_samples as f64 / sps.ctb_size_y as f64).ceil() as u32; 3157 // (7-15) 3158 sps.pic_width_in_ctbs_y = 3159 (sps.pic_width_in_luma_samples as f64 / sps.ctb_size_y as f64).ceil() as u32; 3160 3161 sps.max_tb_log2_size_y = u32::from( 3162 sps.log2_min_luma_transform_block_size_minus2 3163 + 2 3164 + sps.log2_diff_max_min_luma_transform_block_size, 3165 ); 3166 3167 sps.pic_size_in_samples_y = 3168 u32::from(sps.pic_width_in_luma_samples) * u32::from(sps.pic_height_in_luma_samples); 3169 3170 if sps.max_tb_log2_size_y > std::cmp::min(sps.ctb_log2_size_y, 5) { 3171 return Err(format!("Invalid value for MaxTbLog2SizeY: {}", sps.max_tb_log2_size_y)); 3172 } 3173 3174 sps.pic_size_in_ctbs_y = sps.pic_width_in_ctbs_y * sps.pic_height_in_ctbs_y; 3175 3176 sps.max_transform_hierarchy_depth_inter = r.read_ue_max(4)?; 3177 sps.max_transform_hierarchy_depth_intra = r.read_ue_max(4)?; 3178 3179 sps.scaling_list_enabled_flag = r.read_bit()?; 3180 if sps.scaling_list_enabled_flag { 3181 sps.scaling_list_data_present_flag = r.read_bit()?; 3182 if sps.scaling_list_data_present_flag { 3183 Self::parse_scaling_list_data(&mut sps.scaling_list, &mut r)?; 3184 } 3185 } 3186 3187 sps.amp_enabled_flag = r.read_bit()?; 3188 sps.sample_adaptive_offset_enabled_flag = r.read_bit()?; 3189 3190 sps.pcm_enabled_flag = r.read_bit()?; 3191 if sps.pcm_enabled_flag { 3192 sps.pcm_sample_bit_depth_luma_minus1 = r.read_bits(4)?; 3193 sps.pcm_sample_bit_depth_chroma_minus1 = r.read_bits(4)?; 3194 sps.log2_min_pcm_luma_coding_block_size_minus3 = r.read_ue_max(2)?; 3195 sps.log2_diff_max_min_pcm_luma_coding_block_size = r.read_ue_max(2)?; 3196 sps.pcm_loop_filter_disabled_flag = r.read_bit()?; 3197 } 3198 3199 sps.num_short_term_ref_pic_sets = r.read_ue_max(64)?; 3200 3201 for i in 0..sps.num_short_term_ref_pic_sets { 3202 let mut st = ShortTermRefPicSet::default(); 3203 Self::parse_short_term_ref_pic_set(&sps, &mut st, &mut r, i)?; 3204 sps.short_term_ref_pic_set.push(st); 3205 } 3206 3207 sps.long_term_ref_pics_present_flag = r.read_bit()?; 3208 if sps.long_term_ref_pics_present_flag { 3209 sps.num_long_term_ref_pics_sps = r.read_ue_max(32)?; 3210 for i in 0..usize::from(sps.num_long_term_ref_pics_sps) { 3211 sps.lt_ref_pic_poc_lsb_sps[i] = 3212 r.read_bits(usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4)?; 3213 sps.used_by_curr_pic_lt_sps_flag[i] = r.read_bit()?; 3214 } 3215 } 3216 3217 sps.temporal_mvp_enabled_flag = r.read_bit()?; 3218 sps.strong_intra_smoothing_enabled_flag = r.read_bit()?; 3219 3220 sps.vui_parameters_present_flag = r.read_bit()?; 3221 if sps.vui_parameters_present_flag { 3222 Self::parse_vui_parameters(&mut sps, &mut r)?; 3223 } 3224 3225 sps.extension_present_flag = r.read_bit()?; 3226 if sps.extension_present_flag { 3227 sps.range_extension_flag = r.read_bit()?; 3228 if sps.range_extension_flag { 3229 Self::parse_sps_range_extension(&mut sps, &mut r)?; 3230 } 3231 3232 let multilayer_extension_flag = r.read_bit()?; 3233 if multilayer_extension_flag { 3234 return Err("Multilayer extension not supported.".into()); 3235 } 3236 3237 let three_d_extension_flag = r.read_bit()?; 3238 if three_d_extension_flag { 3239 return Err("3D extension not supported.".into()); 3240 } 3241 3242 sps.scc_extension_flag = r.read_bit()?; 3243 if sps.scc_extension_flag { 3244 Self::parse_sps_scc_extension(&mut sps, &mut r)?; 3245 } 3246 } 3247 3248 let shift = if sps.range_extension.high_precision_offsets_enabled_flag { 3249 sps.bit_depth_luma_minus8 + 7 3250 } else { 3251 7 3252 }; 3253 3254 sps.wp_offset_half_range_y = 1 << shift; 3255 3256 let shift = if sps.range_extension.high_precision_offsets_enabled_flag { 3257 sps.bit_depth_chroma_minus8 + 7 3258 } else { 3259 7 3260 }; 3261 3262 sps.wp_offset_half_range_c = 1 << shift; 3263 3264 log::debug!( 3265 "Parsed SPS({}), resolution: ({}, {}): NAL size was {}", 3266 sps.seq_parameter_set_id, 3267 sps.width(), 3268 sps.height(), 3269 nalu.size 3270 ); 3271 3272 if self.active_spses.keys().len() >= MAX_SPS_COUNT { 3273 return Err("Broken data: Number of active SPSs > MAX_SPS_COUNT".into()); 3274 } 3275 3276 let key = sps.seq_parameter_set_id; 3277 let sps = Rc::new(sps); 3278 self.active_spses.remove(&key); 3279 Ok(self.active_spses.entry(key).or_insert(sps)) 3280 } 3281 parse_pps_scc_extension(pps: &mut Pps, sps: &Sps, r: &mut BitReader) -> Result<(), String>3282 fn parse_pps_scc_extension(pps: &mut Pps, sps: &Sps, r: &mut BitReader) -> Result<(), String> { 3283 let scc = &mut pps.scc_extension; 3284 scc.curr_pic_ref_enabled_flag = r.read_bit()?; 3285 scc.residual_adaptive_colour_transform_enabled_flag = r.read_bit()?; 3286 if scc.residual_adaptive_colour_transform_enabled_flag { 3287 scc.slice_act_qp_offsets_present_flag = r.read_bit()?; 3288 scc.act_y_qp_offset_plus5 = r.read_se_bounded(-7, 17)?; 3289 scc.act_cb_qp_offset_plus5 = r.read_se_bounded(-7, 17)?; 3290 scc.act_cr_qp_offset_plus3 = r.read_se_bounded(-9, 15)?; 3291 } 3292 3293 scc.palette_predictor_initializers_present_flag = r.read_bit()?; 3294 if scc.palette_predictor_initializers_present_flag { 3295 let max = sps.scc_extension.palette_max_size 3296 + sps.scc_extension.delta_palette_max_predictor_size; 3297 scc.num_palette_predictor_initializers = r.read_ue_max(max.into())?; 3298 if scc.num_palette_predictor_initializers > 0 { 3299 scc.monochrome_palette_flag = r.read_bit()?; 3300 scc.luma_bit_depth_entry_minus8 = r.read_ue_bounded( 3301 sps.bit_depth_luma_minus8.into(), 3302 sps.bit_depth_luma_minus8.into(), 3303 )?; 3304 if !scc.monochrome_palette_flag { 3305 scc.chroma_bit_depth_entry_minus8 = r.read_ue_bounded( 3306 sps.bit_depth_chroma_minus8.into(), 3307 sps.bit_depth_chroma_minus8.into(), 3308 )?; 3309 } 3310 3311 let num_comps = if scc.monochrome_palette_flag { 1 } else { 3 }; 3312 for comp in 0..num_comps { 3313 let num_bits = if comp == 0 { 3314 scc.luma_bit_depth_entry_minus8 + 8 3315 } else { 3316 scc.chroma_bit_depth_entry_minus8 + 8 3317 }; 3318 for i in 0..usize::from(scc.num_palette_predictor_initializers) { 3319 scc.palette_predictor_initializer[comp][i] = 3320 r.read_bits(num_bits.into())?; 3321 } 3322 } 3323 } 3324 } 3325 Ok(()) 3326 } 3327 parse_pps_range_extension( pps: &mut Pps, sps: &Sps, r: &mut BitReader, ) -> Result<(), String>3328 fn parse_pps_range_extension( 3329 pps: &mut Pps, 3330 sps: &Sps, 3331 r: &mut BitReader, 3332 ) -> Result<(), String> { 3333 let rext = &mut pps.range_extension; 3334 3335 if pps.transform_skip_enabled_flag { 3336 rext.log2_max_transform_skip_block_size_minus2 = 3337 r.read_ue_max(sps.max_tb_log2_size_y - 2)?; 3338 } 3339 3340 rext.cross_component_prediction_enabled_flag = r.read_bit()?; 3341 rext.chroma_qp_offset_list_enabled_flag = r.read_bit()?; 3342 if rext.chroma_qp_offset_list_enabled_flag { 3343 rext.diff_cu_chroma_qp_offset_depth = r.read_ue()?; 3344 rext.chroma_qp_offset_list_len_minus1 = r.read_ue_max(5)?; 3345 for i in 0..=rext.chroma_qp_offset_list_len_minus1 as usize { 3346 rext.cb_qp_offset_list[i] = r.read_se_bounded(-12, 12)?; 3347 rext.cr_qp_offset_list[i] = r.read_se_bounded(-12, 12)?; 3348 } 3349 } 3350 3351 let bit_depth_y = sps.bit_depth_luma_minus8 + 8; 3352 let max = u32::from(std::cmp::max(0, bit_depth_y - 10)); 3353 3354 rext.log2_sao_offset_scale_luma = r.read_ue_max(max)?; 3355 rext.log2_sao_offset_scale_chroma = r.read_ue_max(max)?; 3356 3357 Ok(()) 3358 } 3359 3360 /// Parse a PPS NALU. parse_pps(&mut self, nalu: &Nalu) -> Result<&Pps, String>3361 pub fn parse_pps(&mut self, nalu: &Nalu) -> Result<&Pps, String> { 3362 if !matches!(nalu.header.type_, NaluType::PpsNut) { 3363 return Err(format!( 3364 "Invalid NALU type, expected {:?}, got {:?}", 3365 NaluType::PpsNut, 3366 nalu.header.type_ 3367 )); 3368 } 3369 3370 let data = nalu.as_ref(); 3371 let header = &nalu.header; 3372 let hdr_len = header.len(); 3373 // Skip the header 3374 let mut r = BitReader::new(&data[hdr_len..], true); 3375 3376 let pic_parameter_set_id = r.read_ue_max(MAX_PPS_COUNT as u32 - 1)?; 3377 let seq_parameter_set_id = r.read_ue_max(MAX_SPS_COUNT as u32 - 1)?; 3378 3379 let sps = self.get_sps(seq_parameter_set_id).ok_or::<String>(format!( 3380 "Could not get SPS for seq_parameter_set_id {}", 3381 seq_parameter_set_id 3382 ))?; 3383 3384 let mut pps = Pps { 3385 pic_parameter_set_id, 3386 seq_parameter_set_id, 3387 dependent_slice_segments_enabled_flag: Default::default(), 3388 output_flag_present_flag: Default::default(), 3389 num_extra_slice_header_bits: Default::default(), 3390 sign_data_hiding_enabled_flag: Default::default(), 3391 cabac_init_present_flag: Default::default(), 3392 num_ref_idx_l0_default_active_minus1: Default::default(), 3393 num_ref_idx_l1_default_active_minus1: Default::default(), 3394 init_qp_minus26: Default::default(), 3395 constrained_intra_pred_flag: Default::default(), 3396 transform_skip_enabled_flag: Default::default(), 3397 cu_qp_delta_enabled_flag: Default::default(), 3398 diff_cu_qp_delta_depth: Default::default(), 3399 cb_qp_offset: Default::default(), 3400 cr_qp_offset: Default::default(), 3401 slice_chroma_qp_offsets_present_flag: Default::default(), 3402 weighted_pred_flag: Default::default(), 3403 weighted_bipred_flag: Default::default(), 3404 transquant_bypass_enabled_flag: Default::default(), 3405 tiles_enabled_flag: Default::default(), 3406 entropy_coding_sync_enabled_flag: Default::default(), 3407 num_tile_columns_minus1: Default::default(), 3408 num_tile_rows_minus1: Default::default(), 3409 uniform_spacing_flag: true, 3410 column_width_minus1: Default::default(), 3411 row_height_minus1: Default::default(), 3412 loop_filter_across_tiles_enabled_flag: true, 3413 loop_filter_across_slices_enabled_flag: Default::default(), 3414 deblocking_filter_control_present_flag: Default::default(), 3415 deblocking_filter_override_enabled_flag: Default::default(), 3416 deblocking_filter_disabled_flag: Default::default(), 3417 beta_offset_div2: Default::default(), 3418 tc_offset_div2: Default::default(), 3419 scaling_list_data_present_flag: Default::default(), 3420 scaling_list: Default::default(), 3421 lists_modification_present_flag: Default::default(), 3422 log2_parallel_merge_level_minus2: Default::default(), 3423 slice_segment_header_extension_present_flag: Default::default(), 3424 extension_present_flag: Default::default(), 3425 range_extension_flag: Default::default(), 3426 range_extension: Default::default(), 3427 qp_bd_offset_y: Default::default(), 3428 scc_extension: Default::default(), 3429 scc_extension_flag: Default::default(), 3430 sps: Rc::clone(sps), 3431 }; 3432 3433 pps.dependent_slice_segments_enabled_flag = r.read_bit()?; 3434 pps.output_flag_present_flag = r.read_bit()?; 3435 pps.num_extra_slice_header_bits = r.read_bits(3)?; 3436 pps.sign_data_hiding_enabled_flag = r.read_bit()?; 3437 pps.cabac_init_present_flag = r.read_bit()?; 3438 3439 // 7.4.7.1 3440 pps.num_ref_idx_l0_default_active_minus1 = r.read_ue_max(14)?; 3441 pps.num_ref_idx_l1_default_active_minus1 = r.read_ue_max(14)?; 3442 3443 // (7-5) 3444 let qp_bd_offset_y = 6 * i32::from(sps.bit_depth_luma_minus8); 3445 3446 pps.init_qp_minus26 = r.read_se_bounded(-(26 + qp_bd_offset_y), 25)?; 3447 pps.qp_bd_offset_y = qp_bd_offset_y as u32; 3448 pps.constrained_intra_pred_flag = r.read_bit()?; 3449 pps.transform_skip_enabled_flag = r.read_bit()?; 3450 pps.cu_qp_delta_enabled_flag = r.read_bit()?; 3451 3452 if pps.cu_qp_delta_enabled_flag { 3453 pps.diff_cu_qp_delta_depth = 3454 r.read_ue_max(u32::from(sps.log2_diff_max_min_luma_coding_block_size))?; 3455 } 3456 3457 pps.cb_qp_offset = r.read_se_bounded(-12, 12)?; 3458 pps.cr_qp_offset = r.read_se_bounded(-12, 12)?; 3459 3460 pps.slice_chroma_qp_offsets_present_flag = r.read_bit()?; 3461 pps.weighted_pred_flag = r.read_bit()?; 3462 pps.weighted_bipred_flag = r.read_bit()?; 3463 pps.transquant_bypass_enabled_flag = r.read_bit()?; 3464 pps.tiles_enabled_flag = r.read_bit()?; 3465 pps.entropy_coding_sync_enabled_flag = r.read_bit()?; 3466 3467 // A mix of the rbsp data and the algorithm in 6.5.1 3468 if pps.tiles_enabled_flag { 3469 pps.num_tile_columns_minus1 = r.read_ue_max(sps.pic_width_in_ctbs_y - 1)?; 3470 pps.num_tile_rows_minus1 = r.read_ue_max(sps.pic_height_in_ctbs_y - 1)?; 3471 pps.uniform_spacing_flag = r.read_bit()?; 3472 if !pps.uniform_spacing_flag { 3473 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] = 3474 sps.pic_width_in_ctbs_y - 1; 3475 3476 for i in 0..usize::from(pps.num_tile_columns_minus1) { 3477 pps.column_width_minus1[i] = r.read_ue_max( 3478 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] - 1, 3479 )?; 3480 pps.column_width_minus1[usize::from(pps.num_tile_columns_minus1)] -= 3481 pps.column_width_minus1[i] + 1; 3482 } 3483 3484 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] = 3485 sps.pic_height_in_ctbs_y - 1; 3486 3487 for i in 0..usize::from(pps.num_tile_rows_minus1) { 3488 pps.row_height_minus1[i] = r.read_ue_max( 3489 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] - 1, 3490 )?; 3491 pps.row_height_minus1[usize::from(pps.num_tile_rows_minus1)] -= 3492 pps.row_height_minus1[i] + 1; 3493 } 3494 } else { 3495 let nrows = u32::from(pps.num_tile_rows_minus1) + 1; 3496 let ncols = u32::from(pps.num_tile_columns_minus1) + 1; 3497 3498 for j in 0..ncols { 3499 pps.column_width_minus1[j as usize] = ((j + 1) * sps.pic_width_in_ctbs_y) 3500 / ncols 3501 - j * sps.pic_width_in_ctbs_y / ncols 3502 - 1; 3503 } 3504 3505 for j in 0..nrows { 3506 pps.row_height_minus1[j as usize] = ((j + 1) * sps.pic_height_in_ctbs_y) 3507 / nrows 3508 - j * sps.pic_height_in_ctbs_y / nrows 3509 - 1; 3510 } 3511 } 3512 3513 pps.loop_filter_across_tiles_enabled_flag = r.read_bit()?; 3514 } 3515 3516 pps.loop_filter_across_slices_enabled_flag = r.read_bit()?; 3517 pps.deblocking_filter_control_present_flag = r.read_bit()?; 3518 3519 if pps.deblocking_filter_control_present_flag { 3520 pps.deblocking_filter_override_enabled_flag = r.read_bit()?; 3521 pps.deblocking_filter_disabled_flag = r.read_bit()?; 3522 if !pps.deblocking_filter_disabled_flag { 3523 pps.beta_offset_div2 = r.read_se_bounded(-6, 6)?; 3524 pps.tc_offset_div2 = r.read_se_bounded(-6, 6)?; 3525 } 3526 } 3527 3528 pps.scaling_list_data_present_flag = r.read_bit()?; 3529 3530 if pps.scaling_list_data_present_flag { 3531 Self::parse_scaling_list_data(&mut pps.scaling_list, &mut r)?; 3532 } else { 3533 for size_id in 0..4 { 3534 let mut matrix_id = 0; 3535 while matrix_id < 6 { 3536 Self::fill_default_scaling_list(&mut pps.scaling_list, size_id, matrix_id); 3537 let step = if size_id == 3 { 3 } else { 1 }; 3538 matrix_id += step; 3539 } 3540 } 3541 } 3542 3543 pps.lists_modification_present_flag = r.read_bit()?; 3544 pps.log2_parallel_merge_level_minus2 = r.read_ue_max(sps.ctb_log2_size_y - 2)?; 3545 pps.slice_segment_header_extension_present_flag = r.read_bit()?; 3546 3547 pps.extension_present_flag = r.read_bit()?; 3548 if pps.extension_present_flag { 3549 pps.range_extension_flag = r.read_bit()?; 3550 3551 if pps.range_extension_flag { 3552 Self::parse_pps_range_extension(&mut pps, sps, &mut r)?; 3553 } 3554 3555 let multilayer_extension_flag = r.read_bit()?; 3556 if multilayer_extension_flag { 3557 return Err("Multilayer extension is not supported".into()); 3558 } 3559 3560 let three_d_extension_flag = r.read_bit()?; 3561 if three_d_extension_flag { 3562 return Err("3D extension is not supported".into()); 3563 } 3564 3565 pps.scc_extension_flag = r.read_bit()?; 3566 if pps.scc_extension_flag { 3567 Self::parse_pps_scc_extension(&mut pps, sps, &mut r)?; 3568 } 3569 3570 r.skip_bits(4)?; // pps_extension_4bits 3571 } 3572 3573 log::debug!("Parsed PPS({}), NAL size was {}", pps.pic_parameter_set_id, nalu.size); 3574 3575 if self.active_ppses.keys().len() >= MAX_PPS_COUNT { 3576 return Err("Broken Data: number of active PPSs > MAX_PPS_COUNT".into()); 3577 } 3578 3579 let key = pps.pic_parameter_set_id; 3580 let pps = Rc::new(pps); 3581 self.active_ppses.remove(&key); 3582 Ok(self.active_ppses.entry(key).or_insert(pps)) 3583 } 3584 parse_pred_weight_table( hdr: &mut SliceHeader, r: &mut BitReader, sps: &Sps, ) -> Result<(), String>3585 fn parse_pred_weight_table( 3586 hdr: &mut SliceHeader, 3587 r: &mut BitReader, 3588 sps: &Sps, 3589 ) -> Result<(), String> { 3590 let pwt = &mut hdr.pred_weight_table; 3591 3592 pwt.luma_log2_weight_denom = r.read_ue_max(7)?; 3593 if sps.chroma_array_type != 0 { 3594 pwt.delta_chroma_log2_weight_denom = r.read_se()?; 3595 pwt.chroma_log2_weight_denom = (pwt.luma_log2_weight_denom as i32 3596 + pwt.delta_chroma_log2_weight_denom as i32) 3597 .try_into() 3598 .map_err(|_| { 3599 String::from("Integer overflow on chroma_log2_weight_denom calculation") 3600 })?; 3601 } 3602 3603 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) { 3604 pwt.luma_weight_l0_flag[i] = r.read_bit()?; 3605 } 3606 3607 if sps.chroma_array_type != 0 { 3608 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) { 3609 pwt.chroma_weight_l0_flag[i] = r.read_bit()?; 3610 } 3611 } 3612 3613 for i in 0..=usize::from(hdr.num_ref_idx_l0_active_minus1) { 3614 if pwt.luma_weight_l0_flag[i] { 3615 pwt.delta_luma_weight_l0[i] = r.read_se_bounded(-128, 127)?; 3616 pwt.luma_offset_l0[i] = r.read_se_bounded(-128, 127)?; 3617 } 3618 3619 if pwt.chroma_weight_l0_flag[i] { 3620 for j in 0..2 { 3621 pwt.delta_chroma_weight_l0[i][j] = r.read_se_bounded(-128, 127)?; 3622 pwt.delta_chroma_offset_l0[i][j] = r.read_se_bounded( 3623 -4 * sps.wp_offset_half_range_c as i32, 3624 4 * sps.wp_offset_half_range_c as i32 - 1, 3625 )?; 3626 } 3627 } 3628 } 3629 3630 if hdr.type_.is_b() { 3631 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) { 3632 pwt.luma_weight_l1_flag[i] = r.read_bit()?; 3633 } 3634 3635 if sps.chroma_format_idc != 0 { 3636 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) { 3637 pwt.chroma_weight_l1_flag[i] = r.read_bit()?; 3638 } 3639 } 3640 3641 for i in 0..=usize::from(hdr.num_ref_idx_l1_active_minus1) { 3642 if pwt.luma_weight_l1_flag[i] { 3643 pwt.delta_luma_weight_l1[i] = r.read_se_bounded(-128, 127)?; 3644 pwt.luma_offset_l1[i] = r.read_se_bounded(-128, 127)?; 3645 } 3646 3647 if pwt.chroma_weight_l1_flag[i] { 3648 for j in 0..2 { 3649 pwt.delta_chroma_weight_l1[i][j] = r.read_se_bounded(-128, 127)?; 3650 pwt.delta_chroma_offset_l1[i][j] = r.read_se_bounded( 3651 -4 * sps.wp_offset_half_range_c as i32, 3652 4 * sps.wp_offset_half_range_c as i32 - 1, 3653 )?; 3654 } 3655 } 3656 } 3657 } 3658 3659 Ok(()) 3660 } 3661 parse_ref_pic_lists_modification( hdr: &mut SliceHeader, r: &mut BitReader, ) -> Result<(), String>3662 fn parse_ref_pic_lists_modification( 3663 hdr: &mut SliceHeader, 3664 r: &mut BitReader, 3665 ) -> Result<(), String> { 3666 let rplm = &mut hdr.ref_pic_list_modification; 3667 3668 rplm.ref_pic_list_modification_flag_l0 = r.read_bit()?; 3669 if rplm.ref_pic_list_modification_flag_l0 { 3670 for _ in 0..=hdr.num_ref_idx_l0_active_minus1 { 3671 let num_bits = (hdr.num_pic_total_curr as f64).log2().ceil() as _; 3672 3673 let entry = r.read_bits(num_bits)?; 3674 3675 if entry > hdr.num_pic_total_curr - 1 { 3676 return Err(format!( 3677 "Invalid list_entry_l0 {}, expected at max NumPicTotalCurr - 1: {}", 3678 entry, 3679 hdr.num_pic_total_curr - 1 3680 )); 3681 } 3682 3683 rplm.list_entry_l0.push(entry); 3684 } 3685 } 3686 3687 if hdr.type_.is_b() { 3688 rplm.ref_pic_list_modification_flag_l1 = r.read_bit()?; 3689 if rplm.ref_pic_list_modification_flag_l1 { 3690 for _ in 0..=hdr.num_ref_idx_l1_active_minus1 { 3691 let num_bits = (hdr.num_pic_total_curr as f64).log2().ceil() as _; 3692 3693 let entry = r.read_bits(num_bits)?; 3694 3695 if entry > hdr.num_pic_total_curr - 1 { 3696 return Err(format!( 3697 "Invalid list_entry_l1 {}, expected at max NumPicTotalCurr - 1: {}", 3698 entry, 3699 hdr.num_pic_total_curr - 1 3700 )); 3701 } 3702 3703 rplm.list_entry_l1.push(entry); 3704 } 3705 } 3706 } 3707 3708 Ok(()) 3709 } 3710 3711 /// Further sets default values given `sps` and `pps`. slice_header_set_defaults(hdr: &mut SliceHeader, sps: &Sps, pps: &Pps)3712 pub fn slice_header_set_defaults(hdr: &mut SliceHeader, sps: &Sps, pps: &Pps) { 3713 // Set some defaults that can't be defined in Default::default(). 3714 hdr.deblocking_filter_disabled_flag = pps.deblocking_filter_disabled_flag; 3715 hdr.beta_offset_div2 = pps.beta_offset_div2; 3716 hdr.tc_offset_div2 = pps.tc_offset_div2; 3717 hdr.loop_filter_across_slices_enabled_flag = pps.loop_filter_across_slices_enabled_flag; 3718 hdr.curr_rps_idx = sps.num_short_term_ref_pic_sets; 3719 hdr.use_integer_mv_flag = sps.scc_extension.motion_vector_resolution_control_idc != 0; 3720 } 3721 3722 /// Parses a slice header from a slice NALU. parse_slice_header<'a>(&mut self, nalu: Nalu<'a>) -> Result<Slice<'a>, String>3723 pub fn parse_slice_header<'a>(&mut self, nalu: Nalu<'a>) -> Result<Slice<'a>, String> { 3724 if !matches!( 3725 nalu.header.type_, 3726 NaluType::TrailN 3727 | NaluType::TrailR 3728 | NaluType::TsaN 3729 | NaluType::TsaR 3730 | NaluType::StsaN 3731 | NaluType::StsaR 3732 | NaluType::RadlN 3733 | NaluType::RadlR 3734 | NaluType::RaslN 3735 | NaluType::RaslR 3736 | NaluType::BlaWLp 3737 | NaluType::BlaWRadl 3738 | NaluType::BlaNLp 3739 | NaluType::IdrWRadl 3740 | NaluType::IdrNLp 3741 | NaluType::CraNut, 3742 ) { 3743 return Err(format!("Invalid NALU type: {:?} is not a slice NALU", nalu.header.type_)); 3744 } 3745 3746 let data = nalu.as_ref(); 3747 let nalu_header = &nalu.header; 3748 let hdr_len = nalu_header.len(); 3749 // Skip the header 3750 let mut r = BitReader::new(&data[hdr_len..], true); 3751 3752 let mut hdr = 3753 SliceHeader { first_slice_segment_in_pic_flag: r.read_bit()?, ..Default::default() }; 3754 3755 if nalu.header.type_.is_irap() { 3756 hdr.no_output_of_prior_pics_flag = r.read_bit()?; 3757 } 3758 3759 hdr.pic_parameter_set_id = r.read_ue_max(63)?; 3760 3761 let pps = self.get_pps(hdr.pic_parameter_set_id).ok_or::<String>(format!( 3762 "Could not get PPS for pic_parameter_set_id {}", 3763 hdr.pic_parameter_set_id 3764 ))?; 3765 3766 let sps = &pps.sps; 3767 3768 Self::slice_header_set_defaults(&mut hdr, sps, pps); 3769 3770 if !hdr.first_slice_segment_in_pic_flag { 3771 if pps.dependent_slice_segments_enabled_flag { 3772 hdr.dependent_slice_segment_flag = r.read_bit()?; 3773 } 3774 3775 let num_bits = (sps.pic_size_in_ctbs_y as f64).log2().ceil() as _; 3776 hdr.segment_address = r.read_bits(num_bits)?; 3777 3778 if hdr.segment_address > sps.pic_size_in_ctbs_y - 1 { 3779 return Err(format!("Invalid slice_segment_address {}", hdr.segment_address)); 3780 } 3781 } 3782 3783 if !hdr.dependent_slice_segment_flag { 3784 r.skip_bits(usize::from(pps.num_extra_slice_header_bits))?; 3785 3786 let slice_type: u32 = r.read_ue()?; 3787 hdr.type_ = SliceType::try_from(slice_type)?; 3788 3789 if pps.output_flag_present_flag { 3790 hdr.pic_output_flag = r.read_bit()?; 3791 } 3792 3793 if sps.separate_colour_plane_flag { 3794 hdr.colour_plane_id = r.read_bits(2)?; 3795 } 3796 3797 if !matches!(nalu_header.type_, NaluType::IdrWRadl | NaluType::IdrNLp) { 3798 let num_bits = usize::from(sps.log2_max_pic_order_cnt_lsb_minus4 + 4); 3799 hdr.pic_order_cnt_lsb = r.read_bits(num_bits)?; 3800 3801 if u32::from(hdr.pic_order_cnt_lsb) 3802 > 2u32.pow(u32::from(sps.log2_max_pic_order_cnt_lsb_minus4 + 4)) 3803 { 3804 return Err(format!("Invalid pic_order_cnt_lsb {}", hdr.pic_order_cnt_lsb)); 3805 } 3806 3807 hdr.short_term_ref_pic_set_sps_flag = r.read_bit()?; 3808 3809 if !hdr.short_term_ref_pic_set_sps_flag { 3810 let epb_before = r.num_epb(); 3811 let bits_left_before = r.num_bits_left(); 3812 3813 let st_rps_idx = sps.num_short_term_ref_pic_sets; 3814 3815 Self::parse_short_term_ref_pic_set( 3816 sps, 3817 &mut hdr.short_term_ref_pic_set, 3818 &mut r, 3819 st_rps_idx, 3820 )?; 3821 3822 hdr.st_rps_bits = ((bits_left_before - r.num_bits_left()) 3823 - 8 * (r.num_epb() - epb_before)) 3824 as u32; 3825 } else if sps.num_short_term_ref_pic_sets > 1 { 3826 let num_bits = (sps.num_short_term_ref_pic_sets as f64).log2().ceil() as _; 3827 hdr.short_term_ref_pic_set_idx = r.read_bits(num_bits)?; 3828 3829 if hdr.short_term_ref_pic_set_idx > sps.num_short_term_ref_pic_sets - 1 { 3830 return Err(format!( 3831 "Invalid short_term_ref_pic_set_idx {}", 3832 hdr.short_term_ref_pic_set_idx 3833 )); 3834 } 3835 } 3836 3837 if hdr.short_term_ref_pic_set_sps_flag { 3838 hdr.curr_rps_idx = hdr.short_term_ref_pic_set_idx; 3839 } 3840 3841 if sps.long_term_ref_pics_present_flag { 3842 if sps.num_long_term_ref_pics_sps > 0 { 3843 hdr.num_long_term_sps = 3844 r.read_ue_max(u32::from(sps.num_long_term_ref_pics_sps))?; 3845 } 3846 3847 hdr.num_long_term_pics = r.read_ue_max( 3848 MAX_LONG_TERM_REF_PIC_SETS as u32 - u32::from(hdr.num_long_term_sps), 3849 )?; 3850 3851 let num_lt = hdr.num_long_term_sps + hdr.num_long_term_pics; 3852 for i in 0..usize::from(num_lt) { 3853 // The variables `PocLsbLt[ i ]` and `UsedByCurrPicLt[ i ]` are derived as follows: 3854 // 3855 // – If i is less than num_long_term_sps, `PocLsbLt[ i ]` is set equal to 3856 // lt_ref_pic_poc_lsb_sps[ `lt_idx_sps[ i ]` ] and `UsedByCurrPicLt[ i ]` is set equal 3857 // to used_by_curr_pic_lt_sps_flag[ `lt_idx_sps[ i ]` ]. 3858 // 3859 // – Otherwise, `PocLsbLt[ i ]` 3860 // is set equal to `poc_lsb_lt[ i ]` and `UsedByCurrPicLt[ i ]` is set equal to 3861 // `used_by_curr_pic_lt_flag[ i ]`. 3862 if i < usize::from(hdr.num_long_term_sps) { 3863 if sps.num_long_term_ref_pics_sps > 1 { 3864 let num_bits = 3865 (sps.num_long_term_ref_pics_sps as f64).log2().ceil() as _; 3866 3867 hdr.lt_idx_sps[i] = r.read_bits(num_bits)?; 3868 3869 if hdr.lt_idx_sps[i] > sps.num_long_term_ref_pics_sps - 1 { 3870 return Err(format!( 3871 "Invalid lt_idx_sps[{}] {}", 3872 i, hdr.lt_idx_sps[i] 3873 )); 3874 } 3875 } 3876 3877 hdr.poc_lsb_lt[i] = 3878 sps.lt_ref_pic_poc_lsb_sps[usize::from(hdr.lt_idx_sps[i])]; 3879 hdr.used_by_curr_pic_lt[i] = 3880 sps.used_by_curr_pic_lt_sps_flag[usize::from(hdr.lt_idx_sps[i])]; 3881 } else { 3882 let num_bits = usize::from(sps.log2_max_pic_order_cnt_lsb_minus4) + 4; 3883 hdr.poc_lsb_lt[i] = r.read_bits(num_bits)?; 3884 hdr.used_by_curr_pic_lt[i] = r.read_bit()?; 3885 } 3886 3887 hdr.delta_poc_msb_present_flag[i] = r.read_bit()?; 3888 if hdr.delta_poc_msb_present_flag[i] { 3889 // The value of `delta_poc_msb_cycle_lt[ i ]` shall be 3890 // in the range of 0 to 2(32 − 3891 // log2_max_pic_order_cnt_lsb_minus4 − 4 ), 3892 // inclusive. When `delta_poc_msb_cycle_lt[ i ]` is 3893 // not present, it is inferred to be equal to 0. 3894 let max = 3895 2u32.pow(32 - u32::from(sps.log2_max_pic_order_cnt_lsb_minus4) - 4); 3896 hdr.delta_poc_msb_cycle_lt[i] = r.read_ue_max(max)?; 3897 } 3898 // Equation 7-52 (simplified) 3899 if i != 0 && i != usize::from(hdr.num_long_term_sps) { 3900 hdr.delta_poc_msb_cycle_lt[i] += hdr.delta_poc_msb_cycle_lt[i - 1]; 3901 } 3902 } 3903 } 3904 3905 if sps.temporal_mvp_enabled_flag { 3906 hdr.temporal_mvp_enabled_flag = r.read_bit()?; 3907 } 3908 } 3909 3910 if sps.sample_adaptive_offset_enabled_flag { 3911 hdr.sao_luma_flag = r.read_bit()?; 3912 if sps.chroma_array_type != 0 { 3913 hdr.sao_chroma_flag = r.read_bit()?; 3914 } 3915 } 3916 3917 if hdr.type_.is_p() || hdr.type_.is_b() { 3918 hdr.num_ref_idx_active_override_flag = r.read_bit()?; 3919 if hdr.num_ref_idx_active_override_flag { 3920 hdr.num_ref_idx_l0_active_minus1 = r.read_ue_max(MAX_REF_IDX_ACTIVE - 1)?; 3921 if hdr.type_.is_b() { 3922 hdr.num_ref_idx_l1_active_minus1 = r.read_ue_max(MAX_REF_IDX_ACTIVE - 1)?; 3923 } 3924 } else { 3925 hdr.num_ref_idx_l0_active_minus1 = pps.num_ref_idx_l0_default_active_minus1; 3926 hdr.num_ref_idx_l1_active_minus1 = pps.num_ref_idx_l1_default_active_minus1; 3927 } 3928 3929 // 7-57 3930 let mut num_pic_total_curr = 0; 3931 let rps = if hdr.short_term_ref_pic_set_sps_flag { 3932 sps.short_term_ref_pic_set 3933 .get(usize::from(hdr.curr_rps_idx)) 3934 .ok_or::<String>("Invalid RPS".into())? 3935 } else { 3936 &hdr.short_term_ref_pic_set 3937 }; 3938 3939 for i in 0..usize::from(rps.num_negative_pics) { 3940 if rps.used_by_curr_pic_s0[i] { 3941 num_pic_total_curr += 1; 3942 } 3943 } 3944 3945 for i in 0..usize::from(rps.num_positive_pics) { 3946 if rps.used_by_curr_pic_s1[i] { 3947 num_pic_total_curr += 1; 3948 } 3949 } 3950 3951 for i in 0..usize::from(hdr.num_long_term_sps + hdr.num_long_term_pics) { 3952 if hdr.used_by_curr_pic_lt[i] { 3953 num_pic_total_curr += 1; 3954 } 3955 } 3956 3957 if pps.scc_extension.curr_pic_ref_enabled_flag { 3958 num_pic_total_curr += 1; 3959 } 3960 3961 hdr.num_pic_total_curr = num_pic_total_curr; 3962 3963 if pps.lists_modification_present_flag && hdr.num_pic_total_curr > 1 { 3964 Self::parse_ref_pic_lists_modification(&mut hdr, &mut r)?; 3965 } 3966 3967 if hdr.type_.is_b() { 3968 hdr.mvd_l1_zero_flag = r.read_bit()?; 3969 } 3970 3971 if pps.cabac_init_present_flag { 3972 hdr.cabac_init_flag = r.read_bit()?; 3973 } 3974 3975 if hdr.temporal_mvp_enabled_flag { 3976 if hdr.type_.is_b() { 3977 hdr.collocated_from_l0_flag = r.read_bit()?; 3978 } 3979 3980 if (hdr.collocated_from_l0_flag && hdr.num_ref_idx_l0_active_minus1 > 0) 3981 || (!hdr.collocated_from_l0_flag && hdr.num_ref_idx_l1_active_minus1 > 0) 3982 { 3983 let max = if (hdr.type_.is_p() || hdr.type_.is_b()) 3984 && hdr.collocated_from_l0_flag 3985 { 3986 hdr.num_ref_idx_l0_active_minus1 3987 } else if hdr.type_.is_b() && !hdr.collocated_from_l0_flag { 3988 hdr.num_ref_idx_l1_active_minus1 3989 } else { 3990 return Err("Invalid value for collocated_ref_idx".into()); 3991 }; 3992 3993 { 3994 hdr.collocated_ref_idx = r.read_ue_max(u32::from(max))?; 3995 } 3996 } 3997 } 3998 3999 if (pps.weighted_pred_flag && hdr.type_.is_p()) 4000 || (pps.weighted_bipred_flag && hdr.type_.is_b()) 4001 { 4002 Self::parse_pred_weight_table(&mut hdr, &mut r, sps)?; 4003 } 4004 4005 hdr.five_minus_max_num_merge_cand = r.read_ue()?; 4006 4007 if sps.scc_extension.motion_vector_resolution_control_idc == 2 { 4008 hdr.use_integer_mv_flag = r.read_bit()?; 4009 } 4010 } 4011 4012 hdr.qp_delta = r.read_se_bounded(-87, 77)?; 4013 4014 let slice_qp_y = (26 + pps.init_qp_minus26 + hdr.qp_delta) as i32; 4015 if slice_qp_y < -(pps.qp_bd_offset_y as i32) || slice_qp_y > 51 { 4016 return Err(format!("Invalid slice_qp_delta: {}", hdr.qp_delta)); 4017 } 4018 4019 if pps.slice_chroma_qp_offsets_present_flag { 4020 hdr.cb_qp_offset = r.read_se_bounded(-12, 12)?; 4021 4022 let qp_offset = pps.cb_qp_offset + hdr.cb_qp_offset; 4023 if !(-12..=12).contains(&qp_offset) { 4024 return Err(format!( 4025 "Invalid value for slice_cb_qp_offset: {}", 4026 hdr.cb_qp_offset 4027 )); 4028 } 4029 4030 hdr.cr_qp_offset = r.read_se_bounded(-12, 12)?; 4031 4032 let qp_offset = pps.cr_qp_offset + hdr.cr_qp_offset; 4033 if !(-12..=12).contains(&qp_offset) { 4034 return Err(format!( 4035 "Invalid value for slice_cr_qp_offset: {}", 4036 hdr.cr_qp_offset 4037 )); 4038 } 4039 } 4040 4041 if pps.scc_extension.slice_act_qp_offsets_present_flag { 4042 hdr.slice_act_y_qp_offset = r.read_se_bounded(-12, 12)?; 4043 hdr.slice_act_cb_qp_offset = r.read_se_bounded(-12, 12)?; 4044 hdr.slice_act_cr_qp_offset = r.read_se_bounded(-12, 12)?; 4045 } 4046 4047 if pps.range_extension.chroma_qp_offset_list_enabled_flag { 4048 hdr.cu_chroma_qp_offset_enabled_flag = r.read_bit()?; 4049 } 4050 4051 if pps.deblocking_filter_override_enabled_flag { 4052 hdr.deblocking_filter_override_flag = r.read_bit()?; 4053 } 4054 4055 if hdr.deblocking_filter_override_flag { 4056 hdr.deblocking_filter_disabled_flag = r.read_bit()?; 4057 if !hdr.deblocking_filter_disabled_flag { 4058 hdr.beta_offset_div2 = r.read_se_bounded(-6, 6)?; 4059 hdr.tc_offset_div2 = r.read_se_bounded(-6, 6)?; 4060 } 4061 } 4062 4063 if pps.loop_filter_across_slices_enabled_flag 4064 && (hdr.sao_luma_flag 4065 || hdr.sao_chroma_flag 4066 || !hdr.deblocking_filter_disabled_flag) 4067 { 4068 hdr.loop_filter_across_slices_enabled_flag = r.read_bit()?; 4069 } 4070 } 4071 4072 if pps.tiles_enabled_flag || pps.entropy_coding_sync_enabled_flag { 4073 let max = if !pps.tiles_enabled_flag && pps.entropy_coding_sync_enabled_flag { 4074 sps.pic_height_in_ctbs_y - 1 4075 } else if pps.tiles_enabled_flag && !pps.entropy_coding_sync_enabled_flag { 4076 u32::from((pps.num_tile_columns_minus1 + 1) * (pps.num_tile_rows_minus1 + 1) - 1) 4077 } else { 4078 (u32::from(pps.num_tile_columns_minus1) + 1) * sps.pic_height_in_ctbs_y - 1 4079 }; 4080 4081 hdr.num_entry_point_offsets = r.read_ue_max(max)?; 4082 if hdr.num_entry_point_offsets > 0 { 4083 hdr.offset_len_minus1 = r.read_ue_max(31)?; 4084 for i in 0..hdr.num_entry_point_offsets as usize { 4085 let num_bits = usize::from(hdr.offset_len_minus1 + 1); 4086 hdr.entry_point_offset_minus1[i] = r.read_bits(num_bits)?; 4087 } 4088 } 4089 } 4090 4091 if pps.slice_segment_header_extension_present_flag { 4092 let segment_header_extension_length = r.read_ue_max(256)?; 4093 for _ in 0..segment_header_extension_length { 4094 r.skip_bits(8)?; // slice_segment_header_extension_data_byte[i] 4095 } 4096 } 4097 4098 // byte_alignment() 4099 r.skip_bits(1)?; // Alignment bit 4100 let num_bits = r.num_bits_left() % 8; 4101 r.skip_bits(num_bits)?; 4102 4103 let epb = r.num_epb(); 4104 hdr.header_bit_size = ((nalu.size - epb) * 8 - r.num_bits_left()) as u32; 4105 4106 hdr.n_emulation_prevention_bytes = epb as u32; 4107 4108 log::debug!("Parsed slice {:?}, NAL size was {}", nalu_header.type_, nalu.size); 4109 4110 Ok(Slice { header: hdr, nalu }) 4111 } 4112 4113 /// Returns a previously parsed vps given `vps_id`, if any. get_vps(&self, vps_id: u8) -> Option<&Rc<Vps>>4114 pub fn get_vps(&self, vps_id: u8) -> Option<&Rc<Vps>> { 4115 self.active_vpses.get(&vps_id) 4116 } 4117 4118 /// Returns a previously parsed sps given `sps_id`, if any. get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>>4119 pub fn get_sps(&self, sps_id: u8) -> Option<&Rc<Sps>> { 4120 self.active_spses.get(&sps_id) 4121 } 4122 4123 /// Returns a previously parsed pps given `pps_id`, if any. get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>>4124 pub fn get_pps(&self, pps_id: u8) -> Option<&Rc<Pps>> { 4125 self.active_ppses.get(&pps_id) 4126 } 4127 } 4128 4129 #[cfg(test)] 4130 mod tests { 4131 use std::io::Cursor; 4132 4133 use crate::codec::h264::nalu::Nalu; 4134 use crate::codec::h265::parser::Level; 4135 use crate::codec::h265::parser::NaluHeader; 4136 use crate::codec::h265::parser::NaluType; 4137 use crate::codec::h265::parser::Parser; 4138 use crate::codec::h265::parser::SliceType; 4139 4140 const STREAM_BEAR: &[u8] = include_bytes!("test_data/bear.h265"); 4141 const STREAM_BEAR_NUM_NALUS: usize = 35; 4142 4143 const STREAM_BBB: &[u8] = include_bytes!("test_data/bbb.h265"); 4144 const STREAM_BBB_NUM_NALUS: usize = 64; 4145 4146 const STREAM_TEST25FPS: &[u8] = include_bytes!("test_data/test-25fps.h265"); 4147 const STREAM_TEST25FPS_NUM_NALUS: usize = 254; 4148 4149 const STREAM_TEST_25_FPS_SLICE_0: &[u8] = 4150 include_bytes!("test_data/test-25fps-h265-slice-data-0.bin"); 4151 const STREAM_TEST_25_FPS_SLICE_1: &[u8] = 4152 include_bytes!("test_data/test-25fps-h265-slice-data-1.bin"); 4153 dispatch_parse_call(parser: &mut Parser, nalu: Nalu<NaluHeader>) -> Result<(), String>4154 fn dispatch_parse_call(parser: &mut Parser, nalu: Nalu<NaluHeader>) -> Result<(), String> { 4155 match nalu.header.type_ { 4156 NaluType::TrailN 4157 | NaluType::TrailR 4158 | NaluType::TsaN 4159 | NaluType::TsaR 4160 | NaluType::StsaN 4161 | NaluType::StsaR 4162 | NaluType::RadlN 4163 | NaluType::RadlR 4164 | NaluType::RaslN 4165 | NaluType::RaslR 4166 | NaluType::BlaWLp 4167 | NaluType::BlaWRadl 4168 | NaluType::BlaNLp 4169 | NaluType::IdrWRadl 4170 | NaluType::IdrNLp 4171 | NaluType::CraNut => { 4172 parser.parse_slice_header(nalu).unwrap(); 4173 } 4174 NaluType::VpsNut => { 4175 parser.parse_vps(&nalu).unwrap(); 4176 } 4177 NaluType::SpsNut => { 4178 parser.parse_sps(&nalu).unwrap(); 4179 } 4180 NaluType::PpsNut => { 4181 parser.parse_pps(&nalu).unwrap(); 4182 } 4183 _ => { /* ignore */ } 4184 } 4185 Ok(()) 4186 } 4187 find_nalu_by_type( bitstream: &[u8], nalu_type: NaluType, mut nskip: i32, ) -> Option<Nalu<NaluHeader>>4188 fn find_nalu_by_type( 4189 bitstream: &[u8], 4190 nalu_type: NaluType, 4191 mut nskip: i32, 4192 ) -> Option<Nalu<NaluHeader>> { 4193 let mut cursor = Cursor::new(bitstream); 4194 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) { 4195 if nalu.header.type_ == nalu_type { 4196 if nskip == 0 { 4197 return Some(nalu); 4198 } else { 4199 nskip -= 1; 4200 } 4201 } 4202 } 4203 4204 None 4205 } 4206 4207 /// This test is adapted from chromium, available at media/video/h265_parser_unittest.cc 4208 #[test] parse_nalus_from_stream_file()4209 fn parse_nalus_from_stream_file() { 4210 let mut cursor = Cursor::new(STREAM_BEAR); 4211 let mut num_nalus = 0; 4212 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() { 4213 num_nalus += 1; 4214 } 4215 4216 assert_eq!(num_nalus, STREAM_BEAR_NUM_NALUS); 4217 4218 let mut cursor = Cursor::new(STREAM_BBB); 4219 let mut num_nalus = 0; 4220 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() { 4221 num_nalus += 1; 4222 } 4223 4224 assert_eq!(num_nalus, STREAM_BBB_NUM_NALUS); 4225 4226 let mut cursor = Cursor::new(STREAM_TEST25FPS); 4227 let mut num_nalus = 0; 4228 while Nalu::<NaluHeader>::next(&mut cursor).is_ok() { 4229 num_nalus += 1; 4230 } 4231 4232 assert_eq!(num_nalus, STREAM_TEST25FPS_NUM_NALUS); 4233 } 4234 4235 /// Parse the syntax, making sure we can parse the files without crashing. 4236 /// Does not check whether the parsed values are correct. 4237 #[test] parse_syntax_from_nals()4238 fn parse_syntax_from_nals() { 4239 let mut cursor = Cursor::new(STREAM_BBB); 4240 let mut parser = Parser::default(); 4241 4242 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) { 4243 dispatch_parse_call(&mut parser, nalu).unwrap(); 4244 } 4245 4246 let mut cursor = Cursor::new(STREAM_BEAR); 4247 let mut parser = Parser::default(); 4248 4249 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) { 4250 dispatch_parse_call(&mut parser, nalu).unwrap(); 4251 } 4252 4253 let mut cursor = Cursor::new(STREAM_TEST25FPS); 4254 let mut parser = Parser::default(); 4255 4256 while let Ok(nalu) = Nalu::<NaluHeader>::next(&mut cursor) { 4257 dispatch_parse_call(&mut parser, nalu).unwrap(); 4258 } 4259 } 4260 4261 /// Adapted from Chromium (media/video/h265_parser_unittest.cc::VpsParsing()) 4262 #[test] chromium_vps_parsing()4263 fn chromium_vps_parsing() { 4264 let mut cursor = Cursor::new(STREAM_BEAR); 4265 let mut parser = Parser::default(); 4266 4267 let vps_nalu = Nalu::<NaluHeader>::next(&mut cursor).unwrap(); 4268 let vps = parser.parse_vps(&vps_nalu).unwrap(); 4269 4270 assert!(vps.base_layer_internal_flag); 4271 assert!(vps.base_layer_available_flag); 4272 assert_eq!(vps.max_layers_minus1, 0); 4273 assert_eq!(vps.max_sub_layers_minus1, 0); 4274 assert!(vps.temporal_id_nesting_flag); 4275 assert_eq!(vps.profile_tier_level.general_profile_idc, 1); 4276 assert_eq!(vps.profile_tier_level.general_level_idc, Level::L2); 4277 assert_eq!(vps.max_dec_pic_buffering_minus1[0], 4); 4278 assert_eq!(vps.max_num_reorder_pics[0], 2); 4279 assert_eq!(vps.max_latency_increase_plus1[0], 0); 4280 for i in 1..7 { 4281 assert_eq!(vps.max_dec_pic_buffering_minus1[i], 0); 4282 assert_eq!(vps.max_num_reorder_pics[i], 0); 4283 assert_eq!(vps.max_latency_increase_plus1[i], 0); 4284 } 4285 assert_eq!(vps.max_layer_id, 0); 4286 assert_eq!(vps.num_layer_sets_minus1, 0); 4287 assert!(!vps.timing_info_present_flag); 4288 } 4289 4290 /// Adapted from Chromium (media/video/h265_parser_unittest.cc::SpsParsing()) 4291 #[test] chromium_sps_parsing()4292 fn chromium_sps_parsing() { 4293 let mut parser = Parser::default(); 4294 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap(); 4295 let sps = parser.parse_sps(&sps_nalu).unwrap(); 4296 4297 assert_eq!(sps.max_sub_layers_minus1, 0); 4298 assert_eq!(sps.profile_tier_level.general_profile_idc, 1); 4299 assert_eq!(sps.profile_tier_level.general_level_idc, Level::L2); 4300 assert_eq!(sps.seq_parameter_set_id, 0); 4301 assert_eq!(sps.chroma_format_idc, 1); 4302 assert!(!sps.separate_colour_plane_flag); 4303 assert_eq!(sps.pic_width_in_luma_samples, 320); 4304 assert_eq!(sps.pic_height_in_luma_samples, 184); 4305 assert_eq!(sps.conf_win_left_offset, 0); 4306 assert_eq!(sps.conf_win_right_offset, 0); 4307 assert_eq!(sps.conf_win_top_offset, 0); 4308 assert_eq!(sps.conf_win_bottom_offset, 2); 4309 assert_eq!(sps.bit_depth_luma_minus8, 0); 4310 assert_eq!(sps.bit_depth_chroma_minus8, 0); 4311 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 4); 4312 assert_eq!(sps.max_dec_pic_buffering_minus1[0], 4); 4313 assert_eq!(sps.max_num_reorder_pics[0], 2); 4314 assert_eq!(sps.max_latency_increase_plus1[0], 0); 4315 for i in 1..7 { 4316 assert_eq!(sps.max_dec_pic_buffering_minus1[i], 0); 4317 assert_eq!(sps.max_num_reorder_pics[i], 0); 4318 assert_eq!(sps.max_latency_increase_plus1[i], 0); 4319 } 4320 assert_eq!(sps.log2_min_luma_coding_block_size_minus3, 0); 4321 assert_eq!(sps.log2_diff_max_min_luma_coding_block_size, 3); 4322 assert_eq!(sps.log2_min_luma_transform_block_size_minus2, 0); 4323 assert_eq!(sps.log2_diff_max_min_luma_transform_block_size, 3); 4324 assert_eq!(sps.max_transform_hierarchy_depth_inter, 0); 4325 assert_eq!(sps.max_transform_hierarchy_depth_intra, 0); 4326 assert!(!sps.scaling_list_enabled_flag); 4327 assert!(!sps.scaling_list_data_present_flag); 4328 assert!(!sps.amp_enabled_flag); 4329 assert!(sps.sample_adaptive_offset_enabled_flag); 4330 assert!(!sps.pcm_enabled_flag); 4331 assert_eq!(sps.pcm_sample_bit_depth_luma_minus1, 0); 4332 assert_eq!(sps.pcm_sample_bit_depth_chroma_minus1, 0); 4333 assert_eq!(sps.log2_min_pcm_luma_coding_block_size_minus3, 0); 4334 assert_eq!(sps.log2_diff_max_min_pcm_luma_coding_block_size, 0); 4335 assert!(!sps.pcm_loop_filter_disabled_flag); 4336 assert_eq!(sps.num_short_term_ref_pic_sets, 0); 4337 assert_eq!(sps.num_long_term_ref_pics_sps, 0); 4338 assert!(sps.temporal_mvp_enabled_flag); 4339 assert!(sps.strong_intra_smoothing_enabled_flag); 4340 assert_eq!(sps.vui_parameters.sar_width, 0); 4341 assert_eq!(sps.vui_parameters.sar_height, 0); 4342 assert!(!sps.vui_parameters.video_full_range_flag); 4343 assert!(!sps.vui_parameters.colour_description_present_flag); 4344 4345 // Note: the original test has 0 for the three variables below, but they 4346 // have valid defaults in the spec (i.e.: 2). 4347 assert_eq!(sps.vui_parameters.colour_primaries, 2); 4348 assert_eq!(sps.vui_parameters.transfer_characteristics, 2); 4349 assert_eq!(sps.vui_parameters.matrix_coeffs, 2); 4350 4351 assert_eq!(sps.vui_parameters.def_disp_win_left_offset, 0); 4352 assert_eq!(sps.vui_parameters.def_disp_win_right_offset, 0); 4353 assert_eq!(sps.vui_parameters.def_disp_win_top_offset, 0); 4354 assert_eq!(sps.vui_parameters.def_disp_win_bottom_offset, 0); 4355 } 4356 4357 /// Adapted from Chromium (media/video/h265_parser_unittest.cc::PpsParsing()) 4358 #[test] chromium_pps_parsing()4359 fn chromium_pps_parsing() { 4360 let mut parser = Parser::default(); 4361 4362 // Have to parse the SPS to set up the parser's internal state. 4363 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap(); 4364 parser.parse_sps(&sps_nalu).unwrap(); 4365 4366 let pps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::PpsNut, 0).unwrap(); 4367 let pps = parser.parse_pps(&pps_nalu).unwrap(); 4368 4369 assert_eq!(pps.pic_parameter_set_id, 0); 4370 assert_eq!(pps.seq_parameter_set_id, 0); 4371 assert!(!pps.dependent_slice_segments_enabled_flag); 4372 assert!(!pps.output_flag_present_flag); 4373 assert_eq!(pps.num_extra_slice_header_bits, 0); 4374 assert!(pps.sign_data_hiding_enabled_flag); 4375 assert!(!pps.cabac_init_present_flag); 4376 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0); 4377 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0); 4378 assert_eq!(pps.init_qp_minus26, 0); 4379 assert!(!pps.constrained_intra_pred_flag); 4380 assert!(!pps.transform_skip_enabled_flag); 4381 assert!(pps.cu_qp_delta_enabled_flag); 4382 assert_eq!(pps.diff_cu_qp_delta_depth, 0); 4383 assert_eq!(pps.cb_qp_offset, 0); 4384 assert_eq!(pps.cr_qp_offset, 0); 4385 assert!(!pps.slice_chroma_qp_offsets_present_flag); 4386 assert!(pps.weighted_pred_flag); 4387 assert!(!pps.weighted_bipred_flag); 4388 assert!(!pps.transquant_bypass_enabled_flag); 4389 assert!(!pps.tiles_enabled_flag); 4390 assert!(pps.entropy_coding_sync_enabled_flag); 4391 assert!(pps.loop_filter_across_tiles_enabled_flag); 4392 assert!(!pps.scaling_list_data_present_flag); 4393 assert!(!pps.lists_modification_present_flag); 4394 assert_eq!(pps.log2_parallel_merge_level_minus2, 0); 4395 assert!(!pps.slice_segment_header_extension_present_flag); 4396 } 4397 4398 /// Adapted from Chromium (media/video/h265_parser_unittest.cc::SliceHeaderParsing()) 4399 #[test] chromium_slice_header_parsing()4400 fn chromium_slice_header_parsing() { 4401 let mut parser = Parser::default(); 4402 4403 // Have to parse the SPS/VPS/PPS to set up the parser's internal state. 4404 let vps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::VpsNut, 0).unwrap(); 4405 parser.parse_vps(&vps_nalu).unwrap(); 4406 4407 let sps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::SpsNut, 0).unwrap(); 4408 parser.parse_sps(&sps_nalu).unwrap(); 4409 4410 let pps_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::PpsNut, 0).unwrap(); 4411 parser.parse_pps(&pps_nalu).unwrap(); 4412 4413 // Just like the Chromium test, do an IDR slice, then a non IDR slice. 4414 let slice_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::IdrWRadl, 0).unwrap(); 4415 let slice = parser.parse_slice_header(slice_nalu).unwrap(); 4416 let hdr = &slice.header; 4417 assert!(hdr.first_slice_segment_in_pic_flag); 4418 assert!(!hdr.no_output_of_prior_pics_flag); 4419 assert_eq!(hdr.pic_parameter_set_id, 0); 4420 assert!(!hdr.dependent_slice_segment_flag); 4421 assert_eq!(hdr.type_, SliceType::I); 4422 assert!(hdr.sao_luma_flag); 4423 assert!(hdr.sao_chroma_flag); 4424 assert_eq!(hdr.qp_delta, 8); 4425 assert!(hdr.loop_filter_across_slices_enabled_flag); 4426 4427 let slice_nalu = find_nalu_by_type(STREAM_BEAR, NaluType::TrailR, 0).unwrap(); 4428 let slice = parser.parse_slice_header(slice_nalu).unwrap(); 4429 let hdr = &slice.header; 4430 assert!(hdr.first_slice_segment_in_pic_flag); 4431 assert_eq!(hdr.pic_parameter_set_id, 0); 4432 assert!(!hdr.dependent_slice_segment_flag); 4433 assert_eq!(hdr.type_, SliceType::P); 4434 assert_eq!(hdr.pic_order_cnt_lsb, 4); 4435 assert!(!hdr.short_term_ref_pic_set_sps_flag); 4436 assert_eq!(hdr.short_term_ref_pic_set.num_negative_pics, 1); 4437 assert_eq!(hdr.short_term_ref_pic_set.num_positive_pics, 0); 4438 assert_eq!(hdr.short_term_ref_pic_set.delta_poc_s0[0], -4); 4439 assert!(hdr.short_term_ref_pic_set.used_by_curr_pic_s0[0]); 4440 assert!(hdr.temporal_mvp_enabled_flag); 4441 assert!(hdr.sao_luma_flag); 4442 assert!(hdr.sao_chroma_flag); 4443 assert!(!hdr.num_ref_idx_active_override_flag); 4444 assert_eq!(hdr.pred_weight_table.luma_log2_weight_denom, 0); 4445 assert_eq!(hdr.pred_weight_table.delta_chroma_log2_weight_denom, 7); 4446 assert_eq!(hdr.pred_weight_table.delta_luma_weight_l0[0], 0); 4447 assert_eq!(hdr.pred_weight_table.luma_offset_l0[0], -2); 4448 assert_eq!(hdr.pred_weight_table.delta_chroma_weight_l0[0][0], -9); 4449 assert_eq!(hdr.pred_weight_table.delta_chroma_weight_l0[0][1], -9); 4450 assert_eq!(hdr.pred_weight_table.delta_chroma_offset_l0[0][0], 0); 4451 assert_eq!(hdr.pred_weight_table.delta_chroma_offset_l0[0][1], 0); 4452 assert_eq!(hdr.five_minus_max_num_merge_cand, 3); 4453 assert_eq!(hdr.qp_delta, 8); 4454 assert!(hdr.loop_filter_across_slices_enabled_flag); 4455 } 4456 4457 /// A custom test for VPS parsing with data manually extracted from 4458 /// GStreamer using GDB. 4459 #[test] test25fps_vps_header_parsing()4460 fn test25fps_vps_header_parsing() { 4461 let mut cursor = Cursor::new(STREAM_TEST25FPS); 4462 let mut parser = Parser::default(); 4463 4464 let vps_nalu = Nalu::<NaluHeader>::next(&mut cursor).unwrap(); 4465 let vps = parser.parse_vps(&vps_nalu).unwrap(); 4466 assert!(vps.base_layer_internal_flag); 4467 assert!(vps.base_layer_available_flag); 4468 assert_eq!(vps.max_layers_minus1, 0); 4469 assert_eq!(vps.max_sub_layers_minus1, 0); 4470 assert!(vps.temporal_id_nesting_flag); 4471 assert_eq!(vps.profile_tier_level.general_profile_space, 0); 4472 assert!(!vps.profile_tier_level.general_tier_flag); 4473 assert_eq!(vps.profile_tier_level.general_profile_idc, 1); 4474 for i in 0..32 { 4475 let val = i == 1 || i == 2; 4476 assert_eq!(vps.profile_tier_level.general_profile_compatibility_flag[i], val); 4477 } 4478 assert!(vps.profile_tier_level.general_progressive_source_flag); 4479 assert!(!vps.profile_tier_level.general_interlaced_source_flag); 4480 assert!(!vps.profile_tier_level.general_non_packed_constraint_flag,); 4481 assert!(vps.profile_tier_level.general_frame_only_constraint_flag,); 4482 assert!(!vps.profile_tier_level.general_max_12bit_constraint_flag,); 4483 assert!(!vps.profile_tier_level.general_max_10bit_constraint_flag,); 4484 assert!(!vps.profile_tier_level.general_max_8bit_constraint_flag,); 4485 assert!(!vps.profile_tier_level.general_max_422chroma_constraint_flag,); 4486 assert!(!vps.profile_tier_level.general_max_420chroma_constraint_flag,); 4487 assert!(!vps.profile_tier_level.general_max_monochrome_constraint_flag,); 4488 assert!(!vps.profile_tier_level.general_intra_constraint_flag); 4489 assert!(!vps.profile_tier_level.general_one_picture_only_constraint_flag,); 4490 assert!(!vps.profile_tier_level.general_lower_bit_rate_constraint_flag,); 4491 assert!(!vps.profile_tier_level.general_max_14bit_constraint_flag,); 4492 assert_eq!(vps.profile_tier_level.general_level_idc, Level::L2); 4493 4494 assert!(vps.sub_layer_ordering_info_present_flag); 4495 assert_eq!(vps.max_dec_pic_buffering_minus1[0], 4); 4496 assert_eq!(vps.max_num_reorder_pics[0], 2); 4497 assert_eq!(vps.max_latency_increase_plus1[0], 5); 4498 for i in 1..7 { 4499 assert_eq!(vps.max_dec_pic_buffering_minus1[i], 0); 4500 assert_eq!(vps.max_num_reorder_pics[i], 0); 4501 assert_eq!(vps.max_latency_increase_plus1[i], 0); 4502 } 4503 4504 assert_eq!(vps.max_layer_id, 0); 4505 assert_eq!(vps.num_layer_sets_minus1, 0); 4506 assert!(!vps.timing_info_present_flag); 4507 assert_eq!(vps.num_units_in_tick, 0); 4508 assert_eq!(vps.time_scale, 0); 4509 assert!(!vps.poc_proportional_to_timing_flag); 4510 assert_eq!(vps.num_ticks_poc_diff_one_minus1, 0); 4511 assert_eq!(vps.num_hrd_parameters, 0); 4512 } 4513 4514 /// A custom test for SPS parsing with data manually extracted from 4515 /// GStreamer using GDB. 4516 #[test] test25fps_sps_header_parsing()4517 fn test25fps_sps_header_parsing() { 4518 let mut parser = Parser::default(); 4519 4520 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap(); 4521 let sps = parser.parse_sps(&sps_nalu).unwrap(); 4522 4523 assert_eq!(sps.max_sub_layers_minus1, 0); 4524 4525 assert_eq!(sps.profile_tier_level.general_profile_space, 0); 4526 assert!(!sps.profile_tier_level.general_tier_flag); 4527 assert_eq!(sps.profile_tier_level.general_profile_idc, 1); 4528 for i in 0..32 { 4529 let val = i == 1 || i == 2; 4530 assert_eq!(sps.profile_tier_level.general_profile_compatibility_flag[i], val); 4531 } 4532 assert!(sps.profile_tier_level.general_progressive_source_flag); 4533 assert!(!sps.profile_tier_level.general_interlaced_source_flag); 4534 assert!(!sps.profile_tier_level.general_non_packed_constraint_flag,); 4535 assert!(sps.profile_tier_level.general_frame_only_constraint_flag,); 4536 assert!(!sps.profile_tier_level.general_max_12bit_constraint_flag,); 4537 assert!(!sps.profile_tier_level.general_max_10bit_constraint_flag,); 4538 assert!(!sps.profile_tier_level.general_max_8bit_constraint_flag,); 4539 assert!(!sps.profile_tier_level.general_max_422chroma_constraint_flag,); 4540 assert!(!sps.profile_tier_level.general_max_420chroma_constraint_flag,); 4541 assert!(!sps.profile_tier_level.general_max_monochrome_constraint_flag,); 4542 assert!(!sps.profile_tier_level.general_intra_constraint_flag); 4543 assert!(!sps.profile_tier_level.general_one_picture_only_constraint_flag,); 4544 assert!(!sps.profile_tier_level.general_lower_bit_rate_constraint_flag,); 4545 assert!(!sps.profile_tier_level.general_max_14bit_constraint_flag,); 4546 assert_eq!(sps.profile_tier_level.general_level_idc, Level::L2); 4547 4548 assert_eq!(sps.seq_parameter_set_id, 0); 4549 assert_eq!(sps.chroma_format_idc, 1); 4550 assert!(!sps.separate_colour_plane_flag); 4551 assert_eq!(sps.pic_width_in_luma_samples, 320); 4552 assert_eq!(sps.pic_height_in_luma_samples, 240); 4553 assert_eq!(sps.conf_win_left_offset, 0); 4554 assert_eq!(sps.conf_win_right_offset, 0); 4555 assert_eq!(sps.conf_win_top_offset, 0); 4556 assert_eq!(sps.conf_win_bottom_offset, 0); 4557 assert_eq!(sps.bit_depth_luma_minus8, 0); 4558 assert_eq!(sps.bit_depth_chroma_minus8, 0); 4559 assert_eq!(sps.log2_max_pic_order_cnt_lsb_minus4, 4); 4560 assert!(sps.sub_layer_ordering_info_present_flag); 4561 assert_eq!(sps.max_dec_pic_buffering_minus1[0], 4); 4562 assert_eq!(sps.max_num_reorder_pics[0], 2); 4563 assert_eq!(sps.max_latency_increase_plus1[0], 5); 4564 for i in 1..7 { 4565 assert_eq!(sps.max_dec_pic_buffering_minus1[i], 0); 4566 assert_eq!(sps.max_num_reorder_pics[i], 0); 4567 assert_eq!(sps.max_latency_increase_plus1[i], 0); 4568 } 4569 assert_eq!(sps.log2_min_luma_coding_block_size_minus3, 0); 4570 assert_eq!(sps.log2_diff_max_min_luma_coding_block_size, 3); 4571 assert_eq!(sps.log2_min_luma_transform_block_size_minus2, 0); 4572 assert_eq!(sps.log2_diff_max_min_luma_transform_block_size, 3); 4573 assert_eq!(sps.max_transform_hierarchy_depth_inter, 0); 4574 assert_eq!(sps.max_transform_hierarchy_depth_intra, 0); 4575 assert!(!sps.scaling_list_enabled_flag); 4576 assert!(!sps.scaling_list_data_present_flag); 4577 assert!(!sps.amp_enabled_flag); 4578 assert!(sps.sample_adaptive_offset_enabled_flag); 4579 assert!(!sps.pcm_enabled_flag); 4580 assert_eq!(sps.pcm_sample_bit_depth_luma_minus1, 0); 4581 assert_eq!(sps.pcm_sample_bit_depth_chroma_minus1, 0); 4582 assert_eq!(sps.log2_min_pcm_luma_coding_block_size_minus3, 0); 4583 assert_eq!(sps.log2_diff_max_min_pcm_luma_coding_block_size, 0); 4584 assert!(!sps.pcm_loop_filter_disabled_flag); 4585 assert_eq!(sps.num_short_term_ref_pic_sets, 0); 4586 assert_eq!(sps.num_long_term_ref_pics_sps, 0); 4587 assert!(sps.temporal_mvp_enabled_flag); 4588 assert!(sps.strong_intra_smoothing_enabled_flag); 4589 assert_eq!(sps.vui_parameters.sar_width, 0); 4590 assert_eq!(sps.vui_parameters.sar_height, 0); 4591 assert!(!sps.vui_parameters.video_full_range_flag); 4592 assert!(!sps.vui_parameters.colour_description_present_flag); 4593 assert!(sps.vui_parameters.video_signal_type_present_flag); 4594 assert!(sps.vui_parameters.timing_info_present_flag); 4595 assert_eq!(sps.vui_parameters.num_units_in_tick, 1); 4596 assert_eq!(sps.vui_parameters.time_scale, 25); 4597 assert!(!sps.vui_parameters.poc_proportional_to_timing_flag); 4598 assert_eq!(sps.vui_parameters.num_ticks_poc_diff_one_minus1, 0); 4599 assert!(!sps.vui_parameters.hrd_parameters_present_flag); 4600 assert_eq!(sps.vui_parameters.colour_primaries, 2); 4601 assert_eq!(sps.vui_parameters.transfer_characteristics, 2); 4602 assert_eq!(sps.vui_parameters.matrix_coeffs, 2); 4603 assert_eq!(sps.vui_parameters.def_disp_win_left_offset, 0); 4604 assert_eq!(sps.vui_parameters.def_disp_win_right_offset, 0); 4605 assert_eq!(sps.vui_parameters.def_disp_win_top_offset, 0); 4606 assert_eq!(sps.vui_parameters.def_disp_win_bottom_offset, 0); 4607 } 4608 4609 /// A custom test for PPS parsing with data manually extracted from 4610 /// GStreamer using GDB. 4611 #[test] test25fps_pps_header_parsing()4612 fn test25fps_pps_header_parsing() { 4613 let mut parser = Parser::default(); 4614 4615 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap(); 4616 parser.parse_sps(&sps_nalu).unwrap(); 4617 4618 let pps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::PpsNut, 0).unwrap(); 4619 let pps = parser.parse_pps(&pps_nalu).unwrap(); 4620 4621 assert!(!pps.dependent_slice_segments_enabled_flag); 4622 assert!(!pps.output_flag_present_flag); 4623 assert_eq!(pps.num_extra_slice_header_bits, 0); 4624 assert!(pps.sign_data_hiding_enabled_flag); 4625 assert!(!pps.cabac_init_present_flag); 4626 assert_eq!(pps.num_ref_idx_l0_default_active_minus1, 0); 4627 assert_eq!(pps.num_ref_idx_l1_default_active_minus1, 0); 4628 assert_eq!(pps.init_qp_minus26, 0); 4629 assert!(!pps.constrained_intra_pred_flag); 4630 assert!(!pps.transform_skip_enabled_flag); 4631 assert!(pps.cu_qp_delta_enabled_flag); 4632 assert_eq!(pps.diff_cu_qp_delta_depth, 1); 4633 assert_eq!(pps.cb_qp_offset, 0); 4634 assert_eq!(pps.cr_qp_offset, 0); 4635 assert!(!pps.slice_chroma_qp_offsets_present_flag); 4636 assert!(pps.weighted_pred_flag); 4637 assert!(!pps.weighted_bipred_flag); 4638 assert!(!pps.transquant_bypass_enabled_flag); 4639 assert!(!pps.tiles_enabled_flag); 4640 assert!(pps.entropy_coding_sync_enabled_flag); 4641 assert_eq!(pps.num_tile_rows_minus1, 0); 4642 assert_eq!(pps.num_tile_columns_minus1, 0); 4643 assert!(pps.uniform_spacing_flag); 4644 assert_eq!(pps.column_width_minus1, [0; 19]); 4645 assert_eq!(pps.row_height_minus1, [0; 21]); 4646 assert!(pps.loop_filter_across_slices_enabled_flag); 4647 assert!(pps.loop_filter_across_tiles_enabled_flag); 4648 assert!(!pps.deblocking_filter_control_present_flag); 4649 assert!(!pps.deblocking_filter_override_enabled_flag); 4650 assert!(!pps.deblocking_filter_disabled_flag); 4651 assert_eq!(pps.beta_offset_div2, 0); 4652 assert_eq!(pps.tc_offset_div2, 0); 4653 assert!(!pps.lists_modification_present_flag); 4654 assert_eq!(pps.log2_parallel_merge_level_minus2, 0); 4655 assert!(!pps.slice_segment_header_extension_present_flag); 4656 assert!(!pps.extension_present_flag); 4657 } 4658 4659 /// A custom test for slice header parsing with data manually extracted from 4660 /// GStreamer using GDB. 4661 #[test] test25fps_slice_header_parsing()4662 fn test25fps_slice_header_parsing() { 4663 let mut parser = Parser::default(); 4664 4665 // Have to parse the SPS/VPS/PPS to set up the parser's internal state. 4666 let vps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::VpsNut, 0).unwrap(); 4667 parser.parse_vps(&vps_nalu).unwrap(); 4668 4669 let sps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::SpsNut, 0).unwrap(); 4670 parser.parse_sps(&sps_nalu).unwrap(); 4671 4672 let pps_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::PpsNut, 0).unwrap(); 4673 parser.parse_pps(&pps_nalu).unwrap(); 4674 4675 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::IdrNLp, 0).unwrap(); 4676 let slice = parser.parse_slice_header(slice_nalu).unwrap(); 4677 let hdr = &slice.header; 4678 4679 assert!(hdr.first_slice_segment_in_pic_flag); 4680 assert!(!hdr.no_output_of_prior_pics_flag); 4681 assert!(!hdr.dependent_slice_segment_flag); 4682 assert_eq!(hdr.type_, SliceType::I); 4683 assert!(hdr.pic_output_flag); 4684 assert_eq!(hdr.colour_plane_id, 0); 4685 assert_eq!(hdr.pic_order_cnt_lsb, 0); 4686 assert!(!hdr.short_term_ref_pic_set_sps_flag); 4687 assert_eq!(hdr.lt_idx_sps, [0; 16]); 4688 assert_eq!(hdr.poc_lsb_lt, [0; 16]); 4689 assert_eq!(hdr.used_by_curr_pic_lt, [false; 16]); 4690 assert_eq!(hdr.delta_poc_msb_cycle_lt, [0; 16]); 4691 assert_eq!(hdr.delta_poc_msb_present_flag, [false; 16]); 4692 assert!(!hdr.temporal_mvp_enabled_flag); 4693 assert!(hdr.sao_luma_flag); 4694 assert!(hdr.sao_chroma_flag); 4695 assert!(!hdr.num_ref_idx_active_override_flag); 4696 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0); 4697 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0); 4698 assert!(!hdr.cabac_init_flag); 4699 assert!(hdr.collocated_from_l0_flag); 4700 assert_eq!(hdr.five_minus_max_num_merge_cand, 0); 4701 assert!(!hdr.use_integer_mv_flag); 4702 assert_eq!(hdr.qp_delta, 7); 4703 assert_eq!(hdr.cb_qp_offset, 0); 4704 assert_eq!(hdr.cr_qp_offset, 0); 4705 assert!(!hdr.cu_chroma_qp_offset_enabled_flag); 4706 assert!(!hdr.deblocking_filter_override_flag); 4707 assert!(!hdr.deblocking_filter_override_flag); 4708 assert_eq!(hdr.beta_offset_div2, 0); 4709 assert_eq!(hdr.tc_offset_div2, 0); 4710 assert!(hdr.loop_filter_across_slices_enabled_flag); 4711 assert_eq!(hdr.num_entry_point_offsets, 3); 4712 assert_eq!(hdr.offset_len_minus1, 11); 4713 assert_eq!(hdr.num_pic_total_curr, 0); 4714 4715 // Remove the 2 bytes from the NALU header. 4716 assert_eq!(hdr.header_bit_size - 16, 72); 4717 4718 assert_eq!(hdr.n_emulation_prevention_bytes, 0); 4719 4720 assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_0); 4721 4722 // Next slice 4723 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::TrailR, 0).unwrap(); 4724 let slice = parser.parse_slice_header(slice_nalu).unwrap(); 4725 let hdr = &slice.header; 4726 4727 assert!(hdr.first_slice_segment_in_pic_flag); 4728 assert!(!hdr.no_output_of_prior_pics_flag); 4729 assert!(!hdr.dependent_slice_segment_flag); 4730 assert_eq!(hdr.type_, SliceType::P); 4731 assert!(hdr.pic_output_flag); 4732 assert_eq!(hdr.colour_plane_id, 0); 4733 assert_eq!(hdr.pic_order_cnt_lsb, 3); 4734 assert!(!hdr.short_term_ref_pic_set_sps_flag); 4735 assert_eq!(hdr.short_term_ref_pic_set.num_delta_pocs, 1); 4736 assert_eq!(hdr.short_term_ref_pic_set.num_negative_pics, 1); 4737 assert_eq!(hdr.short_term_ref_pic_set.num_positive_pics, 0); 4738 assert!(hdr.short_term_ref_pic_set.used_by_curr_pic_s0[0]); 4739 assert_eq!(hdr.short_term_ref_pic_set.delta_poc_s0[0], -3); 4740 assert_eq!(hdr.lt_idx_sps, [0; 16]); 4741 assert_eq!(hdr.poc_lsb_lt, [0; 16]); 4742 assert_eq!(hdr.used_by_curr_pic_lt, [false; 16]); 4743 assert_eq!(hdr.delta_poc_msb_cycle_lt, [0; 16]); 4744 assert_eq!(hdr.delta_poc_msb_present_flag, [false; 16]); 4745 assert!(hdr.temporal_mvp_enabled_flag); 4746 assert!(hdr.sao_luma_flag); 4747 assert!(hdr.sao_chroma_flag); 4748 assert!(!hdr.num_ref_idx_active_override_flag); 4749 assert_eq!(hdr.num_ref_idx_l0_active_minus1, 0); 4750 assert_eq!(hdr.num_ref_idx_l1_active_minus1, 0); 4751 assert!(!hdr.cabac_init_flag); 4752 assert!(hdr.collocated_from_l0_flag); 4753 assert_eq!(hdr.pred_weight_table.luma_log2_weight_denom, 7); 4754 assert_eq!(hdr.five_minus_max_num_merge_cand, 2); 4755 assert!(!hdr.use_integer_mv_flag); 4756 assert_eq!(hdr.num_entry_point_offsets, 3); 4757 assert_eq!(hdr.qp_delta, 7); 4758 assert_eq!(hdr.cb_qp_offset, 0); 4759 assert_eq!(hdr.cr_qp_offset, 0); 4760 assert!(!hdr.cu_chroma_qp_offset_enabled_flag); 4761 assert!(!hdr.deblocking_filter_override_flag); 4762 assert!(!hdr.deblocking_filter_override_flag); 4763 assert_eq!(hdr.beta_offset_div2, 0); 4764 assert_eq!(hdr.tc_offset_div2, 0); 4765 assert!(!hdr.loop_filter_across_slices_enabled_flag); 4766 assert_eq!(hdr.num_entry_point_offsets, 3); 4767 assert_eq!(hdr.offset_len_minus1, 10); 4768 assert_eq!(hdr.num_pic_total_curr, 1); 4769 4770 assert_eq!(slice.nalu.size, 2983); 4771 // Subtract 2 bytes to account for the header size. 4772 assert_eq!(hdr.header_bit_size - 16, 96); 4773 assert_eq!(slice.nalu.as_ref(), STREAM_TEST_25_FPS_SLICE_1); 4774 4775 // Next slice 4776 let slice_nalu = find_nalu_by_type(STREAM_TEST25FPS, NaluType::TrailR, 1).unwrap(); 4777 let slice = parser.parse_slice_header(slice_nalu).unwrap(); 4778 let hdr = &slice.header; 4779 4780 assert_eq!(slice.nalu.size, 290); 4781 // Subtract 2 bytes to account for the header size. 4782 assert_eq!(hdr.header_bit_size - 16, 80); 4783 } 4784 } 4785