vp9_encodeframe.c 159 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9
10
 */

Dmitry Kovalev's avatar
Dmitry Kovalev committed
11
12
13
14
#include <limits.h>
#include <math.h>
#include <stdio.h>

Jim Bankoski's avatar
Jim Bankoski committed
15
#include "./vp9_rtcd.h"
Johann's avatar
Johann committed
16
#include "./vpx_dsp_rtcd.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
17
18
#include "./vpx_config.h"

19
#include "vpx_dsp/vpx_dsp_common.h"
20
#include "vpx_ports/mem.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
21
#include "vpx_ports/vpx_timer.h"
22
#include "vpx_ports/system_state.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
23

24
#include "vp9/common/vp9_common.h"
Yaowu Xu's avatar
Yaowu Xu committed
25
#include "vp9/common/vp9_entropy.h"
26
#include "vp9/common/vp9_entropymode.h"
27
#include "vp9/common/vp9_idct.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
28
29
30
#include "vp9/common/vp9_mvref_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
31
#include "vp9/common/vp9_reconintra.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
32
#include "vp9/common/vp9_reconinter.h"
33
#include "vp9/common/vp9_seg_common.h"
34
#include "vp9/common/vp9_tile_common.h"
35

36
#include "vp9/encoder/vp9_aq_360.h"
37
#include "vp9/encoder/vp9_aq_complexity.h"
Marco Paniconi's avatar
Marco Paniconi committed
38
39
#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
#include "vp9/encoder/vp9_aq_variance.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
40
41
42
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
43
#include "vp9/encoder/vp9_ethread.h"
44
#include "vp9/encoder/vp9_extend.h"
45
#include "vp9/encoder/vp9_pickmode.h"
46
#include "vp9/encoder/vp9_rd.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
47
48
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_segmentation.h"
49
#include "vp9/encoder/vp9_tokenize.h"
50

51
52
static void encode_superblock(VP9_COMP *cpi, ThreadData * td,
                              TOKENEXTRA **t, int output_enabled,
53
54
                              int mi_row, int mi_col, BLOCK_SIZE bsize,
                              PICK_MODE_CONTEXT *ctx);
55

56
57
58
59
// This is used as a reference when computing the source variance for the
//  purposes of activity masking.
// Eventually this should be replaced by custom no-reference routines,
//  which will be faster.
60
static const uint8_t VP9_VAR_OFFS[64] = {
61
62
63
64
65
66
67
68
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128
69
70
};

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#if CONFIG_VP9_HIGHBITDEPTH
static const uint16_t VP9_HIGH_VAR_OFFS_8[64] = {
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128,
    128, 128, 128, 128, 128, 128, 128, 128
};

static const uint16_t VP9_HIGH_VAR_OFFS_10[64] = {
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
    128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4
};

static const uint16_t VP9_HIGH_VAR_OFFS_12[64] = {
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
    128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16
};
#endif  // CONFIG_VP9_HIGHBITDEPTH

106
107
108
unsigned int vp9_get_sby_perpixel_variance(VP9_COMP *cpi,
                                           const struct buf_2d *ref,
                                           BLOCK_SIZE bs) {
109
110
111
  unsigned int sse;
  const unsigned int var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
                                              VP9_VAR_OFFS, 0, &sse);
112
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
113
114
}

115
#if CONFIG_VP9_HIGHBITDEPTH
116
unsigned int vp9_high_get_sby_perpixel_variance(
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    VP9_COMP *cpi, const struct buf_2d *ref, BLOCK_SIZE bs, int bd) {
  unsigned int var, sse;
  switch (bd) {
    case 10:
      var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
                               CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_10),
                               0, &sse);
      break;
    case 12:
      var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
                               CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_12),
                               0, &sse);
      break;
    case 8:
    default:
      var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
                               CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_8),
                               0, &sse);
      break;
  }
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}
#endif  // CONFIG_VP9_HIGHBITDEPTH

141
static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi,
142
143
                                                   const struct buf_2d *ref,
                                                   int mi_row, int mi_col,
144
                                                   BLOCK_SIZE bs) {
145
146
  unsigned int sse, var;
  uint8_t *last_y;
147
  const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
148
149
150
151
152

  assert(last != NULL);
  last_y =
      &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
  var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
153
154
155
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}

156
static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi, MACROBLOCK *x,
157
158
                                                   int mi_row,
                                                   int mi_col) {
159
  unsigned int var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src,
160
161
162
                                                    mi_row, mi_col,
                                                    BLOCK_64X64);
  if (var < 8)
163
    return BLOCK_64X64;
164
  else if (var < 128)
165
    return BLOCK_32X32;
166
167
168
169
  else if (var < 2048)
    return BLOCK_16X16;
  else
    return BLOCK_8X8;
170
171
}

172
173
// Lighter version of set_offsets that only sets the mode info
// pointers.
Jingning Han's avatar
Jingning Han committed
174
static INLINE void set_mode_info_offsets(VP9_COMMON *const cm,
175
                                         MACROBLOCK *const x,
Jingning Han's avatar
Jingning Han committed
176
177
178
                                         MACROBLOCKD *const xd,
                                         int mi_row,
                                         int mi_col) {
179
  const int idx_str = xd->mi_stride * mi_row + mi_col;
180
181
  xd->mi = cm->mi_grid_visible + idx_str;
  xd->mi[0] = cm->mi + idx_str;
182
  x->mbmi_ext = x->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
183
184
185
}

