Commit a2915b29 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by David Michael Barr
Browse files

Use the same quantizer for DC and AC coefficients.

We are limited by the resolution of the tables, but by picking
 lambda based on the desired quantizer (which can have much higher
 precision), this should be reasonably close to a truely flat
 quantizer.

This should improve PSNR and will likely harm the other metrics.
parent ea4bf00c
...@@ -74,6 +74,16 @@ fn select_qi(quantizer: i64, qlookup: &[i16; QINDEX_RANGE]) -> u8 { ...@@ -74,6 +74,16 @@ fn select_qi(quantizer: i64, qlookup: &[i16; QINDEX_RANGE]) -> u8 {
} }
} }
pub fn select_dc_qi(quantizer: i64, bit_depth: usize) -> u8 {
let qlookup = match bit_depth {
8 => &dc_qlookup_Q3,
10 => &dc_qlookup_10_Q3,
12 => &dc_qlookup_12_Q3,
_ => unimplemented!()
};
select_qi(quantizer, qlookup)
}
pub fn select_ac_qi(quantizer: i64, bit_depth: usize) -> u8 { pub fn select_ac_qi(quantizer: i64, bit_depth: usize) -> u8 {
let qlookup = match bit_depth { let qlookup = match bit_depth {
8 => &ac_qlookup_Q3, 8 => &ac_qlookup_Q3,
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
use crate::encoder::FrameInvariants; use crate::encoder::FrameInvariants;
use crate::quantize::ac_q; use crate::quantize::ac_q;
use crate::quantize::dc_q;
use crate::quantize::select_ac_qi; use crate::quantize::select_ac_qi;
use crate::quantize::select_dc_qi;
// The number of frame sub-types for which we track distinct parameters. // The number of frame sub-types for which we track distinct parameters.
pub const FRAME_NSUBTYPES: usize = 4; pub const FRAME_NSUBTYPES: usize = 4;
...@@ -241,17 +241,14 @@ const Q57_SQUARE_EXP_SCALE: f64 = ...@@ -241,17 +241,14 @@ const Q57_SQUARE_EXP_SCALE: f64 =
(2.0 * ::std::f64::consts::LN_2) / ((1i64 << 57) as f64); (2.0 * ::std::f64::consts::LN_2) / ((1i64 << 57) as f64);
impl QuantizerParameters { impl QuantizerParameters {
fn new_from_log_q( fn new_from_log_q(log_target_q: i64, bit_depth: i32) -> QuantizerParameters {
log_target_dc_q: i64, log_target_ac_q: i64, bit_depth: i32 let quantizer = bexp64(log_target_q + q57(QSCALE + bit_depth - 8));
) -> QuantizerParameters {
let quantizer = bexp64(log_target_ac_q + q57(QSCALE + bit_depth - 8));
let qi = select_ac_qi(quantizer, bit_depth as usize);
QuantizerParameters { QuantizerParameters {
log_target_q: log_target_dc_q, log_target_q,
dc_qi: qi, dc_qi: select_dc_qi(quantizer, bit_depth as usize),
ac_qi: qi, ac_qi: select_ac_qi(quantizer, bit_depth as usize),
lambda: (::std::f64::consts::LN_2 / 6.0) lambda: (::std::f64::consts::LN_2 / 6.0)
* ((log_target_dc_q as f64) * Q57_SQUARE_EXP_SCALE).exp() * ((log_target_q as f64) * Q57_SQUARE_EXP_SCALE).exp()
} }
} }
} }
...@@ -282,15 +279,11 @@ impl RCState { ...@@ -282,15 +279,11 @@ impl RCState {
let q_drop = 15 * (fti - FRAME_SUBTYPE_P); let q_drop = 15 * (fti - FRAME_SUBTYPE_P);
base_qi.min(255 - q_drop) + q_drop base_qi.min(255 - q_drop) + q_drop
}; };
// We want to use the DC quantizer to calculate lambda, but we cannot use // We use the AC quantizer as the source quantizer since its quantizer
// it to map log_q back to qi, because the DC quantizer table entries // tables have unique entries, while the DC tables do not.
// are not unique. let quantizer = ac_q(qi as u8, 0, bit_depth as usize) as i64;
// The corresponding AC quantizer table entries are unique. // Get the log quantizer as Q57.
let dc_quantizer = dc_q(qi as u8, 0, bit_depth as usize) as i64; let log_q = blog64(quantizer) - q57(QSCALE + bit_depth - 8);
let ac_quantizer = ac_q(qi as u8, 0, bit_depth as usize) as i64; QuantizerParameters::new_from_log_q(log_q, bit_depth)
// Get the log quantizers as Q57.
let log_dc_q = blog64(dc_quantizer) - q57(QSCALE + bit_depth - 8);
let log_ac_q = blog64(ac_quantizer) - q57(QSCALE + bit_depth - 8);
QuantizerParameters::new_from_log_q(log_dc_q, log_ac_q, bit_depth)
} }
} }
Supports Markdown
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