Skip to content

header: implement frame_size_with_refs() #2520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/api/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,10 @@ impl<T: Pixel> ContextInner<T> {
// We do want to propagate the lookahead_rec_buffer though.
let rfs = Arc::new(ReferenceFrame {
order_hint: fi.order_hint,
width: fi.width as u32,
height: fi.height as u32,
render_width: fi.render_width,
render_height: fi.render_height,
// Use the original frame contents.
frame: fs.input.clone(),
input_hres: fs.input_hres.clone(),
Expand Down Expand Up @@ -710,6 +714,10 @@ impl<T: Pixel> ContextInner<T> {
// FrameInvariants to pick it up.
let rfs = Arc::new(ReferenceFrame {
order_hint: fi.order_hint,
width: fi.width as u32,
height: fi.height as u32,
render_width: fi.render_width,
render_height: fi.render_height,
// Use the original frame contents.
frame: fs.input.clone(),
input_hres: fs.input_hres.clone(),
Expand Down
30 changes: 30 additions & 0 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ pub const IMPORTANCE_BLOCK_SIZE: usize =
#[derive(Debug, Clone)]
pub struct ReferenceFrame<T: Pixel> {
pub order_hint: u32,
pub width: u32,
pub height: u32,
pub render_width: u32,
pub render_height: u32,
pub frame: Arc<Frame<T>>,
pub input_hres: Arc<Plane<T>>,
pub input_qres: Arc<Plane<T>>,
Expand Down Expand Up @@ -480,6 +484,8 @@ pub struct FrameInvariants<T: Pixel> {
pub height: usize,
pub render_width: u32,
pub render_height: u32,
pub frame_size_override_flag: bool,
pub render_and_frame_size_different: bool,
pub sb_width: usize,
pub sb_height: usize,
pub w_in_b: usize,
Expand Down Expand Up @@ -592,13 +598,17 @@ impl<T: Pixel> FrameInvariants<T> {
);

let (width, height) = (config.width, config.height);
let frame_size_override_flag = width as u32 != sequence.max_frame_width
|| height as u32 != sequence.max_frame_height;

let sar = config.sample_aspect_ratio.as_f64();
let (render_width, render_height) = if sar > 1.0 {
((width as f64 * sar).round() as u32, height as u32)
} else {
(width as u32, (height as f64 / sar).round() as u32)
};
let render_and_frame_size_different =
render_width != width as u32 || render_height != height as u32;

let use_reduced_tx_set = config.speed_settings.reduced_tx_set;
let use_tx_domain_distortion =
Expand Down Expand Up @@ -660,6 +670,8 @@ impl<T: Pixel> FrameInvariants<T> {
height,
render_width,
render_height,
frame_size_override_flag,
render_and_frame_size_different,
sb_width: width.align_power_of_two_and_shift(6),
sb_height: height.align_power_of_two_and_shift(6),
w_in_b,
Expand Down Expand Up @@ -814,6 +826,20 @@ impl<T: Pixel> FrameInvariants<T> {
fi.error_resilient =
if fi.frame_type == FrameType::SWITCH { true } else { error_resilient };

// force frame_size_with_refs() code path if render size != frame size
if fi.frame_type == FrameType::INTER
&& !fi.error_resilient
&& fi.render_and_frame_size_different
{
fi.frame_size_override_flag = true;
}

if fi.frame_type == FrameType::SWITCH {
fi.frame_size_override_flag = true;
} else if fi.sequence.reduced_still_picture_hdr {
fi.frame_size_override_flag = false;
}

// this is the slot that the current frame is going to be saved into
let slot_idx = inter_cfg.get_slot_idx(fi.pyramid_level, fi.order_hint);
fi.show_frame = inter_cfg.get_show_frame(fi.idx_in_group_output);
Expand Down Expand Up @@ -3810,6 +3836,10 @@ pub fn update_rec_buffer<T: Pixel>(
) {
let rfs = Arc::new(ReferenceFrame {
order_hint: fi.order_hint,
width: fi.width as u32,
height: fi.height as u32,
render_width: fi.render_width,
render_height: fi.render_height,
frame: fs.rec.clone(),
input_hres: fs.input_hres.clone(),
input_qres: fs.input_qres.clone(),
Expand Down
122 changes: 74 additions & 48 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,16 @@ pub trait UncompressedHeader {
fn write_color_config(&mut self, seq: &Sequence) -> io::Result<()>;
// End of OBU Headers

fn write_max_frame_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()>;
fn write_frame_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()>;
fn write_frame_size_override<T: Pixel>(
fn write_render_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()>;
fn write_frame_size_with_refs<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()>;
fn write_deblock_filter_a<T: Pixel>(
Expand Down Expand Up @@ -304,7 +310,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
fn write_sequence_header<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()> {
self.write_frame_size(fi)?;
self.write_max_frame_size(fi)?;

let seq = &fi.sequence;

Expand Down Expand Up @@ -538,13 +544,10 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
//self.write(frame_id_len, fi.current_frame_id);
}

let mut frame_size_override_flag = false;
if fi.frame_type == FrameType::SWITCH {
frame_size_override_flag = true;
} else if fi.sequence.reduced_still_picture_hdr {
frame_size_override_flag = false;
} else {
self.write_bit(frame_size_override_flag)?; // frame size overhead flag
if fi.frame_type != FrameType::SWITCH
&& !fi.sequence.reduced_still_picture_hdr
{
self.write_bit(fi.frame_size_override_flag)?; // frame size overhead flag
}

if fi.sequence.enable_order_hint {
Expand Down Expand Up @@ -600,19 +603,8 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {

// if KEY or INTRA_ONLY frame
if fi.intra_only {
if frame_size_override_flag {
self.write_frame_size_override(fi);
}
if fi.sequence.enable_superres {
unimplemented!();
}
let render_and_frame_size_different = fi.render_width != fi.width as u32
|| fi.render_height != fi.height as u32;
self.write_bit(render_and_frame_size_different)?;
if render_and_frame_size_different {
self.write(16, fi.render_width - 1);
self.write(16, fi.render_height - 1);
}
self.write_frame_size(fi)?;
self.write_render_size(fi)?;
if fi.allow_screen_content_tools != 0 {
// TODO: && UpscaledWidth == FrameWidth.
self.write_bit(fi.allow_intrabc)?;
Expand All @@ -639,23 +631,11 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
}
}

if !fi.error_resilient && frame_size_override_flag {
unimplemented!();
if !fi.error_resilient && fi.frame_size_override_flag {
self.write_frame_size_with_refs(fi)?;
} else {
if frame_size_override_flag {
self.write_frame_size_override(fi);
}
if fi.sequence.enable_superres {
unimplemented!();
}
let render_and_frame_size_different = fi.render_width
!= fi.width as u32
|| fi.render_height != fi.height as u32;
self.write_bit(render_and_frame_size_different)?;
if render_and_frame_size_different {
self.write(16, fi.render_width - 1);
self.write(16, fi.render_height - 1);
}
self.write_frame_size(fi)?;
self.write_render_size(fi)?;
}

if fi.force_integer_mv == 0 {
Expand Down Expand Up @@ -870,7 +850,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
}
// End of OBU Headers

fn write_frame_size<T: Pixel>(
fn write_max_frame_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()> {
// width_bits and height_bits will have to be moved to the sequence header OBU
Expand All @@ -888,19 +868,65 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
Ok(())
}

fn write_frame_size_override<T: Pixel>(
fn write_frame_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()> {
// width_bits and height_bits will have to be moved to the sequence header OBU
// when we add support for it.
let width = fi.width - 1;
let height = fi.height - 1;
let width_bits = 32 - (width as u32).leading_zeros();
let height_bits = 32 - (height as u32).leading_zeros();
assert!(width_bits <= 16);
assert!(height_bits <= 16);
self.write(width_bits, width as u16)?;
self.write(height_bits, height as u16)?;
if fi.frame_size_override_flag {
let width = fi.width - 1;
let height = fi.height - 1;
let width_bits = 32 - (width as u32).leading_zeros();
let height_bits = 32 - (height as u32).leading_zeros();
assert!(width_bits <= 16);
assert!(height_bits <= 16);
self.write(width_bits, width as u16)?;
self.write(height_bits, height as u16)?;
}
if fi.sequence.enable_superres {
unimplemented!();
}
Ok(())
}

fn write_render_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()> {
self.write_bit(fi.render_and_frame_size_different)?;
if fi.render_and_frame_size_different {
self.write(16, fi.render_width - 1)?;
self.write(16, fi.render_height - 1)?;
}
Ok(())
}

fn write_frame_size_with_refs<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()> {
let mut found_ref = false;
for i in 0..INTER_REFS_PER_FRAME {
if let Some(ref rec) = fi.rec_buffer.frames[fi.ref_frames[i] as usize] {
if rec.width == fi.width as u32
&& rec.height == fi.height as u32
&& rec.render_width == fi.render_width
&& rec.render_height == fi.render_height
{
self.write_bit(true)?;
found_ref = true;
break;
} else {
self.write_bit(false)?;
}
} else {
self.write_bit(false)?;
}
}
if !found_ref {
self.write_frame_size(fi)?;
self.write_render_size(fi)?;
} else if fi.sequence.enable_superres {
unimplemented!();
}
Ok(())
}

Expand Down