summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/encoder/vp9_rdopt.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 27c580107..8ed27a80c 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3131,14 +3131,16 @@ static unsigned int max_var_adjust[VP9E_CONTENT_INVALID] = { 16, 16, 250 };
static void rd_variance_adjustment(VP9_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bsize, int64_t *this_rd,
struct buf_2d *recon,
- MV_REFERENCE_FRAME ref_frame) {
+ MV_REFERENCE_FRAME ref_frame,
+ PREDICTION_MODE this_mode) {
MACROBLOCKD *const xd = &x->e_mbd;
unsigned int rec_variance;
unsigned int src_variance;
unsigned int src_rec_min;
- unsigned int absvar_diff = 0;
+ unsigned int var_diff = 0;
unsigned int var_factor = 0;
unsigned int adj_max;
+ unsigned int low_var_thresh = LOW_VAR_THRESH;
const int bw = num_8x8_blocks_wide_lookup[bsize];
const int bh = num_8x8_blocks_high_lookup[bsize];
vp9e_tune_content content_type = cpi->oxcf.content;
@@ -3163,28 +3165,45 @@ static void rd_variance_adjustment(VP9_COMP *cpi, MACROBLOCK *x,
rec_variance /= (bw * bh);
src_variance /= (bw * bh);
+ if (content_type == VP9E_CONTENT_FILM) {
+ if (cpi->oxcf.pass == 2) {
+ // Adjust low variance threshold based on estimated group noise enegry.
+ double noise_factor =
+ (double)cpi->twopass.gf_group.group_noise_energy / SECTION_NOISE_DEF;
+ low_var_thresh = (unsigned int)(low_var_thresh * noise_factor);
+ }
+ } else {
+ low_var_thresh = LOW_VAR_THRESH / 2;
+ }
+
// Lower of source (raw per pixel value) and recon variance. Note that
// if the source per pixel is 0 then the recon value here will not be per
// pixel (see above) so will likely be much larger.
src_rec_min = VPXMIN(src_variance, rec_variance);
- if (src_rec_min > LOW_VAR_THRESH) return;
+ if (src_rec_min > low_var_thresh) return;
- absvar_diff = (src_variance > rec_variance) ? (src_variance - rec_variance)
- : (rec_variance - src_variance);
+ // We care more when the reconstruction has lower variance so give this case
+ // a stronger weighting.
+ var_diff = (src_variance > rec_variance) ? (src_variance - rec_variance) * 2
+ : (rec_variance - src_variance) / 2;
adj_max = max_var_adjust[content_type];
var_factor =
- (unsigned int)((int64_t)VAR_MULT * absvar_diff) / VPXMAX(1, src_variance);
+ (unsigned int)((int64_t)VAR_MULT * var_diff) / VPXMAX(1, src_variance);
var_factor = VPXMIN(adj_max, var_factor);
*this_rd += (*this_rd * var_factor) / 100;
if (content_type == VP9E_CONTENT_FILM) {
- if (src_rec_min <= LOW_VAR_THRESH / 2) {
- if (ref_frame == INTRA_FRAME) *this_rd *= 2;
- if (bsize > BLOCK_16X16) *this_rd *= 2;
+ if (src_rec_min <= low_var_thresh / 2) {
+ if (ref_frame == INTRA_FRAME) {
+ if (this_mode == DC_PRED)
+ *this_rd *= 2;
+ else
+ *this_rd += (*this_rd / 4);
+ }
}
}
@@ -3726,7 +3745,8 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, TileDataEnc *tile_data,
// Apply an adjustment to the rd value based on the similarity of the
// source variance and reconstructed variance.
if (recon) {
- rd_variance_adjustment(cpi, x, bsize, &this_rd, recon, ref_frame);
+ rd_variance_adjustment(cpi, x, bsize, &this_rd, recon, ref_frame,
+ this_mode);
}
if (ref_frame == INTRA_FRAME) {