static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
186
187
                        MACROBLOCK *const x, int mi_row, int mi_col,
                        BLOCK_SIZE bsize) {
188
189
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;
Scott LaVarnway's avatar
Scott LaVarnway committed
190
  MODE_INFO *mi;
191
192
193
194
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
  const struct segmentation *const seg = &cm->seg;

195
  set_skip_context(xd, mi_row, mi_col);
196

197
198
  set_mode_info_offsets(cm, x, xd, mi_row, mi_col);

Scott LaVarnway's avatar
Scott LaVarnway committed
199
  mi = xd->mi[0];
200
201

  // Set up destination pointers.
202
  vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

  // Set up limit values for MV components.
  // Mv beyond the range do not produce new/different prediction block.
  x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
  x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
  x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
  x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;

  // Set up distance of MB to edge of frame in 1/8th pel units.
  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
                 cm->mi_rows, cm->mi_cols);

  // Set up source buffers.
  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);

  // R/D setup.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
220
221
  x->rddiv = cpi->rd.RDDIV;
  x->rdmult = cpi->rd.RDMULT;
222
223
224

  // Setup segment ID.
  if (seg->enabled) {
225
226
    if (cpi->oxcf.aq_mode != VARIANCE_AQ &&
        cpi->oxcf.aq_mode != EQUATOR360_AQ) {
227
228
      const uint8_t *const map = seg->update_map ? cpi->segmentation_map
                                                 : cm->last_frame_seg_map;
Scott LaVarnway's avatar
Scott LaVarnway committed
229
      mi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
230
231
232
    }
    vp9_init_plane_quantizers(cpi, x);

Scott LaVarnway's avatar
Scott LaVarnway committed
233
    x->encode_breakout = cpi->segment_encode_breakout[mi->segment_id];
234
  } else {
Scott LaVarnway's avatar
Scott LaVarnway committed
235
    mi->segment_id = 0;
236
237
    x->encode_breakout = cpi->encode_breakout;
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
238
239
240

  // required by vp9_append_sub8x8_mvs_for_idx() and vp9_find_best_ref_mvs()
  xd->tile = *tile;
241
242
}

243
244
245
static void duplicate_mode_info_in_sb(VP9_COMMON *cm, MACROBLOCKD *xd,
                                      int mi_row, int mi_col,
                                      BLOCK_SIZE bsize) {
246
247
248
249
250
251
  const int block_width = num_8x8_blocks_wide_lookup[bsize];
  const int block_height = num_8x8_blocks_high_lookup[bsize];
  int i, j;
  for (j = 0; j < block_height; ++j)
    for (i = 0; i < block_width; ++i) {
      if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols)
252
        xd->mi[j * xd->mi_stride + i] = xd->mi[0];
253
254
255
256
    }
}

static void set_block_size(VP9_COMP * const cpi,
257
                           MACROBLOCK *const x,
258
                           MACROBLOCKD *const xd,
259
260
261
                           int mi_row, int mi_col,
                           BLOCK_SIZE bsize) {
  if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
262
    set_mode_info_offsets(&cpi->common, x, xd, mi_row, mi_col);
Scott LaVarnway's avatar
Scott LaVarnway committed
263
    xd->mi[0]->sb_type = bsize;
264
265
266
267
268
269
  }
}

typedef struct {
  int64_t sum_square_error;
  int64_t sum_error;
270
  int log2_count;
271
272
273
274
275
276
277
278
279
280
281
282
  int variance;
} var;

typedef struct {
  var none;
  var horz[2];
  var vert[2];
} partition_variance;

typedef struct {
  partition_variance part_variances;
  var split[4];
283
284
285
286
287
} v4x4;

typedef struct {
  partition_variance part_variances;
  v4x4 split[4];
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
} v8x8;

typedef struct {
  partition_variance part_variances;
  v8x8 split[4];
} v16x16;

typedef struct {
  partition_variance part_variances;
  v16x16 split[4];
} v32x32;

typedef struct {
  partition_variance part_variances;
  v32x32 split[4];
} v64x64;

typedef struct {
  partition_variance *part_variances;
  var *split[4];
} variance_node;

typedef enum {
  V16X16,
  V32X32,
  V64X64,
} TREE_LEVEL;

static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
  int i;
