1use std::io;
2
3use byteorder::{BigEndian, ReadBytesExt};
4use scuffle_bytes_util::BitReader;
5
6use super::ObuHeader;
7use crate::obu::utils::read_uvlc;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct SequenceHeaderObu {
13 pub header: ObuHeader,
14 pub seq_profile: u8,
15 pub still_picture: bool,
16 pub reduced_still_picture_header: bool,
17 pub timing_info: Option<TimingInfo>,
18 pub decoder_model_info: Option<DecoderModelInfo>,
19 pub operating_points: Vec<OperatingPoint>,
20 pub max_frame_width: u64,
21 pub max_frame_height: u64,
22 pub frame_ids: Option<FrameIds>,
23 pub use_128x128_superblock: bool,
24 pub enable_filter_intra: bool,
25 pub enable_intra_edge_filter: bool,
26 pub enable_interintra_compound: bool,
27 pub enable_masked_compound: bool,
28 pub enable_warped_motion: bool,
29 pub enable_dual_filter: bool,
30 pub enable_order_hint: bool,
31 pub enable_jnt_comp: bool,
32 pub enable_ref_frame_mvs: bool,
33 pub seq_force_screen_content_tools: u8,
34 pub seq_force_integer_mv: u8,
35 pub order_hint_bits: u8,
36 pub enable_superres: bool,
37 pub enable_cdef: bool,
38 pub enable_restoration: bool,
39 pub color_config: ColorConfig,
40 pub film_grain_params_present: bool,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, Copy)]
44pub struct FrameIds {
45 pub delta_frame_id_length: u8,
46 pub additional_frame_id_length: u8,
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Copy)]
50pub struct OperatingPoint {
51 pub idc: u16,
52 pub seq_level_idx: u8,
53 pub seq_tier: bool,
54 pub operating_parameters_info: Option<OperatingParametersInfo>,
55 pub initial_display_delay: Option<u8>,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Copy)]
59pub struct TimingInfo {
60 pub num_units_in_display_tick: u32,
61 pub time_scale: u32,
62 pub num_ticks_per_picture: Option<u64>,
63}
64
65impl TimingInfo {
66 pub fn parse(bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
67 let num_units_in_display_tick = bit_reader.read_u32::<BigEndian>()?;
68 let time_scale = bit_reader.read_u32::<BigEndian>()?;
69 let num_ticks_per_picture = if bit_reader.read_bit()? {
70 Some(read_uvlc(bit_reader)? + 1)
71 } else {
72 None
73 };
74 Ok(Self {
75 num_units_in_display_tick,
76 time_scale,
77 num_ticks_per_picture,
78 })
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Copy)]
83pub struct DecoderModelInfo {
84 pub buffer_delay_length: u8,
85 pub num_units_in_decoding_tick: u32,
86 pub buffer_removal_time_length: u8,
87 pub frame_presentation_time_length: u8,
88}
89
90impl DecoderModelInfo {
91 pub fn parse(bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
92 let buffer_delay_length = bit_reader.read_bits(5)? as u8 + 1;
93 let num_units_in_decoding_tick = bit_reader.read_u32::<BigEndian>()?;
94 let buffer_removal_time_length = bit_reader.read_bits(5)? as u8 + 1;
95 let frame_presentation_time_length = bit_reader.read_bits(5)? as u8 + 1;
96 Ok(Self {
97 buffer_delay_length,
98 num_units_in_decoding_tick,
99 buffer_removal_time_length,
100 frame_presentation_time_length,
101 })
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Copy)]
106pub struct OperatingParametersInfo {
107 pub decoder_buffer_delay: u64,
108 pub encoder_buffer_delay: u64,
109 pub low_delay_mode_flag: bool,
110}
111
112impl OperatingParametersInfo {
113 pub fn parse(delay_bit_length: u8, bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
114 let decoder_buffer_delay = bit_reader.read_bits(delay_bit_length)?;
115 let encoder_buffer_delay = bit_reader.read_bits(delay_bit_length)?;
116 let low_delay_mode_flag = bit_reader.read_bit()?;
117 Ok(Self {
118 decoder_buffer_delay,
119 encoder_buffer_delay,
120 low_delay_mode_flag,
121 })
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Eq, Copy)]
126pub struct ColorConfig {
127 pub bit_depth: i32,
128 pub mono_chrome: bool,
129 pub num_planes: u8,
130 pub color_primaries: u8,
131 pub transfer_characteristics: u8,
132 pub matrix_coefficients: u8,
133 pub full_color_range: bool,
134 pub subsampling_x: bool,
135 pub subsampling_y: bool,
136 pub chroma_sample_position: u8,
137 pub separate_uv_delta_q: bool,
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Copy)]
141struct ColorRangeAndSubsampling {
142 color_range: bool,
143 subsampling_x: bool,
144 subsampling_y: bool,
145}
146
147impl ColorConfig {
148 fn parse_color_range_and_subsampling(
149 bit_reader: &mut BitReader<impl io::Read>,
150 seq_profile: u8,
151 color_primaries: u8,
152 transfer_characteristics: u8,
153 matrix_coefficients: u8,
154 bit_depth: i32,
155 ) -> io::Result<ColorRangeAndSubsampling> {
156 let color_range;
157 let subsampling_x;
158 let subsampling_y;
159
160 const CP_BT_709: u8 = 1;
161 const TC_SRGB: u8 = 13;
162 const MC_IDENTITY: u8 = 0;
163
164 if color_primaries == CP_BT_709 && transfer_characteristics == TC_SRGB && matrix_coefficients == MC_IDENTITY {
165 color_range = true;
166 subsampling_x = false;
167 subsampling_y = false;
168 } else {
169 color_range = bit_reader.read_bit()?;
170 if seq_profile == 0 {
171 subsampling_x = true;
172 subsampling_y = true;
173 } else if seq_profile == 1 {
174 subsampling_x = false;
175 subsampling_y = false;
176 } else if bit_depth == 12 {
177 subsampling_x = bit_reader.read_bit()?;
178 if subsampling_x {
179 subsampling_y = bit_reader.read_bit()?;
180 } else {
181 subsampling_y = false;
182 }
183 } else {
184 subsampling_x = true;
185 subsampling_y = false;
186 }
187 }
188
189 Ok(ColorRangeAndSubsampling {
190 color_range,
191 subsampling_x,
192 subsampling_y,
193 })
194 }
195
196 pub fn parse(seq_profile: u8, bit_reader: &mut BitReader<impl io::Read>) -> io::Result<Self> {
197 let high_bitdepth = bit_reader.read_bit()?;
198 let bit_depth = match (seq_profile, high_bitdepth) {
199 (2, true) if bit_reader.read_bit()? => 12,
200 (_, true) => 10,
201 (_, false) => 8,
202 };
203
204 let mono_chrome = if seq_profile == 1 { false } else { bit_reader.read_bit()? };
205
206 let color_primaries;
207 let transfer_characteristics;
208 let matrix_coefficients;
209
210 let color_description_present_flag = bit_reader.read_bit()?;
211 if color_description_present_flag {
212 color_primaries = bit_reader.read_bits(8)? as u8;
213 transfer_characteristics = bit_reader.read_bits(8)? as u8;
214 matrix_coefficients = bit_reader.read_bits(8)? as u8;
215 } else {
216 color_primaries = 2; transfer_characteristics = 2; matrix_coefficients = 2; }
220
221 let num_planes = if mono_chrome { 1 } else { 3 };
222
223 if mono_chrome {
224 Ok(ColorConfig {
225 bit_depth,
226 color_primaries,
227 transfer_characteristics,
228 matrix_coefficients,
229 full_color_range: bit_reader.read_bit()?,
230 subsampling_x: true,
231 subsampling_y: true,
232 mono_chrome,
233 separate_uv_delta_q: false,
234 chroma_sample_position: 0, num_planes,
236 })
237 } else {
238 let ColorRangeAndSubsampling {
239 color_range,
240 subsampling_x,
241 subsampling_y,
242 } = Self::parse_color_range_and_subsampling(
243 bit_reader,
244 seq_profile,
245 color_primaries,
246 transfer_characteristics,
247 matrix_coefficients,
248 bit_depth,
249 )?;
250
251 let chroma_sample_position = if subsampling_x && subsampling_y {
252 bit_reader.read_bits(2)? as u8
253 } else {
254 0 };
256
257 let separate_uv_delta_q = bit_reader.read_bit()?;
258 Ok(ColorConfig {
259 bit_depth,
260 mono_chrome,
261 color_primaries,
262 transfer_characteristics,
263 matrix_coefficients,
264 full_color_range: color_range,
265 subsampling_x,
266 subsampling_y,
267 chroma_sample_position,
268 separate_uv_delta_q,
269 num_planes,
270 })
271 }
272 }
273}
274
275impl SequenceHeaderObu {
276 pub const fn header(&self) -> &ObuHeader {
277 &self.header
278 }
279
280 pub fn parse(header: ObuHeader, reader: &mut impl io::Read) -> io::Result<Self> {
281 let mut bit_reader = BitReader::new(reader);
282
283 let seq_profile = bit_reader.read_bits(3)? as u8;
284 let still_picture = bit_reader.read_bit()?;
285 let reduced_still_picture_header = bit_reader.read_bit()?;
286
287 if !still_picture && reduced_still_picture_header {
288 return Err(io::Error::new(
289 io::ErrorKind::InvalidData,
290 "reduced_still_picture_header is true but still_picture is false",
291 ));
292 }
293
294 let mut timing_info = None;
295 let mut decoder_model_info = None;
296 let mut operating_points = Vec::new();
297
298 if reduced_still_picture_header {
299 operating_points.push(OperatingPoint {
300 idc: 0,
301 seq_level_idx: bit_reader.read_bits(5)? as u8,
302 seq_tier: false,
303 operating_parameters_info: None,
304 initial_display_delay: None,
305 });
306 } else {
307 let timing_info_present_flag = bit_reader.read_bit()?;
308 if timing_info_present_flag {
309 timing_info = Some(TimingInfo::parse(&mut bit_reader)?);
310
311 let decoder_model_info_present_flag = bit_reader.read_bit()?;
312 if decoder_model_info_present_flag {
313 decoder_model_info = Some(DecoderModelInfo::parse(&mut bit_reader)?);
314 }
315 }
316
317 let initial_display_delay_present_flag = bit_reader.read_bit()?;
318 let operating_points_cnt_minus_1 = bit_reader.read_bits(5)? as u8;
319 for _ in 0..operating_points_cnt_minus_1 + 1 {
320 let idc = bit_reader.read_bits(12)? as u16;
321 let seq_level_idx = bit_reader.read_bits(5)? as u8;
322 let seq_tier = if seq_level_idx > 7 { bit_reader.read_bit()? } else { false };
323 let decoder_model_present_for_this_op = if let Some(decoder_model_info) = decoder_model_info {
324 bit_reader.read_bit()?.then_some(decoder_model_info.buffer_delay_length)
325 } else {
326 None
327 };
328
329 let operating_parameters_info = if let Some(delay_bit_length) = decoder_model_present_for_this_op {
330 Some(OperatingParametersInfo::parse(delay_bit_length, &mut bit_reader)?)
331 } else {
332 None
333 };
334
335 let initial_display_delay = if initial_display_delay_present_flag {
336 if bit_reader.read_bit()? {
337 Some(bit_reader.read_bits(4)? as u8 + 1) } else {
340 None
341 }
342 } else {
343 None
344 };
345
346 operating_points.push(OperatingPoint {
347 idc,
348 seq_level_idx,
349 seq_tier,
350 operating_parameters_info,
351 initial_display_delay,
352 });
353 }
354 }
355
356 let frame_width_bits = bit_reader.read_bits(4)? as u8 + 1;
357 let frame_height_bits = bit_reader.read_bits(4)? as u8 + 1;
358
359 let max_frame_width = bit_reader.read_bits(frame_width_bits)? + 1;
360 let max_frame_height = bit_reader.read_bits(frame_height_bits)? + 1;
361
362 let frame_id_numbers_present_flag = if reduced_still_picture_header {
363 false
364 } else {
365 bit_reader.read_bit()?
366 };
367 let frame_ids = if frame_id_numbers_present_flag {
368 let delta_frame_id_length = bit_reader.read_bits(4)? as u8 + 2;
369 let additional_frame_id_length = bit_reader.read_bits(3)? as u8 + 1;
370 Some(FrameIds {
371 delta_frame_id_length,
372 additional_frame_id_length,
373 })
374 } else {
375 None
376 };
377
378 let use_128x128_superblock = bit_reader.read_bit()?;
379 let enable_filter_intra = bit_reader.read_bit()?;
380 let enable_intra_edge_filter = bit_reader.read_bit()?;
381
382 let enable_interintra_compound;
383 let enable_masked_compound;
384 let enable_warped_motion;
385 let enable_dual_filter;
386 let enable_order_hint;
387 let enable_jnt_comp;
388 let enable_ref_frame_mvs;
389 let order_hint_bits;
390 let seq_force_integer_mv;
391
392 let seq_force_screen_content_tools;
393
394 if !reduced_still_picture_header {
395 enable_interintra_compound = bit_reader.read_bit()?;
396 enable_masked_compound = bit_reader.read_bit()?;
397 enable_warped_motion = bit_reader.read_bit()?;
398 enable_dual_filter = bit_reader.read_bit()?;
399 enable_order_hint = bit_reader.read_bit()?;
400 if enable_order_hint {
401 enable_jnt_comp = bit_reader.read_bit()?;
402 enable_ref_frame_mvs = bit_reader.read_bit()?;
403 } else {
404 enable_jnt_comp = false;
405 enable_ref_frame_mvs = false;
406 }
407 if bit_reader.read_bit()? {
408 seq_force_screen_content_tools = 2; } else {
411 seq_force_screen_content_tools = bit_reader.read_bits(1)? as u8;
412 }
413
414 if seq_force_screen_content_tools == 0 || bit_reader.read_bit()? {
417 seq_force_integer_mv = 2; } else {
419 seq_force_integer_mv = bit_reader.read_bits(1)? as u8;
420 }
421
422 if enable_order_hint {
423 order_hint_bits = bit_reader.read_bits(3)? as u8 + 1;
424 } else {
425 order_hint_bits = 0;
426 }
427 } else {
428 enable_interintra_compound = false;
429 enable_masked_compound = false;
430 enable_warped_motion = false;
431 enable_dual_filter = false;
432 enable_order_hint = false;
433 enable_jnt_comp = false;
434 enable_ref_frame_mvs = false;
435 seq_force_screen_content_tools = 2; seq_force_integer_mv = 2; order_hint_bits = 0;
438 }
439
440 let enable_superres = bit_reader.read_bit()?;
441 let enable_cdef = bit_reader.read_bit()?;
442 let enable_restoration = bit_reader.read_bit()?;
443
444 let color_config = ColorConfig::parse(seq_profile, &mut bit_reader)?;
445
446 let film_grain_params_present = bit_reader.read_bit()?;
447
448 Ok(Self {
449 header,
450 seq_profile,
451 still_picture,
452 reduced_still_picture_header,
453 operating_points,
454 decoder_model_info,
455 max_frame_width,
456 max_frame_height,
457 frame_ids,
458 use_128x128_superblock,
459 enable_filter_intra,
460 enable_intra_edge_filter,
461 enable_interintra_compound,
462 enable_masked_compound,
463 enable_warped_motion,
464 enable_dual_filter,
465 enable_order_hint,
466 enable_jnt_comp,
467 enable_ref_frame_mvs,
468 seq_force_screen_content_tools,
469 seq_force_integer_mv,
470 order_hint_bits,
471 enable_superres,
472 enable_cdef,
473 enable_restoration,
474 timing_info,
475 color_config,
476 film_grain_params_present,
477 })
478 }
479}
480
481#[cfg(test)]
482#[cfg_attr(all(coverage_nightly, test), coverage(off))]
483mod tests {
484 use byteorder::WriteBytesExt;
485 use scuffle_bytes_util::BitWriter;
486
487 use super::*;
488 use crate::ObuType;
489
490 #[test]
491 fn test_seq_obu_parse() {
492 let obu = b"\0\0\0j\xef\xbf\xe1\xbc\x02\x19\x90\x10\x10\x10@";
493
494 let header = ObuHeader {
495 obu_type: ObuType::SequenceHeader,
496 size: None,
497 extension_header: None,
498 };
499
500 let seq_header = SequenceHeaderObu::parse(header, &mut io::Cursor::new(obu)).unwrap();
501
502 insta::assert_debug_snapshot!(seq_header, @r"
503 SequenceHeaderObu {
504 header: ObuHeader {
505 obu_type: SequenceHeader,
506 size: None,
507 extension_header: None,
508 },
509 seq_profile: 0,
510 still_picture: false,
511 reduced_still_picture_header: false,
512 timing_info: None,
513 decoder_model_info: None,
514 operating_points: [
515 OperatingPoint {
516 idc: 0,
517 seq_level_idx: 13,
518 seq_tier: false,
519 operating_parameters_info: None,
520 initial_display_delay: None,
521 },
522 ],
523 max_frame_width: 3840,
524 max_frame_height: 2160,
525 frame_ids: None,
526 use_128x128_superblock: false,
527 enable_filter_intra: false,
528 enable_intra_edge_filter: false,
529 enable_interintra_compound: false,
530 enable_masked_compound: false,
531 enable_warped_motion: false,
532 enable_dual_filter: false,
533 enable_order_hint: true,
534 enable_jnt_comp: false,
535 enable_ref_frame_mvs: false,
536 seq_force_screen_content_tools: 0,
537 seq_force_integer_mv: 2,
538 order_hint_bits: 7,
539 enable_superres: false,
540 enable_cdef: true,
541 enable_restoration: true,
542 color_config: ColorConfig {
543 bit_depth: 8,
544 mono_chrome: false,
545 num_planes: 3,
546 color_primaries: 1,
547 transfer_characteristics: 1,
548 matrix_coefficients: 1,
549 full_color_range: false,
550 subsampling_x: true,
551 subsampling_y: true,
552 chroma_sample_position: 0,
553 separate_uv_delta_q: false,
554 },
555 film_grain_params_present: false,
556 }
557 ");
558
559 assert_eq!(seq_header.header(), &header);
560 }
561
562 #[test]
563 fn test_seq_obu_parse_reduced_still_picture() {
564 let mut bits = BitWriter::new(Vec::new());
565
566 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();
572 bits.write_bits(15, 4).unwrap();
573 bits.write_bits(1919, 16).unwrap();
574 bits.write_bits(1079, 16).unwrap();
575
576 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(
592 ObuHeader {
593 obu_type: ObuType::SequenceHeader,
594 size: None,
595 extension_header: None,
596 },
597 &mut io::Cursor::new(bits.finish().unwrap()),
598 )
599 .unwrap();
600
601 insta::assert_debug_snapshot!(obu_header, @r"
602 SequenceHeaderObu {
603 header: ObuHeader {
604 obu_type: SequenceHeader,
605 size: None,
606 extension_header: None,
607 },
608 seq_profile: 2,
609 still_picture: true,
610 reduced_still_picture_header: true,
611 timing_info: None,
612 decoder_model_info: None,
613 operating_points: [
614 OperatingPoint {
615 idc: 0,
616 seq_level_idx: 11,
617 seq_tier: false,
618 operating_parameters_info: None,
619 initial_display_delay: None,
620 },
621 ],
622 max_frame_width: 1920,
623 max_frame_height: 1080,
624 frame_ids: None,
625 use_128x128_superblock: false,
626 enable_filter_intra: false,
627 enable_intra_edge_filter: false,
628 enable_interintra_compound: false,
629 enable_masked_compound: false,
630 enable_warped_motion: false,
631 enable_dual_filter: false,
632 enable_order_hint: false,
633 enable_jnt_comp: false,
634 enable_ref_frame_mvs: false,
635 seq_force_screen_content_tools: 2,
636 seq_force_integer_mv: 2,
637 order_hint_bits: 0,
638 enable_superres: false,
639 enable_cdef: false,
640 enable_restoration: false,
641 color_config: ColorConfig {
642 bit_depth: 8,
643 mono_chrome: true,
644 num_planes: 1,
645 color_primaries: 2,
646 transfer_characteristics: 2,
647 matrix_coefficients: 2,
648 full_color_range: true,
649 subsampling_x: true,
650 subsampling_y: true,
651 chroma_sample_position: 0,
652 separate_uv_delta_q: false,
653 },
654 film_grain_params_present: true,
655 }
656 ");
657 }
658
659 #[test]
660 fn test_seq_obu_parse_timing_info_decoder_model_preset() {
661 let mut bits = BitWriter::new(Vec::new());
662
663 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();
714 bits.write_bit(true).unwrap();
715 bits.write_bit(false).unwrap();
716 bits.write_bit(false).unwrap();
717
718 bits.write_bits(0b100, 3).unwrap();
719
720 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(
733 ObuHeader {
734 obu_type: ObuType::SequenceHeader,
735 size: None,
736 extension_header: None,
737 },
738 &mut io::Cursor::new(bits.finish().unwrap()),
739 )
740 .unwrap();
741
742 insta::assert_debug_snapshot!(obu_header, @r"
743 SequenceHeaderObu {
744 header: ObuHeader {
745 obu_type: SequenceHeader,
746 size: None,
747 extension_header: None,
748 },
749 seq_profile: 2,
750 still_picture: false,
751 reduced_still_picture_header: false,
752 timing_info: Some(
753 TimingInfo {
754 num_units_in_display_tick: 1,
755 time_scale: 1,
756 num_ticks_per_picture: None,
757 },
758 ),
759 decoder_model_info: Some(
760 DecoderModelInfo {
761 buffer_delay_length: 5,
762 num_units_in_decoding_tick: 1,
763 buffer_removal_time_length: 5,
764 frame_presentation_time_length: 5,
765 },
766 ),
767 operating_points: [
768 OperatingPoint {
769 idc: 0,
770 seq_level_idx: 1,
771 seq_tier: false,
772 operating_parameters_info: Some(
773 OperatingParametersInfo {
774 decoder_buffer_delay: 10,
775 encoder_buffer_delay: 5,
776 low_delay_mode_flag: false,
777 },
778 ),
779 initial_display_delay: Some(
780 16,
781 ),
782 },
783 ],
784 max_frame_width: 1920,
785 max_frame_height: 1080,
786 frame_ids: Some(
787 FrameIds {
788 delta_frame_id_length: 15,
789 additional_frame_id_length: 6,
790 },
791 ),
792 use_128x128_superblock: false,
793 enable_filter_intra: false,
794 enable_intra_edge_filter: false,
795 enable_interintra_compound: false,
796 enable_masked_compound: false,
797 enable_warped_motion: false,
798 enable_dual_filter: false,
799 enable_order_hint: true,
800 enable_jnt_comp: false,
801 enable_ref_frame_mvs: false,
802 seq_force_screen_content_tools: 1,
803 seq_force_integer_mv: 0,
804 order_hint_bits: 5,
805 enable_superres: false,
806 enable_cdef: false,
807 enable_restoration: false,
808 color_config: ColorConfig {
809 bit_depth: 8,
810 mono_chrome: true,
811 num_planes: 1,
812 color_primaries: 2,
813 transfer_characteristics: 2,
814 matrix_coefficients: 2,
815 full_color_range: true,
816 subsampling_x: true,
817 subsampling_y: true,
818 chroma_sample_position: 0,
819 separate_uv_delta_q: false,
820 },
821 film_grain_params_present: true,
822 }
823 ");
824 }
825
826 #[test]
827 fn test_seq_obu_parse_num_ticks_per_picture() {
828 let mut bits = BitWriter::new(Vec::new());
829
830 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();
882 bits.write_bit(true).unwrap();
883 bits.write_bit(false).unwrap();
884 bits.write_bit(false).unwrap();
885
886 bits.write_bits(0b100, 3).unwrap();
887
888 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(
901 ObuHeader {
902 obu_type: ObuType::SequenceHeader,
903 size: None,
904 extension_header: None,
905 },
906 &mut io::Cursor::new(bits.finish().unwrap()),
907 )
908 .unwrap();
909
910 insta::assert_debug_snapshot!(obu_header, @r"
911 SequenceHeaderObu {
912 header: ObuHeader {
913 obu_type: SequenceHeader,
914 size: None,
915 extension_header: None,
916 },
917 seq_profile: 2,
918 still_picture: false,
919 reduced_still_picture_header: false,
920 timing_info: Some(
921 TimingInfo {
922 num_units_in_display_tick: 1,
923 time_scale: 1,
924 num_ticks_per_picture: Some(
925 1,
926 ),
927 },
928 ),
929 decoder_model_info: Some(
930 DecoderModelInfo {
931 buffer_delay_length: 5,
932 num_units_in_decoding_tick: 1,
933 buffer_removal_time_length: 5,
934 frame_presentation_time_length: 5,
935 },
936 ),
937 operating_points: [
938 OperatingPoint {
939 idc: 0,
940 seq_level_idx: 1,
941 seq_tier: false,
942 operating_parameters_info: Some(
943 OperatingParametersInfo {
944 decoder_buffer_delay: 10,
945 encoder_buffer_delay: 5,
946 low_delay_mode_flag: false,
947 },
948 ),
949 initial_display_delay: Some(
950 16,
951 ),
952 },
953 ],
954 max_frame_width: 1920,
955 max_frame_height: 1080,
956 frame_ids: Some(
957 FrameIds {
958 delta_frame_id_length: 15,
959 additional_frame_id_length: 6,
960 },
961 ),
962 use_128x128_superblock: false,
963 enable_filter_intra: false,
964 enable_intra_edge_filter: false,
965 enable_interintra_compound: false,
966 enable_masked_compound: false,
967 enable_warped_motion: false,
968 enable_dual_filter: false,
969 enable_order_hint: true,
970 enable_jnt_comp: false,
971 enable_ref_frame_mvs: false,
972 seq_force_screen_content_tools: 1,
973 seq_force_integer_mv: 0,
974 order_hint_bits: 5,
975 enable_superres: false,
976 enable_cdef: false,
977 enable_restoration: false,
978 color_config: ColorConfig {
979 bit_depth: 8,
980 mono_chrome: true,
981 num_planes: 1,
982 color_primaries: 2,
983 transfer_characteristics: 2,
984 matrix_coefficients: 2,
985 full_color_range: true,
986 subsampling_x: true,
987 subsampling_y: true,
988 chroma_sample_position: 0,
989 separate_uv_delta_q: false,
990 },
991 film_grain_params_present: true,
992 }
993 ");
994 }
995
996 #[test]
997 fn test_seq_obu_parse_initial_display_delay_is_none() {
998 let mut bits = BitWriter::new(Vec::new());
999
1000 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();
1050 bits.write_bit(true).unwrap();
1051 bits.write_bit(false).unwrap();
1052 bits.write_bit(false).unwrap();
1053
1054 bits.write_bits(0b100, 3).unwrap();
1055
1056 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(
1069 ObuHeader {
1070 obu_type: ObuType::SequenceHeader,
1071 size: None,
1072 extension_header: None,
1073 },
1074 &mut io::Cursor::new(bits.finish().unwrap()),
1075 )
1076 .unwrap();
1077
1078 insta::assert_debug_snapshot!(obu_header, @r"
1079 SequenceHeaderObu {
1080 header: ObuHeader {
1081 obu_type: SequenceHeader,
1082 size: None,
1083 extension_header: None,
1084 },
1085 seq_profile: 2,
1086 still_picture: false,
1087 reduced_still_picture_header: false,
1088 timing_info: Some(
1089 TimingInfo {
1090 num_units_in_display_tick: 1,
1091 time_scale: 1,
1092 num_ticks_per_picture: None,
1093 },
1094 ),
1095 decoder_model_info: Some(
1096 DecoderModelInfo {
1097 buffer_delay_length: 5,
1098 num_units_in_decoding_tick: 1,
1099 buffer_removal_time_length: 5,
1100 frame_presentation_time_length: 5,
1101 },
1102 ),
1103 operating_points: [
1104 OperatingPoint {
1105 idc: 0,
1106 seq_level_idx: 1,
1107 seq_tier: false,
1108 operating_parameters_info: Some(
1109 OperatingParametersInfo {
1110 decoder_buffer_delay: 10,
1111 encoder_buffer_delay: 5,
1112 low_delay_mode_flag: false,
1113 },
1114 ),
1115 initial_display_delay: None,
1116 },
1117 ],
1118 max_frame_width: 1920,
1119 max_frame_height: 1080,
1120 frame_ids: Some(
1121 FrameIds {
1122 delta_frame_id_length: 15,
1123 additional_frame_id_length: 6,
1124 },
1125 ),
1126 use_128x128_superblock: false,
1127 enable_filter_intra: false,
1128 enable_intra_edge_filter: false,
1129 enable_interintra_compound: false,
1130 enable_masked_compound: false,
1131 enable_warped_motion: false,
1132 enable_dual_filter: false,
1133 enable_order_hint: true,
1134 enable_jnt_comp: false,
1135 enable_ref_frame_mvs: false,
1136 seq_force_screen_content_tools: 1,
1137 seq_force_integer_mv: 0,
1138 order_hint_bits: 5,
1139 enable_superres: false,
1140 enable_cdef: false,
1141 enable_restoration: false,
1142 color_config: ColorConfig {
1143 bit_depth: 8,
1144 mono_chrome: true,
1145 num_planes: 1,
1146 color_primaries: 2,
1147 transfer_characteristics: 2,
1148 matrix_coefficients: 2,
1149 full_color_range: true,
1150 subsampling_x: true,
1151 subsampling_y: true,
1152 chroma_sample_position: 0,
1153 separate_uv_delta_q: false,
1154 },
1155 film_grain_params_present: true,
1156 }
1157 ");
1158 }
1159
1160 #[test]
1161 fn test_seq_obu_parse_enable_order_hint_is_false() {
1162 let mut bits = BitWriter::new(Vec::new());
1163
1164 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(
1227 ObuHeader {
1228 obu_type: ObuType::SequenceHeader,
1229 size: None,
1230 extension_header: None,
1231 },
1232 &mut io::Cursor::new(bits.finish().unwrap()),
1233 )
1234 .unwrap();
1235
1236 insta::assert_debug_snapshot!(obu_header, @r"
1237 SequenceHeaderObu {
1238 header: ObuHeader {
1239 obu_type: SequenceHeader,
1240 size: None,
1241 extension_header: None,
1242 },
1243 seq_profile: 2,
1244 still_picture: false,
1245 reduced_still_picture_header: false,
1246 timing_info: Some(
1247 TimingInfo {
1248 num_units_in_display_tick: 1,
1249 time_scale: 1,
1250 num_ticks_per_picture: None,
1251 },
1252 ),
1253 decoder_model_info: Some(
1254 DecoderModelInfo {
1255 buffer_delay_length: 5,
1256 num_units_in_decoding_tick: 1,
1257 buffer_removal_time_length: 5,
1258 frame_presentation_time_length: 5,
1259 },
1260 ),
1261 operating_points: [
1262 OperatingPoint {
1263 idc: 0,
1264 seq_level_idx: 1,
1265 seq_tier: false,
1266 operating_parameters_info: Some(
1267 OperatingParametersInfo {
1268 decoder_buffer_delay: 10,
1269 encoder_buffer_delay: 5,
1270 low_delay_mode_flag: false,
1271 },
1272 ),
1273 initial_display_delay: None,
1274 },
1275 ],
1276 max_frame_width: 1920,
1277 max_frame_height: 1080,
1278 frame_ids: Some(
1279 FrameIds {
1280 delta_frame_id_length: 15,
1281 additional_frame_id_length: 6,
1282 },
1283 ),
1284 use_128x128_superblock: false,
1285 enable_filter_intra: false,
1286 enable_intra_edge_filter: false,
1287 enable_interintra_compound: false,
1288 enable_masked_compound: false,
1289 enable_warped_motion: false,
1290 enable_dual_filter: false,
1291 enable_order_hint: false,
1292 enable_jnt_comp: false,
1293 enable_ref_frame_mvs: false,
1294 seq_force_screen_content_tools: 2,
1295 seq_force_integer_mv: 2,
1296 order_hint_bits: 0,
1297 enable_superres: false,
1298 enable_cdef: false,
1299 enable_restoration: false,
1300 color_config: ColorConfig {
1301 bit_depth: 8,
1302 mono_chrome: true,
1303 num_planes: 1,
1304 color_primaries: 2,
1305 transfer_characteristics: 2,
1306 matrix_coefficients: 2,
1307 full_color_range: true,
1308 subsampling_x: true,
1309 subsampling_y: true,
1310 chroma_sample_position: 0,
1311 separate_uv_delta_q: false,
1312 },
1313 film_grain_params_present: true,
1314 }
1315 ");
1316 }
1317
1318 #[test]
1319 fn test_seq_obu_parse_decoder_model_info_present_is_false() {
1320 let mut bits = BitWriter::new(Vec::new());
1321
1322 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(
1376 ObuHeader {
1377 obu_type: ObuType::SequenceHeader,
1378 size: None,
1379 extension_header: None,
1380 },
1381 &mut io::Cursor::new(bits.finish().unwrap()),
1382 )
1383 .unwrap();
1384
1385 insta::assert_debug_snapshot!(obu_header, @r"
1386 SequenceHeaderObu {
1387 header: ObuHeader {
1388 obu_type: SequenceHeader,
1389 size: None,
1390 extension_header: None,
1391 },
1392 seq_profile: 2,
1393 still_picture: false,
1394 reduced_still_picture_header: false,
1395 timing_info: Some(
1396 TimingInfo {
1397 num_units_in_display_tick: 1,
1398 time_scale: 1,
1399 num_ticks_per_picture: None,
1400 },
1401 ),
1402 decoder_model_info: None,
1403 operating_points: [
1404 OperatingPoint {
1405 idc: 0,
1406 seq_level_idx: 1,
1407 seq_tier: false,
1408 operating_parameters_info: None,
1409 initial_display_delay: None,
1410 },
1411 ],
1412 max_frame_width: 1920,
1413 max_frame_height: 1080,
1414 frame_ids: Some(
1415 FrameIds {
1416 delta_frame_id_length: 15,
1417 additional_frame_id_length: 6,
1418 },
1419 ),
1420 use_128x128_superblock: false,
1421 enable_filter_intra: false,
1422 enable_intra_edge_filter: false,
1423 enable_interintra_compound: false,
1424 enable_masked_compound: false,
1425 enable_warped_motion: false,
1426 enable_dual_filter: false,
1427 enable_order_hint: false,
1428 enable_jnt_comp: false,
1429 enable_ref_frame_mvs: false,
1430 seq_force_screen_content_tools: 2,
1431 seq_force_integer_mv: 2,
1432 order_hint_bits: 0,
1433 enable_superres: false,
1434 enable_cdef: false,
1435 enable_restoration: false,
1436 color_config: ColorConfig {
1437 bit_depth: 8,
1438 mono_chrome: true,
1439 num_planes: 1,
1440 color_primaries: 2,
1441 transfer_characteristics: 2,
1442 matrix_coefficients: 2,
1443 full_color_range: true,
1444 subsampling_x: true,
1445 subsampling_y: true,
1446 chroma_sample_position: 0,
1447 separate_uv_delta_q: false,
1448 },
1449 film_grain_params_present: true,
1450 }
1451 ");
1452 }
1453
1454 #[test]
1455 fn test_seq_obu_parse_color_range_and_subsampling() {
1456 let mut bits = BitWriter::new(Vec::new());
1457
1458 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(
1463 &mut BitReader::new(std::io::Cursor::new(Vec::new())),
1464 0,
1465 1,
1466 13,
1467 0,
1468 8,
1469 )
1470 .unwrap();
1471
1472 assert_eq!(
1473 color_range_and_subsampling,
1474 ColorRangeAndSubsampling {
1475 color_range: true,
1476 subsampling_x: false,
1477 subsampling_y: false,
1478 }
1479 );
1480
1481 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1482 &mut BitReader::new(std::io::Cursor::new(&[0b10000000])),
1483 0,
1484 1,
1485 0,
1486 0,
1487 8,
1488 )
1489 .unwrap();
1490
1491 assert_eq!(
1492 color_range_and_subsampling,
1493 ColorRangeAndSubsampling {
1494 color_range: true,
1495 subsampling_x: true,
1496 subsampling_y: true,
1497 }
1498 );
1499
1500 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1501 &mut BitReader::new(std::io::Cursor::new(&[0b10000000])),
1502 1,
1503 1,
1504 0,
1505 0,
1506 8,
1507 )
1508 .unwrap();
1509
1510 assert_eq!(
1511 color_range_and_subsampling,
1512 ColorRangeAndSubsampling {
1513 color_range: true,
1514 subsampling_x: false,
1515 subsampling_y: false,
1516 }
1517 );
1518
1519 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1520 &mut BitReader::new(std::io::Cursor::new(&[0b11100000])),
1521 2,
1522 1,
1523 0,
1524 0,
1525 12,
1526 )
1527 .unwrap();
1528
1529 assert_eq!(
1530 color_range_and_subsampling,
1531 ColorRangeAndSubsampling {
1532 color_range: true,
1533 subsampling_x: true,
1534 subsampling_y: true,
1535 }
1536 );
1537
1538 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1539 &mut BitReader::new(std::io::Cursor::new(&[0b11000000])),
1540 2,
1541 1,
1542 0,
1543 0,
1544 12,
1545 )
1546 .unwrap();
1547
1548 assert_eq!(
1549 color_range_and_subsampling,
1550 ColorRangeAndSubsampling {
1551 color_range: true,
1552 subsampling_x: true,
1553 subsampling_y: false,
1554 }
1555 );
1556
1557 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1558 &mut BitReader::new(std::io::Cursor::new(&[0b10100000])),
1559 2,
1560 1,
1561 0,
1562 0,
1563 12,
1564 )
1565 .unwrap();
1566
1567 assert_eq!(
1568 color_range_and_subsampling,
1569 ColorRangeAndSubsampling {
1570 color_range: true,
1571 subsampling_x: false,
1572 subsampling_y: false,
1573 }
1574 );
1575
1576 let color_range_and_subsampling = ColorConfig::parse_color_range_and_subsampling(
1577 &mut BitReader::new(std::io::Cursor::new(&[0b11100000])),
1578 2,
1579 1,
1580 0,
1581 0,
1582 8,
1583 )
1584 .unwrap();
1585
1586 assert_eq!(
1587 color_range_and_subsampling,
1588 ColorRangeAndSubsampling {
1589 color_range: true,
1590 subsampling_x: true,
1591 subsampling_y: false,
1592 }
1593 );
1594 }
1595
1596 #[test]
1597 fn test_color_config_parse_bit_depth_12() {
1598 let mut bits = BitWriter::new(Vec::new());
1599
1600 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();
1606 bits.write_bits(15, 4).unwrap();
1607 bits.write_bits(1919, 16).unwrap();
1608 bits.write_bits(1079, 16).unwrap();
1609
1610 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(
1627 ObuHeader {
1628 obu_type: ObuType::SequenceHeader,
1629 size: None,
1630 extension_header: None,
1631 },
1632 &mut io::Cursor::new(bits.finish().unwrap()),
1633 )
1634 .unwrap();
1635
1636 insta::assert_debug_snapshot!(obu_header, @r"
1637 SequenceHeaderObu {
1638 header: ObuHeader {
1639 obu_type: SequenceHeader,
1640 size: None,
1641 extension_header: None,
1642 },
1643 seq_profile: 2,
1644 still_picture: true,
1645 reduced_still_picture_header: true,
1646 timing_info: None,
1647 decoder_model_info: None,
1648 operating_points: [
1649 OperatingPoint {
1650 idc: 0,
1651 seq_level_idx: 11,
1652 seq_tier: false,
1653 operating_parameters_info: None,
1654 initial_display_delay: None,
1655 },
1656 ],
1657 max_frame_width: 1920,
1658 max_frame_height: 1080,
1659 frame_ids: None,
1660 use_128x128_superblock: false,
1661 enable_filter_intra: false,
1662 enable_intra_edge_filter: false,
1663 enable_interintra_compound: false,
1664 enable_masked_compound: false,
1665 enable_warped_motion: false,
1666 enable_dual_filter: false,
1667 enable_order_hint: false,
1668 enable_jnt_comp: false,
1669 enable_ref_frame_mvs: false,
1670 seq_force_screen_content_tools: 2,
1671 seq_force_integer_mv: 2,
1672 order_hint_bits: 0,
1673 enable_superres: false,
1674 enable_cdef: false,
1675 enable_restoration: false,
1676 color_config: ColorConfig {
1677 bit_depth: 12,
1678 mono_chrome: true,
1679 num_planes: 1,
1680 color_primaries: 2,
1681 transfer_characteristics: 2,
1682 matrix_coefficients: 2,
1683 full_color_range: true,
1684 subsampling_x: true,
1685 subsampling_y: true,
1686 chroma_sample_position: 0,
1687 separate_uv_delta_q: false,
1688 },
1689 film_grain_params_present: true,
1690 }
1691 ");
1692 }
1693
1694 #[test]
1695 fn test_color_config_parse_bit_depth_10() {
1696 let mut bits = BitWriter::new(Vec::new());
1697
1698 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();
1704 bits.write_bits(15, 4).unwrap();
1705 bits.write_bits(1919, 16).unwrap();
1706 bits.write_bits(1079, 16).unwrap();
1707
1708 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(
1725 ObuHeader {
1726 obu_type: ObuType::SequenceHeader,
1727 size: None,
1728 extension_header: None,
1729 },
1730 &mut io::Cursor::new(bits.finish().unwrap()),
1731 )
1732 .unwrap();
1733
1734 insta::assert_debug_snapshot!(obu_header, @r"
1735 SequenceHeaderObu {
1736 header: ObuHeader {
1737 obu_type: SequenceHeader,
1738 size: None,
1739 extension_header: None,
1740 },
1741 seq_profile: 2,
1742 still_picture: true,
1743 reduced_still_picture_header: true,
1744 timing_info: None,
1745 decoder_model_info: None,
1746 operating_points: [
1747 OperatingPoint {
1748 idc: 0,
1749 seq_level_idx: 11,
1750 seq_tier: false,
1751 operating_parameters_info: None,
1752 initial_display_delay: None,
1753 },
1754 ],
1755 max_frame_width: 1920,
1756 max_frame_height: 1080,
1757 frame_ids: None,
1758 use_128x128_superblock: false,
1759 enable_filter_intra: false,
1760 enable_intra_edge_filter: false,
1761 enable_interintra_compound: false,
1762 enable_masked_compound: false,
1763 enable_warped_motion: false,
1764 enable_dual_filter: false,
1765 enable_order_hint: false,
1766 enable_jnt_comp: false,
1767 enable_ref_frame_mvs: false,
1768 seq_force_screen_content_tools: 2,
1769 seq_force_integer_mv: 2,
1770 order_hint_bits: 0,
1771 enable_superres: false,
1772 enable_cdef: false,
1773 enable_restoration: false,
1774 color_config: ColorConfig {
1775 bit_depth: 10,
1776 mono_chrome: true,
1777 num_planes: 1,
1778 color_primaries: 2,
1779 transfer_characteristics: 2,
1780 matrix_coefficients: 2,
1781 full_color_range: true,
1782 subsampling_x: true,
1783 subsampling_y: true,
1784 chroma_sample_position: 0,
1785 separate_uv_delta_q: false,
1786 },
1787 film_grain_params_present: true,
1788 }
1789 ");
1790 }
1791
1792 #[test]
1793 fn test_color_config_parse_csp_unknown() {
1794 let mut bits = BitWriter::new(Vec::new());
1795
1796 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();
1802 bits.write_bits(15, 4).unwrap();
1803 bits.write_bits(1919, 16).unwrap();
1804 bits.write_bits(1079, 16).unwrap();
1805
1806 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(
1821 ObuHeader {
1822 obu_type: ObuType::SequenceHeader,
1823 size: None,
1824 extension_header: None,
1825 },
1826 &mut io::Cursor::new(bits.finish().unwrap()),
1827 )
1828 .unwrap();
1829
1830 insta::assert_debug_snapshot!(obu_header, @r"
1831 SequenceHeaderObu {
1832 header: ObuHeader {
1833 obu_type: SequenceHeader,
1834 size: None,
1835 extension_header: None,
1836 },
1837 seq_profile: 1,
1838 still_picture: true,
1839 reduced_still_picture_header: true,
1840 timing_info: None,
1841 decoder_model_info: None,
1842 operating_points: [
1843 OperatingPoint {
1844 idc: 0,
1845 seq_level_idx: 11,
1846 seq_tier: false,
1847 operating_parameters_info: None,
1848 initial_display_delay: None,
1849 },
1850 ],
1851 max_frame_width: 1920,
1852 max_frame_height: 1080,
1853 frame_ids: None,
1854 use_128x128_superblock: false,
1855 enable_filter_intra: false,
1856 enable_intra_edge_filter: false,
1857 enable_interintra_compound: false,
1858 enable_masked_compound: false,
1859 enable_warped_motion: false,
1860 enable_dual_filter: false,
1861 enable_order_hint: false,
1862 enable_jnt_comp: false,
1863 enable_ref_frame_mvs: false,
1864 seq_force_screen_content_tools: 2,
1865 seq_force_integer_mv: 2,
1866 order_hint_bits: 0,
1867 enable_superres: false,
1868 enable_cdef: false,
1869 enable_restoration: false,
1870 color_config: ColorConfig {
1871 bit_depth: 8,
1872 mono_chrome: false,
1873 num_planes: 3,
1874 color_primaries: 2,
1875 transfer_characteristics: 2,
1876 matrix_coefficients: 2,
1877 full_color_range: false,
1878 subsampling_x: false,
1879 subsampling_y: false,
1880 chroma_sample_position: 0,
1881 separate_uv_delta_q: true,
1882 },
1883 film_grain_params_present: true,
1884 }
1885 ");
1886 }
1887}