vp9_encodeframe.c 157 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
  if (!is_key_frame) {
718
719
720
    // 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
721
    MODE_INFO *mi = xd->mi[0];
722
    unsigned int uv_sad;
723
    const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
724

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

730
    assert(yv12 != NULL);
731
732
733
734
735
736
737

    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);
    }

738
739
    if (yv12_g && yv12_g != yv12 &&
       (cpi->ref_frame_flags & VP9_GOLD_FLAG)) {
740
741
742
743
744
745
746
747
748
      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;
    }
749

Yaowu Xu's avatar
Yaowu Xu committed
750
    vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
751
                         &cm->frame_refs[LAST_FRAME - 1].sf);
Scott LaVarnway's avatar
Scott LaVarnway committed
752
753
754
755
756
    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;
757

758
    y_sad = vp9_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
759
760
761
    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
762
763
      mi->ref_frame[0] = GOLDEN_FRAME;
      mi->mv[0].as_int = 0;
764
765
      y_sad = y_sad_g;
    } else {
Scott LaVarnway's avatar
Scott LaVarnway committed
766
      x->pred_mv[LAST_FRAME] = mi->mv[0].as_mv;
767
    }
768

769
    vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_64X64);
770
771
772
773

    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
774
      const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
775

Yaowu Xu's avatar
Yaowu Xu committed
776
      if (bs == BLOCK_INVALID)
777
        uv_sad = UINT_MAX;
Yaowu Xu's avatar
Yaowu Xu committed
778
779
780
      else
        uv_sad = cpi->fn_ptr[bs].sdf(p->src.buf, p->src.stride,
                                     pd->dst.buf, pd->dst.stride);
781

782
      x->color_sensitivity[i - 1] = uv_sad > (y_sad >> 2);
783
    }
784
785
786

    d = xd->plane[0].dst.buf;
    dp = xd->plane[0].dst.stride;
787
788
789
790
791
792
793
794
795

    // 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) {
796
        set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_64X64);
797
798
799
        return 0;
      }
    }
800
801
802
  } else {
    d = VP9_VAR_OFFS;
    dp = 0;
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
#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
819
820
  }

Marco's avatar
Marco committed
821
  // Index for force_split: 0 for 64x64, 1-4 for 32x32 blocks,
822
  // 5-20 for the 16x16 blocks.
Marco's avatar
Marco committed
823
  force_split[0] = 0;
824
825
  // Fill in the entire tree of 8x8 (or 4x4 under some conditions) variances
  // for splits.
826
827
828
  for (i = 0; i < 4; i++) {
    const int x32_idx = ((i & 1) << 5);
    const int y32_idx = ((i >> 1) << 5);
829
    const int i2 = i << 2;
Marco's avatar
Marco committed
830
    force_split[i + 1] = 0;
831
    avg_16x16[i] = 0;
832
833
834
    for (j = 0; j < 4; j++) {
      const int x16_idx = x32_idx + ((j & 1) << 4);
      const int y16_idx = y32_idx + ((j >> 1) << 4);
835
      const int split_index = 5 + i2 + j;
836
      v16x16 *vst = &vt.split[i].split[j];
837
      force_split[split_index] = 0;
838
      variance4x4downsample[i2 + j] = 0;
839
      if (!is_key_frame) {
840
        fill_variance_8x8avg(s, sp, d, dp, x16_idx, y16_idx, vst,
841
#if CONFIG_VP9_HIGHBITDEPTH
842
                            xd->cur_buf->flags,
843
#endif
844
845
846
                            pixels_wide,
                            pixels_high,
                            is_key_frame);
847
        fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
848
        get_variance(&vt.split[i].split[j].part_variances.none);
849
        avg_16x16[i] += vt.split[i].split[j].part_variances.none.variance;
850
851
852
853
854
855
856
        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;
857
858
        } else if (cpi->oxcf.speed < 8 &&
                   vt.split[i].split[j].part_variances.none.variance >
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
                   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;
          }
        }
875
      }
876
      if (is_key_frame || (low_res &&
877
          vt.split[i].split[j].part_variances.none.variance >
878
          (thresholds[1] << 1))) {
879
        force_split[split_index] = 0;
880
881
882
883
884
        // 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);
885
          v8x8 *vst2 = is_key_frame ? &vst->split[k] :
886
              &vt2[i2 + j].split[k];
887
          fill_variance_4x4avg(s, sp, d, dp, x8_idx, y8_idx, vst2,
888
#if CONFIG_VP9_HIGHBITDEPTH
889
                               xd->cur_buf->flags,
890
#endif
891
892
893
                               pixels_wide,
                               pixels_high,
                               is_key_frame);
894
        }
895
896
897
898
      }
    }
  }
  // Fill the rest of the variance tree by summing split partition values.
899
  avg_32x32 = 0;
900
  for (i = 0; i < 4; i++) {
901
    const int i2 = i << 2;
902
    for (j = 0; j < 4; j++) {
903
      if (variance4x4downsample[i2 + j] == 1) {
904
        v16x16 *vtemp = (!is_key_frame) ? &vt2[i2 + j] :
905
            &vt.split[i].split[j];
Marco's avatar
Marco committed
906
        for (m = 0; m < 4; m++)
907
908
          fill_variance_tree(&vtemp->split[m], BLOCK_8X8);
        fill_variance_tree(vtemp, BLOCK_16X16);
909
910
911
912
913
914
915
916
        // 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;
        }
917
      }
918
919
    }
    fill_variance_tree(&vt.split[i], BLOCK_32X32);
920
921
922
923
    // 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.
924
925
    if (!force_split[i + 1]) {
      get_variance(&vt.split[i].part_variances.none);
926
927
      if (vt.split[i].part_variances.none.variance > thresholds[1] ||
          (!is_key_frame &&
928
929
          vt.split[i].part_variances.none.variance > (thresholds[1] >> 1) &&
          vt.split[i].part_variances.none.variance > (avg_16x16[i] >> 1))) {
930
931
932
        force_split[i + 1] = 1;
        force_split[0] = 1;
      }
933
      avg_32x32 += vt.split[i].part_variances.none.variance;
Marco's avatar
Marco committed
934
    }
935
  }
936
  if (!force_split[0]) {
Marco's avatar
Marco committed
937
    fill_variance_tree(&vt, BLOCK_64X64);
938
    get_variance(&vt.part_variances.none);
939
940
941
    // 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 &&
942
        vt.part_variances.none.variance > (5 * avg_32x32) >> 4)
943
      force_split[0] = 1;
944
  }
945

946
  // Now go through the entire structure, splitting every block size until
947
  // we get to one that's got a variance lower than our threshold.
948
  if ( mi_col + 8 > cm->mi_cols || mi_row + 8 > cm->mi_rows ||
949
      !set_vt_partitioning(cpi, x, xd, &vt, BLOCK_64X64, mi_row, mi_col,
950
                           thresholds[0], BLOCK_16X16, force_split[0])) {
951
952
953
    for (i = 0; i < 4; ++i) {
      const int x32_idx = ((i & 1) << 2);
      const int y32_idx = ((i >> 1) << 2);
954
      const int i2 = i << 2;