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:
paulwilkins 2015-03-06 17:21:36 +00:00
parent 4640a0c480
commit 9a1ce7be7d
3 changed files with 74 additions and 7 deletions

View File

@ -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.

View File

@ -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) {

View File

@ -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,