318
  node->part_variances = NULL;
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  switch (bsize) {
    case BLOCK_64X64: {
      v64x64 *vt = (v64x64 *) data;
      node->part_variances = &vt->part_variances;
      for (i = 0; i < 4; i++)
        node->split[i] = &vt->split[i].part_variances.none;
      break;
    }
    case BLOCK_32X32: {
      v32x32 *vt = (v32x32 *) data;
      node->part_variances = &vt->part_variances;
      for (i = 0; i < 4; i++)
        node->split[i] = &vt->split[i].part_variances.none;
      break;
    }
    case BLOCK_16X16: {
      v16x16 *vt = (v16x16 *) data;
      node->part_variances = &vt->part_variances;
      for (i = 0; i < 4; i++)
        node->split[i] = &vt->split[i].part_variances.none;
      break;
    }
    case BLOCK_8X8: {
      v8x8 *vt = (v8x8 *) data;
      node->part_variances = &vt->part_variances;
344
345
346
347
348
349
350
      for (i = 0; i < 4; i++)
        node->split[i] = &vt->split[i].part_variances.none;
      break;
    }
    case BLOCK_4X4: {
      v4x4 *vt = (v4x4 *) data;
      node->part_variances = &vt->part_variances;
351
352
353
354
355
356
      for (i = 0; i < 4; i++)
        node->split[i] = &vt->split[i];
      break;
    }
    default: {
      assert(0);
357
      break;
358
359
360
361
362
363
364
365
    }
  }
}

// Set variance values given sum square error, sum error, count.
static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
  v->sum_square_error = s2;
  v->sum_error = s;
366
  v->log2_count = c;
367
368
369
}

static void get_variance(var *v) {
370
371
  v->variance = (int)(256 * (v->sum_square_error -
      ((v->sum_error * v->sum_error) >> v->log2_count)) >> v->log2_count);
372
373
}

374
static void sum_2_variances(const var *a, const var *b, var *r) {
375
  assert(a->log2_count == b->log2_count);
376
  fill_variance(a->sum_square_error + b->sum_square_error,
377
                a->sum_error + b->sum_error, a->log2_count + 1, r);
378
379
380
381
}

static void fill_variance_tree(void *data, BLOCK_SIZE bsize) {
  variance_node node;
382
  memset(&node, 0, sizeof(node));
383
384
385
386
387
388
389
390
391
392
  tree_to_node(data, bsize, &node);
  sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]);
  sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]);
  sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]);
  sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]);
  sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1],
                  &node.part_variances->none);
}

static int set_vt_partitioning(VP9_COMP *cpi,
393
                               MACROBLOCK *const x,
394
                               MACROBLOCKD *const xd,
395
396
397
                               void *data,
                               BLOCK_SIZE bsize,
                               int mi_row,
398
                               int mi_col,
399
                               int64_t threshold,
400
                               BLOCK_SIZE bsize_min,
Marco's avatar
Marco committed
401
                               int force_split) {
402
403
404
405
  VP9_COMMON * const cm = &cpi->common;
  variance_node vt;
  const int block_width = num_8x8_blocks_wide_lookup[bsize];
  const int block_height = num_8x8_blocks_high_lookup[bsize];
406

407
408
409
  assert(block_height == block_width);
  tree_to_node(data, bsize, &vt);

410
  if (force_split == 1)
411
412
    return 0;

413
  // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
414
415
  // variance is below threshold, otherwise split will be selected.
  // No check for vert/horiz split as too few samples for variance.
416
  if (bsize == bsize_min) {
417
    // Variance already computed to set the force_split.
418
    if (cm->frame_type == KEY_FRAME)
419
      get_variance(&vt.part_variances->none);
420
421
    if (mi_col + block_width / 2 < cm->mi_cols &&
        mi_row + block_height / 2 < cm->mi_rows &&
422
        vt.part_variances->none.variance < threshold) {
423
      set_block_size(cpi, x, xd, mi_row, mi_col, bsize);
424
425
426
      return 1;
    }
    return 0;
427
  } else if (bsize > bsize_min) {
428
    // Variance already computed to set the force_split.
429
    if (cm->frame_type == KEY_FRAME)
Marco's avatar
Marco committed
430
      get_variance(&vt.part_variances->none);
431
    // For key frame: take split for bsize above 32X32 or very high variance.
432
433
    if (cm->frame_type == KEY_FRAME &&
        (bsize > BLOCK_32X32 ||
434
        vt.part_variances->none.variance > (threshold << 4))) {
435
436
437
438
439
      return 0;
    }
    // If variance is low, take the bsize (no split).
    if (mi_col + block_width / 2 < cm->mi_cols &&
        mi_row + block_height / 2 < cm->mi_rows &&
440
        vt.part_variances->none.variance < threshold) {
441
      set_block_size(cpi, x, xd, mi_row, mi_col, bsize);
442
443
      return 1;
    }
444

445
    // Check vertical split.
446
    if (mi_row + block_height / 2 < cm->mi_rows) {
Yaowu Xu's avatar
Yaowu Xu committed
447
      BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
448
449
      get_variance(&vt.part_variances->vert[0]);
      get_variance(&vt.part_variances->vert[1]);
450
      if (vt.part_variances->vert[0].variance < threshold &&
Yaowu Xu's avatar
Yaowu Xu committed
451
452
          vt.part_variances->vert[1].variance < threshold &&
          get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
453
454
        set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
        set_block_size(cpi, x, xd, mi_row, mi_col + block_width / 2, subsize);
455
456
        return 1;
      }
457
    }
458
    // Check horizontal split.
459
    if (mi_col + block_width / 2 < cm->mi_cols) {
Yaowu Xu's avatar
Yaowu Xu committed
460
      BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
461
462
      get_variance(&vt.part_variances->horz[0]);
      get_variance(&vt.part_variances->horz[1]);
463
      if (vt.part_variances->horz[0].variance < threshold &&
Yaowu Xu's avatar
Yaowu Xu committed
464
465
          vt.part_variances->horz[1].variance < threshold &&
          get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
466
467
        set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
        set_block_size(cpi, x, xd, mi_row + block_height / 2, mi_col, subsize);
468
469
        return 1;
      }
470
    }
471

472
    return 0;
473
474
475
476
  }
  return 0;
}

