1use std::io;
2
3use byteorder::ReadBytesExt;
4use scuffle_bytes_util::{BitReader, range_check};
5use scuffle_expgolomb::BitReaderExpGolombExt;
6
7#[derive(Debug, Clone, PartialEq)]
14pub struct HrdParameters {
15 pub common_inf: CommonInf,
17 pub sub_layers: Vec<HrdParametersSubLayer>,
19}
20
21impl HrdParameters {
22 pub(crate) fn parse<R: io::Read>(
23 bit_reader: &mut BitReader<R>,
24 common_inf_present_flag: bool,
25 max_num_sub_layers_minus1: u8,
26 ) -> io::Result<Self> {
27 let mut common_inf = CommonInf::default();
28
29 let mut nal_hrd_parameters_present_flag = false;
30 let mut vcl_hrd_parameters_present_flag = false;
31
32 if common_inf_present_flag {
33 nal_hrd_parameters_present_flag = bit_reader.read_bit()?;
34 vcl_hrd_parameters_present_flag = bit_reader.read_bit()?;
35
36 if nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag {
37 let sub_pic_hrd_params_present_flag = bit_reader.read_bit()?;
38 if sub_pic_hrd_params_present_flag {
39 let tick_divisor_minus2 = bit_reader.read_u8()?;
40 let du_cpb_removal_delay_increment_length_minus1 = bit_reader.read_bits(5)? as u8;
41 let sub_pic_cpb_params_in_pic_timing_sei_flag = bit_reader.read_bit()?;
42 let dpb_output_delay_du_length_minus1 = bit_reader.read_bits(5)? as u8;
43
44 common_inf.sub_pic_hrd_params = Some(SubPicHrdParams {
45 tick_divisor_minus2,
46 du_cpb_removal_delay_increment_length_minus1,
47 sub_pic_cpb_params_in_pic_timing_sei_flag,
48 dpb_output_delay_du_length_minus1,
49 cpb_size_du_scale: 0, });
51 }
52
53 common_inf.bit_rate_scale = Some(bit_reader.read_bits(4)? as u8);
54 common_inf.cpb_size_scale = Some(bit_reader.read_bits(4)? as u8);
55
56 if sub_pic_hrd_params_present_flag {
57 let cpb_size_du_scale = bit_reader.read_bits(4)? as u8;
58
59 if let Some(ref mut sub_pic_hrd_params) = common_inf.sub_pic_hrd_params {
61 sub_pic_hrd_params.cpb_size_du_scale = cpb_size_du_scale;
62 }
63 }
64
65 common_inf.initial_cpb_removal_delay_length_minus1 = bit_reader.read_bits(5)? as u8;
66 common_inf.au_cpb_removal_delay_length_minus1 = bit_reader.read_bits(5)? as u8;
67 common_inf.dpb_output_delay_length_minus1 = bit_reader.read_bits(5)? as u8;
68 }
69 }
70
71 let mut sub_layers = Vec::with_capacity(max_num_sub_layers_minus1 as usize + 1);
72
73 for _ in 0..=max_num_sub_layers_minus1 {
74 sub_layers.push(HrdParametersSubLayer::parse(
75 bit_reader,
76 common_inf.sub_pic_hrd_params.is_some(),
77 nal_hrd_parameters_present_flag,
78 vcl_hrd_parameters_present_flag,
79 )?);
80 }
81
82 Ok(HrdParameters { common_inf, sub_layers })
83 }
84}
85
86#[derive(Debug, Clone, PartialEq)]
88pub struct CommonInf {
89 pub sub_pic_hrd_params: Option<SubPicHrdParams>,
91 pub bit_rate_scale: Option<u8>,
94 pub cpb_size_scale: Option<u8>,
97 pub initial_cpb_removal_delay_length_minus1: u8,
101 pub au_cpb_removal_delay_length_minus1: u8,
105 pub dpb_output_delay_length_minus1: u8,
109}
110
111impl Default for CommonInf {
112 fn default() -> Self {
113 Self {
114 sub_pic_hrd_params: None,
115 bit_rate_scale: None,
116 cpb_size_scale: None,
117 initial_cpb_removal_delay_length_minus1: 23,
118 au_cpb_removal_delay_length_minus1: 23,
119 dpb_output_delay_length_minus1: 23,
120 }
121 }
122}
123
124#[derive(Debug, Clone, PartialEq)]
126pub struct SubPicHrdParams {
127 pub tick_divisor_minus2: u8,
130 pub du_cpb_removal_delay_increment_length_minus1: u8,
135 pub sub_pic_cpb_params_in_pic_timing_sei_flag: bool,
143 pub dpb_output_delay_du_length_minus1: u8,
147 pub cpb_size_du_scale: u8,
150}
151
152#[derive(Debug, Clone, PartialEq)]
154pub struct HrdParametersSubLayer {
155 pub fixed_pic_rate_general_flag: bool,
160 pub fixed_pic_rate_within_cvs_flag: bool,
165 pub elemental_duration_in_tc_minus1: Option<u64>,
171 pub low_delay_hrd_flag: bool,
174 pub cpb_cnt_minus1: u64,
179 pub sub_layer_parameters: Vec<SubLayerHrdParameters>,
181}
182
183impl HrdParametersSubLayer {
184 fn parse(
185 bit_reader: &mut BitReader<impl io::Read>,
186 sub_pic_hrd_params_present_flag: bool,
187 nal_hrd_parameters_present_flag: bool,
188 vcl_hrd_parameters_present_flag: bool,
189 ) -> io::Result<Self> {
190 let mut fixed_pic_rate_within_cvs_flag = true;
191
192 let fixed_pic_rate_general_flag = bit_reader.read_bit()?;
193 if !fixed_pic_rate_general_flag {
194 fixed_pic_rate_within_cvs_flag = bit_reader.read_bit()?;
195 }
196
197 let mut elemental_duration_in_tc_minus1_value = None;
198 let mut low_delay_hrd_flag = false;
199 if fixed_pic_rate_within_cvs_flag {
200 let elemental_duration_in_tc_minus1 = bit_reader.read_exp_golomb()?;
201 range_check!(elemental_duration_in_tc_minus1, 0, 2047)?;
202 elemental_duration_in_tc_minus1_value = Some(elemental_duration_in_tc_minus1);
203 } else {
204 low_delay_hrd_flag = bit_reader.read_bit()?;
205 }
206
207 let mut cpb_cnt_minus1 = 0;
208 if !low_delay_hrd_flag {
209 cpb_cnt_minus1 = bit_reader.read_exp_golomb()?;
210 range_check!(cpb_cnt_minus1, 0, 31)?;
211 }
212
213 let mut sub_layer_parameters = Vec::new();
214
215 if nal_hrd_parameters_present_flag {
216 sub_layer_parameters.append(&mut SubLayerHrdParameters::parse(
217 bit_reader,
218 true,
219 cpb_cnt_minus1 + 1,
220 sub_pic_hrd_params_present_flag,
221 )?);
222 }
223
224 if vcl_hrd_parameters_present_flag {
225 sub_layer_parameters.append(&mut SubLayerHrdParameters::parse(
226 bit_reader,
227 false,
228 cpb_cnt_minus1 + 1,
229 sub_pic_hrd_params_present_flag,
230 )?);
231 }
232
233 Ok(Self {
234 fixed_pic_rate_general_flag,
235 fixed_pic_rate_within_cvs_flag,
236 elemental_duration_in_tc_minus1: elemental_duration_in_tc_minus1_value,
237 low_delay_hrd_flag,
238 cpb_cnt_minus1,
239 sub_layer_parameters,
240 })
241 }
242}
243
244#[derive(Debug, Clone, PartialEq)]
251pub struct SubLayerHrdParameters {
252 nal_hrd: bool,
254 pub bit_rate_value_minus1: u32,
263 pub cpb_size_value_minus1: u32,
272 pub cpb_size_du_value_minus1: Option<u64>,
281 pub bit_rate_du_value_minus1: Option<u64>,
290 pub cbr_flag: bool,
295}
296
297impl SubLayerHrdParameters {
298 fn parse<R: io::Read>(
299 bit_reader: &mut BitReader<R>,
300 nal_hrd: bool,
301 cpb_cnt: u64,
302 sub_pic_hrd_params_present_flag: bool,
303 ) -> io::Result<Vec<Self>> {
304 let mut parameters: Vec<Self> = Vec::with_capacity(cpb_cnt as usize);
305
306 for i in 0..cpb_cnt as usize {
307 let bit_rate_value_minus1 = bit_reader.read_exp_golomb()?;
308 range_check!(bit_rate_value_minus1, 0, 2u64.pow(32) - 2)?;
309 let bit_rate_value_minus1 = bit_rate_value_minus1 as u32;
310 if i > 0 && bit_rate_value_minus1 <= parameters[i - 1].bit_rate_value_minus1 {
311 return Err(io::Error::new(
312 io::ErrorKind::InvalidData,
313 "bit_rate_value_minus1 must be greater than the previous value",
314 ));
315 }
316
317 let cpb_size_value_minus1 = bit_reader.read_exp_golomb()?;
318 range_check!(cpb_size_value_minus1, 0, 2u64.pow(32) - 2)?;
319 let cpb_size_value_minus1 = cpb_size_value_minus1 as u32;
320 if i > 0 && cpb_size_value_minus1 > parameters[i - 1].cpb_size_value_minus1 {
321 return Err(io::Error::new(
322 io::ErrorKind::InvalidData,
323 "cpb_size_value_minus1 must be less than or equal to the previous value",
324 ));
325 }
326
327 let mut cpb_size_du_value_minus1 = None;
328 let mut bit_rate_du_value_minus1 = None;
329 if sub_pic_hrd_params_present_flag {
330 cpb_size_du_value_minus1 = Some(bit_reader.read_exp_golomb()?);
331 bit_rate_du_value_minus1 = Some(bit_reader.read_exp_golomb()?);
332 }
333
334 let cbr_flag = bit_reader.read_bit()?;
335
336 parameters.push(Self {
337 nal_hrd,
338 bit_rate_value_minus1,
339 cpb_size_value_minus1,
340 cpb_size_du_value_minus1,
341 bit_rate_du_value_minus1,
342 cbr_flag,
343 });
344 }
345
346 Ok(parameters)
347 }
348
349 pub fn bit_rate(
360 &self,
361 sub_pic_hrd_flag: bool,
362 bit_rate_scale: u8,
363 br_vcl_factor: u64,
364 br_nal_factor: u64,
365 max_br: u64,
366 ) -> u64 {
367 let value = if !sub_pic_hrd_flag {
368 self.bit_rate_value_minus1 as u64
369 } else {
370 self.bit_rate_du_value_minus1.unwrap_or_else(|| {
371 if self.nal_hrd {
372 br_nal_factor * max_br
373 } else {
374 br_vcl_factor * max_br
375 }
376 })
377 };
378 (value + 1) * 2u64.pow(6 + bit_rate_scale as u32)
379 }
380
381 pub fn cpb_size(
392 &self,
393 sub_pic_hrd_flag: bool,
394 cpb_size_scale: u8,
395 cpb_vcl_factor: u64,
396 cpb_nal_factor: u64,
397 max_cpb: u64,
398 ) -> u64 {
399 let value = if !sub_pic_hrd_flag {
400 self.bit_rate_value_minus1 as u64
401 } else {
402 self.bit_rate_du_value_minus1.unwrap_or_else(|| {
403 if self.nal_hrd {
404 cpb_nal_factor * max_cpb
405 } else {
406 cpb_vcl_factor * max_cpb
407 }
408 })
409 };
410 (value + 1) * 2u64.pow(4 + cpb_size_scale as u32)
411 }
412}
413
414#[cfg(test)]
415#[cfg_attr(all(test, coverage_nightly), coverage(off))]
416mod tests {
417 use byteorder::WriteBytesExt;
418 use scuffle_bytes_util::{BitReader, BitWriter};
419 use scuffle_expgolomb::BitWriterExpGolombExt;
420
421 use super::HrdParameters;
422
423 #[test]
424 fn test_parse() {
425 let mut data = Vec::new();
426 let mut bit_writer = BitWriter::new(&mut data);
427
428 bit_writer.write_bit(true).unwrap(); bit_writer.write_bit(true).unwrap(); bit_writer.write_bit(false).unwrap(); bit_writer.write_bits(0, 4).unwrap(); bit_writer.write_bits(0, 4).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bit(true).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_bit(false).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_bit(false).unwrap(); bit_writer.write_bits(0, 8).unwrap(); let mut bit_reader = BitReader::new(&data[..]);
458 let hrd_parameters = HrdParameters::parse(&mut bit_reader, true, 0).unwrap();
459 assert_eq!(hrd_parameters.common_inf.bit_rate_scale, Some(0));
460 assert_eq!(hrd_parameters.common_inf.cpb_size_scale, Some(0));
461 assert_eq!(hrd_parameters.common_inf.initial_cpb_removal_delay_length_minus1, 0);
462 assert_eq!(hrd_parameters.common_inf.au_cpb_removal_delay_length_minus1, 0);
463 assert_eq!(hrd_parameters.common_inf.dpb_output_delay_length_minus1, 0);
464 assert_eq!(hrd_parameters.sub_layers.len(), 1);
465 assert!(hrd_parameters.sub_layers[0].fixed_pic_rate_general_flag);
466 assert!(hrd_parameters.sub_layers[0].fixed_pic_rate_within_cvs_flag);
467 assert_eq!(hrd_parameters.sub_layers[0].elemental_duration_in_tc_minus1, Some(0));
468 assert!(!hrd_parameters.sub_layers[0].low_delay_hrd_flag);
469 assert_eq!(hrd_parameters.sub_layers[0].cpb_cnt_minus1, 0);
470 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters.len(), 2);
471 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate_value_minus1, 0);
472 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size_value_minus1, 0);
473 assert_eq!(
474 hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size_du_value_minus1,
475 None
476 );
477 assert_eq!(
478 hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate_du_value_minus1,
479 None
480 );
481 assert!(!hrd_parameters.sub_layers[0].sub_layer_parameters[0].cbr_flag);
482 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate_value_minus1, 0);
483 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size_value_minus1, 0);
484 assert_eq!(
485 hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size_du_value_minus1,
486 None
487 );
488 assert_eq!(
489 hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate_du_value_minus1,
490 None
491 );
492 assert!(!hrd_parameters.sub_layers[0].sub_layer_parameters[1].cbr_flag);
493
494 assert_eq!(
495 hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate(false, 0, 0, 0, 0),
496 64
497 );
498 assert_eq!(
499 hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate(true, 0, 0, 0, 0),
500 64
501 );
502 assert_eq!(
503 hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate(false, 0, 0, 0, 0),
504 64
505 );
506 assert_eq!(
507 hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate(true, 0, 0, 0, 0),
508 64
509 );
510
511 assert_eq!(
512 hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size(false, 0, 0, 0, 0),
513 16
514 );
515 assert_eq!(
516 hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size(true, 0, 0, 0, 0),
517 16
518 );
519 assert_eq!(
520 hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size(false, 0, 0, 0, 0),
521 16
522 );
523 assert_eq!(
524 hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size(true, 0, 0, 0, 0),
525 16
526 );
527 }
528
529 #[test]
530 fn test_parse_sub_pic_hrd_params_present_flag() {
531 let mut data = Vec::new();
532 let mut bit_writer = BitWriter::new(&mut data);
533
534 bit_writer.write_bit(true).unwrap(); bit_writer.write_bit(true).unwrap(); bit_writer.write_bit(true).unwrap(); bit_writer.write_u8(42).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bit(false).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bits(0, 4).unwrap(); bit_writer.write_bits(0, 4).unwrap(); bit_writer.write_bits(0, 4).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bits(0, 5).unwrap(); bit_writer.write_bit(true).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_bit(false).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_exp_golomb(0).unwrap(); bit_writer.write_bit(false).unwrap(); bit_writer.write_bits(0, 8).unwrap(); let mut bit_reader = BitReader::new(&data[..]);
573 let hrd_parameters = HrdParameters::parse(&mut bit_reader, true, 0).unwrap();
574 assert_eq!(hrd_parameters.common_inf.bit_rate_scale, Some(0));
575 assert_eq!(hrd_parameters.common_inf.cpb_size_scale, Some(0));
576 assert_eq!(hrd_parameters.common_inf.initial_cpb_removal_delay_length_minus1, 0);
577 assert_eq!(hrd_parameters.common_inf.au_cpb_removal_delay_length_minus1, 0);
578 assert_eq!(hrd_parameters.common_inf.dpb_output_delay_length_minus1, 0);
579 assert!(hrd_parameters.common_inf.sub_pic_hrd_params.is_some());
580 assert_eq!(hrd_parameters.sub_layers.len(), 1);
581 assert!(hrd_parameters.sub_layers[0].fixed_pic_rate_general_flag);
582 assert!(hrd_parameters.sub_layers[0].fixed_pic_rate_within_cvs_flag);
583 assert_eq!(hrd_parameters.sub_layers[0].elemental_duration_in_tc_minus1, Some(0));
584 assert!(!hrd_parameters.sub_layers[0].low_delay_hrd_flag);
585 assert_eq!(hrd_parameters.sub_layers[0].cpb_cnt_minus1, 0);
586 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters.len(), 2);
587 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate_value_minus1, 0);
588 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size_value_minus1, 0);
589 assert_eq!(
590 hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size_du_value_minus1,
591 Some(0)
592 );
593 assert_eq!(
594 hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate_du_value_minus1,
595 Some(0)
596 );
597 assert!(!hrd_parameters.sub_layers[0].sub_layer_parameters[0].cbr_flag);
598 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate_value_minus1, 0);
599 assert_eq!(hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size_value_minus1, 0);
600 assert_eq!(
601 hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size_du_value_minus1,
602 Some(0)
603 );
604 assert_eq!(
605 hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate_du_value_minus1,
606 Some(0)
607 );
608 assert!(!hrd_parameters.sub_layers[0].sub_layer_parameters[1].cbr_flag);
609
610 assert_eq!(
611 hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate(false, 0, 0, 0, 0),
612 64
613 );
614 assert_eq!(
615 hrd_parameters.sub_layers[0].sub_layer_parameters[0].bit_rate(true, 0, 0, 0, 0),
616 64
617 );
618 assert_eq!(
619 hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate(false, 0, 0, 0, 0),
620 64
621 );
622 assert_eq!(
623 hrd_parameters.sub_layers[0].sub_layer_parameters[1].bit_rate(true, 0, 0, 0, 0),
624 64
625 );
626
627 assert_eq!(
628 hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size(false, 0, 0, 0, 0),
629 16
630 );
631 assert_eq!(
632 hrd_parameters.sub_layers[0].sub_layer_parameters[0].cpb_size(true, 0, 0, 0, 0),
633 16
634 );
635 assert_eq!(
636 hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size(false, 0, 0, 0, 0),
637 16
638 );
639 assert_eq!(
640 hrd_parameters.sub_layers[0].sub_layer_parameters[1].cpb_size(true, 0, 0, 0, 0),
641 16
642 );
643 }
644}