]> granicus.if.org Git - libvpx/commitdiff
Merge "Use source frame difference to make partition decision"
authorYunqing Wang <yunqingwang@google.com>
Wed, 9 Apr 2014 17:26:42 +0000 (10:26 -0700)
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>
Wed, 9 Apr 2014 17:26:42 +0000 (10:26 -0700)
1  2 
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_speed_features.c
vp9/encoder/vp9_speed_features.h

index fcea638cf60af01cd443d3a4603950d5c51d2419,e1ddc7f2fd78139ab7775b1f1160cdbfb97831a2..a0605a41349d82c6f443150cbcfc0b8fdd73f4a1
@@@ -1446,8 -1392,128 +1446,128 @@@ static void copy_partitioning(VP9_COMMO
    }
  }
  
+ const struct {
+   int row;
+   int col;
+ } coord_lookup[16] = {
+     // 32x32 index = 0
+     {0, 0}, {0, 2}, {2, 0}, {2, 2},
+     // 32x32 index = 1
+     {0, 4}, {0, 6}, {2, 4}, {2, 6},
+     // 32x32 index = 2
+     {4, 0}, {4, 2}, {6, 0}, {6, 2},
+     // 32x32 index = 3
+     {4, 4}, {4, 6}, {6, 4}, {6, 6},
+ };
+ static void set_source_var_based_partition(VP9_COMP *cpi,
+                                            const TileInfo *const tile,
+                                            MODE_INFO **mi_8x8,
+                                            int mi_row, int mi_col) {
+   VP9_COMMON *const cm = &cpi->common;
+   MACROBLOCK *x = &cpi->mb;
+   const int mis = cm->mode_info_stride;
+   int row8x8_remaining = tile->mi_row_end - mi_row;
+   int col8x8_remaining = tile->mi_col_end - mi_col;
+   int r, c;
+   MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
+   assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
+   // In-image SB64
+   if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
+       (row8x8_remaining >= MI_BLOCK_SIZE)) {
+     const int src_stride = x->plane[0].src.stride;
+     const int pre_stride = cpi->Last_Source->y_stride;
+     const uint8_t *src = x->plane[0].src.buf;
+     const int pre_offset = (mi_row * MI_SIZE) * pre_stride +
+                            (mi_col * MI_SIZE);
+     const uint8_t *pre_src = cpi->Last_Source->y_buffer + pre_offset;
+     const int thr_32x32 = cpi->sf.source_var_thresh;
+     const int thr_64x64 = thr_32x32 << 1;
+     int i, j;
+     int index;
+     diff d32[4];
+     int use16x16 = 0;
+     for (i = 0; i < 4; i++) {
+       diff d16[4];
+       for (j = 0; j < 4; j++) {
+         int b_mi_row = coord_lookup[i * 4 + j].row;
+         int b_mi_col = coord_lookup[i * 4 + j].col;
+         int b_offset = b_mi_row * MI_SIZE * src_stride +
+                        b_mi_col * MI_SIZE;
+         vp9_get_sse_sum_16x16(src + b_offset,
+                               src_stride,
+                               pre_src + b_offset,
+                               pre_stride, &d16[j].sse, &d16[j].sum);
+         d16[j].var = d16[j].sse -
+             (((uint32_t)d16[j].sum * d16[j].sum) >> 8);
+         index = b_mi_row * mis + b_mi_col;
+         mi_8x8[index] = mi_upper_left + index;
+         mi_8x8[index]->mbmi.sb_type = BLOCK_16X16;
+         // TODO(yunqingwang): If d16[j].var is very large, use 8x8 partition
+         // size to further improve quality.
+       }
+       if (d16[0].var < thr_32x32 && d16[1].var < thr_32x32 &&
+           d16[2].var < thr_32x32 && d16[3].var < thr_32x32) {
+         d32[i].sse = d16[0].sse;
+         d32[i].sum = d16[0].sum;
+         for (j = 1; j < 4; j++) {
+           d32[i].sse += d16[j].sse;
+           d32[i].sum += d16[j].sum;
+         }
+         d32[i].var = d32[i].sse - (((int64_t)d32[i].sum * d32[i].sum) >> 10);
+         index = coord_lookup[i*4].row * mis + coord_lookup[i*4].col;
+         mi_8x8[index] = mi_upper_left + index;
+         mi_8x8[index]->mbmi.sb_type = BLOCK_32X32;
+         if (!((cm->current_video_frame - 1) %
+             cpi->sf.search_type_check_frequency))
+           cpi->use_large_partition_rate += 1;
+       } else {
+         use16x16 = 1;
+       }
+     }
+     if (!use16x16) {
+       if (d32[0].var < thr_64x64 && d32[1].var < thr_64x64 &&
+           d32[2].var < thr_64x64 && d32[3].var < thr_64x64)  {
+         mi_8x8[0] = mi_upper_left;
+         mi_8x8[0]->mbmi.sb_type = BLOCK_64X64;
+       }
+     }
+   } else {   // partial in-image SB64
+     BLOCK_SIZE bsize = BLOCK_16X16;
+     int bh = num_8x8_blocks_high_lookup[bsize];
+     int bw = num_8x8_blocks_wide_lookup[bsize];
+     for (r = 0; r < MI_BLOCK_SIZE; r += bh) {
+       for (c = 0; c < MI_BLOCK_SIZE; c += bw) {
+         int index = r * mis + c;
+         // Find a partition size that fits
+         bsize = find_partition_size(bsize,
+                                     (row8x8_remaining - r),
+                                     (col8x8_remaining - c), &bh, &bw);
+         mi_8x8[index] = mi_upper_left + index;
+         mi_8x8[index]->mbmi.sb_type = bsize;
+       }
+     }
+   }
+ }
  static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
 -  const int mis = cm->mode_info_stride;
 +  const int mis = cm->mi_stride;
    int block_row, block_col;
  
    if (cm->prev_mi) {
@@@ -3066,13 -3155,10 +3186,10 @@@ static void encode_nonrd_sb_row(VP9_COM
         mi_col += MI_BLOCK_SIZE) {
      int dummy_rate = 0;
      int64_t dummy_dist = 0;
 -    const int idx_str = cm->mode_info_stride * mi_row + mi_col;
 +    const int idx_str = cm->mi_stride * mi_row + mi_col;
      MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
      MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
-     BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ?
-         cpi->sf.always_this_block_size :
-         get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
+     BLOCK_SIZE bsize;
  
      cpi->mb.source_variance = UINT_MAX;
      vp9_zero(cpi->mb.pred_mv);
Simple merge
index c72b62bc5aa57d6ec0da1ac11719bf478b5d8162,9171612798d630971b4ac70b91aed1520928c0ed..d6b6174fa6ffa3d6927fc4be94e1113f3ab6ce62
@@@ -263,9 -256,12 +263,13 @@@ static void set_rt_speed_feature(VP9_CO
      sf->search_method = FAST_DIAMOND;
      sf->allow_skip_recode = 0;
    }
 +
    if (speed >= 6) {
-     sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
+     // Adaptively switch between SOURCE_VAR_BASED_PARTITION and FIXED_PARTITION.
+     sf->partition_search_type = SOURCE_VAR_BASED_PARTITION;
+     sf->search_type_check_frequency = 50;
+     sf->source_var_thresh = 360;
      sf->use_nonrd_pick_mode = 1;
      sf->search_method = FAST_DIAMOND;
    }
@@@ -338,11 -329,10 +342,13 @@@ void vp9_set_speed_features(VP9_COMP *c
    // This setting only takes effect when partition_search_type is set
    // to FIXED_PARTITION.
    sf->always_this_block_size = BLOCK_16X16;
+   sf->search_type_check_frequency = 50;
+   sf->source_var_thresh = 100;
  
 -  switch (cpi->oxcf.mode) {
 +  // Recode loop tolerence %.
 +  sf->recode_tolerance = 25;
 +
 +  switch (oxcf->mode) {
      case MODE_BESTQUALITY:
      case MODE_SECONDPASS_BEST:  // This is the best quality mode.
        cpi->diamond_search_sad = vp9_full_range_search;
index aaeb079cf9316f937569a9151c9c2991e1389331,fccab53e82bc6f8235f3e40439304152a76d8ada..72f548a04a828304449b0d073654a1728020185c
@@@ -110,22 -110,12 +110,25 @@@ typedef enum 
  
    // Use an arbitrary partitioning scheme based on source variance within
    // a 64X64 SB
-   VAR_BASED_PARTITION
+   VAR_BASED_PARTITION,
+   // Use non-fixed partitions based on source variance
+   SOURCE_VAR_BASED_PARTITION
  } PARTITION_SEARCH_TYPE;
  
 +typedef enum {
 +  // Does a dry run to see if any of the contexts need to be updated or not,
 +  // before the final run.
 +  TWO_LOOP = 0,
 +
 +  // No dry run conducted.
 +  ONE_LOOP = 1,
 +
 +  // No dry run, also only half the coef contexts and bands are updated.
 +  // The rest are not updated at all.
 +  ONE_LOOP_REDUCED = 2
 +} FAST_COEFF_UPDATE;
 +
  typedef struct {
    // Frame level coding parameter update
    int frame_parameter_update;