shithub: libvpx

Download patch

ref: 06c8713e89514ccbed2d68e847adfd7830b53881
parent: 36533e8c5a00b0ae430ba2b102bedfd587e67db1
author: Marco <marpan@google.com>
date: Thu Mar 16 11:55:33 EDT 2017

vp9: Use sb content measure to bias against golden.

For each superblock, keep track of how far from current frame
was the last significant content change, and use that (along
with GF distance), to turnoff GF search in non-rd pickmode.

Only enabled for speed >= 8.

avgPNSR on RTC/RTC_derf down by ~0.9/1.2.
Speedup on mac: ~3-5%.
Speedup on arm: 3.6% for VGA and 4.4% for HD.

Change-Id: Ic3f3d6a2af650aca6ba0064d2b1db8d48c035ac7

--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -170,6 +170,8 @@
 
   uint8_t skip_low_source_sad;
 
+  uint8_t last_sb_high_content;
+
   // Used to save the status of whether a block has a low variance in
   // choose_partitioning. 0 for 64x64, 1~2 for 64x32, 3~4 for 32x64, 5~8 for
   // 32x32, 9~24 for 16x16.
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1018,6 +1018,7 @@
                               content_state == kLowSadHighSumdiff)
                                  ? 1
                                  : 0;
+    x->last_sb_high_content = cpi->content_state_sb_fd[sb_offset2];
     // If source_sad is low copy the partition without computing the y_sad.
     if (x->skip_low_source_sad && cpi->sf.copy_partition_flag &&
         copy_partitioning(cpi, x, mi_row, mi_col, segment_id, sb_offset)) {
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -466,6 +466,9 @@
   vpx_free(cpi->content_state_sb);
   cpi->content_state_sb = NULL;
 
+  vpx_free(cpi->content_state_sb_fd);
+  cpi->content_state_sb_fd = NULL;
+
   vp9_cyclic_refresh_free(cpi->cyclic_refresh);
   cpi->cyclic_refresh = NULL;
 
@@ -3141,10 +3144,14 @@
         cpi->svc.current_superframe < 1)) ||
       cpi->resize_pending || cpi->resize_state || cpi->external_resize) {
     compute_source_sad = 0;
-    if (cpi->content_state_sb != NULL)
+    if (cpi->content_state_sb != NULL) {
       memset(cpi->content_state_sb, 0, (cm->mi_stride >> 3) *
                                            ((cm->mi_rows >> 3) + 1) *
                                            sizeof(*cpi->content_state_sb));
+      memset(cpi->content_state_sb_fd, 0,
+             (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) *
+                 sizeof(*cpi->content_state_sb_fd));
+    }
   }
 
   // Avoid scaling last_source unless its needed.
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -705,7 +705,12 @@
   uint8_t *copied_frame_cnt;
   uint8_t max_copied_frame;
 
+  // For each superblock: saves the content value (e.g., low/high sad/sumdiff)
+  // based on source sad, prior to encoding the frame.
   uint8_t *content_state_sb;
+  // For each superblock: keeps track of the last time (in frame distance) the
+  // the superblock did not have low source sad.
+  uint8_t *content_state_sb_fd;
 
   LevelConstraint level_constraint;
 } VP9_COMP;
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1563,6 +1563,11 @@
     usable_ref_frame = LAST_FRAME;
 #endif
 
+  if (cpi->oxcf.speed >= 8 && !cpi->use_svc &&
+      ((cpi->rc.frames_since_golden + 1) < x->last_sb_high_content ||
+       x->last_sb_high_content > 40))
+    usable_ref_frame = LAST_FRAME;
+
   for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) {
     if (!skip_ref_find_pred[ref_frame]) {
       find_predictors(cpi, x, ref_frame, frame_mv, const_motion,
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -2285,6 +2285,7 @@
         int sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
         int sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
         uint64_t avg_source_sad_threshold = 10000;
+        uint64_t avg_source_sad_threshold2 = 12000;
         if (cpi->oxcf.lag_in_frames > 0) {
           src_y = frames[frame]->y_buffer;
           src_ystride = frames[frame]->y_stride;
@@ -2315,6 +2316,13 @@
                   cpi->content_state_sb[num_samples] =
                       ((tmp_sse - tmp_variance) < 25) ? kHighSadLowSumdiff
                                                       : kHighSadHighSumdiff;
+                if (tmp_sad < avg_source_sad_threshold2) {
+                  // Cap the increment to 255.
+                  if (cpi->content_state_sb_fd[num_samples] < 255)
+                    cpi->content_state_sb_fd[num_samples]++;
+                } else {
+                  cpi->content_state_sb_fd[num_samples] = 0;
+                }
               }
               avg_sad += tmp_sad;
               num_samples++;
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -518,6 +518,8 @@
            cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) {
         cpi->content_state_sb = (uint8_t *)vpx_calloc(
             (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(uint8_t));
+        cpi->content_state_sb_fd = (uint8_t *)vpx_calloc(
+            (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(uint8_t));
       }
     }
   }