Skip to main content

rav1e/
header.rs

1// Copyright (c) 2018-2022, The rav1e contributors. All rights reserved
2//
3// This source code is subject to the terms of the BSD 2 Clause License and
4// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
5// was not distributed with this source code in the LICENSE file, you can
6// obtain it at www.aomedia.org/license/software. If the Alliance for Open
7// Media Patent License 1.0 was not distributed with this source code in the
8// PATENTS file, you can obtain it at www.aomedia.org/license/patent.
9
10use 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    // NOTE from libaom:
97    // Disallow values larger than 32-bits to ensure consistent behavior on 32 and
98    // 64 bit targets: value is typically used to determine buffer allocation size
99    // when decoded.
100    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        // Signal that more bytes follow.
108        byte |= 0x80;
109      }
110      coded_value.push(byte);
111
112      if value == 0 {
113        // We have to break at the end of the loop
114        // because there must be at least one byte written.
115        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
129// to write little endian values in a globally big-endian BitWriter
130impl<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  // Start of OBU Headers
141  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  // End of OBU Headers
160
161  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  // Start of OBU Headers
193  // Write OBU Header syntax
194  fn write_obu_header(
195    &mut self, obu_type: ObuType, obu_extension: u32,
196  ) -> io::Result<()> {
197    self.write_bit(false)?; // forbidden bit.
198    self.write::<4, u8>(obu_type as u8)?;
199    self.write_bit(obu_extension != 0)?;
200    self.write_bit(true)?; // obu_has_payload_length_field
201    self.write_bit(false)?; // reserved
202
203    if obu_extension != 0 {
204      unimplemented!();
205      //self.write(8, obu_extension & 0xFF)?; size += 8;
206    }
207
208    Ok(())
209  }
210
211  fn write_sequence_metadata_obu(
212    &mut self, obu_meta_type: ObuMetaType, seq: &Sequence,
213  ) -> io::Result<()> {
214    // header
215    self.write_obu_header(ObuType::OBU_METADATA, 0)?;
216
217    // uleb128() - length
218    // we use a constant value to avoid computing the OBU size every time
219    // since it is fixed (depending on the metadata)
220    // +2 is for the metadata_type field and the trailing bits byte
221    self.write_uleb128(obu_meta_type.size() + 2)?;
222
223    // uleb128() - metadata_type (1 byte)
224    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    // trailing bits (1 byte)
249    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    // metadata type + country code + optional extension + trailing bits
259    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    // trailing bits (1 byte)
272    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)?; // profile
286    self.write_bit(fi.sequence.still_picture)?; // still_picture
287    self.write_bit(fi.sequence.reduced_still_picture_hdr)?; // reduced_still_picture_header
288
289    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])?; // level
296      assert_eq!(fi.sequence.tier[0], 0);
297    } else {
298      self.write_bit(fi.sequence.timing_info_present)?; // timing info present
299
300      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)?; // equal picture interval
305        self.write_bit(true)?; // zero interval
306        self.write_bit(false)?; // decoder model info present flag
307      }
308
309      self.write_bit(false)?; // initial display delay present flag
310      self.write::<5, u8>(0)?; // one operating point
311      self.write::<12, u16>(0)?; // idc
312      self.write::<5, u8>(fi.sequence.level_idx[0])?; // level
313      if fi.sequence.level_idx[0] > 7 {
314        self.write::<1, u8>(0)?; // tier
315      }
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      // We must always have delta_frame_id_length < frame_id_length,
342      // in order for a frame to be referenced with a unique delta.
343      // Avoid wasting bits by using a coding that enforces this restriction.
344      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  // <https://aomediacodec.github.io/av1-spec/#color-config-syntax>
405  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)?; // twelve_bit
410    }
411
412    let monochrome = seq.chroma_sampling == ChromaSampling::Cs400;
413    if seq.profile == 1 {
414      assert!(!monochrome);
415    } else {
416      self.write_bit(monochrome)?; // mono_chrome
417    }
418
419    // color_description_present_flag
420    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)?; // color_range
431    }
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)?; // separate_uv_delta_q
457
458    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        //TODO:
478        /* temporal_point_info();
479        if fi.sequence.decoder_model_info_present_flag &&
480           timing_info.equal_picture_interval == 0 {
481          // write frame_presentation_delay;
482        }
483        if fi.sequence.frame_id_numbers_present_flag {
484          // write display_frame_id;
485        }*/
486
487        self.write_bit(true)?; // trailing bit
488        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)?; // show frame
494
495      if fi.show_frame {
496        //TODO:
497        /* temporal_point_info();
498        if fi.sequence.decoder_model_info_present_flag &&
499           timing_info.equal_picture_interval == 0 {
500          // write frame_presentation_delay;
501        }*/
502      } 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)?; // error resilient
513      }
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      //TODO:
544      //let frame_id_len = fi.sequence.frame_id_length;
545      //self.write(frame_id_len, fi.current_frame_id);
546    }
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)?; // frame size overhead flag
552    }
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        // unshown keyframe (forward keyframe)
571        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      // Inter frame info goes here
580      if fi.intra_only {
581        assert!(fi.refresh_frame_flags != ALL_REF_FRAMES_MASK);
582      } else {
583        // TODO: This should be set once inter mode is used
584      }
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      // Write all ref frame order hints if error_resilient_mode == 1
590      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 KEY or INTRA_ONLY frame
605    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        // TODO: && UpscaledWidth == FrameWidth.
610        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      // Done by above
617    } 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    // tile
663    // <https://aomediacodec.github.io/av1-spec/#tile-info-syntax>
664
665    // Can we use the uniform spacing tile syntax?  'Uniform spacing'
666    // is a slight misnomer; it's more constrained than just a uniform
667    // spacing.
668    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      // yes; our actual tile width/height setting (which is always
676      // currently uniform) also matches the constrained width/height
677      // calculation implicit in the uniform spacing flag.
678
679      self.write_bit(true)?; // uniform_tile_spacing_flag
680
681      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)?; // uniform_tile_spacing_flag
698      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      // context_update_tile_id
731      // for now, always use the first tile CDF
732      self.write_var(tiles_log2 as u32, fs.context_update_tile_id as u32)?;
733
734      // tile_size_bytes_minus_1
735      self.write::<2, u32>(fs.max_tile_size_bytes - 1)?;
736    }
737
738    // quantization
739    assert!(fi.base_q_idx > 0);
740    self.write::<8, u8>(fi.base_q_idx)?; // base_q_idx
741    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)?; // no qm
755
756    // segmentation
757    self.write_segment_data(fi, &fs.segmentation)?;
758
759    // delta_q
760    self.write_bit(false)?; // delta_q_present_flag: no delta q
761
762    // delta_lf_params in the spec
763    self.write_deblock_filter_a(fi, &fs.deblock)?;
764
765    // code for features not yet implemented....
766
767    // loop_filter_params in the spec
768    self.write_deblock_filter_b(fi, &fs.deblock)?;
769
770    // cdef
771    self.write_frame_cdef(fi)?;
772
773    // loop restoration
774    self.write_frame_lrf(fi, &fs.restoration)?;
775
776    self.write_bit(fi.tx_mode_select)?; // tx mode
777
778    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)?; // skip_mode_present
788    }
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)?; // allow_warped_motion
794    }
795
796    self.write_bit(fi.use_reduced_tx_set)?; // reduced tx
797
798    // global motion
799    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 => { /* Nothing to do */ }
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        // Apply grain
842        self.write_bit(true)?;
843        self.write::<16, u16>(grain_params.random_seed)?;
844        if fi.frame_type == FrameType::INTER {
845          // For the purposes of photon noise,
846          // it's simpler to always update the params,
847          // and the output will be the same.
848          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        // No film grain for this frame
934        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  // End of OBU Headers
946
947  fn write_max_frame_size<T: Pixel>(
948    &mut self, fi: &FrameInvariants<T>,
949  ) -> io::Result<()> {
950    // width_bits and height_bits will have to be moved to the sequence header OBU
951    // when we add support for it.
952    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    // width_bits and height_bits will have to be moved to the sequence header OBU
969    // when we add support for it.
970    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])?; // loop deblocking filter level 0
1052    assert!(deblock.levels[1] < 64);
1053    self.write::<6, u8>(deblock.levels[1])?; // loop deblocking filter level 1
1054    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])?; // loop deblocking filter level 2
1057      assert!(deblock.levels[3] < 64);
1058      self.write::<6, u8>(deblock.levels[3])?; // loop deblocking filter level 3
1059    }
1060    self.write::<3, u8>(deblock.sharpness)?; // deblocking filter sharpness
1061    self.write_bit(deblock.deltas_enabled)?; // loop deblocking filter deltas enabled
1062    if deblock.deltas_enabled {
1063      self.write_bit(deblock.delta_updates_enabled)?; // deltas updates enabled
1064      if deblock.delta_updates_enabled {
1065        // conditionally write ref delta updates
1066        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        // conditionally write mode delta updates
1081        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)?; // cdef bits
1109      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])?; // cdef y strength
1113        if fi.sequence.chroma_sampling != ChromaSampling::Cs400 {
1114          self.write::<6, u8>(fi.cdef_uv_strengths[i])?; // cdef uv strength
1115        }
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      // && !self.lossless
1126      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)?; // filter type by plane
1135        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        // The Y shift value written here indicates shift up from superblock size
1144        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)?; /* Without using temporal prediction */
1178        }
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}