1use std::io;
4
5use byteorder::{BigEndian, ReadBytesExt};
6use scuffle_bytes_util::BitReader;
7
8use super::ObuHeader;
9use crate::obu::utils::read_uvlc;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct SequenceHeaderObu {
16 pub header: ObuHeader,
18 pub seq_profile: u8,
22 pub still_picture: bool,
26 pub reduced_still_picture_header: bool,
30 pub timing_info: Option<TimingInfo>,
32 pub decoder_model_info: Option<DecoderModelInfo>,
37 pub operating_points: Vec<OperatingPoint>,
39 pub max_frame_width: u64,
41 pub max_frame_height: u64,
43 pub frame_ids: Option<FrameIds>,
45 pub use_128x128_superblock: bool,
49 pub enable_filter_intra: bool,
53 pub enable_intra_edge_filter: bool,
57 pub enable_interintra_compound: bool,
61 pub enable_masked_compound: bool,
65 pub enable_warped_motion: bool,
69 pub enable_dual_filter: bool,
73 pub enable_order_hint: bool,
77 pub enable_jnt_comp: bool,
81 pub enable_ref_frame_mvs: bool,
85 pub seq_force_screen_content_tools: u8,
87 pub seq_force_integer_mv: u8,
89 pub order_hint_bits: u8,
93 pub enable_superres: bool,
97 pub enable_cdef: bool,
101 pub enable_restoration: bool,
105 pub color_config: ColorConfig,
107 pub film_grain_params_present: bool,
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Copy)]
115pub struct FrameIds {
116 pub delta_frame_id_length: u8,
120 pub additional_frame_id_length: u8,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq, Copy)]
130pub struct OperatingPoint {
131 pub idc: u16,
135 pub seq_level_idx: u8,
139 pub seq_tier: bool,
143 pub operating_parameters_info: Option<OperatingParametersInfo>,
145 pub initial_display_delay: Option<u8>,
149}
150
151#[derive(Debug, Clone, PartialEq, Eq, Copy)]
155pub struct TimingInfo {
156 pub num_units_in_display_tick: u32,
160 pub time_scale: u32,
164 pub num_ticks_per_picture: Option<u64>,
168}
169
170impl TimingInfo {
171 pub fn parse(bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
173 let num_units_in_display_tick = bit_reader.read_u32::<BigEndian>()?;
174 let time_scale = bit_reader.read_u32::<BigEndian>()?;
175 let num_ticks_per_picture = if bit_reader.read_bit()? {
176 Some(read_uvlc(bit_reader)? + 1)
177 } else {
178 None
179 };
180 Ok(Self {
181 num_units_in_display_tick,
182 time_scale,
183 num_ticks_per_picture,
184 })
185 }
186}
187
188#[derive(Debug, Clone, PartialEq, Eq, Copy)]
192pub struct DecoderModelInfo {
193 pub buffer_delay_length: u8,
197 pub num_units_in_decoding_tick: u32,
201 pub buffer_removal_time_length: u8,
205 pub frame_presentation_time_length: u8,
209}
210
211impl DecoderModelInfo {
212 pub fn parse(bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
214 let buffer_delay_length = bit_reader.read_bits(5)? as u8 + 1;
215 let num_units_in_decoding_tick = bit_reader.read_u32::<BigEndian>()?;
216 let buffer_removal_time_length = bit_reader.read_bits(5)? as u8 + 1;
217 let frame_presentation_time_length = bit_reader.read_bits(5)? as u8 + 1;
218 Ok(Self {
219 buffer_delay_length,
220 num_units_in_decoding_tick,
221 buffer_removal_time_length,
222 frame_presentation_time_length,
223 })
224 }
225}
226
227#[derive(Debug, Clone, PartialEq, Eq, Copy)]
231pub struct OperatingParametersInfo {
232 pub decoder_buffer_delay: u64,
234 pub encoder_buffer_delay: u64,
236 pub low_delay_mode_flag: bool,
240}
241
242impl OperatingParametersInfo {
243 pub fn parse(delay_bit_length: u8, bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
245 let decoder_buffer_delay = bit_reader.read_bits(delay_bit_length)?;
246 let encoder_buffer_delay = bit_reader.read_bits(delay_bit_length)?;
247 let low_delay_mode_flag = bit_reader.read_bit()?;
248
249 Ok(Self {
250 decoder_buffer_delay,
251 encoder_buffer_delay,
252 low_delay_mode_flag,
253 })
254 }
255}
256
257#[derive(Debug, Clone, PartialEq, Eq, Copy)]
261pub struct ColorConfig {
262 pub bit_depth: i32,
264 pub mono_chrome: bool,
268 pub num_planes: u8,
270 pub color_primaries: u8,
274 pub transfer_characteristics: u8,
278 pub matrix_coefficients: u8,
282 pub full_color_range: bool,
286 pub subsampling_x: bool,
290 pub subsampling_y: bool,
294 pub chroma_sample_position: u8,
298 pub separate_uv_delta_q: bool,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Copy)]
305struct ColorRangeAndSubsampling {
306 color_range: bool,
307 subsampling_x: bool,
308 subsampling_y: bool,
309}
310
311impl ColorConfig {
312 fn parse_color_range_and_subsampling(
313 bit_reader: &mut BitReader<impl io::Read>,
314 seq_profile: u8,
315 color_primaries: u8,
316 transfer_characteristics: u8,
317 matrix_coefficients: u8,
318 bit_depth: i32,
319 ) -> io::Result<ColorRangeAndSubsampling> {
320 let color_range;
321 let subsampling_x;
322 let subsampling_y;
323
324 const CP_BT_709: u8 = 1;
325 const TC_SRGB: u8 = 13;
326 const MC_IDENTITY: u8 = 0;
327
328 if color_primaries == CP_BT_709 && transfer_characteristics == TC_SRGB && matrix_coefficients == MC_IDENTITY {
329 color_range = true;
330 subsampling_x = false;
331 subsampling_y = false;
332 } else {
333 color_range = bit_reader.read_bit()?;
334 if seq_profile == 0 {
335 subsampling_x = true;
336 subsampling_y = true;
337 } else if seq_profile == 1 {
338 subsampling_x = false;
339 subsampling_y = false;
340 } else if bit_depth == 12 {
341 subsampling_x = bit_reader.read_bit()?;
342 if subsampling_x {
343 subsampling_y = bit_reader.read_bit()?;
344 } else {
345 subsampling_y = false;
346 }
347 } else {
348 subsampling_x = true;
349 subsampling_y = false;
350 }
351 }
352
353 Ok(ColorRangeAndSubsampling {
354 color_range,
355 subsampling_x,
356 subsampling_y,
357 })
358 }
359
360 pub fn parse(seq_profile: u8, bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
362 let high_bitdepth = bit_reader.read_bit()?;
363 let bit_depth = match (seq_profile, high_bitdepth) {
364 (2, true) if bit_reader.read_bit()? => 12,
365 (_, true) => 10,
366 (_, false) => 8,
367 };
368
369 let mono_chrome = if seq_profile == 1 { false } else { bit_reader.read_bit()? };
370
371 let color_primaries;
372 let transfer_characteristics;
373 let matrix_coefficients;
374
375 let color_description_present_flag = bit_reader.read_bit()?;
376 if color_description_present_flag {
377 color_primaries = bit_reader.read_bits(8)? as u8;
378 transfer_characteristics = bit_reader.read_bits(8)? as u8;
379 matrix_coefficients = bit_reader.read_bits(8)? as u8;
380 } else {
381 color_primaries = 2; transfer_characteristics = 2; matrix_coefficients = 2; }
385
386 let num_planes = if mono_chrome { 1 } else { 3 };
387
388 if mono_chrome {
389 Ok(ColorConfig {
390 bit_depth,
391 color_primaries,
392 transfer_characteristics,
393 matrix_coefficients,
394 full_color_range: bit_reader.read_bit()?,
395 subsampling_x: true,
396 subsampling_y: true,
397 mono_chrome,
398 separate_uv_delta_q: false,
399 chroma_sample_position: 0, num_planes,
401 })
402 } else {
403 let ColorRangeAndSubsampling {
404 color_range,
405 subsampling_x,
406 subsampling_y,
407 } = Self::parse_color_range_and_subsampling(
408 bit_reader,
409 seq_profile,
410 color_primaries,
411 transfer_characteristics,
412 matrix_coefficients,
413 bit_depth,
414 )?;
415
416 let chroma_sample_position = if subsampling_x && subsampling_y {
417 bit_reader.read_bits(2)? as u8
418 } else {
419 0 };
421
422 let separate_uv_delta_q = bit_reader.read_bit()?;
423 Ok(ColorConfig {
424 bit_depth,
425 mono_chrome,
426 color_primaries,
427 transfer_characteristics,
428 matrix_coefficients,
429 full_color_range: color_range,
430 subsampling_x,
431 subsampling_y,
432 chroma_sample_position,
433 separate_uv_delta_q,
434 num_planes,
435 })
436 }
437 }
438}
439
440impl SequenceHeaderObu {
441 pub const fn header(&self) -> &ObuHeader {
443 &self.header
444 }
445
446 pub fn parse(header: ObuHeader, reader: &mut impl io::Read) -> io::Result<Self> {
450 let mut bit_reader = BitReader::new(reader);
451
452 let seq_profile = bit_reader.read_bits(3)? as u8;
453 let still_picture = bit_reader.read_bit()?;
454 let reduced_still_picture_header = bit_reader.read_bit()?;
455
456 if !still_picture && reduced_still_picture_header {
457 return Err(io::Error::new(
458 io::ErrorKind::InvalidData,
459 "reduced_still_picture_header is true but still_picture is false",
460 ));
461 }
462
463 let mut timing_info = None;
464 let mut decoder_model_info = None;
465 let mut operating_points = Vec::new();
466
467 if reduced_still_picture_header {
468 operating_points.push(OperatingPoint {
469 idc: 0,
470 seq_level_idx: bit_reader.read_bits(5)? as u8,
471 seq_tier: false,
472 operating_parameters_info: None,
473 initial_display_delay: None,
474 });
475 } else {
476 let timing_info_present_flag = bit_reader.read_bit()?;
477 if timing_info_present_flag {
478 timing_info = Some(TimingInfo::parse(&mut bit_reader)?);
479
480 let decoder_model_info_present_flag = bit_reader.read_bit()?;
481 if decoder_model_info_present_flag {
482 decoder_model_info = Some(DecoderModelInfo::parse(&mut bit_reader)?);
483 }
484 }
485
486 let initial_display_delay_present_flag = bit_reader.read_bit()?;
487 let operating_points_cnt_minus_1 = bit_reader.read_bits(5)? as u8;
488 for _ in 0..operating_points_cnt_minus_1 + 1 {
489 let idc = bit_reader.read_bits(12)? as u16;
490 let seq_level_idx = bit_reader.read_bits(5)? as u8;
491 let seq_tier = if seq_level_idx > 7 { bit_reader.read_bit()? } else { false };
492 let decoder_model_present_for_this_op = if let Some(decoder_model_info) = decoder_model_info {
493 bit_reader.read_bit()?.then_some(decoder_model_info.buffer_delay_length)
494 } else {
495 None
496 };
497
498 let operating_parameters_info = if let Some(delay_bit_length) = decoder_model_present_for_this_op {
499 Some(OperatingParametersInfo::parse(delay_bit_length, &mut bit_reader)?)
500 } else {
501 None
502 };
503
504 let initial_display_delay = if initial_display_delay_present_flag {
505 if bit_reader.read_bit()? {
506 Some(bit_reader.read_bits(4)? as u8 + 1) } else {
509 None
510 }
511 } else {
512 None
513 };
514
515 operating_points.push(OperatingPoint {
516 idc,
517 seq_level_idx,
518 seq_tier,
519 operating_parameters_info,
520 initial_display_delay,
521 });
522 }
523 }
524
525 let frame_width_bits = bit_reader.read_bits(4)? as u8 + 1;
526 let frame_height_bits = bit_reader.read_bits(4)? as u8 + 1;
527
528 let max_frame_width = bit_reader.read_bits(frame_width_bits)? + 1;
529 let max_frame_height = bit_reader.read_bits(frame_height_bits)? + 1;
530
531 let frame_id_numbers_present_flag = if reduced_still_picture_header {
532 false
533 } else {
534 bit_reader.read_bit()?
535 };
536 let frame_ids = if frame_id_numbers_present_flag {
537 let delta_frame_id_length = bit_reader.read_bits(4)? as u8 + 2;
538 let additional_frame_id_length = bit_reader.read_bits(3)? as u8 + 1;
539 Some(FrameIds {
540 delta_frame_id_length,
541 additional_frame_id_length,
542 })
543 } else {
544 None
545 };
546
547 let use_128x128_superblock = bit_reader.read_bit()?;
548 let enable_filter_intra = bit_reader.read_bit()?;
549 let enable_intra_edge_filter = bit_reader.read_bit()?;
550
551 let enable_interintra_compound;
552 let enable_masked_compound;
553 let enable_warped_motion;
554 let enable_dual_filter;
555 let enable_order_hint;
556 let enable_jnt_comp;
557 let enable_ref_frame_mvs;
558 let order_hint_bits;
559 let seq_force_integer_mv;
560
561 let seq_force_screen_content_tools;
562
563 if !reduced_still_picture_header {
564 enable_interintra_compound = bit_reader.read_bit()?;
565 enable_masked_compound = bit_reader.read_bit()?;
566 enable_warped_motion = bit_reader.read_bit()?;
567 enable_dual_filter = bit_reader.read_bit()?;
568 enable_order_hint = bit_reader.read_bit()?;
569 if enable_order_hint {
570 enable_jnt_comp = bit_reader.read_bit()?;
571 enable_ref_frame_mvs = bit_reader.read_bit()?;
572 } else {
573 enable_jnt_comp = false;
574 enable_ref_frame_mvs = false;
575 }
576 if bit_reader.read_bit()? {
577 seq_force_screen_content_tools = 2; } else {
580 seq_force_screen_content_tools = bit_reader.read_bits(1)? as u8;
581 }
582
583 if seq_force_screen_content_tools == 0 || bit_reader.read_bit()? {
586 seq_force_integer_mv = 2; } else {
588 seq_force_integer_mv = bit_reader.read_bits(1)? as u8;
589 }
590
591 if enable_order_hint {
592 order_hint_bits = bit_reader.read_bits(3)? as u8 + 1;
593 } else {
594 order_hint_bits = 0;
595 }
596 } else {
597 enable_interintra_compound = false;
598 enable_masked_compound = false;
599 enable_warped_motion = false;
600 enable_dual_filter = false;
601 enable_order_hint = false;
602 enable_jnt_comp = false;
603 enable_ref_frame_mvs = false;
604 seq_force_screen_content_tools = 2; seq_force_integer_mv = 2; order_hint_bits = 0;
607 }
608
609 let enable_superres = bit_reader.read_bit()?;
610 let enable_cdef = bit_reader.read_bit()?;
611 let enable_restoration = bit_reader.read_bit()?;
612
613 let color_config = ColorConfig::parse(seq_profile, &mut bit_reader)?;
614
615 let film_grain_params_present = bit_reader.read_bit()?;
616
617 Ok(Self {
618 header,
619 seq_profile,
620 still_picture,
621 reduced_still_picture_header,
622 operating_points,
623 decoder_model_info,
624 max_frame_width,
625 max_frame_height,
626 frame_ids,
627 use_128x128_superblock,
628 enable_filter_intra,
629 enable_intra_edge_filter,
630 enable_interintra_compound,
631 enable_masked_compound,
632 enable_warped_motion,
633 enable_dual_filter,
634 enable_order_hint,
635 enable_jnt_comp,
636 enable_ref_frame_mvs,
637 seq_force_screen_content_tools,
638 seq_force_integer_mv,
639 order_hint_bits,
640 enable_superres,
641 enable_cdef,
642 enable_restoration,
643 timing_info,
644 color_config,
645 film_grain_params_present,
646 })
647 }
648}
649
650#[cfg(test)]
651#[cfg_attr(all(coverage_nightly, test), coverage(off))]
652mod tests {
653 use byteorder::WriteBytesExt;
654 use scuffle_bytes_util::BitWriter;
655
656 use super::*;
657 use crate::ObuType;
658
659 #[test]
660 fn test_seq_obu_parse() {
661 let obu = b"\0\0\0j\xef\xbf\xe1\xbc\x02\x19\x90\x10\x10\x10@";
662
663 let header = ObuHeader {
664 obu_type: ObuType::SequenceHeader,
665 size: None,
666 extension_header: None,
667 };
668
669 let seq_header = SequenceHeaderObu::parse(header, &mut io::Cursor::new(obu)).unwrap();
670
671 insta::assert_debug_snapshot!(seq_header, @r"
672 SequenceHeaderObu {
673 header: ObuHeader {
674 obu_type: SequenceHeader,
675 size: None,
676 extension_header: None,
677 },
678 seq_profile: 0,
679 still_picture: false,
680 reduced_still_picture_header: false,
681 timing_info: None,
682 decoder_model_info: None,
683 operating_points: [
684 OperatingPoint {
685 idc: 0,
686 seq_level_idx: 13,
687 seq_tier: false,
688 operating_parameters_info: None,
689 initial_display_delay: None,
690 },
691 ],
692 max_frame_width: 3840,
693 max_frame_height: 2160,
694 frame_ids: None,
695 use_128x128_superblock: false,
696 enable_filter_intra: false,
697 enable_intra_edge_filter: false,
698 enable_interintra_compound: false,
699 enable_masked_compound: false,
700 enable_warped_motion: false,
701 enable_dual_filter: false,
702 enable_order_hint: true,
703 enable_jnt_comp: false,
704 enable_ref_frame_mvs: false,
705 seq_force_screen_content_tools: 0,
706 seq_force_integer_mv: 2,
707 order_hint_bits: 7,
708 enable_superres: false,
709 enable_cdef: true,
710 enable_restoration: true,
711 color_config: ColorConfig {
712 bit_depth: 8,
713 mono_chrome: false,
714 num_planes: 3,
715 color_primaries: 1,
716 transfer_characteristics: 1,
717 matrix_coefficients: 1,
718 full_color_range: false,
719 subsampling_x: true,
720 subsampling_y: true,
721 chroma_sample_position: 0,
722 separate_uv_delta_q: false,
723 },
724 film_grain_params_present: false,
725 }
726 ");
727
728 assert_eq!(seq_header.header(), &header);
729 }
730
731 #[test]
732 fn test_seq_obu_parse_reduced_still_picture() {
733 let mut bits = BitWriter::new(Vec::new());
734
735 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(11, 5).unwrap(); bits.write_bits(15, 4).unwrap();
741 bits.write_bits(15, 4).unwrap();
742 bits.write_bits(1919, 16).unwrap();
743 bits.write_bits(1079, 16).unwrap();
744
745 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
761 ObuHeader {
762 obu_type: ObuType::SequenceHeader,
763 size: None,
764 extension_header: None,
765 },
766 &mut io::Cursor::new(bits.finish().unwrap()),
767 )
768 .unwrap();
769
770 insta::assert_debug_snapshot!(obu_header, @r"
771 SequenceHeaderObu {
772 header: ObuHeader {
773 obu_type: SequenceHeader,
774 size: None,
775 extension_header: None,
776 },
777 seq_profile: 2,
778 still_picture: true,
779 reduced_still_picture_header: true,
780 timing_info: None,
781 decoder_model_info: None,
782 operating_points: [
783 OperatingPoint {
784 idc: 0,
785 seq_level_idx: 11,
786 seq_tier: false,
787 operating_parameters_info: None,
788 initial_display_delay: None,
789 },
790 ],
791 max_frame_width: 1920,
792 max_frame_height: 1080,
793 frame_ids: None,
794 use_128x128_superblock: false,
795 enable_filter_intra: false,
796 enable_intra_edge_filter: false,
797 enable_interintra_compound: false,
798 enable_masked_compound: false,
799 enable_warped_motion: false,
800 enable_dual_filter: false,
801 enable_order_hint: false,
802 enable_jnt_comp: false,
803 enable_ref_frame_mvs: false,
804 seq_force_screen_content_tools: 2,
805 seq_force_integer_mv: 2,
806 order_hint_bits: 0,
807 enable_superres: false,
808 enable_cdef: false,
809 enable_restoration: false,
810 color_config: ColorConfig {
811 bit_depth: 8,
812 mono_chrome: true,
813 num_planes: 1,
814 color_primaries: 2,
815 transfer_characteristics: 2,
816 matrix_coefficients: 2,
817 full_color_range: true,
818 subsampling_x: true,
819 subsampling_y: true,
820 chroma_sample_position: 0,
821 separate_uv_delta_q: false,
822 },
823 film_grain_params_present: true,
824 }
825 ");
826 }
827
828 #[test]
829 fn test_seq_obu_parse_timing_info_decoder_model_preset() {
830 let mut bits = BitWriter::new(Vec::new());
831
832 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0, 5).unwrap(); bits.write_bits(0, 12).unwrap(); bits.write_bits(1, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1010, 5).unwrap(); bits.write_bits(0b0101, 5).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(15, 4).unwrap(); bits.write_bits(15, 4).unwrap(); bits.write_bits(15, 4).unwrap(); bits.write_bits(1919, 16).unwrap(); bits.write_bits(1079, 16).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1101, 4).unwrap(); bits.write_bits(0b101, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap();
883 bits.write_bit(true).unwrap();
884 bits.write_bit(false).unwrap();
885 bits.write_bit(false).unwrap();
886
887 bits.write_bits(0b100, 3).unwrap();
888
889 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
902 ObuHeader {
903 obu_type: ObuType::SequenceHeader,
904 size: None,
905 extension_header: None,
906 },
907 &mut io::Cursor::new(bits.finish().unwrap()),
908 )
909 .unwrap();
910
911 insta::assert_debug_snapshot!(obu_header, @r"
912 SequenceHeaderObu {
913 header: ObuHeader {
914 obu_type: SequenceHeader,
915 size: None,
916 extension_header: None,
917 },
918 seq_profile: 2,
919 still_picture: false,
920 reduced_still_picture_header: false,
921 timing_info: Some(
922 TimingInfo {
923 num_units_in_display_tick: 1,
924 time_scale: 1,
925 num_ticks_per_picture: None,
926 },
927 ),
928 decoder_model_info: Some(
929 DecoderModelInfo {
930 buffer_delay_length: 5,
931 num_units_in_decoding_tick: 1,
932 buffer_removal_time_length: 5,
933 frame_presentation_time_length: 5,
934 },
935 ),
936 operating_points: [
937 OperatingPoint {
938 idc: 0,
939 seq_level_idx: 1,
940 seq_tier: false,
941 operating_parameters_info: Some(
942 OperatingParametersInfo {
943 decoder_buffer_delay: 10,
944 encoder_buffer_delay: 5,
945 low_delay_mode_flag: false,
946 },
947 ),
948 initial_display_delay: Some(
949 16,
950 ),
951 },
952 ],
953 max_frame_width: 1920,
954 max_frame_height: 1080,
955 frame_ids: Some(
956 FrameIds {
957 delta_frame_id_length: 15,
958 additional_frame_id_length: 6,
959 },
960 ),
961 use_128x128_superblock: false,
962 enable_filter_intra: false,
963 enable_intra_edge_filter: false,
964 enable_interintra_compound: false,
965 enable_masked_compound: false,
966 enable_warped_motion: false,
967 enable_dual_filter: false,
968 enable_order_hint: true,
969 enable_jnt_comp: false,
970 enable_ref_frame_mvs: false,
971 seq_force_screen_content_tools: 1,
972 seq_force_integer_mv: 0,
973 order_hint_bits: 5,
974 enable_superres: false,
975 enable_cdef: false,
976 enable_restoration: false,
977 color_config: ColorConfig {
978 bit_depth: 8,
979 mono_chrome: true,
980 num_planes: 1,
981 color_primaries: 2,
982 transfer_characteristics: 2,
983 matrix_coefficients: 2,
984 full_color_range: true,
985 subsampling_x: true,
986 subsampling_y: true,
987 chroma_sample_position: 0,
988 separate_uv_delta_q: false,
989 },
990 film_grain_params_present: true,
991 }
992 ");
993 }
994
995 #[test]
996 fn test_seq_obu_parse_num_ticks_per_picture() {
997 let mut bits = BitWriter::new(Vec::new());
998
999 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b01, 1).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0, 5).unwrap(); bits.write_bits(0, 12).unwrap(); bits.write_bits(1, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1010, 5).unwrap(); bits.write_bits(0b0101, 5).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(15, 4).unwrap(); bits.write_bits(15, 4).unwrap(); bits.write_bits(15, 4).unwrap(); bits.write_bits(1919, 16).unwrap(); bits.write_bits(1079, 16).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1101, 4).unwrap(); bits.write_bits(0b101, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap();
1051 bits.write_bit(true).unwrap();
1052 bits.write_bit(false).unwrap();
1053 bits.write_bit(false).unwrap();
1054
1055 bits.write_bits(0b100, 3).unwrap();
1056
1057 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1070 ObuHeader {
1071 obu_type: ObuType::SequenceHeader,
1072 size: None,
1073 extension_header: None,
1074 },
1075 &mut io::Cursor::new(bits.finish().unwrap()),
1076 )
1077 .unwrap();
1078
1079 insta::assert_debug_snapshot!(obu_header, @r"
1080 SequenceHeaderObu {
1081 header: ObuHeader {
1082 obu_type: SequenceHeader,
1083 size: None,
1084 extension_header: None,
1085 },
1086 seq_profile: 2,
1087 still_picture: false,
1088 reduced_still_picture_header: false,
1089 timing_info: Some(
1090 TimingInfo {
1091 num_units_in_display_tick: 1,
1092 time_scale: 1,
1093 num_ticks_per_picture: Some(
1094 1,
1095 ),
1096 },
1097 ),
1098 decoder_model_info: Some(
1099 DecoderModelInfo {
1100 buffer_delay_length: 5,
1101 num_units_in_decoding_tick: 1,
1102 buffer_removal_time_length: 5,
1103 frame_presentation_time_length: 5,
1104 },
1105 ),
1106 operating_points: [
1107 OperatingPoint {
1108 idc: 0,
1109 seq_level_idx: 1,
1110 seq_tier: false,
1111 operating_parameters_info: Some(
1112 OperatingParametersInfo {
1113 decoder_buffer_delay: 10,
1114 encoder_buffer_delay: 5,
1115 low_delay_mode_flag: false,
1116 },
1117 ),
1118 initial_display_delay: Some(
1119 16,
1120 ),
1121 },
1122 ],
1123 max_frame_width: 1920,
1124 max_frame_height: 1080,
1125 frame_ids: Some(
1126 FrameIds {
1127 delta_frame_id_length: 15,
1128 additional_frame_id_length: 6,
1129 },
1130 ),
1131 use_128x128_superblock: false,
1132 enable_filter_intra: false,
1133 enable_intra_edge_filter: false,
1134 enable_interintra_compound: false,
1135 enable_masked_compound: false,
1136 enable_warped_motion: false,
1137 enable_dual_filter: false,
1138 enable_order_hint: true,
1139 enable_jnt_comp: false,
1140 enable_ref_frame_mvs: false,
1141 seq_force_screen_content_tools: 1,
1142 seq_force_integer_mv: 0,
1143 order_hint_bits: 5,
1144 enable_superres: false,
1145 enable_cdef: false,
1146 enable_restoration: false,
1147 color_config: ColorConfig {
1148 bit_depth: 8,
1149 mono_chrome: true,
1150 num_planes: 1,
1151 color_primaries: 2,
1152 transfer_characteristics: 2,
1153 matrix_coefficients: 2,
1154 full_color_range: true,
1155 subsampling_x: true,
1156 subsampling_y: true,
1157 chroma_sample_position: 0,
1158 separate_uv_delta_q: false,
1159 },
1160 film_grain_params_present: true,
1161 }
1162 ");
1163 }
1164
1165 #[test]
1166 fn test_seq_obu_parse_initial_display_delay_is_none() {
1167 let mut bits = BitWriter::new(Vec::new());
1168
1169 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0, 5).unwrap(); bits.write_bits(0, 12).unwrap(); bits.write_bits(1, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1010, 5).unwrap(); bits.write_bits(0b0101, 5).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bits(11, 4).unwrap(); bits.write_bits(11, 4).unwrap(); bits.write_bits(1919, 12).unwrap(); bits.write_bits(1079, 12).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1101, 4).unwrap(); bits.write_bits(0b101, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap();
1219 bits.write_bit(true).unwrap();
1220 bits.write_bit(false).unwrap();
1221 bits.write_bit(false).unwrap();
1222
1223 bits.write_bits(0b100, 3).unwrap();
1224
1225 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1238 ObuHeader {
1239 obu_type: ObuType::SequenceHeader,
1240 size: None,
1241 extension_header: None,
1242 },
1243 &mut io::Cursor::new(bits.finish().unwrap()),
1244 )
1245 .unwrap();
1246
1247 insta::assert_debug_snapshot!(obu_header, @r"
1248 SequenceHeaderObu {
1249 header: ObuHeader {
1250 obu_type: SequenceHeader,
1251 size: None,
1252 extension_header: None,
1253 },
1254 seq_profile: 2,
1255 still_picture: false,
1256 reduced_still_picture_header: false,
1257 timing_info: Some(
1258 TimingInfo {
1259 num_units_in_display_tick: 1,
1260 time_scale: 1,
1261 num_ticks_per_picture: None,
1262 },
1263 ),
1264 decoder_model_info: Some(
1265 DecoderModelInfo {
1266 buffer_delay_length: 5,
1267 num_units_in_decoding_tick: 1,
1268 buffer_removal_time_length: 5,
1269 frame_presentation_time_length: 5,
1270 },
1271 ),
1272 operating_points: [
1273 OperatingPoint {
1274 idc: 0,
1275 seq_level_idx: 1,
1276 seq_tier: false,
1277 operating_parameters_info: Some(
1278 OperatingParametersInfo {
1279 decoder_buffer_delay: 10,
1280 encoder_buffer_delay: 5,
1281 low_delay_mode_flag: false,
1282 },
1283 ),
1284 initial_display_delay: None,
1285 },
1286 ],
1287 max_frame_width: 1920,
1288 max_frame_height: 1080,
1289 frame_ids: Some(
1290 FrameIds {
1291 delta_frame_id_length: 15,
1292 additional_frame_id_length: 6,
1293 },
1294 ),
1295 use_128x128_superblock: false,
1296 enable_filter_intra: false,
1297 enable_intra_edge_filter: false,
1298 enable_interintra_compound: false,
1299 enable_masked_compound: false,
1300 enable_warped_motion: false,
1301 enable_dual_filter: false,
1302 enable_order_hint: true,
1303 enable_jnt_comp: false,
1304 enable_ref_frame_mvs: false,
1305 seq_force_screen_content_tools: 1,
1306 seq_force_integer_mv: 0,
1307 order_hint_bits: 5,
1308 enable_superres: false,
1309 enable_cdef: false,
1310 enable_restoration: false,
1311 color_config: ColorConfig {
1312 bit_depth: 8,
1313 mono_chrome: true,
1314 num_planes: 1,
1315 color_primaries: 2,
1316 transfer_characteristics: 2,
1317 matrix_coefficients: 2,
1318 full_color_range: true,
1319 subsampling_x: true,
1320 subsampling_y: true,
1321 chroma_sample_position: 0,
1322 separate_uv_delta_q: false,
1323 },
1324 film_grain_params_present: true,
1325 }
1326 ");
1327 }
1328
1329 #[test]
1330 fn test_seq_obu_parse_enable_order_hint_is_false() {
1331 let mut bits = BitWriter::new(Vec::new());
1332
1333 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bits(4, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0, 5).unwrap(); bits.write_bits(0, 12).unwrap(); bits.write_bits(1, 5).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1010, 5).unwrap(); bits.write_bits(0b0101, 5).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bits(11, 4).unwrap(); bits.write_bits(11, 4).unwrap(); bits.write_bits(1919, 12).unwrap(); bits.write_bits(1079, 12).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1101, 4).unwrap(); bits.write_bits(0b101, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1396 ObuHeader {
1397 obu_type: ObuType::SequenceHeader,
1398 size: None,
1399 extension_header: None,
1400 },
1401 &mut io::Cursor::new(bits.finish().unwrap()),
1402 )
1403 .unwrap();
1404
1405 insta::assert_debug_snapshot!(obu_header, @r"
1406 SequenceHeaderObu {
1407 header: ObuHeader {
1408 obu_type: SequenceHeader,
1409 size: None,
1410 extension_header: None,
1411 },
1412 seq_profile: 2,
1413 still_picture: false,
1414 reduced_still_picture_header: false,
1415 timing_info: Some(
1416 TimingInfo {
1417 num_units_in_display_tick: 1,
1418 time_scale: 1,
1419 num_ticks_per_picture: None,
1420 },
1421 ),
1422 decoder_model_info: Some(
1423 DecoderModelInfo {
1424 buffer_delay_length: 5,
1425 num_units_in_decoding_tick: 1,
1426 buffer_removal_time_length: 5,
1427 frame_presentation_time_length: 5,
1428 },
1429 ),
1430 operating_points: [
1431 OperatingPoint {
1432 idc: 0,
1433 seq_level_idx: 1,
1434 seq_tier: false,
1435 operating_parameters_info: Some(
1436 OperatingParametersInfo {
1437 decoder_buffer_delay: 10,
1438 encoder_buffer_delay: 5,
1439 low_delay_mode_flag: false,
1440 },
1441 ),
1442 initial_display_delay: None,
1443 },
1444 ],
1445 max_frame_width: 1920,
1446 max_frame_height: 1080,
1447 frame_ids: Some(
1448 FrameIds {
1449 delta_frame_id_length: 15,
1450 additional_frame_id_length: 6,
1451 },
1452 ),
1453 use_128x128_superblock: false,
1454 enable_filter_intra: false,
1455 enable_intra_edge_filter: false,
1456 enable_interintra_compound: false,
1457 enable_masked_compound: false,
1458 enable_warped_motion: false,
1459 enable_dual_filter: false,
1460 enable_order_hint: false,
1461 enable_jnt_comp: false,
1462 enable_ref_frame_mvs: false,
1463 seq_force_screen_content_tools: 2,
1464 seq_force_integer_mv: 2,
1465 order_hint_bits: 0,
1466 enable_superres: false,
1467 enable_cdef: false,
1468 enable_restoration: false,
1469 color_config: ColorConfig {
1470 bit_depth: 8,
1471 mono_chrome: true,
1472 num_planes: 1,
1473 color_primaries: 2,
1474 transfer_characteristics: 2,
1475 matrix_coefficients: 2,
1476 full_color_range: true,
1477 subsampling_x: true,
1478 subsampling_y: true,
1479 chroma_sample_position: 0,
1480 separate_uv_delta_q: false,
1481 },
1482 film_grain_params_present: true,
1483 }
1484 ");
1485 }
1486
1487 #[test]
1488 fn test_seq_obu_parse_decoder_model_info_present_is_false() {
1489 let mut bits = BitWriter::new(Vec::new());
1490
1491 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_u32::<BigEndian>(1).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0, 5).unwrap(); bits.write_bits(0, 12).unwrap(); bits.write_bits(1, 5).unwrap(); bits.write_bit(false).unwrap(); bits.write_bits(11, 4).unwrap(); bits.write_bits(11, 4).unwrap(); bits.write_bits(1919, 12).unwrap(); bits.write_bits(1079, 12).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(0b1101, 4).unwrap(); bits.write_bits(0b101, 3).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1545 ObuHeader {
1546 obu_type: ObuType::SequenceHeader,
1547 size: None,
1548 extension_header: None,
1549 },
1550 &mut io::Cursor::new(bits.finish().unwrap()),
1551 )
1552 .unwrap();
1553
1554 insta::assert_debug_snapshot!(obu_header, @r"
1555 SequenceHeaderObu {
1556 header: ObuHeader {
1557 obu_type: SequenceHeader,
1558 size: None,
1559 extension_header: None,
1560 },
1561 seq_profile: 2,
1562 still_picture: false,
1563 reduced_still_picture_header: false,
1564 timing_info: Some(
1565 TimingInfo {
1566 num_units_in_display_tick: 1,
1567 time_scale: 1,
1568 num_ticks_per_picture: None,
1569 },
1570 ),
1571 decoder_model_info: None,
1572 operating_points: [
1573 OperatingPoint {
1574 idc: 0,
1575 seq_level_idx: 1,
1576 seq_tier: false,
1577 operating_parameters_info: None,
1578 initial_display_delay: None,
1579 },
1580 ],
1581 max_frame_width: 1920,
1582 max_frame_height: 1080,
1583 frame_ids: Some(
1584 FrameIds {
1585 delta_frame_id_length: 15,
1586 additional_frame_id_length: 6,
1587 },
1588 ),
1589 use_128x128_superblock: false,
1590 enable_filter_intra: false,
1591 enable_intra_edge_filter: false,
1592 enable_interintra_compound: false,
1593 enable_masked_compound: false,
1594 enable_warped_motion: false,
1595 enable_dual_filter: false,
1596 enable_order_hint: false,
1597 enable_jnt_comp: false,
1598 enable_ref_frame_mvs: false,
1599 seq_force_screen_content_tools: 2,
1600 seq_force_integer_mv: 2,
1601 order_hint_bits: 0,
1602 enable_superres: false,
1603 enable_cdef: false,
1604 enable_restoration: false,
1605 color_config: ColorConfig {
1606 bit_depth: 8,
1607 mono_chrome: true,
1608 num_planes: 1,
1609 color_primaries: 2,
1610 transfer_characteristics: 2,
1611 matrix_coefficients: 2,
1612 full_color_range: true,
1613 subsampling_x: true,
1614 subsampling_y: true,
1615 chroma_sample_position: 0,
1616 separate_uv_delta_q: false,
1617 },
1618 film_grain_params_present: true,
1619 }
1620 ");
1621 }
1622
1623 #[test]
1624 fn test_seq_obu_parse_color_range_and_subsampling() {
1625 let mut bits = BitWriter::new(Vec::new());
1626
1627 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1632 &mut BitReader::new(std::io::Cursor::new(Vec::new())),
1633 0,
1634 1,
1635 13,
1636 0,
1637 8,
1638 )
1639 .unwrap();
1640
1641 assert_eq!(
1642 color_range_and_subsampling,
1643 ColorRangeAndSubsampling {
1644 color_range: true,
1645 subsampling_x: false,
1646 subsampling_y: false,
1647 }
1648 );
1649
1650 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1651 &mut BitReader::new(std::io::Cursor::new(&[0b10000000])),
1652 0,
1653 1,
1654 0,
1655 0,
1656 8,
1657 )
1658 .unwrap();
1659
1660 assert_eq!(
1661 color_range_and_subsampling,
1662 ColorRangeAndSubsampling {
1663 color_range: true,
1664 subsampling_x: true,
1665 subsampling_y: true,
1666 }
1667 );
1668
1669 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1670 &mut BitReader::new(std::io::Cursor::new(&[0b10000000])),
1671 1,
1672 1,
1673 0,
1674 0,
1675 8,
1676 )
1677 .unwrap();
1678
1679 assert_eq!(
1680 color_range_and_subsampling,
1681 ColorRangeAndSubsampling {
1682 color_range: true,
1683 subsampling_x: false,
1684 subsampling_y: false,
1685 }
1686 );
1687
1688 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1689 &mut BitReader::new(std::io::Cursor::new(&[0b11100000])),
1690 2,
1691 1,
1692 0,
1693 0,
1694 12,
1695 )
1696 .unwrap();
1697
1698 assert_eq!(
1699 color_range_and_subsampling,
1700 ColorRangeAndSubsampling {
1701 color_range: true,
1702 subsampling_x: true,
1703 subsampling_y: true,
1704 }
1705 );
1706
1707 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1708 &mut BitReader::new(std::io::Cursor::new(&[0b11000000])),
1709 2,
1710 1,
1711 0,
1712 0,
1713 12,
1714 )
1715 .unwrap();
1716
1717 assert_eq!(
1718 color_range_and_subsampling,
1719 ColorRangeAndSubsampling {
1720 color_range: true,
1721 subsampling_x: true,
1722 subsampling_y: false,
1723 }
1724 );
1725
1726 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1727 &mut BitReader::new(std::io::Cursor::new(&[0b10100000])),
1728 2,
1729 1,
1730 0,
1731 0,
1732 12,
1733 )
1734 .unwrap();
1735
1736 assert_eq!(
1737 color_range_and_subsampling,
1738 ColorRangeAndSubsampling {
1739 color_range: true,
1740 subsampling_x: false,
1741 subsampling_y: false,
1742 }
1743 );
1744
1745 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1746 &mut BitReader::new(std::io::Cursor::new(&[0b11100000])),
1747 2,
1748 1,
1749 0,
1750 0,
1751 8,
1752 )
1753 .unwrap();
1754
1755 assert_eq!(
1756 color_range_and_subsampling,
1757 ColorRangeAndSubsampling {
1758 color_range: true,
1759 subsampling_x: true,
1760 subsampling_y: false,
1761 }
1762 );
1763 }
1764
1765 #[test]
1766 fn test_color_config_parse_bit_depth_12() {
1767 let mut bits = BitWriter::new(Vec::new());
1768
1769 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(11, 5).unwrap(); bits.write_bits(15, 4).unwrap();
1775 bits.write_bits(15, 4).unwrap();
1776 bits.write_bits(1919, 16).unwrap();
1777 bits.write_bits(1079, 16).unwrap();
1778
1779 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1796 ObuHeader {
1797 obu_type: ObuType::SequenceHeader,
1798 size: None,
1799 extension_header: None,
1800 },
1801 &mut io::Cursor::new(bits.finish().unwrap()),
1802 )
1803 .unwrap();
1804
1805 insta::assert_debug_snapshot!(obu_header, @r"
1806 SequenceHeaderObu {
1807 header: ObuHeader {
1808 obu_type: SequenceHeader,
1809 size: None,
1810 extension_header: None,
1811 },
1812 seq_profile: 2,
1813 still_picture: true,
1814 reduced_still_picture_header: true,
1815 timing_info: None,
1816 decoder_model_info: None,
1817 operating_points: [
1818 OperatingPoint {
1819 idc: 0,
1820 seq_level_idx: 11,
1821 seq_tier: false,
1822 operating_parameters_info: None,
1823 initial_display_delay: None,
1824 },
1825 ],
1826 max_frame_width: 1920,
1827 max_frame_height: 1080,
1828 frame_ids: None,
1829 use_128x128_superblock: false,
1830 enable_filter_intra: false,
1831 enable_intra_edge_filter: false,
1832 enable_interintra_compound: false,
1833 enable_masked_compound: false,
1834 enable_warped_motion: false,
1835 enable_dual_filter: false,
1836 enable_order_hint: false,
1837 enable_jnt_comp: false,
1838 enable_ref_frame_mvs: false,
1839 seq_force_screen_content_tools: 2,
1840 seq_force_integer_mv: 2,
1841 order_hint_bits: 0,
1842 enable_superres: false,
1843 enable_cdef: false,
1844 enable_restoration: false,
1845 color_config: ColorConfig {
1846 bit_depth: 12,
1847 mono_chrome: true,
1848 num_planes: 1,
1849 color_primaries: 2,
1850 transfer_characteristics: 2,
1851 matrix_coefficients: 2,
1852 full_color_range: true,
1853 subsampling_x: true,
1854 subsampling_y: true,
1855 chroma_sample_position: 0,
1856 separate_uv_delta_q: false,
1857 },
1858 film_grain_params_present: true,
1859 }
1860 ");
1861 }
1862
1863 #[test]
1864 fn test_color_config_parse_bit_depth_10() {
1865 let mut bits = BitWriter::new(Vec::new());
1866
1867 bits.write_bits(0b010, 3).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(11, 5).unwrap(); bits.write_bits(15, 4).unwrap();
1873 bits.write_bits(15, 4).unwrap();
1874 bits.write_bits(1919, 16).unwrap();
1875 bits.write_bits(1079, 16).unwrap();
1876
1877 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1894 ObuHeader {
1895 obu_type: ObuType::SequenceHeader,
1896 size: None,
1897 extension_header: None,
1898 },
1899 &mut io::Cursor::new(bits.finish().unwrap()),
1900 )
1901 .unwrap();
1902
1903 insta::assert_debug_snapshot!(obu_header, @r"
1904 SequenceHeaderObu {
1905 header: ObuHeader {
1906 obu_type: SequenceHeader,
1907 size: None,
1908 extension_header: None,
1909 },
1910 seq_profile: 2,
1911 still_picture: true,
1912 reduced_still_picture_header: true,
1913 timing_info: None,
1914 decoder_model_info: None,
1915 operating_points: [
1916 OperatingPoint {
1917 idc: 0,
1918 seq_level_idx: 11,
1919 seq_tier: false,
1920 operating_parameters_info: None,
1921 initial_display_delay: None,
1922 },
1923 ],
1924 max_frame_width: 1920,
1925 max_frame_height: 1080,
1926 frame_ids: None,
1927 use_128x128_superblock: false,
1928 enable_filter_intra: false,
1929 enable_intra_edge_filter: false,
1930 enable_interintra_compound: false,
1931 enable_masked_compound: false,
1932 enable_warped_motion: false,
1933 enable_dual_filter: false,
1934 enable_order_hint: false,
1935 enable_jnt_comp: false,
1936 enable_ref_frame_mvs: false,
1937 seq_force_screen_content_tools: 2,
1938 seq_force_integer_mv: 2,
1939 order_hint_bits: 0,
1940 enable_superres: false,
1941 enable_cdef: false,
1942 enable_restoration: false,
1943 color_config: ColorConfig {
1944 bit_depth: 10,
1945 mono_chrome: true,
1946 num_planes: 1,
1947 color_primaries: 2,
1948 transfer_characteristics: 2,
1949 matrix_coefficients: 2,
1950 full_color_range: true,
1951 subsampling_x: true,
1952 subsampling_y: true,
1953 chroma_sample_position: 0,
1954 separate_uv_delta_q: false,
1955 },
1956 film_grain_params_present: true,
1957 }
1958 ");
1959 }
1960
1961 #[test]
1962 fn test_color_config_parse_csp_unknown() {
1963 let mut bits = BitWriter::new(Vec::new());
1964
1965 bits.write_bits(0b001, 3).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); bits.write_bits(11, 5).unwrap(); bits.write_bits(15, 4).unwrap();
1971 bits.write_bits(15, 4).unwrap();
1972 bits.write_bits(1919, 16).unwrap();
1973 bits.write_bits(1079, 16).unwrap();
1974
1975 bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(false).unwrap(); bits.write_bit(true).unwrap(); bits.write_bit(true).unwrap(); let obu_header = SequenceHeaderObu::parse(
1990 ObuHeader {
1991 obu_type: ObuType::SequenceHeader,
1992 size: None,
1993 extension_header: None,
1994 },
1995 &mut io::Cursor::new(bits.finish().unwrap()),
1996 )
1997 .unwrap();
1998
1999 insta::assert_debug_snapshot!(obu_header, @r"
2000 SequenceHeaderObu {
2001 header: ObuHeader {
2002 obu_type: SequenceHeader,
2003 size: None,
2004 extension_header: None,
2005 },
2006 seq_profile: 1,
2007 still_picture: true,
2008 reduced_still_picture_header: true,
2009 timing_info: None,
2010 decoder_model_info: None,
2011 operating_points: [
2012 OperatingPoint {
2013 idc: 0,
2014 seq_level_idx: 11,
2015 seq_tier: false,
2016 operating_parameters_info: None,
2017 initial_display_delay: None,
2018 },
2019 ],
2020 max_frame_width: 1920,
2021 max_frame_height: 1080,
2022 frame_ids: None,
2023 use_128x128_superblock: false,
2024 enable_filter_intra: false,
2025 enable_intra_edge_filter: false,
2026 enable_interintra_compound: false,
2027 enable_masked_compound: false,
2028 enable_warped_motion: false,
2029 enable_dual_filter: false,
2030 enable_order_hint: false,
2031 enable_jnt_comp: false,
2032 enable_ref_frame_mvs: false,
2033 seq_force_screen_content_tools: 2,
2034 seq_force_integer_mv: 2,
2035 order_hint_bits: 0,
2036 enable_superres: false,
2037 enable_cdef: false,
2038 enable_restoration: false,
2039 color_config: ColorConfig {
2040 bit_depth: 8,
2041 mono_chrome: false,
2042 num_planes: 3,
2043 color_primaries: 2,
2044 transfer_characteristics: 2,
2045 matrix_coefficients: 2,
2046 full_color_range: false,
2047 subsampling_x: false,
2048 subsampling_y: false,
2049 chroma_sample_position: 0,
2050 separate_uv_delta_q: true,
2051 },
2052 film_grain_params_present: true,
2053 }
2054 ");
2055 }
2056}