Commit b6425127 authored by Guillaume Martres's avatar Guillaume Martres Committed by Guillaume Martres

Remove rd_variance_adjustment

This function is called after `super_block_yrd` and assumes that the dst
buffer is correct but that is no longer always the case after
daf841b4 since we don't call
`txfm_rd_in_plane` after the RDO loop in `choose_tx_size_from_rd`.
We could fix this by always saving and restoring the dst buffer but
removing `rd_variance_adjustment` is a better solution:
- Getting the dst buffer always right is tricky as demonstrated by the
  fact that it is wrong now, even if we fix it now we could break it later
  and not notice
- Perceptual weighting is a good idea but `rd_variance_adjustment` is the
  wrong approach as it weights both the rate and the distortion:
  to get meaningful units you should only weight the distortion,
  weighting rate means that we pretend some bits cost less than other
  bits, this is not the case. The distortion weighting approach is
  implemented by Daala in `od_compute_dist` and we plan to experiment
  with this in AV1 too.
- Removing `rd_variance_adjustment` improves coding efficiency on all
  metrics, here are the results for objective-1-fast using the Low
  Latency settings:

      PSNR Y:     -0.14%
     PSNRHVS:     -0.17%
        SSIM:     -0.12%
      MSSSIM:     -0.12%
   CIEDE2000:     -0.07%

Change-Id: I74b26b568ee65f56521646b8f30dd53bcd29fce3
parent 6a9922c0
...@@ -3898,61 +3898,6 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x, ...@@ -3898,61 +3898,6 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist); rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
} }
// This function is designed to apply a bias or adjustment to an rd value based
// on the relative variance of the source and reconstruction.
#define LOW_VAR_THRESH 16
#define VLOW_ADJ_MAX 25
#define VHIGH_ADJ_MAX 8
static void rd_variance_adjustment(const AV1_COMP *const cpi, MACROBLOCK *x,
BLOCK_SIZE bsize, int64_t *this_rd,
MV_REFERENCE_FRAME ref_frame,
unsigned int source_variance) {
MACROBLOCKD *const xd = &x->e_mbd;
unsigned int recon_variance;
unsigned int absvar_diff = 0;
int64_t var_error = 0;
int64_t var_factor = 0;
if (*this_rd == INT64_MAX) return;
#if CONFIG_AOM_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
recon_variance = av1_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst,
bsize, xd->bd);
} else {
recon_variance =
av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
}
#else
recon_variance = av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
#endif // CONFIG_AOM_HIGHBITDEPTH
if ((source_variance + recon_variance) > LOW_VAR_THRESH) {
absvar_diff = (source_variance > recon_variance)
? (source_variance - recon_variance)
: (recon_variance - source_variance);
var_error = ((int64_t)200 * source_variance * recon_variance) /
(((int64_t)source_variance * source_variance) +
((int64_t)recon_variance * recon_variance));
var_error = 100 - var_error;
}
// Source variance above a threshold and ref frame is intra.
// This case is targeted mainly at discouraging intra modes that give rise
// to a predictor with a low spatial complexity compared to the source.
if ((source_variance > LOW_VAR_THRESH) && (ref_frame == INTRA_FRAME) &&
(source_variance > recon_variance)) {
var_factor = AOMMIN(absvar_diff, AOMMIN(VLOW_ADJ_MAX, var_error));
// A second possible case of interest is where the source variance
// is very low and we wish to discourage false texture or motion trails.
} else if ((source_variance < (LOW_VAR_THRESH >> 1)) &&
(recon_variance > source_variance)) {
var_factor = AOMMIN(absvar_diff, AOMMIN(VHIGH_ADJ_MAX, var_error));
}
*this_rd += (*this_rd * var_factor) / 100;
}
// Do we have an internal image edge (e.g. formatting bars). // Do we have an internal image edge (e.g. formatting bars).
int av1_internal_image_edge(const AV1_COMP *cpi) { int av1_internal_image_edge(const AV1_COMP *cpi) {
return (cpi->oxcf.pass == 2) && return (cpi->oxcf.pass == 2) &&
...@@ -4848,11 +4793,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data, ...@@ -4848,11 +4793,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
#endif // CONFIG_MOTION_VAR #endif // CONFIG_MOTION_VAR
} }
// Apply an adjustment to the rd value based on the similarity of the
// source variance and reconstructed variance.
rd_variance_adjustment(cpi, x, bsize, &this_rd, ref_frame,
x->source_variance);
if (ref_frame == INTRA_FRAME) { if (ref_frame == INTRA_FRAME) {
// Keep record of best intra rd // Keep record of best intra rd
if (this_rd < best_intra_rd) { if (this_rd < best_intra_rd) {
......
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