1/*
2 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  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.
9 */
10
11#include <limits.h>
12#include <math.h>
13#include <stdio.h>
14
15#include "./vp9_rtcd.h"
16#include "./vpx_config.h"
17
18#include "vpx_ports/vpx_timer.h"
19
20#include "vp9/common/vp9_common.h"
21#include "vp9/common/vp9_entropy.h"
22#include "vp9/common/vp9_entropymode.h"
23#include "vp9/common/vp9_idct.h"
24#include "vp9/common/vp9_mvref_common.h"
25#include "vp9/common/vp9_pred_common.h"
26#include "vp9/common/vp9_quant_common.h"
27#include "vp9/common/vp9_reconintra.h"
28#include "vp9/common/vp9_reconinter.h"
29#include "vp9/common/vp9_seg_common.h"
30#include "vp9/common/vp9_systemdependent.h"
31#include "vp9/common/vp9_tile_common.h"
32
33#include "vp9/encoder/vp9_aq_complexity.h"
34#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
35#include "vp9/encoder/vp9_aq_variance.h"
36#include "vp9/encoder/vp9_encodeframe.h"
37#include "vp9/encoder/vp9_encodemb.h"
38#include "vp9/encoder/vp9_encodemv.h"
39#include "vp9/encoder/vp9_extend.h"
40#include "vp9/encoder/vp9_pickmode.h"
41#include "vp9/encoder/vp9_rdopt.h"
42#include "vp9/encoder/vp9_segmentation.h"
43#include "vp9/encoder/vp9_tokenize.h"
44
45#define GF_ZEROMV_ZBIN_BOOST 0
46#define LF_ZEROMV_ZBIN_BOOST 0
47#define MV_ZBIN_BOOST        0
48#define SPLIT_MV_ZBIN_BOOST  0
49#define INTRA_ZBIN_BOOST     0
50
51static INLINE uint8_t *get_sb_index(MACROBLOCK *x, BLOCK_SIZE subsize) {
52  switch (subsize) {
53    case BLOCK_64X64:
54    case BLOCK_64X32:
55    case BLOCK_32X64:
56    case BLOCK_32X32:
57      return &x->sb_index;
58    case BLOCK_32X16:
59    case BLOCK_16X32:
60    case BLOCK_16X16:
61      return &x->mb_index;
62    case BLOCK_16X8:
63    case BLOCK_8X16:
64    case BLOCK_8X8:
65      return &x->b_index;
66    case BLOCK_8X4:
67    case BLOCK_4X8:
68    case BLOCK_4X4:
69      return &x->ab_index;
70    default:
71      assert(0);
72      return NULL;
73  }
74}
75
76static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
77                              int mi_row, int mi_col, BLOCK_SIZE bsize);
78
79static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
80
81// activity_avg must be positive, or flat regions could get a zero weight
82//  (infinite lambda), which confounds analysis.
83// This also avoids the need for divide by zero checks in
84//  vp9_activity_masking().
85#define ACTIVITY_AVG_MIN 64
86
87// Motion vector component magnitude threshold for defining fast motion.
88#define FAST_MOTION_MV_THRESH 24
89
90// This is used as a reference when computing the source variance for the
91//  purposes of activity masking.
92// Eventually this should be replaced by custom no-reference routines,
93//  which will be faster.
94static const uint8_t VP9_VAR_OFFS[64] = {
95  128, 128, 128, 128, 128, 128, 128, 128,
96  128, 128, 128, 128, 128, 128, 128, 128,
97  128, 128, 128, 128, 128, 128, 128, 128,
98  128, 128, 128, 128, 128, 128, 128, 128,
99  128, 128, 128, 128, 128, 128, 128, 128,
100  128, 128, 128, 128, 128, 128, 128, 128,
101  128, 128, 128, 128, 128, 128, 128, 128,
102  128, 128, 128, 128, 128, 128, 128, 128
103};
104
105static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi,
106                                              MACROBLOCK *x,
107                                              BLOCK_SIZE bs) {
108  unsigned int var, sse;
109  var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride,
110                           VP9_VAR_OFFS, 0, &sse);
111  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
112}
113
114static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi,
115                                                   MACROBLOCK *x,
116                                                   int mi_row,
117                                                   int mi_col,
118                                                   BLOCK_SIZE bs) {
119  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
120  int offset = (mi_row * MI_SIZE) * yv12->y_stride + (mi_col * MI_SIZE);
121  unsigned int var, sse;
122  var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf,
123                           x->plane[0].src.stride,
124                           yv12->y_buffer + offset,
125                           yv12->y_stride,
126                           &sse);
127  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
128}
129
130static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi,
131                                                   int mi_row,
132                                                   int mi_col) {
133  unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
134                                                    mi_row, mi_col,
135                                                    BLOCK_64X64);
136  if (var < 8)
137    return BLOCK_64X64;
138  else if (var < 128)
139    return BLOCK_32X32;
140  else if (var < 2048)
141    return BLOCK_16X16;
142  else
143    return BLOCK_8X8;
144}
145
146static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi,
147                                                      int mi_row,
148                                                      int mi_col) {
149  unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
150                                                    mi_row, mi_col,
151                                                    BLOCK_64X64);
152  if (var < 4)
153    return BLOCK_64X64;
154  else if (var < 10)
155    return BLOCK_32X32;
156  else
157    return BLOCK_16X16;
158}
159
160// Lighter version of set_offsets that only sets the mode info
161// pointers.
162static INLINE void set_modeinfo_offsets(VP9_COMMON *const cm,
163                                        MACROBLOCKD *const xd,
164                                        int mi_row,
165                                        int mi_col) {
166  const int idx_str = xd->mi_stride * mi_row + mi_col;
167  xd->mi = cm->mi_grid_visible + idx_str;
168  xd->mi[0] = cm->mi + idx_str;
169}
170
171static int is_block_in_mb_map(const VP9_COMP *cpi, int mi_row, int mi_col,
172                              BLOCK_SIZE bsize) {
173  const VP9_COMMON *const cm = &cpi->common;
174  const int mb_rows = cm->mb_rows;
175  const int mb_cols = cm->mb_cols;
176  const int mb_row = mi_row >> 1;
177  const int mb_col = mi_col >> 1;
178  const int mb_width = num_8x8_blocks_wide_lookup[bsize] >> 1;
179  const int mb_height = num_8x8_blocks_high_lookup[bsize] >> 1;
180  int r, c;
181  if (bsize <= BLOCK_16X16) {
182    return cpi->active_map[mb_row * mb_cols + mb_col];
183  }
184  for (r = 0; r < mb_height; ++r) {
185    for (c = 0; c < mb_width; ++c) {
186      int row = mb_row + r;
187      int col = mb_col + c;
188      if (row >= mb_rows || col >= mb_cols)
189        continue;
190      if (cpi->active_map[row * mb_cols + col])
191        return 1;
192    }
193  }
194  return 0;
195}
196
197static int check_active_map(const VP9_COMP *cpi, const MACROBLOCK *x,
198                            int mi_row, int mi_col,
199                            BLOCK_SIZE bsize) {
200  if (cpi->active_map_enabled && !x->e_mbd.lossless) {
201    return is_block_in_mb_map(cpi, mi_row, mi_col, bsize);
202  } else {
203    return 1;
204  }
205}
206
207static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
208                        int mi_row, int mi_col, BLOCK_SIZE bsize) {
209  MACROBLOCK *const x = &cpi->mb;
210  VP9_COMMON *const cm = &cpi->common;
211  MACROBLOCKD *const xd = &x->e_mbd;
212  MB_MODE_INFO *mbmi;
213  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
214  const int mi_height = num_8x8_blocks_high_lookup[bsize];
215  const int mb_row = mi_row >> 1;
216  const int mb_col = mi_col >> 1;
217  const int idx_map = mb_row * cm->mb_cols + mb_col;
218  const struct segmentation *const seg = &cm->seg;
219
220  set_skip_context(xd, mi_row, mi_col);
221
222  // Activity map pointer
223  x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
224  x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
225
226  set_modeinfo_offsets(cm, xd, mi_row, mi_col);
227
228  mbmi = &xd->mi[0]->mbmi;
229
230  // Set up destination pointers.
231  vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
232
233  // Set up limit values for MV components.
234  // Mv beyond the range do not produce new/different prediction block.
235  x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
236  x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
237  x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
238  x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
239
240  // Set up distance of MB to edge of frame in 1/8th pel units.
241  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
242  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
243                 cm->mi_rows, cm->mi_cols);
244
245  // Set up source buffers.
246  vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
247
248  // R/D setup.
249  x->rddiv = cpi->RDDIV;
250  x->rdmult = cpi->RDMULT;
251
252  // Setup segment ID.
253  if (seg->enabled) {
254    if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
255      const uint8_t *const map = seg->update_map ? cpi->segmentation_map
256                                                 : cm->last_frame_seg_map;
257      mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
258    }
259    vp9_init_plane_quantizers(cpi, x);
260
261    if (seg->enabled && cpi->seg0_cnt > 0 &&
262        !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) &&
263        vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) {
264      cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
265    } else {
266      const int y = mb_row & ~3;
267      const int x = mb_col & ~3;
268      const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
269      const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
270      const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1;
271      const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1;
272
273      cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
274          << 16) / cm->MBs;
275    }
276
277    x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
278  } else {
279    mbmi->segment_id = 0;
280    x->encode_breakout = cpi->encode_breakout;
281  }
282}
283
284static void duplicate_mode_info_in_sb(VP9_COMMON * const cm,
285                                     MACROBLOCKD *const xd,
286                                     int mi_row,
287                                     int mi_col,
288                                     BLOCK_SIZE bsize) {
289  const int block_width = num_8x8_blocks_wide_lookup[bsize];
290  const int block_height = num_8x8_blocks_high_lookup[bsize];
291  int i, j;
292  for (j = 0; j < block_height; ++j)
293    for (i = 0; i < block_width; ++i) {
294      if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols)
295        xd->mi[j * xd->mi_stride + i] = xd->mi[0];
296    }
297}
298
299static void set_block_size(VP9_COMP * const cpi,
300                           const TileInfo *const tile,
301                           int mi_row, int mi_col,
302                           BLOCK_SIZE bsize) {
303  if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
304    MACROBLOCKD *const xd = &cpi->mb.e_mbd;
305    set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col);
306    xd->mi[0]->mbmi.sb_type = bsize;
307    duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize);
308  }
309}
310
311typedef struct {
312  int64_t sum_square_error;
313  int64_t sum_error;
314  int count;
315  int variance;
316} var;
317
318typedef struct {
319  var none;
320  var horz[2];
321  var vert[2];
322} partition_variance;
323
324typedef struct {
325  partition_variance part_variances;
326  var split[4];
327} v8x8;
328
329typedef struct {
330  partition_variance part_variances;
331  v8x8 split[4];
332} v16x16;
333
334typedef struct {
335  partition_variance part_variances;
336  v16x16 split[4];
337} v32x32;
338
339typedef struct {
340  partition_variance part_variances;
341  v32x32 split[4];
342} v64x64;
343
344typedef struct {
345  partition_variance *part_variances;
346  var *split[4];
347} variance_node;
348
349typedef enum {
350  V16X16,
351  V32X32,
352  V64X64,
353} TREE_LEVEL;
354
355static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
356  int i;
357  switch (bsize) {
358    case BLOCK_64X64: {
359      v64x64 *vt = (v64x64 *) data;
360      node->part_variances = &vt->part_variances;
361      for (i = 0; i < 4; i++)
362        node->split[i] = &vt->split[i].part_variances.none;
363      break;
364    }
365    case BLOCK_32X32: {
366      v32x32 *vt = (v32x32 *) data;
367      node->part_variances = &vt->part_variances;
368      for (i = 0; i < 4; i++)
369        node->split[i] = &vt->split[i].part_variances.none;
370      break;
371    }
372    case BLOCK_16X16: {
373      v16x16 *vt = (v16x16 *) data;
374      node->part_variances = &vt->part_variances;
375      for (i = 0; i < 4; i++)
376        node->split[i] = &vt->split[i].part_variances.none;
377      break;
378    }
379    case BLOCK_8X8: {
380      v8x8 *vt = (v8x8 *) data;
381      node->part_variances = &vt->part_variances;
382      for (i = 0; i < 4; i++)
383        node->split[i] = &vt->split[i];
384      break;
385    }
386    default: {
387      assert(0);
388    }
389  }
390}
391
392// Set variance values given sum square error, sum error, count.
393static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
394  v->sum_square_error = s2;
395  v->sum_error = s;
396  v->count = c;
397  if (c > 0)
398    v->variance = (int)(256 *
399                        (v->sum_square_error - v->sum_error * v->sum_error /
400                         v->count) / v->count);
401  else
402    v->variance = 0;
403}
404
405void sum_2_variances(const var *a, const var *b, var *r) {
406  fill_variance(a->sum_square_error + b->sum_square_error,
407                a->sum_error + b->sum_error, a->count + b->count, r);
408}
409
410static void fill_variance_tree(void *data, BLOCK_SIZE bsize) {
411  variance_node node;
412  tree_to_node(data, bsize, &node);
413  sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]);
414  sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]);
415  sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]);
416  sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]);
417  sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1],
418                  &node.part_variances->none);
419}
420
421static int set_vt_partitioning(VP9_COMP *cpi,
422                               void *data,
423                               const TileInfo *const tile,
424                               BLOCK_SIZE bsize,
425                               int mi_row,
426                               int mi_col,
427                               int mi_size) {
428  VP9_COMMON * const cm = &cpi->common;
429  variance_node vt;
430  const int block_width = num_8x8_blocks_wide_lookup[bsize];
431  const int block_height = num_8x8_blocks_high_lookup[bsize];
432  // TODO(debargha): Choose this more intelligently.
433  const int64_t threshold_multiplier = 25;
434  int64_t threshold = threshold_multiplier * cpi->common.base_qindex;
435  assert(block_height == block_width);
436
437  tree_to_node(data, bsize, &vt);
438
439  // Split none is available only if we have more than half a block size
440  // in width and height inside the visible image.
441  if (mi_col + block_width / 2 < cm->mi_cols &&
442      mi_row + block_height / 2 < cm->mi_rows &&
443      vt.part_variances->none.variance < threshold) {
444    set_block_size(cpi, tile, mi_row, mi_col, bsize);
445    return 1;
446  }
447
448  // Vertical split is available on all but the bottom border.
449  if (mi_row + block_height / 2 < cm->mi_rows &&
450      vt.part_variances->vert[0].variance < threshold &&
451      vt.part_variances->vert[1].variance < threshold) {
452    BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
453    set_block_size(cpi, tile, mi_row, mi_col, subsize);
454    set_block_size(cpi, tile, mi_row, mi_col + block_width / 2, subsize);
455    return 1;
456  }
457
458  // Horizontal split is available on all but the right border.
459  if (mi_col + block_width / 2 < cm->mi_cols &&
460      vt.part_variances->horz[0].variance < threshold &&
461      vt.part_variances->horz[1].variance < threshold) {
462    BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
463    set_block_size(cpi, tile, mi_row, mi_col, subsize);
464    set_block_size(cpi, tile, mi_row + block_height / 2, mi_col, subsize);
465    return 1;
466  }
467  return 0;
468}
469
470// TODO(debargha): Fix this function and make it work as expected.
471static void choose_partitioning(VP9_COMP *cpi,
472                                const TileInfo *const tile,
473                                int mi_row, int mi_col) {
474  VP9_COMMON * const cm = &cpi->common;
475  MACROBLOCK *x = &cpi->mb;
476  MACROBLOCKD *xd = &cpi->mb.e_mbd;
477
478  int i, j, k;
479  v64x64 vt;
480  uint8_t *s;
481  const uint8_t *d;
482  int sp;
483  int dp;
484  int pixels_wide = 64, pixels_high = 64;
485  int_mv nearest_mv, near_mv;
486  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
487  const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
488
489  vp9_zero(vt);
490  set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
491
492  if (xd->mb_to_right_edge < 0)
493    pixels_wide += (xd->mb_to_right_edge >> 3);
494  if (xd->mb_to_bottom_edge < 0)
495    pixels_high += (xd->mb_to_bottom_edge >> 3);
496
497  s = x->plane[0].src.buf;
498  sp = x->plane[0].src.stride;
499
500  if (cm->frame_type != KEY_FRAME) {
501    vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf);
502
503    xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
504    xd->mi[0]->mbmi.sb_type = BLOCK_64X64;
505    vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv,
506                          xd->mi[0]->mbmi.ref_mvs[LAST_FRAME],
507                          &nearest_mv, &near_mv);
508
509    xd->mi[0]->mbmi.mv[0] = nearest_mv;
510    vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64);
511
512    d = xd->plane[0].dst.buf;
513    dp = xd->plane[0].dst.stride;
514  } else {
515    d = VP9_VAR_OFFS;
516    dp = 0;
517  }
518
519  // Fill in the entire tree of 8x8 variances for splits.
520  for (i = 0; i < 4; i++) {
521    const int x32_idx = ((i & 1) << 5);
522    const int y32_idx = ((i >> 1) << 5);
523    for (j = 0; j < 4; j++) {
524      const int x16_idx = x32_idx + ((j & 1) << 4);
525      const int y16_idx = y32_idx + ((j >> 1) << 4);
526      v16x16 *vst = &vt.split[i].split[j];
527      for (k = 0; k < 4; k++) {
528        int x_idx = x16_idx + ((k & 1) << 3);
529        int y_idx = y16_idx + ((k >> 1) << 3);
530        unsigned int sse = 0;
531        int sum = 0;
532        if (x_idx < pixels_wide && y_idx < pixels_high)
533          vp9_get_sse_sum_8x8(s + y_idx * sp + x_idx, sp,
534                              d + y_idx * dp + x_idx, dp, &sse, &sum);
535        fill_variance(sse, sum, 64, &vst->split[k].part_variances.none);
536      }
537    }
538  }
539  // Fill the rest of the variance tree by summing split partition values.
540  for (i = 0; i < 4; i++) {
541    for (j = 0; j < 4; j++) {
542      fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
543    }
544    fill_variance_tree(&vt.split[i], BLOCK_32X32);
545  }
546  fill_variance_tree(&vt, BLOCK_64X64);
547
548  // Now go through the entire structure,  splitting every block size until
549  // we get to one that's got a variance lower than our threshold,  or we
550  // hit 8x8.
551  if (!set_vt_partitioning(cpi, &vt, tile, BLOCK_64X64,
552                           mi_row, mi_col, 8)) {
553    for (i = 0; i < 4; ++i) {
554      const int x32_idx = ((i & 1) << 2);
555      const int y32_idx = ((i >> 1) << 2);
556      if (!set_vt_partitioning(cpi, &vt.split[i], tile, BLOCK_32X32,
557                               (mi_row + y32_idx), (mi_col + x32_idx), 4)) {
558        for (j = 0; j < 4; ++j) {
559          const int x16_idx = ((j & 1) << 1);
560          const int y16_idx = ((j >> 1) << 1);
561          // NOTE: This is a temporary hack to disable 8x8 partitions,
562          // since it works really bad - possibly due to a bug
563#define DISABLE_8X8_VAR_BASED_PARTITION
564#ifdef DISABLE_8X8_VAR_BASED_PARTITION
565          if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows &&
566              mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) {
567            set_block_size(cpi, tile,
568                           (mi_row + y32_idx + y16_idx),
569                           (mi_col + x32_idx + x16_idx),
570                           BLOCK_16X16);
571          } else {
572            for (k = 0; k < 4; ++k) {
573              const int x8_idx = (k & 1);
574              const int y8_idx = (k >> 1);
575              set_block_size(cpi, tile,
576                             (mi_row + y32_idx + y16_idx + y8_idx),
577                             (mi_col + x32_idx + x16_idx + x8_idx),
578                             BLOCK_8X8);
579            }
580          }
581#else
582          if (!set_vt_partitioning(cpi, &vt.split[i].split[j], tile,
583                                   BLOCK_16X16,
584                                   (mi_row + y32_idx + y16_idx),
585                                   (mi_col + x32_idx + x16_idx), 2)) {
586            for (k = 0; k < 4; ++k) {
587              const int x8_idx = (k & 1);
588              const int y8_idx = (k >> 1);
589              set_block_size(cpi, tile,
590                             (mi_row + y32_idx + y16_idx + y8_idx),
591                             (mi_col + x32_idx + x16_idx + x8_idx),
592                             BLOCK_8X8);
593            }
594          }
595#endif
596        }
597      }
598    }
599  }
600}
601
602// Original activity measure from Tim T's code.
603static unsigned int tt_activity_measure(MACROBLOCK *x) {
604  unsigned int sse;
605  // TODO: This could also be done over smaller areas (8x8), but that would
606  // require extensive changes elsewhere, as lambda is assumed to be fixed
607  // over an entire MB in most of the code.
608  // Another option is to compute four 8x8 variances, and pick a single
609  // lambda using a non-linear combination (e.g., the smallest, or second
610  // smallest, etc.).
611  const unsigned int act = vp9_variance16x16(x->plane[0].src.buf,
612                                             x->plane[0].src.stride,
613                                             VP9_VAR_OFFS, 0, &sse) << 4;
614  // If the region is flat, lower the activity some more.
615  return act < (8 << 12) ? MIN(act, 5 << 12) : act;
616}
617
618// Stub for alternative experimental activity measures.
619static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) {
620  return vp9_encode_intra(x, use_dc_pred);
621}
622
623// Measure the activity of the current macroblock
624// What we measure here is TBD so abstracted to this function
625#define ALT_ACT_MEASURE 1
626static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) {
627  unsigned int mb_activity;
628
629  if (ALT_ACT_MEASURE) {
630    const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
631
632    // Or use and alternative.
633    mb_activity = alt_activity_measure(x, use_dc_pred);
634  } else {
635    // Original activity measure from Tim T's code.
636    mb_activity = tt_activity_measure(x);
637  }
638
639  return MAX(mb_activity, ACTIVITY_AVG_MIN);
640}
641
642// Calculate an "average" mb activity value for the frame
643#define ACT_MEDIAN 0
644static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
645#if ACT_MEDIAN
646  // Find median: Simple n^2 algorithm for experimentation
647  {
648    unsigned int median;
649    unsigned int i, j;
650    unsigned int *sortlist;
651    unsigned int tmp;
652
653    // Create a list to sort to
654    CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
655                    cpi->common.MBs));
656
657    // Copy map to sort list
658    vpx_memcpy(sortlist, cpi->mb_activity_map,
659        sizeof(unsigned int) * cpi->common.MBs);
660
661    // Ripple each value down to its correct position
662    for (i = 1; i < cpi->common.MBs; i ++) {
663      for (j = i; j > 0; j --) {
664        if (sortlist[j] < sortlist[j - 1]) {
665          // Swap values
666          tmp = sortlist[j - 1];
667          sortlist[j - 1] = sortlist[j];
668          sortlist[j] = tmp;
669        } else {
670          break;
671        }
672      }
673    }
674
675    // Even number MBs so estimate median as mean of two either side.
676    median = (1 + sortlist[cpi->common.MBs >> 1] +
677        sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
678
679    cpi->activity_avg = median;
680
681    vpx_free(sortlist);
682  }
683#else
684  // Simple mean for now
685  cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs);
686#endif  // ACT_MEDIAN
687
688  if (cpi->activity_avg < ACTIVITY_AVG_MIN)
689    cpi->activity_avg = ACTIVITY_AVG_MIN;
690
691  // Experimental code: return fixed value normalized for several clips
692  if (ALT_ACT_MEASURE)
693    cpi->activity_avg = 100000;
694}
695
696#define USE_ACT_INDEX   0
697#define OUTPUT_NORM_ACT_STATS   0
698
699#if USE_ACT_INDEX
700// Calculate an activity index for each mb
701static void calc_activity_index(VP9_COMP *cpi, MACROBLOCK *x) {
702  VP9_COMMON *const cm = &cpi->common;
703  int mb_row, mb_col;
704
705  int64_t act;
706  int64_t a;
707  int64_t b;
708
709#if OUTPUT_NORM_ACT_STATS
710  FILE *f = fopen("norm_act.stt", "a");
711  fprintf(f, "\n%12d\n", cpi->activity_avg);
712#endif
713
714  // Reset pointers to start of activity map
715  x->mb_activity_ptr = cpi->mb_activity_map;
716
717  // Calculate normalized mb activity number.
718  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
719    // for each macroblock col in image
720    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
721      // Read activity from the map
722      act = *(x->mb_activity_ptr);
723
724      // Calculate a normalized activity number
725      a = act + 4 * cpi->activity_avg;
726      b = 4 * act + cpi->activity_avg;
727
728      if (b >= a)
729      *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
730      else
731      *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
732
733#if OUTPUT_NORM_ACT_STATS
734      fprintf(f, " %6d", *(x->mb_activity_ptr));
735#endif
736      // Increment activity map pointers
737      x->mb_activity_ptr++;
738    }
739
740#if OUTPUT_NORM_ACT_STATS
741    fprintf(f, "\n");
742#endif
743  }
744
745#if OUTPUT_NORM_ACT_STATS
746  fclose(f);
747#endif
748}
749#endif  // USE_ACT_INDEX
750
751// Loop through all MBs. Note activity of each, average activity and
752// calculate a normalized activity for each
753static void build_activity_map(VP9_COMP *cpi) {
754  MACROBLOCK *const x = &cpi->mb;
755  MACROBLOCKD *xd = &x->e_mbd;
756  VP9_COMMON *const cm = &cpi->common;
757
758#if ALT_ACT_MEASURE
759  YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm);
760  int recon_yoffset;
761  int recon_y_stride = new_yv12->y_stride;
762#endif
763
764  int mb_row, mb_col;
765  unsigned int mb_activity;
766  int64_t activity_sum = 0;
767
768  x->mb_activity_ptr = cpi->mb_activity_map;
769
770  // for each macroblock row in image
771  for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
772#if ALT_ACT_MEASURE
773    // reset above block coeffs
774    xd->up_available = (mb_row != 0);
775    recon_yoffset = (mb_row * recon_y_stride * 16);
776#endif
777    // for each macroblock col in image
778    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
779#if ALT_ACT_MEASURE
780      xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
781      xd->left_available = (mb_col != 0);
782      recon_yoffset += 16;
783#endif
784
785      // measure activity
786      mb_activity = mb_activity_measure(x, mb_row, mb_col);
787
788      // Keep frame sum
789      activity_sum += mb_activity;
790
791      // Store MB level activity details.
792      *x->mb_activity_ptr = mb_activity;
793
794      // Increment activity map pointer
795      x->mb_activity_ptr++;
796
797      // adjust to the next column of source macroblocks
798      x->plane[0].src.buf += 16;
799    }
800
801    // adjust to the next row of mbs
802    x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
803  }
804
805  // Calculate an "average" MB activity
806  calc_av_activity(cpi, activity_sum);
807
808#if USE_ACT_INDEX
809  // Calculate an activity index number of each mb
810  calc_activity_index(cpi, x);
811#endif
812}
813
814// Macroblock activity masking
815static void activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
816#if USE_ACT_INDEX
817  x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
818  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
819  x->errorperbit += (x->errorperbit == 0);
820#else
821  const int64_t act = *(x->mb_activity_ptr);
822
823  // Apply the masking to the RD multiplier.
824  const int64_t a = act + (2 * cpi->activity_avg);
825  const int64_t b = (2 * act) + cpi->activity_avg;
826
827  x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a);
828  x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
829  x->errorperbit += (x->errorperbit == 0);
830#endif
831
832  // Activity based Zbin adjustment
833  adjust_act_zbin(cpi, x);
834}
835
836static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
837                         int mi_row, int mi_col, BLOCK_SIZE bsize,
838                         int output_enabled) {
839  int i, x_idx, y;
840  VP9_COMMON *const cm = &cpi->common;
841  MACROBLOCK *const x = &cpi->mb;
842  MACROBLOCKD *const xd = &x->e_mbd;
843  struct macroblock_plane *const p = x->plane;
844  struct macroblockd_plane *const pd = xd->plane;
845  MODE_INFO *mi = &ctx->mic;
846  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
847  MODE_INFO *mi_addr = xd->mi[0];
848  const struct segmentation *const seg = &cm->seg;
849
850  const int mis = cm->mi_stride;
851  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
852  const int mi_height = num_8x8_blocks_high_lookup[bsize];
853  int max_plane;
854
855  assert(mi->mbmi.sb_type == bsize);
856
857  *mi_addr = *mi;
858
859  // If segmentation in use
860  if (seg->enabled && output_enabled) {
861    // For in frame complexity AQ copy the segment id from the segment map.
862    if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
863      const uint8_t *const map = seg->update_map ? cpi->segmentation_map
864                                                 : cm->last_frame_seg_map;
865      mi_addr->mbmi.segment_id =
866        vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
867    }
868    // Else for cyclic refresh mode update the segment map, set the segment id
869    // and then update the quantizer.
870    else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
871      vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi,
872                                        mi_row, mi_col, bsize, 1);
873      vp9_init_plane_quantizers(cpi, x);
874    }
875  }
876
877  max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
878  for (i = 0; i < max_plane; ++i) {
879    p[i].coeff = ctx->coeff_pbuf[i][1];
880    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
881    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
882    p[i].eobs = ctx->eobs_pbuf[i][1];
883  }
884
885  for (i = max_plane; i < MAX_MB_PLANE; ++i) {
886    p[i].coeff = ctx->coeff_pbuf[i][2];
887    p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
888    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
889    p[i].eobs = ctx->eobs_pbuf[i][2];
890  }
891
892  // Restore the coding context of the MB to that that was in place
893  // when the mode was picked for it
894  for (y = 0; y < mi_height; y++)
895    for (x_idx = 0; x_idx < mi_width; x_idx++)
896      if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
897        && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
898        xd->mi[x_idx + y * mis] = mi_addr;
899      }
900
901  if (cpi->oxcf.aq_mode)
902    vp9_init_plane_quantizers(cpi, x);
903
904  // FIXME(rbultje) I'm pretty sure this should go to the end of this block
905  // (i.e. after the output_enabled)
906  if (bsize < BLOCK_32X32) {
907    if (bsize < BLOCK_16X16)
908      ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
909    ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
910  }
911
912  if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
913    mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
914    mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
915  }
916
917  x->skip = ctx->skip;
918  vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
919             sizeof(uint8_t) * ctx->num_4x4_blk);
920
921  if (!output_enabled)
922    return;
923
924  if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
925    for (i = 0; i < TX_MODES; i++)
926      cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i];
927  }
928
929#if CONFIG_INTERNAL_STATS
930  if (frame_is_intra_only(cm)) {
931    static const int kf_mode_index[] = {
932      THR_DC        /*DC_PRED*/,
933      THR_V_PRED    /*V_PRED*/,
934      THR_H_PRED    /*H_PRED*/,
935      THR_D45_PRED  /*D45_PRED*/,
936      THR_D135_PRED /*D135_PRED*/,
937      THR_D117_PRED /*D117_PRED*/,
938      THR_D153_PRED /*D153_PRED*/,
939      THR_D207_PRED /*D207_PRED*/,
940      THR_D63_PRED  /*D63_PRED*/,
941      THR_TM        /*TM_PRED*/,
942    };
943    ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]];
944  } else {
945    // Note how often each mode chosen as best
946    ++cpi->mode_chosen_counts[ctx->best_mode_index];
947  }
948#endif
949  if (!frame_is_intra_only(cm)) {
950    if (is_inter_block(mbmi)) {
951      vp9_update_mv_count(cm, xd);
952
953      if (cm->interp_filter == SWITCHABLE) {
954        const int ctx = vp9_get_pred_context_switchable_interp(xd);
955        ++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
956      }
957    }
958
959    cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
960    cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
961    cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
962
963    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
964      cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
965  }
966}
967
968void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
969                          int mi_row, int mi_col) {
970  uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
971                               src->alpha_buffer};
972  const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
973                          src->alpha_stride};
974  int i;
975
976  // Set current frame pointer.
977  x->e_mbd.cur_buf = src;
978
979  for (i = 0; i < MAX_MB_PLANE; i++)
980    setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
981                     NULL, x->e_mbd.plane[i].subsampling_x,
982                     x->e_mbd.plane[i].subsampling_y);
983}
984
985static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
986                             int mi_row, int mi_col,
987                             int *totalrate, int64_t *totaldist,
988                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
989                             int64_t best_rd) {
990  VP9_COMMON *const cm = &cpi->common;
991  MACROBLOCK *const x = &cpi->mb;
992  MACROBLOCKD *const xd = &x->e_mbd;
993  MB_MODE_INFO *mbmi;
994  struct macroblock_plane *const p = x->plane;
995  struct macroblockd_plane *const pd = xd->plane;
996  const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
997  int i, orig_rdmult;
998  double rdmult_ratio;
999
1000  vp9_clear_system_state();
1001  rdmult_ratio = 1.0;  // avoid uninitialized warnings
1002
1003  // Use the lower precision, but faster, 32x32 fdct for mode selection.
1004  x->use_lp32x32fdct = 1;
1005
1006  if (bsize < BLOCK_8X8) {
1007    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1008    // there is nothing to be done.
1009    if (x->ab_index != 0) {
1010      *totalrate = 0;
1011      *totaldist = 0;
1012      return;
1013    }
1014  }
1015
1016  set_offsets(cpi, tile, mi_row, mi_col, bsize);
1017  mbmi = &xd->mi[0]->mbmi;
1018  mbmi->sb_type = bsize;
1019
1020  for (i = 0; i < MAX_MB_PLANE; ++i) {
1021    p[i].coeff = ctx->coeff_pbuf[i][0];
1022    p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
1023    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
1024    p[i].eobs = ctx->eobs_pbuf[i][0];
1025  }
1026  ctx->is_coded = 0;
1027  x->skip_recode = 0;
1028
1029  // Set to zero to make sure we do not use the previous encoded frame stats
1030  mbmi->skip = 0;
1031
1032  x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
1033
1034  if (aq_mode == VARIANCE_AQ) {
1035    const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
1036                                            : vp9_block_energy(cpi, x, bsize);
1037
1038    if (cm->frame_type == KEY_FRAME ||
1039        cpi->refresh_alt_ref_frame ||
1040        (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
1041      mbmi->segment_id = vp9_vaq_segment_id(energy);
1042    } else {
1043      const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1044                                                    : cm->last_frame_seg_map;
1045      mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
1046    }
1047
1048    rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
1049    vp9_init_plane_quantizers(cpi, x);
1050  }
1051
1052  // Save rdmult before it might be changed, so it can be restored later.
1053  orig_rdmult = x->rdmult;
1054  if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
1055    activity_masking(cpi, x);
1056
1057  if (aq_mode == VARIANCE_AQ) {
1058    vp9_clear_system_state();
1059    x->rdmult = (int)round(x->rdmult * rdmult_ratio);
1060  } else if (aq_mode == COMPLEXITY_AQ) {
1061    const int mi_offset = mi_row * cm->mi_cols + mi_col;
1062    unsigned char complexity = cpi->complexity_map[mi_offset];
1063    const int is_edge = (mi_row <= 1) || (mi_row >= (cm->mi_rows - 2)) ||
1064                        (mi_col <= 1) || (mi_col >= (cm->mi_cols - 2));
1065    if (!is_edge && (complexity > 128))
1066      x->rdmult += ((x->rdmult * (complexity - 128)) / 256);
1067  } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1068    const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1069        : cm->last_frame_seg_map;
1070    // If segment 1, use rdmult for that segment.
1071    if (vp9_get_segment_id(cm, map, bsize, mi_row, mi_col))
1072      x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
1073  }
1074
1075  // Find best coding mode & reconstruct the MB so it is available
1076  // as a predictor for MBs that follow in the SB
1077  if (frame_is_intra_only(cm)) {
1078    vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
1079                              best_rd);
1080  } else {
1081    if (bsize >= BLOCK_8X8)
1082      vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
1083                                totalrate, totaldist, bsize, ctx, best_rd);
1084    else
1085      vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
1086                                    totaldist, bsize, ctx, best_rd);
1087  }
1088
1089  if (aq_mode == VARIANCE_AQ) {
1090    x->rdmult = orig_rdmult;
1091    if (*totalrate != INT_MAX) {
1092      vp9_clear_system_state();
1093      *totalrate = (int)round(*totalrate * rdmult_ratio);
1094    }
1095  } else if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) ||
1096      (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)) {
1097    x->rdmult = orig_rdmult;
1098  }
1099}
1100
1101static void update_stats(VP9_COMP *cpi) {
1102  VP9_COMMON *const cm = &cpi->common;
1103  const MACROBLOCK *const x = &cpi->mb;
1104  const MACROBLOCKD *const xd = &x->e_mbd;
1105  const MODE_INFO *const mi = xd->mi[0];
1106  const MB_MODE_INFO *const mbmi = &mi->mbmi;
1107
1108  if (!frame_is_intra_only(cm)) {
1109    const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
1110                                                     SEG_LVL_REF_FRAME);
1111    if (!seg_ref_active) {
1112      FRAME_COUNTS *const counts = &cm->counts;
1113      const int inter_block = is_inter_block(mbmi);
1114
1115      counts->intra_inter[vp9_get_intra_inter_context(xd)][inter_block]++;
1116
1117      // If the segment reference feature is enabled we have only a single
1118      // reference frame allowed for the segment so exclude it from
1119      // the reference frame counts used to work out probabilities.
1120      if (inter_block) {
1121        const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1122
1123        if (cm->reference_mode == REFERENCE_MODE_SELECT)
1124          counts->comp_inter[vp9_get_reference_mode_context(cm, xd)]
1125                            [has_second_ref(mbmi)]++;
1126
1127        if (has_second_ref(mbmi)) {
1128          counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
1129                          [ref0 == GOLDEN_FRAME]++;
1130        } else {
1131          counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
1132                            [ref0 != LAST_FRAME]++;
1133          if (ref0 != LAST_FRAME)
1134            counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
1135                              [ref0 != GOLDEN_FRAME]++;
1136        }
1137      }
1138    }
1139  }
1140}
1141
1142static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
1143  switch (bsize) {
1144    case BLOCK_64X64:
1145      return &x->sb64_partitioning;
1146    case BLOCK_32X32:
1147      return &x->sb_partitioning[x->sb_index];
1148    case BLOCK_16X16:
1149      return &x->mb_partitioning[x->sb_index][x->mb_index];
1150    case BLOCK_8X8:
1151      return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
1152    default:
1153      assert(0);
1154      return NULL;
1155  }
1156}
1157
1158static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
1159                            ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1160                            ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1161                            PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1162                            BLOCK_SIZE bsize) {
1163  MACROBLOCK *const x = &cpi->mb;
1164  MACROBLOCKD *const xd = &x->e_mbd;
1165  int p;
1166  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1167  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1168  int mi_width = num_8x8_blocks_wide_lookup[bsize];
1169  int mi_height = num_8x8_blocks_high_lookup[bsize];
1170  for (p = 0; p < MAX_MB_PLANE; p++) {
1171    vpx_memcpy(
1172        xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
1173        a + num_4x4_blocks_wide * p,
1174        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1175        xd->plane[p].subsampling_x);
1176    vpx_memcpy(
1177        xd->left_context[p]
1178            + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1179        l + num_4x4_blocks_high * p,
1180        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1181        xd->plane[p].subsampling_y);
1182  }
1183  vpx_memcpy(xd->above_seg_context + mi_col, sa,
1184             sizeof(*xd->above_seg_context) * mi_width);
1185  vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl,
1186             sizeof(xd->left_seg_context[0]) * mi_height);
1187}
1188static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
1189                         ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1190                         ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1191                         PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1192                         BLOCK_SIZE bsize) {
1193  const MACROBLOCK *const x = &cpi->mb;
1194  const MACROBLOCKD *const xd = &x->e_mbd;
1195  int p;
1196  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1197  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1198  int mi_width = num_8x8_blocks_wide_lookup[bsize];
1199  int mi_height = num_8x8_blocks_high_lookup[bsize];
1200
1201  // buffer the above/left context information of the block in search.
1202  for (p = 0; p < MAX_MB_PLANE; ++p) {
1203    vpx_memcpy(
1204        a + num_4x4_blocks_wide * p,
1205        xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
1206        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1207        xd->plane[p].subsampling_x);
1208    vpx_memcpy(
1209        l + num_4x4_blocks_high * p,
1210        xd->left_context[p]
1211            + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1212        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1213        xd->plane[p].subsampling_y);
1214  }
1215  vpx_memcpy(sa, xd->above_seg_context + mi_col,
1216             sizeof(*xd->above_seg_context) * mi_width);
1217  vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK),
1218             sizeof(xd->left_seg_context[0]) * mi_height);
1219}
1220
1221static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
1222                     TOKENEXTRA **tp, int mi_row, int mi_col,
1223                     int output_enabled, BLOCK_SIZE bsize) {
1224  MACROBLOCK *const x = &cpi->mb;
1225
1226  if (bsize < BLOCK_8X8) {
1227    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1228    // there is nothing to be done.
1229    if (x->ab_index > 0)
1230      return;
1231  }
1232  set_offsets(cpi, tile, mi_row, mi_col, bsize);
1233  update_state(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize,
1234               output_enabled);
1235  encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
1236
1237  if (output_enabled) {
1238    update_stats(cpi);
1239
1240    (*tp)->token = EOSB_TOKEN;
1241    (*tp)++;
1242  }
1243}
1244
1245static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
1246                      TOKENEXTRA **tp, int mi_row, int mi_col,
1247                      int output_enabled, BLOCK_SIZE bsize) {
1248  VP9_COMMON *const cm = &cpi->common;
1249  MACROBLOCK *const x = &cpi->mb;
1250  MACROBLOCKD *const xd = &x->e_mbd;
1251
1252  const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
1253  int ctx;
1254  PARTITION_TYPE partition;
1255  BLOCK_SIZE subsize;
1256
1257  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1258    return;
1259
1260  if (bsize >= BLOCK_8X8) {
1261    ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1262    subsize = *get_sb_partitioning(x, bsize);
1263  } else {
1264    ctx = 0;
1265    subsize = BLOCK_4X4;
1266  }
1267
1268  partition = partition_lookup[bsl][subsize];
1269
1270  switch (partition) {
1271    case PARTITION_NONE:
1272      if (output_enabled && bsize >= BLOCK_8X8)
1273        cm->counts.partition[ctx][PARTITION_NONE]++;
1274      encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1275      break;
1276    case PARTITION_VERT:
1277      if (output_enabled)
1278        cm->counts.partition[ctx][PARTITION_VERT]++;
1279      *get_sb_index(x, subsize) = 0;
1280      encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1281      if (mi_col + hbs < cm->mi_cols) {
1282        *get_sb_index(x, subsize) = 1;
1283        encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
1284      }
1285      break;
1286    case PARTITION_HORZ:
1287      if (output_enabled)
1288        cm->counts.partition[ctx][PARTITION_HORZ]++;
1289      *get_sb_index(x, subsize) = 0;
1290      encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1291      if (mi_row + hbs < cm->mi_rows) {
1292        *get_sb_index(x, subsize) = 1;
1293        encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
1294      }
1295      break;
1296    case PARTITION_SPLIT:
1297      subsize = get_subsize(bsize, PARTITION_SPLIT);
1298      if (output_enabled)
1299        cm->counts.partition[ctx][PARTITION_SPLIT]++;
1300
1301      *get_sb_index(x, subsize) = 0;
1302      encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1303      *get_sb_index(x, subsize) = 1;
1304      encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
1305      *get_sb_index(x, subsize) = 2;
1306      encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
1307      *get_sb_index(x, subsize) = 3;
1308      encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1309                subsize);
1310      break;
1311    default:
1312      assert("Invalid partition type.");
1313  }
1314
1315  if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1316    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1317}
1318
1319// Check to see if the given partition size is allowed for a specified number
1320// of 8x8 block rows and columns remaining in the image.
1321// If not then return the largest allowed partition size
1322static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize,
1323                                      int rows_left, int cols_left,
1324                                      int *bh, int *bw) {
1325  if (rows_left <= 0 || cols_left <= 0) {
1326    return MIN(bsize, BLOCK_8X8);
1327  } else {
1328    for (; bsize > 0; bsize -= 3) {
1329      *bh = num_8x8_blocks_high_lookup[bsize];
1330      *bw = num_8x8_blocks_wide_lookup[bsize];
1331      if ((*bh <= rows_left) && (*bw <= cols_left)) {
1332        break;
1333      }
1334    }
1335  }
1336  return bsize;
1337}
1338
1339// This function attempts to set all mode info entries in a given SB64
1340// to the same block partition size.
1341// However, at the bottom and right borders of the image the requested size
1342// may not be allowed in which case this code attempts to choose the largest
1343// allowable partition.
1344static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
1345                                   MODE_INFO **mi_8x8, int mi_row, int mi_col,
1346                                   BLOCK_SIZE bsize) {
1347  VP9_COMMON *const cm = &cpi->common;
1348  const int mis = cm->mi_stride;
1349  int row8x8_remaining = tile->mi_row_end - mi_row;
1350  int col8x8_remaining = tile->mi_col_end - mi_col;
1351  int block_row, block_col;
1352  MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
1353  int bh = num_8x8_blocks_high_lookup[bsize];
1354  int bw = num_8x8_blocks_wide_lookup[bsize];
1355
1356  assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1357
1358  // Apply the requested partition size to the SB64 if it is all "in image"
1359  if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1360      (row8x8_remaining >= MI_BLOCK_SIZE)) {
1361    for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1362      for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1363        int index = block_row * mis + block_col;
1364        mi_8x8[index] = mi_upper_left + index;
1365        mi_8x8[index]->mbmi.sb_type = bsize;
1366      }
1367    }
1368  } else {
1369    // Else this is a partial SB64.
1370    for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1371      for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1372        int index = block_row * mis + block_col;
1373        // Find a partition size that fits
1374        bsize = find_partition_size(bsize,
1375                                    (row8x8_remaining - block_row),
1376                                    (col8x8_remaining - block_col), &bh, &bw);
1377        mi_8x8[index] = mi_upper_left + index;
1378        mi_8x8[index]->mbmi.sb_type = bsize;
1379      }
1380    }
1381  }
1382}
1383
1384static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8,
1385                              MODE_INFO **prev_mi_8x8) {
1386  const int mis = cm->mi_stride;
1387  int block_row, block_col;
1388
1389  for (block_row = 0; block_row < 8; ++block_row) {
1390    for (block_col = 0; block_col < 8; ++block_col) {
1391      MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col];
1392      const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
1393
1394      if (prev_mi) {
1395        const ptrdiff_t offset = prev_mi - cm->prev_mi;
1396        mi_8x8[block_row * mis + block_col] = cm->mi + offset;
1397        mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type;
1398      }
1399    }
1400  }
1401}
1402
1403static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
1404  const int mis = cm->mi_stride;
1405  int block_row, block_col;
1406
1407  if (cm->prev_mi) {
1408    for (block_row = 0; block_row < 8; ++block_row) {
1409      for (block_col = 0; block_col < 8; ++block_col) {
1410        const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col];
1411        if (prev_mi) {
1412          if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 ||
1413              abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8)
1414            return 1;
1415        }
1416      }
1417    }
1418  }
1419  return 0;
1420}
1421
1422static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
1423                            int mi_row, int mi_col, int bsize) {
1424  VP9_COMMON *const cm = &cpi->common;
1425  MACROBLOCK *const x = &cpi->mb;
1426  MACROBLOCKD *const xd = &x->e_mbd;
1427  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1428  const struct segmentation *const seg = &cm->seg;
1429
1430  *(xd->mi[0]) = ctx->mic;
1431
1432  // For in frame adaptive Q, check for reseting the segment_id and updating
1433  // the cyclic refresh map.
1434  if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled) {
1435    vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi,
1436                                      mi_row, mi_col, bsize, 1);
1437    vp9_init_plane_quantizers(cpi, x);
1438  }
1439
1440  if (is_inter_block(mbmi)) {
1441    vp9_update_mv_count(cm, xd);
1442
1443    if (cm->interp_filter == SWITCHABLE) {
1444      const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
1445      ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter];
1446    }
1447  }
1448
1449  x->skip = ctx->skip;
1450}
1451
1452static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile,
1453                        TOKENEXTRA **tp, int mi_row, int mi_col,
1454                        int output_enabled, BLOCK_SIZE bsize) {
1455  MACROBLOCK *const x = &cpi->mb;
1456
1457  if (bsize < BLOCK_8X8) {
1458    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1459    // there is nothing to be done.
1460    if (x->ab_index > 0)
1461      return;
1462  }
1463
1464  set_offsets(cpi, tile, mi_row, mi_col, bsize);
1465  update_state_rt(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize);
1466
1467  encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
1468  update_stats(cpi);
1469
1470  (*tp)->token = EOSB_TOKEN;
1471  (*tp)++;
1472}
1473
1474static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
1475                         TOKENEXTRA **tp, int mi_row, int mi_col,
1476                         int output_enabled, BLOCK_SIZE bsize) {
1477  VP9_COMMON *const cm = &cpi->common;
1478  MACROBLOCK *const x = &cpi->mb;
1479  MACROBLOCKD *const xd = &x->e_mbd;
1480
1481  const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
1482  int ctx;
1483  PARTITION_TYPE partition;
1484  BLOCK_SIZE subsize;
1485
1486  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1487    return;
1488
1489  if (bsize >= BLOCK_8X8) {
1490    MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1491    const int idx_str = xd->mi_stride * mi_row + mi_col;
1492    MODE_INFO ** mi_8x8 = cm->mi_grid_visible + idx_str;
1493    ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1494    subsize = mi_8x8[0]->mbmi.sb_type;
1495  } else {
1496    ctx = 0;
1497    subsize = BLOCK_4X4;
1498  }
1499
1500  partition = partition_lookup[bsl][subsize];
1501
1502  switch (partition) {
1503    case PARTITION_NONE:
1504      if (output_enabled && bsize >= BLOCK_8X8)
1505        cm->counts.partition[ctx][PARTITION_NONE]++;
1506      encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1507      break;
1508    case PARTITION_VERT:
1509      if (output_enabled)
1510        cm->counts.partition[ctx][PARTITION_VERT]++;
1511      *get_sb_index(x, subsize) = 0;
1512      encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1513      if (mi_col + hbs < cm->mi_cols) {
1514        *get_sb_index(x, subsize) = 1;
1515        encode_b_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
1516                    subsize);
1517      }
1518      break;
1519    case PARTITION_HORZ:
1520      if (output_enabled)
1521        cm->counts.partition[ctx][PARTITION_HORZ]++;
1522      *get_sb_index(x, subsize) = 0;
1523      encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1524      if (mi_row + hbs < cm->mi_rows) {
1525        *get_sb_index(x, subsize) = 1;
1526        encode_b_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
1527                    subsize);
1528      }
1529      break;
1530    case PARTITION_SPLIT:
1531      subsize = get_subsize(bsize, PARTITION_SPLIT);
1532      if (output_enabled)
1533        cm->counts.partition[ctx][PARTITION_SPLIT]++;
1534
1535      *get_sb_index(x, subsize) = 0;
1536      encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1537      *get_sb_index(x, subsize) = 1;
1538      encode_sb_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
1539                   subsize);
1540      *get_sb_index(x, subsize) = 2;
1541      encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
1542                   subsize);
1543      *get_sb_index(x, subsize) = 3;
1544      encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1545                   subsize);
1546      break;
1547    default:
1548      assert("Invalid partition type.");
1549  }
1550
1551  if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1552    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1553}
1554
1555static void rd_use_partition(VP9_COMP *cpi,
1556                             const TileInfo *const tile,
1557                             MODE_INFO **mi_8x8,
1558                             TOKENEXTRA **tp, int mi_row, int mi_col,
1559                             BLOCK_SIZE bsize, int *rate, int64_t *dist,
1560                             int do_recon) {
1561  VP9_COMMON *const cm = &cpi->common;
1562  MACROBLOCK *const x = &cpi->mb;
1563  MACROBLOCKD *const xd = &x->e_mbd;
1564  const int mis = cm->mi_stride;
1565  const int bsl = b_width_log2(bsize);
1566  const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2;
1567  const int bss = (1 << bsl) / 4;
1568  int i, pl;
1569  PARTITION_TYPE partition = PARTITION_NONE;
1570  BLOCK_SIZE subsize;
1571  ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1572  PARTITION_CONTEXT sl[8], sa[8];
1573  int last_part_rate = INT_MAX;
1574  int64_t last_part_dist = INT64_MAX;
1575  int64_t last_part_rd = INT64_MAX;
1576  int none_rate = INT_MAX;
1577  int64_t none_dist = INT64_MAX;
1578  int64_t none_rd = INT64_MAX;
1579  int chosen_rate = INT_MAX;
1580  int64_t chosen_dist = INT64_MAX;
1581  int64_t chosen_rd = INT64_MAX;
1582  BLOCK_SIZE sub_subsize = BLOCK_4X4;
1583  int splits_below = 0;
1584  BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
1585  int do_partition_search = 1;
1586
1587  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1588    return;
1589
1590  assert(num_4x4_blocks_wide_lookup[bsize] ==
1591         num_4x4_blocks_high_lookup[bsize]);
1592
1593  partition = partition_lookup[bsl][bs_type];
1594  subsize = get_subsize(bsize, partition);
1595
1596  if (bsize < BLOCK_8X8) {
1597    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1598    // there is nothing to be done.
1599    if (x->ab_index != 0) {
1600      *rate = 0;
1601      *dist = 0;
1602      return;
1603    }
1604  } else {
1605    *(get_sb_partitioning(x, bsize)) = subsize;
1606  }
1607  save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1608
1609  if (bsize == BLOCK_16X16) {
1610    set_offsets(cpi, tile, mi_row, mi_col, bsize);
1611    x->mb_energy = vp9_block_energy(cpi, x, bsize);
1612  } else {
1613    x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
1614  }
1615
1616  if (!x->in_active_map) {
1617    do_partition_search = 0;
1618    if (mi_row + (mi_step >> 1) < cm->mi_rows &&
1619        mi_col + (mi_step >> 1) < cm->mi_cols) {
1620      *(get_sb_partitioning(x, bsize)) = bsize;
1621      bs_type = mi_8x8[0]->mbmi.sb_type = bsize;
1622      subsize = bsize;
1623      partition = PARTITION_NONE;
1624    }
1625  }
1626  if (do_partition_search &&
1627      cpi->sf.partition_search_type == SEARCH_PARTITION &&
1628      cpi->sf.adjust_partitioning_from_last_frame) {
1629    // Check if any of the sub blocks are further split.
1630    if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
1631      sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
1632      splits_below = 1;
1633      for (i = 0; i < 4; i++) {
1634        int jj = i >> 1, ii = i & 0x01;
1635        MODE_INFO * this_mi = mi_8x8[jj * bss * mis + ii * bss];
1636        if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
1637          splits_below = 0;
1638        }
1639      }
1640    }
1641
1642    // If partition is not none try none unless each of the 4 splits are split
1643    // even further..
1644    if (partition != PARTITION_NONE && !splits_below &&
1645        mi_row + (mi_step >> 1) < cm->mi_rows &&
1646        mi_col + (mi_step >> 1) < cm->mi_cols) {
1647      *(get_sb_partitioning(x, bsize)) = bsize;
1648      rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize,
1649                       get_block_context(x, bsize), INT64_MAX);
1650
1651      pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1652
1653      if (none_rate < INT_MAX) {
1654        none_rate += x->partition_cost[pl][PARTITION_NONE];
1655        none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist);
1656      }
1657
1658      restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1659      mi_8x8[0]->mbmi.sb_type = bs_type;
1660      *(get_sb_partitioning(x, bsize)) = subsize;
1661    }
1662  }
1663
1664  switch (partition) {
1665    case PARTITION_NONE:
1666      rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1667                       &last_part_dist, bsize,
1668                       get_block_context(x, bsize), INT64_MAX);
1669      break;
1670    case PARTITION_HORZ:
1671      *get_sb_index(x, subsize) = 0;
1672      rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1673                       &last_part_dist, subsize,
1674                       get_block_context(x, subsize), INT64_MAX);
1675      if (last_part_rate != INT_MAX &&
1676          bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
1677        int rt = 0;
1678        int64_t dt = 0;
1679        update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
1680                     subsize, 0);
1681        encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
1682        *get_sb_index(x, subsize) = 1;
1683        rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt,
1684                         subsize, get_block_context(x, subsize), INT64_MAX);
1685        if (rt == INT_MAX || dt == INT64_MAX) {
1686          last_part_rate = INT_MAX;
1687          last_part_dist = INT64_MAX;
1688          break;
1689        }
1690
1691        last_part_rate += rt;
1692        last_part_dist += dt;
1693      }
1694      break;
1695    case PARTITION_VERT:
1696      *get_sb_index(x, subsize) = 0;
1697      rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1698                       &last_part_dist, subsize,
1699                       get_block_context(x, subsize), INT64_MAX);
1700      if (last_part_rate != INT_MAX &&
1701          bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
1702        int rt = 0;
1703        int64_t dt = 0;
1704        update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
1705                     subsize, 0);
1706        encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
1707        *get_sb_index(x, subsize) = 1;
1708        rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt,
1709                         subsize, get_block_context(x, subsize), INT64_MAX);
1710        if (rt == INT_MAX || dt == INT64_MAX) {
1711          last_part_rate = INT_MAX;
1712          last_part_dist = INT64_MAX;
1713          break;
1714        }
1715        last_part_rate += rt;
1716        last_part_dist += dt;
1717      }
1718      break;
1719    case PARTITION_SPLIT:
1720      // Split partition.
1721      last_part_rate = 0;
1722      last_part_dist = 0;
1723      for (i = 0; i < 4; i++) {
1724        int x_idx = (i & 1) * (mi_step >> 1);
1725        int y_idx = (i >> 1) * (mi_step >> 1);
1726        int jj = i >> 1, ii = i & 0x01;
1727        int rt;
1728        int64_t dt;
1729
1730        if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1731          continue;
1732
1733        *get_sb_index(x, subsize) = i;
1734
1735        rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
1736                         mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt,
1737                         i != 3);
1738        if (rt == INT_MAX || dt == INT64_MAX) {
1739          last_part_rate = INT_MAX;
1740          last_part_dist = INT64_MAX;
1741          break;
1742        }
1743        last_part_rate += rt;
1744        last_part_dist += dt;
1745      }
1746      break;
1747    default:
1748      assert(0);
1749  }
1750
1751  pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1752  if (last_part_rate < INT_MAX) {
1753    last_part_rate += x->partition_cost[pl][partition];
1754    last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist);
1755  }
1756
1757  if (do_partition_search
1758      && cpi->sf.adjust_partitioning_from_last_frame
1759      && cpi->sf.partition_search_type == SEARCH_PARTITION
1760      && partition != PARTITION_SPLIT && bsize > BLOCK_8X8
1761      && (mi_row + mi_step < cm->mi_rows ||
1762          mi_row + (mi_step >> 1) == cm->mi_rows)
1763      && (mi_col + mi_step < cm->mi_cols ||
1764          mi_col + (mi_step >> 1) == cm->mi_cols)) {
1765    BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
1766    chosen_rate = 0;
1767    chosen_dist = 0;
1768    restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1769
1770    // Split partition.
1771    for (i = 0; i < 4; i++) {
1772      int x_idx = (i & 1) * (mi_step >> 1);
1773      int y_idx = (i >> 1) * (mi_step >> 1);
1774      int rt = 0;
1775      int64_t dt = 0;
1776      ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1777      PARTITION_CONTEXT sl[8], sa[8];
1778
1779      if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1780        continue;
1781
1782      *get_sb_index(x, split_subsize) = i;
1783      *get_sb_partitioning(x, bsize) = split_subsize;
1784      *get_sb_partitioning(x, split_subsize) = split_subsize;
1785
1786      save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1787
1788      rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt,
1789                       split_subsize, get_block_context(x, split_subsize),
1790                       INT64_MAX);
1791
1792      restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1793
1794      if (rt == INT_MAX || dt == INT64_MAX) {
1795        chosen_rate = INT_MAX;
1796        chosen_dist = INT64_MAX;
1797        break;
1798      }
1799
1800      chosen_rate += rt;
1801      chosen_dist += dt;
1802
1803      if (i != 3)
1804        encode_sb(cpi, tile, tp,  mi_row + y_idx, mi_col + x_idx, 0,
1805                  split_subsize);
1806
1807      pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
1808                                   split_subsize);
1809      chosen_rate += x->partition_cost[pl][PARTITION_NONE];
1810    }
1811    pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1812    if (chosen_rate < INT_MAX) {
1813      chosen_rate += x->partition_cost[pl][PARTITION_SPLIT];
1814      chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist);
1815    }
1816  }
1817
1818  // If last_part is better set the partitioning to that...
1819  if (last_part_rd < chosen_rd) {
1820    mi_8x8[0]->mbmi.sb_type = bsize;
1821    if (bsize >= BLOCK_8X8)
1822      *(get_sb_partitioning(x, bsize)) = subsize;
1823    chosen_rate = last_part_rate;
1824    chosen_dist = last_part_dist;
1825    chosen_rd = last_part_rd;
1826  }
1827  // If none was better set the partitioning to that...
1828  if (none_rd < chosen_rd) {
1829    if (bsize >= BLOCK_8X8)
1830      *(get_sb_partitioning(x, bsize)) = bsize;
1831    chosen_rate = none_rate;
1832    chosen_dist = none_dist;
1833  }
1834
1835  restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1836
1837  // We must have chosen a partitioning and encoding or we'll fail later on.
1838  // No other opportunities for success.
1839  if ( bsize == BLOCK_64X64)
1840    assert(chosen_rate < INT_MAX && chosen_dist < INT64_MAX);
1841
1842  if (do_recon) {
1843    int output_enabled = (bsize == BLOCK_64X64);
1844
1845    // Check the projected output rate for this SB against it's target
1846    // and and if necessary apply a Q delta using segmentation to get
1847    // closer to the target.
1848    if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
1849      vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
1850                                    output_enabled, chosen_rate);
1851    }
1852
1853    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
1854      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
1855                                              chosen_rate, chosen_dist);
1856
1857    encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
1858  }
1859
1860  *rate = chosen_rate;
1861  *dist = chosen_dist;
1862}
1863
1864static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
1865  BLOCK_4X4,   BLOCK_4X4,   BLOCK_4X4,
1866  BLOCK_4X4,   BLOCK_4X4,   BLOCK_4X4,
1867  BLOCK_8X8,   BLOCK_8X8,   BLOCK_8X8,
1868  BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
1869  BLOCK_16X16
1870};
1871
1872static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
1873  BLOCK_8X8,   BLOCK_16X16, BLOCK_16X16,
1874  BLOCK_16X16, BLOCK_32X32, BLOCK_32X32,
1875  BLOCK_32X32, BLOCK_64X64, BLOCK_64X64,
1876  BLOCK_64X64, BLOCK_64X64, BLOCK_64X64,
1877  BLOCK_64X64
1878};
1879
1880// Look at all the mode_info entries for blocks that are part of this
1881// partition and find the min and max values for sb_type.
1882// At the moment this is designed to work on a 64x64 SB but could be
1883// adjusted to use a size parameter.
1884//
1885// The min and max are assumed to have been initialized prior to calling this
1886// function so repeat calls can accumulate a min and max of more than one sb64.
1887static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8,
1888                                        BLOCK_SIZE * min_block_size,
1889                                        BLOCK_SIZE * max_block_size ) {
1890  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1891  int sb_width_in_blocks = MI_BLOCK_SIZE;
1892  int sb_height_in_blocks  = MI_BLOCK_SIZE;
1893  int i, j;
1894  int index = 0;
1895
1896  // Check the sb_type for each block that belongs to this region.
1897  for (i = 0; i < sb_height_in_blocks; ++i) {
1898    for (j = 0; j < sb_width_in_blocks; ++j) {
1899      MODE_INFO * mi = mi_8x8[index+j];
1900      BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0;
1901      *min_block_size = MIN(*min_block_size, sb_type);
1902      *max_block_size = MAX(*max_block_size, sb_type);
1903    }
1904    index += xd->mi_stride;
1905  }
1906}
1907
1908// Next square block size less or equal than current block size.
1909static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
1910  BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
1911  BLOCK_8X8, BLOCK_8X8, BLOCK_8X8,
1912  BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
1913  BLOCK_32X32, BLOCK_32X32, BLOCK_32X32,
1914  BLOCK_64X64
1915};
1916
1917// Look at neighboring blocks and set a min and max partition size based on
1918// what they chose.
1919static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
1920                                    int mi_row, int mi_col,
1921                                    BLOCK_SIZE *min_block_size,
1922                                    BLOCK_SIZE *max_block_size) {
1923  VP9_COMMON *const cm = &cpi->common;
1924  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1925  MODE_INFO **mi_8x8 = xd->mi;
1926  const int left_in_image = xd->left_available && mi_8x8[-1];
1927  const int above_in_image = xd->up_available &&
1928                             mi_8x8[-xd->mi_stride];
1929  MODE_INFO **above_sb64_mi_8x8;
1930  MODE_INFO **left_sb64_mi_8x8;
1931
1932  int row8x8_remaining = tile->mi_row_end - mi_row;
1933  int col8x8_remaining = tile->mi_col_end - mi_col;
1934  int bh, bw;
1935  BLOCK_SIZE min_size = BLOCK_4X4;
1936  BLOCK_SIZE max_size = BLOCK_64X64;
1937  // Trap case where we do not have a prediction.
1938  if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
1939    // Default "min to max" and "max to min"
1940    min_size = BLOCK_64X64;
1941    max_size = BLOCK_4X4;
1942
1943    // NOTE: each call to get_sb_partition_size_range() uses the previous
1944    // passed in values for min and max as a starting point.
1945    // Find the min and max partition used in previous frame at this location
1946    if (cm->frame_type != KEY_FRAME) {
1947      MODE_INFO **const prev_mi =
1948          &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
1949      get_sb_partition_size_range(cpi, prev_mi, &min_size, &max_size);
1950    }
1951    // Find the min and max partition sizes used in the left SB64
1952    if (left_in_image) {
1953      left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE];
1954      get_sb_partition_size_range(cpi, left_sb64_mi_8x8,
1955                                  &min_size, &max_size);
1956    }
1957    // Find the min and max partition sizes used in the above SB64.
1958    if (above_in_image) {
1959      above_sb64_mi_8x8 = &mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE];
1960      get_sb_partition_size_range(cpi, above_sb64_mi_8x8,
1961                                  &min_size, &max_size);
1962    }
1963    // adjust observed min and max
1964    if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
1965      min_size = min_partition_size[min_size];
1966      max_size = max_partition_size[max_size];
1967    }
1968  }
1969
1970  // Check border cases where max and min from neighbors may not be legal.
1971  max_size = find_partition_size(max_size,
1972                                 row8x8_remaining, col8x8_remaining,
1973                                 &bh, &bw);
1974  min_size = MIN(min_size, max_size);
1975
1976  // When use_square_partition_only is true, make sure at least one square
1977  // partition is allowed by selecting the next smaller square size as
1978  // *min_block_size.
1979  if (cpi->sf.use_square_partition_only &&
1980      next_square_size[max_size] < min_size) {
1981     min_size = next_square_size[max_size];
1982  }
1983  *min_block_size = min_size;
1984  *max_block_size = max_size;
1985}
1986
1987static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
1988  vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
1989}
1990
1991static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
1992  vpx_memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
1993}
1994
1995// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
1996// unlikely to be selected depending on previous rate-distortion optimization
1997// results, for encoding speed-up.
1998static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
1999                              TOKENEXTRA **tp, int mi_row,
2000                              int mi_col, BLOCK_SIZE bsize, int *rate,
2001                              int64_t *dist, int do_recon, int64_t best_rd) {
2002  VP9_COMMON *const cm = &cpi->common;
2003  MACROBLOCK *const x = &cpi->mb;
2004  MACROBLOCKD *const xd = &x->e_mbd;
2005  const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
2006  ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
2007  PARTITION_CONTEXT sl[8], sa[8];
2008  TOKENEXTRA *tp_orig = *tp;
2009  PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
2010  int i, pl;
2011  BLOCK_SIZE subsize;
2012  int this_rate, sum_rate = 0, best_rate = INT_MAX;
2013  int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
2014  int64_t sum_rd = 0;
2015  int do_split = bsize >= BLOCK_8X8;
2016  int do_rect = 1;
2017  // Override skipping rectangular partition operations for edge blocks
2018  const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
2019  const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
2020  const int xss = x->e_mbd.plane[1].subsampling_x;
2021  const int yss = x->e_mbd.plane[1].subsampling_y;
2022
2023  int partition_none_allowed = !force_horz_split && !force_vert_split;
2024  int partition_horz_allowed = !force_vert_split && yss <= xss &&
2025                               bsize >= BLOCK_8X8;
2026  int partition_vert_allowed = !force_horz_split && xss <= yss &&
2027                               bsize >= BLOCK_8X8;
2028  (void) *tp_orig;
2029
2030  if (bsize < BLOCK_8X8) {
2031    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
2032    // there is nothing to be done.
2033    if (x->ab_index != 0) {
2034      *rate = 0;
2035      *dist = 0;
2036      return;
2037    }
2038  }
2039  assert(num_8x8_blocks_wide_lookup[bsize] ==
2040             num_8x8_blocks_high_lookup[bsize]);
2041
2042  if (bsize == BLOCK_16X16) {
2043    set_offsets(cpi, tile, mi_row, mi_col, bsize);
2044    x->mb_energy = vp9_block_energy(cpi, x, bsize);
2045  } else {
2046    x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
2047  }
2048
2049  // Determine partition types in search according to the speed features.
2050  // The threshold set here has to be of square block size.
2051  if (cpi->sf.auto_min_max_partition_size) {
2052    partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
2053                               bsize >= cpi->sf.min_partition_size);
2054    partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2055                                bsize >  cpi->sf.min_partition_size) ||
2056                                force_horz_split);
2057    partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2058                                bsize >  cpi->sf.min_partition_size) ||
2059                                force_vert_split);
2060    do_split &= bsize > cpi->sf.min_partition_size;
2061  }
2062  if (cpi->sf.use_square_partition_only) {
2063    partition_horz_allowed &= force_horz_split;
2064    partition_vert_allowed &= force_vert_split;
2065  }
2066
2067  save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2068
2069  if (cpi->sf.disable_split_var_thresh && partition_none_allowed) {
2070    unsigned int source_variancey;
2071    vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
2072    source_variancey = get_sby_perpixel_variance(cpi, x, bsize);
2073    if (source_variancey < cpi->sf.disable_split_var_thresh) {
2074      do_split = 0;
2075      if (source_variancey < cpi->sf.disable_split_var_thresh / 2)
2076        do_rect = 0;
2077    }
2078  }
2079
2080  if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
2081    do_split = 0;
2082  // PARTITION_NONE
2083  if (partition_none_allowed) {
2084    rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize,
2085                     ctx, best_rd);
2086    if (this_rate != INT_MAX) {
2087      if (bsize >= BLOCK_8X8) {
2088        pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2089        this_rate += x->partition_cost[pl][PARTITION_NONE];
2090      }
2091      sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
2092      if (sum_rd < best_rd) {
2093        int64_t stop_thresh = 4096;
2094        int64_t stop_thresh_rd;
2095
2096        best_rate = this_rate;
2097        best_dist = this_dist;
2098        best_rd = sum_rd;
2099        if (bsize >= BLOCK_8X8)
2100          *(get_sb_partitioning(x, bsize)) = bsize;
2101
2102        // Adjust threshold according to partition size.
2103        stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
2104            b_height_log2_lookup[bsize]);
2105
2106        stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
2107        // If obtained distortion is very small, choose current partition
2108        // and stop splitting.
2109        if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
2110          do_split = 0;
2111          do_rect = 0;
2112        }
2113      }
2114    }
2115    if (!x->in_active_map) {
2116      do_split = 0;
2117      do_rect = 0;
2118    }
2119    restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2120  }
2121
2122  // store estimated motion vector
2123  if (cpi->sf.adaptive_motion_search)
2124    store_pred_mv(x, ctx);
2125
2126  // PARTITION_SPLIT
2127  sum_rd = 0;
2128  // TODO(jingning): use the motion vectors given by the above search as
2129  // the starting point of motion search in the following partition type check.
2130  if (do_split) {
2131    subsize = get_subsize(bsize, PARTITION_SPLIT);
2132    for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
2133      const int x_idx = (i & 1) * mi_step;
2134      const int y_idx = (i >> 1) * mi_step;
2135
2136      if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2137        continue;
2138
2139      *get_sb_index(x, subsize) = i;
2140      if (cpi->sf.adaptive_motion_search)
2141        load_pred_mv(x, ctx);
2142      if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2143          partition_none_allowed)
2144        get_block_context(x, subsize)->pred_interp_filter =
2145            ctx->mic.mbmi.interp_filter;
2146      rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize,
2147                        &this_rate, &this_dist, i != 3, best_rd - sum_rd);
2148
2149      if (this_rate == INT_MAX) {
2150        sum_rd = INT64_MAX;
2151      } else {
2152        sum_rate += this_rate;
2153        sum_dist += this_dist;
2154        sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2155      }
2156    }
2157    if (sum_rd < best_rd && i == 4) {
2158      pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2159      sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
2160      sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2161      if (sum_rd < best_rd) {
2162        best_rate = sum_rate;
2163        best_dist = sum_dist;
2164        best_rd = sum_rd;
2165        *(get_sb_partitioning(x, bsize)) = subsize;
2166      }
2167    } else {
2168      // skip rectangular partition test when larger block size
2169      // gives better rd cost
2170      if (cpi->sf.less_rectangular_check)
2171        do_rect &= !partition_none_allowed;
2172    }
2173    restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2174  }
2175
2176  // PARTITION_HORZ
2177  if (partition_horz_allowed && do_rect) {
2178    subsize = get_subsize(bsize, PARTITION_HORZ);
2179    *get_sb_index(x, subsize) = 0;
2180    if (cpi->sf.adaptive_motion_search)
2181      load_pred_mv(x, ctx);
2182    if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2183        partition_none_allowed)
2184      get_block_context(x, subsize)->pred_interp_filter =
2185          ctx->mic.mbmi.interp_filter;
2186    rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
2187                     get_block_context(x, subsize), best_rd);
2188    sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2189
2190    if (sum_rd < best_rd && mi_row + mi_step < cm->mi_rows) {
2191      update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
2192                   subsize, 0);
2193      encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
2194
2195      *get_sb_index(x, subsize) = 1;
2196      if (cpi->sf.adaptive_motion_search)
2197        load_pred_mv(x, ctx);
2198      if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2199          partition_none_allowed)
2200        get_block_context(x, subsize)->pred_interp_filter =
2201            ctx->mic.mbmi.interp_filter;
2202      rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rate,
2203                       &this_dist, subsize, get_block_context(x, subsize),
2204                       best_rd - sum_rd);
2205      if (this_rate == INT_MAX) {
2206        sum_rd = INT64_MAX;
2207      } else {
2208        sum_rate += this_rate;
2209        sum_dist += this_dist;
2210        sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2211      }
2212    }
2213    if (sum_rd < best_rd) {
2214      pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2215      sum_rate += x->partition_cost[pl][PARTITION_HORZ];
2216      sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2217      if (sum_rd < best_rd) {
2218        best_rd = sum_rd;
2219        best_rate = sum_rate;
2220        best_dist = sum_dist;
2221        *(get_sb_partitioning(x, bsize)) = subsize;
2222      }
2223    }
2224    restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2225  }
2226
2227  // PARTITION_VERT
2228  if (partition_vert_allowed && do_rect) {
2229    subsize = get_subsize(bsize, PARTITION_VERT);
2230
2231    *get_sb_index(x, subsize) = 0;
2232    if (cpi->sf.adaptive_motion_search)
2233      load_pred_mv(x, ctx);
2234    if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2235        partition_none_allowed)
2236      get_block_context(x, subsize)->pred_interp_filter =
2237          ctx->mic.mbmi.interp_filter;
2238    rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
2239                     get_block_context(x, subsize), best_rd);
2240    sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2241    if (sum_rd < best_rd && mi_col + mi_step < cm->mi_cols) {
2242      update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
2243                   subsize, 0);
2244      encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
2245
2246      *get_sb_index(x, subsize) = 1;
2247      if (cpi->sf.adaptive_motion_search)
2248        load_pred_mv(x, ctx);
2249      if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2250          partition_none_allowed)
2251        get_block_context(x, subsize)->pred_interp_filter =
2252            ctx->mic.mbmi.interp_filter;
2253      rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rate,
2254                       &this_dist, subsize, get_block_context(x, subsize),
2255                       best_rd - sum_rd);
2256      if (this_rate == INT_MAX) {
2257        sum_rd = INT64_MAX;
2258      } else {
2259        sum_rate += this_rate;
2260        sum_dist += this_dist;
2261        sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2262      }
2263    }
2264    if (sum_rd < best_rd) {
2265      pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2266      sum_rate += x->partition_cost[pl][PARTITION_VERT];
2267      sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2268      if (sum_rd < best_rd) {
2269        best_rate = sum_rate;
2270        best_dist = sum_dist;
2271        best_rd = sum_rd;
2272        *(get_sb_partitioning(x, bsize)) = subsize;
2273      }
2274    }
2275    restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2276  }
2277
2278  // TODO(jbb): This code added so that we avoid static analysis
2279  // warning related to the fact that best_rd isn't used after this
2280  // point.  This code should be refactored so that the duplicate
2281  // checks occur in some sub function and thus are used...
2282  (void) best_rd;
2283  *rate = best_rate;
2284  *dist = best_dist;
2285
2286  if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
2287    int output_enabled = (bsize == BLOCK_64X64);
2288
2289    // Check the projected output rate for this SB against it's target
2290    // and and if necessary apply a Q delta using segmentation to get
2291    // closer to the target.
2292    if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
2293      vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
2294                                    best_rate);
2295    }
2296
2297    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2298      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
2299                                              best_rate, best_dist);
2300
2301    encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
2302  }
2303  if (bsize == BLOCK_64X64) {
2304    assert(tp_orig < *tp);
2305    assert(best_rate < INT_MAX);
2306    assert(best_dist < INT64_MAX);
2307  } else {
2308    assert(tp_orig == *tp);
2309  }
2310}
2311
2312static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
2313                             int mi_row, TOKENEXTRA **tp) {
2314  VP9_COMMON *const cm = &cpi->common;
2315  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
2316  int mi_col;
2317
2318  // Initialize the left context for the new SB row
2319  vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
2320  vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
2321
2322  // Code each SB in the row
2323  for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
2324       mi_col += MI_BLOCK_SIZE) {
2325    int dummy_rate;
2326    int64_t dummy_dist;
2327
2328    BLOCK_SIZE i;
2329    MACROBLOCK *x = &cpi->mb;
2330
2331    if (cpi->sf.adaptive_pred_interp_filter) {
2332      for (i = BLOCK_4X4; i < BLOCK_8X8; ++i) {
2333        const int num_4x4_w = num_4x4_blocks_wide_lookup[i];
2334        const int num_4x4_h = num_4x4_blocks_high_lookup[i];
2335        const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h);
2336        for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index)
2337          for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index)
2338            for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index)
2339              get_block_context(x, i)->pred_interp_filter = SWITCHABLE;
2340      }
2341    }
2342
2343    vp9_zero(cpi->mb.pred_mv);
2344
2345    if ((cpi->sf.partition_search_type == SEARCH_PARTITION &&
2346         cpi->sf.use_lastframe_partitioning) ||
2347        cpi->sf.partition_search_type == FIXED_PARTITION ||
2348        cpi->sf.partition_search_type == VAR_BASED_PARTITION ||
2349        cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
2350      const int idx_str = cm->mi_stride * mi_row + mi_col;
2351      MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
2352      MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
2353      cpi->mb.source_variance = UINT_MAX;
2354      if (cpi->sf.partition_search_type == FIXED_PARTITION) {
2355        set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2356        set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
2357                               cpi->sf.always_this_block_size);
2358        rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2359                         &dummy_rate, &dummy_dist, 1);
2360      } else if (cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
2361        BLOCK_SIZE bsize;
2362        set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2363        bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
2364        set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
2365        rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2366                         &dummy_rate, &dummy_dist, 1);
2367      } else if (cpi->sf.partition_search_type == VAR_BASED_PARTITION) {
2368        choose_partitioning(cpi, tile, mi_row, mi_col);
2369        rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2370                         &dummy_rate, &dummy_dist, 1);
2371      } else {
2372        if ((cm->current_video_frame
2373            % cpi->sf.last_partitioning_redo_frequency) == 0
2374            || cm->prev_mi == 0
2375            || cm->show_frame == 0
2376            || cm->frame_type == KEY_FRAME
2377            || cpi->rc.is_src_frame_alt_ref
2378            || ((cpi->sf.use_lastframe_partitioning ==
2379                 LAST_FRAME_PARTITION_LOW_MOTION) &&
2380                 sb_has_motion(cm, prev_mi_8x8))) {
2381          // If required set upper and lower partition size limits
2382          if (cpi->sf.auto_min_max_partition_size) {
2383            set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2384            rd_auto_partition_range(cpi, tile, mi_row, mi_col,
2385                                    &cpi->sf.min_partition_size,
2386                                    &cpi->sf.max_partition_size);
2387          }
2388          rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
2389                            &dummy_rate, &dummy_dist, 1, INT64_MAX);
2390        } else {
2391          copy_partitioning(cm, mi_8x8, prev_mi_8x8);
2392          rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2393                           &dummy_rate, &dummy_dist, 1);
2394        }
2395      }
2396    } else {
2397      // If required set upper and lower partition size limits
2398      if (cpi->sf.auto_min_max_partition_size) {
2399        set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2400        rd_auto_partition_range(cpi, tile, mi_row, mi_col,
2401                                &cpi->sf.min_partition_size,
2402                                &cpi->sf.max_partition_size);
2403      }
2404      rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
2405                        &dummy_rate, &dummy_dist, 1, INT64_MAX);
2406    }
2407  }
2408}
2409
2410static void init_encode_frame_mb_context(VP9_COMP *cpi) {
2411  MACROBLOCK *const x = &cpi->mb;
2412  VP9_COMMON *const cm = &cpi->common;
2413  MACROBLOCKD *const xd = &x->e_mbd;
2414  const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
2415
2416  x->act_zbin_adj = 0;
2417  cpi->seg0_idx = 0;
2418
2419  // Copy data over into macro block data structures.
2420  vp9_setup_src_planes(x, cpi->Source, 0, 0);
2421
2422  // TODO(jkoleszar): are these initializations required?
2423  vp9_setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0,
2424                       NULL);
2425  vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0);
2426
2427  vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
2428
2429  xd->mi[0]->mbmi.mode = DC_PRED;
2430  xd->mi[0]->mbmi.uv_mode = DC_PRED;
2431
2432  // Note: this memset assumes above_context[0], [1] and [2]
2433  // are allocated as part of the same buffer.
2434  vpx_memset(xd->above_context[0], 0,
2435             sizeof(*xd->above_context[0]) *
2436             2 * aligned_mi_cols * MAX_MB_PLANE);
2437  vpx_memset(xd->above_seg_context, 0,
2438             sizeof(*xd->above_seg_context) * aligned_mi_cols);
2439}
2440
2441static void switch_lossless_mode(VP9_COMP *cpi, int lossless) {
2442  if (lossless) {
2443    // printf("Switching to lossless\n");
2444    cpi->mb.fwd_txm4x4 = vp9_fwht4x4;
2445    cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add;
2446    cpi->mb.optimize = 0;
2447    cpi->common.lf.filter_level = 0;
2448    cpi->zbin_mode_boost_enabled = 0;
2449    cpi->common.tx_mode = ONLY_4X4;
2450  } else {
2451    // printf("Not lossless\n");
2452    cpi->mb.fwd_txm4x4 = vp9_fdct4x4;
2453    cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add;
2454  }
2455}
2456
2457static int check_dual_ref_flags(VP9_COMP *cpi) {
2458  const int ref_flags = cpi->ref_frame_flags;
2459
2460  if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
2461    return 0;
2462  } else {
2463    return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG)
2464        + !!(ref_flags & VP9_ALT_FLAG)) >= 2;
2465  }
2466}
2467
2468static int get_skip_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs) {
2469  int x, y;
2470
2471  for (y = 0; y < ymbs; y++) {
2472    for (x = 0; x < xmbs; x++) {
2473      if (!mi_8x8[y * mis + x]->mbmi.skip)
2474        return 0;
2475    }
2476  }
2477
2478  return 1;
2479}
2480
2481static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) {
2482  int mi_row, mi_col;
2483  const int mis = cm->mi_stride;
2484  MODE_INFO **mi_ptr = cm->mi_grid_visible;
2485
2486  for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
2487    for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
2488      if (mi_ptr[mi_col]->mbmi.tx_size > txfm_max)
2489        mi_ptr[mi_col]->mbmi.tx_size = txfm_max;
2490    }
2491  }
2492}
2493
2494static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
2495  if (frame_is_intra_only(&cpi->common))
2496    return INTRA_FRAME;
2497  else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
2498    return ALTREF_FRAME;
2499  else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
2500    return LAST_FRAME;
2501  else
2502    return GOLDEN_FRAME;
2503}
2504
2505static TX_MODE select_tx_mode(const VP9_COMP *cpi) {
2506  if (cpi->oxcf.lossless) {
2507    return ONLY_4X4;
2508  } else if (cpi->common.current_video_frame == 0) {
2509    return TX_MODE_SELECT;
2510  } else {
2511    if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
2512      return ALLOW_32X32;
2513    } else if (cpi->sf.tx_size_search_method == USE_FULL_RD) {
2514      const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
2515      return cpi->rd_tx_select_threshes[frame_type][ALLOW_32X32] >
2516                 cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ?
2517                     ALLOW_32X32 : TX_MODE_SELECT;
2518    } else {
2519      unsigned int total = 0;
2520      int i;
2521      for (i = 0; i < TX_SIZES; ++i)
2522        total += cpi->tx_stepdown_count[i];
2523
2524      if (total) {
2525        const double fraction = (double)cpi->tx_stepdown_count[0] / total;
2526        return fraction > 0.90 ? ALLOW_32X32 : TX_MODE_SELECT;
2527      } else {
2528        return cpi->common.tx_mode;
2529      }
2530    }
2531  }
2532}
2533
2534// Start RTC Exploration
2535typedef enum {
2536  BOTH_ZERO = 0,
2537  ZERO_PLUS_PREDICTED = 1,
2538  BOTH_PREDICTED = 2,
2539  NEW_PLUS_NON_INTRA = 3,
2540  BOTH_NEW = 4,
2541  INTRA_PLUS_NON_INTRA = 5,
2542  BOTH_INTRA = 6,
2543  INVALID_CASE = 9
2544} motion_vector_context;
2545
2546static void set_mode_info(MB_MODE_INFO *mbmi, BLOCK_SIZE bsize,
2547                          MB_PREDICTION_MODE mode) {
2548  mbmi->mode = mode;
2549  mbmi->uv_mode = mode;
2550  mbmi->mv[0].as_int = 0;
2551  mbmi->mv[1].as_int = 0;
2552  mbmi->ref_frame[0] = INTRA_FRAME;
2553  mbmi->ref_frame[1] = NONE;
2554  mbmi->tx_size = max_txsize_lookup[bsize];
2555  mbmi->skip = 0;
2556  mbmi->sb_type = bsize;
2557  mbmi->segment_id = 0;
2558}
2559
2560static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
2561                                int mi_row, int mi_col,
2562                                int *rate, int64_t *dist,
2563                                BLOCK_SIZE bsize) {
2564  VP9_COMMON *const cm = &cpi->common;
2565  MACROBLOCK *const x = &cpi->mb;
2566  MACROBLOCKD *const xd = &x->e_mbd;
2567  set_offsets(cpi, tile, mi_row, mi_col, bsize);
2568  xd->mi[0]->mbmi.sb_type = bsize;
2569
2570  if (!frame_is_intra_only(cm)) {
2571    vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col,
2572                        rate, dist, bsize);
2573  } else {
2574    MB_PREDICTION_MODE intramode = DC_PRED;
2575    set_mode_info(&xd->mi[0]->mbmi, bsize, intramode);
2576  }
2577  duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2578}
2579
2580static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
2581                              int mi_row, int mi_col,
2582                              BLOCK_SIZE bsize, BLOCK_SIZE subsize) {
2583  MACROBLOCKD *xd = &x->e_mbd;
2584  int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
2585  PARTITION_TYPE partition = partition_lookup[bsl][subsize];
2586
2587  assert(bsize >= BLOCK_8X8);
2588
2589  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
2590    return;
2591
2592  switch (partition) {
2593    case PARTITION_NONE:
2594      set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2595      *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2596      duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2597      break;
2598    case PARTITION_VERT:
2599      *get_sb_index(x, subsize) = 0;
2600      set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2601      *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2602      duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2603
2604      if (mi_col + hbs < cm->mi_cols) {
2605        *get_sb_index(x, subsize) = 1;
2606        set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs);
2607        *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2608        duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize);
2609      }
2610      break;
2611    case PARTITION_HORZ:
2612      *get_sb_index(x, subsize) = 0;
2613      set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2614      *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2615      duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2616      if (mi_row + hbs < cm->mi_rows) {
2617        *get_sb_index(x, subsize) = 1;
2618        set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col);
2619        *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2620        duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize);
2621      }
2622      break;
2623    case PARTITION_SPLIT:
2624      *get_sb_index(x, subsize) = 0;
2625      fill_mode_info_sb(cm, x, mi_row, mi_col, subsize,
2626                        *(get_sb_partitioning(x, subsize)));
2627      *get_sb_index(x, subsize) = 1;
2628      fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize,
2629                        *(get_sb_partitioning(x, subsize)));
2630      *get_sb_index(x, subsize) = 2;
2631      fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize,
2632                        *(get_sb_partitioning(x, subsize)));
2633      *get_sb_index(x, subsize) = 3;
2634      fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize,
2635                        *(get_sb_partitioning(x, subsize)));
2636      break;
2637    default:
2638      break;
2639  }
2640}
2641
2642static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
2643                                 TOKENEXTRA **tp, int mi_row,
2644                                 int mi_col, BLOCK_SIZE bsize, int *rate,
2645                                 int64_t *dist, int do_recon, int64_t best_rd) {
2646  VP9_COMMON *const cm = &cpi->common;
2647  MACROBLOCK *const x = &cpi->mb;
2648  MACROBLOCKD *const xd = &x->e_mbd;
2649  const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
2650  TOKENEXTRA *tp_orig = *tp;
2651  PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
2652  int i;
2653  BLOCK_SIZE subsize;
2654  int this_rate, sum_rate = 0, best_rate = INT_MAX;
2655  int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
2656  int64_t sum_rd = 0;
2657  int do_split = bsize >= BLOCK_8X8;
2658  int do_rect = 1;
2659  // Override skipping rectangular partition operations for edge blocks
2660  const int force_horz_split = (mi_row + ms >= cm->mi_rows);
2661  const int force_vert_split = (mi_col + ms >= cm->mi_cols);
2662  const int xss = x->e_mbd.plane[1].subsampling_x;
2663  const int yss = x->e_mbd.plane[1].subsampling_y;
2664
2665  int partition_none_allowed = !force_horz_split && !force_vert_split;
2666  int partition_horz_allowed = !force_vert_split && yss <= xss &&
2667                               bsize >= BLOCK_8X8;
2668  int partition_vert_allowed = !force_horz_split && xss <= yss &&
2669                               bsize >= BLOCK_8X8;
2670  (void) *tp_orig;
2671
2672  if (bsize < BLOCK_8X8) {
2673    // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
2674    // there is nothing to be done.
2675    if (x->ab_index != 0) {
2676      *rate = 0;
2677      *dist = 0;
2678      return;
2679    }
2680  }
2681
2682  assert(num_8x8_blocks_wide_lookup[bsize] ==
2683             num_8x8_blocks_high_lookup[bsize]);
2684
2685  x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
2686
2687  // Determine partition types in search according to the speed features.
2688  // The threshold set here has to be of square block size.
2689  if (cpi->sf.auto_min_max_partition_size) {
2690    partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
2691                               bsize >= cpi->sf.min_partition_size);
2692    partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2693                                bsize >  cpi->sf.min_partition_size) ||
2694                                force_horz_split);
2695    partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2696                                bsize >  cpi->sf.min_partition_size) ||
2697                                force_vert_split);
2698    do_split &= bsize > cpi->sf.min_partition_size;
2699  }
2700  if (cpi->sf.use_square_partition_only) {
2701    partition_horz_allowed &= force_horz_split;
2702    partition_vert_allowed &= force_vert_split;
2703  }
2704
2705  if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
2706    do_split = 0;
2707
2708  // PARTITION_NONE
2709  if (partition_none_allowed) {
2710    nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2711                        &this_rate, &this_dist, bsize);
2712    ctx->mic.mbmi = xd->mi[0]->mbmi;
2713
2714    if (this_rate != INT_MAX) {
2715      int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2716      this_rate += x->partition_cost[pl][PARTITION_NONE];
2717      sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
2718      if (sum_rd < best_rd) {
2719        int64_t stop_thresh = 4096;
2720        int64_t stop_thresh_rd;
2721
2722        best_rate = this_rate;
2723        best_dist = this_dist;
2724        best_rd = sum_rd;
2725        if (bsize >= BLOCK_8X8)
2726          *(get_sb_partitioning(x, bsize)) = bsize;
2727
2728        // Adjust threshold according to partition size.
2729        stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
2730            b_height_log2_lookup[bsize]);
2731
2732        stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
2733        // If obtained distortion is very small, choose current partition
2734        // and stop splitting.
2735        if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
2736          do_split = 0;
2737          do_rect = 0;
2738        }
2739      }
2740    }
2741    if (!x->in_active_map) {
2742      do_split = 0;
2743      do_rect = 0;
2744    }
2745  }
2746
2747  // store estimated motion vector
2748  store_pred_mv(x, ctx);
2749
2750  // PARTITION_SPLIT
2751  sum_rd = 0;
2752  if (do_split) {
2753    int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2754    sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
2755    subsize = get_subsize(bsize, PARTITION_SPLIT);
2756    for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
2757      const int x_idx = (i & 1) * ms;
2758      const int y_idx = (i >> 1) * ms;
2759
2760      if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2761        continue;
2762
2763      *get_sb_index(x, subsize) = i;
2764      load_pred_mv(x, ctx);
2765
2766      nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
2767                           subsize, &this_rate, &this_dist, 0,
2768                           best_rd - sum_rd);
2769
2770      if (this_rate == INT_MAX) {
2771        sum_rd = INT64_MAX;
2772      } else {
2773        sum_rate += this_rate;
2774        sum_dist += this_dist;
2775        sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2776      }
2777    }
2778
2779    if (sum_rd < best_rd) {
2780      best_rate = sum_rate;
2781      best_dist = sum_dist;
2782      best_rd = sum_rd;
2783      *(get_sb_partitioning(x, bsize)) = subsize;
2784    } else {
2785      // skip rectangular partition test when larger block size
2786      // gives better rd cost
2787      if (cpi->sf.less_rectangular_check)
2788        do_rect &= !partition_none_allowed;
2789    }
2790  }
2791
2792  // PARTITION_HORZ
2793  if (partition_horz_allowed && do_rect) {
2794    subsize = get_subsize(bsize, PARTITION_HORZ);
2795    *get_sb_index(x, subsize) = 0;
2796    if (cpi->sf.adaptive_motion_search)
2797      load_pred_mv(x, ctx);
2798
2799    nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2800                        &this_rate, &this_dist, subsize);
2801
2802    get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2803
2804    sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2805
2806    if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
2807      *get_sb_index(x, subsize) = 1;
2808
2809      load_pred_mv(x, ctx);
2810
2811      nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col,
2812                          &this_rate, &this_dist, subsize);
2813
2814      get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2815
2816      if (this_rate == INT_MAX) {
2817        sum_rd = INT64_MAX;
2818      } else {
2819        int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2820        this_rate += x->partition_cost[pl][PARTITION_HORZ];
2821        sum_rate += this_rate;
2822        sum_dist += this_dist;
2823        sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2824      }
2825    }
2826    if (sum_rd < best_rd) {
2827      best_rd = sum_rd;
2828      best_rate = sum_rate;
2829      best_dist = sum_dist;
2830      *(get_sb_partitioning(x, bsize)) = subsize;
2831    }
2832  }
2833
2834  // PARTITION_VERT
2835  if (partition_vert_allowed && do_rect) {
2836    subsize = get_subsize(bsize, PARTITION_VERT);
2837
2838    *get_sb_index(x, subsize) = 0;
2839    if (cpi->sf.adaptive_motion_search)
2840      load_pred_mv(x, ctx);
2841
2842    nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2843                        &this_rate, &this_dist, subsize);
2844    get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2845    sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2846    if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
2847      *get_sb_index(x, subsize) = 1;
2848
2849      load_pred_mv(x, ctx);
2850
2851      nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms,
2852                          &this_rate, &this_dist, subsize);
2853
2854      get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2855
2856      if (this_rate == INT_MAX) {
2857        sum_rd = INT64_MAX;
2858      } else {
2859        int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2860        this_rate += x->partition_cost[pl][PARTITION_VERT];
2861        sum_rate += this_rate;
2862        sum_dist += this_dist;
2863        sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2864      }
2865    }
2866    if (sum_rd < best_rd) {
2867      best_rate = sum_rate;
2868      best_dist = sum_dist;
2869      best_rd = sum_rd;
2870      *(get_sb_partitioning(x, bsize)) = subsize;
2871    }
2872  }
2873
2874  *rate = best_rate;
2875  *dist = best_dist;
2876
2877  if (best_rate == INT_MAX)
2878    return;
2879
2880  // update mode info array
2881  fill_mode_info_sb(cm, x, mi_row, mi_col, bsize,
2882                    *(get_sb_partitioning(x, bsize)));
2883
2884  if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
2885    int output_enabled = (bsize == BLOCK_64X64);
2886
2887    // Check the projected output rate for this SB against it's target
2888    // and and if necessary apply a Q delta using segmentation to get
2889    // closer to the target.
2890    if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
2891      vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
2892                                    best_rate);
2893    }
2894
2895    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2896      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
2897                                              best_rate, best_dist);
2898
2899    encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
2900  }
2901
2902  if (bsize == BLOCK_64X64) {
2903    assert(tp_orig < *tp);
2904    assert(best_rate < INT_MAX);
2905    assert(best_dist < INT64_MAX);
2906  } else {
2907    assert(tp_orig == *tp);
2908  }
2909}
2910
2911static void nonrd_use_partition(VP9_COMP *cpi,
2912                                const TileInfo *const tile,
2913                                MODE_INFO **mi_8x8,
2914                                TOKENEXTRA **tp,
2915                                int mi_row, int mi_col,
2916                                BLOCK_SIZE bsize, int output_enabled,
2917                                int *totrate, int64_t *totdist) {
2918  VP9_COMMON *const cm = &cpi->common;
2919  MACROBLOCK *const x = &cpi->mb;
2920  MACROBLOCKD *const xd = &x->e_mbd;
2921  const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
2922  const int mis = cm->mi_stride;
2923  PARTITION_TYPE partition;
2924  BLOCK_SIZE subsize;
2925  int rate = INT_MAX;
2926  int64_t dist = INT64_MAX;
2927
2928  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
2929    return;
2930
2931  if (bsize >= BLOCK_8X8) {
2932    subsize = mi_8x8[0]->mbmi.sb_type;
2933  } else {
2934    subsize = BLOCK_4X4;
2935  }
2936
2937  partition = partition_lookup[bsl][subsize];
2938
2939  switch (partition) {
2940    case PARTITION_NONE:
2941      nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
2942      get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2943      break;
2944    case PARTITION_VERT:
2945      *get_sb_index(x, subsize) = 0;
2946      nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
2947      get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2948      if (mi_col + hbs < cm->mi_cols) {
2949        *get_sb_index(x, subsize) = 1;
2950        nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
2951                            &rate, &dist, subsize);
2952        get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2953        if (rate != INT_MAX && dist != INT64_MAX &&
2954            *totrate != INT_MAX && *totdist != INT64_MAX) {
2955          *totrate += rate;
2956          *totdist += dist;
2957        }
2958      }
2959      break;
2960    case PARTITION_HORZ:
2961      *get_sb_index(x, subsize) = 0;
2962      nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
2963      get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2964      if (mi_row + hbs < cm->mi_rows) {
2965        *get_sb_index(x, subsize) = 1;
2966        nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
2967                            &rate, &dist, subsize);
2968        get_block_context(x, subsize)->mic.mbmi = mi_8x8[0]->mbmi;
2969        if (rate != INT_MAX && dist != INT64_MAX &&
2970            *totrate != INT_MAX && *totdist != INT64_MAX) {
2971          *totrate += rate;
2972          *totdist += dist;
2973        }
2974      }
2975      break;
2976    case PARTITION_SPLIT:
2977      subsize = get_subsize(bsize, PARTITION_SPLIT);
2978      *get_sb_index(x, subsize) = 0;
2979      nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
2980                          subsize, output_enabled, totrate, totdist);
2981      *get_sb_index(x, subsize) = 1;
2982      nonrd_use_partition(cpi, tile, mi_8x8 + hbs, tp,
2983                          mi_row, mi_col + hbs, subsize, output_enabled,
2984                          &rate, &dist);
2985      if (rate != INT_MAX && dist != INT64_MAX &&
2986          *totrate != INT_MAX && *totdist != INT64_MAX) {
2987        *totrate += rate;
2988        *totdist += dist;
2989      }
2990      *get_sb_index(x, subsize) = 2;
2991      nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis, tp,
2992                          mi_row + hbs, mi_col, subsize, output_enabled,
2993                          &rate, &dist);
2994      if (rate != INT_MAX && dist != INT64_MAX &&
2995          *totrate != INT_MAX && *totdist != INT64_MAX) {
2996        *totrate += rate;
2997        *totdist += dist;
2998      }
2999      *get_sb_index(x, subsize) = 3;
3000      nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis + hbs, tp,
3001                          mi_row + hbs, mi_col + hbs, subsize, output_enabled,
3002                          &rate, &dist);
3003      if (rate != INT_MAX && dist != INT64_MAX &&
3004          *totrate != INT_MAX && *totdist != INT64_MAX) {
3005        *totrate += rate;
3006        *totdist += dist;
3007      }
3008      break;
3009    default:
3010      assert("Invalid partition type.");
3011  }
3012
3013  if (bsize == BLOCK_64X64 && output_enabled) {
3014    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
3015      vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
3016                                              *totrate, *totdist);
3017    encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize);
3018  }
3019}
3020
3021static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
3022                                int mi_row, TOKENEXTRA **tp) {
3023  VP9_COMMON *cm = &cpi->common;
3024  MACROBLOCKD *xd = &cpi->mb.e_mbd;
3025  int mi_col;
3026
3027  // Initialize the left context for the new SB row
3028  vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
3029  vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
3030
3031  // Code each SB in the row
3032  for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
3033       mi_col += MI_BLOCK_SIZE) {
3034    int dummy_rate = 0;
3035    int64_t dummy_dist = 0;
3036    const int idx_str = cm->mi_stride * mi_row + mi_col;
3037    MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
3038    MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
3039
3040    BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ?
3041        cpi->sf.always_this_block_size :
3042        get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
3043
3044    cpi->mb.source_variance = UINT_MAX;
3045    vp9_zero(cpi->mb.pred_mv);
3046
3047    // Set the partition type of the 64X64 block
3048    switch (cpi->sf.partition_search_type) {
3049      case VAR_BASED_PARTITION:
3050        choose_partitioning(cpi, tile, mi_row, mi_col);
3051        nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3052                            1, &dummy_rate, &dummy_dist);
3053        break;
3054      case VAR_BASED_FIXED_PARTITION:
3055      case FIXED_PARTITION:
3056        set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
3057        nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3058                            1, &dummy_rate, &dummy_dist);
3059        break;
3060      case REFERENCE_PARTITION:
3061        if (cpi->sf.partition_check || sb_has_motion(cm, prev_mi_8x8)) {
3062          nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
3063                               &dummy_rate, &dummy_dist, 1, INT64_MAX);
3064        } else {
3065          copy_partitioning(cm, mi_8x8, prev_mi_8x8);
3066          nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
3067                              BLOCK_64X64, 1, &dummy_rate, &dummy_dist);
3068        }
3069        break;
3070      default:
3071        assert(0);
3072    }
3073  }
3074}
3075// end RTC play code
3076
3077static void encode_frame_internal(VP9_COMP *cpi) {
3078  int mi_row;
3079  MACROBLOCK *const x = &cpi->mb;
3080  VP9_COMMON *const cm = &cpi->common;
3081  MACROBLOCKD *const xd = &x->e_mbd;
3082
3083//  fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n",
3084//           cpi->common.current_video_frame, cpi->common.show_frame,
3085//           cm->frame_type);
3086
3087  xd->mi = cm->mi_grid_visible;
3088  xd->mi[0] = cm->mi;
3089
3090  vp9_zero(cm->counts);
3091  vp9_zero(cpi->coef_counts);
3092  vp9_zero(cpi->tx_stepdown_count);
3093
3094  // Set frame level transform size use case
3095  cm->tx_mode = select_tx_mode(cpi);
3096
3097  cpi->mb.e_mbd.lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0
3098      && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
3099  switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless);
3100
3101  vp9_frame_init_quantizer(cpi);
3102
3103  vp9_initialize_rd_consts(cpi);
3104  vp9_initialize_me_consts(cpi, cm->base_qindex);
3105
3106  if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3107    // Initialize encode frame context.
3108    init_encode_frame_mb_context(cpi);
3109
3110    // Build a frame level activity map
3111    build_activity_map(cpi);
3112  }
3113
3114  // Re-initialize encode frame context.
3115  init_encode_frame_mb_context(cpi);
3116
3117  vp9_zero(cpi->rd_comp_pred_diff);
3118  vp9_zero(cpi->rd_filter_diff);
3119  vp9_zero(cpi->rd_tx_select_diff);
3120  vp9_zero(cpi->rd_tx_select_threshes);
3121
3122  set_prev_mi(cm);
3123
3124  if (cpi->sf.use_nonrd_pick_mode) {
3125    // Initialize internal buffer pointers for rtc coding, where non-RD
3126    // mode decision is used and hence no buffer pointer swap needed.
3127    int i;
3128    struct macroblock_plane *const p = x->plane;
3129    struct macroblockd_plane *const pd = xd->plane;
3130    PICK_MODE_CONTEXT *ctx = &cpi->mb.sb64_context;
3131
3132    for (i = 0; i < MAX_MB_PLANE; ++i) {
3133      p[i].coeff = ctx->coeff_pbuf[i][0];
3134      p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
3135      pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
3136      p[i].eobs = ctx->eobs_pbuf[i][0];
3137    }
3138    vp9_zero(x->zcoeff_blk);
3139  }
3140
3141  {
3142    struct vpx_usec_timer emr_timer;
3143    vpx_usec_timer_start(&emr_timer);
3144
3145    {
3146      // Take tiles into account and give start/end MB
3147      int tile_col, tile_row;
3148      TOKENEXTRA *tp = cpi->tok;
3149      const int tile_cols = 1 << cm->log2_tile_cols;
3150      const int tile_rows = 1 << cm->log2_tile_rows;
3151
3152      for (tile_row = 0; tile_row < tile_rows; tile_row++) {
3153        for (tile_col = 0; tile_col < tile_cols; tile_col++) {
3154          TileInfo tile;
3155          TOKENEXTRA *tp_old = tp;
3156
3157          // For each row of SBs in the frame
3158          vp9_tile_init(&tile, cm, tile_row, tile_col);
3159          for (mi_row = tile.mi_row_start;
3160               mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) {
3161            if (cpi->sf.use_nonrd_pick_mode && cm->frame_type != KEY_FRAME)
3162              encode_nonrd_sb_row(cpi, &tile, mi_row, &tp);
3163            else
3164              encode_rd_sb_row(cpi, &tile, mi_row, &tp);
3165          }
3166          cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old);
3167          assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols));
3168        }
3169      }
3170    }
3171
3172    vpx_usec_timer_mark(&emr_timer);
3173    cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer);
3174  }
3175
3176  if (cpi->sf.skip_encode_sb) {
3177    int j;
3178    unsigned int intra_count = 0, inter_count = 0;
3179    for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) {
3180      intra_count += cm->counts.intra_inter[j][0];
3181      inter_count += cm->counts.intra_inter[j][1];
3182    }
3183    cpi->sf.skip_encode_frame = (intra_count << 2) < inter_count &&
3184                                cm->frame_type != KEY_FRAME &&
3185                                cm->show_frame;
3186  } else {
3187    cpi->sf.skip_encode_frame = 0;
3188  }
3189
3190#if 0
3191  // Keep record of the total distortion this time around for future use
3192  cpi->last_frame_distortion = cpi->frame_distortion;
3193#endif
3194}
3195
3196void vp9_encode_frame(VP9_COMP *cpi) {
3197  VP9_COMMON *const cm = &cpi->common;
3198
3199  // In the longer term the encoder should be generalized to match the
3200  // decoder such that we allow compound where one of the 3 buffers has a
3201  // different sign bias and that buffer is then the fixed ref. However, this
3202  // requires further work in the rd loop. For now the only supported encoder
3203  // side behavior is where the ALT ref buffer has opposite sign bias to
3204  // the other two.
3205  if (!frame_is_intra_only(cm)) {
3206    if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3207             cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
3208        (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3209             cm->ref_frame_sign_bias[LAST_FRAME])) {
3210      cm->allow_comp_inter_inter = 0;
3211    } else {
3212      cm->allow_comp_inter_inter = 1;
3213      cm->comp_fixed_ref = ALTREF_FRAME;
3214      cm->comp_var_ref[0] = LAST_FRAME;
3215      cm->comp_var_ref[1] = GOLDEN_FRAME;
3216    }
3217  }
3218
3219  if (cpi->sf.frame_parameter_update) {
3220    int i;
3221    REFERENCE_MODE reference_mode;
3222    /*
3223     * This code does a single RD pass over the whole frame assuming
3224     * either compound, single or hybrid prediction as per whatever has
3225     * worked best for that type of frame in the past.
3226     * It also predicts whether another coding mode would have worked
3227     * better that this coding mode. If that is the case, it remembers
3228     * that for subsequent frames.
3229     * It does the same analysis for transform size selection also.
3230     */
3231    const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
3232    const int64_t *mode_thresh = cpi->rd_prediction_type_threshes[frame_type];
3233    const int64_t *filter_thresh = cpi->rd_filter_threshes[frame_type];
3234
3235    /* prediction (compound, single or hybrid) mode selection */
3236    if (frame_type == 3 || !cm->allow_comp_inter_inter)
3237      reference_mode = SINGLE_REFERENCE;
3238    else if (mode_thresh[COMPOUND_REFERENCE] > mode_thresh[SINGLE_REFERENCE] &&
3239             mode_thresh[COMPOUND_REFERENCE] >
3240                 mode_thresh[REFERENCE_MODE_SELECT] &&
3241             check_dual_ref_flags(cpi) &&
3242             cpi->static_mb_pct == 100)
3243      reference_mode = COMPOUND_REFERENCE;
3244    else if (mode_thresh[SINGLE_REFERENCE] > mode_thresh[REFERENCE_MODE_SELECT])
3245      reference_mode = SINGLE_REFERENCE;
3246    else
3247      reference_mode = REFERENCE_MODE_SELECT;
3248
3249    if (cm->interp_filter == SWITCHABLE) {
3250      if (frame_type != ALTREF_FRAME &&
3251          filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP] &&
3252          filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP_SHARP] &&
3253          filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[SWITCHABLE - 1]) {
3254        cm->interp_filter = EIGHTTAP_SMOOTH;
3255      } else if (filter_thresh[EIGHTTAP_SHARP] > filter_thresh[EIGHTTAP] &&
3256          filter_thresh[EIGHTTAP_SHARP] > filter_thresh[SWITCHABLE - 1]) {
3257        cm->interp_filter = EIGHTTAP_SHARP;
3258      } else if (filter_thresh[EIGHTTAP] > filter_thresh[SWITCHABLE - 1]) {
3259        cm->interp_filter = EIGHTTAP;
3260      }
3261    }
3262
3263    cpi->mb.e_mbd.lossless = cpi->oxcf.lossless;
3264    cm->reference_mode = reference_mode;
3265
3266    encode_frame_internal(cpi);
3267
3268    for (i = 0; i < REFERENCE_MODES; ++i) {
3269      const int diff = (int) (cpi->rd_comp_pred_diff[i] / cm->MBs);
3270      cpi->rd_prediction_type_threshes[frame_type][i] += diff;
3271      cpi->rd_prediction_type_threshes[frame_type][i] >>= 1;
3272    }
3273
3274    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
3275      const int64_t diff = cpi->rd_filter_diff[i] / cm->MBs;
3276      cpi->rd_filter_threshes[frame_type][i] =
3277          (cpi->rd_filter_threshes[frame_type][i] + diff) / 2;
3278    }
3279
3280    for (i = 0; i < TX_MODES; ++i) {
3281      int64_t pd = cpi->rd_tx_select_diff[i];
3282      int diff;
3283      if (i == TX_MODE_SELECT)
3284        pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZES - 1), 0);
3285      diff = (int) (pd / cm->MBs);
3286      cpi->rd_tx_select_threshes[frame_type][i] += diff;
3287      cpi->rd_tx_select_threshes[frame_type][i] /= 2;
3288    }
3289
3290    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
3291      int single_count_zero = 0;
3292      int comp_count_zero = 0;
3293
3294      for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
3295        single_count_zero += cm->counts.comp_inter[i][0];
3296        comp_count_zero += cm->counts.comp_inter[i][1];
3297      }
3298
3299      if (comp_count_zero == 0) {
3300        cm->reference_mode = SINGLE_REFERENCE;
3301        vp9_zero(cm->counts.comp_inter);
3302      } else if (single_count_zero == 0) {
3303        cm->reference_mode = COMPOUND_REFERENCE;
3304        vp9_zero(cm->counts.comp_inter);
3305      }
3306    }
3307
3308    if (cm->tx_mode == TX_MODE_SELECT) {
3309      int count4x4 = 0;
3310      int count8x8_lp = 0, count8x8_8x8p = 0;
3311      int count16x16_16x16p = 0, count16x16_lp = 0;
3312      int count32x32 = 0;
3313
3314      for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
3315        count4x4 += cm->counts.tx.p32x32[i][TX_4X4];
3316        count4x4 += cm->counts.tx.p16x16[i][TX_4X4];
3317        count4x4 += cm->counts.tx.p8x8[i][TX_4X4];
3318
3319        count8x8_lp += cm->counts.tx.p32x32[i][TX_8X8];
3320        count8x8_lp += cm->counts.tx.p16x16[i][TX_8X8];
3321        count8x8_8x8p += cm->counts.tx.p8x8[i][TX_8X8];
3322
3323        count16x16_16x16p += cm->counts.tx.p16x16[i][TX_16X16];
3324        count16x16_lp += cm->counts.tx.p32x32[i][TX_16X16];
3325        count32x32 += cm->counts.tx.p32x32[i][TX_32X32];
3326      }
3327
3328      if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
3329          count32x32 == 0) {
3330        cm->tx_mode = ALLOW_8X8;
3331        reset_skip_txfm_size(cm, TX_8X8);
3332      } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
3333                 count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
3334        cm->tx_mode = ONLY_4X4;
3335        reset_skip_txfm_size(cm, TX_4X4);
3336      } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
3337        cm->tx_mode = ALLOW_32X32;
3338      } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
3339        cm->tx_mode = ALLOW_16X16;
3340        reset_skip_txfm_size(cm, TX_16X16);
3341      }
3342    }
3343  } else {
3344    cpi->mb.e_mbd.lossless = cpi->oxcf.lossless;
3345    cm->reference_mode = SINGLE_REFERENCE;
3346    // Force the usage of the BILINEAR interp_filter.
3347    cm->interp_filter = BILINEAR;
3348    encode_frame_internal(cpi);
3349  }
3350}
3351
3352static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
3353  const MB_PREDICTION_MODE y_mode = mi->mbmi.mode;
3354  const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
3355  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
3356
3357  if (bsize < BLOCK_8X8) {
3358    int idx, idy;
3359    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
3360    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
3361    for (idy = 0; idy < 2; idy += num_4x4_h)
3362      for (idx = 0; idx < 2; idx += num_4x4_w)
3363        ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode];
3364  } else {
3365    ++counts->y_mode[size_group_lookup[bsize]][y_mode];
3366  }
3367
3368  ++counts->uv_mode[y_mode][uv_mode];
3369}
3370
3371// Experimental stub function to create a per MB zbin adjustment based on
3372// some previously calculated measure of MB activity.
3373static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) {
3374#if USE_ACT_INDEX
3375  x->act_zbin_adj = *(x->mb_activity_ptr);
3376#else
3377  // Apply the masking to the RD multiplier.
3378  const int64_t act = *(x->mb_activity_ptr);
3379  const int64_t a = act + 4 * cpi->activity_avg;
3380  const int64_t b = 4 * act + cpi->activity_avg;
3381
3382  if (act > cpi->activity_avg)
3383    x->act_zbin_adj = (int) (((int64_t) b + (a >> 1)) / a) - 1;
3384  else
3385    x->act_zbin_adj = 1 - (int) (((int64_t) a + (b >> 1)) / b);
3386#endif
3387}
3388
3389static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) {
3390  if (enabled) {
3391    if (is_inter_block(mbmi)) {
3392      if (mbmi->mode == ZEROMV) {
3393        return mbmi->ref_frame[0] != LAST_FRAME ? GF_ZEROMV_ZBIN_BOOST
3394                                                : LF_ZEROMV_ZBIN_BOOST;
3395      } else {
3396        return mbmi->sb_type < BLOCK_8X8 ? SPLIT_MV_ZBIN_BOOST
3397                                         : MV_ZBIN_BOOST;
3398      }
3399    } else {
3400      return INTRA_ZBIN_BOOST;
3401    }
3402  } else {
3403    return 0;
3404  }
3405}
3406
3407static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
3408                              int mi_row, int mi_col, BLOCK_SIZE bsize) {
3409  VP9_COMMON *const cm = &cpi->common;
3410  MACROBLOCK *const x = &cpi->mb;
3411  MACROBLOCKD *const xd = &x->e_mbd;
3412  MODE_INFO **mi_8x8 = xd->mi;
3413  MODE_INFO *mi = mi_8x8[0];
3414  MB_MODE_INFO *mbmi = &mi->mbmi;
3415  PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
3416  unsigned int segment_id = mbmi->segment_id;
3417  const int mis = cm->mi_stride;
3418  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
3419  const int mi_height = num_8x8_blocks_high_lookup[bsize];
3420
3421  x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 &&
3422                   cpi->oxcf.aq_mode != COMPLEXITY_AQ &&
3423                   cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ &&
3424                   cpi->sf.allow_skip_recode;
3425
3426  x->skip_optimize = ctx->is_coded;
3427  ctx->is_coded = 1;
3428  x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
3429  x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame &&
3430                    x->q_index < QIDX_SKIP_THRESH);
3431
3432  if (x->skip_encode)
3433    return;
3434
3435  if (cm->frame_type == KEY_FRAME) {
3436    if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3437      adjust_act_zbin(cpi, x);
3438      vp9_update_zbin_extra(cpi, x);
3439    }
3440  } else {
3441    set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3442
3443    if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3444      // Adjust the zbin based on this MB rate.
3445      adjust_act_zbin(cpi, x);
3446    }
3447
3448    // Experimental code. Special case for gf and arf zeromv modes.
3449    // Increase zbin size to suppress noise
3450    cpi->zbin_mode_boost = get_zbin_mode_boost(mbmi,
3451                                               cpi->zbin_mode_boost_enabled);
3452    vp9_update_zbin_extra(cpi, x);
3453  }
3454
3455  if (!is_inter_block(mbmi)) {
3456    int plane;
3457    mbmi->skip = 1;
3458    for (plane = 0; plane < MAX_MB_PLANE; ++plane)
3459      vp9_encode_intra_block_plane(x, MAX(bsize, BLOCK_8X8), plane);
3460    if (output_enabled)
3461      sum_intra_stats(&cm->counts, mi);
3462    vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8));
3463  } else {
3464    int ref;
3465    const int is_compound = has_second_ref(mbmi);
3466    for (ref = 0; ref < 1 + is_compound; ++ref) {
3467      YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
3468                                                     mbmi->ref_frame[ref]);
3469      vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
3470                           &xd->block_refs[ref]->sf);
3471    }
3472    vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
3473
3474    if (!x->skip) {
3475      mbmi->skip = 1;
3476      vp9_encode_sb(x, MAX(bsize, BLOCK_8X8));
3477      vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8));
3478    } else {
3479      mbmi->skip = 1;
3480      if (output_enabled)
3481        cm->counts.skip[vp9_get_skip_context(xd)][1]++;
3482      reset_skip_context(xd, MAX(bsize, BLOCK_8X8));
3483    }
3484  }
3485
3486  if (output_enabled) {
3487    if (cm->tx_mode == TX_MODE_SELECT &&
3488        mbmi->sb_type >= BLOCK_8X8  &&
3489        !(is_inter_block(mbmi) &&
3490            (mbmi->skip ||
3491             vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)))) {
3492      ++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
3493                      &cm->counts.tx)[mbmi->tx_size];
3494    } else {
3495      int x, y;
3496      TX_SIZE tx_size;
3497      // The new intra coding scheme requires no change of transform size
3498      if (is_inter_block(&mi->mbmi)) {
3499        tx_size = MIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
3500                      max_txsize_lookup[bsize]);
3501      } else {
3502        tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
3503      }
3504
3505      for (y = 0; y < mi_height; y++)
3506        for (x = 0; x < mi_width; x++)
3507          if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
3508            mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;
3509    }
3510  }
3511}
3512