Home | History | Annotate | Download | only in encoder
      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 
     51 static 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 
     76 static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
     77                               int mi_row, int mi_col, BLOCK_SIZE bsize);
     78 
     79 static 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.
     94 static 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 
    105 static 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 
    114 static 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 
    130 static 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 
    146 static 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.
    162 static 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 
    171 static 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 
    197 static 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 
    207 static 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 
    284 static 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 
    299 static 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 
    311 typedef struct {
    312   int64_t sum_square_error;
    313   int64_t sum_error;
    314   int count;
    315   int variance;
    316 } var;
    317 
    318 typedef struct {
    319   var none;
    320   var horz[2];
    321   var vert[2];
    322 } partition_variance;
    323 
    324 typedef struct {
    325   partition_variance part_variances;
    326   var split[4];
    327 } v8x8;
    328 
    329 typedef struct {
    330   partition_variance part_variances;
    331   v8x8 split[4];
    332 } v16x16;
    333 
    334 typedef struct {
    335   partition_variance part_variances;
    336   v16x16 split[4];
    337 } v32x32;
    338 
    339 typedef struct {
    340   partition_variance part_variances;
    341   v32x32 split[4];
    342 } v64x64;
    343 
    344 typedef struct {
    345   partition_variance *part_variances;
    346   var *split[4];
    347 } variance_node;
    348 
    349 typedef enum {
    350   V16X16,
    351   V32X32,
    352   V64X64,
    353 } TREE_LEVEL;
    354 
    355 static 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.
    393 static 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 
    405 void 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 
    410 static 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 
    421 static 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.
    471 static 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.
    603 static 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.
    619 static 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
    626 static 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
    644 static 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
    701 static 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
    753 static 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
    815 static 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 
    836 static 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 
    968 void 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 
    985 static 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 
   1101 static 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 
   1142 static 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 
   1158 static 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 }
   1188 static 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 
   1221 static 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 
   1245 static 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
   1322 static 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.
   1344 static 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 
   1384 static 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 
   1403 static 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 
   1422 static 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 
   1452 static 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 
   1474 static 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 
   1555 static 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 
   1864 static 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 
   1872 static 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.
   1887 static 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.
   1909 static 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.
   1919 static 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 
   1987 static 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 
   1991 static 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.
   1998 static 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 
   2312 static 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 
   2410 static 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 
   2441 static 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 
   2457 static 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 
   2468 static 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 
   2481 static 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 
   2494 static 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 
   2505 static 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
   2535 typedef 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 
   2546 static 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 
   2560 static 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 
   2580 static 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 
   2642 static 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 
   2911 static 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 
   3021 static 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 
   3077 static 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 
   3196 void 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 
   3352 static 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.
   3373 static 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 
   3389 static 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 
   3407 static 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