shithub: libvpx

Download patch

ref: 6b6ff9c9698518abed286b339f63415b7785ebd4
parent: a2dfbbd7d69f2991b571090c6b356203dffba523
parent: 2ba4729ef80b73187d0f9d9a1fbf7eca60887f67
author: Jerome Jiang <jianj@google.com>
date: Thu May 18 15:37:29 EDT 2017

Merge "vp9: Make copy partition work for SVC and dynamic resize."

--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -841,7 +841,8 @@
   }
 }
 
-static void copy_partitioning_helper(VP9_COMP *cpi, BLOCK_SIZE bsize,
+static void copy_partitioning_helper(VP9_COMP *cpi, MACROBLOCK *x,
+                                     MACROBLOCKD *xd, BLOCK_SIZE bsize,
                                      int mi_row, int mi_col) {
   VP9_COMMON *const cm = &cpi->common;
   BLOCK_SIZE *prev_part = cpi->prev_partition;
@@ -851,36 +852,32 @@
   const int bs = (1 << bsl) / 4;
   BLOCK_SIZE subsize;
   PARTITION_TYPE partition;
-  MODE_INFO *mi = NULL;
 
   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
 
   partition = partition_lookup[bsl][prev_part[start_pos]];
   subsize = get_subsize(bsize, partition);
-  mi = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col];
 
   if (subsize < BLOCK_8X8) {
-    mi->sb_type = bsize;
+    set_block_size(cpi, x, xd, mi_row, mi_col, bsize);
   } else {
     switch (partition) {
-      case PARTITION_NONE: mi->sb_type = bsize; break;
+      case PARTITION_NONE:
+        set_block_size(cpi, x, xd, mi_row, mi_col, bsize);
+        break;
       case PARTITION_HORZ:
-        mi->sb_type = subsize;
-        if (mi_row + bs < cm->mi_rows)
-          cm->mi_grid_visible[(mi_row + bs) * cm->mi_stride + mi_col]->sb_type =
-              subsize;
+        set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
+        set_block_size(cpi, x, xd, mi_row + bs, mi_col, subsize);
         break;
       case PARTITION_VERT:
-        mi->sb_type = subsize;
-        if (mi_col + bs < cm->mi_cols)
-          cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col + bs]->sb_type =
-              subsize;
+        set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
+        set_block_size(cpi, x, xd, mi_row, mi_col + bs, subsize);
         break;
       case PARTITION_SPLIT:
-        copy_partitioning_helper(cpi, subsize, mi_row, mi_col);
-        copy_partitioning_helper(cpi, subsize, mi_row + bs, mi_col);
-        copy_partitioning_helper(cpi, subsize, mi_row, mi_col + bs);
-        copy_partitioning_helper(cpi, subsize, mi_row + bs, mi_col + bs);
+        copy_partitioning_helper(cpi, x, xd, subsize, mi_row, mi_col);
+        copy_partitioning_helper(cpi, x, xd, subsize, mi_row + bs, mi_col);
+        copy_partitioning_helper(cpi, x, xd, subsize, mi_row, mi_col + bs);
+        copy_partitioning_helper(cpi, x, xd, subsize, mi_row + bs, mi_col + bs);
         break;
       default: assert(0);
     }
@@ -887,13 +884,25 @@
   }
 }
 
-static int copy_partitioning(VP9_COMP *cpi, MACROBLOCK *x, int mi_row,
-                             int mi_col, int segment_id, int sb_offset) {
-  if (cpi->rc.frames_since_key > 1 && segment_id == CR_SEGMENT_ID_BASE &&
+static int copy_partitioning(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
+                             int mi_row, int mi_col, int segment_id,
+                             int sb_offset) {
+  int base_is_key = 0;
+  int frames_since_key_thresh = 1;
+  if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
+    int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id,
+                                 cpi->svc.number_temporal_layers);
+    const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
+    if (lc->is_key_frame) base_is_key = 1;
+    frames_since_key_thresh = cpi->svc.number_spatial_layers << 1;
+  }
+  if (cpi->rc.frames_since_key > frames_since_key_thresh &&
+      !cpi->resize_pending && !base_is_key &&
+      segment_id == CR_SEGMENT_ID_BASE &&
       cpi->prev_segment_id[sb_offset] == CR_SEGMENT_ID_BASE &&
       cpi->copied_frame_cnt[sb_offset] < cpi->max_copied_frame) {
     if (cpi->prev_partition != NULL) {
-      copy_partitioning_helper(cpi, BLOCK_64X64, mi_row, mi_col);
+      copy_partitioning_helper(cpi, x, xd, BLOCK_64X64, mi_row, mi_col);
       cpi->copied_frame_cnt[sb_offset] += 1;
       memcpy(x->variance_low, &(cpi->prev_variance_low[sb_offset * 25]),
              sizeof(x->variance_low));
@@ -1081,7 +1090,7 @@
       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)) {
+        copy_partitioning(cpi, x, xd, mi_row, mi_col, segment_id, sb_offset)) {
       return 0;
     }
   }
@@ -1208,7 +1217,7 @@
     // Stop the copy every cpi->max_copied_frame to refresh the partition.
     // TODO(jianj) : tune the threshold.
     if (cpi->sf.copy_partition_flag && y_sad_last < cpi->vbp_threshold_copy &&
-        copy_partitioning(cpi, x, mi_row, mi_col, segment_id, sb_offset)) {
+        copy_partitioning(cpi, x, xd, mi_row, mi_col, segment_id, sb_offset)) {
       chroma_check(cpi, x, bsize, y_sad, is_key_frame);
       return 0;
     }
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -564,10 +564,11 @@
 
   if (speed >= 8) {
     sf->adaptive_rd_thresh = 4;
-    // Enable partition copy
-    if (!cpi->last_frame_dropped && !cpi->use_svc && !cpi->resize_pending &&
-        cpi->resize_state == ORIG && !cpi->external_resize &&
-        cpi->oxcf.resize_mode == RESIZE_NONE) {
+    // Enable partition copy. For SVC, only enabled for top resolution layer,
+    if (!cpi->last_frame_dropped && cpi->resize_state == ORIG &&
+        !cpi->external_resize &&
+        (!cpi->use_svc ||
+         cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) {
       sf->copy_partition_flag = 1;
       cpi->max_copied_frame = 4;
     }