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