shithub: libvpx

Download patch

ref: 8dc15230576f8900327f38c667dda1cab41e3894
parent: d642dd43110f93fafa9c88e86cf2fc6464340663
parent: 06c8713e89514ccbed2d68e847adfd7830b53881
author: Marco Paniconi <marpan@google.com>
date: Mon Mar 20 17:35:11 EDT 2017

Merge "vp9: Use sb content measure to bias against golden."

--- 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));
       }
     }
   }