Marco's avatar
Marco committed
477
478
479
480
481
482
483
484
// Set the variance split thresholds for following the block sizes:
// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
// currently only used on key frame.
static void set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q) {
  VP9_COMMON *const cm = &cpi->common;
  const int is_key_frame = (cm->frame_type == KEY_FRAME);
  const int threshold_multiplier = is_key_frame ? 20 : 1;
Marco's avatar
Marco committed
485
  int64_t threshold_base = (int64_t)(threshold_multiplier *
Marco's avatar
Marco committed
486
487
488
489
490
491
492
      cpi->y_dequant[q][1]);
  if (is_key_frame) {
    thresholds[0] = threshold_base;
    thresholds[1] = threshold_base >> 2;
    thresholds[2] = threshold_base >> 2;
    thresholds[3] = threshold_base << 2;
  } else {
493
    // Increase base variance threshold based on  estimated noise level.
494
    if (cpi->noise_estimate.enabled) {
495
496
497
      NOISE_LEVEL noise_level = vp9_noise_estimate_extract_level(
          &cpi->noise_estimate);
      if (noise_level == kHigh)
498
        threshold_base = 3 * threshold_base;
499
500
      else if (noise_level == kMedium)
        threshold_base = threshold_base << 1;
501
      else if (noise_level < kLow)
502
        threshold_base = (7 * threshold_base) >> 3;
503
    }
Marco's avatar
Marco committed
504
    if (cm->width <= 352 && cm->height <= 288) {
505
506
      thresholds[0] = threshold_base >> 3;
      thresholds[1] = threshold_base >> 1;
507
      thresholds[2] = threshold_base << 3;
Marco's avatar
Marco committed
508
509
510
    } else {
      thresholds[0] = threshold_base;
      thresholds[1] = (5 * threshold_base) >> 2;
511
512
      if (cm->width >= 1920 && cm->height >= 1080)
        thresholds[1] = (7 * threshold_base) >> 2;
Marco's avatar
Marco committed
513
514
515
516
517
518
519
      thresholds[2] = threshold_base << cpi->oxcf.speed;
    }
  }
}

void vp9_set_variance_partition_thresholds(VP9_COMP *cpi, int q) {
  VP9_COMMON *const cm = &cpi->common;
Yaowu Xu's avatar
Yaowu Xu committed
520
  SPEED_FEATURES *const sf = &cpi->sf;
Marco's avatar
Marco committed
521
  const int is_key_frame = (cm->frame_type == KEY_FRAME);
522
523
  if (sf->partition_search_type != VAR_BASED_PARTITION &&
      sf->partition_search_type != REFERENCE_PARTITION) {
Yaowu Xu's avatar
Yaowu Xu committed
524
525
    return;
  } else {
Marco's avatar
Marco committed
526
527
    set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
    // The thresholds below are not changed locally.
528
    if (is_key_frame) {
529
      cpi->vbp_threshold_sad = 0;
530
531
      cpi->vbp_bsize_min = BLOCK_8X8;
    } else {
Marco's avatar
Marco committed
532
      if (cm->width <= 352 && cm->height <= 288)
533
        cpi->vbp_threshold_sad = 10;
Marco's avatar
Marco committed
534
      else
535
536
        cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000 ?
            (cpi->y_dequant[q][1] << 1) : 1000;
537
538
      cpi->vbp_bsize_min = BLOCK_16X16;
    }
539
    cpi->vbp_threshold_minmax = 15 + (q >> 3);
Yaowu Xu's avatar
Yaowu Xu committed
540
541
542
  }
}

