vp9: Add rc quantity to track amount of low motion in scene.
authorMarco <marpan@google.com>
Fri, 22 Apr 2016 22:27:53 +0000 (15:27 -0700)
committerMarco <marpan@google.com>
Mon, 25 Apr 2016 16:07:35 +0000 (09:07 -0700)
Use it for now in noise estimation to bypass estimation if
motion level is high.

Change-Id: I033662dc909f2060e4e81abf562a7ad262dc8170

vp9/encoder/vp9_noise_estimate.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_ratectrl.h

index a96b912..d4fee6f 100644 (file)
@@ -128,6 +128,14 @@ void vp9_update_noise_estimate(VP9_COMP *const cpi) {
       ne->last_h = cm->height;
     }
     return;
+  } else if (cpi->rc.avg_frame_low_motion < 50) {
+    // Force noise estimation to 0 and denoiser off if content has high motion.
+    ne->level = kLowLow;
+#if CONFIG_VP9_TEMPORAL_DENOISING
+    if (cpi->oxcf.noise_sensitivity > 0)
+      vp9_denoiser_set_noise_level(&cpi->denoiser, ne->level);
+#endif
+    return;
   } else {
     int num_samples = 0;
     uint64_t avg_est = 0;
index 3bd1753..749f91a 100644 (file)
@@ -338,6 +338,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
   rc->total_target_bits = 0;
   rc->total_target_vs_actual = 0;
   rc->avg_intersize_gfint = 0;
+  rc->avg_frame_low_motion = 0;
 
   rc->frames_since_key = 8;  // Sensible default for first frame.
   rc->this_key_frame_forced = 0;
@@ -1334,6 +1335,26 @@ static void update_golden_frame_stats(VP9_COMP *cpi) {
   }
 }
 
+static void compute_frame_low_motion(VP9_COMP *const cpi) {
+  VP9_COMMON *const cm = &cpi->common;
+  int mi_row, mi_col;
+  MODE_INFO **mi = cm->mi_grid_visible;
+  RATE_CONTROL *const rc = &cpi->rc;
+  const int rows = cm->mi_rows, cols = cm->mi_cols;
+  int cnt_zeromv = 0;
+  for (mi_row = 0; mi_row < rows; mi_row++) {
+    for (mi_col = 0; mi_col < cols; mi_col++) {
+      if (abs(mi[0]->mv[0].as_mv.row) < 16 &&
+          abs(mi[0]->mv[0].as_mv.col) < 16)
+        cnt_zeromv++;
+      mi++;
+    }
+    mi += 8;
+  }
+  cnt_zeromv = 100 * cnt_zeromv / (rows * cols);
+  rc->avg_frame_low_motion = (3 * rc->avg_frame_low_motion + cnt_zeromv) >> 2;
+}
+
 void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
   const VP9_COMMON *const cm = &cpi->common;
   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
@@ -1447,6 +1468,9 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
         rc->next_frame_size_selector != rc->frame_size_selector;
     rc->frame_size_selector = rc->next_frame_size_selector;
   }
+
+  if (oxcf->pass == 0 && cm->frame_type != KEY_FRAME)
+    compute_frame_low_motion(cpi);
 }
 
 void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) {
index 7b6f165..eef1940 100644 (file)
@@ -163,6 +163,7 @@ typedef struct {
   int high_source_sad;
   int count_last_scene_change;
   int avg_intersize_gfint;
+  int avg_frame_low_motion;
 } RATE_CONTROL;
 
 struct VP9_COMP;