]> granicus.if.org Git - libvpx/commitdiff
vp9: Use sb content measure to bias against golden.
authorMarco <marpan@google.com>
Thu, 16 Mar 2017 22:55:33 +0000 (15:55 -0700)
committerMarco <marpan@google.com>
Mon, 20 Mar 2017 19:42:26 +0000 (12:42 -0700)
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

vp9/encoder/vp9_block.h
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_encoder.h
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_speed_features.c

index c86c818aaadba485fc770fa3dc595e9c9ec3885e..071a9b3e353396960a56cea1330027e8215f4772 100644 (file)
@@ -170,6 +170,8 @@ struct macroblock {
 
   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.
index df72667d4244bc0f9d97220e9371f20ad44e039a..e6f4901fdb7dbb0a98762485ef5b71993e1a5fe6 100644 (file)
@@ -1018,6 +1018,7 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
                               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)) {
index 64d6985b55fba3042c305ab8d0017ba027102fb2..aba2c115a370f7b7ae1628f61e2fc53b60eb6620 100644 (file)
@@ -466,6 +466,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
   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 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
         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.
index ba29cabb1ffd2ca6764d5f842f1d263e96f4c1d6..72c0ba78706ac1604cb6a1a642bf58e5f4a3f40d 100644 (file)
@@ -705,7 +705,12 @@ typedef struct VP9_COMP {
   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;
index 46fb67a93818f24e03488d89a2bc08aaa92a0bd2..ecc9afbad656232aaf03de0e915b06a14da31f74 100644 (file)
@@ -1563,6 +1563,11 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
     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,
index b95cd77736b687c71137818810c6bbc6f1b239e0..fb41427eab62b2544e8f1de869a31bcf01517ef1 100644 (file)
@@ -2285,6 +2285,7 @@ void vp9_avg_source_sad(VP9_COMP *cpi) {
         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 @@ void vp9_avg_source_sad(VP9_COMP *cpi) {
                   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++;
index 2ce836f2eba35e6f4ced5fa4701760f95d4c4944..fd589f9909a3a6253b929206861923a4957535a6 100644 (file)
@@ -518,6 +518,8 @@ static void set_rt_speed_feature_framesize_independent(
            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));
       }
     }
   }