543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
// Compute the minmax over the 8x8 subblocks.
static int compute_minmax_8x8(const uint8_t *s, int sp, const uint8_t *d,
                              int dp, int x16_idx, int y16_idx,
#if CONFIG_VP9_HIGHBITDEPTH
                              int highbd_flag,
#endif
                              int pixels_wide,
                              int pixels_high) {
  int k;
  int minmax_max = 0;
  int minmax_min = 255;
  // Loop over the 4 8x8 subblocks.
  for (k = 0; k < 4; k++) {
    int x8_idx = x16_idx + ((k & 1) << 3);
    int y8_idx = y16_idx + ((k >> 1) << 3);
    int min = 0;
    int max = 0;
    if (x8_idx < pixels_wide && y8_idx < pixels_high) {
#if CONFIG_VP9_HIGHBITDEPTH
      if (highbd_flag & YV12_FLAG_HIGHBITDEPTH) {
James Zern's avatar
James Zern committed
563
        vpx_highbd_minmax_8x8(s + y8_idx * sp + x8_idx, sp,
564
565
566
                              d + y8_idx * dp + x8_idx, dp,
                              &min, &max);
      } else {
James Zern's avatar
James Zern committed
567
        vpx_minmax_8x8(s + y8_idx * sp + x8_idx, sp,
568
569
570
571
                       d + y8_idx * dp + x8_idx, dp,
                       &min, &max);
      }
#else
James Zern's avatar
James Zern committed
572
      vpx_minmax_8x8(s + y8_idx * sp + x8_idx, sp,
573
574
575
576
577
578
579
580
581
582
583
584
                     d + y8_idx * dp + x8_idx, dp,
                     &min, &max);
#endif
      if ((max - min) > minmax_max)
        minmax_max = (max - min);
      if ((max - min) < minmax_min)
        minmax_min = (max - min);
    }
  }
  return (minmax_max - minmax_min);
}

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
static void fill_variance_4x4avg(const uint8_t *s, int sp, const uint8_t *d,
                                 int dp, int x8_idx, int y8_idx, v8x8 *vst,
#if CONFIG_VP9_HIGHBITDEPTH
                                 int highbd_flag,
#endif
                                 int pixels_wide,
                                 int pixels_high,
                                 int is_key_frame) {
  int k;
  for (k = 0; k < 4; k++) {
    int x4_idx = x8_idx + ((k & 1) << 2);
    int y4_idx = y8_idx + ((k >> 1) << 2);
    unsigned int sse = 0;
    int sum = 0;
    if (x4_idx < pixels_wide && y4_idx < pixels_high) {
      int s_avg;
      int d_avg = 128;
#if CONFIG_VP9_HIGHBITDEPTH
      if (highbd_flag & YV12_FLAG_HIGHBITDEPTH) {
James Zern's avatar
James Zern committed
604
        s_avg = vpx_highbd_avg_4x4(s + y4_idx * sp + x4_idx, sp);
605
        if (!is_key_frame)
James Zern's avatar
James Zern committed
606
          d_avg = vpx_highbd_avg_4x4(d + y4_idx * dp + x4_idx, dp);
607
      } else {
James Zern's avatar
James Zern committed
608
        s_avg = vpx_avg_4x4(s + y4_idx * sp + x4_idx, sp);
609
        if (!is_key_frame)
James Zern's avatar
James Zern committed
610
          d_avg = vpx_avg_4x4(d + y4_idx * dp + x4_idx, dp);
611
612
      }
#else
James Zern's avatar
James Zern committed
613
      s_avg = vpx_avg_4x4(s + y4_idx * sp + x4_idx, sp);
614
      if (!is_key_frame)
James Zern's avatar
James Zern committed
615
        d_avg = vpx_avg_4x4(d + y4_idx * dp + x4_idx, dp);
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
#endif
      sum = s_avg - d_avg;
      sse = sum * sum;
    }
    fill_variance(sse, sum, 0, &vst->split[k].part_variances.none);
  }
}

static void fill_variance_8x8avg(const uint8_t *s, int sp, const uint8_t *d,
                                 int dp, int x16_idx, int y16_idx, v16x16 *vst,
#if CONFIG_VP9_HIGHBITDEPTH
                                 int highbd_flag,
#endif
                                 int pixels_wide,
                                 int pixels_high,
                                 int is_key_frame) {
  int k;
  for (k = 0; k < 4; k++) {
    int x8_idx = x16_idx + ((k & 1) << 3);
    int y8_idx = y16_idx + ((k >> 1) << 3);
    unsigned int sse = 0;
    int sum = 0;
    if (x8_idx < pixels_wide && y8_idx < pixels_high) {
      int s_avg;
      int d_avg = 128;
#if CONFIG_VP9_HIGHBITDEPTH
      if (highbd_flag & YV12_FLAG_HIGHBITDEPTH) {
James Zern's avatar
James Zern committed
643
        s_avg = vpx_highbd_avg_8x8(s + y8_idx * sp + x8_idx, sp);
644
        if (!is_key_frame)
James Zern's avatar
James Zern committed
645
          d_avg = vpx_highbd_avg_8x8(d + y8_idx * dp + x8_idx, dp);
646
      } else {
James Zern's avatar
James Zern committed
647
        s_avg = vpx_avg_8x8(s + y8_idx * sp + x8_idx, sp);
648
        if (!is_key_frame)
James Zern's avatar
James Zern committed
649
          d_avg = vpx_avg_8x8(d + y8_idx * dp + x8_idx, dp);
650
651
      }
#else
James Zern's avatar
James Zern committed
652
      s_avg = vpx_avg_8x8(s + y8_idx * sp + x8_idx, sp);
653
      if (!is_key_frame)
James Zern's avatar
James Zern committed
654
        d_avg = vpx_avg_8x8(d + y8_idx * dp + x8_idx, dp);
655
656
657
658
659
660
661
662
#endif
      sum = s_avg - d_avg;
      sse = sum * sum;
    }
    fill_variance(sse, sum, 0, &vst->split[k].part_variances.none);
  }
}

