From 8cf656e3f2be9ad651c9450ace39e16ddb529e3a Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Tue, 2 Apr 2019 16:38:49 +0100 Subject: [PATCH] Film Mode: Bias based on sub block energy. Apply a bias for film mode against intra coding (especially DC_PRED) and compound modes if the sub blocks of the current block have significantly different variance in the source. Change-Id: Iac1fc0510141be5c472a0ec57567bab3d2fc4164 --- vp9/encoder/vp9_rdopt.c | 53 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index bf631d1..a1f1069 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -3132,6 +3132,7 @@ 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 second_ref_frame, PREDICTION_MODE this_mode) { MACROBLOCKD *const xd = &x->e_mbd; unsigned int rec_variance; @@ -3175,6 +3176,8 @@ static void rd_variance_adjustment(VP9_COMP *cpi, MACROBLOCK *x, if (ref_frame == INTRA_FRAME) { low_var_thresh *= 2; if (this_mode == DC_PRED) low_var_thresh *= 5; + } else if (second_ref_frame > INTRA_FRAME) { + low_var_thresh *= 2; } } } else { @@ -3199,19 +3202,13 @@ static void rd_variance_adjustment(VP9_COMP *cpi, MACROBLOCK *x, (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) { - if (this_mode == DC_PRED) - *this_rd *= 2; - else - *this_rd += (*this_rd / 4); - } - } + if ((content_type == VP9E_CONTENT_FILM) && + ((ref_frame == INTRA_FRAME) || (second_ref_frame > INTRA_FRAME))) { + var_factor *= 2; } + *this_rd += (*this_rd * var_factor) / 100; + (void)xd; } @@ -3747,11 +3744,39 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, TileDataEnc *tile_data, this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); } - // Apply an adjustment to the rd value based on the similarity of the - // source variance and reconstructed variance. if (recon) { + // In film mode bias against DC pred and other intra if there is a + // significant difference between the variance of the sub blocks in the + // the source. Also apply some bias against compound modes which also + // tend to blur fine texture such as film grain over time. + // + // The sub block test here acts in the case where one or more sub + // blocks have high relatively variance but others relatively low + // variance. Here the high variance sub blocks may push the + // total variance for the current block size over the thresholds + // used in rd_variance_adjustment() below. + if (cpi->oxcf.content == VP9E_CONTENT_FILM) { + if (bsize >= BLOCK_16X16) { + int min_energy, max_energy; + vp9_get_sub_block_energy(cpi, x, mi_row, mi_col, bsize, &min_energy, + &max_energy); + if (max_energy > min_energy) { + if (ref_frame == INTRA_FRAME) { + if (this_mode == DC_PRED) + this_rd += (this_rd * (max_energy - min_energy)); + else + this_rd += (this_rd * (max_energy - min_energy)) / 4; + } else if (second_ref_frame > INTRA_FRAME) { + this_rd += this_rd / 4; + } + } + } + } + + // 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, recon, ref_frame, - this_mode); + second_ref_frame, this_mode); } if (ref_frame == INTRA_FRAME) { -- 2.7.4