Experimental rd bias based on source vs recon variance.
This experiment biases the rd decision based on the impact a mode decision has on the relative spatial complexity of the reconstruction vs the source. The aim is to better retain a semblance of texture even if it is slightly misaligned / wrong, rather than use a simple rd measure that tends to favor use of a flat predictor if a perfect match can't be found. This improves the appearance of texture and visual quality on specific test clips but is hidden under a flag and currently off by default pending visual quality testing on a wider Yt set. Change-Id: Idf6e754a8949bf39ed9d314c6f2daaa20c888aad
This commit is contained in:
parent
4640a0c480
commit
9a1ce7be7d
@ -99,9 +99,9 @@ static const uint16_t VP9_HIGH_VAR_OFFS_12[64] = {
|
||||
};
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi,
|
||||
const struct buf_2d *ref,
|
||||
BLOCK_SIZE bs) {
|
||||
unsigned int vp9_get_sby_perpixel_variance(VP9_COMP *cpi,
|
||||
const struct buf_2d *ref,
|
||||
BLOCK_SIZE bs) {
|
||||
unsigned int sse;
|
||||
const unsigned int var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
|
||||
VP9_VAR_OFFS, 0, &sse);
|
||||
@ -109,7 +109,7 @@ static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi,
|
||||
}
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
static unsigned int high_get_sby_perpixel_variance(
|
||||
unsigned int vp9_high_get_sby_perpixel_variance(
|
||||
VP9_COMP *cpi, const struct buf_2d *ref, BLOCK_SIZE bs, int bd) {
|
||||
unsigned int var, sse;
|
||||
switch (bd) {
|
||||
@ -1072,13 +1072,15 @@ static void rd_pick_sb_modes(VP9_COMP *cpi,
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
x->source_variance =
|
||||
high_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize, xd->bd);
|
||||
vp9_high_get_sby_perpixel_variance(cpi, &x->plane[0].src,
|
||||
bsize, xd->bd);
|
||||
} else {
|
||||
x->source_variance =
|
||||
get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
|
||||
vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
|
||||
}
|
||||
#else
|
||||
x->source_variance = get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
|
||||
x->source_variance =
|
||||
vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
// Save rdmult before it might be changed, so it can be restored later.
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
#define MIN_EARLY_TERM_INDEX 3
|
||||
#define NEW_MV_DISCOUNT_FACTOR 8
|
||||
#define SOURCE_VARIANCE_RD_ADJUSTMENT 0
|
||||
|
||||
typedef struct {
|
||||
PREDICTION_MODE mode;
|
||||
@ -2824,6 +2825,55 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
|
||||
}
|
||||
|
||||
#if SOURCE_VARIANCE_RD_ADJUSTMENT
|
||||
// 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 LOW_VAR_DIFF_THRESH 1
|
||||
#define VLOW_ADJ_MAX 25
|
||||
#define VHIGH_ADJ_MAX 10
|
||||
static void rd_variance_adjustment(VP9_COMP *cpi,
|
||||
MACROBLOCK *x,
|
||||
BLOCK_SIZE bsize,
|
||||
int64_t *this_rd,
|
||||
unsigned int source_variance) {
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
unsigned int recon_variance;
|
||||
unsigned int var_diff;
|
||||
|
||||
if (*this_rd == INT64_MAX)
|
||||
return;
|
||||
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
recon_variance =
|
||||
vp9_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
|
||||
} else {
|
||||
recon_variance =
|
||||
vp9_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
|
||||
}
|
||||
#else
|
||||
recon_variance =
|
||||
vp9_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
||||
var_diff = (source_variance > recon_variance)
|
||||
? (source_variance - recon_variance) : (recon_variance - source_variance);
|
||||
|
||||
if ((source_variance > LOW_VAR_THRESH) && (var_diff > LOW_VAR_DIFF_THRESH)) {
|
||||
unsigned int var_factor;
|
||||
if (source_variance > recon_variance) {
|
||||
var_factor =
|
||||
MIN(VLOW_ADJ_MAX, (var_diff * VLOW_ADJ_MAX) / source_variance);
|
||||
} else {
|
||||
var_factor =
|
||||
MIN(VHIGH_ADJ_MAX, (var_diff * VHIGH_ADJ_MAX) / source_variance);
|
||||
}
|
||||
*this_rd += (*this_rd * var_factor) / 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
TileDataEnc *tile_data,
|
||||
MACROBLOCK *x,
|
||||
@ -3280,6 +3330,12 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
|
||||
}
|
||||
|
||||
#if SOURCE_VARIANCE_RD_ADJUSTMENT
|
||||
// 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, x->source_variance);
|
||||
#endif
|
||||
|
||||
if (ref_frame == INTRA_FRAME) {
|
||||
// Keep record of best intra rd
|
||||
if (this_rd < best_intra_rd) {
|
||||
|
@ -29,6 +29,15 @@ void vp9_rd_pick_intra_mode_sb(struct VP9_COMP *cpi, struct macroblock *x,
|
||||
struct RD_COST *rd_cost, BLOCK_SIZE bsize,
|
||||
PICK_MODE_CONTEXT *ctx, int64_t best_rd);
|
||||
|
||||
unsigned int vp9_get_sby_perpixel_variance(VP9_COMP *cpi,
|
||||
const struct buf_2d *ref,
|
||||
BLOCK_SIZE bs);
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
unsigned int vp9_high_get_sby_perpixel_variance(VP9_COMP *cpi,
|
||||
const struct buf_2d *ref,
|
||||
BLOCK_SIZE bs, int bd);
|
||||
#endif
|
||||
|
||||
void vp9_rd_pick_inter_mode_sb(struct VP9_COMP *cpi,
|
||||
struct TileDataEnc *tile_data,
|
||||
struct macroblock *x,
|
||||
|
Loading…
x
Reference in New Issue
Block a user