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