Merge PR #3121: perf(av1): cheaper dequantisation per transform block

This commit is contained in:
aiongg
2026-10-31 02:10:52 +00:00
5 changed files with 14 additions and 11 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ reference) is used only as an external test oracle.
| Tiles and tile groups (uniform and explicit spacing, tile size bytes) | 5.11 | done (tiles decoded in parallel) |
| Intra frame mode info: partitions, skip, segment id, CDEF index, delta q / lf, y / uv modes, angle deltas, CfL alphas, palette (colors, cache, color index map), filter intra, tx size (incl. var-tx syntax) | 5.11 | done, bit-exact |
| Coefficients (all_zero, eob, base / br levels, Golomb, dc sign, tx type sets, scans) | 5.11.39 | done, bit-exact |
| Dequantisation incl. quantiser matrices | 7.12 | done (qmatrix not yet oracle-tested) |
| Dequantisation incl. quantiser matrices | 7.12 | done |
| Inverse transforms: DCT 4–64, ADST 4/8/16, flip ADST, identity 4–32, WHT (lossless), rectangular | 7.13 | done, bit-exact |
| Intra prediction: DC, V/H + directional with edge filter and upsampling, smooth (3), Paeth, recursive filter intra, CfL, palette | 7.11.2, 7.11.4, 7.11.5 | done, bit-exact |
| Inter mode info: segment id prediction, skip mode, reference frames (single / compound, uni / bi), modes, DRL, MV coding, inter-intra, motion mode, compound type, interpolation filters | 5.11.18–5.11.32 | done, bit-exact |
+2 -1
View File
@@ -113,7 +113,8 @@ pub(crate) struct TileDecoder<'a, 'f> {
pub b: Block,
pub mvs: crate::mvpred::MvStack,
pub nb: crate::inter_info::Neighbours,
/// Quant[] for the current transform block (raster order, stride per Adjusted size).
/// Quant[] for the current transform block (raster order, stride per Adjusted size); all
/// zero between transform blocks (`reconstruct` clears what it reads).
quant: Vec<i32>,
dequant: Vec<i32>,
residual: Vec<i32>,
+7 -8
View File
@@ -174,8 +174,6 @@ impl<'a, 'f> TileDecoder<'a, 'f> {
pub(super) fn coeffs(&mut self, plane: usize, start_x: usize, start_y: usize, tx_sz: usize) -> usize {
let pos = TxbPos { x4: start_x >> 2, y4: start_y >> 2, w4: TX_WIDTH[tx_sz] as usize >> 2, h4: TX_HEIGHT[tx_sz] as usize >> 2 };
let tx_sz_ctx = (TX_SIZE_SQR[tx_sz] as usize + TX_SIZE_SQR_UP[tx_sz] as usize + 1) >> 1;
let seg_eob = if tx_sz == TX_16X64 || tx_sz == TX_64X16 { 512 } else { 1024.min(TX_WIDTH[tx_sz] as usize * TX_HEIGHT[tx_sz] as usize) };
self.quant[..seg_eob].iter_mut().for_each(|q| *q = 0);
let mut eob = 0usize;
let mut cul_level = 0u32;
let mut dc_category = 0u8;
@@ -458,10 +456,11 @@ impl<'a, 'f> TileDecoder<'a, 'f> {
/// Reconstruct process (7.12.3).
pub(super) fn reconstruct(&mut self, plane: usize, x: usize, y: usize, tx_sz: usize, dc_only: bool) {
let dq_denom: i64 = match tx_sz {
TX_32X32 | TX_16X32 | TX_32X16 | TX_16X64 | TX_64X16 => 2,
TX_64X64 | TX_32X64 | TX_64X32 => 4,
_ => 1,
// dqDenom (7.12.3) is 1, 2 or 4 and the dividend is non-negative.
let dq_shift = match tx_sz {
TX_32X32 | TX_16X32 | TX_32X16 | TX_16X64 | TX_64X16 => 1,
TX_64X64 | TX_32X64 | TX_64X32 => 2,
_ => 0,
};
let log2w = TX_WIDTH_LOG2[tx_sz] as u32;
let log2h = TX_HEIGHT_LOG2[tx_sz] as u32;
@@ -492,7 +491,7 @@ impl<'a, 'f> TileDecoder<'a, 'f> {
}
for i in 0..th {
for j in 0..tw {
let qv = self.quant[i * tw + j];
let qv = std::mem::take(&mut self.quant[i * tw + j]);
if qv == 0 {
continue;
}
@@ -504,7 +503,7 @@ impl<'a, 'f> TileDecoder<'a, 'f> {
q
};
let dq = qv as i64 * q2;
let mag = (dq.abs() & 0xFFFFFF) / dq_denom;
let mag = (dq.abs() & 0xFFFFFF) >> dq_shift;
let dq2 = if dq < 0 { -mag } else { mag };
self.dequant[i * 64 + j] = dq2.clamp(-lim, lim - 1) as i32;
}
+3 -1
View File
@@ -15,12 +15,14 @@ fn specs() -> Vec<Spec> {
]
}
/// Super-resolution (denominator 12 on the inter frames) and film grain synthesis.
/// Super-resolution (denominator 12 on the inter frames), film grain synthesis and quantiser
/// matrices.
fn specs_tools() -> Vec<Spec> {
let p = |params: &'static str| -> Vec<&'static str> { vec!["-preset", "6", "-crf", "35", "-svtav1-params", params] };
vec![
Spec::new("inter_superres", "testsrc2=s=416x240:r=25", 8, "yuv420p", &p("superres-mode=1:superres-denom=12:superres-kf-denom=13")),
Spec::new("inter_film_grain", "testsrc2=s=352x288:r=25,noise=alls=20:allf=t", 8, "yuv420p", &p("film-grain=10")),
Spec::new("inter_qmatrix_10bit", "mandelbrot=s=352x288:r=25", 8, "yuv420p10le", &p("enable-qm=1:qm-min=0:qm-max=8")),
]
}
+1
View File
@@ -34,6 +34,7 @@ fn specs_filters() -> Vec<Spec> {
Spec::new("intra_lr_mandel", "mandelbrot=s=352x288:r=25", 2, "yuv420p", &p("4", "40", "enable-cdef=0:keyint=1")),
Spec::new("intra_all_testsrc", "testsrc2=s=640x360:r=25", 2, "yuv420p", &p("4", "45", "keyint=1")),
Spec::new("intra_all_10bit", "mandelbrot=s=320x240:r=25", 2, "yuv420p10le", &p("4", "40", "keyint=1")),
Spec::new("intra_qmatrix_noise", "testsrc2=s=352x288:r=25,noise=alls=10:allf=t", 2, "yuv420p", &p("6", "30", "enable-qm=1:qm-min=0:qm-max=8:keyint=1")),
Spec::new("intra_all_noise_odd", "testsrc2=s=250x150:r=25,noise=alls=20:allf=t", 2, "yuv420p", &p("3", "35", "keyint=1")),
// 128x128 superblocks, intra edge filter off, Wiener LR on all planes
Spec::new("intra_all_grad_noise_10bit", "gradients=s=640x360:r=25,noise=alls=25:allf=t", 1, "yuv420p10le", &p("1", "50", "keyint=1")),