Commit ccd6faa2 authored by Josh Holmer's avatar Josh Holmer Committed by Luca Barbato

Fix infinite loop for very short clips with frame reordering

Fixes #890
parent ab9a6e7c
...@@ -509,6 +509,11 @@ impl Context { ...@@ -509,6 +509,11 @@ impl Context {
} }
} }
match self.frame_q.get(&fi.number) {
Some(Some(_)) => {},
_ => { return Err(fi); }
}
// Now that we know the frame number, look up the correct frame type // Now that we know the frame number, look up the correct frame type
let frame_type = self.determine_frame_type(fi.number); let frame_type = self.determine_frame_type(fi.number);
if frame_type == FrameType::KEY { if frame_type == FrameType::KEY {
......
...@@ -33,6 +33,18 @@ fn fill_frame(ra: &mut ChaChaRng, frame: &mut Frame) { ...@@ -33,6 +33,18 @@ fn fill_frame(ra: &mut ChaChaRng, frame: &mut Frame) {
} }
} }
fn read_frame_batch(ctx: &mut Context, ra: &mut ChaChaRng) {
while ctx.needs_more_lookahead() {
let mut input = ctx.new_frame();
fill_frame(ra, Arc::get_mut(&mut input).unwrap());
let _ = ctx.send_frame(Some(input));
}
if !ctx.needs_more_frames(ctx.get_frame_count()) {
ctx.flush();
}
}
struct AomDecoder { struct AomDecoder {
dec: aom_codec_ctx dec: aom_codec_ctx
} }
...@@ -207,6 +219,19 @@ fn reordering() { ...@@ -207,6 +219,19 @@ fn reordering() {
} }
} }
#[test]
fn reordering_short_video() {
// Regression test for https://github.com/xiph/rav1e/issues/890
let limit = 2;
let w = 64;
let h = 80;
let speed = 10;
let q = 100;
let keyint = 12;
encode_decode(w, h, speed, q, limit, 8, keyint, keyint, false);
}
#[test] #[test]
#[ignore] #[ignore]
fn odd_size_frame_with_full_rdo() { fn odd_size_frame_with_full_rdo() {
...@@ -294,18 +319,15 @@ fn encode_decode( ...@@ -294,18 +319,15 @@ fn encode_decode(
let mut ctx = let mut ctx =
setup_encoder(w, h, speed, quantizer, bit_depth, ChromaSampling::Cs420, setup_encoder(w, h, speed, quantizer, bit_depth, ChromaSampling::Cs420,
min_keyint, max_keyint, low_latency); min_keyint, max_keyint, low_latency);
ctx.set_frames_to_be_coded(limit as u64);
println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer); println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer);
let mut iter: aom_codec_iter_t = ptr::null_mut(); let mut iter: aom_codec_iter_t = ptr::null_mut();
let mut rec_fifo = VecDeque::new(); let mut rec_fifo = VecDeque::new();
for _ in 0..limit { for _ in 0..limit {
let mut input = ctx.new_frame(); read_frame_batch(&mut ctx, &mut ra);
fill_frame(&mut ra, Arc::get_mut(&mut input).unwrap());
let _ = ctx.send_frame(Some(input));
let mut done = false; let mut done = false;
let mut corrupted_count = 0; let mut corrupted_count = 0;
...@@ -352,6 +374,7 @@ fn encode_decode( ...@@ -352,6 +374,7 @@ fn encode_decode(
let img = aom_codec_get_frame(&mut dec.dec, &mut iter); let img = aom_codec_get_frame(&mut dec.dec, &mut iter);
println!("Retrieved."); println!("Retrieved.");
if img.is_null() { if img.is_null() {
done = true;
break; break;
} }
let mut corrupted = 0; let mut corrupted = 0;
......
...@@ -27,6 +27,18 @@ fn fill_frame(ra: &mut ChaChaRng, frame: &mut Frame) { ...@@ -27,6 +27,18 @@ fn fill_frame(ra: &mut ChaChaRng, frame: &mut Frame) {
} }
} }
fn read_frame_batch(ctx: &mut Context, ra: &mut ChaChaRng) {
while ctx.needs_more_lookahead() {
let mut input = ctx.new_frame();
fill_frame(ra, Arc::get_mut(&mut input).unwrap());
let _ = ctx.send_frame(Some(input));
}
if !ctx.needs_more_frames(ctx.get_frame_count()) {
ctx.flush();
}
}
struct Decoder { struct Decoder {
dec: *mut Dav1dContext dec: *mut Dav1dContext
} }
...@@ -282,16 +294,14 @@ fn encode_decode( ...@@ -282,16 +294,14 @@ fn encode_decode(
let mut ctx = let mut ctx =
setup_encoder(w, h, speed, quantizer, bit_depth, ChromaSampling::Cs420, setup_encoder(w, h, speed, quantizer, bit_depth, ChromaSampling::Cs420,
min_keyint, max_keyint, low_latency); min_keyint, max_keyint, low_latency);
ctx.set_frames_to_be_coded(limit as u64);
println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer); println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer);
let mut rec_fifo = VecDeque::new(); let mut rec_fifo = VecDeque::new();
for _ in 0..limit { for _ in 0..limit {
let mut input = ctx.new_frame(); read_frame_batch(&mut ctx, &mut ra);
fill_frame(&mut ra, Arc::get_mut(&mut input).unwrap());
let _ = ctx.send_frame(input);
let mut done = false; let mut done = false;
let mut corrupted_count = 0; let mut corrupted_count = 0;
...@@ -339,6 +349,7 @@ fn encode_decode( ...@@ -339,6 +349,7 @@ fn encode_decode(
let ret = dav1d_get_picture(dec.dec, &mut pic); let ret = dav1d_get_picture(dec.dec, &mut pic);
println!("Retrieved."); println!("Retrieved.");
if ret == -(EAGAIN as i32) { if ret == -(EAGAIN as i32) {
done = true;
break; break;
} }
if ret != 0 { if ret != 0 {
......
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