shithub: libvpx

Download patch

ref: 8cf656e3f2be9ad651c9450ace39e16ddb529e3a
parent: 4d1637ff67a8912504e27d31ff445b0be4531451
author: Paul Wilkins <[email protected]>
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) {