663
// This function chooses partitioning based on the variance between source and
664
// reconstructed last, where variance is computed for down-sampled inputs.
665
static int choose_partitioning(VP9_COMP *cpi,
666
                                const TileInfo *const tile,
667
                                MACROBLOCK *x,
668
669
                                int mi_row, int mi_col) {
  VP9_COMMON * const cm = &cpi->common;
670
  MACROBLOCKD *xd = &x->e_mbd;
671
  int i, j, k, m;
672
  v64x64 vt;
673
  v16x16 vt2[16];
674
  int force_split[21];
675
676
  int avg_32x32;
  int avg_16x16[4];
677
678
679
680
681
  uint8_t *s;
  const uint8_t *d;
  int sp;
  int dp;
  int pixels_wide = 64, pixels_high = 64;
682
683
  int64_t thresholds[4] = {cpi->vbp_thresholds[0], cpi->vbp_thresholds[1],
      cpi->vbp_thresholds[2], cpi->vbp_thresholds[3]};
Yaowu Xu's avatar
Yaowu Xu committed
684

685
686
687
688
689
  // For the variance computation under SVC mode, we treat the frame as key if
  // the reference (base layer frame) is key frame (i.e., is_key_frame == 1).
  const int is_key_frame = (cm->frame_type == KEY_FRAME ||
      (is_one_pass_cbr_svc(cpi) &&
      cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame));
690
  // Always use 4x4 partition for key frame.
691
  const int use_4x4_partition = cm->frame_type == KEY_FRAME;
Yaowu Xu's avatar
Yaowu Xu committed
692
  const int low_res = (cm->width <= 352 && cm->height <= 288);
693
694
  int variance4x4downsample[16];

695
696
697
698
  int segment_id = CR_SEGMENT_ID_BASE;
  if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
    const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map :
                                                    cm->last_frame_seg_map;
699
    segment_id = get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
700
701
702

    if (cyclic_refresh_segment_id_boosted(segment_id)) {
      int q = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Marco's avatar
Marco committed
703
      set_vbp_thresholds(cpi, thresholds, q);
704
    }
705
706
  }

707
  set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
708
709
710
711
712
713
714
715
716

  if (xd->mb_to_right_edge < 0)
    pixels_wide += (xd->mb_to_right_edge >> 3);
  if (xd->mb_to_bottom_edge < 0)
    pixels_high += (xd->mb_to_bottom_edge >> 3);

  s = x->plane[0].src.buf;
  sp = x->plane[0].src.stride;

717
718
719
720
  // Index for force_split: 0 for 64x64, 1-4 for 32x32 blocks,
  // 5-20 for the 16x16 blocks.
  force_split[0] = 0;

721
  if (!is_key_frame) {
722
723
724
    // In the case of spatial/temporal scalable coding, the assumption here is
    // that the temporal reference frame will always be of type LAST_FRAME.
    // TODO(marpan): If that assumption is broken, we need to revisit this code.
Scott LaVarnway's avatar
Scott LaVarnway committed
725
    MODE_INFO *mi = xd->mi[0];
726
    unsigned int uv_sad;
727
    const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
728

729
    const YV12_BUFFER_CONFIG *yv12_g = NULL;
730
    unsigned int y_sad, y_sad_g;
Yaowu Xu's avatar
Yaowu Xu committed
731
732
    const BLOCK_SIZE bsize = BLOCK_32X32
        + (mi_col + 4 < cm->mi_cols) * 2 + (mi_row + 4 < cm->mi_rows);
733

734
    assert(yv12 != NULL);
735
736
737
738
739
740
741

    if (!(is_one_pass_cbr_svc(cpi) && cpi->svc.spatial_layer_id)) {
      // For now, GOLDEN will not be used for non-zero spatial layers, since
      // it may not be a temporal reference.
      yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
    }

742
743
    if (yv12_g && yv12_g != yv12 &&
       (cpi->ref_frame_flags & VP9_GOLD_FLAG)) {
744
745
746
747
748
749
750
751
752
      vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
                           &cm->frame_refs[GOLDEN_FRAME - 1].sf);
      y_sad_g = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf,
                                       x->plane[0].src.stride,
                                       xd->plane[0].pre[0].buf,
                                       xd->plane[0].pre[0].stride);
    } else {
      y_sad_g = UINT_MAX;
    }
753

Yaowu Xu's avatar
Yaowu Xu committed
754
    vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
755
                         &cm->frame_refs[LAST_FRAME - 1].sf);
Scott LaVarnway's avatar
Scott LaVarnway committed
756
757
758
759
760
    mi->ref_frame[0] = LAST_FRAME;
    mi->ref_frame[1] = NONE;
    mi->sb_type = BLOCK_64X64;
    mi->mv[0].as_int = 0;
    mi->interp_filter = BILINEAR;
761

762
    y_sad = vp9_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
763
764
765
    if (y_sad_g < y_sad) {
      vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
                           &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Scott LaVarnway's avatar
Scott LaVarnway committed
766
767
      mi->ref_frame[0] = GOLDEN_FRAME;
      mi->mv[0].as_int = 0;
768
769
      y_sad = y_sad_g;
    } else {
Scott LaVarnway's avatar
Scott LaVarnway committed
770
      x->pred_mv[LAST_FRAME] = mi->mv[0].as_mv;
771
    }
