]> granicus.if.org Git - libvpx/commitdiff
vp9: Stop copying partition every a fixed number of frames.
authorJerome Jiang <jianj@google.com>
Fri, 13 Jan 2017 22:20:59 +0000 (14:20 -0800)
committerJerome Jiang <jianj@google.com>
Wed, 18 Jan 2017 19:23:59 +0000 (11:23 -0800)
Avoid quality loss when copying partition of superblock with large motions.
Maximum consecutively copied frames can be set (currently 5).

Change-Id: I11c30575514f02194c0f001444cf4021609e5049

vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_encoder.h
vp9/encoder/vp9_speed_features.c

index b6fadafa3a74b41137f01add8231f3594af7a8c6..73d277313f5cd82a62554e63f87df5c2b2486b7b 100644 (file)
@@ -1043,19 +1043,25 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
 
     // If the y_sad is small enough, copy the partition of the superblock in the
     // last frame to current frame only if the last frame is not a keyframe.
+    // Stop the copy every cpi->max_copied_frame to refresh the partition.
     // TODO(jianj) : tune the threshold.
     if (cpi->sf.copy_partition_flag && cpi->rc.frames_since_key > 1 &&
         segment_id == CR_SEGMENT_ID_BASE &&
         cpi->prev_segment_id[sb_offset] == CR_SEGMENT_ID_BASE &&
-        y_sad_last < cpi->vbp_threshold_copy) {
+        y_sad_last < cpi->vbp_threshold_copy &&
+        cpi->copied_frame_cnt[sb_offset] < cpi->max_copied_frame) {
       if (cpi->prev_partition != NULL) {
         copy_prev_partition(cpi, BLOCK_64X64, mi_row, mi_col);
         chroma_check(cpi, x, bsize, y_sad, is_key_frame);
+        cpi->copied_frame_cnt[sb_offset] += 1;
         memcpy(x->variance_low, &(cpi->prev_variance_low[sb_offset * 25]),
                sizeof(x->variance_low));
         return 0;
       }
     }
+    if (cpi->sf.copy_partition_flag &&
+        cpi->copied_frame_cnt[sb_offset] == cpi->max_copied_frame)
+      cpi->copied_frame_cnt[sb_offset] = 0;
   } else {
     d = VP9_VAR_OFFS;
     dp = 0;
index 63d005ee9043dc3f5190afbd68ef62a04cae5bfa..934afc1528efe387e3670ed7b6663be452ed8959 100644 (file)
@@ -459,6 +459,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
   vpx_free(cpi->prev_variance_low);
   cpi->prev_variance_low = NULL;
 
+  vpx_free(cpi->copied_frame_cnt);
+  cpi->copied_frame_cnt = NULL;
+
   vp9_cyclic_refresh_free(cpi->cyclic_refresh);
   cpi->cyclic_refresh = NULL;
 
index 6741a24b66e3929a5c633fc9b0b9f46656354055..cb10e507444f199ad135f303e90670ccb5c56d1a 100644 (file)
@@ -639,6 +639,8 @@ typedef struct VP9_COMP {
   // This is for the last frame and is copied to the current frame
   // when partition copy happens.
   uint8_t *prev_variance_low;
+  uint8_t *copied_frame_cnt;
+  uint8_t max_copied_frame;
 
   LevelConstraint level_constraint;
 } VP9_COMP;
index 17e2bdbd863b2e7f5e764bd629d312b4ceccd355..934897df0446505aa5cdb2f6021a41b049cb6d44 100644 (file)
@@ -502,8 +502,9 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, int speed,
     if (!cpi->use_svc && !cpi->resize_pending && !cpi->resize_state &&
         !cpi->external_resize && cpi->oxcf.resize_mode == RESIZE_NONE)
       sf->copy_partition_flag = 1;
+
     if (sf->copy_partition_flag) {
-      sf->use_source_sad = 1;
+      cpi->max_copied_frame = 5;
       if (cpi->prev_partition == NULL) {
         cpi->prev_partition = (BLOCK_SIZE *)vpx_calloc(
             cm->mi_stride * cm->mi_rows, sizeof(BLOCK_SIZE));
@@ -517,7 +518,12 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, int speed,
             (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * 25,
             sizeof(uint8_t));
       }
+      if (cpi->copied_frame_cnt == NULL) {
+        cpi->copied_frame_cnt = (uint8_t *)vpx_calloc(
+            (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(uint8_t));
+      }
     }
+
     sf->mv.subpel_force_stop = (content == VP9E_CONTENT_SCREEN) ? 3 : 2;
     if (content == VP9E_CONTENT_SCREEN) sf->lpf_pick = LPF_PICK_MINIMAL_LPF;
     // Only keep INTRA_DC mode for speed 8.