Commit cf42ee54 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by Derek Buitenhuis
Browse files

Make FrameInvariants invariant in encode_frame().

Despite the name, we were passing FrameInvariants to encode_frame()
 as &mut.
There were two places that it actually mutated the contents.
1) In write_sequence_header_obu(), several fields were set to
    constants.
   Given that we write the sequence header multiple times, but its
    contents should never change, the initialization does not
    belong in this function, as that is just asking to violate this
    constraint if we ever make them non-constant.
   Instead just initialize the fields when the rest of the
    FrameInvariant struct is initialized, since the values are
    currently constant anyway.
   We can find a better place than write_sequence_header_obu()
    (one that really is called once per sequence) if we ever want
    to make them non-constant.
2) The ref_frame_sign_bias[] fields are initialized at the very
    start of encode_frame().
   These can instead be initialized in new_inter_frame() as soon as
    ref_frames[i] is set.

With the above two changes we can drop the &mut and ensure that
 FrameInvariants really is invariant.
parent 17822b57
......@@ -88,6 +88,9 @@ impl Default for Tune {
}
}
const FRAME_ID_LENGTH: u32 = 15;
const DELTA_FRAME_ID_LENGTH: u32 = 14;
#[derive(Copy, Clone, Debug)]
pub struct Sequence {
// OBU Sequence header of AV1
......@@ -191,8 +194,8 @@ impl Sequence {
max_frame_width: config.width as u32,
max_frame_height: config.height as u32,
frame_id_numbers_present_flag: false,
frame_id_length: 0,
delta_frame_id_length: 0,
frame_id_length: FRAME_ID_LENGTH,
delta_frame_id_length: DELTA_FRAME_ID_LENGTH,
use_128x128_superblock: false,
order_hint_bits_minus_1: 5,
force_screen_content_tools: 0,
......@@ -720,7 +723,17 @@ impl<T: Pixel> FrameInvariants<T> {
} else {
3 + lvl1 as u8
}
}
};
fi.ref_frame_sign_bias[i] = if !fi.sequence.enable_order_hint {
false
} else if let Some(ref rec) =
fi.rec_buffer.frames[fi.ref_frames[i] as usize]
{
let hint = rec.order_hint;
fi.sequence.get_relative_dist(hint, fi.order_hint) > 0
} else {
false
};
}
fi.reference_mode = if inter_cfg.multiref && inter_cfg.reorder && inter_cfg.idx_in_group != 0 {
......@@ -812,7 +825,7 @@ pub fn write_temporal_delimiter(
}
fn write_obus<T: Pixel>(
packet: &mut dyn io::Write, fi: &mut FrameInvariants<T>, fs: &FrameState<T>
packet: &mut dyn io::Write, fi: &FrameInvariants<T>, fs: &FrameState<T>
) -> io::Result<()> {
let obu_extension = 0 as u32;
......@@ -2246,24 +2259,10 @@ pub fn encode_show_existing_frame<T: Pixel>(
}
pub fn encode_frame<T: Pixel>(
fi: &mut FrameInvariants<T>, fs: &mut FrameState<T>
fi: &FrameInvariants<T>, fs: &mut FrameState<T>
) -> Vec<u8> {
debug_assert!(!fi.show_existing_frame);
let mut packet = Vec::new();
if !fi.intra_only {
for i in 0..INTER_REFS_PER_FRAME {
fi.ref_frame_sign_bias[i] = if !fi.sequence.enable_order_hint {
false
} else if let Some(ref rec) =
fi.rec_buffer.frames[fi.ref_frames[i] as usize]
{
let hint = rec.order_hint;
fi.sequence.get_relative_dist(hint, fi.order_hint) > 0
} else {
false
};
}
}
fs.input_hres.downsample_from(&fs.input.planes[0]);
fs.input_hres.pad(fi.width, fi.height);
......
......@@ -40,9 +40,6 @@ const LEVEL_MAJOR_BITS: usize = 3;
const LEVEL_MINOR_BITS: usize = 2;
#[allow(unused)]
const LEVEL_BITS: usize = LEVEL_MAJOR_BITS + LEVEL_MINOR_BITS;
const FRAME_ID_LENGTH: usize = 15;
const DELTA_FRAME_ID_LENGTH: usize = 14;
#[allow(dead_code,non_camel_case_types)]
#[derive(Debug, Clone, Copy, PartialEq)]
......@@ -151,16 +148,16 @@ pub trait UncompressedHeader {
&mut self, obu_meta_type: ObuMetaType, seq: Sequence
) -> io::Result<()>;
fn write_sequence_header_obu<T: Pixel>(
&mut self, fi: &mut FrameInvariants<T>
&mut self, fi: &FrameInvariants<T>
) -> io::Result<()>;
fn write_frame_header_obu<T: Pixel>(
&mut self, fi: &FrameInvariants<T>, fs: &FrameState<T>
) -> io::Result<()>;
fn write_sequence_header<T: Pixel>(
&mut self, fi: &mut FrameInvariants<T>
&mut self, fi: &FrameInvariants<T>
) -> io::Result<()>;
fn write_color_config(
&mut self, seq: &mut Sequence
&mut self, seq: &Sequence
) -> io::Result<()>;
// End of OBU Headers
......@@ -253,7 +250,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
}
fn write_sequence_header_obu<T: Pixel>(
&mut self, fi: &mut FrameInvariants<T>
&mut self, fi: &FrameInvariants<T>
) -> io::Result<()> {
self.write(3, fi.sequence.profile)?; // profile
self.write_bit(false)?; // still_picture
......@@ -270,7 +267,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
self.write_sequence_header(fi)?;
self.write_color_config(&mut fi.sequence)?;
self.write_color_config(&fi.sequence)?;
self.write_bit(fi.sequence.film_grain_params_present)?;
......@@ -278,21 +275,16 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
}
fn write_sequence_header<T: Pixel>(
&mut self, fi: &mut FrameInvariants<T>
&mut self, fi: &FrameInvariants<T>
) -> io::Result<()> {
self.write_frame_size(fi)?;
let seq = &mut fi.sequence;
seq.frame_id_numbers_present_flag = false;
let seq = &fi.sequence;
if !seq.reduced_still_picture_hdr {
self.write_bit(seq.frame_id_numbers_present_flag)?;
}
seq.frame_id_length = FRAME_ID_LENGTH as u32;
seq.delta_frame_id_length = DELTA_FRAME_ID_LENGTH as u32;
if seq.frame_id_numbers_present_flag {
// We must always have delta_frame_id_length < frame_id_length,
// in order for a frame to be referenced with a unique delta.
......@@ -345,7 +337,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
Ok(())
}
fn write_color_config(&mut self, seq: &mut Sequence) -> io::Result<()> {
fn write_color_config(&mut self, seq: &Sequence) -> io::Result<()> {
let high_bd = seq.bit_depth > 8;
self.write_bit(high_bd)?;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment