shithub: libvpx

Download patch

ref: 835f16ea362c61d660986bde58dd40d80ee62cf5
parent: aa5b517a39ae9f311129636a2c0dc41892d3d44f
parent: 1abf575f326c8e7163ffc0122595d2537e207f96
author: Marco Paniconi <marpan@google.com>
date: Tue Dec 8 19:34:09 EST 2015

Merge "vp9 denoiser: Re-evaluate mode selection for golden reference."

--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -194,7 +194,8 @@
                                                          int mi_col,
                                                          PICK_MODE_CONTEXT *ctx,
                                                          int motion_magnitude,
-                                                         int is_skin) {
+                                                         int is_skin,
+                                                         int *zeromv_filter) {
   int mv_col, mv_row;
   int sse_diff = ctx->zeromv_sse - ctx->newmv_sse;
   MV_REFERENCE_FRAME frame;
@@ -237,6 +238,7 @@
     mbmi->mv[0].as_int = 0;
     ctx->best_sse_inter_mode = ZEROMV;
     ctx->best_sse_mv.as_int = 0;
+    *zeromv_filter = 1;
   }
 
   if (ctx->newmv_sse > sse_thresh(bs, increase_denoising)) {
@@ -320,6 +322,7 @@
                           VP9_DENOISER_DECISION *denoiser_decision) {
   int mv_col, mv_row;
   int motion_magnitude = 0;
+  int zeromv_filter = 0;
   VP9_DENOISER_DECISION decision = COPY_BLOCK;
   YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME];
   YV12_BUFFER_CONFIG mc_avg = denoiser->mc_running_avg_y;
@@ -360,7 +363,8 @@
                                            denoiser->increase_denoising,
                                            mi_row, mi_col, ctx,
                                            motion_magnitude,
-                                           is_skin);
+                                           is_skin,
+                                           &zeromv_filter);
 
   if (decision == FILTER_BLOCK) {
     decision = vp9_denoiser_filter(src.buf, src.stride,
@@ -382,6 +386,8 @@
                       num_4x4_blocks_high_lookup[bs] << 2);
   }
   *denoiser_decision = decision;
+  if (decision == FILTER_BLOCK && zeromv_filter == 1)
+    *denoiser_decision = FILTER_ZEROMV_BLOCK;
 }
 
 static void copy_frame(YV12_BUFFER_CONFIG * const dest,
--- a/vp9/encoder/vp9_denoiser.h
+++ b/vp9/encoder/vp9_denoiser.h
@@ -23,7 +23,8 @@
 
 typedef enum vp9_denoiser_decision {
   COPY_BLOCK,
-  FILTER_BLOCK
+  FILTER_BLOCK,
+  FILTER_ZEROMV_BLOCK
 } VP9_DENOISER_DECISION;
 
 typedef enum vp9_denoiser_level {
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1696,11 +1696,11 @@
     VP9_DENOISER_DECISION decision = COPY_BLOCK;
     vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col,
                          VPXMAX(BLOCK_8X8, bsize), ctx, &decision);
-    // If INTRA mode was selected, re-evaluate ZEROMV on denoised result.
-    // Only do this under noise conditions, and if rdcost of ZEROMV on
-    // original source is not significantly higher than rdcost of INTRA MODE.
-    if (best_ref_frame == INTRA_FRAME &&
-        decision == FILTER_BLOCK &&
+    // If INTRA or GOLDEN reference was selected, re-evaluate ZEROMV on denoised
+    // result. Only do this under noise conditions, and if rdcost of ZEROMV on
+    // original source is not significantly higher than rdcost of best mode.
+    if (((best_ref_frame == INTRA_FRAME && decision >= FILTER_BLOCK) ||
+        (best_ref_frame == GOLDEN_FRAME && decision == FILTER_ZEROMV_BLOCK)) &&
         cpi->noise_estimate.enabled &&
         cpi->noise_estimate.level > kLow &&
         zero_last_cost_orig < (best_rdc.rdcost << 3)) {
@@ -1721,13 +1721,21 @@
       this_rdc.dist = dist;
       this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, rate, dist);
       // Switch to ZEROMV if the rdcost for ZEROMV on denoised source
-      // is lower than INTRA (on original source).
+      // is lower than best_ref mode (on original source).
       if (this_rdc.rdcost > best_rdc.rdcost) {
         this_rdc = best_rdc;
         mbmi->mode = best_mode;
         mbmi->ref_frame[0] = best_ref_frame;
-        mbmi->mv[0].as_int = INVALID_MV;
         mbmi->interp_filter = best_pred_filter;
+        if (best_ref_frame == INTRA_FRAME)
+          mbmi->mv[0].as_int = INVALID_MV;
+        else if (best_ref_frame == GOLDEN_FRAME) {
+          mbmi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
+          if (reuse_inter_pred) {
+            xd->plane[0].pre[0] = yv12_mb[GOLDEN_FRAME][0];
+            vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
+          }
+        }
         mbmi->tx_size = best_tx_size;
         x->skip_txfm[0] = best_mode_skip_txfm;
       } else {