Unverified Commit 5625ee37 authored by Tristan Matthews's avatar Tristan Matthews Committed by GitHub
Browse files

cdef: pick strength based on quantizer (#1401)

* cdef: pick strength based on quantizer

   PSNR | PSNR Cb | PSNR Cr | PSNR HVS |    SSIM | MS SSIM | CIEDE 2000
-0.3890 | -0.7035 | -1.2771 |  -0.1636 | -0.0987 | -0.0441 |    -0.1748

~4-6% faster encoding time for low QP.
parent e0b826a4
......@@ -24,7 +24,7 @@ pub struct CdefDirections {
}
pub const CDEF_VERY_LARGE: u16 = 30000;
const CDEF_SEC_STRENGTHS: u8 = 4;
pub(crate) const CDEF_SEC_STRENGTHS: u8 = 4;
// Instead of dividing by n between 2 and 8, we multiply by 3*5*7*8/n.
// The output is then 840 times larger, but we don't care for finding
......
......@@ -19,6 +19,9 @@ use crate::partition::*;
use crate::predict::PredictionMode;
use crate::frame::*;
use crate::quantize::*;
use crate::rate::bexp64;
use crate::rate::q57;
use crate::rate::QSCALE;
use crate::rate::QuantizerParameters;
use crate::rate::FRAME_SUBTYPE_I;
use crate::rate::FRAME_SUBTYPE_P;
......@@ -595,7 +598,7 @@ impl<T: Pixel> FrameInvariants<T> {
disable_frame_end_update_cdf: false,
allow_warped_motion: false,
cdef_damping: 3,
cdef_bits: 3,
cdef_bits: 0,
cdef_y_strengths: [0*4+0, 1*4+0, 2*4+1, 3*4+1, 5*4+2, 7*4+3, 10*4+3, 13*4+3],
cdef_uv_strengths: [0*4+0, 1*4+0, 2*4+1, 3*4+1, 5*4+2, 7*4+3, 10*4+3, 13*4+3],
delta_q_present: false,
......@@ -759,11 +762,6 @@ impl<T: Pixel> FrameInvariants<T> {
pub fn set_quantizers(&mut self, qps: &QuantizerParameters) {
self.base_q_idx = qps.ac_qi[0];
if self.frame_type != FrameType::KEY {
self.cdef_bits = 3 - ((self.base_q_idx.max(128) - 128) >> 5);
} else {
self.cdef_bits = 3;
}
let base_q_idx = self.base_q_idx as i32;
for pi in 0..3 {
debug_assert!(qps.dc_qi[pi] as i32 - base_q_idx >= -128);
......@@ -776,6 +774,24 @@ impl<T: Pixel> FrameInvariants<T> {
self.lambda =
qps.lambda * ((1 << (2 * (self.sequence.bit_depth - 8))) as f64);
self.me_lambda = self.lambda.sqrt();
let q = bexp64(qps.log_target_q as i64 + q57(QSCALE)) as f32;
/* These coefficients were trained on libaom. */
if !self.intra_only {
let predicted_y_f1 = clamp((-q * q * 0.0000023593946_f32 + q * 0.0068615186_f32 + 0.02709886_f32).round() as i32, 0, 15);
let predicted_y_f2 = clamp((-q * q * 0.00000057629734_f32 + q * 0.0013993345_f32 + 0.03831067_f32).round() as i32, 0, 3);
let predicted_uv_f1 = clamp((-q * q * 0.0000007095069_f32 + q * 0.0034628846_f32 + 0.00887099_f32).round() as i32, 0, 15);
let predicted_uv_f2 = clamp((q * q * 0.00000023874085_f32 + q * 0.00028223585_f32 + 0.05576307_f32).round() as i32, 0, 3);
self.cdef_y_strengths[0] = (predicted_y_f1 * CDEF_SEC_STRENGTHS as i32 + predicted_y_f2) as u8;
self.cdef_uv_strengths[0] = (predicted_uv_f1 * CDEF_SEC_STRENGTHS as i32 + predicted_uv_f2) as u8;
} else {
let predicted_y_f1 = clamp((q * q * 0.0000033731974_f32 + q * 0.008070594_f32 + 0.0187634_f32).round() as i32, 0, 15);
let predicted_y_f2 = clamp((-q * q * -0.0000029167343_f32 + q * 0.0027798624_f32 + 0.0079405_f32).round() as i32, 0, 3);
let predicted_uv_f1 = clamp((-q * q * 0.0000130790995_f32 + q * 0.012892405_f32 - 0.00748388_f32).round() as i32, 0, 15);
let predicted_uv_f2 = clamp((q * q * 0.0000032651783_f32 + q * 0.00035520183_f32 + 0.00228092_f32).round() as i32, 0, 3);
self.cdef_y_strengths[0] = (predicted_y_f1 * CDEF_SEC_STRENGTHS as i32 + predicted_y_f2) as u8;
self.cdef_uv_strengths[0] = (predicted_uv_f1 * CDEF_SEC_STRENGTHS as i32 + predicted_uv_f2) as u8;
}
}
#[inline(always)]
......
......@@ -47,7 +47,7 @@ const TWOPASS_PACKET_SZ: usize = 8;
const SEF_BITS: i64 = 24;
// The scale of AV1 quantizer tables (relative to the pixel domain), i.e., Q3.
const QSCALE: i32 = 3;
pub(crate) const QSCALE: i32 = 3;
// We clamp the actual I and B frame delays to a minimum of 10 to work
// within the range of values where later incrementing the delay works as
......@@ -92,7 +92,7 @@ fn ilog64(v: i64) -> i32 {
// Convert an integer into a Q57 fixed-point fraction.
// The integer must be in the range -64 to 63, inclusive.
const fn q57(v: i32) -> i64 {
pub(crate) const fn q57(v: i32) -> i64 {
// TODO: Add assert if it ever becomes possible to do in a const function.
(v as i64) << 57
}
......@@ -116,7 +116,7 @@ const ATANH_LOG2: &[i64; 32] = &[
// input: a log base 2 in Q57 format.
// output: a 64 bit integer in Q0 (no fraction).
// TODO: Mark const once we can use local variables in a const function.
fn bexp64(logq57: i64) -> i64 {
pub(crate) fn bexp64(logq57: i64) -> i64 {
let ipart = (logq57 >> 57) as i32;
if ipart < 0 {
return 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