772

773
    vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_64X64);
774

775
776
777
778
779
    // Check if most of the superblock is skin content, and if so, force split
    // to 32x32. Avoid checking superblocks on/near boundary for high resoln
    // Note superblock may still pick 64X64 if y_sad is very small
    // (i.e., y_sad < cpi->vbp_threshold_sad) below. For now leave this as is.
    x->sb_is_skin = 0;
780
#if !CONFIG_VP9_HIGHBITDEPTH
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
    if (cpi->oxcf.content != VP9E_CONTENT_SCREEN && (low_res || (mi_col >= 8 &&
        mi_col + 8 < cm->mi_cols && mi_row >= 8 && mi_row + 8 < cm->mi_rows))) {
      int num_16x16_skin = 0;
      int num_16x16_nonskin = 0;
      uint8_t *ysignal = x->plane[0].src.buf;
      uint8_t *usignal = x->plane[1].src.buf;
      uint8_t *vsignal = x->plane[2].src.buf;
      int spuv = x->plane[1].src.stride;
      for (i = 0; i < 4; i++) {
        for (j = 0; j < 4; j++) {
          int is_skin = vp9_compute_skin_block(ysignal,
                                               usignal,
                                               vsignal,
                                               sp,
                                               spuv,
                                               BLOCK_16X16);
          num_16x16_skin += is_skin;
          num_16x16_nonskin += (1 - is_skin);
          if (num_16x16_nonskin > 3) {
            // Exit loop if at least 4 of the 16x16 blocks are not skin.
            i = 4;
            j = 4;
          }
          ysignal += 16;
          usignal += 8;
          vsignal += 8;
        }
        ysignal += (sp << 4) - 64;
        usignal += (spuv << 3) - 32;
        vsignal += (spuv << 3) - 32;
      }
      if (num_16x16_skin > 12) {
        x->sb_is_skin = 1;
        force_split[0] = 1;
      }
    }
817
#endif
818
819
820
    for (i = 1; i <= 2; ++i) {
      struct macroblock_plane  *p = &x->plane[i];
      struct macroblockd_plane *pd = &xd->plane[i];
Yaowu Xu's avatar
Yaowu Xu committed
821
      const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
822

Yaowu Xu's avatar
Yaowu Xu committed
823
      if (bs == BLOCK_INVALID)
824
        uv_sad = UINT_MAX;
Yaowu Xu's avatar
Yaowu Xu committed
825
826
827
      else
        uv_sad = cpi->fn_ptr[bs].sdf(p->src.buf, p->src.stride,
                                     pd->dst.buf, pd->dst.stride);
828

829
830
831
        // TODO(marpan): Investigate if we should lower this threshold if
        // superblock is detected as skin.
        x->color_sensitivity[i - 1] = uv_sad > (y_sad >> 2);
832
    }
833
834
835

    d = xd->plane[0].dst.buf;
    dp = xd->plane[0].dst.stride;
836
837
838
839
840
841
842
843
844

    // If the y_sad is very small, take 64x64 as partition and exit.
    // Don't check on boosted segment for now, as 64x64 is suppressed there.
    if (segment_id == CR_SEGMENT_ID_BASE &&
        y_sad < cpi->vbp_threshold_sad) {
      const int block_width = num_8x8_blocks_wide_lookup[BLOCK_64X64];
      const int block_height = num_8x8_blocks_high_lookup[BLOCK_64X64];
      if (mi_col + block_width / 2 < cm->mi_cols &&
          mi_row + block_height / 2 < cm->mi_rows) {
845
        set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_64X64);
846
847
848
        return 0;
      }
    }
849
850
851
  } else {
    d = VP9_VAR_OFFS;
    dp = 0;
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
#if CONFIG_VP9_HIGHBITDEPTH
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
      switch (xd->bd) {
        case 10:
          d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_10);
          break;
        case 12:
          d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_12);
          break;
        case 8:
        default:
          d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_8);
          break;
      }
    }
#endif  // CONFIG_VP9_HIGHBITDEPTH
868
869
  }

870
871
  // Fill in the entire tree of 8x8 (or 4x4 under some conditions) variances
  // for splits.
