1use crate::api::*;
11use crate::context::*;
12use crate::ec::*;
13use crate::lrf::*;
14use crate::partition::*;
15use crate::tiling::MAX_TILE_WIDTH;
16use crate::util::Fixed;
17use crate::util::Pixel;
18
19use crate::DeblockState;
20use crate::FrameInvariants;
21use crate::FrameState;
22use crate::SegmentationState;
23use crate::Sequence;
24
25use arrayvec::ArrayVec;
26use bitstream_io::{BigEndian, BitWrite, BitWriter, LittleEndian};
27
28use std::io;
29
30pub const PRIMARY_REF_NONE: u32 = 7;
31pub const ALL_REF_FRAMES_MASK: u32 = (1 << REF_FRAMES) - 1;
32
33const PRIMARY_REF_BITS: u32 = 3;
34
35#[allow(unused)]
36const OP_POINTS_IDC_BITS: usize = 12;
37#[allow(unused)]
38const LEVEL_MAJOR_MIN: usize = 2;
39#[allow(unused)]
40const LEVEL_MAJOR_BITS: usize = 3;
41#[allow(unused)]
42const LEVEL_MINOR_BITS: usize = 2;
43#[allow(unused)]
44const LEVEL_BITS: usize = LEVEL_MAJOR_BITS + LEVEL_MINOR_BITS;
45
46#[allow(dead_code, non_camel_case_types)]
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum ReferenceMode {
49 SINGLE = 0,
50 COMPOUND = 1,
51 SELECT = 2,
52}
53
54#[allow(non_camel_case_types)]
55#[allow(unused)]
56pub enum ObuType {
57 OBU_SEQUENCE_HEADER = 1,
58 OBU_TEMPORAL_DELIMITER = 2,
59 OBU_FRAME_HEADER = 3,
60 OBU_TILE_GROUP = 4,
61 OBU_METADATA = 5,
62 OBU_FRAME = 6,
63 OBU_REDUNDANT_FRAME_HEADER = 7,
64 OBU_TILE_LIST = 8,
65 OBU_PADDING = 15,
66}
67
68#[derive(Clone, Copy)]
69#[allow(non_camel_case_types)]
70#[allow(unused)]
71pub enum ObuMetaType {
72 OBU_META_HDR_CLL = 1,
73 OBU_META_HDR_MDCV = 2,
74 OBU_META_SCALABILITY = 3,
75 OBU_META_ITUT_T35 = 4,
76 OBU_META_TIMECODE = 5,
77}
78
79impl ObuMetaType {
80 const fn size(self) -> u64 {
81 use self::ObuMetaType::*;
82 match self {
83 OBU_META_HDR_CLL => 4,
84 OBU_META_HDR_MDCV => 24,
85 _ => 0,
86 }
87 }
88}
89
90pub trait ULEB128Writer {
91 fn write_uleb128(&mut self, payload: u64) -> io::Result<()>;
92}
93
94impl<W: io::Write> ULEB128Writer for BitWriter<W, BigEndian> {
95 fn write_uleb128(&mut self, payload: u64) -> io::Result<()> {
96 let mut coded_value: ArrayVec<u8, 8> = ArrayVec::new();
101
102 let mut value = payload as u32;
103 loop {
104 let mut byte = (value & 0x7f) as u8;
105 value >>= 7u8;
106 if value != 0 {
107 byte |= 0x80;
109 }
110 coded_value.push(byte);
111
112 if value == 0 {
113 break;
116 }
117 }
118
119 self.write_bytes(&coded_value)?;
120
121 Ok(())
122 }
123}
124
125pub trait LEWriter {
126 fn write_le(&mut self, bytes: u32, payload: u64) -> io::Result<()>;
127}
128
129impl<W: io::Write> LEWriter for BitWriter<W, BigEndian> {
131 fn write_le(&mut self, bytes: u32, value: u64) -> io::Result<()> {
132 let mut data = Vec::new();
133 let mut bwle = BitWriter::endian(&mut data, LittleEndian);
134 bwle.write_var(bytes * 8, value)?;
135 self.write_bytes(&data)
136 }
137}
138
139pub trait UncompressedHeader {
140 fn write_obu_header(
142 &mut self, obu_type: ObuType, obu_extension: u32,
143 ) -> io::Result<()>;
144 fn write_sequence_metadata_obu(
145 &mut self, obu_meta_type: ObuMetaType, seq: &Sequence,
146 ) -> io::Result<()>;
147 fn write_sequence_header_obu<T: Pixel>(
148 &mut self, fi: &FrameInvariants<T>,
149 ) -> io::Result<()>;
150 fn write_frame_header_obu<T: Pixel>(
151 &mut self, fi: &FrameInvariants<T>, fs: &FrameState<T>,
152 inter_cfg: &InterConfig,
153 ) -> io::Result<()>;
154 fn write_sequence_header<T: Pixel>(
155 &mut self, fi: &FrameInvariants<T>,
156 ) -> io::Result<()>;
157 fn write_color_config(&mut self, seq: &Sequence) -> io::Result<()>;
158 fn write_t35_metadata_obu(&mut self, t35: &T35) -> io::Result<()>;
159 fn write_max_frame_size<T: Pixel>(
162 &mut self, fi: &FrameInvariants<T>,
163 ) -> io::Result<()>;
164 fn write_frame_size<T: Pixel>(
165 &mut self, fi: &FrameInvariants<T>,
166 ) -> io::Result<()>;
167 fn write_render_size<T: Pixel>(
168 &mut self, fi: &FrameInvariants<T>,
169 ) -> io::Result<()>;
170 fn write_frame_size_with_refs<T: Pixel>(
171 &mut self, fi: &FrameInvariants<T>,
172 ) -> io::Result<()>;
173 fn write_deblock_filter_a<T: Pixel>(
174 &mut self, fi: &FrameInvariants<T>, deblock: &DeblockState,
175 ) -> io::Result<()>;
176 fn write_deblock_filter_b<T: Pixel>(
177 &mut self, fi: &FrameInvariants<T>, deblock: &DeblockState,
178 ) -> io::Result<()>;
179 fn write_frame_cdef<T: Pixel>(
180 &mut self, fi: &FrameInvariants<T>,
181 ) -> io::Result<()>;
182 fn write_frame_lrf<T: Pixel>(
183 &mut self, fi: &FrameInvariants<T>, rs: &RestorationState,
184 ) -> io::Result<()>;
185 fn write_segment_data<T: Pixel>(
186 &mut self, fi: &FrameInvariants<T>, segmentation: &SegmentationState,
187 ) -> io::Result<()>;
188 fn write_delta_q(&mut self, delta_q: i8) -> io::Result<()>;
189}
190
191impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
192 fn write_obu_header(
195 &mut self, obu_type: ObuType, obu_extension: u32,
196 ) -> io::Result<()> {
197 self.write_bit(false)?; self.write::<4, u8>(obu_type as u8)?;
199 self.write_bit(obu_extension != 0)?;
200 self.write_bit(true)?; self.write_bit(false)?; if obu_extension != 0 {
204 unimplemented!();
205 }
207
208 Ok(())
209 }
210
211 fn write_sequence_metadata_obu(
212 &mut self, obu_meta_type: ObuMetaType, seq: &Sequence,
213 ) -> io::Result<()> {
214 self.write_obu_header(ObuType::OBU_METADATA, 0)?;
216
217 self.write_uleb128(obu_meta_type.size() + 2)?;
222
223 self.write_uleb128(obu_meta_type as u64)?;
225
226 match obu_meta_type {
227 ObuMetaType::OBU_META_HDR_CLL => {
228 let cll = seq.content_light.unwrap();
229 self.write::<16, u16>(cll.max_content_light_level)?;
230 self.write::<16, u16>(cll.max_frame_average_light_level)?;
231 }
232 ObuMetaType::OBU_META_HDR_MDCV => {
233 let mdcv = seq.mastering_display.unwrap();
234 for i in 0..3 {
235 self.write::<16, u16>(mdcv.primaries[i].x)?;
236 self.write::<16, u16>(mdcv.primaries[i].y)?;
237 }
238
239 self.write::<16, u16>(mdcv.white_point.x)?;
240 self.write::<16, u16>(mdcv.white_point.y)?;
241
242 self.write::<32, u32>(mdcv.max_luminance)?;
243 self.write::<32, u32>(mdcv.min_luminance)?;
244 }
245 _ => {}
246 }
247
248 self.write_bit(true)?;
250 self.byte_align()?;
251
252 Ok(())
253 }
254
255 fn write_t35_metadata_obu(&mut self, t35: &T35) -> io::Result<()> {
256 self.write_obu_header(ObuType::OBU_METADATA, 0)?;
257
258 self.write_uleb128(
260 t35.data.len() as u64 + if t35.country_code == 0xFF { 4 } else { 3 },
261 )?;
262
263 self.write_uleb128(ObuMetaType::OBU_META_ITUT_T35 as u64)?;
264
265 self.write::<8, u8>(t35.country_code)?;
266 if t35.country_code == 0xFF {
267 self.write::<8, u8>(t35.country_code_extension_byte)?;
268 }
269 self.write_bytes(&t35.data)?;
270
271 self.write_bit(true)?;
273 self.byte_align()?;
274
275 Ok(())
276 }
277
278 fn write_sequence_header_obu<T: Pixel>(
279 &mut self, fi: &FrameInvariants<T>,
280 ) -> io::Result<()> {
281 assert!(
282 !fi.sequence.reduced_still_picture_hdr || fi.sequence.still_picture
283 );
284
285 self.write::<3, u8>(fi.sequence.profile)?; self.write_bit(fi.sequence.still_picture)?; self.write_bit(fi.sequence.reduced_still_picture_hdr)?; assert!(fi.sequence.level_idx[0] <= 31);
290 if fi.sequence.reduced_still_picture_hdr {
291 assert!(!fi.sequence.timing_info_present);
292 assert!(!fi.sequence.decoder_model_info_present_flag);
293 assert_eq!(fi.sequence.operating_points_cnt_minus_1, 0);
294 assert_eq!(fi.sequence.operating_point_idc[0], 0);
295 self.write::<5, u8>(fi.sequence.level_idx[0])?; assert_eq!(fi.sequence.tier[0], 0);
297 } else {
298 self.write_bit(fi.sequence.timing_info_present)?; if fi.sequence.timing_info_present {
301 self.write::<32, u64>(fi.sequence.time_base.num)?;
302 self.write::<32, u64>(fi.sequence.time_base.den)?;
303
304 self.write_bit(true)?; self.write_bit(true)?; self.write_bit(false)?; }
308
309 self.write_bit(false)?; self.write::<5, u8>(0)?; self.write::<12, u16>(0)?; self.write::<5, u8>(fi.sequence.level_idx[0])?; if fi.sequence.level_idx[0] > 7 {
314 self.write::<1, u8>(0)?; }
316 }
317
318 self.write_sequence_header(fi)?;
319
320 self.write_color_config(&fi.sequence)?;
321
322 self.write_bit(fi.sequence.film_grain_params_present)?;
323
324 Ok(())
325 }
326
327 fn write_sequence_header<T: Pixel>(
328 &mut self, fi: &FrameInvariants<T>,
329 ) -> io::Result<()> {
330 self.write_max_frame_size(fi)?;
331
332 let seq = &fi.sequence;
333
334 if seq.reduced_still_picture_hdr {
335 assert!(!seq.frame_id_numbers_present_flag);
336 } else {
337 self.write_bit(seq.frame_id_numbers_present_flag)?;
338 }
339
340 if seq.frame_id_numbers_present_flag {
341 self.write::<4, u32>(seq.delta_frame_id_length - 2)?;
345 self.write::<3, u32>(
346 seq.frame_id_length - seq.delta_frame_id_length - 1,
347 )?;
348 }
349
350 self.write_bit(seq.use_128x128_superblock)?;
351 self.write_bit(seq.enable_filter_intra)?;
352 self.write_bit(seq.enable_intra_edge_filter)?;
353
354 if seq.reduced_still_picture_hdr {
355 assert!(!seq.enable_interintra_compound);
356 assert!(!seq.enable_masked_compound);
357 assert!(!seq.enable_warped_motion);
358 assert!(!seq.enable_dual_filter);
359 assert!(!seq.enable_order_hint);
360 assert!(!seq.enable_jnt_comp);
361 assert!(!seq.enable_ref_frame_mvs);
362 assert!(seq.force_screen_content_tools == 2);
363 assert!(seq.force_integer_mv == 2);
364 } else {
365 self.write_bit(seq.enable_interintra_compound)?;
366 self.write_bit(seq.enable_masked_compound)?;
367 self.write_bit(seq.enable_warped_motion)?;
368 self.write_bit(seq.enable_dual_filter)?;
369 self.write_bit(seq.enable_order_hint)?;
370
371 if seq.enable_order_hint {
372 self.write_bit(seq.enable_jnt_comp)?;
373 self.write_bit(seq.enable_ref_frame_mvs)?;
374 }
375
376 if seq.force_screen_content_tools == 2 {
377 self.write_bit(true)?;
378 } else {
379 self.write_bit(false)?;
380 self.write_bit(seq.force_screen_content_tools != 0)?;
381 }
382 if seq.force_screen_content_tools > 0 {
383 if seq.force_integer_mv == 2 {
384 self.write_bit(true)?;
385 } else {
386 self.write_bit(false)?;
387 self.write_bit(seq.force_integer_mv != 0)?;
388 }
389 } else {
390 assert!(seq.force_integer_mv == 2);
391 }
392 if seq.enable_order_hint {
393 self.write::<3, u32>(seq.order_hint_bits_minus_1)?;
394 }
395 }
396
397 self.write_bit(seq.enable_superres)?;
398 self.write_bit(seq.enable_cdef)?;
399 self.write_bit(seq.enable_restoration)?;
400
401 Ok(())
402 }
403
404 fn write_color_config(&mut self, seq: &Sequence) -> io::Result<()> {
406 let high_bitdepth = seq.bit_depth > 8;
407 self.write_bit(high_bitdepth)?;
408 if seq.profile == 2 && high_bitdepth {
409 self.write_bit(seq.bit_depth == 12)?; }
411
412 let monochrome = seq.chroma_sampling == ChromaSampling::Cs400;
413 if seq.profile == 1 {
414 assert!(!monochrome);
415 } else {
416 self.write_bit(monochrome)?; }
418
419 self.write_bit(seq.color_description.is_some())?;
421 let mut srgb_triple = false;
422 if let Some(color_description) = seq.color_description {
423 self.write::<8, _>(color_description.color_primaries as u8)?;
424 self.write::<8, _>(color_description.transfer_characteristics as u8)?;
425 self.write::<8, _>(color_description.matrix_coefficients as u8)?;
426 srgb_triple = color_description.is_srgb_triple();
427 }
428
429 if monochrome || !srgb_triple {
430 self.write_bit(seq.pixel_range == PixelRange::Full)?; }
432 if monochrome {
433 return Ok(());
434 } else if srgb_triple {
435 assert!(seq.pixel_range == PixelRange::Full);
436 assert!(seq.chroma_sampling == ChromaSampling::Cs444);
437 } else {
438 if seq.profile == 0 {
439 assert!(seq.chroma_sampling == ChromaSampling::Cs420);
440 } else if seq.profile == 1 {
441 assert!(seq.chroma_sampling == ChromaSampling::Cs444);
442 } else if seq.bit_depth == 12 {
443 let subsampling_x = seq.chroma_sampling != ChromaSampling::Cs444;
444 let subsampling_y = seq.chroma_sampling == ChromaSampling::Cs420;
445 self.write_bit(subsampling_x)?;
446 if subsampling_x {
447 self.write_bit(subsampling_y)?;
448 }
449 } else {
450 assert!(seq.chroma_sampling == ChromaSampling::Cs422);
451 }
452 if seq.chroma_sampling == ChromaSampling::Cs420 {
453 self.write::<2, u8>(seq.chroma_sample_position as u8)?;
454 }
455 }
456 self.write_bit(true)?; Ok(())
459 }
460
461 #[allow(unused)]
462 fn write_frame_header_obu<T: Pixel>(
463 &mut self, fi: &FrameInvariants<T>, fs: &FrameState<T>,
464 inter_cfg: &InterConfig,
465 ) -> io::Result<()> {
466 if fi.sequence.reduced_still_picture_hdr {
467 assert!(!fi.is_show_existing_frame());
468 assert!(fi.frame_type == FrameType::KEY);
469 assert!(fi.show_frame);
470 assert!(!fi.showable_frame);
471 } else {
472 self.write_bit(fi.is_show_existing_frame())?;
473
474 if fi.is_show_existing_frame() {
475 self.write::<3, u32>(fi.frame_to_show_map_idx)?;
476
477 self.write_bit(true)?; self.byte_align()?;
489 return Ok(());
490 }
491
492 self.write::<2, u8>(fi.frame_type as u8)?;
493 self.write_bit(fi.show_frame)?; if fi.show_frame {
496 } else {
503 self.write_bit(fi.showable_frame)?;
504 }
505
506 if fi.error_resilient {
507 assert!(fi.primary_ref_frame == PRIMARY_REF_NONE);
508 }
509 if fi.frame_type == FrameType::SWITCH {
510 assert!(fi.error_resilient);
511 } else if !(fi.frame_type == FrameType::KEY && fi.show_frame) {
512 self.write_bit(fi.error_resilient)?; }
514 }
515
516 self.write_bit(fi.disable_cdf_update)?;
517
518 if fi.sequence.force_screen_content_tools == 2 {
519 self.write_bit(fi.allow_screen_content_tools != 0)?;
520 } else {
521 assert!(
522 fi.allow_screen_content_tools
523 == fi.sequence.force_screen_content_tools
524 );
525 }
526
527 if fi.allow_screen_content_tools > 0 {
528 if fi.sequence.force_integer_mv == 2 {
529 self.write_bit(fi.force_integer_mv != 0)?;
530 } else {
531 assert!(fi.force_integer_mv == fi.sequence.force_integer_mv);
532 }
533 }
534
535 assert!(
536 fi.force_integer_mv
537 == u32::from(fi.frame_type == FrameType::KEY || fi.intra_only)
538 );
539
540 if fi.sequence.frame_id_numbers_present_flag {
541 unimplemented!();
542
543 }
547
548 if fi.frame_type != FrameType::SWITCH
549 && !fi.sequence.reduced_still_picture_hdr
550 {
551 self.write_bit(fi.frame_size_override_flag)?; }
553
554 if fi.sequence.enable_order_hint {
555 let n = fi.sequence.order_hint_bits_minus_1 + 1;
556 let mask = (1 << n) - 1;
557 self.write_var(n, fi.order_hint & mask)?;
558 }
559
560 if !fi.error_resilient && !fi.intra_only {
561 self.write::<PRIMARY_REF_BITS, u32>(fi.primary_ref_frame)?;
562 }
563
564 if fi.sequence.decoder_model_info_present_flag {
565 unimplemented!();
566 }
567
568 if fi.frame_type == FrameType::KEY {
569 if !fi.show_frame {
570 unimplemented!();
572 self.write_var(REF_FRAMES as u32, fi.refresh_frame_flags)?;
573 } else {
574 assert!(fi.refresh_frame_flags == ALL_REF_FRAMES_MASK);
575 }
576 } else if fi.frame_type == FrameType::SWITCH {
577 assert!(fi.refresh_frame_flags == ALL_REF_FRAMES_MASK);
578 } else {
579 if fi.intra_only {
581 assert!(fi.refresh_frame_flags != ALL_REF_FRAMES_MASK);
582 } else {
583 }
585 self.write_var(REF_FRAMES as u32, fi.refresh_frame_flags)?;
586 };
587
588 if (!fi.intra_only || fi.refresh_frame_flags != ALL_REF_FRAMES_MASK) {
589 if (fi.error_resilient && fi.sequence.enable_order_hint) {
591 for i in 0..REF_FRAMES {
592 let n = fi.sequence.order_hint_bits_minus_1 + 1;
593 let mask = (1 << n) - 1;
594 if let Some(ref rec) = fi.rec_buffer.frames[i] {
595 let ref_hint = rec.order_hint;
596 self.write_var(n, ref_hint & mask)?;
597 } else {
598 self.write_var(n, 0)?;
599 }
600 }
601 }
602 }
603
604 if fi.intra_only {
606 self.write_frame_size(fi)?;
607 self.write_render_size(fi)?;
608 if fi.allow_screen_content_tools != 0 {
609 self.write_bit(fi.allow_intrabc)?;
611 }
612 }
613
614 let frame_refs_short_signaling = false;
615 if fi.frame_type == FrameType::KEY || fi.intra_only {
616 } else {
618 if fi.sequence.enable_order_hint {
619 self.write_bit(frame_refs_short_signaling)?;
620 if frame_refs_short_signaling {
621 unimplemented!();
622 }
623 }
624
625 for i in 0..INTER_REFS_PER_FRAME {
626 if !frame_refs_short_signaling {
627 self.write_var(REF_FRAMES_LOG2 as u32, fi.ref_frames[i])?;
628 }
629 if fi.sequence.frame_id_numbers_present_flag {
630 unimplemented!();
631 }
632 }
633
634 if !fi.error_resilient && fi.frame_size_override_flag {
635 self.write_frame_size_with_refs(fi)?;
636 } else {
637 self.write_frame_size(fi)?;
638 self.write_render_size(fi)?;
639 }
640
641 if fi.force_integer_mv == 0 {
642 self.write_bit(fi.allow_high_precision_mv);
643 }
644
645 self.write_bit(fi.is_filter_switchable)?;
646 if !fi.is_filter_switchable {
647 self.write::<2, u8>(fi.default_filter as u8)?;
648 }
649 self.write_bit(fi.is_motion_mode_switchable)?;
650
651 if (!fi.error_resilient && fi.sequence.enable_ref_frame_mvs) {
652 self.write_bit(fi.use_ref_frame_mvs)?;
653 }
654 }
655
656 if fi.sequence.reduced_still_picture_hdr || fi.disable_cdf_update {
657 assert!(fi.disable_frame_end_update_cdf);
658 } else {
659 self.write_bit(fi.disable_frame_end_update_cdf)?;
660 }
661
662 let ti = &fi.sequence.tiling;
669
670 if fi.sb_width.align_power_of_two_and_shift(ti.tile_cols_log2)
671 == ti.tile_width_sb
672 && fi.sb_height.align_power_of_two_and_shift(ti.tile_rows_log2)
673 == ti.tile_height_sb
674 {
675 self.write_bit(true)?; let cols_ones = ti.tile_cols_log2 - ti.min_tile_cols_log2;
682 for _ in 0..cols_ones {
683 self.write_bit(true);
684 }
685 if ti.tile_cols_log2 < ti.max_tile_cols_log2 {
686 self.write_bit(false);
687 }
688
689 let rows_ones = ti.tile_rows_log2 - ti.min_tile_rows_log2;
690 for _ in 0..rows_ones {
691 self.write_bit(true);
692 }
693 if ti.tile_rows_log2 < ti.max_tile_rows_log2 {
694 self.write_bit(false);
695 }
696 } else {
697 self.write_bit(false)?; let mut sofar = 0;
699 let mut widest_tile_sb = 0;
700 for _ in 0..ti.cols {
701 let max = (MAX_TILE_WIDTH
702 >> if fi.sequence.use_128x128_superblock { 7 } else { 6 })
703 .min(fi.sb_width - sofar) as u16;
704 let this_sb_width = ti.tile_width_sb.min(fi.sb_width - sofar);
705 self.write_quniform(max, (this_sb_width - 1) as u16);
706 sofar += this_sb_width;
707 widest_tile_sb = widest_tile_sb.max(this_sb_width);
708 }
709
710 let max_tile_area_sb = if ti.min_tiles_log2 > 0 {
711 (fi.sb_height * fi.sb_width) >> (ti.min_tiles_log2 + 1)
712 } else {
713 fi.sb_height * fi.sb_width
714 };
715
716 let max_tile_height_sb = (max_tile_area_sb / widest_tile_sb).max(1);
717
718 sofar = 0;
719 for i in 0..ti.rows {
720 let max = max_tile_height_sb.min(fi.sb_height - sofar) as u16;
721 let this_sb_height = ti.tile_height_sb.min(fi.sb_height - sofar);
722
723 self.write_quniform(max, (this_sb_height - 1) as u16);
724 sofar += this_sb_height;
725 }
726 }
727
728 let tiles_log2 = ti.tile_cols_log2 + ti.tile_rows_log2;
729 if tiles_log2 > 0 {
730 self.write_var(tiles_log2 as u32, fs.context_update_tile_id as u32)?;
733
734 self.write::<2, u32>(fs.max_tile_size_bytes - 1)?;
736 }
737
738 assert!(fi.base_q_idx > 0);
740 self.write::<8, u8>(fi.base_q_idx)?; self.write_delta_q(fi.dc_delta_q[0])?;
742 if fi.sequence.chroma_sampling != ChromaSampling::Cs400 {
743 assert!(fi.ac_delta_q[0] == 0);
744 let diff_uv_delta = fi.dc_delta_q[1] != fi.dc_delta_q[2]
745 || fi.ac_delta_q[1] != fi.ac_delta_q[2];
746 self.write_bit(diff_uv_delta)?;
747 self.write_delta_q(fi.dc_delta_q[1])?;
748 self.write_delta_q(fi.ac_delta_q[1])?;
749 if diff_uv_delta {
750 self.write_delta_q(fi.dc_delta_q[2])?;
751 self.write_delta_q(fi.ac_delta_q[2])?;
752 }
753 }
754 self.write_bit(false)?; self.write_segment_data(fi, &fs.segmentation)?;
758
759 self.write_bit(false)?; self.write_deblock_filter_a(fi, &fs.deblock)?;
764
765 self.write_deblock_filter_b(fi, &fs.deblock)?;
769
770 self.write_frame_cdef(fi)?;
772
773 self.write_frame_lrf(fi, &fs.restoration)?;
775
776 self.write_bit(fi.tx_mode_select)?; let mut reference_select = false;
779 if !fi.intra_only {
780 reference_select = fi.reference_mode != ReferenceMode::SINGLE;
781 self.write_bit(reference_select)?;
782 }
783
784 let skip_mode_allowed =
785 fi.sequence.get_skip_mode_allowed(fi, inter_cfg, reference_select);
786 if skip_mode_allowed {
787 self.write_bit(false)?; }
789
790 if fi.intra_only || fi.error_resilient || !fi.sequence.enable_warped_motion
791 {
792 } else {
793 self.write_bit(fi.allow_warped_motion)?; }
795
796 self.write_bit(fi.use_reduced_tx_set)?; if !fi.intra_only {
800 for i in 0..7 {
801 let mode = fi.globalmv_transformation_type[i];
802 self.write_bit(mode != GlobalMVMode::IDENTITY)?;
803 if mode != GlobalMVMode::IDENTITY {
804 self.write_bit(mode == GlobalMVMode::ROTZOOM)?;
805 if mode != GlobalMVMode::ROTZOOM {
806 self.write_bit(mode == GlobalMVMode::TRANSLATION)?;
807 }
808 }
809 match mode {
810 GlobalMVMode::IDENTITY => { }
811 GlobalMVMode::TRANSLATION => {
812 let mv_x = 0;
813 let mv_x_ref = 0;
814 let mv_y = 0;
815 let mv_y_ref = 0;
816 let bits = 12 - 6 + 3 - !fi.allow_high_precision_mv as u8;
817 let bits_diff = 12 - 3 + fi.allow_high_precision_mv as u8;
818 BCodeWriter::write_s_refsubexpfin(
819 self,
820 (1 << bits) + 1,
821 3,
822 mv_x_ref >> bits_diff,
823 mv_x >> bits_diff,
824 )?;
825 BCodeWriter::write_s_refsubexpfin(
826 self,
827 (1 << bits) + 1,
828 3,
829 mv_y_ref >> bits_diff,
830 mv_y >> bits_diff,
831 )?;
832 }
833 GlobalMVMode::ROTZOOM => unimplemented!(),
834 GlobalMVMode::AFFINE => unimplemented!(),
835 };
836 }
837 }
838
839 if fi.sequence.film_grain_params_present {
840 if let Some(grain_params) = fi.film_grain_params() {
841 self.write_bit(true)?;
843 self.write::<16, u16>(grain_params.random_seed)?;
844 if fi.frame_type == FrameType::INTER {
845 self.write_bit(true)?;
849 }
850
851 self.write::<4, u8>(grain_params.scaling_points_y.len() as u8)?;
852 for point in &grain_params.scaling_points_y {
853 self.write::<8, u8>(point[0])?;
854 self.write::<8, u8>(point[1])?;
855 }
856
857 let chroma_scaling_from_luma =
858 if fi.sequence.chroma_sampling != ChromaSampling::Cs400 {
859 self.write_bit(grain_params.chroma_scaling_from_luma)?;
860 grain_params.chroma_scaling_from_luma
861 } else {
862 false
863 };
864 if !(fi.sequence.chroma_sampling == ChromaSampling::Cs400
865 || chroma_scaling_from_luma
866 || (fi.sequence.chroma_sampling == ChromaSampling::Cs420
867 && grain_params.scaling_points_y.is_empty()))
868 {
869 self.write::<4, u8>(grain_params.scaling_points_cb.len() as u8)?;
870 for point in &grain_params.scaling_points_cb {
871 self.write::<8, u8>(point[0])?;
872 self.write::<8, u8>(point[1])?;
873 }
874 self.write::<4, u8>(grain_params.scaling_points_cr.len() as u8)?;
875 for point in &grain_params.scaling_points_cr {
876 self.write::<8, u8>(point[0])?;
877 self.write::<8, u8>(point[1])?;
878 }
879 }
880
881 self.write::<2, u8>(grain_params.scaling_shift - 8)?;
882 self.write::<2, u8>(grain_params.ar_coeff_lag)?;
883
884 let mut num_pos_luma =
885 (2 * grain_params.ar_coeff_lag * (grain_params.ar_coeff_lag + 1))
886 as usize;
887 let mut num_pos_chroma;
888 if !grain_params.scaling_points_y.is_empty() {
889 num_pos_chroma = num_pos_luma + 1;
890 for i in 0..num_pos_luma {
891 self.write::<8, u8>(
892 (grain_params.ar_coeffs_y[i] as i16 + 128) as u8,
893 )?;
894 }
895 } else {
896 num_pos_chroma = num_pos_luma;
897 }
898
899 if chroma_scaling_from_luma
900 || !grain_params.scaling_points_cb.is_empty()
901 {
902 for i in 0..num_pos_chroma {
903 self.write::<8, u8>(
904 (grain_params.ar_coeffs_cb[i] as i16 + 128) as u8,
905 )?;
906 }
907 }
908 if chroma_scaling_from_luma
909 || !grain_params.scaling_points_cr.is_empty()
910 {
911 for i in 0..num_pos_chroma {
912 self.write::<8, u8>(
913 (grain_params.ar_coeffs_cr[i] as i16 + 128) as u8,
914 )?;
915 }
916 }
917
918 self.write::<2, u8>(grain_params.ar_coeff_shift - 6)?;
919 self.write::<2, u8>(grain_params.grain_scale_shift)?;
920 if !grain_params.scaling_points_cb.is_empty() {
921 self.write::<8, u8>(grain_params.cb_mult)?;
922 self.write::<8, u8>(grain_params.cb_luma_mult)?;
923 self.write::<9, u16>(grain_params.cb_offset)?;
924 }
925 if !grain_params.scaling_points_cr.is_empty() {
926 self.write::<8, u8>(grain_params.cr_mult)?;
927 self.write::<8, u8>(grain_params.cr_luma_mult)?;
928 self.write::<9, u16>(grain_params.cr_offset)?;
929 }
930 self.write_bit(grain_params.overlap_flag)?;
931 self.write_bit(fi.sequence.pixel_range == PixelRange::Limited)?;
932 } else {
933 self.write_bit(false)?;
935 }
936 }
937
938 if fi.large_scale_tile {
939 unimplemented!();
940 }
941 self.byte_align()?;
942
943 Ok(())
944 }
945 fn write_max_frame_size<T: Pixel>(
948 &mut self, fi: &FrameInvariants<T>,
949 ) -> io::Result<()> {
950 let width = fi.width - 1;
953 let height = fi.height - 1;
954 let width_bits = log_in_base_2(width as u32) as u32 + 1;
955 let height_bits = log_in_base_2(height as u32) as u32 + 1;
956 assert!(width_bits <= 16);
957 assert!(height_bits <= 16);
958 self.write::<4, u32>(width_bits - 1)?;
959 self.write::<4, u32>(height_bits - 1)?;
960 self.write_var(width_bits, width as u16)?;
961 self.write_var(height_bits, height as u16)?;
962 Ok(())
963 }
964
965 fn write_frame_size<T: Pixel>(
966 &mut self, fi: &FrameInvariants<T>,
967 ) -> io::Result<()> {
968 if fi.frame_size_override_flag {
971 let width = fi.width - 1;
972 let height = fi.height - 1;
973 let width_bits = log_in_base_2(width as u32) as u32 + 1;
974 let height_bits = log_in_base_2(height as u32) as u32 + 1;
975 assert!(width_bits <= 16);
976 assert!(height_bits <= 16);
977 self.write_var(width_bits, width as u16)?;
978 self.write_var(height_bits, height as u16)?;
979 }
980 if fi.sequence.enable_superres {
981 unimplemented!();
982 }
983 Ok(())
984 }
985
986 fn write_render_size<T: Pixel>(
987 &mut self, fi: &FrameInvariants<T>,
988 ) -> io::Result<()> {
989 self.write_bit(fi.render_and_frame_size_different)?;
990 if fi.render_and_frame_size_different {
991 self.write::<16, u32>(fi.render_width - 1)?;
992 self.write::<16, u32>(fi.render_height - 1)?;
993 }
994 Ok(())
995 }
996
997 fn write_frame_size_with_refs<T: Pixel>(
998 &mut self, fi: &FrameInvariants<T>,
999 ) -> io::Result<()> {
1000 let mut found_ref = false;
1001 for i in 0..INTER_REFS_PER_FRAME {
1002 if let Some(ref rec) = fi.rec_buffer.frames[fi.ref_frames[i] as usize] {
1003 if rec.width == fi.width as u32
1004 && rec.height == fi.height as u32
1005 && rec.render_width == fi.render_width
1006 && rec.render_height == fi.render_height
1007 {
1008 self.write_bit(true)?;
1009 found_ref = true;
1010 break;
1011 } else {
1012 self.write_bit(false)?;
1013 }
1014 } else {
1015 self.write_bit(false)?;
1016 }
1017 }
1018 if !found_ref {
1019 self.write_frame_size(fi)?;
1020 self.write_render_size(fi)?;
1021 } else if fi.sequence.enable_superres {
1022 unimplemented!();
1023 }
1024 Ok(())
1025 }
1026
1027 fn write_deblock_filter_a<T: Pixel>(
1028 &mut self, fi: &FrameInvariants<T>, deblock: &DeblockState,
1029 ) -> io::Result<()> {
1030 if fi.delta_q_present {
1031 if !fi.allow_intrabc {
1032 self.write_bit(deblock.block_deltas_enabled)?;
1033 }
1034 if deblock.block_deltas_enabled {
1035 self.write::<2, u8>(deblock.block_delta_shift)?;
1036 self.write_bit(deblock.block_delta_multi)?;
1037 }
1038 }
1039 Ok(())
1040 }
1041
1042 fn write_deblock_filter_b<T: Pixel>(
1043 &mut self, fi: &FrameInvariants<T>, deblock: &DeblockState,
1044 ) -> io::Result<()> {
1045 let planes = if fi.sequence.chroma_sampling == ChromaSampling::Cs400 {
1046 1
1047 } else {
1048 MAX_PLANES
1049 };
1050 assert!(deblock.levels[0] < 64);
1051 self.write::<6, u8>(deblock.levels[0])?; assert!(deblock.levels[1] < 64);
1053 self.write::<6, u8>(deblock.levels[1])?; if planes > 1 && (deblock.levels[0] > 0 || deblock.levels[1] > 0) {
1055 assert!(deblock.levels[2] < 64);
1056 self.write::<6, u8>(deblock.levels[2])?; assert!(deblock.levels[3] < 64);
1058 self.write::<6, u8>(deblock.levels[3])?; }
1060 self.write::<3, u8>(deblock.sharpness)?; self.write_bit(deblock.deltas_enabled)?; if deblock.deltas_enabled {
1063 self.write_bit(deblock.delta_updates_enabled)?; if deblock.delta_updates_enabled {
1065 let prev_ref_deltas = if fi.primary_ref_frame == PRIMARY_REF_NONE {
1067 [1, 0, 0, 0, 0, -1, -1, -1]
1068 } else {
1069 fi.rec_buffer.deblock
1070 [fi.ref_frames[fi.primary_ref_frame as usize] as usize]
1071 .ref_deltas
1072 };
1073 for i in 0..REF_FRAMES {
1074 let update = deblock.ref_deltas[i] != prev_ref_deltas[i];
1075 self.write_bit(update)?;
1076 if update {
1077 self.write_signed::<7, i8>(deblock.ref_deltas[i])?;
1078 }
1079 }
1080 let prev_mode_deltas = if fi.primary_ref_frame == PRIMARY_REF_NONE {
1082 [0, 0]
1083 } else {
1084 fi.rec_buffer.deblock
1085 [fi.ref_frames[fi.primary_ref_frame as usize] as usize]
1086 .mode_deltas
1087 };
1088 for i in 0..2 {
1089 let update = deblock.mode_deltas[i] != prev_mode_deltas[i];
1090 self.write_bit(update)?;
1091 if update {
1092 self.write_signed::<7, i8>(deblock.mode_deltas[i])?;
1093 }
1094 }
1095 }
1096 }
1097 Ok(())
1098 }
1099
1100 fn write_frame_cdef<T: Pixel>(
1101 &mut self, fi: &FrameInvariants<T>,
1102 ) -> io::Result<()> {
1103 if fi.sequence.enable_cdef && !fi.allow_intrabc {
1104 assert!(fi.cdef_damping >= 3);
1105 assert!(fi.cdef_damping <= 6);
1106 self.write::<2, u8>(fi.cdef_damping - 3)?;
1107 assert!(fi.cdef_bits < 4);
1108 self.write::<2, u8>(fi.cdef_bits)?; for i in 0..(1 << fi.cdef_bits) {
1110 assert!(fi.cdef_y_strengths[i] < 64);
1111 assert!(fi.cdef_uv_strengths[i] < 64);
1112 self.write::<6, u8>(fi.cdef_y_strengths[i])?; if fi.sequence.chroma_sampling != ChromaSampling::Cs400 {
1114 self.write::<6, u8>(fi.cdef_uv_strengths[i])?; }
1116 }
1117 }
1118 Ok(())
1119 }
1120
1121 fn write_frame_lrf<T: Pixel>(
1122 &mut self, fi: &FrameInvariants<T>, rs: &RestorationState,
1123 ) -> io::Result<()> {
1124 if fi.sequence.enable_restoration && !fi.allow_intrabc {
1125 let planes = if fi.sequence.chroma_sampling == ChromaSampling::Cs400 {
1127 1
1128 } else {
1129 MAX_PLANES
1130 };
1131 let mut use_lrf = false;
1132 let mut use_chroma_lrf = false;
1133 for i in 0..planes {
1134 self.write::<2, u8>(rs.planes[i].cfg.lrf_type)?; if rs.planes[i].cfg.lrf_type != RESTORE_NONE {
1136 use_lrf = true;
1137 if i > 0 {
1138 use_chroma_lrf = true;
1139 }
1140 }
1141 }
1142 if use_lrf {
1143 if !fi.sequence.use_128x128_superblock {
1145 self.write::<1, u8>(u8::from(rs.planes[0].cfg.unit_size > 64))?;
1146 }
1147
1148 if rs.planes[0].cfg.unit_size > 64 {
1149 self.write::<1, u8>(u8::from(rs.planes[0].cfg.unit_size > 128))?;
1150 }
1151
1152 if use_chroma_lrf
1153 && fi.sequence.chroma_sampling == ChromaSampling::Cs420
1154 {
1155 self.write::<1, u8>(u8::from(
1156 rs.planes[0].cfg.unit_size > rs.planes[1].cfg.unit_size,
1157 ))?;
1158 }
1159 }
1160 }
1161 Ok(())
1162 }
1163
1164 fn write_segment_data<T: Pixel>(
1165 &mut self, fi: &FrameInvariants<T>, segmentation: &SegmentationState,
1166 ) -> io::Result<()> {
1167 assert_eq!(fi.enable_segmentation, segmentation.enabled);
1168 self.write_bit(fi.enable_segmentation)?;
1169
1170 if segmentation.enabled {
1171 if fi.primary_ref_frame == PRIMARY_REF_NONE {
1172 assert!(segmentation.update_map);
1173 assert!(segmentation.update_data);
1174 } else {
1175 self.write_bit(segmentation.update_map)?;
1176 if segmentation.update_map {
1177 self.write_bit(false)?; }
1179 self.write_bit(segmentation.update_data)?;
1180 }
1181 if segmentation.update_data {
1182 for i in 0..8 {
1183 for j in 0..SegLvl::SEG_LVL_MAX as usize {
1184 self.write_bit(segmentation.features[i][j])?;
1185 if segmentation.features[i][j] {
1186 let bits = seg_feature_bits[j];
1187 let data = segmentation.data[i][j];
1188 if seg_feature_is_signed[j] {
1189 self.write_signed_var(bits + 1, data)?;
1190 } else {
1191 self.write_var(bits, data)?;
1192 }
1193 }
1194 }
1195 }
1196 }
1197 }
1198 Ok(())
1199 }
1200
1201 fn write_delta_q(&mut self, delta_q: i8) -> io::Result<()> {
1202 self.write_bit(delta_q != 0)?;
1203 if delta_q != 0 {
1204 assert!((-63..=63).contains(&delta_q));
1205 self.write_signed::<7, i8>(delta_q)?;
1206 }
1207 Ok(())
1208 }
1209}
1210
1211#[cfg(test)]
1212mod tests {
1213 use super::ULEB128Writer;
1214 use bitstream_io::{BigEndian, BitWriter};
1215 use nom::error::Error;
1216 use nom::IResult;
1217 use quickcheck::quickcheck;
1218
1219 fn leb128(mut input: &[u8]) -> IResult<&[u8], u64, Error<&[u8]>> {
1220 use nom::bytes::complete::take;
1221
1222 let mut value = 0u64;
1223 for i in 0..8u8 {
1224 let result = take(1usize)(input)?;
1225 input = result.0;
1226 let leb128_byte = result.1[0];
1227 value |= u64::from(leb128_byte & 0x7f) << (i * 7);
1228 if (leb128_byte & 0x80) == 0 {
1229 break;
1230 }
1231 }
1232 Ok((input, value))
1233 }
1234
1235 quickcheck! {
1236 fn validate_leb128_write(val: u32) -> bool {
1237 let mut buf1 = Vec::new();
1238 let mut bw1 = BitWriter::endian(&mut buf1, BigEndian);
1239 bw1.write_uleb128(val as u64).unwrap();
1240 let result = leb128(&buf1).unwrap();
1241 u64::from(val) == result.1 && result.0.is_empty()
1242 }
1243 }
1244}