shithub: libvpx

Download patch

ref: 1c0857d648c1e2eb13de3d2e717b1848bbc602d9
parent: 68fbf82ef0150da74470af78be8e2868e4ec2812
parent: 0ef5016878f0c22ac8262db78eef0b977ccb3b9c
author: Paul Wilkins <paulwilkins@google.com>
date: Tue Apr 2 08:00:03 EDT 2019

Merge changes Ied3992f4,I83ca669b,I8f1c1a29

* changes:
  Further Adjustments to film mode bias.
  Add GF group noise weighting in rd_variance_adjustment()
  Adjustment to low variance block bias in rd_variance_adjustment()

--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3131,14 +3131,16 @@
 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 @@
   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 @@
     // 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) {