872
873
874
  for (i = 0; i < 4; i++) {
    const int x32_idx = ((i & 1) << 5);
    const int y32_idx = ((i >> 1) << 5);
875
    const int i2 = i << 2;
Marco's avatar
Marco committed
876
    force_split[i + 1] = 0;
877
    avg_16x16[i] = 0;
878
879
880
    for (j = 0; j < 4; j++) {
      const int x16_idx = x32_idx + ((j & 1) << 4);
      const int y16_idx = y32_idx + ((j >> 1) << 4);
881
      const int split_index = 5 + i2 + j;
882
      v16x16 *vst = &vt.split[i].split[j];
883
      force_split[split_index] = 0;
884
      variance4x4downsample[i2 + j] = 0;
885
      if (!is_key_frame) {
886
        fill_variance_8x8avg(s, sp, d, dp, x16_idx, y16_idx, vst,
887
#if CONFIG_VP9_HIGHBITDEPTH
888
                            xd->cur_buf->flags,
889
#endif
890
891
892
                            pixels_wide,
                            pixels_high,
                            is_key_frame);
893
        fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
894
        get_variance(&vt.split[i].split[j].part_variances.none);
895
        avg_16x16[i] += vt.split[i].split[j].part_variances.none.variance;
896
897
898
899
900
901
902
        if (vt.split[i].split[j].part_variances.none.variance >
            thresholds[2]) {
          // 16X16 variance is above threshold for split, so force split to 8x8
          // for this 16x16 block (this also forces splits for upper levels).
          force_split[split_index] = 1;
          force_split[i + 1] = 1;
          force_split[0] = 1;
903
904
        } else if (cpi->oxcf.speed < 8 &&
                   vt.split[i].split[j].part_variances.none.variance >
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
                   thresholds[1] &&
                   !cyclic_refresh_segment_id_boosted(segment_id)) {
          // We have some nominal amount of 16x16 variance (based on average),
          // compute the minmax over the 8x8 sub-blocks, and if above threshold,
          // force split to 8x8 block for this 16x16 block.
          int minmax = compute_minmax_8x8(s, sp, d, dp, x16_idx, y16_idx,
#if CONFIG_VP9_HIGHBITDEPTH
                                          xd->cur_buf->flags,
#endif
                                          pixels_wide, pixels_high);
          if (minmax > cpi->vbp_threshold_minmax) {
            force_split[split_index] = 1;
            force_split[i + 1] = 1;
            force_split[0] = 1;
          }
        }
921
      }
922
      if (is_key_frame || (low_res &&
923
          vt.split[i].split[j].part_variances.none.variance >
924
          (thresholds[1] << 1))) {
925
        force_split[split_index] = 0;
926
927
928
929
930
        // Go down to 4x4 down-sampling for variance.
        variance4x4downsample[i2 + j] = 1;
        for (k = 0; k < 4; k++) {
          int x8_idx = x16_idx + ((k & 1) << 3);
          int y8_idx = y16_idx + ((k >> 1) << 3);
931
          v8x8 *vst2 = is_key_frame ? &vst->split[k] :
932
              &vt2[i2 + j].split[k];
933
          fill_variance_4x4avg(s, sp, d, dp, x8_idx, y8_idx, vst2,
934
#if CONFIG_VP9_HIGHBITDEPTH
935
                               xd->cur_buf->flags,
936
#endif
937
938
939
                               pixels_wide,
                               pixels_high,
                               is_key_frame);
940
        }
941
942
943
944
      }
    }
  }
  // Fill the rest of the variance tree by summing split partition values.
945
  avg_32x32 = 0;
946
  for (i = 0; i < 4; i++) {
947
    const int i2 = i << 2;
948
    for (j = 0; j < 4; j++) {
949
      if (variance4x4downsample[i2 + j] == 1) {
950
        v16x16 *vtemp = (!is_key_frame) ? &vt2[i2 + j] :
951
            &vt.split[i].split[j];
Marco's avatar
Marco committed
952
        for (m = 0; m < 4; m++)
953
954
          fill_variance_tree(&vtemp->split[m], BLOCK_8X8);
        fill_variance_tree(vtemp, BLOCK_16X16);
955
956
957
958
959
960
961
962
        // If variance of this 16x16 block is above the threshold, force block
        // to split. This also forces a split on the upper levels.
        get_variance(&vtemp->part_variances.none);
        if (vtemp->part_variances.none.variance > thresholds[2]) {
          force_split[5 + i2 + j] = 1;
          force_split[i + 1] = 1;
          force_split[0] = 1;
        }
963
      }
964
965
    }
    fill_variance_tree(&vt.split[i], BLOCK_32X32);
966
967
968
969
    // If variance of this 32x32 block is above the threshold, or if its above
    // (some threshold of) the average variance over the sub-16x16 blocks, then
    // force this block to split. This also forces a split on the upper
    // (64x64) level.
970
971
    if (!force_split[i + 1]) {
      get_variance(&vt.split[i].part_variances.none);
972
973
      if (vt.split[i].part_variances.none.variance > thresholds[1] ||
          (!is_key_frame &&
974
975
          vt.split[i].part_variances.none.variance > (thresholds[1] >> 1) &&
          vt.split[i].part_variances.none.variance > (avg_16x16[i] >> 1))) {
976
977
978
        force_split[i + 1] = 1;
        force_split[0] = 1;
      }
979
      avg_32x32 += vt.split[i].part_variances.none.variance;
Marco's avatar
Marco committed
980
    }
981
  }
982
  if (!force_split[0]) {
Marco's avatar
Marco committed
983
    fill_variance_tree(&vt, BLOCK_64X64);
984
    get_variance(&vt.part_variances.none);
985
986
987
    // If variance of this 64x64 block is above (some threshold of) the average
    // variance over the sub-32x32 blocks, then force this block to split.
    if (!is_key_frame &&
988
        vt.part_variances.none.variance > (5 * avg_32x32) >> 4)
989
      force_split[0] = 1;