ref: 8cf656e3f2be9ad651c9450ace39e16ddb529e3a
parent: 4d1637ff67a8912504e27d31ff445b0be4531451
author: Paul Wilkins <paulwilkins@google.com>
date: Tue Apr 2 12:38:49 EDT 2019
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
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3132,6 +3132,7 @@
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 @@
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 @@
(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 @@
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) {