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