Skip to content
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

Refactor internals #2689

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions src/api/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ impl Config {

let (frame, params) = f;
let _ = inner.send_frame(frame, params); // TODO make sure it cannot fail.
inner.compute_fi();
}

inner.limit = Some(inner.frame_count);
Expand Down
86 changes: 50 additions & 36 deletions src/api/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ pub(crate) struct ContextInner<T: Pixel> {
next_lookahead_output_frameno: u64,
/// Optional opaque to be sent back to the user
opaque_q: BTreeMap<u64, Opaque>,
is_flushing: bool,
}

impl<T: Pixel> ContextInner<T> {
Expand Down Expand Up @@ -310,37 +311,20 @@ impl<T: Pixel> ContextInner<T> {
next_lookahead_frame: 1,
next_lookahead_output_frameno: 0,
opaque_q: BTreeMap::new(),
is_flushing: false,
}
}

#[hawktracer(send_frame)]
pub fn send_frame(
&mut self, frame: Option<Arc<Frame<T>>>, params: Option<FrameParameters>,
) -> Result<(), EncoderStatus> {
let input_frameno = self.frame_count;
let is_flushing = frame.is_none();
if !is_flushing {
self.frame_count += 1;
}
self.frame_q.insert(input_frameno, frame);

if let Some(params) = params {
if params.frame_type_override == FrameTypeOverride::Key {
self.keyframes_forced.insert(input_frameno);
}
if let Some(op) = params.opaque {
self.opaque_q.insert(input_frameno, op);
}
}

// lookahead computations
pub(crate) fn compute_fi(&mut self) {
if !self.needs_more_frame_q_lookahead(self.next_lookahead_frame) {
let lookahead_frames = self
.frame_q
.range(self.next_lookahead_frame - 1..)
.filter_map(|(&_input_frameno, frame)| frame.clone())
.collect::<Vec<_>>();

if is_flushing {
if self.is_flushing {
// This is the last time send_frame is called, process all the
// remaining frames.
for cur_lookahead_frames in
Expand All @@ -359,6 +343,28 @@ impl<T: Pixel> ContextInner<T> {
}

self.compute_frame_invariants();
}

#[hawktracer(send_frame)]
pub fn send_frame(
&mut self, frame: Option<Arc<Frame<T>>>, params: Option<FrameParameters>,
) -> Result<(), EncoderStatus> {
let input_frameno = self.frame_count;

self.is_flushing = frame.is_none();
if !self.is_flushing {
self.frame_count += 1;
}
self.frame_q.insert(input_frameno, frame);

if let Some(params) = params {
if params.frame_type_override == FrameTypeOverride::Key {
self.keyframes_forced.insert(input_frameno);
}
if let Some(op) = params.opaque {
self.opaque_q.insert(input_frameno, op);
}
}

Ok(())
}
Expand Down Expand Up @@ -418,14 +424,15 @@ impl<T: Pixel> ContextInner<T> {

fn set_frame_properties(
&mut self, output_frameno: u64,
) -> Result<(), EncoderStatus> {
) -> Result<bool, EncoderStatus> {
let fi = self.build_frame_properties(output_frameno)?;
let valid = !fi.invalid;

let frame =
self.frame_q.get(&fi.input_frameno).as_ref().unwrap().as_ref().unwrap();
self.frame_data.insert(output_frameno, FrameData::new(fi, frame.clone()));

Ok(())
Ok(valid)
}

#[allow(unused)]
Expand Down Expand Up @@ -576,6 +583,13 @@ impl<T: Pixel> ContextInner<T> {
fn compute_lookahead_motion_vectors(&mut self, output_frameno: u64) {
let qps = {
let frame_data = self.frame_data.get(&output_frameno).unwrap();
// We're only interested in valid frames which are not show-existing-frame.
// Those two don't modify the rec_buffer so there's no need to do anything
// special about it either, it'll propagate on its own.
if frame_data.fi.invalid || frame_data.fi.show_existing_frame {
return;
}

let fti = frame_data.fi.get_frame_subtype();
self.rc_state.select_qi(
self,
Expand All @@ -588,13 +602,6 @@ impl<T: Pixel> ContextInner<T> {
let fs = &mut frame_data.fs;
let fi = &mut frame_data.fi;

// We're only interested in valid frames which are not show-existing-frame.
// Those two don't modify the rec_buffer so there's no need to do anything
// special about it either, it'll propagate on its own.
if fi.invalid || fi.show_existing_frame {
return;
}

#[cfg(feature = "dump_lookahead_data")]
{
let data_location = Self::build_dump_properties();
Expand Down Expand Up @@ -774,12 +781,17 @@ impl<T: Pixel> ContextInner<T> {

#[hawktracer(compute_frame_invariants)]
pub fn compute_frame_invariants(&mut self) {
while self.set_frame_properties(self.next_lookahead_output_frameno).is_ok()
while let Ok(valid) =
self.set_frame_properties(self.next_lookahead_output_frameno)
{
self
.compute_lookahead_motion_vectors(self.next_lookahead_output_frameno);
if self.config.temporal_rdo() {
self.compute_lookahead_intra_costs(self.next_lookahead_output_frameno);
if valid {
self.compute_lookahead_motion_vectors(
self.next_lookahead_output_frameno,
);
if self.config.temporal_rdo() {
self
.compute_lookahead_intra_costs(self.next_lookahead_output_frameno);
}
}
self.next_lookahead_output_frameno += 1;
}
Expand Down Expand Up @@ -995,7 +1007,7 @@ impl<T: Pixel> ContextInner<T> {
let output_frame_data = self.frame_data.remove(&output_frameno).unwrap();
let fi = &output_frame_data.fi;

let frame = self.frame_q[&fi.input_frameno].as_ref().unwrap();
let frame = &output_frame_data.fs.input;

// There can be at most 3 of these.
let mut unique_indices = ArrayVec::<_, 3>::new();
Expand Down Expand Up @@ -1279,6 +1291,8 @@ impl<T: Pixel> ContextInner<T> {
return Err(EncoderStatus::LimitReached);
}

self.compute_fi();

if self.needs_more_fi_lookahead() {
return Err(EncoderStatus::NeedMoreData);
}
Expand Down
8 changes: 7 additions & 1 deletion src/api/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@ fn send_test_frame<T: Pixel>(ctx: &mut Context<T>, content_value: T) {
}

fn get_frame_invariants<T: Pixel>(
ctx: Context<T>,
mut ctx: Context<T>,
) -> impl Iterator<Item = FrameInvariants<T>> {
ctx.inner.compute_fi();
ctx.inner.frame_data.into_iter().map(|(_, v)| v.fi)
}

Expand Down Expand Up @@ -1777,6 +1778,7 @@ fn lookahead_size_properly_bounded(
for i in 0..LIMIT {
let input = ctx.new_frame();
let _ = ctx.send_frame(input);
ctx.inner.compute_fi();
pre_receive_frame_q_lens[i] = ctx.inner.frame_q.len();
pre_receive_fi_lens[i] = ctx.inner.frame_data.len();
while ctx.receive_packet().is_ok() {
Expand Down Expand Up @@ -2047,6 +2049,7 @@ fn min_quantizer_bounds_correctly() {
ctx.flush();

for i in 0..limit {
ctx.inner.compute_fi();
ctx.inner.encode_packet(i).unwrap();
let frame_data = ctx.inner.frame_data.get(&i).unwrap();
if i == 0 {
Expand Down Expand Up @@ -2078,6 +2081,7 @@ fn min_quantizer_bounds_correctly() {
ctx.flush();

for i in 0..limit {
ctx.inner.compute_fi();
ctx.inner.encode_packet(i).unwrap();
let frame_data = ctx.inner.frame_data.get(&i).unwrap();
if i == 0 {
Expand Down Expand Up @@ -2112,6 +2116,7 @@ fn max_quantizer_bounds_correctly() {
ctx.flush();

for i in 0..limit {
ctx.inner.compute_fi();
ctx.inner.encode_packet(i).unwrap();
let frame_data = ctx.inner.frame_data.get(&i).unwrap();
if i == 0 {
Expand Down Expand Up @@ -2143,6 +2148,7 @@ fn max_quantizer_bounds_correctly() {
ctx.flush();

for i in 0..limit {
ctx.inner.compute_fi();
ctx.inner.encode_packet(i).unwrap();
let frame_data = ctx.inner.frame_data.get(&i).unwrap();
if i == 0 {
Expand Down