Commit f2aa4c65 authored by David Michael Barr's avatar David Michael Barr

Add encode-decode tests for bitrate config

Fix overflow in motion estimation RDO.
parent 9da3cabf
...@@ -163,7 +163,7 @@ pub fn motion_estimation( ...@@ -163,7 +163,7 @@ pub fn motion_estimation(
let y_lo = po.y + ((-range + (cmv.row / 8) as isize).max(mvy_min / 8).min(mvy_max / 8)); let y_lo = po.y + ((-range + (cmv.row / 8) as isize).max(mvy_min / 8).min(mvy_max / 8));
let y_hi = po.y + ((range + (cmv.row / 8) as isize).max(mvy_min / 8).min(mvy_max / 8)); let y_hi = po.y + ((range + (cmv.row / 8) as isize).max(mvy_min / 8).min(mvy_max / 8));
let mut lowest_cost = std::u32::MAX; let mut lowest_cost = std::u64::MAX;
let mut best_mv = MotionVector { row: 0, col: 0 }; let mut best_mv = MotionVector { row: 0, col: 0 };
// 0.5 is a fudge factor // 0.5 is a fudge factor
...@@ -241,7 +241,7 @@ pub fn motion_estimation( ...@@ -241,7 +241,7 @@ pub fn motion_estimation(
let rate1 = get_mv_rate(cand_mv, pmv[0], fi.allow_high_precision_mv); let rate1 = get_mv_rate(cand_mv, pmv[0], fi.allow_high_precision_mv);
let rate2 = get_mv_rate(cand_mv, pmv[1], fi.allow_high_precision_mv); let rate2 = get_mv_rate(cand_mv, pmv[1], fi.allow_high_precision_mv);
let rate = rate1.min(rate2 + 1); let rate = rate1.min(rate2 + 1);
let cost = 256 * sad + rate * lambda; let cost = 256 * sad as u64 + rate as u64 * lambda as u64;
if cost < lowest_cost { if cost < lowest_cost {
lowest_cost = cost; lowest_cost = cost;
...@@ -261,7 +261,7 @@ pub fn motion_estimation( ...@@ -261,7 +261,7 @@ pub fn motion_estimation(
fn full_search( fn full_search(
x_lo: isize, x_hi: isize, y_lo: isize, y_hi: isize, blk_h: usize, x_lo: isize, x_hi: isize, y_lo: isize, y_hi: isize, blk_h: usize,
blk_w: usize, p_org: &Plane, p_ref: &Plane, best_mv: &mut MotionVector, blk_w: usize, p_org: &Plane, p_ref: &Plane, best_mv: &mut MotionVector,
lowest_cost: &mut u32, po: &PlaneOffset, step: usize, bit_depth: usize, lowest_cost: &mut u64, po: &PlaneOffset, step: usize, bit_depth: usize,
lambda: u32, pmv: &[MotionVector; 2], allow_high_precision_mv: bool lambda: u32, pmv: &[MotionVector; 2], allow_high_precision_mv: bool
) { ) {
let search_range_y = (y_lo..=y_hi).step_by(step); let search_range_y = (y_lo..=y_hi).step_by(step);
...@@ -282,7 +282,7 @@ fn full_search( ...@@ -282,7 +282,7 @@ fn full_search(
let rate1 = get_mv_rate(mv, pmv[0], allow_high_precision_mv); let rate1 = get_mv_rate(mv, pmv[0], allow_high_precision_mv);
let rate2 = get_mv_rate(mv, pmv[1], allow_high_precision_mv); let rate2 = get_mv_rate(mv, pmv[1], allow_high_precision_mv);
let rate = rate1.min(rate2 + 1); let rate = rate1.min(rate2 + 1);
let cost = 256 * sad + rate * lambda; let cost = 256 * sad as u64 + rate as u64 * lambda as u64;
(cost, mv) (cost, mv)
}).min_by_key(|(c, _)| *c).unwrap(); }).min_by_key(|(c, _)| *c).unwrap();
...@@ -332,7 +332,7 @@ pub fn estimate_motion_ss4( ...@@ -332,7 +332,7 @@ pub fn estimate_motion_ss4(
let y_lo = po.y + (((-range_y).max(mvy_min / 8)) >> 2); let y_lo = po.y + (((-range_y).max(mvy_min / 8)) >> 2);
let y_hi = po.y + (((range_y).min(mvy_max / 8)) >> 2); let y_hi = po.y + (((range_y).min(mvy_max / 8)) >> 2);
let mut lowest_cost = std::u32::MAX; let mut lowest_cost = std::u64::MAX;
let mut best_mv = MotionVector { row: 0, col: 0 }; let mut best_mv = MotionVector { row: 0, col: 0 };
// Divide by 16 to account for subsampling, 0.125 is a fudge factor // Divide by 16 to account for subsampling, 0.125 is a fudge factor
...@@ -378,7 +378,7 @@ pub fn estimate_motion_ss2( ...@@ -378,7 +378,7 @@ pub fn estimate_motion_ss2(
let range = 16; let range = 16;
let (mvx_min, mvx_max, mvy_min, mvy_max) = get_mv_range(fi, &bo_adj, blk_w, blk_h); let (mvx_min, mvx_max, mvy_min, mvy_max) = get_mv_range(fi, &bo_adj, blk_w, blk_h);
let mut lowest_cost = std::u32::MAX; let mut lowest_cost = std::u64::MAX;
let mut best_mv = MotionVector { row: 0, col: 0 }; let mut best_mv = MotionVector { row: 0, col: 0 };
// Divide by 4 to account for subsampling, 0.125 is a fudge factor // Divide by 4 to account for subsampling, 0.125 is a fudge factor
......
...@@ -85,7 +85,7 @@ impl Drop for AomDecoder { ...@@ -85,7 +85,7 @@ impl Drop for AomDecoder {
fn setup_encoder( fn setup_encoder(
w: usize, h: usize, speed: usize, quantizer: usize, bit_depth: usize, w: usize, h: usize, speed: usize, quantizer: usize, bit_depth: usize,
chroma_sampling: ChromaSampling, min_keyint: u64, max_keyint: u64, chroma_sampling: ChromaSampling, min_keyint: u64, max_keyint: u64,
low_latency: bool low_latency: bool, bitrate: i32
) -> Context { ) -> Context {
unsafe { unsafe {
av1_rtcd(); av1_rtcd();
...@@ -101,6 +101,7 @@ fn setup_encoder( ...@@ -101,6 +101,7 @@ fn setup_encoder(
enc.height = h; enc.height = h;
enc.bit_depth = bit_depth; enc.bit_depth = bit_depth;
enc.chroma_sampling = chroma_sampling; enc.chroma_sampling = chroma_sampling;
enc.bitrate = bitrate;
let cfg = Config { let cfg = Config {
enc enc
...@@ -120,7 +121,7 @@ fn speed(s: usize) { ...@@ -120,7 +121,7 @@ fn speed(s: usize) {
let h = 80; let h = 80;
for b in DIMENSION_OFFSETS.iter() { for b in DIMENSION_OFFSETS.iter() {
encode_decode(w + b.0, h + b.1, s, quantizer, limit, 8, Default::default(), 15, 15, true); encode_decode(w + b.0, h + b.1, s, quantizer, limit, 8, Default::default(), 15, 15, true, 0);
} }
} }
...@@ -175,7 +176,7 @@ fn dimension(w: usize, h: usize) { ...@@ -175,7 +176,7 @@ fn dimension(w: usize, h: usize) {
let limit = 1; let limit = 1;
let speed = 4; let speed = 4;
encode_decode(w, h, speed, quantizer, limit, 8, Default::default(), 15, 15, true); encode_decode(w, h, speed, quantizer, limit, 8, Default::default(), 15, 15, true, 0);
} }
#[test] #[test]
...@@ -187,7 +188,21 @@ fn quantizer() { ...@@ -187,7 +188,21 @@ fn quantizer() {
for b in DIMENSION_OFFSETS.iter() { for b in DIMENSION_OFFSETS.iter() {
for &q in [80, 100, 120].iter() { for &q in [80, 100, 120].iter() {
encode_decode(w + b.0, h + b.1, speed, q, limit, 8, Default::default(), 15, 15, true); encode_decode(w + b.0, h + b.1, speed, q, limit, 8, Default::default(), 15, 15, true, 0);
}
}
}
#[test]
fn bitrate() {
let limit = 5;
let w = 64;
let h = 80;
let speed = 4;
for &q in [172, 220, 252, 255].iter() {
for &r in [100, 1000, 10_000].iter() {
encode_decode(w, h, speed, q, limit, 8, Default::default(), 15, 15, true, r);
} }
} }
} }
...@@ -200,7 +215,7 @@ fn keyframes() { ...@@ -200,7 +215,7 @@ fn keyframes() {
let speed = 10; let speed = 10;
let q = 100; let q = 100;
encode_decode(w, h, speed, q, limit, 8, Default::default(), 6, 6, true); encode_decode(w, h, speed, q, limit, 8, Default::default(), 6, 6, true, 0);
} }
#[test] #[test]
...@@ -212,7 +227,7 @@ fn reordering() { ...@@ -212,7 +227,7 @@ fn reordering() {
let q = 100; let q = 100;
for keyint in &[4, 5, 6] { for keyint in &[4, 5, 6] {
encode_decode(w, h, speed, q, limit, 8, Default::default(), *keyint, *keyint, false); encode_decode(w, h, speed, q, limit, 8, Default::default(), *keyint, *keyint, false, 0);
} }
} }
...@@ -226,7 +241,7 @@ fn reordering_short_video() { ...@@ -226,7 +241,7 @@ fn reordering_short_video() {
let q = 100; let q = 100;
let keyint = 12; let keyint = 12;
encode_decode(w, h, speed, q, limit, 8, Default::default(), keyint, keyint, false); encode_decode(w, h, speed, q, limit, 8, Default::default(), keyint, keyint, false, 0);
} }
#[test] #[test]
...@@ -238,7 +253,7 @@ fn odd_size_frame_with_full_rdo() { ...@@ -238,7 +253,7 @@ fn odd_size_frame_with_full_rdo() {
let speed = 0; let speed = 0;
let qindex = 100; let qindex = 100;
encode_decode(w, h, speed, qindex, limit, 8, Default::default(), 15, 15, true); encode_decode(w, h, speed, qindex, limit, 8, Default::default(), 15, 15, true, 0);
} }
#[test] #[test]
...@@ -250,10 +265,10 @@ fn high_bd() { ...@@ -250,10 +265,10 @@ fn high_bd() {
let h = 80; let h = 80;
// 10-bit // 10-bit
encode_decode(w, h, speed, quantizer, limit, 10, Default::default(), 15, 15, true); encode_decode(w, h, speed, quantizer, limit, 10, Default::default(), 15, 15, true, 0);
// 12-bit // 12-bit
encode_decode(w, h, speed, quantizer, limit, 12, Default::default(), 15, 15, true); encode_decode(w, h, speed, quantizer, limit, 12, Default::default(), 15, 15, true, 0);
} }
#[test] #[test]
...@@ -267,10 +282,10 @@ fn chroma_sampling() { ...@@ -267,10 +282,10 @@ fn chroma_sampling() {
// TODO: bump keyint when inter is supported // TODO: bump keyint when inter is supported
// 4:2:2 // 4:2:2
encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs422, 1, 1, true); encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs422, 1, 1, true, 0);
// 4:4:4 // 4:4:4
encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs444, 1, 1, true); encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs444, 1, 1, true, 0);
} }
fn compare_plane<T: Ord + std::fmt::Debug>( fn compare_plane<T: Ord + std::fmt::Debug>(
...@@ -326,14 +341,14 @@ fn compare_img(img: *const aom_image_t, frame: &Frame, bit_depth: usize, width: ...@@ -326,14 +341,14 @@ fn compare_img(img: *const aom_image_t, frame: &Frame, bit_depth: usize, width:
fn encode_decode( fn encode_decode(
w: usize, h: usize, speed: usize, quantizer: usize, limit: usize, w: usize, h: usize, speed: usize, quantizer: usize, limit: usize,
bit_depth: usize, chroma_sampling: ChromaSampling, min_keyint: u64, bit_depth: usize, chroma_sampling: ChromaSampling, min_keyint: u64,
max_keyint: u64, low_latency: bool max_keyint: u64, low_latency: bool, bitrate: i32
) { ) {
let mut ra = ChaChaRng::from_seed([0; 32]); let mut ra = ChaChaRng::from_seed([0; 32]);
let mut dec = setup_decoder(w, h); let mut dec = setup_decoder(w, h);
let mut ctx = let mut ctx =
setup_encoder(w, h, speed, quantizer, bit_depth, chroma_sampling, setup_encoder(w, h, speed, quantizer, bit_depth, chroma_sampling,
min_keyint, max_keyint, low_latency); min_keyint, max_keyint, low_latency, bitrate);
ctx.set_limit(limit as u64); ctx.set_limit(limit as u64);
println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer); println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer);
......
...@@ -69,7 +69,7 @@ impl Drop for Decoder { ...@@ -69,7 +69,7 @@ impl Drop for Decoder {
fn setup_encoder( fn setup_encoder(
w: usize, h: usize, speed: usize, quantizer: usize, bit_depth: usize, w: usize, h: usize, speed: usize, quantizer: usize, bit_depth: usize,
chroma_sampling: ChromaSampling, min_keyint: u64, max_keyint: u64, chroma_sampling: ChromaSampling, min_keyint: u64, max_keyint: u64,
low_latency: bool low_latency: bool, bitrate: i32
) -> Context { ) -> Context {
let mut enc = EncoderConfig::with_speed_preset(speed); let mut enc = EncoderConfig::with_speed_preset(speed);
...@@ -81,6 +81,7 @@ fn setup_encoder( ...@@ -81,6 +81,7 @@ fn setup_encoder(
enc.height = h; enc.height = h;
enc.bit_depth = bit_depth; enc.bit_depth = bit_depth;
enc.chroma_sampling = chroma_sampling; enc.chroma_sampling = chroma_sampling;
enc.bitrate = bitrate;
let cfg = Config { let cfg = Config {
enc enc
...@@ -100,7 +101,7 @@ fn speed(s: usize) { ...@@ -100,7 +101,7 @@ fn speed(s: usize) {
let h = 80; let h = 80;
for b in DIMENSION_OFFSETS.iter() { for b in DIMENSION_OFFSETS.iter() {
encode_decode(w + b.0, h + b.1, s, quantizer, limit, 8, Default::default(), 15, 15, true); encode_decode(w + b.0, h + b.1, s, quantizer, limit, 8, Default::default(), 15, 15, true, 0);
} }
} }
...@@ -155,7 +156,7 @@ fn dimension(w: usize, h: usize) { ...@@ -155,7 +156,7 @@ fn dimension(w: usize, h: usize) {
let limit = 1; let limit = 1;
let speed = 4; let speed = 4;
encode_decode(w, h, speed, quantizer, limit, 8, Default::default(), 15, 15, true); encode_decode(w, h, speed, quantizer, limit, 8, Default::default(), 15, 15, true, 0);
} }
#[test] #[test]
...@@ -167,7 +168,21 @@ fn quantizer() { ...@@ -167,7 +168,21 @@ fn quantizer() {
for b in DIMENSION_OFFSETS.iter() { for b in DIMENSION_OFFSETS.iter() {
for &q in [80, 100, 120].iter() { for &q in [80, 100, 120].iter() {
encode_decode(w + b.0, h + b.1, speed, q, limit, 8, Default::default(), 15, 15, true); encode_decode(w + b.0, h + b.1, speed, q, limit, 8, Default::default(), 15, 15, true, 0);
}
}
}
#[test]
fn bitrate() {
let limit = 5;
let w = 64;
let h = 80;
let speed = 4;
for &q in [172, 220, 252, 255].iter() {
for &r in [100, 1000, 10_000].iter() {
encode_decode(w, h, speed, q, limit, 8, Default::default(), 15, 15, true, r);
} }
} }
} }
...@@ -180,7 +195,7 @@ fn keyframes() { ...@@ -180,7 +195,7 @@ fn keyframes() {
let speed = 10; let speed = 10;
let q = 100; let q = 100;
encode_decode(w, h, speed, q, limit, 8, Default::default(), 6, 6, true); encode_decode(w, h, speed, q, limit, 8, Default::default(), 6, 6, true, 0);
} }
#[test] #[test]
...@@ -192,7 +207,7 @@ fn reordering() { ...@@ -192,7 +207,7 @@ fn reordering() {
let q = 100; let q = 100;
for keyint in &[4, 5, 6] { for keyint in &[4, 5, 6] {
encode_decode(w, h, speed, q, limit, 8, Default::default(), *keyint, *keyint, false); encode_decode(w, h, speed, q, limit, 8, Default::default(), *keyint, *keyint, false, 0);
} }
} }
...@@ -205,7 +220,7 @@ fn odd_size_frame_with_full_rdo() { ...@@ -205,7 +220,7 @@ fn odd_size_frame_with_full_rdo() {
let speed = 0; let speed = 0;
let qindex = 100; let qindex = 100;
encode_decode(w, h, speed, qindex, limit, 8, Default::default(), 15, 15, true); encode_decode(w, h, speed, qindex, limit, 8, Default::default(), 15, 15, true, 0);
} }
fn high_bd(bits: usize) { fn high_bd(bits: usize) {
...@@ -215,7 +230,7 @@ fn high_bd(bits: usize) { ...@@ -215,7 +230,7 @@ fn high_bd(bits: usize) {
let w = 64; let w = 64;
let h = 80; let h = 80;
encode_decode(w, h, speed, quantizer, limit, bits, Default::default(), 15, 15, true); encode_decode(w, h, speed, quantizer, limit, bits, Default::default(), 15, 15, true, 0);
} }
#[test] #[test]
...@@ -229,10 +244,10 @@ fn chroma_sampling() { ...@@ -229,10 +244,10 @@ fn chroma_sampling() {
// TODO: bump keyint when inter is supported // TODO: bump keyint when inter is supported
// 4:2:2 // 4:2:2
encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs422, 1, 1, true); encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs422, 1, 1, true, 0);
// 4:4:4 // 4:4:4
encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs444, 1, 1, true); encode_decode(w, h, speed, quantizer, limit, 8, ChromaSampling::Cs444, 1, 1, true, 0);
} }
#[test] #[test]
...@@ -301,14 +316,14 @@ fn compare_pic(pic: &Dav1dPicture, frame: &Frame, bit_depth: usize, width: usize ...@@ -301,14 +316,14 @@ fn compare_pic(pic: &Dav1dPicture, frame: &Frame, bit_depth: usize, width: usize
fn encode_decode( fn encode_decode(
w: usize, h: usize, speed: usize, quantizer: usize, limit: usize, w: usize, h: usize, speed: usize, quantizer: usize, limit: usize,
bit_depth: usize, chroma_sampling: ChromaSampling, min_keyint: u64, bit_depth: usize, chroma_sampling: ChromaSampling, min_keyint: u64,
max_keyint: u64, low_latency: bool max_keyint: u64, low_latency: bool, bitrate: i32
) { ) {
let mut ra = ChaChaRng::from_seed([0; 32]); let mut ra = ChaChaRng::from_seed([0; 32]);
let dec = setup_decoder(); let dec = setup_decoder();
let mut ctx = let mut ctx =
setup_encoder(w, h, speed, quantizer, bit_depth, chroma_sampling, setup_encoder(w, h, speed, quantizer, bit_depth, chroma_sampling,
min_keyint, max_keyint, low_latency); min_keyint, max_keyint, low_latency, bitrate);
ctx.set_limit(limit as u64); ctx.set_limit(limit as u64);
println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer); println!("Encoding {}x{} speed {} quantizer {}", w, h, speed, quantizer);
......
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