]> granicus.if.org Git - libvpx/blob - vp9/encoder/vp9_encodeframe.c
Experimental rd bias based on source vs recon variance.
[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_ethread.h"
40 #include "vp9/encoder/vp9_extend.h"
41 #include "vp9/encoder/vp9_pickmode.h"
42 #include "vp9/encoder/vp9_rd.h"
43 #include "vp9/encoder/vp9_rdopt.h"
44 #include "vp9/encoder/vp9_segmentation.h"
45 #include "vp9/encoder/vp9_tokenize.h"
46
47 static void encode_superblock(VP9_COMP *cpi, ThreadData * td,
48                               TOKENEXTRA **t, int output_enabled,
49                               int mi_row, int mi_col, BLOCK_SIZE bsize,
50                               PICK_MODE_CONTEXT *ctx);
51
52 // This is used as a reference when computing the source variance for the
53 //  purposes of activity masking.
54 // Eventually this should be replaced by custom no-reference routines,
55 //  which will be faster.
56 static const uint8_t VP9_VAR_OFFS[64] = {
57     128, 128, 128, 128, 128, 128, 128, 128,
58     128, 128, 128, 128, 128, 128, 128, 128,
59     128, 128, 128, 128, 128, 128, 128, 128,
60     128, 128, 128, 128, 128, 128, 128, 128,
61     128, 128, 128, 128, 128, 128, 128, 128,
62     128, 128, 128, 128, 128, 128, 128, 128,
63     128, 128, 128, 128, 128, 128, 128, 128,
64     128, 128, 128, 128, 128, 128, 128, 128
65 };
66
67 #if CONFIG_VP9_HIGHBITDEPTH
68 static const uint16_t VP9_HIGH_VAR_OFFS_8[64] = {
69     128, 128, 128, 128, 128, 128, 128, 128,
70     128, 128, 128, 128, 128, 128, 128, 128,
71     128, 128, 128, 128, 128, 128, 128, 128,
72     128, 128, 128, 128, 128, 128, 128, 128,
73     128, 128, 128, 128, 128, 128, 128, 128,
74     128, 128, 128, 128, 128, 128, 128, 128,
75     128, 128, 128, 128, 128, 128, 128, 128,
76     128, 128, 128, 128, 128, 128, 128, 128
77 };
78
79 static const uint16_t VP9_HIGH_VAR_OFFS_10[64] = {
80     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
81     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
82     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
83     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
84     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
85     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
86     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4,
87     128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4, 128*4
88 };
89
90 static const uint16_t VP9_HIGH_VAR_OFFS_12[64] = {
91     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
92     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
93     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
94     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
95     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
96     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
97     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16,
98     128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16, 128*16
99 };
100 #endif  // CONFIG_VP9_HIGHBITDEPTH
101
102 unsigned int vp9_get_sby_perpixel_variance(VP9_COMP *cpi,
103                                            const struct buf_2d *ref,
104                                            BLOCK_SIZE bs) {
105   unsigned int sse;
106   const unsigned int var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
107                                               VP9_VAR_OFFS, 0, &sse);
108   return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
109 }
110
111 #if CONFIG_VP9_HIGHBITDEPTH
112 unsigned int vp9_high_get_sby_perpixel_variance(
113     VP9_COMP *cpi, const struct buf_2d *ref, BLOCK_SIZE bs, int bd) {
114   unsigned int var, sse;
115   switch (bd) {
116     case 10:
117       var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
118                                CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_10),
119                                0, &sse);
120       break;
121     case 12:
122       var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
123                                CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_12),
124                                0, &sse);
125       break;
126     case 8:
127     default:
128       var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
129                                CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_8),
130                                0, &sse);
131       break;
132   }
133   return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
134 }
135 #endif  // CONFIG_VP9_HIGHBITDEPTH
136
137 static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi,
138                                                    const struct buf_2d *ref,
139                                                    int mi_row, int mi_col,
140                                                    BLOCK_SIZE bs) {
141   unsigned int sse, var;
142   uint8_t *last_y;
143   const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
144
145   assert(last != NULL);
146   last_y =
147       &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
148   var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
149   return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
150 }
151
152 static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi, MACROBLOCK *x,
153                                                    int mi_row,
154                                                    int mi_col) {
155   unsigned int var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src,
156                                                     mi_row, mi_col,
157                                                     BLOCK_64X64);
158   if (var < 8)
159     return BLOCK_64X64;
160   else if (var < 128)
161     return BLOCK_32X32;
162   else if (var < 2048)
163     return BLOCK_16X16;
164   else
165     return BLOCK_8X8;
166 }
167
168 static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi,
169                                                       MACROBLOCK *x,
170                                                       int mi_row,
171                                                       int mi_col) {
172   unsigned int var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src,
173                                                     mi_row, mi_col,
174                                                     BLOCK_64X64);
175   if (var < 4)
176     return BLOCK_64X64;
177   else if (var < 10)
178     return BLOCK_32X32;
179   else
180     return BLOCK_16X16;
181 }
182
183 // Lighter version of set_offsets that only sets the mode info
184 // pointers.
185 static INLINE void set_mode_info_offsets(VP9_COMMON *const cm,
186                                          MACROBLOCKD *const xd,
187                                          int mi_row,
188                                          int mi_col) {
189   const int idx_str = xd->mi_stride * mi_row + mi_col;
190   xd->mi = cm->mi + idx_str;
191   xd->mi[0].src_mi = &xd->mi[0];
192 }
193
194 static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
195                         MACROBLOCK *const x, int mi_row, int mi_col,
196                         BLOCK_SIZE bsize) {
197   VP9_COMMON *const cm = &cpi->common;
198   MACROBLOCKD *const xd = &x->e_mbd;
199   MB_MODE_INFO *mbmi;
200   const int mi_width = num_8x8_blocks_wide_lookup[bsize];
201   const int mi_height = num_8x8_blocks_high_lookup[bsize];
202   const struct segmentation *const seg = &cm->seg;
203
204   set_skip_context(xd, mi_row, mi_col);
205
206   set_mode_info_offsets(cm, xd, mi_row, mi_col);
207
208   mbmi = &xd->mi[0].src_mi->mbmi;
209
210   // Set up destination pointers.
211   vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
212
213   // Set up limit values for MV components.
214   // Mv beyond the range do not produce new/different prediction block.
215   x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
216   x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
217   x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
218   x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
219
220   // Set up distance of MB to edge of frame in 1/8th pel units.
221   assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
222   set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
223                  cm->mi_rows, cm->mi_cols);
224
225   // Set up source buffers.
226   vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
227
228   // R/D setup.
229   x->rddiv = cpi->rd.RDDIV;
230   x->rdmult = cpi->rd.RDMULT;
231
232   // Setup segment ID.
233   if (seg->enabled) {
234     if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
235       const uint8_t *const map = seg->update_map ? cpi->segmentation_map
236                                                  : cm->last_frame_seg_map;
237       mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
238     }
239     vp9_init_plane_quantizers(cpi, x);
240
241     x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
242   } else {
243     mbmi->segment_id = 0;
244     x->encode_breakout = cpi->encode_breakout;
245   }
246 }
247
248 static void duplicate_mode_info_in_sb(VP9_COMMON *cm, MACROBLOCKD *xd,
249                                       int mi_row, int mi_col,
250                                       BLOCK_SIZE bsize) {
251   const int block_width = num_8x8_blocks_wide_lookup[bsize];
252   const int block_height = num_8x8_blocks_high_lookup[bsize];
253   int i, j;
254   for (j = 0; j < block_height; ++j)
255     for (i = 0; i < block_width; ++i) {
256       if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols)
257         xd->mi[j * xd->mi_stride + i].src_mi = &xd->mi[0];
258     }
259 }
260
261 static void set_block_size(VP9_COMP * const cpi,
262                            MACROBLOCKD *const xd,
263                            int mi_row, int mi_col,
264                            BLOCK_SIZE bsize) {
265   if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
266     set_mode_info_offsets(&cpi->common, xd, mi_row, mi_col);
267     xd->mi[0].src_mi->mbmi.sb_type = bsize;
268   }
269 }
270
271 typedef struct {
272   int64_t sum_square_error;
273   int64_t sum_error;
274   int log2_count;
275   int variance;
276 } var;
277
278 typedef struct {
279   var none;
280   var horz[2];
281   var vert[2];
282 } partition_variance;
283
284 typedef struct {
285   partition_variance part_variances;
286   var split[4];
287 } v4x4;
288
289 typedef struct {
290   partition_variance part_variances;
291   v4x4 split[4];
292 } v8x8;
293
294 typedef struct {
295   partition_variance part_variances;
296   v8x8 split[4];
297 } v16x16;
298
299 typedef struct {
300   partition_variance part_variances;
301   v16x16 split[4];
302 } v32x32;
303
304 typedef struct {
305   partition_variance part_variances;
306   v32x32 split[4];
307 } v64x64;
308
309 typedef struct {
310   partition_variance *part_variances;
311   var *split[4];
312 } variance_node;
313
314 typedef enum {
315   V16X16,
316   V32X32,
317   V64X64,
318 } TREE_LEVEL;
319
320 static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
321   int i;
322   node->part_variances = NULL;
323   switch (bsize) {
324     case BLOCK_64X64: {
325       v64x64 *vt = (v64x64 *) data;
326       node->part_variances = &vt->part_variances;
327       for (i = 0; i < 4; i++)
328         node->split[i] = &vt->split[i].part_variances.none;
329       break;
330     }
331     case BLOCK_32X32: {
332       v32x32 *vt = (v32x32 *) data;
333       node->part_variances = &vt->part_variances;
334       for (i = 0; i < 4; i++)
335         node->split[i] = &vt->split[i].part_variances.none;
336       break;
337     }
338     case BLOCK_16X16: {
339       v16x16 *vt = (v16x16 *) data;
340       node->part_variances = &vt->part_variances;
341       for (i = 0; i < 4; i++)
342         node->split[i] = &vt->split[i].part_variances.none;
343       break;
344     }
345     case BLOCK_8X8: {
346       v8x8 *vt = (v8x8 *) data;
347       node->part_variances = &vt->part_variances;
348       for (i = 0; i < 4; i++)
349         node->split[i] = &vt->split[i].part_variances.none;
350       break;
351     }
352     case BLOCK_4X4: {
353       v4x4 *vt = (v4x4 *) data;
354       node->part_variances = &vt->part_variances;
355       for (i = 0; i < 4; i++)
356         node->split[i] = &vt->split[i];
357       break;
358     }
359     default: {
360       assert(0);
361       break;
362     }
363   }
364 }
365
366 // Set variance values given sum square error, sum error, count.
367 static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
368   v->sum_square_error = s2;
369   v->sum_error = s;
370   v->log2_count = c;
371 }
372
373 static void get_variance(var *v) {
374   v->variance = (int)(256 * (v->sum_square_error -
375       ((v->sum_error * v->sum_error) >> v->log2_count)) >> v->log2_count);
376 }
377
378 void sum_2_variances(const var *a, const var *b, var *r) {
379   assert(a->log2_count == b->log2_count);
380   fill_variance(a->sum_square_error + b->sum_square_error,
381                 a->sum_error + b->sum_error, a->log2_count + 1, r);
382 }
383
384 static void fill_variance_tree(void *data, BLOCK_SIZE bsize) {
385   variance_node node;
386   tree_to_node(data, bsize, &node);
387   sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]);
388   sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]);
389   sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]);
390   sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]);
391   sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1],
392                   &node.part_variances->none);
393 }
394
395 static int set_vt_partitioning(VP9_COMP *cpi,
396                                MACROBLOCKD *const xd,
397                                void *data,
398                                BLOCK_SIZE bsize,
399                                int mi_row,
400                                int mi_col,
401                                int64_t threshold,
402                                BLOCK_SIZE bsize_min,
403                                int force_split) {
404   VP9_COMMON * const cm = &cpi->common;
405   variance_node vt;
406   const int block_width = num_8x8_blocks_wide_lookup[bsize];
407   const int block_height = num_8x8_blocks_high_lookup[bsize];
408
409   assert(block_height == block_width);
410   tree_to_node(data, bsize, &vt);
411
412   if (force_split)
413     return 0;
414
415   // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
416   // variance is below threshold, otherwise split will be selected.
417   // No check for vert/horiz split as too few samples for variance.
418   if (bsize == bsize_min) {
419     get_variance(&vt.part_variances->none);
420     if (mi_col + block_width / 2 < cm->mi_cols &&
421         mi_row + block_height / 2 < cm->mi_rows &&
422         vt.part_variances->none.variance < threshold) {
423       set_block_size(cpi, xd, mi_row, mi_col, bsize);
424       return 1;
425     }
426     return 0;
427   } else if (bsize > bsize_min) {
428     // Variance is already computed for 32x32 blocks to set the force_split.
429     if (bsize != BLOCK_32X32)
430       get_variance(&vt.part_variances->none);
431     // For key frame or low_res: for bsize above 32X32 or very high variance,
432     // take split.
433     if (cm->frame_type == KEY_FRAME &&
434         (bsize > BLOCK_32X32 ||
435         vt.part_variances->none.variance > (threshold << 4))) {
436       return 0;
437     }
438     // If variance is low, take the bsize (no split).
439     if (mi_col + block_width / 2 < cm->mi_cols &&
440         mi_row + block_height / 2 < cm->mi_rows &&
441         vt.part_variances->none.variance < threshold) {
442       set_block_size(cpi, xd, mi_row, mi_col, bsize);
443       return 1;
444     }
445
446     // Check vertical split.
447     if (mi_row + block_height / 2 < cm->mi_rows) {
448       get_variance(&vt.part_variances->vert[0]);
449       get_variance(&vt.part_variances->vert[1]);
450       if (vt.part_variances->vert[0].variance < threshold &&
451           vt.part_variances->vert[1].variance < threshold) {
452         BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
453         set_block_size(cpi, xd, mi_row, mi_col, subsize);
454         set_block_size(cpi, xd, mi_row, mi_col + block_width / 2, subsize);
455         return 1;
456       }
457     }
458     // Check horizontal split.
459     if (mi_col + block_width / 2 < cm->mi_cols) {
460       get_variance(&vt.part_variances->horz[0]);
461       get_variance(&vt.part_variances->horz[1]);
462       if (vt.part_variances->horz[0].variance < threshold &&
463           vt.part_variances->horz[1].variance < threshold) {
464         BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
465         set_block_size(cpi, xd, mi_row, mi_col, subsize);
466         set_block_size(cpi, xd, mi_row + block_height / 2, mi_col, subsize);
467         return 1;
468       }
469     }
470
471     return 0;
472   }
473   return 0;
474 }
475
476
477 void vp9_set_vbp_thresholds(VP9_COMP *cpi, int q) {
478   SPEED_FEATURES *const sf = &cpi->sf;
479   if (sf->partition_search_type != VAR_BASED_PARTITION &&
480       sf->partition_search_type != REFERENCE_PARTITION) {
481     return;
482   } else {
483     VP9_COMMON *const cm = &cpi->common;
484     const int is_key_frame = (cm->frame_type == KEY_FRAME);
485     const int threshold_multiplier = is_key_frame ? 80 : 4;
486     const int64_t threshold_base = (int64_t)(threshold_multiplier *
487         vp9_convert_qindex_to_q(q, cm->bit_depth));
488
489     // TODO(marpan): Allow 4x4 partitions for inter-frames.
490     // use_4x4_partition = (variance4x4downsample[i2 + j] == 1);
491     // If 4x4 partition is not used, then 8x8 partition will be selected
492     // if variance of 16x16 block is very high, so use larger threshold
493     // for 16x16 (threshold_bsize_min) in that case.
494     if (is_key_frame) {
495       cpi->vbp_threshold = threshold_base >> 2;
496       cpi->vbp_threshold_bsize_max = threshold_base;
497       cpi->vbp_threshold_bsize_min = threshold_base << 2;
498       cpi->vbp_threshold_16x16 = cpi->vbp_threshold;
499       cpi->vbp_bsize_min = BLOCK_8X8;
500     } else {
501       cpi->vbp_threshold = threshold_base;
502       if (cm->width <= 352 && cm->height <= 288) {
503         cpi->vbp_threshold_bsize_max = threshold_base >> 2;
504         cpi->vbp_threshold_bsize_min = threshold_base << 3;
505       } else {
506         cpi->vbp_threshold_bsize_max = threshold_base;
507         cpi->vbp_threshold_bsize_min = threshold_base << cpi->oxcf.speed;
508       }
509       cpi->vbp_threshold_16x16 = cpi->vbp_threshold_bsize_min;
510       cpi->vbp_bsize_min = BLOCK_16X16;
511     }
512   }
513 }
514
515 // This function chooses partitioning based on the variance between source and
516 // reconstructed last, where variance is computed for down-sampled inputs.
517 static void choose_partitioning(VP9_COMP *cpi,
518                                 const TileInfo *const tile,
519                                 MACROBLOCK *x,
520                                 int mi_row, int mi_col) {
521   VP9_COMMON * const cm = &cpi->common;
522   MACROBLOCKD *xd = &x->e_mbd;
523   int i, j, k, m;
524   v64x64 vt;
525   v16x16 vt2[16];
526   int force_split[5];
527   uint8_t *s;
528   const uint8_t *d;
529   int sp;
530   int dp;
531   int pixels_wide = 64, pixels_high = 64;
532
533   // Always use 4x4 partition for key frame.
534   const int is_key_frame = (cm->frame_type == KEY_FRAME);
535   const int use_4x4_partition = is_key_frame;
536   const int low_res = (cm->width <= 352 && cm->height <= 288);
537   int variance4x4downsample[16];
538
539   int segment_id = CR_SEGMENT_ID_BASE;
540   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
541     const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map :
542                                                     cm->last_frame_seg_map;
543     segment_id = vp9_get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
544   }
545
546   set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
547
548   if (xd->mb_to_right_edge < 0)
549     pixels_wide += (xd->mb_to_right_edge >> 3);
550   if (xd->mb_to_bottom_edge < 0)
551     pixels_high += (xd->mb_to_bottom_edge >> 3);
552
553   s = x->plane[0].src.buf;
554   sp = x->plane[0].src.stride;
555
556   if (!is_key_frame) {
557     MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
558     unsigned int uv_sad;
559     const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
560
561     const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
562     unsigned int y_sad, y_sad_g;
563     BLOCK_SIZE bsize;
564     if (mi_row + 4 < cm->mi_rows && mi_col + 4 < cm->mi_cols)
565       bsize = BLOCK_64X64;
566     else if (mi_row + 4 < cm->mi_rows && mi_col + 4 >= cm->mi_cols)
567       bsize = BLOCK_32X64;
568     else if (mi_row + 4 >= cm->mi_rows && mi_col + 4 < cm->mi_cols)
569       bsize = BLOCK_64X32;
570     else
571       bsize = BLOCK_32X32;
572
573     assert(yv12 != NULL);
574
575     if (yv12_g && yv12_g != yv12) {
576       vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
577                            &cm->frame_refs[GOLDEN_FRAME - 1].sf);
578       y_sad_g = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf,
579                                        x->plane[0].src.stride,
580                                        xd->plane[0].pre[0].buf,
581                                        xd->plane[0].pre[0].stride);
582     } else {
583       y_sad_g = UINT_MAX;
584     }
585
586     vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
587                          &cm->frame_refs[LAST_FRAME - 1].sf);
588     mbmi->ref_frame[0] = LAST_FRAME;
589     mbmi->ref_frame[1] = NONE;
590     mbmi->sb_type = BLOCK_64X64;
591     mbmi->mv[0].as_int = 0;
592     mbmi->interp_filter = BILINEAR;
593
594     y_sad = vp9_int_pro_motion_estimation(cpi, x, bsize);
595     if (y_sad_g < y_sad) {
596       vp9_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
597                            &cm->frame_refs[GOLDEN_FRAME - 1].sf);
598       mbmi->ref_frame[0] = GOLDEN_FRAME;
599       mbmi->mv[0].as_int = 0;
600       y_sad = y_sad_g;
601     } else {
602       x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
603     }
604
605     vp9_build_inter_predictors_sb(xd, mi_row, mi_col, BLOCK_64X64);
606
607     for (i = 1; i <= 2; ++i) {
608       struct macroblock_plane  *p = &x->plane[i];
609       struct macroblockd_plane *pd = &xd->plane[i];
610       const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
611
612       if (bs == BLOCK_INVALID)
613         uv_sad = UINT_MAX;
614       else
615         uv_sad = cpi->fn_ptr[bs].sdf(p->src.buf, p->src.stride,
616                                      pd->dst.buf, pd->dst.stride);
617
618       x->color_sensitivity[i - 1] = uv_sad > (y_sad >> 2);
619     }
620
621     d = xd->plane[0].dst.buf;
622     dp = xd->plane[0].dst.stride;
623   } else {
624     d = VP9_VAR_OFFS;
625     dp = 0;
626 #if CONFIG_VP9_HIGHBITDEPTH
627     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
628       switch (xd->bd) {
629         case 10:
630           d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_10);
631           break;
632         case 12:
633           d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_12);
634           break;
635         case 8:
636         default:
637           d = CONVERT_TO_BYTEPTR(VP9_HIGH_VAR_OFFS_8);
638           break;
639       }
640     }
641 #endif  // CONFIG_VP9_HIGHBITDEPTH
642   }
643
644   // Index for force_split: 0 for 64x64, 1-4 for 32x32 blocks,
645   force_split[0] = 0;
646   // Fill in the entire tree of 8x8 (or 4x4 under some conditions) variances
647   // for splits.
648   for (i = 0; i < 4; i++) {
649     const int x32_idx = ((i & 1) << 5);
650     const int y32_idx = ((i >> 1) << 5);
651     const int i2 = i << 2;
652     force_split[i + 1] = 0;
653     for (j = 0; j < 4; j++) {
654       const int x16_idx = x32_idx + ((j & 1) << 4);
655       const int y16_idx = y32_idx + ((j >> 1) << 4);
656       v16x16 *vst = &vt.split[i].split[j];
657       variance4x4downsample[i2 + j] = 0;
658       if (!is_key_frame) {
659         for (k = 0; k < 4; k++) {
660           int x8_idx = x16_idx + ((k & 1) << 3);
661           int y8_idx = y16_idx + ((k >> 1) << 3);
662           unsigned int sse = 0;
663           int sum = 0;
664           if (x8_idx < pixels_wide && y8_idx < pixels_high) {
665             int s_avg, d_avg;
666 #if CONFIG_VP9_HIGHBITDEPTH
667             if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
668               s_avg = vp9_highbd_avg_8x8(s + y8_idx * sp + x8_idx, sp);
669               d_avg = vp9_highbd_avg_8x8(d + y8_idx * dp + x8_idx, dp);
670             } else {
671               s_avg = vp9_avg_8x8(s + y8_idx * sp + x8_idx, sp);
672               d_avg = vp9_avg_8x8(d + y8_idx * dp + x8_idx, dp);
673             }
674 #else
675             s_avg = vp9_avg_8x8(s + y8_idx * sp + x8_idx, sp);
676             d_avg = vp9_avg_8x8(d + y8_idx * dp + x8_idx, dp);
677 #endif
678             sum = s_avg - d_avg;
679             sse = sum * sum;
680           }
681           // If variance is based on 8x8 downsampling, we stop here and have
682           // one sample for 8x8 block (so use 1 for count in fill_variance),
683           // which of course means variance = 0 for 8x8 block.
684           fill_variance(sse, sum, 0, &vst->split[k].part_variances.none);
685         }
686         fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
687         // For low-resolution, compute the variance based on 8x8 down-sampling,
688         // and if it is large (above the threshold) we go down for 4x4.
689         // For key frame we always go down to 4x4.
690         if (low_res)
691           get_variance(&vt.split[i].split[j].part_variances.none);
692       }
693       if (is_key_frame || (low_res &&
694           vt.split[i].split[j].part_variances.none.variance >
695           (cpi->vbp_threshold << 1))) {
696         // Go down to 4x4 down-sampling for variance.
697         variance4x4downsample[i2 + j] = 1;
698         for (k = 0; k < 4; k++) {
699           int x8_idx = x16_idx + ((k & 1) << 3);
700           int y8_idx = y16_idx + ((k >> 1) << 3);
701           v8x8 *vst2 = is_key_frame ? &vst->split[k] :
702               &vt2[i2 + j].split[k];
703           for (m = 0; m < 4; m++) {
704             int x4_idx = x8_idx + ((m & 1) << 2);
705             int y4_idx = y8_idx + ((m >> 1) << 2);
706             unsigned int sse = 0;
707             int sum = 0;
708             if (x4_idx < pixels_wide && y4_idx < pixels_high) {
709               int d_avg = 128;
710 #if CONFIG_VP9_HIGHBITDEPTH
711               int s_avg;
712               if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
713                 s_avg = vp9_highbd_avg_4x4(s + y4_idx * sp + x4_idx, sp);
714                 if (cm->frame_type != KEY_FRAME)
715                   d_avg = vp9_highbd_avg_4x4(d + y4_idx * dp + x4_idx, dp);
716               } else {
717                 s_avg = vp9_avg_4x4(s + y4_idx * sp + x4_idx, sp);
718                 if (cm->frame_type != KEY_FRAME)
719                   d_avg = vp9_avg_4x4(d + y4_idx * dp + x4_idx, dp);
720               }
721 #else
722               int s_avg = vp9_avg_4x4(s + y4_idx * sp + x4_idx, sp);
723               if (!is_key_frame)
724                 d_avg = vp9_avg_4x4(d + y4_idx * dp + x4_idx, dp);
725 #endif
726               sum = s_avg - d_avg;
727               sse = sum * sum;
728             }
729             // If variance is based on 4x4 down-sampling, we stop here and have
730             // one sample for 4x4 block (so use 1 for count in fill_variance),
731             // which of course means variance = 0 for 4x4 block.
732             fill_variance(sse, sum, 0, &vst2->split[m].part_variances.none);
733           }
734         }
735       }
736     }
737   }
738
739   // No 64x64 blocks on segments other than base (un-boosted) segment,
740   // so force split.
741   if (cyclic_refresh_segment_id_boosted(segment_id))
742     force_split[0] = 1;
743
744   // Fill the rest of the variance tree by summing split partition values.
745   for (i = 0; i < 4; i++) {
746     const int i2 = i << 2;
747     for (j = 0; j < 4; j++) {
748       if (variance4x4downsample[i2 + j] == 1) {
749         v16x16 *vtemp = (!is_key_frame) ? &vt2[i2 + j] :
750             &vt.split[i].split[j];
751         for (m = 0; m < 4; m++)
752           fill_variance_tree(&vtemp->split[m], BLOCK_8X8);
753         fill_variance_tree(vtemp, BLOCK_16X16);
754       }
755     }
756     fill_variance_tree(&vt.split[i], BLOCK_32X32);
757     // If variance of this 32x32 block is above the threshold, force the block
758     // to split. This also forces a split on the upper (64x64) level.
759     get_variance(&vt.split[i].part_variances.none);
760     if (vt.split[i].part_variances.none.variance > cpi->vbp_threshold) {
761       force_split[i + 1] = 1;
762       force_split[0] = 1;
763     }
764   }
765   if (!force_split[0])
766     fill_variance_tree(&vt, BLOCK_64X64);
767
768   // Now go through the entire structure,  splitting every block size until
769   // we get to one that's got a variance lower than our threshold.
770   if ( mi_col + 8 > cm->mi_cols || mi_row + 8 > cm->mi_rows ||
771       !set_vt_partitioning(cpi, xd, &vt, BLOCK_64X64, mi_row, mi_col,
772                            cpi->vbp_threshold_bsize_max, BLOCK_16X16,
773                            force_split[0])) {
774     for (i = 0; i < 4; ++i) {
775       const int x32_idx = ((i & 1) << 2);
776       const int y32_idx = ((i >> 1) << 2);
777       const int i2 = i << 2;
778       if (!set_vt_partitioning(cpi, xd, &vt.split[i], BLOCK_32X32,
779                                (mi_row + y32_idx), (mi_col + x32_idx),
780                                cpi->vbp_threshold,
781                                BLOCK_16X16, force_split[i + 1])) {
782         for (j = 0; j < 4; ++j) {
783           const int x16_idx = ((j & 1) << 1);
784           const int y16_idx = ((j >> 1) << 1);
785           // For inter frames: if variance4x4downsample[] == 1 for this 16x16
786           // block, then the variance is based on 4x4 down-sampling, so use vt2
787           // in set_vt_partioning(), otherwise use vt.
788           v16x16 *vtemp = (!is_key_frame &&
789                            variance4x4downsample[i2 + j] == 1) ?
790                            &vt2[i2 + j] : &vt.split[i].split[j];
791           if (!set_vt_partitioning(cpi, xd, vtemp, BLOCK_16X16,
792                                    mi_row + y32_idx + y16_idx,
793                                    mi_col + x32_idx + x16_idx,
794                                    cpi->vbp_threshold_16x16,
795                                    cpi->vbp_bsize_min, 0)) {
796             for (k = 0; k < 4; ++k) {
797               const int x8_idx = (k & 1);
798               const int y8_idx = (k >> 1);
799               if (use_4x4_partition) {
800                 if (!set_vt_partitioning(cpi, xd, &vtemp->split[k],
801                                          BLOCK_8X8,
802                                          mi_row + y32_idx + y16_idx + y8_idx,
803                                          mi_col + x32_idx + x16_idx + x8_idx,
804                                          cpi->vbp_threshold_bsize_min,
805                                          BLOCK_8X8, 0)) {
806                   set_block_size(cpi, xd,
807                                  (mi_row + y32_idx + y16_idx + y8_idx),
808                                  (mi_col + x32_idx + x16_idx + x8_idx),
809                                  BLOCK_4X4);
810                 }
811               } else {
812                 set_block_size(cpi, xd,
813                                (mi_row + y32_idx + y16_idx + y8_idx),
814                                (mi_col + x32_idx + x16_idx + x8_idx),
815                                BLOCK_8X8);
816               }
817             }
818           }
819         }
820       }
821     }
822   }
823 }
824
825 static void update_state(VP9_COMP *cpi, ThreadData *td,
826                          PICK_MODE_CONTEXT *ctx,
827                          int mi_row, int mi_col, BLOCK_SIZE bsize,
828                          int output_enabled) {
829   int i, x_idx, y;
830   VP9_COMMON *const cm = &cpi->common;
831   RD_COUNTS *const rdc = &td->rd_counts;
832   MACROBLOCK *const x = &td->mb;
833   MACROBLOCKD *const xd = &x->e_mbd;
834   struct macroblock_plane *const p = x->plane;
835   struct macroblockd_plane *const pd = xd->plane;
836   MODE_INFO *mi = &ctx->mic;
837   MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
838   MODE_INFO *mi_addr = &xd->mi[0];
839   const struct segmentation *const seg = &cm->seg;
840   const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
841   const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
842   const int x_mis = MIN(bw, cm->mi_cols - mi_col);
843   const int y_mis = MIN(bh, cm->mi_rows - mi_row);
844   MV_REF *const frame_mvs =
845       cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
846   int w, h;
847
848   const int mis = cm->mi_stride;
849   const int mi_width = num_8x8_blocks_wide_lookup[bsize];
850   const int mi_height = num_8x8_blocks_high_lookup[bsize];
851   int max_plane;
852
853   assert(mi->mbmi.sb_type == bsize);
854
855   *mi_addr = *mi;
856   mi_addr->src_mi = mi_addr;
857
858   // If segmentation in use
859   if (seg->enabled) {
860     // For in frame complexity AQ copy the segment id from the segment map.
861     if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
862       const uint8_t *const map = seg->update_map ? cpi->segmentation_map
863                                                  : cm->last_frame_seg_map;
864       mi_addr->mbmi.segment_id =
865         vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
866     }
867     // Else for cyclic refresh mode update the segment map, set the segment id
868     // and then update the quantizer.
869     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
870       vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0].src_mi->mbmi, mi_row,
871                                         mi_col, bsize, ctx->rate, ctx->dist);
872     }
873   }
874
875   max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
876   for (i = 0; i < max_plane; ++i) {
877     p[i].coeff = ctx->coeff_pbuf[i][1];
878     p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
879     pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
880     p[i].eobs = ctx->eobs_pbuf[i][1];
881   }
882
883   for (i = max_plane; i < MAX_MB_PLANE; ++i) {
884     p[i].coeff = ctx->coeff_pbuf[i][2];
885     p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
886     pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
887     p[i].eobs = ctx->eobs_pbuf[i][2];
888   }
889
890   // Restore the coding context of the MB to that that was in place
891   // when the mode was picked for it
892   for (y = 0; y < mi_height; y++)
893     for (x_idx = 0; x_idx < mi_width; x_idx++)
894       if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
895         && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
896         xd->mi[x_idx + y * mis].src_mi = mi_addr;
897       }
898
899   if (cpi->oxcf.aq_mode)
900     vp9_init_plane_quantizers(cpi, x);
901
902   // FIXME(rbultje) I'm pretty sure this should go to the end of this block
903   // (i.e. after the output_enabled)
904   if (bsize < BLOCK_32X32) {
905     if (bsize < BLOCK_16X16)
906       ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
907     ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
908   }
909
910   if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
911     mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
912     mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
913   }
914
915   x->skip = ctx->skip;
916   vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
917              sizeof(uint8_t) * ctx->num_4x4_blk);
918
919   if (!output_enabled)
920     return;
921
922   if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
923     for (i = 0; i < TX_MODES; i++)
924       rdc->tx_select_diff[i] += ctx->tx_rd_diff[i];
925   }
926
927 #if CONFIG_INTERNAL_STATS
928   if (frame_is_intra_only(cm)) {
929     static const int kf_mode_index[] = {
930       THR_DC        /*DC_PRED*/,
931       THR_V_PRED    /*V_PRED*/,
932       THR_H_PRED    /*H_PRED*/,
933       THR_D45_PRED  /*D45_PRED*/,
934       THR_D135_PRED /*D135_PRED*/,
935       THR_D117_PRED /*D117_PRED*/,
936       THR_D153_PRED /*D153_PRED*/,
937       THR_D207_PRED /*D207_PRED*/,
938       THR_D63_PRED  /*D63_PRED*/,
939       THR_TM        /*TM_PRED*/,
940     };
941     ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]];
942   } else {
943     // Note how often each mode chosen as best
944     ++cpi->mode_chosen_counts[ctx->best_mode_index];
945   }
946 #endif
947   if (!frame_is_intra_only(cm)) {
948     if (is_inter_block(mbmi)) {
949       vp9_update_mv_count(td);
950
951       if (cm->interp_filter == SWITCHABLE) {
952         const int ctx = vp9_get_pred_context_switchable_interp(xd);
953         ++td->counts->switchable_interp[ctx][mbmi->interp_filter];
954       }
955     }
956
957     rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
958     rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
959     rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
960
961     for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
962       rdc->filter_diff[i] += ctx->best_filter_diff[i];
963   }
964
965   for (h = 0; h < y_mis; ++h) {
966     MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
967     for (w = 0; w < x_mis; ++w) {
968       MV_REF *const mv = frame_mv + w;
969       mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0];
970       mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1];
971       mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int;
972       mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int;
973     }
974   }
975 }
976
977 void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
978                           int mi_row, int mi_col) {
979   uint8_t *const buffers[3] = {src->y_buffer, src->u_buffer, src->v_buffer };
980   const int strides[3] = {src->y_stride, src->uv_stride, src->uv_stride };
981   int i;
982
983   // Set current frame pointer.
984   x->e_mbd.cur_buf = src;
985
986   for (i = 0; i < MAX_MB_PLANE; i++)
987     setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
988                      NULL, x->e_mbd.plane[i].subsampling_x,
989                      x->e_mbd.plane[i].subsampling_y);
990 }
991
992 static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode,
993                                    RD_COST *rd_cost, BLOCK_SIZE bsize) {
994   MACROBLOCKD *const xd = &x->e_mbd;
995   MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
996   INTERP_FILTER filter_ref;
997
998   if (xd->up_available)
999     filter_ref = xd->mi[-xd->mi_stride].src_mi->mbmi.interp_filter;
1000   else if (xd->left_available)
1001     filter_ref = xd->mi[-1].src_mi->mbmi.interp_filter;
1002   else
1003     filter_ref = EIGHTTAP;
1004
1005   mbmi->sb_type = bsize;
1006   mbmi->mode = ZEROMV;
1007   mbmi->tx_size = MIN(max_txsize_lookup[bsize],
1008                       tx_mode_to_biggest_tx_size[tx_mode]);
1009   mbmi->skip = 1;
1010   mbmi->uv_mode = DC_PRED;
1011   mbmi->ref_frame[0] = LAST_FRAME;
1012   mbmi->ref_frame[1] = NONE;
1013   mbmi->mv[0].as_int = 0;
1014   mbmi->interp_filter = filter_ref;
1015
1016   xd->mi[0].src_mi->bmi[0].as_mv[0].as_int = 0;
1017   x->skip = 1;
1018
1019   vp9_rd_cost_init(rd_cost);
1020 }
1021
1022 static int set_segment_rdmult(VP9_COMP *const cpi,
1023                                MACROBLOCK *const x,
1024                                int8_t segment_id) {
1025   int segment_qindex;
1026   VP9_COMMON *const cm = &cpi->common;
1027   vp9_init_plane_quantizers(cpi, x);
1028   vp9_clear_system_state();
1029   segment_qindex = vp9_get_qindex(&cm->seg, segment_id,
1030                                   cm->base_qindex);
1031   return vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
1032 }
1033
1034 static void rd_pick_sb_modes(VP9_COMP *cpi,
1035                              TileDataEnc *tile_data,
1036                              MACROBLOCK *const x,
1037                              int mi_row, int mi_col, RD_COST *rd_cost,
1038                              BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1039                              int64_t best_rd) {
1040   VP9_COMMON *const cm = &cpi->common;
1041   TileInfo *const tile_info = &tile_data->tile_info;
1042   MACROBLOCKD *const xd = &x->e_mbd;
1043   MB_MODE_INFO *mbmi;
1044   struct macroblock_plane *const p = x->plane;
1045   struct macroblockd_plane *const pd = xd->plane;
1046   const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1047   int i, orig_rdmult;
1048
1049   vp9_clear_system_state();
1050
1051   // Use the lower precision, but faster, 32x32 fdct for mode selection.
1052   x->use_lp32x32fdct = 1;
1053
1054   set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1055   mbmi = &xd->mi[0].src_mi->mbmi;
1056   mbmi->sb_type = bsize;
1057
1058   for (i = 0; i < MAX_MB_PLANE; ++i) {
1059     p[i].coeff = ctx->coeff_pbuf[i][0];
1060     p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
1061     pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
1062     p[i].eobs = ctx->eobs_pbuf[i][0];
1063   }
1064   ctx->is_coded = 0;
1065   ctx->skippable = 0;
1066   ctx->pred_pixel_ready = 0;
1067   x->skip_recode = 0;
1068
1069   // Set to zero to make sure we do not use the previous encoded frame stats
1070   mbmi->skip = 0;
1071
1072 #if CONFIG_VP9_HIGHBITDEPTH
1073   if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1074     x->source_variance =
1075         vp9_high_get_sby_perpixel_variance(cpi, &x->plane[0].src,
1076                                            bsize, xd->bd);
1077   } else {
1078     x->source_variance =
1079       vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1080   }
1081 #else
1082   x->source_variance =
1083     vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1084 #endif  // CONFIG_VP9_HIGHBITDEPTH
1085
1086   // Save rdmult before it might be changed, so it can be restored later.
1087   orig_rdmult = x->rdmult;
1088
1089   if (aq_mode == VARIANCE_AQ) {
1090     const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
1091                                             : vp9_block_energy(cpi, x, bsize);
1092     if (cm->frame_type == KEY_FRAME ||
1093         cpi->refresh_alt_ref_frame ||
1094         (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
1095       mbmi->segment_id = vp9_vaq_segment_id(energy);
1096     } else {
1097       const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1098                                                     : cm->last_frame_seg_map;
1099       mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
1100     }
1101     x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1102   } else if (aq_mode == COMPLEXITY_AQ) {
1103     x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1104   } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1105     const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1106                                                   : cm->last_frame_seg_map;
1107     // If segment 1, use rdmult for that segment.
1108     if (vp9_get_segment_id(cm, map, bsize, mi_row, mi_col))
1109       x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
1110   }
1111
1112   // Find best coding mode & reconstruct the MB so it is available
1113   // as a predictor for MBs that follow in the SB
1114   if (frame_is_intra_only(cm)) {
1115     vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
1116   } else {
1117     if (bsize >= BLOCK_8X8) {
1118       if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
1119         vp9_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1120                                            ctx, best_rd);
1121       else
1122         vp9_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col,
1123                                   rd_cost, bsize, ctx, best_rd);
1124     } else {
1125       vp9_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1126                                     rd_cost, bsize, ctx, best_rd);
1127     }
1128   }
1129
1130
1131   // Examine the resulting rate and for AQ mode 2 make a segment choice.
1132   if ((rd_cost->rate != INT_MAX) &&
1133       (aq_mode == COMPLEXITY_AQ) && (bsize >= BLOCK_16X16) &&
1134       (cm->frame_type == KEY_FRAME ||
1135        cpi->refresh_alt_ref_frame ||
1136        (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
1137     vp9_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
1138   }
1139
1140   x->rdmult = orig_rdmult;
1141
1142   // TODO(jingning) The rate-distortion optimization flow needs to be
1143   // refactored to provide proper exit/return handle.
1144   if (rd_cost->rate == INT_MAX)
1145     rd_cost->rdcost = INT64_MAX;
1146
1147   ctx->rate = rd_cost->rate;
1148   ctx->dist = rd_cost->dist;
1149 }
1150
1151 static void update_stats(VP9_COMMON *cm, ThreadData *td) {
1152   const MACROBLOCK *x = &td->mb;
1153   const MACROBLOCKD *const xd = &x->e_mbd;
1154   const MODE_INFO *const mi = xd->mi[0].src_mi;
1155   const MB_MODE_INFO *const mbmi = &mi->mbmi;
1156   const BLOCK_SIZE bsize = mbmi->sb_type;
1157
1158   if (!frame_is_intra_only(cm)) {
1159     FRAME_COUNTS *const counts = td->counts;
1160     const int inter_block = is_inter_block(mbmi);
1161     const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
1162                                                      SEG_LVL_REF_FRAME);
1163     if (!seg_ref_active) {
1164       counts->intra_inter[vp9_get_intra_inter_context(xd)][inter_block]++;
1165       // If the segment reference feature is enabled we have only a single
1166       // reference frame allowed for the segment so exclude it from
1167       // the reference frame counts used to work out probabilities.
1168       if (inter_block) {
1169         const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1170         if (cm->reference_mode == REFERENCE_MODE_SELECT)
1171           counts->comp_inter[vp9_get_reference_mode_context(cm, xd)]
1172                             [has_second_ref(mbmi)]++;
1173
1174         if (has_second_ref(mbmi)) {
1175           counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
1176                           [ref0 == GOLDEN_FRAME]++;
1177         } else {
1178           counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
1179                             [ref0 != LAST_FRAME]++;
1180           if (ref0 != LAST_FRAME)
1181             counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
1182                               [ref0 != GOLDEN_FRAME]++;
1183         }
1184       }
1185     }
1186     if (inter_block &&
1187         !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1188       const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
1189       if (bsize >= BLOCK_8X8) {
1190         const PREDICTION_MODE mode = mbmi->mode;
1191         ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
1192       } else {
1193         const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1194         const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1195         int idx, idy;
1196         for (idy = 0; idy < 2; idy += num_4x4_h) {
1197           for (idx = 0; idx < 2; idx += num_4x4_w) {
1198             const int j = idy * 2 + idx;
1199             const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
1200             ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
1201           }
1202         }
1203       }
1204     }
1205   }
1206 }
1207
1208 static void restore_context(MACROBLOCK *const x, int mi_row, int mi_col,
1209                             ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1210                             ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1211                             PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1212                             BLOCK_SIZE bsize) {
1213   MACROBLOCKD *const xd = &x->e_mbd;
1214   int p;
1215   const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1216   const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1217   int mi_width = num_8x8_blocks_wide_lookup[bsize];
1218   int mi_height = num_8x8_blocks_high_lookup[bsize];
1219   for (p = 0; p < MAX_MB_PLANE; p++) {
1220     vpx_memcpy(
1221         xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
1222         a + num_4x4_blocks_wide * p,
1223         (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1224         xd->plane[p].subsampling_x);
1225     vpx_memcpy(
1226         xd->left_context[p]
1227             + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1228         l + num_4x4_blocks_high * p,
1229         (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1230         xd->plane[p].subsampling_y);
1231   }
1232   vpx_memcpy(xd->above_seg_context + mi_col, sa,
1233              sizeof(*xd->above_seg_context) * mi_width);
1234   vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl,
1235              sizeof(xd->left_seg_context[0]) * mi_height);
1236 }
1237
1238 static void save_context(MACROBLOCK *const x, int mi_row, int mi_col,
1239                          ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1240                          ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1241                          PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1242                          BLOCK_SIZE bsize) {
1243   const MACROBLOCKD *const xd = &x->e_mbd;
1244   int p;
1245   const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1246   const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1247   int mi_width = num_8x8_blocks_wide_lookup[bsize];
1248   int mi_height = num_8x8_blocks_high_lookup[bsize];
1249
1250   // buffer the above/left context information of the block in search.
1251   for (p = 0; p < MAX_MB_PLANE; ++p) {
1252     vpx_memcpy(
1253         a + num_4x4_blocks_wide * p,
1254         xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
1255         (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1256         xd->plane[p].subsampling_x);
1257     vpx_memcpy(
1258         l + num_4x4_blocks_high * p,
1259         xd->left_context[p]
1260             + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1261         (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1262         xd->plane[p].subsampling_y);
1263   }
1264   vpx_memcpy(sa, xd->above_seg_context + mi_col,
1265              sizeof(*xd->above_seg_context) * mi_width);
1266   vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK),
1267              sizeof(xd->left_seg_context[0]) * mi_height);
1268 }
1269
1270 static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
1271                      ThreadData *td,
1272                      TOKENEXTRA **tp, int mi_row, int mi_col,
1273                      int output_enabled, BLOCK_SIZE bsize,
1274                      PICK_MODE_CONTEXT *ctx) {
1275   MACROBLOCK *const x = &td->mb;
1276   set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
1277   update_state(cpi, td, ctx, mi_row, mi_col, bsize, output_enabled);
1278   encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx);
1279
1280   if (output_enabled) {
1281     update_stats(&cpi->common, td);
1282
1283     (*tp)->token = EOSB_TOKEN;
1284     (*tp)++;
1285   }
1286 }
1287
1288 static void encode_sb(VP9_COMP *cpi, ThreadData *td,
1289                       const TileInfo *const tile,
1290                       TOKENEXTRA **tp, int mi_row, int mi_col,
1291                       int output_enabled, BLOCK_SIZE bsize,
1292                       PC_TREE *pc_tree) {
1293   VP9_COMMON *const cm = &cpi->common;
1294   MACROBLOCK *const x = &td->mb;
1295   MACROBLOCKD *const xd = &x->e_mbd;
1296
1297   const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1298   int ctx;
1299   PARTITION_TYPE partition;
1300   BLOCK_SIZE subsize = bsize;
1301
1302   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1303     return;
1304
1305   if (bsize >= BLOCK_8X8) {
1306     ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1307     subsize = get_subsize(bsize, pc_tree->partitioning);
1308   } else {
1309     ctx = 0;
1310     subsize = BLOCK_4X4;
1311   }
1312
1313   partition = partition_lookup[bsl][subsize];
1314   if (output_enabled && bsize != BLOCK_4X4)
1315     td->counts->partition[ctx][partition]++;
1316
1317   switch (partition) {
1318     case PARTITION_NONE:
1319       encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
1320                &pc_tree->none);
1321       break;
1322     case PARTITION_VERT:
1323       encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
1324                &pc_tree->vertical[0]);
1325       if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
1326         encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled,
1327                  subsize, &pc_tree->vertical[1]);
1328       }
1329       break;
1330     case PARTITION_HORZ:
1331       encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
1332                &pc_tree->horizontal[0]);
1333       if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
1334         encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled,
1335                  subsize, &pc_tree->horizontal[1]);
1336       }
1337       break;
1338     case PARTITION_SPLIT:
1339       if (bsize == BLOCK_8X8) {
1340         encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize,
1341                  pc_tree->leaf_split[0]);
1342       } else {
1343         encode_sb(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize,
1344                   pc_tree->split[0]);
1345         encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled,
1346                   subsize, pc_tree->split[1]);
1347         encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled,
1348                   subsize, pc_tree->split[2]);
1349         encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1350                   subsize, pc_tree->split[3]);
1351       }
1352       break;
1353     default:
1354       assert(0 && "Invalid partition type.");
1355       break;
1356   }
1357
1358   if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1359     update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1360 }
1361
1362 // Check to see if the given partition size is allowed for a specified number
1363 // of 8x8 block rows and columns remaining in the image.
1364 // If not then return the largest allowed partition size
1365 static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize,
1366                                       int rows_left, int cols_left,
1367                                       int *bh, int *bw) {
1368   if (rows_left <= 0 || cols_left <= 0) {
1369     return MIN(bsize, BLOCK_8X8);
1370   } else {
1371     for (; bsize > 0; bsize -= 3) {
1372       *bh = num_8x8_blocks_high_lookup[bsize];
1373       *bw = num_8x8_blocks_wide_lookup[bsize];
1374       if ((*bh <= rows_left) && (*bw <= cols_left)) {
1375         break;
1376       }
1377     }
1378   }
1379   return bsize;
1380 }
1381
1382 static void set_partial_b64x64_partition(MODE_INFO *mi, int mis,
1383     int bh_in, int bw_in, int row8x8_remaining, int col8x8_remaining,
1384     BLOCK_SIZE bsize, MODE_INFO *mi_8x8) {
1385   int bh = bh_in;
1386   int r, c;
1387   for (r = 0; r < MI_BLOCK_SIZE; r += bh) {
1388     int bw = bw_in;
1389     for (c = 0; c < MI_BLOCK_SIZE; c += bw) {
1390       const int index = r * mis + c;
1391       mi_8x8[index].src_mi = mi + index;
1392       mi_8x8[index].src_mi->mbmi.sb_type = find_partition_size(bsize,
1393           row8x8_remaining - r, col8x8_remaining - c, &bh, &bw);
1394     }
1395   }
1396 }
1397
1398 // This function attempts to set all mode info entries in a given SB64
1399 // to the same block partition size.
1400 // However, at the bottom and right borders of the image the requested size
1401 // may not be allowed in which case this code attempts to choose the largest
1402 // allowable partition.
1403 static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
1404                                    MODE_INFO *mi_8x8, int mi_row, int mi_col,
1405                                    BLOCK_SIZE bsize) {
1406   VP9_COMMON *const cm = &cpi->common;
1407   const int mis = cm->mi_stride;
1408   const int row8x8_remaining = tile->mi_row_end - mi_row;
1409   const int col8x8_remaining = tile->mi_col_end - mi_col;
1410   int block_row, block_col;
1411   MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
1412   int bh = num_8x8_blocks_high_lookup[bsize];
1413   int bw = num_8x8_blocks_wide_lookup[bsize];
1414
1415   assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1416
1417   // Apply the requested partition size to the SB64 if it is all "in image"
1418   if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1419       (row8x8_remaining >= MI_BLOCK_SIZE)) {
1420     for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1421       for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1422         int index = block_row * mis + block_col;
1423         mi_8x8[index].src_mi = mi_upper_left + index;
1424         mi_8x8[index].src_mi->mbmi.sb_type = bsize;
1425       }
1426     }
1427   } else {
1428     // Else this is a partial SB64.
1429     set_partial_b64x64_partition(mi_upper_left, mis, bh, bw, row8x8_remaining,
1430         col8x8_remaining, bsize, mi_8x8);
1431   }
1432 }
1433
1434 const struct {
1435   int row;
1436   int col;
1437 } coord_lookup[16] = {
1438     // 32x32 index = 0
1439     {0, 0}, {0, 2}, {2, 0}, {2, 2},
1440     // 32x32 index = 1
1441     {0, 4}, {0, 6}, {2, 4}, {2, 6},
1442     // 32x32 index = 2
1443     {4, 0}, {4, 2}, {6, 0}, {6, 2},
1444     // 32x32 index = 3
1445     {4, 4}, {4, 6}, {6, 4}, {6, 6},
1446 };
1447
1448 static void set_source_var_based_partition(VP9_COMP *cpi,
1449                                            const TileInfo *const tile,
1450                                            MACROBLOCK *const x,
1451                                            MODE_INFO *mi_8x8,
1452                                            int mi_row, int mi_col) {
1453   VP9_COMMON *const cm = &cpi->common;
1454   const int mis = cm->mi_stride;
1455   const int row8x8_remaining = tile->mi_row_end - mi_row;
1456   const int col8x8_remaining = tile->mi_col_end - mi_col;
1457   MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
1458
1459   vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
1460
1461   assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1462
1463   // In-image SB64
1464   if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1465       (row8x8_remaining >= MI_BLOCK_SIZE)) {
1466     int i, j;
1467     int index;
1468     diff d32[4];
1469     const int offset = (mi_row >> 1) * cm->mb_cols + (mi_col >> 1);
1470     int is_larger_better = 0;
1471     int use32x32 = 0;
1472     unsigned int thr = cpi->source_var_thresh;
1473
1474     vpx_memset(d32, 0, 4 * sizeof(diff));
1475
1476     for (i = 0; i < 4; i++) {
1477       diff *d16[4];
1478
1479       for (j = 0; j < 4; j++) {
1480         int b_mi_row = coord_lookup[i * 4 + j].row;
1481         int b_mi_col = coord_lookup[i * 4 + j].col;
1482         int boffset = b_mi_row / 2 * cm->mb_cols +
1483                       b_mi_col / 2;
1484
1485         d16[j] = cpi->source_diff_var + offset + boffset;
1486
1487         index = b_mi_row * mis + b_mi_col;
1488         mi_8x8[index].src_mi = mi_upper_left + index;
1489         mi_8x8[index].src_mi->mbmi.sb_type = BLOCK_16X16;
1490
1491         // TODO(yunqingwang): If d16[j].var is very large, use 8x8 partition
1492         // size to further improve quality.
1493       }
1494
1495       is_larger_better = (d16[0]->var < thr) && (d16[1]->var < thr) &&
1496           (d16[2]->var < thr) && (d16[3]->var < thr);
1497
1498       // Use 32x32 partition
1499       if (is_larger_better) {
1500         use32x32 += 1;
1501
1502         for (j = 0; j < 4; j++) {
1503           d32[i].sse += d16[j]->sse;
1504           d32[i].sum += d16[j]->sum;
1505         }
1506
1507         d32[i].var = d32[i].sse - (((int64_t)d32[i].sum * d32[i].sum) >> 10);
1508
1509         index = coord_lookup[i*4].row * mis + coord_lookup[i*4].col;
1510         mi_8x8[index].src_mi = mi_upper_left + index;
1511         mi_8x8[index].src_mi->mbmi.sb_type = BLOCK_32X32;
1512       }
1513     }
1514
1515     if (use32x32 == 4) {
1516       thr <<= 1;
1517       is_larger_better = (d32[0].var < thr) && (d32[1].var < thr) &&
1518           (d32[2].var < thr) && (d32[3].var < thr);
1519
1520       // Use 64x64 partition
1521       if (is_larger_better) {
1522         mi_8x8[0].src_mi = mi_upper_left;
1523         mi_8x8[0].src_mi->mbmi.sb_type = BLOCK_64X64;
1524       }
1525     }
1526   } else {   // partial in-image SB64
1527     int bh = num_8x8_blocks_high_lookup[BLOCK_16X16];
1528     int bw = num_8x8_blocks_wide_lookup[BLOCK_16X16];
1529     set_partial_b64x64_partition(mi_upper_left, mis, bh, bw,
1530         row8x8_remaining, col8x8_remaining, BLOCK_16X16, mi_8x8);
1531   }
1532 }
1533
1534 static void update_state_rt(VP9_COMP *cpi, ThreadData *td,
1535                             PICK_MODE_CONTEXT *ctx,
1536                             int mi_row, int mi_col, int bsize) {
1537   VP9_COMMON *const cm = &cpi->common;
1538   MACROBLOCK *const x = &td->mb;
1539   MACROBLOCKD *const xd = &x->e_mbd;
1540   MODE_INFO *const mi = xd->mi[0].src_mi;
1541   MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
1542   const struct segmentation *const seg = &cm->seg;
1543   const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
1544   const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
1545   const int x_mis = MIN(bw, cm->mi_cols - mi_col);
1546   const int y_mis = MIN(bh, cm->mi_rows - mi_row);
1547
1548   xd->mi[0] = ctx->mic;
1549   xd->mi[0].src_mi = &xd->mi[0];
1550
1551   if (seg->enabled && cpi->oxcf.aq_mode) {
1552     // For in frame complexity AQ or variance AQ, copy segment_id from
1553     // segmentation_map.
1554     if (cpi->oxcf.aq_mode == COMPLEXITY_AQ ||
1555         cpi->oxcf.aq_mode == VARIANCE_AQ ) {
1556       const uint8_t *const map = seg->update_map ? cpi->segmentation_map
1557                                                  : cm->last_frame_seg_map;
1558       mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
1559     } else {
1560     // Setting segmentation map for cyclic_refresh.
1561       vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize,
1562                                         ctx->rate, ctx->dist);
1563     }
1564     vp9_init_plane_quantizers(cpi, x);
1565   }
1566
1567   if (is_inter_block(mbmi)) {
1568     vp9_update_mv_count(td);
1569     if (cm->interp_filter == SWITCHABLE) {
1570       const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
1571       ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
1572     }
1573
1574     if (mbmi->sb_type < BLOCK_8X8) {
1575       mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1576       mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1577     }
1578   }
1579
1580   if (cm->use_prev_frame_mvs) {
1581     MV_REF *const frame_mvs =
1582         cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1583     int w, h;
1584
1585     for (h = 0; h < y_mis; ++h) {
1586       MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1587       for (w = 0; w < x_mis; ++w) {
1588         MV_REF *const mv = frame_mv + w;
1589         mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0];
1590         mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1];
1591         mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int;
1592         mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int;
1593       }
1594     }
1595   }
1596
1597   x->skip = ctx->skip;
1598   x->skip_txfm[0] = mbmi->segment_id ? 0 : ctx->skip_txfm[0];
1599 }
1600
1601 static void encode_b_rt(VP9_COMP *cpi, ThreadData *td,
1602                         const TileInfo *const tile,
1603                         TOKENEXTRA **tp, int mi_row, int mi_col,
1604                         int output_enabled, BLOCK_SIZE bsize,
1605                         PICK_MODE_CONTEXT *ctx) {
1606   MACROBLOCK *const x = &td->mb;
1607   set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
1608   update_state_rt(cpi, td, ctx, mi_row, mi_col, bsize);
1609
1610 #if CONFIG_VP9_TEMPORAL_DENOISING
1611   if (cpi->oxcf.noise_sensitivity > 0 && output_enabled &&
1612       cpi->common.frame_type != KEY_FRAME) {
1613     vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col,
1614                          MAX(BLOCK_8X8, bsize), ctx);
1615   }
1616 #endif
1617
1618   encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx);
1619   update_stats(&cpi->common, td);
1620
1621   (*tp)->token = EOSB_TOKEN;
1622   (*tp)++;
1623 }
1624
1625 static void encode_sb_rt(VP9_COMP *cpi, ThreadData *td,
1626                          const TileInfo *const tile,
1627                          TOKENEXTRA **tp, int mi_row, int mi_col,
1628                          int output_enabled, BLOCK_SIZE bsize,
1629                          PC_TREE *pc_tree) {
1630   VP9_COMMON *const cm = &cpi->common;
1631   MACROBLOCK *const x = &td->mb;
1632   MACROBLOCKD *const xd = &x->e_mbd;
1633
1634   const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1635   int ctx;
1636   PARTITION_TYPE partition;
1637   BLOCK_SIZE subsize;
1638
1639   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1640     return;
1641
1642   if (bsize >= BLOCK_8X8) {
1643     const int idx_str = xd->mi_stride * mi_row + mi_col;
1644     MODE_INFO *mi_8x8 = cm->mi[idx_str].src_mi;
1645     ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1646     subsize = mi_8x8[0].src_mi->mbmi.sb_type;
1647   } else {
1648     ctx = 0;
1649     subsize = BLOCK_4X4;
1650   }
1651
1652   partition = partition_lookup[bsl][subsize];
1653   if (output_enabled && bsize != BLOCK_4X4)
1654     td->counts->partition[ctx][partition]++;
1655
1656   switch (partition) {
1657     case PARTITION_NONE:
1658       encode_b_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize,
1659                   &pc_tree->none);
1660       break;
1661     case PARTITION_VERT:
1662       encode_b_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize,
1663                   &pc_tree->vertical[0]);
1664       if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
1665         encode_b_rt(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled,
1666                     subsize, &pc_tree->vertical[1]);
1667       }
1668       break;
1669     case PARTITION_HORZ:
1670       encode_b_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize,
1671                   &pc_tree->horizontal[0]);
1672       if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
1673         encode_b_rt(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled,
1674                     subsize, &pc_tree->horizontal[1]);
1675       }
1676       break;
1677     case PARTITION_SPLIT:
1678       subsize = get_subsize(bsize, PARTITION_SPLIT);
1679       encode_sb_rt(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize,
1680                    pc_tree->split[0]);
1681       encode_sb_rt(cpi, td, tile, tp, mi_row, mi_col + hbs, output_enabled,
1682                    subsize, pc_tree->split[1]);
1683       encode_sb_rt(cpi, td, tile, tp, mi_row + hbs, mi_col, output_enabled,
1684                    subsize, pc_tree->split[2]);
1685       encode_sb_rt(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs,
1686                    output_enabled, subsize, pc_tree->split[3]);
1687       break;
1688     default:
1689       assert(0 && "Invalid partition type.");
1690       break;
1691   }
1692
1693   if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1694     update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1695 }
1696
1697 static void rd_use_partition(VP9_COMP *cpi,
1698                              ThreadData *td,
1699                              TileDataEnc *tile_data,
1700                              MODE_INFO *mi_8x8, TOKENEXTRA **tp,
1701                              int mi_row, int mi_col,
1702                              BLOCK_SIZE bsize,
1703                              int *rate, int64_t *dist,
1704                              int do_recon, PC_TREE *pc_tree) {
1705   VP9_COMMON *const cm = &cpi->common;
1706   TileInfo *const tile_info = &tile_data->tile_info;
1707   MACROBLOCK *const x = &td->mb;
1708   MACROBLOCKD *const xd = &x->e_mbd;
1709   const int mis = cm->mi_stride;
1710   const int bsl = b_width_log2_lookup[bsize];
1711   const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2;
1712   const int bss = (1 << bsl) / 4;
1713   int i, pl;
1714   PARTITION_TYPE partition = PARTITION_NONE;
1715   BLOCK_SIZE subsize;
1716   ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1717   PARTITION_CONTEXT sl[8], sa[8];
1718   RD_COST last_part_rdc, none_rdc, chosen_rdc;
1719   BLOCK_SIZE sub_subsize = BLOCK_4X4;
1720   int splits_below = 0;
1721   BLOCK_SIZE bs_type = mi_8x8[0].src_mi->mbmi.sb_type;
1722   int do_partition_search = 1;
1723   PICK_MODE_CONTEXT *ctx = &pc_tree->none;
1724
1725   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1726     return;
1727
1728   assert(num_4x4_blocks_wide_lookup[bsize] ==
1729          num_4x4_blocks_high_lookup[bsize]);
1730
1731   vp9_rd_cost_reset(&last_part_rdc);
1732   vp9_rd_cost_reset(&none_rdc);
1733   vp9_rd_cost_reset(&chosen_rdc);
1734
1735   partition = partition_lookup[bsl][bs_type];
1736   subsize = get_subsize(bsize, partition);
1737
1738   pc_tree->partitioning = partition;
1739   save_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
1740
1741   if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode) {
1742     set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1743     x->mb_energy = vp9_block_energy(cpi, x, bsize);
1744   }
1745
1746   if (do_partition_search &&
1747       cpi->sf.partition_search_type == SEARCH_PARTITION &&
1748       cpi->sf.adjust_partitioning_from_last_frame) {
1749     // Check if any of the sub blocks are further split.
1750     if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
1751       sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
1752       splits_below = 1;
1753       for (i = 0; i < 4; i++) {
1754         int jj = i >> 1, ii = i & 0x01;
1755         MODE_INFO *this_mi = mi_8x8[jj * bss * mis + ii * bss].src_mi;
1756         if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
1757           splits_below = 0;
1758         }
1759       }
1760     }
1761
1762     // If partition is not none try none unless each of the 4 splits are split
1763     // even further..
1764     if (partition != PARTITION_NONE && !splits_below &&
1765         mi_row + (mi_step >> 1) < cm->mi_rows &&
1766         mi_col + (mi_step >> 1) < cm->mi_cols) {
1767       pc_tree->partitioning = PARTITION_NONE;
1768       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc, bsize,
1769                        ctx, INT64_MAX);
1770
1771       pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1772
1773       if (none_rdc.rate < INT_MAX) {
1774         none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
1775         none_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, none_rdc.rate,
1776                                  none_rdc.dist);
1777       }
1778
1779       restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
1780       mi_8x8[0].src_mi->mbmi.sb_type = bs_type;
1781       pc_tree->partitioning = partition;
1782     }
1783   }
1784
1785   switch (partition) {
1786     case PARTITION_NONE:
1787       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
1788                        bsize, ctx, INT64_MAX);
1789       break;
1790     case PARTITION_HORZ:
1791       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
1792                        subsize, &pc_tree->horizontal[0],
1793                        INT64_MAX);
1794       if (last_part_rdc.rate != INT_MAX &&
1795           bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
1796         RD_COST tmp_rdc;
1797         PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
1798         vp9_rd_cost_init(&tmp_rdc);
1799         update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
1800         encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
1801         rd_pick_sb_modes(cpi, tile_data, x,
1802                          mi_row + (mi_step >> 1), mi_col, &tmp_rdc,
1803                          subsize, &pc_tree->horizontal[1], INT64_MAX);
1804         if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
1805           vp9_rd_cost_reset(&last_part_rdc);
1806           break;
1807         }
1808         last_part_rdc.rate += tmp_rdc.rate;
1809         last_part_rdc.dist += tmp_rdc.dist;
1810         last_part_rdc.rdcost += tmp_rdc.rdcost;
1811       }
1812       break;
1813     case PARTITION_VERT:
1814       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
1815                        subsize, &pc_tree->vertical[0], INT64_MAX);
1816       if (last_part_rdc.rate != INT_MAX &&
1817           bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
1818         RD_COST tmp_rdc;
1819         PICK_MODE_CONTEXT *ctx = &pc_tree->vertical[0];
1820         vp9_rd_cost_init(&tmp_rdc);
1821         update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
1822         encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
1823         rd_pick_sb_modes(cpi, tile_data, x,
1824                          mi_row, mi_col + (mi_step >> 1), &tmp_rdc,
1825                          subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
1826                          INT64_MAX);
1827         if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
1828           vp9_rd_cost_reset(&last_part_rdc);
1829           break;
1830         }
1831         last_part_rdc.rate += tmp_rdc.rate;
1832         last_part_rdc.dist += tmp_rdc.dist;
1833         last_part_rdc.rdcost += tmp_rdc.rdcost;
1834       }
1835       break;
1836     case PARTITION_SPLIT:
1837       if (bsize == BLOCK_8X8) {
1838         rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
1839                          subsize, pc_tree->leaf_split[0], INT64_MAX);
1840         break;
1841       }
1842       last_part_rdc.rate = 0;
1843       last_part_rdc.dist = 0;
1844       last_part_rdc.rdcost = 0;
1845       for (i = 0; i < 4; i++) {
1846         int x_idx = (i & 1) * (mi_step >> 1);
1847         int y_idx = (i >> 1) * (mi_step >> 1);
1848         int jj = i >> 1, ii = i & 0x01;
1849         RD_COST tmp_rdc;
1850         if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1851           continue;
1852
1853         vp9_rd_cost_init(&tmp_rdc);
1854         rd_use_partition(cpi, td, tile_data,
1855                          mi_8x8 + jj * bss * mis + ii * bss, tp,
1856                          mi_row + y_idx, mi_col + x_idx, subsize,
1857                          &tmp_rdc.rate, &tmp_rdc.dist,
1858                          i != 3, pc_tree->split[i]);
1859         if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
1860           vp9_rd_cost_reset(&last_part_rdc);
1861           break;
1862         }
1863         last_part_rdc.rate += tmp_rdc.rate;
1864         last_part_rdc.dist += tmp_rdc.dist;
1865       }
1866       break;
1867     default:
1868       assert(0);
1869       break;
1870   }
1871
1872   pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1873   if (last_part_rdc.rate < INT_MAX) {
1874     last_part_rdc.rate += cpi->partition_cost[pl][partition];
1875     last_part_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
1876                                   last_part_rdc.rate, last_part_rdc.dist);
1877   }
1878
1879   if (do_partition_search
1880       && cpi->sf.adjust_partitioning_from_last_frame
1881       && cpi->sf.partition_search_type == SEARCH_PARTITION
1882       && partition != PARTITION_SPLIT && bsize > BLOCK_8X8
1883       && (mi_row + mi_step < cm->mi_rows ||
1884           mi_row + (mi_step >> 1) == cm->mi_rows)
1885       && (mi_col + mi_step < cm->mi_cols ||
1886           mi_col + (mi_step >> 1) == cm->mi_cols)) {
1887     BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
1888     chosen_rdc.rate = 0;
1889     chosen_rdc.dist = 0;
1890     restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
1891     pc_tree->partitioning = PARTITION_SPLIT;
1892
1893     // Split partition.
1894     for (i = 0; i < 4; i++) {
1895       int x_idx = (i & 1) * (mi_step >> 1);
1896       int y_idx = (i >> 1) * (mi_step >> 1);
1897       RD_COST tmp_rdc;
1898       ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1899       PARTITION_CONTEXT sl[8], sa[8];
1900
1901       if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1902         continue;
1903
1904       save_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
1905       pc_tree->split[i]->partitioning = PARTITION_NONE;
1906       rd_pick_sb_modes(cpi, tile_data, x,
1907                        mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
1908                        split_subsize, &pc_tree->split[i]->none, INT64_MAX);
1909
1910       restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
1911
1912       if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
1913         vp9_rd_cost_reset(&chosen_rdc);
1914         break;
1915       }
1916
1917       chosen_rdc.rate += tmp_rdc.rate;
1918       chosen_rdc.dist += tmp_rdc.dist;
1919
1920       if (i != 3)
1921         encode_sb(cpi, td, tile_info, tp,  mi_row + y_idx, mi_col + x_idx, 0,
1922                   split_subsize, pc_tree->split[i]);
1923
1924       pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
1925                                    split_subsize);
1926       chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
1927     }
1928     pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1929     if (chosen_rdc.rate < INT_MAX) {
1930       chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
1931       chosen_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
1932                                  chosen_rdc.rate, chosen_rdc.dist);
1933     }
1934   }
1935
1936   // If last_part is better set the partitioning to that.
1937   if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
1938     mi_8x8[0].src_mi->mbmi.sb_type = bsize;
1939     if (bsize >= BLOCK_8X8)
1940       pc_tree->partitioning = partition;
1941     chosen_rdc = last_part_rdc;
1942   }
1943   // If none was better set the partitioning to that.
1944   if (none_rdc.rdcost < chosen_rdc.rdcost) {
1945     if (bsize >= BLOCK_8X8)
1946       pc_tree->partitioning = PARTITION_NONE;
1947     chosen_rdc = none_rdc;
1948   }
1949
1950   restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
1951
1952   // We must have chosen a partitioning and encoding or we'll fail later on.
1953   // No other opportunities for success.
1954   if (bsize == BLOCK_64X64)
1955     assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
1956
1957   if (do_recon) {
1958     int output_enabled = (bsize == BLOCK_64X64);
1959     encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
1960               pc_tree);
1961   }
1962
1963   *rate = chosen_rdc.rate;
1964   *dist = chosen_rdc.dist;
1965 }
1966
1967 static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
1968   BLOCK_4X4,   BLOCK_4X4,   BLOCK_4X4,
1969   BLOCK_4X4,   BLOCK_4X4,   BLOCK_4X4,
1970   BLOCK_8X8,   BLOCK_8X8,   BLOCK_8X8,
1971   BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
1972   BLOCK_16X16
1973 };
1974
1975 static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
1976   BLOCK_8X8,   BLOCK_16X16, BLOCK_16X16,
1977   BLOCK_16X16, BLOCK_32X32, BLOCK_32X32,
1978   BLOCK_32X32, BLOCK_64X64, BLOCK_64X64,
1979   BLOCK_64X64, BLOCK_64X64, BLOCK_64X64,
1980   BLOCK_64X64
1981 };
1982
1983 // Look at all the mode_info entries for blocks that are part of this
1984 // partition and find the min and max values for sb_type.
1985 // At the moment this is designed to work on a 64x64 SB but could be
1986 // adjusted to use a size parameter.
1987 //
1988 // The min and max are assumed to have been initialized prior to calling this
1989 // function so repeat calls can accumulate a min and max of more than one sb64.
1990 static void get_sb_partition_size_range(MACROBLOCKD *xd, MODE_INFO *mi_8x8,
1991                                         BLOCK_SIZE *min_block_size,
1992                                         BLOCK_SIZE *max_block_size,
1993                                         int bs_hist[BLOCK_SIZES]) {
1994   int sb_width_in_blocks = MI_BLOCK_SIZE;
1995   int sb_height_in_blocks  = MI_BLOCK_SIZE;
1996   int i, j;
1997   int index = 0;
1998
1999   // Check the sb_type for each block that belongs to this region.
2000   for (i = 0; i < sb_height_in_blocks; ++i) {
2001     for (j = 0; j < sb_width_in_blocks; ++j) {
2002       MODE_INFO *mi = mi_8x8[index+j].src_mi;
2003       BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0;
2004       bs_hist[sb_type]++;
2005       *min_block_size = MIN(*min_block_size, sb_type);
2006       *max_block_size = MAX(*max_block_size, sb_type);
2007     }
2008     index += xd->mi_stride;
2009   }
2010 }
2011
2012 // Next square block size less or equal than current block size.
2013 static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2014   BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
2015   BLOCK_8X8, BLOCK_8X8, BLOCK_8X8,
2016   BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
2017   BLOCK_32X32, BLOCK_32X32, BLOCK_32X32,
2018   BLOCK_64X64
2019 };
2020
2021 // Look at neighboring blocks and set a min and max partition size based on
2022 // what they chose.
2023 static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
2024                                     MACROBLOCKD *const xd,
2025                                     int mi_row, int mi_col,
2026                                     BLOCK_SIZE *min_block_size,
2027                                     BLOCK_SIZE *max_block_size) {
2028   VP9_COMMON *const cm = &cpi->common;
2029   MODE_INFO *mi = xd->mi[0].src_mi;
2030   const int left_in_image = xd->left_available && mi[-1].src_mi;
2031   const int above_in_image = xd->up_available && mi[-xd->mi_stride].src_mi;
2032   const int row8x8_remaining = tile->mi_row_end - mi_row;
2033   const int col8x8_remaining = tile->mi_col_end - mi_col;
2034   int bh, bw;
2035   BLOCK_SIZE min_size = BLOCK_4X4;
2036   BLOCK_SIZE max_size = BLOCK_64X64;
2037   int i = 0;
2038   int bs_hist[BLOCK_SIZES] = {0};
2039
2040   // Trap case where we do not have a prediction.
2041   if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
2042     // Default "min to max" and "max to min"
2043     min_size = BLOCK_64X64;
2044     max_size = BLOCK_4X4;
2045
2046     // NOTE: each call to get_sb_partition_size_range() uses the previous
2047     // passed in values for min and max as a starting point.
2048     // Find the min and max partition used in previous frame at this location
2049     if (cm->frame_type != KEY_FRAME) {
2050       MODE_INFO *prev_mi =
2051           cm->prev_mip + cm->mi_stride + 1 + mi_row * xd->mi_stride + mi_col;
2052
2053       get_sb_partition_size_range(xd, prev_mi, &min_size, &max_size, bs_hist);
2054     }
2055     // Find the min and max partition sizes used in the left SB64
2056     if (left_in_image) {
2057       MODE_INFO *left_sb64_mi = mi[-MI_BLOCK_SIZE].src_mi;
2058       get_sb_partition_size_range(xd, left_sb64_mi, &min_size, &max_size,
2059                                   bs_hist);
2060     }
2061     // Find the min and max partition sizes used in the above SB64.
2062     if (above_in_image) {
2063       MODE_INFO *above_sb64_mi = mi[-xd->mi_stride * MI_BLOCK_SIZE].src_mi;
2064       get_sb_partition_size_range(xd, above_sb64_mi, &min_size, &max_size,
2065                                   bs_hist);
2066     }
2067
2068     // adjust observed min and max
2069     if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
2070       min_size = min_partition_size[min_size];
2071       max_size = max_partition_size[max_size];
2072     } else if (cpi->sf.auto_min_max_partition_size ==
2073                CONSTRAIN_NEIGHBORING_MIN_MAX) {
2074       // adjust the search range based on the histogram of the observed
2075       // partition sizes from left, above the previous co-located blocks
2076       int sum = 0;
2077       int first_moment = 0;
2078       int second_moment = 0;
2079       int var_unnormalized = 0;
2080
2081       for (i = 0; i < BLOCK_SIZES; i++) {
2082         sum += bs_hist[i];
2083         first_moment += bs_hist[i] * i;
2084         second_moment += bs_hist[i] * i * i;
2085       }
2086
2087       // if variance is small enough,
2088       // adjust the range around its mean size, which gives a tighter range
2089       var_unnormalized = second_moment - first_moment * first_moment / sum;
2090       if (var_unnormalized <= 4 * sum) {
2091         int mean = first_moment / sum;
2092         min_size = min_partition_size[mean];
2093         max_size = max_partition_size[mean];
2094       } else {
2095         min_size = min_partition_size[min_size];
2096         max_size = max_partition_size[max_size];
2097       }
2098     }
2099   }
2100
2101   // Check border cases where max and min from neighbors may not be legal.
2102   max_size = find_partition_size(max_size,
2103                                  row8x8_remaining, col8x8_remaining,
2104                                  &bh, &bw);
2105   min_size = MIN(min_size, max_size);
2106
2107   // When use_square_partition_only is true, make sure at least one square
2108   // partition is allowed by selecting the next smaller square size as
2109   // *min_block_size.
2110   if (cpi->sf.use_square_partition_only &&
2111       next_square_size[max_size] < min_size) {
2112      min_size = next_square_size[max_size];
2113   }
2114
2115   *min_block_size = min_size;
2116   *max_block_size = max_size;
2117 }
2118
2119 static void auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
2120                                  MACROBLOCKD *const xd,
2121                                  int mi_row, int mi_col,
2122                                  BLOCK_SIZE *min_block_size,
2123                                  BLOCK_SIZE *max_block_size) {
2124   VP9_COMMON *const cm = &cpi->common;
2125   MODE_INFO *mi_8x8 = xd->mi;
2126   const int left_in_image = xd->left_available && mi_8x8[-1].src_mi;
2127   const int above_in_image = xd->up_available &&
2128                              mi_8x8[-xd->mi_stride].src_mi;
2129   int row8x8_remaining = tile->mi_row_end - mi_row;
2130   int col8x8_remaining = tile->mi_col_end - mi_col;
2131   int bh, bw;
2132   BLOCK_SIZE min_size = BLOCK_32X32;
2133   BLOCK_SIZE max_size = BLOCK_8X8;
2134   int bsl = mi_width_log2_lookup[BLOCK_64X64];
2135   const int search_range_ctrl = (((mi_row + mi_col) >> bsl) +
2136                        get_chessboard_index(cm->current_video_frame)) & 0x1;
2137   // Trap case where we do not have a prediction.
2138   if (search_range_ctrl &&
2139       (left_in_image || above_in_image || cm->frame_type != KEY_FRAME)) {
2140     int block;
2141     MODE_INFO *mi;
2142     BLOCK_SIZE sb_type;
2143
2144     // Find the min and max partition sizes used in the left SB64.
2145     if (left_in_image) {
2146       MODE_INFO *cur_mi;
2147       mi = mi_8x8[-1].src_mi;
2148       for (block = 0; block < MI_BLOCK_SIZE; ++block) {
2149         cur_mi = mi[block * xd->mi_stride].src_mi;
2150         sb_type = cur_mi ? cur_mi->mbmi.sb_type : 0;
2151         min_size = MIN(min_size, sb_type);
2152         max_size = MAX(max_size, sb_type);
2153       }
2154     }
2155     // Find the min and max partition sizes used in the above SB64.
2156     if (above_in_image) {
2157       mi = mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE].src_mi;
2158       for (block = 0; block < MI_BLOCK_SIZE; ++block) {
2159         sb_type = mi[block].src_mi ? mi[block].src_mi->mbmi.sb_type : 0;
2160         min_size = MIN(min_size, sb_type);
2161         max_size = MAX(max_size, sb_type);
2162       }
2163     }
2164
2165     min_size = min_partition_size[min_size];
2166     max_size = find_partition_size(max_size, row8x8_remaining, col8x8_remaining,
2167                                    &bh, &bw);
2168     min_size = MIN(min_size, max_size);
2169     min_size = MAX(min_size, BLOCK_8X8);
2170     max_size = MIN(max_size, BLOCK_32X32);
2171   } else {
2172     min_size = BLOCK_8X8;
2173     max_size = BLOCK_32X32;
2174   }
2175
2176   *min_block_size = min_size;
2177   *max_block_size = max_size;
2178 }
2179
2180 // TODO(jingning) refactor functions setting partition search range
2181 static void set_partition_range(VP9_COMMON *cm, MACROBLOCKD *xd,
2182                                 int mi_row, int mi_col, BLOCK_SIZE bsize,
2183                                 BLOCK_SIZE *min_bs, BLOCK_SIZE *max_bs) {
2184   int mi_width  = num_8x8_blocks_wide_lookup[bsize];
2185   int mi_height = num_8x8_blocks_high_lookup[bsize];
2186   int idx, idy;
2187
2188   MODE_INFO *mi;
2189   const int idx_str = cm->mi_stride * mi_row + mi_col;
2190   MODE_INFO *prev_mi = (cm->prev_mip + cm->mi_stride + 1 + idx_str)->src_mi;
2191
2192
2193   BLOCK_SIZE bs, min_size, max_size;
2194
2195   min_size = BLOCK_64X64;
2196   max_size = BLOCK_4X4;
2197
2198   if (prev_mi) {
2199     for (idy = 0; idy < mi_height; ++idy) {
2200       for (idx = 0; idx < mi_width; ++idx) {
2201         mi = prev_mi[idy * cm->mi_stride + idx].src_mi;
2202         bs = mi ? mi->mbmi.sb_type : bsize;
2203         min_size = MIN(min_size, bs);
2204         max_size = MAX(max_size, bs);
2205       }
2206     }
2207   }
2208
2209   if (xd->left_available) {
2210     for (idy = 0; idy < mi_height; ++idy) {
2211       mi = xd->mi[idy * cm->mi_stride - 1].src_mi;
2212       bs = mi ? mi->mbmi.sb_type : bsize;
2213       min_size = MIN(min_size, bs);
2214       max_size = MAX(max_size, bs);
2215     }
2216   }
2217
2218   if (xd->up_available) {
2219     for (idx = 0; idx < mi_width; ++idx) {
2220       mi = xd->mi[idx - cm->mi_stride].src_mi;
2221       bs = mi ? mi->mbmi.sb_type : bsize;
2222       min_size = MIN(min_size, bs);
2223       max_size = MAX(max_size, bs);
2224     }
2225   }
2226
2227   if (min_size == max_size) {
2228     min_size = min_partition_size[min_size];
2229     max_size = max_partition_size[max_size];
2230   }
2231
2232   *min_bs = min_size;
2233   *max_bs = max_size;
2234 }
2235
2236 static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2237   vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
2238 }
2239
2240 static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2241   vpx_memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
2242 }
2243
2244 #if CONFIG_FP_MB_STATS
2245 const int num_16x16_blocks_wide_lookup[BLOCK_SIZES] =
2246   {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 4, 4};
2247 const int num_16x16_blocks_high_lookup[BLOCK_SIZES] =
2248   {1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 4, 2, 4};
2249 const int qindex_skip_threshold_lookup[BLOCK_SIZES] =
2250   {0, 10, 10, 30, 40, 40, 60, 80, 80, 90, 100, 100, 120};
2251 const int qindex_split_threshold_lookup[BLOCK_SIZES] =
2252   {0, 3, 3, 7, 15, 15, 30, 40, 40, 60, 80, 80, 120};
2253 const int complexity_16x16_blocks_threshold[BLOCK_SIZES] =
2254   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 6};
2255
2256 typedef enum {
2257   MV_ZERO = 0,
2258   MV_LEFT = 1,
2259   MV_UP = 2,
2260   MV_RIGHT = 3,
2261   MV_DOWN = 4,
2262   MV_INVALID
2263 } MOTION_DIRECTION;
2264
2265 static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
2266   if (fp_byte & FPMB_MOTION_ZERO_MASK) {
2267     return MV_ZERO;
2268   } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
2269     return MV_LEFT;
2270   } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
2271     return MV_RIGHT;
2272   } else if (fp_byte & FPMB_MOTION_UP_MASK) {
2273     return MV_UP;
2274   } else {
2275     return MV_DOWN;
2276   }
2277 }
2278
2279 static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
2280                                            MOTION_DIRECTION that_mv) {
2281   if (this_mv == that_mv) {
2282     return 0;
2283   } else {
2284     return abs(this_mv - that_mv) == 2 ? 2 : 1;
2285   }
2286 }
2287 #endif
2288
2289 // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
2290 // unlikely to be selected depending on previous rate-distortion optimization
2291 // results, for encoding speed-up.
2292 static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
2293                               TileDataEnc *tile_data,
2294                               TOKENEXTRA **tp, int mi_row, int mi_col,
2295                               BLOCK_SIZE bsize, RD_COST *rd_cost,
2296                               int64_t best_rd, PC_TREE *pc_tree) {
2297   VP9_COMMON *const cm = &cpi->common;
2298   TileInfo *const tile_info = &tile_data->tile_info;
2299   MACROBLOCK *const x = &td->mb;
2300   MACROBLOCKD *const xd = &x->e_mbd;
2301   const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
2302   ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
2303   PARTITION_CONTEXT sl[8], sa[8];
2304   TOKENEXTRA *tp_orig = *tp;
2305   PICK_MODE_CONTEXT *ctx = &pc_tree->none;
2306   int i, pl;
2307   BLOCK_SIZE subsize;
2308   RD_COST this_rdc, sum_rdc, best_rdc;
2309   int do_split = bsize >= BLOCK_8X8;
2310   int do_rect = 1;
2311
2312   // Override skipping rectangular partition operations for edge blocks
2313   const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
2314   const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
2315   const int xss = x->e_mbd.plane[1].subsampling_x;
2316   const int yss = x->e_mbd.plane[1].subsampling_y;
2317
2318   BLOCK_SIZE min_size = x->min_partition_size;
2319   BLOCK_SIZE max_size = x->max_partition_size;
2320
2321 #if CONFIG_FP_MB_STATS
2322   unsigned int src_diff_var = UINT_MAX;
2323   int none_complexity = 0;
2324 #endif
2325
2326   int partition_none_allowed = !force_horz_split && !force_vert_split;
2327   int partition_horz_allowed = !force_vert_split && yss <= xss &&
2328                                bsize >= BLOCK_8X8;
2329   int partition_vert_allowed = !force_horz_split && xss <= yss &&
2330                                bsize >= BLOCK_8X8;
2331   (void) *tp_orig;
2332
2333   assert(num_8x8_blocks_wide_lookup[bsize] ==
2334              num_8x8_blocks_high_lookup[bsize]);
2335
2336   vp9_rd_cost_init(&this_rdc);
2337   vp9_rd_cost_init(&sum_rdc);
2338   vp9_rd_cost_reset(&best_rdc);
2339   best_rdc.rdcost = best_rd;
2340
2341   set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2342
2343   if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode)
2344     x->mb_energy = vp9_block_energy(cpi, x, bsize);
2345
2346   if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
2347     int cb_partition_search_ctrl = ((pc_tree->index == 0 || pc_tree->index == 3)
2348         + get_chessboard_index(cm->current_video_frame)) & 0x1;
2349
2350     if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
2351       set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
2352   }
2353
2354   // Determine partition types in search according to the speed features.
2355   // The threshold set here has to be of square block size.
2356   if (cpi->sf.auto_min_max_partition_size) {
2357     partition_none_allowed &= (bsize <= max_size && bsize >= min_size);
2358     partition_horz_allowed &= ((bsize <= max_size && bsize > min_size) ||
2359                                 force_horz_split);
2360     partition_vert_allowed &= ((bsize <= max_size && bsize > min_size) ||
2361                                 force_vert_split);
2362     do_split &= bsize > min_size;
2363   }
2364   if (cpi->sf.use_square_partition_only) {
2365     partition_horz_allowed &= force_horz_split;
2366     partition_vert_allowed &= force_vert_split;
2367   }
2368
2369   save_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
2370
2371 #if CONFIG_FP_MB_STATS
2372   if (cpi->use_fp_mb_stats) {
2373     set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2374     src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src,
2375                                                   mi_row, mi_col, bsize);
2376   }
2377 #endif
2378
2379 #if CONFIG_FP_MB_STATS
2380   // Decide whether we shall split directly and skip searching NONE by using
2381   // the first pass block statistics
2382   if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_split &&
2383       partition_none_allowed && src_diff_var > 4 &&
2384       cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
2385     int mb_row = mi_row >> 1;
2386     int mb_col = mi_col >> 1;
2387     int mb_row_end =
2388         MIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
2389     int mb_col_end =
2390         MIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
2391     int r, c;
2392
2393     // compute a complexity measure, basically measure inconsistency of motion
2394     // vectors obtained from the first pass in the current block
2395     for (r = mb_row; r < mb_row_end ; r++) {
2396       for (c = mb_col; c < mb_col_end; c++) {
2397         const int mb_index = r * cm->mb_cols + c;
2398
2399         MOTION_DIRECTION this_mv;
2400         MOTION_DIRECTION right_mv;
2401         MOTION_DIRECTION bottom_mv;
2402
2403         this_mv =
2404             get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
2405
2406         // to its right
2407         if (c != mb_col_end - 1) {
2408           right_mv = get_motion_direction_fp(
2409               cpi->twopass.this_frame_mb_stats[mb_index + 1]);
2410           none_complexity += get_motion_inconsistency(this_mv, right_mv);
2411         }
2412
2413         // to its bottom
2414         if (r != mb_row_end - 1) {
2415           bottom_mv = get_motion_direction_fp(
2416               cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
2417           none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
2418         }
2419
2420         // do not count its left and top neighbors to avoid double counting
2421       }
2422     }
2423
2424     if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
2425       partition_none_allowed = 0;
2426     }
2427   }
2428 #endif
2429
2430   // PARTITION_NONE
2431   if (partition_none_allowed) {
2432     rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col,
2433                      &this_rdc, bsize, ctx, best_rdc.rdcost);
2434     if (this_rdc.rate != INT_MAX) {
2435       if (bsize >= BLOCK_8X8) {
2436         pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2437         this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2438         this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
2439                                  this_rdc.rate, this_rdc.dist);
2440       }
2441
2442       if (this_rdc.rdcost < best_rdc.rdcost) {
2443         int64_t dist_breakout_thr = cpi->sf.partition_search_breakout_dist_thr;
2444         int rate_breakout_thr = cpi->sf.partition_search_breakout_rate_thr;
2445
2446         best_rdc = this_rdc;
2447         if (bsize >= BLOCK_8X8)
2448           pc_tree->partitioning = PARTITION_NONE;
2449
2450         // Adjust dist breakout threshold according to the partition size.
2451         dist_breakout_thr >>= 8 - (b_width_log2_lookup[bsize] +
2452             b_height_log2_lookup[bsize]);
2453
2454         rate_breakout_thr *= num_pels_log2_lookup[bsize];
2455
2456         // If all y, u, v transform blocks in this partition are skippable, and
2457         // the dist & rate are within the thresholds, the partition search is
2458         // terminated for current branch of the partition search tree.
2459         // The dist & rate thresholds are set to 0 at speed 0 to disable the
2460         // early termination at that speed.
2461         if (!x->e_mbd.lossless &&
2462             (ctx->skippable && best_rdc.dist < dist_breakout_thr &&
2463             best_rdc.rate < rate_breakout_thr)) {
2464           do_split = 0;
2465           do_rect = 0;
2466         }
2467
2468 #if CONFIG_FP_MB_STATS
2469         // Check if every 16x16 first pass block statistics has zero
2470         // motion and the corresponding first pass residue is small enough.
2471         // If that is the case, check the difference variance between the
2472         // current frame and the last frame. If the variance is small enough,
2473         // stop further splitting in RD optimization
2474         if (cpi->use_fp_mb_stats && do_split != 0 &&
2475             cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
2476           int mb_row = mi_row >> 1;
2477           int mb_col = mi_col >> 1;
2478           int mb_row_end =
2479               MIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
2480           int mb_col_end =
2481               MIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
2482           int r, c;
2483
2484           int skip = 1;
2485           for (r = mb_row; r < mb_row_end; r++) {
2486             for (c = mb_col; c < mb_col_end; c++) {
2487               const int mb_index = r * cm->mb_cols + c;
2488               if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
2489                     FPMB_MOTION_ZERO_MASK) ||
2490                   !(cpi->twopass.this_frame_mb_stats[mb_index] &
2491                     FPMB_ERROR_SMALL_MASK)) {
2492                 skip = 0;
2493                 break;
2494               }
2495             }
2496             if (skip == 0) {
2497               break;
2498             }
2499           }
2500           if (skip) {
2501             if (src_diff_var == UINT_MAX) {
2502               set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2503               src_diff_var = get_sby_perpixel_diff_variance(
2504                   cpi, &x->plane[0].src, mi_row, mi_col, bsize);
2505             }
2506             if (src_diff_var < 8) {
2507               do_split = 0;
2508               do_rect = 0;
2509             }
2510           }
2511         }
2512 #endif
2513       }
2514     }
2515     restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
2516   }
2517
2518   // store estimated motion vector
2519   if (cpi->sf.adaptive_motion_search)
2520     store_pred_mv(x, ctx);
2521
2522   // PARTITION_SPLIT
2523   // TODO(jingning): use the motion vectors given by the above search as
2524   // the starting point of motion search in the following partition type check.
2525   if (do_split) {
2526     subsize = get_subsize(bsize, PARTITION_SPLIT);
2527     if (bsize == BLOCK_8X8) {
2528       i = 4;
2529       if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
2530         pc_tree->leaf_split[0]->pred_interp_filter =
2531             ctx->mic.mbmi.interp_filter;
2532       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
2533                        pc_tree->leaf_split[0], best_rdc.rdcost);
2534       if (sum_rdc.rate == INT_MAX)
2535         sum_rdc.rdcost = INT64_MAX;
2536     } else {
2537       for (i = 0; i < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++i) {
2538       const int x_idx = (i & 1) * mi_step;
2539       const int y_idx = (i >> 1) * mi_step;
2540
2541         if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2542           continue;
2543
2544         if (cpi->sf.adaptive_motion_search)
2545           load_pred_mv(x, ctx);
2546
2547         pc_tree->split[i]->index = i;
2548         rd_pick_partition(cpi, td, tile_data, tp,
2549                           mi_row + y_idx, mi_col + x_idx,
2550                           subsize, &this_rdc,
2551                           best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[i]);
2552
2553         if (this_rdc.rate == INT_MAX) {
2554           sum_rdc.rdcost = INT64_MAX;
2555           break;
2556         } else {
2557           sum_rdc.rate += this_rdc.rate;
2558           sum_rdc.dist += this_rdc.dist;
2559           sum_rdc.rdcost += this_rdc.rdcost;
2560         }
2561       }
2562     }
2563
2564     if (sum_rdc.rdcost < best_rdc.rdcost && i == 4) {
2565       pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2566       sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2567       sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
2568                               sum_rdc.rate, sum_rdc.dist);
2569
2570       if (sum_rdc.rdcost < best_rdc.rdcost) {
2571         best_rdc = sum_rdc;
2572         pc_tree->partitioning = PARTITION_SPLIT;
2573       }
2574     } else {
2575       // skip rectangular partition test when larger block size
2576       // gives better rd cost
2577       if (cpi->sf.less_rectangular_check)
2578         do_rect &= !partition_none_allowed;
2579     }
2580     restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
2581   }
2582
2583   // PARTITION_HORZ
2584   if (partition_horz_allowed && do_rect) {
2585     subsize = get_subsize(bsize, PARTITION_HORZ);
2586     if (cpi->sf.adaptive_motion_search)
2587       load_pred_mv(x, ctx);
2588     if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2589         partition_none_allowed)
2590       pc_tree->horizontal[0].pred_interp_filter =
2591           ctx->mic.mbmi.interp_filter;
2592     rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
2593                      &pc_tree->horizontal[0], best_rdc.rdcost);
2594
2595     if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + mi_step < cm->mi_rows &&
2596         bsize > BLOCK_8X8) {
2597       PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
2598       update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
2599       encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
2600
2601       if (cpi->sf.adaptive_motion_search)
2602         load_pred_mv(x, ctx);
2603       if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2604           partition_none_allowed)
2605         pc_tree->horizontal[1].pred_interp_filter =
2606             ctx->mic.mbmi.interp_filter;
2607       rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col,
2608                        &this_rdc, subsize, &pc_tree->horizontal[1],
2609                        best_rdc.rdcost - sum_rdc.rdcost);
2610       if (this_rdc.rate == INT_MAX) {
2611         sum_rdc.rdcost = INT64_MAX;
2612       } else {
2613         sum_rdc.rate += this_rdc.rate;
2614         sum_rdc.dist += this_rdc.dist;
2615         sum_rdc.rdcost += this_rdc.rdcost;
2616       }
2617     }
2618
2619     if (sum_rdc.rdcost < best_rdc.rdcost) {
2620       pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2621       sum_rdc.rate += cpi->partition_cost[pl][PARTITION_HORZ];
2622       sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
2623       if (sum_rdc.rdcost < best_rdc.rdcost) {
2624         best_rdc = sum_rdc;
2625         pc_tree->partitioning = PARTITION_HORZ;
2626       }
2627     }
2628     restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
2629   }
2630   // PARTITION_VERT
2631   if (partition_vert_allowed && do_rect) {
2632     subsize = get_subsize(bsize, PARTITION_VERT);
2633
2634     if (cpi->sf.adaptive_motion_search)
2635       load_pred_mv(x, ctx);
2636     if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2637         partition_none_allowed)
2638       pc_tree->vertical[0].pred_interp_filter =
2639           ctx->mic.mbmi.interp_filter;
2640     rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
2641                      &pc_tree->vertical[0], best_rdc.rdcost);
2642     if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + mi_step < cm->mi_cols &&
2643         bsize > BLOCK_8X8) {
2644       update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 0);
2645       encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize,
2646                         &pc_tree->vertical[0]);
2647
2648       if (cpi->sf.adaptive_motion_search)
2649         load_pred_mv(x, ctx);
2650       if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2651           partition_none_allowed)
2652         pc_tree->vertical[1].pred_interp_filter =
2653             ctx->mic.mbmi.interp_filter;
2654       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step,
2655                        &this_rdc, subsize,
2656                        &pc_tree->vertical[1], best_rdc.rdcost - sum_rdc.rdcost);
2657       if (this_rdc.rate == INT_MAX) {
2658         sum_rdc.rdcost = INT64_MAX;
2659       } else {
2660         sum_rdc.rate += this_rdc.rate;
2661         sum_rdc.dist += this_rdc.dist;
2662         sum_rdc.rdcost += this_rdc.rdcost;
2663       }
2664     }
2665
2666     if (sum_rdc.rdcost < best_rdc.rdcost) {
2667       pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2668       sum_rdc.rate += cpi->partition_cost[pl][PARTITION_VERT];
2669       sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
2670                               sum_rdc.rate, sum_rdc.dist);
2671       if (sum_rdc.rdcost < best_rdc.rdcost) {
2672         best_rdc = sum_rdc;
2673         pc_tree->partitioning = PARTITION_VERT;
2674       }
2675     }
2676     restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
2677   }
2678
2679   // TODO(jbb): This code added so that we avoid static analysis
2680   // warning related to the fact that best_rd isn't used after this
2681   // point.  This code should be refactored so that the duplicate
2682   // checks occur in some sub function and thus are used...
2683   (void) best_rd;
2684   *rd_cost = best_rdc;
2685
2686
2687   if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
2688       pc_tree->index != 3) {
2689     int output_enabled = (bsize == BLOCK_64X64);
2690     encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
2691               bsize, pc_tree);
2692   }
2693
2694   if (bsize == BLOCK_64X64) {
2695     assert(tp_orig < *tp);
2696     assert(best_rdc.rate < INT_MAX);
2697     assert(best_rdc.dist < INT64_MAX);
2698   } else {
2699     assert(tp_orig == *tp);
2700   }
2701 }
2702
2703 static void encode_rd_sb_row(VP9_COMP *cpi,
2704                              ThreadData *td,
2705                              TileDataEnc *tile_data,
2706                              int mi_row,
2707                              TOKENEXTRA **tp) {
2708   VP9_COMMON *const cm = &cpi->common;
2709   TileInfo *const tile_info = &tile_data->tile_info;
2710   MACROBLOCK *const x = &td->mb;
2711   MACROBLOCKD *const xd = &x->e_mbd;
2712   SPEED_FEATURES *const sf = &cpi->sf;
2713   int mi_col;
2714
2715   // Initialize the left context for the new SB row
2716   vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
2717   vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
2718
2719   // Code each SB in the row
2720   for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
2721        mi_col += MI_BLOCK_SIZE) {
2722     const struct segmentation *const seg = &cm->seg;
2723     int dummy_rate;
2724     int64_t dummy_dist;
2725     RD_COST dummy_rdc;
2726     int i;
2727     int seg_skip = 0;
2728
2729     const int idx_str = cm->mi_stride * mi_row + mi_col;
2730     MODE_INFO *mi = cm->mi + idx_str;
2731
2732     if (sf->adaptive_pred_interp_filter) {
2733       for (i = 0; i < 64; ++i)
2734         td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
2735
2736       for (i = 0; i < 64; ++i) {
2737         td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
2738         td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
2739         td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
2740         td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
2741       }
2742     }
2743
2744     vp9_zero(x->pred_mv);
2745     td->pc_root->index = 0;
2746
2747     if (seg->enabled) {
2748       const uint8_t *const map = seg->update_map ? cpi->segmentation_map
2749                                                  : cm->last_frame_seg_map;
2750       int segment_id = vp9_get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
2751       seg_skip = vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP);
2752     }
2753
2754     x->source_variance = UINT_MAX;
2755     if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
2756       const BLOCK_SIZE bsize =
2757           seg_skip ? BLOCK_64X64 : sf->always_this_block_size;
2758       set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
2759       set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
2760       rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
2761                        BLOCK_64X64, &dummy_rate, &dummy_dist, 1, td->pc_root);
2762     } else if (cpi->partition_search_skippable_frame) {
2763       BLOCK_SIZE bsize;
2764       set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
2765       bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
2766       set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
2767       rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
2768                        BLOCK_64X64, &dummy_rate, &dummy_dist, 1, td->pc_root);
2769     } else if (sf->partition_search_type == VAR_BASED_PARTITION &&
2770                cm->frame_type != KEY_FRAME) {
2771       choose_partitioning(cpi, tile_info, x, mi_row, mi_col);
2772       rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
2773                        BLOCK_64X64, &dummy_rate, &dummy_dist, 1, td->pc_root);
2774     } else {
2775       // If required set upper and lower partition size limits
2776       if (sf->auto_min_max_partition_size) {
2777         set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
2778         rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
2779                                 &x->min_partition_size,
2780                                 &x->max_partition_size);
2781       }
2782       rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, BLOCK_64X64,
2783                         &dummy_rdc, INT64_MAX, td->pc_root);
2784     }
2785   }
2786 }
2787
2788 static void init_encode_frame_mb_context(VP9_COMP *cpi) {
2789   MACROBLOCK *const x = &cpi->td.mb;
2790   VP9_COMMON *const cm = &cpi->common;
2791   MACROBLOCKD *const xd = &x->e_mbd;
2792   const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
2793
2794   // Copy data over into macro block data structures.
2795   vp9_setup_src_planes(x, cpi->Source, 0, 0);
2796
2797   vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
2798
2799   // Note: this memset assumes above_context[0], [1] and [2]
2800   // are allocated as part of the same buffer.
2801   vpx_memset(xd->above_context[0], 0,
2802              sizeof(*xd->above_context[0]) *
2803              2 * aligned_mi_cols * MAX_MB_PLANE);
2804   vpx_memset(xd->above_seg_context, 0,
2805              sizeof(*xd->above_seg_context) * aligned_mi_cols);
2806 }
2807
2808 static int check_dual_ref_flags(VP9_COMP *cpi) {
2809   const int ref_flags = cpi->ref_frame_flags;
2810
2811   if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
2812     return 0;
2813   } else {
2814     return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG)
2815         + !!(ref_flags & VP9_ALT_FLAG)) >= 2;
2816   }
2817 }
2818
2819 static void reset_skip_tx_size(VP9_COMMON *cm, TX_SIZE max_tx_size) {
2820   int mi_row, mi_col;
2821   const int mis = cm->mi_stride;
2822   MODE_INFO *mi_ptr = cm->mi;
2823
2824   for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
2825     for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
2826       if (mi_ptr[mi_col].src_mi->mbmi.tx_size > max_tx_size)
2827         mi_ptr[mi_col].src_mi->mbmi.tx_size = max_tx_size;
2828     }
2829   }
2830 }
2831
2832 static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
2833   if (frame_is_intra_only(&cpi->common))
2834     return INTRA_FRAME;
2835   else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
2836     return ALTREF_FRAME;
2837   else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
2838     return GOLDEN_FRAME;
2839   else
2840     return LAST_FRAME;
2841 }
2842
2843 static TX_MODE select_tx_mode(const VP9_COMP *cpi, MACROBLOCKD *const xd) {
2844   if (xd->lossless)
2845     return ONLY_4X4;
2846   if (cpi->common.frame_type == KEY_FRAME &&
2847       cpi->sf.use_nonrd_pick_mode &&
2848       cpi->sf.partition_search_type == VAR_BASED_PARTITION)
2849     return ALLOW_16X16;
2850   if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
2851     return ALLOW_32X32;
2852   else if (cpi->sf.tx_size_search_method == USE_FULL_RD||
2853            cpi->sf.tx_size_search_method == USE_TX_8X8)
2854     return TX_MODE_SELECT;
2855   else
2856     return cpi->common.tx_mode;
2857 }
2858
2859 static void hybrid_intra_mode_search(VP9_COMP *cpi, MACROBLOCK *const x,
2860                                      RD_COST *rd_cost, BLOCK_SIZE bsize,
2861                                      PICK_MODE_CONTEXT *ctx) {
2862   if (bsize < BLOCK_16X16)
2863     vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, INT64_MAX);
2864   else
2865     vp9_pick_intra_mode(cpi, x, rd_cost, bsize, ctx);
2866 }
2867
2868 static void nonrd_pick_sb_modes(VP9_COMP *cpi,
2869                                 TileDataEnc *tile_data, MACROBLOCK *const x,
2870                                 int mi_row, int mi_col, RD_COST *rd_cost,
2871                                 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
2872   VP9_COMMON *const cm = &cpi->common;
2873   TileInfo *const tile_info = &tile_data->tile_info;
2874   MACROBLOCKD *const xd = &x->e_mbd;
2875   MB_MODE_INFO *mbmi;
2876   set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2877   mbmi = &xd->mi[0].src_mi->mbmi;
2878   mbmi->sb_type = bsize;
2879
2880   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled)
2881     if (mbmi->segment_id)
2882       x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
2883
2884   if (cm->frame_type == KEY_FRAME)
2885     hybrid_intra_mode_search(cpi, x, rd_cost, bsize, ctx);
2886   else if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
2887     set_mode_info_seg_skip(x, cm->tx_mode, rd_cost, bsize);
2888   else if (bsize >= BLOCK_8X8)
2889     vp9_pick_inter_mode(cpi, x, tile_data, mi_row, mi_col,
2890                         rd_cost, bsize, ctx);
2891   else
2892     vp9_pick_inter_mode_sub8x8(cpi, x, tile_data, mi_row, mi_col,
2893                                rd_cost, bsize, ctx);
2894
2895   duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2896
2897   if (rd_cost->rate == INT_MAX)
2898     vp9_rd_cost_reset(rd_cost);
2899
2900   ctx->rate = rd_cost->rate;
2901   ctx->dist = rd_cost->dist;
2902 }
2903
2904 static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
2905                               int mi_row, int mi_col,
2906                               BLOCK_SIZE bsize,
2907                               PC_TREE *pc_tree) {
2908   MACROBLOCKD *xd = &x->e_mbd;
2909   int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
2910   PARTITION_TYPE partition = pc_tree->partitioning;
2911   BLOCK_SIZE subsize = get_subsize(bsize, partition);
2912
2913   assert(bsize >= BLOCK_8X8);
2914
2915   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
2916     return;
2917
2918   switch (partition) {
2919     case PARTITION_NONE:
2920       set_mode_info_offsets(cm, xd, mi_row, mi_col);
2921       *(xd->mi[0].src_mi) = pc_tree->none.mic;
2922       duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2923       break;
2924     case PARTITION_VERT:
2925       set_mode_info_offsets(cm, xd, mi_row, mi_col);
2926       *(xd->mi[0].src_mi) = pc_tree->vertical[0].mic;
2927       duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, subsize);
2928
2929       if (mi_col + hbs < cm->mi_cols) {
2930         set_mode_info_offsets(cm, xd, mi_row, mi_col + hbs);
2931         *(xd->mi[0].src_mi) = pc_tree->vertical[1].mic;
2932         duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, subsize);
2933       }
2934       break;
2935     case PARTITION_HORZ:
2936       set_mode_info_offsets(cm, xd, mi_row, mi_col);
2937       *(xd->mi[0].src_mi) = pc_tree->horizontal[0].mic;
2938       duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, subsize);
2939       if (mi_row + hbs < cm->mi_rows) {
2940         set_mode_info_offsets(cm, xd, mi_row + hbs, mi_col);
2941         *(xd->mi[0].src_mi) = pc_tree->horizontal[1].mic;
2942         duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, subsize);
2943       }
2944       break;
2945     case PARTITION_SPLIT: {
2946       fill_mode_info_sb(cm, x, mi_row, mi_col, subsize, pc_tree->split[0]);
2947       fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize,
2948                         pc_tree->split[1]);
2949       fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize,
2950                         pc_tree->split[2]);
2951       fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize,
2952                         pc_tree->split[3]);
2953       break;
2954     }
2955     default:
2956       break;
2957   }
2958 }
2959
2960 // Reset the prediction pixel ready flag recursively.
2961 static void pred_pixel_ready_reset(PC_TREE *pc_tree, BLOCK_SIZE bsize) {
2962   pc_tree->none.pred_pixel_ready = 0;
2963   pc_tree->horizontal[0].pred_pixel_ready = 0;
2964   pc_tree->horizontal[1].pred_pixel_ready = 0;
2965   pc_tree->vertical[0].pred_pixel_ready = 0;
2966   pc_tree->vertical[1].pred_pixel_ready = 0;
2967
2968   if (bsize > BLOCK_8X8) {
2969     BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
2970     int i;
2971     for (i = 0; i < 4; ++i)
2972       pred_pixel_ready_reset(pc_tree->split[i], subsize);
2973   }
2974 }
2975
2976 static void nonrd_pick_partition(VP9_COMP *cpi, ThreadData *td,
2977                                  TileDataEnc *tile_data,
2978                                  TOKENEXTRA **tp, int mi_row,
2979                                  int mi_col, BLOCK_SIZE bsize, RD_COST *rd_cost,
2980                                  int do_recon, int64_t best_rd,
2981                                  PC_TREE *pc_tree) {
2982   const SPEED_FEATURES *const sf = &cpi->sf;
2983   VP9_COMMON *const cm = &cpi->common;
2984   TileInfo *const tile_info = &tile_data->tile_info;
2985   MACROBLOCK *const x = &td->mb;
2986   MACROBLOCKD *const xd = &x->e_mbd;
2987   const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
2988   TOKENEXTRA *tp_orig = *tp;
2989   PICK_MODE_CONTEXT *ctx = &pc_tree->none;
2990   int i;
2991   BLOCK_SIZE subsize = bsize;
2992   RD_COST this_rdc, sum_rdc, best_rdc;
2993   int do_split = bsize >= BLOCK_8X8;
2994   int do_rect = 1;
2995   // Override skipping rectangular partition operations for edge blocks
2996   const int force_horz_split = (mi_row + ms >= cm->mi_rows);
2997   const int force_vert_split = (mi_col + ms >= cm->mi_cols);
2998   const int xss = x->e_mbd.plane[1].subsampling_x;
2999   const int yss = x->e_mbd.plane[1].subsampling_y;
3000
3001   int partition_none_allowed = !force_horz_split && !force_vert_split;
3002   int partition_horz_allowed = !force_vert_split && yss <= xss &&
3003                                bsize >= BLOCK_8X8;
3004   int partition_vert_allowed = !force_horz_split && xss <= yss &&
3005                                bsize >= BLOCK_8X8;
3006   (void) *tp_orig;
3007
3008   assert(num_8x8_blocks_wide_lookup[bsize] ==
3009              num_8x8_blocks_high_lookup[bsize]);
3010
3011   vp9_rd_cost_init(&sum_rdc);
3012   vp9_rd_cost_reset(&best_rdc);
3013   best_rdc.rdcost = best_rd;
3014
3015   // Determine partition types in search according to the speed features.
3016   // The threshold set here has to be of square block size.
3017   if (sf->auto_min_max_partition_size) {
3018     partition_none_allowed &= (bsize <= x->max_partition_size &&
3019                                bsize >= x->min_partition_size);
3020     partition_horz_allowed &= ((bsize <= x->max_partition_size &&
3021                                 bsize > x->min_partition_size) ||
3022                                 force_horz_split);
3023     partition_vert_allowed &= ((bsize <= x->max_partition_size &&
3024                                 bsize > x->min_partition_size) ||
3025                                 force_vert_split);
3026     do_split &= bsize > x->min_partition_size;
3027   }
3028   if (sf->use_square_partition_only) {
3029     partition_horz_allowed &= force_horz_split;
3030     partition_vert_allowed &= force_vert_split;
3031   }
3032
3033   ctx->pred_pixel_ready = !(partition_vert_allowed ||
3034                             partition_horz_allowed ||
3035                             do_split);
3036
3037   // PARTITION_NONE
3038   if (partition_none_allowed) {
3039     nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col,
3040                         &this_rdc, bsize, ctx);
3041     ctx->mic.mbmi = xd->mi[0].src_mi->mbmi;
3042     ctx->skip_txfm[0] = x->skip_txfm[0];
3043     ctx->skip = x->skip;
3044
3045     if (this_rdc.rate != INT_MAX) {
3046       int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3047       this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
3048       this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
3049                               this_rdc.rate, this_rdc.dist);
3050       if (this_rdc.rdcost < best_rdc.rdcost) {
3051         int64_t dist_breakout_thr = sf->partition_search_breakout_dist_thr;
3052         int64_t rate_breakout_thr = sf->partition_search_breakout_rate_thr;
3053
3054         dist_breakout_thr >>= 8 - (b_width_log2_lookup[bsize] +
3055             b_height_log2_lookup[bsize]);
3056
3057         rate_breakout_thr *= num_pels_log2_lookup[bsize];
3058
3059         best_rdc = this_rdc;
3060         if (bsize >= BLOCK_8X8)
3061           pc_tree->partitioning = PARTITION_NONE;
3062
3063         if (!x->e_mbd.lossless &&
3064             this_rdc.rate < rate_breakout_thr &&
3065             this_rdc.dist < dist_breakout_thr) {
3066           do_split = 0;
3067           do_rect = 0;
3068         }
3069       }
3070     }
3071   }
3072
3073   // store estimated motion vector
3074   store_pred_mv(x, ctx);
3075
3076   // PARTITION_SPLIT
3077   if (do_split) {
3078     int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3079     sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
3080     sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3081     subsize = get_subsize(bsize, PARTITION_SPLIT);
3082     for (i = 0; i < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++i) {
3083       const int x_idx = (i & 1) * ms;
3084       const int y_idx = (i >> 1) * ms;
3085
3086       if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3087         continue;
3088       load_pred_mv(x, ctx);
3089       nonrd_pick_partition(cpi, td, tile_data, tp,
3090                            mi_row + y_idx, mi_col + x_idx,
3091                            subsize, &this_rdc, 0,
3092                            best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[i]);
3093
3094       if (this_rdc.rate == INT_MAX) {
3095         vp9_rd_cost_reset(&sum_rdc);
3096       } else {
3097         sum_rdc.rate += this_rdc.rate;
3098         sum_rdc.dist += this_rdc.dist;
3099         sum_rdc.rdcost += this_rdc.rdcost;
3100       }
3101     }
3102
3103     if (sum_rdc.rdcost < best_rdc.rdcost) {
3104       best_rdc = sum_rdc;
3105       pc_tree->partitioning = PARTITION_SPLIT;
3106     } else {
3107       // skip rectangular partition test when larger block size
3108       // gives better rd cost
3109       if (sf->less_rectangular_check)
3110         do_rect &= !partition_none_allowed;
3111     }
3112   }
3113
3114   // PARTITION_HORZ
3115   if (partition_horz_allowed && do_rect) {
3116     subsize = get_subsize(bsize, PARTITION_HORZ);
3117     if (sf->adaptive_motion_search)
3118       load_pred_mv(x, ctx);
3119     pc_tree->horizontal[0].pred_pixel_ready = 1;
3120     nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
3121                         &pc_tree->horizontal[0]);
3122
3123     pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
3124     pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
3125     pc_tree->horizontal[0].skip = x->skip;
3126
3127     if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + ms < cm->mi_rows) {
3128       load_pred_mv(x, ctx);
3129       pc_tree->horizontal[1].pred_pixel_ready = 1;
3130       nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + ms, mi_col,
3131                           &this_rdc, subsize,
3132                           &pc_tree->horizontal[1]);
3133
3134       pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
3135       pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
3136       pc_tree->horizontal[1].skip = x->skip;
3137
3138       if (this_rdc.rate == INT_MAX) {
3139         vp9_rd_cost_reset(&sum_rdc);
3140       } else {
3141         int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3142         this_rdc.rate += cpi->partition_cost[pl][PARTITION_HORZ];
3143         sum_rdc.rate += this_rdc.rate;
3144         sum_rdc.dist += this_rdc.dist;
3145         sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
3146                                 sum_rdc.rate, sum_rdc.dist);
3147       }
3148     }
3149
3150     if (sum_rdc.rdcost < best_rdc.rdcost) {
3151       best_rdc = sum_rdc;
3152       pc_tree->partitioning = PARTITION_HORZ;
3153     } else {
3154       pred_pixel_ready_reset(pc_tree, bsize);
3155     }
3156   }
3157
3158   // PARTITION_VERT
3159   if (partition_vert_allowed && do_rect) {
3160     subsize = get_subsize(bsize, PARTITION_VERT);
3161     if (sf->adaptive_motion_search)
3162       load_pred_mv(x, ctx);
3163     pc_tree->vertical[0].pred_pixel_ready = 1;
3164     nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
3165                         &pc_tree->vertical[0]);
3166     pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
3167     pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
3168     pc_tree->vertical[0].skip = x->skip;
3169
3170     if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + ms < cm->mi_cols) {
3171       load_pred_mv(x, ctx);
3172       pc_tree->vertical[1].pred_pixel_ready = 1;
3173       nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + ms,
3174                           &this_rdc, subsize,
3175                           &pc_tree->vertical[1]);
3176       pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
3177       pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
3178       pc_tree->vertical[1].skip = x->skip;
3179
3180       if (this_rdc.rate == INT_MAX) {
3181         vp9_rd_cost_reset(&sum_rdc);
3182       } else {
3183         int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3184         sum_rdc.rate += cpi->partition_cost[pl][PARTITION_VERT];
3185         sum_rdc.rate += this_rdc.rate;
3186         sum_rdc.dist += this_rdc.dist;
3187         sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
3188                                 sum_rdc.rate, sum_rdc.dist);
3189       }
3190     }
3191
3192     if (sum_rdc.rdcost < best_rdc.rdcost) {
3193       best_rdc = sum_rdc;
3194       pc_tree->partitioning = PARTITION_VERT;
3195     } else {
3196       pred_pixel_ready_reset(pc_tree, bsize);
3197     }
3198   }
3199
3200   *rd_cost = best_rdc;
3201
3202   if (best_rdc.rate == INT_MAX) {
3203     vp9_rd_cost_reset(rd_cost);
3204     return;
3205   }
3206
3207   // update mode info array
3208   fill_mode_info_sb(cm, x, mi_row, mi_col, bsize, pc_tree);
3209
3210   if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && do_recon) {
3211     int output_enabled = (bsize == BLOCK_64X64);
3212     encode_sb_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
3213                  bsize, pc_tree);
3214   }
3215
3216   if (bsize == BLOCK_64X64 && do_recon) {
3217     assert(tp_orig < *tp);
3218     assert(best_rdc.rate < INT_MAX);
3219     assert(best_rdc.dist < INT64_MAX);
3220   } else {
3221     assert(tp_orig == *tp);
3222   }
3223 }
3224
3225 static void nonrd_select_partition(VP9_COMP *cpi,
3226                                    ThreadData *td,
3227                                    TileDataEnc *tile_data,
3228                                    MODE_INFO *mi,
3229                                    TOKENEXTRA **tp,
3230                                    int mi_row, int mi_col,
3231                                    BLOCK_SIZE bsize, int output_enabled,
3232                                    RD_COST *rd_cost, PC_TREE *pc_tree) {
3233   VP9_COMMON *const cm = &cpi->common;
3234   TileInfo *const tile_info = &tile_data->tile_info;
3235   MACROBLOCK *const x = &td->mb;
3236   MACROBLOCKD *const xd = &x->e_mbd;
3237   const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
3238   const int mis = cm->mi_stride;
3239   PARTITION_TYPE partition;
3240   BLOCK_SIZE subsize;
3241   RD_COST this_rdc;
3242
3243   vp9_rd_cost_reset(&this_rdc);
3244   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
3245     return;
3246
3247   subsize = (bsize >= BLOCK_8X8) ? mi[0].src_mi->mbmi.sb_type : BLOCK_4X4;
3248   partition = partition_lookup[bsl][subsize];
3249
3250   if (bsize == BLOCK_32X32 && partition != PARTITION_NONE &&
3251       subsize >= BLOCK_16X16) {
3252     x->max_partition_size = BLOCK_32X32;
3253     x->min_partition_size = BLOCK_8X8;
3254     nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize,
3255                          rd_cost, 0, INT64_MAX, pc_tree);
3256   } else if (bsize == BLOCK_16X16 && partition != PARTITION_NONE) {
3257     x->max_partition_size = BLOCK_16X16;
3258     x->min_partition_size = BLOCK_8X8;
3259     nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize,
3260                          rd_cost, 0, INT64_MAX, pc_tree);
3261   } else {
3262     switch (partition) {
3263       case PARTITION_NONE:
3264         pc_tree->none.pred_pixel_ready = 1;
3265         nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost,
3266                             subsize, &pc_tree->none);
3267         pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
3268         pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
3269         pc_tree->none.skip = x->skip;
3270         break;
3271       case PARTITION_VERT:
3272         pc_tree->vertical[0].pred_pixel_ready = 1;
3273         nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost,
3274                             subsize, &pc_tree->vertical[0]);
3275         pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
3276         pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
3277         pc_tree->vertical[0].skip = x->skip;
3278         if (mi_col + hbs < cm->mi_cols) {
3279           pc_tree->vertical[1].pred_pixel_ready = 1;
3280           nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs,
3281                               &this_rdc, subsize, &pc_tree->vertical[1]);
3282           pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
3283           pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
3284           pc_tree->vertical[1].skip = x->skip;
3285           if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
3286               rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
3287             rd_cost->rate += this_rdc.rate;
3288             rd_cost->dist += this_rdc.dist;
3289           }
3290         }
3291         break;
3292       case PARTITION_HORZ:
3293         pc_tree->horizontal[0].pred_pixel_ready = 1;
3294         nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost,
3295                             subsize, &pc_tree->horizontal[0]);
3296         pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
3297         pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
3298         pc_tree->horizontal[0].skip = x->skip;
3299         if (mi_row + hbs < cm->mi_rows) {
3300           pc_tree->horizontal[1].pred_pixel_ready = 1;
3301           nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col,
3302                               &this_rdc, subsize, &pc_tree->horizontal[1]);
3303           pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
3304           pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
3305           pc_tree->horizontal[1].skip = x->skip;
3306           if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
3307               rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
3308             rd_cost->rate += this_rdc.rate;
3309             rd_cost->dist += this_rdc.dist;
3310           }
3311         }
3312         break;
3313       case PARTITION_SPLIT:
3314         subsize = get_subsize(bsize, PARTITION_SPLIT);
3315         nonrd_select_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
3316                                subsize, output_enabled, rd_cost,
3317                                pc_tree->split[0]);
3318         nonrd_select_partition(cpi, td, tile_data, mi + hbs, tp,
3319                                mi_row, mi_col + hbs, subsize, output_enabled,
3320                                &this_rdc, pc_tree->split[1]);
3321         if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
3322             rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
3323           rd_cost->rate += this_rdc.rate;
3324           rd_cost->dist += this_rdc.dist;
3325         }
3326         nonrd_select_partition(cpi, td, tile_data, mi + hbs * mis, tp,
3327                                mi_row + hbs, mi_col, subsize, output_enabled,
3328                                &this_rdc, pc_tree->split[2]);
3329         if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
3330             rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
3331           rd_cost->rate += this_rdc.rate;
3332           rd_cost->dist += this_rdc.dist;
3333         }
3334         nonrd_select_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp,
3335                                mi_row + hbs, mi_col + hbs, subsize,
3336                                output_enabled, &this_rdc, pc_tree->split[3]);
3337         if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
3338             rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
3339           rd_cost->rate += this_rdc.rate;
3340           rd_cost->dist += this_rdc.dist;
3341         }
3342         break;
3343       default:
3344         assert(0 && "Invalid partition type.");
3345         break;
3346     }
3347   }
3348
3349   if (bsize == BLOCK_64X64 && output_enabled)
3350     encode_sb_rt(cpi, td, tile_info, tp, mi_row, mi_col, 1, bsize, pc_tree);
3351 }
3352
3353
3354 static void nonrd_use_partition(VP9_COMP *cpi,
3355                                 ThreadData *td,
3356                                 TileDataEnc *tile_data,
3357                                 MODE_INFO *mi,
3358                                 TOKENEXTRA **tp,
3359                                 int mi_row, int mi_col,
3360                                 BLOCK_SIZE bsize, int output_enabled,
3361                                 RD_COST *dummy_cost, PC_TREE *pc_tree) {
3362   VP9_COMMON *const cm = &cpi->common;
3363   TileInfo *tile_info = &tile_data->tile_info;
3364   MACROBLOCK *const x = &td->mb;
3365   MACROBLOCKD *const xd = &x->e_mbd;
3366   const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
3367   const int mis = cm->mi_stride;
3368   PARTITION_TYPE partition;
3369   BLOCK_SIZE subsize;
3370
3371   if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
3372     return;
3373
3374   subsize = (bsize >= BLOCK_8X8) ? mi[0].src_mi->mbmi.sb_type : BLOCK_4X4;
3375   partition = partition_lookup[bsl][subsize];
3376
3377   if (output_enabled && bsize != BLOCK_4X4) {
3378     int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
3379     td->counts->partition[ctx][partition]++;
3380   }
3381
3382   switch (partition) {
3383     case PARTITION_NONE:
3384       pc_tree->none.pred_pixel_ready = 1;
3385       nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
3386                           subsize, &pc_tree->none);
3387       pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
3388       pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
3389       pc_tree->none.skip = x->skip;
3390       encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
3391                   subsize, &pc_tree->none);
3392       break;
3393     case PARTITION_VERT:
3394       pc_tree->vertical[0].pred_pixel_ready = 1;
3395       nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
3396                           subsize, &pc_tree->vertical[0]);
3397       pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
3398       pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
3399       pc_tree->vertical[0].skip = x->skip;
3400       encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
3401                   subsize, &pc_tree->vertical[0]);
3402       if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
3403         pc_tree->vertical[1].pred_pixel_ready = 1;
3404         nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs,
3405                             dummy_cost, subsize, &pc_tree->vertical[1]);
3406         pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
3407         pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
3408         pc_tree->vertical[1].skip = x->skip;
3409         encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col + hbs,
3410                     output_enabled, subsize, &pc_tree->vertical[1]);
3411       }
3412       break;
3413     case PARTITION_HORZ:
3414       pc_tree->horizontal[0].pred_pixel_ready = 1;
3415       nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
3416                           subsize, &pc_tree->horizontal[0]);
3417       pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
3418       pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
3419       pc_tree->horizontal[0].skip = x->skip;
3420       encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
3421                   subsize, &pc_tree->horizontal[0]);
3422
3423       if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
3424         pc_tree->horizontal[1].pred_pixel_ready = 1;
3425         nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col,
3426                             dummy_cost, subsize, &pc_tree->horizontal[1]);
3427         pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
3428         pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
3429         pc_tree->horizontal[1].skip = x->skip;
3430         encode_b_rt(cpi, td, tile_info, tp, mi_row + hbs, mi_col,
3431                     output_enabled, subsize, &pc_tree->horizontal[1]);
3432       }
3433       break;
3434     case PARTITION_SPLIT:
3435       subsize = get_subsize(bsize, PARTITION_SPLIT);
3436       if (bsize == BLOCK_8X8) {
3437         nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
3438                             subsize, pc_tree->leaf_split[0]);
3439         encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col,
3440                     output_enabled, subsize, pc_tree->leaf_split[0]);
3441       } else {
3442         nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
3443                             subsize, output_enabled, dummy_cost,
3444                             pc_tree->split[0]);
3445         nonrd_use_partition(cpi, td, tile_data, mi + hbs, tp,
3446                             mi_row, mi_col + hbs, subsize, output_enabled,
3447                             dummy_cost, pc_tree->split[1]);
3448         nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis, tp,
3449                             mi_row + hbs, mi_col, subsize, output_enabled,
3450                             dummy_cost, pc_tree->split[2]);
3451         nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp,
3452                             mi_row + hbs, mi_col + hbs, subsize, output_enabled,
3453                             dummy_cost, pc_tree->split[3]);
3454       }
3455       break;
3456     default:
3457       assert(0 && "Invalid partition type.");
3458       break;
3459   }
3460
3461   if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
3462     update_partition_context(xd, mi_row, mi_col, subsize, bsize);
3463 }
3464
3465 static void encode_nonrd_sb_row(VP9_COMP *cpi,
3466                                 ThreadData *td,
3467                                 TileDataEnc *tile_data,
3468                                 int mi_row,
3469                                 TOKENEXTRA **tp) {
3470   SPEED_FEATURES *const sf = &cpi->sf;
3471   VP9_COMMON *const cm = &cpi->common;
3472   TileInfo *const tile_info = &tile_data->tile_info;
3473   MACROBLOCK *const x = &td->mb;
3474   MACROBLOCKD *const xd = &x->e_mbd;
3475   int mi_col;
3476
3477   // Initialize the left context for the new SB row
3478   vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
3479   vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
3480
3481   // Code each SB in the row
3482   for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
3483        mi_col += MI_BLOCK_SIZE) {
3484     const struct segmentation *const seg = &cm->seg;
3485     RD_COST dummy_rdc;
3486     const int idx_str = cm->mi_stride * mi_row + mi_col;
3487     MODE_INFO *mi = cm->mi + idx_str;
3488     PARTITION_SEARCH_TYPE partition_search_type = sf->partition_search_type;
3489     BLOCK_SIZE bsize = BLOCK_64X64;
3490     int seg_skip = 0;
3491     x->source_variance = UINT_MAX;
3492     vp9_zero(x->pred_mv);
3493     vp9_rd_cost_init(&dummy_rdc);
3494     x->color_sensitivity[0] = 0;
3495     x->color_sensitivity[1] = 0;
3496
3497     if (seg->enabled) {
3498       const uint8_t *const map = seg->update_map ? cpi->segmentation_map
3499                                                  : cm->last_frame_seg_map;
3500       int segment_id = vp9_get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
3501       seg_skip = vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP);
3502       if (seg_skip) {
3503         partition_search_type = FIXED_PARTITION;
3504       }
3505     }
3506
3507     // Set the partition type of the 64X64 block
3508     switch (partition_search_type) {
3509       case VAR_BASED_PARTITION:
3510         // TODO(jingning, marpan): The mode decision and encoding process
3511         // support both intra and inter sub8x8 block coding for RTC mode.
3512         // Tune the thresholds accordingly to use sub8x8 block coding for
3513         // coding performance improvement.
3514         choose_partitioning(cpi, tile_info, x, mi_row, mi_col);
3515         nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
3516                             BLOCK_64X64, 1, &dummy_rdc, td->pc_root);
3517         break;
3518       case SOURCE_VAR_BASED_PARTITION:
3519         set_source_var_based_partition(cpi, tile_info, x, mi, mi_row, mi_col);
3520         nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
3521                             BLOCK_64X64, 1, &dummy_rdc, td->pc_root);
3522         break;
3523       case FIXED_PARTITION:
3524         if (!seg_skip)
3525           bsize = sf->always_this_block_size;
3526         set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
3527         nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
3528                             BLOCK_64X64, 1, &dummy_rdc, td->pc_root);
3529         break;
3530       case REFERENCE_PARTITION:
3531         set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
3532         if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
3533             xd->mi[0].src_mi->mbmi.segment_id) {
3534           x->max_partition_size = BLOCK_64X64;
3535           x->min_partition_size = BLOCK_8X8;
3536           nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col,
3537                                BLOCK_64X64, &dummy_rdc, 1,
3538                                INT64_MAX, td->pc_root);
3539         } else {
3540           choose_partitioning(cpi, tile_info, x, mi_row, mi_col);
3541           nonrd_select_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
3542                                  BLOCK_64X64, 1, &dummy_rdc, td->pc_root);
3543         }
3544
3545         break;
3546       default:
3547         assert(0);
3548         break;
3549     }
3550   }
3551 }
3552 // end RTC play code
3553
3554 static int set_var_thresh_from_histogram(VP9_COMP *cpi) {
3555   const SPEED_FEATURES *const sf = &cpi->sf;
3556   const VP9_COMMON *const cm = &cpi->common;
3557
3558   const uint8_t *src = cpi->Source->y_buffer;
3559   const uint8_t *last_src = cpi->Last_Source->y_buffer;
3560   const int src_stride = cpi->Source->y_stride;
3561   const int last_stride = cpi->Last_Source->y_stride;
3562
3563   // Pick cutoff threshold
3564   const int cutoff = (MIN(cm->width, cm->height) >= 720) ?
3565       (cm->MBs * VAR_HIST_LARGE_CUT_OFF / 100) :
3566       (cm->MBs * VAR_HIST_SMALL_CUT_OFF / 100);
3567   DECLARE_ALIGNED_ARRAY(16, int, hist, VAR_HIST_BINS);
3568   diff *var16 = cpi->source_diff_var;
3569
3570   int sum = 0;
3571   int i, j;
3572
3573   vpx_memset(hist, 0, VAR_HIST_BINS * sizeof(hist[0]));
3574
3575   for (i = 0; i < cm->mb_rows; i++) {
3576     for (j = 0; j < cm->mb_cols; j++) {
3577 #if CONFIG_VP9_HIGHBITDEPTH
3578       if (cm->use_highbitdepth) {
3579         switch (cm->bit_depth) {
3580           case VPX_BITS_8:
3581             vp9_highbd_get16x16var(src, src_stride, last_src, last_stride,
3582                                    &var16->sse, &var16->sum);
3583             break;
3584           case VPX_BITS_10:
3585             vp9_highbd_10_get16x16var(src, src_stride, last_src, last_stride,
3586                                     &var16->sse, &var16->sum);
3587             break;
3588           case VPX_BITS_12:
3589             vp9_highbd_12_get16x16var(src, src_stride, last_src, last_stride,
3590                                       &var16->sse, &var16->sum);
3591             break;
3592           default:
3593             assert(0 && "cm->bit_depth should be VPX_BITS_8, VPX_BITS_10"
3594                    " or VPX_BITS_12");
3595             return -1;
3596         }
3597       } else {
3598         vp9_get16x16var(src, src_stride, last_src, last_stride,
3599                         &var16->sse, &var16->sum);
3600       }
3601 #else
3602       vp9_get16x16var(src, src_stride, last_src, last_stride,
3603                       &var16->sse, &var16->sum);
3604 #endif  // CONFIG_VP9_HIGHBITDEPTH
3605       var16->var = var16->sse -
3606           (((uint32_t)var16->sum * var16->sum) >> 8);
3607
3608       if (var16->var >= VAR_HIST_MAX_BG_VAR)
3609         hist[VAR_HIST_BINS - 1]++;
3610       else
3611         hist[var16->var / VAR_HIST_FACTOR]++;
3612
3613       src += 16;
3614       last_src += 16;
3615       var16++;
3616     }
3617
3618     src = src - cm->mb_cols * 16 + 16 * src_stride;
3619     last_src = last_src - cm->mb_cols * 16 + 16 * last_stride;
3620   }
3621
3622   cpi->source_var_thresh = 0;
3623
3624   if (hist[VAR_HIST_BINS - 1] < cutoff) {
3625     for (i = 0; i < VAR_HIST_BINS - 1; i++) {
3626       sum += hist[i];
3627
3628       if (sum > cutoff) {
3629         cpi->source_var_thresh = (i + 1) * VAR_HIST_FACTOR;
3630         return 0;
3631       }
3632     }
3633   }
3634
3635   return sf->search_type_check_frequency;
3636 }
3637
3638 static void source_var_based_partition_search_method(VP9_COMP *cpi) {
3639   VP9_COMMON *const cm = &cpi->common;
3640   SPEED_FEATURES *const sf = &cpi->sf;
3641
3642   if (cm->frame_type == KEY_FRAME) {
3643     // For key frame, use SEARCH_PARTITION.
3644     sf->partition_search_type = SEARCH_PARTITION;
3645   } else if (cm->intra_only) {
3646     sf->partition_search_type = FIXED_PARTITION;
3647   } else {
3648     if (cm->last_width != cm->width || cm->last_height != cm->height) {
3649       if (cpi->source_diff_var)
3650         vpx_free(cpi->source_diff_var);
3651
3652       CHECK_MEM_ERROR(cm, cpi->source_diff_var,
3653                       vpx_calloc(cm->MBs, sizeof(diff)));
3654     }
3655
3656     if (!cpi->frames_till_next_var_check)
3657       cpi->frames_till_next_var_check = set_var_thresh_from_histogram(cpi);
3658
3659     if (cpi->frames_till_next_var_check > 0) {
3660       sf->partition_search_type = FIXED_PARTITION;
3661       cpi->frames_till_next_var_check--;
3662     }
3663   }
3664 }
3665
3666 static int get_skip_encode_frame(const VP9_COMMON *cm, ThreadData *const td) {
3667   unsigned int intra_count = 0, inter_count = 0;
3668   int j;
3669
3670   for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) {
3671     intra_count += td->counts->intra_inter[j][0];
3672     inter_count += td->counts->intra_inter[j][1];
3673   }
3674
3675   return (intra_count << 2) < inter_count &&
3676          cm->frame_type != KEY_FRAME &&
3677          cm->show_frame;
3678 }
3679
3680 void vp9_init_tile_data(VP9_COMP *cpi) {
3681   VP9_COMMON *const cm = &cpi->common;
3682   const int tile_cols = 1 << cm->log2_tile_cols;
3683   const int tile_rows = 1 << cm->log2_tile_rows;
3684   int tile_col, tile_row;
3685   TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
3686   int tile_tok = 0;
3687
3688   if (cpi->tile_data == NULL) {
3689     CHECK_MEM_ERROR(cm, cpi->tile_data,
3690         vpx_malloc(tile_cols * tile_rows * sizeof(*cpi->tile_data)));
3691     for (tile_row = 0; tile_row < tile_rows; ++tile_row)
3692       for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
3693         TileDataEnc *tile_data =
3694             &cpi->tile_data[tile_row * tile_cols + tile_col];
3695         int i, j;
3696         for (i = 0; i < BLOCK_SIZES; ++i) {
3697           for (j = 0; j < MAX_MODES; ++j) {
3698             tile_data->thresh_freq_fact[i][j] = 32;
3699             tile_data->mode_map[i][j] = j;
3700           }
3701         }
3702       }
3703   }
3704
3705   for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
3706     for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
3707       TileInfo *tile_info =
3708           &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
3709       vp9_tile_init(tile_info, cm, tile_row, tile_col);
3710
3711       cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
3712       pre_tok = cpi->tile_tok[tile_row][tile_col];
3713       tile_tok = allocated_tokens(*tile_info);
3714     }
3715   }
3716 }
3717
3718 void vp9_encode_tile(VP9_COMP *cpi, ThreadData *td,
3719                      int tile_row, int tile_col) {
3720   VP9_COMMON *const cm = &cpi->common;
3721   const int tile_cols = 1 << cm->log2_tile_cols;
3722   TileDataEnc *this_tile =
3723       &cpi->tile_data[tile_row * tile_cols + tile_col];
3724   const TileInfo * const tile_info = &this_tile->tile_info;
3725   TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
3726   int mi_row;
3727
3728   for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
3729        mi_row += MI_BLOCK_SIZE) {
3730     if (cpi->sf.use_nonrd_pick_mode)
3731       encode_nonrd_sb_row(cpi, td, this_tile, mi_row, &tok);
3732     else
3733       encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
3734   }
3735   cpi->tok_count[tile_row][tile_col] =
3736       (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
3737   assert(tok - cpi->tile_tok[tile_row][tile_col] <=
3738       allocated_tokens(*tile_info));
3739 }
3740
3741 static void encode_tiles(VP9_COMP *cpi) {
3742   VP9_COMMON *const cm = &cpi->common;
3743   const int tile_cols = 1 << cm->log2_tile_cols;
3744   const int tile_rows = 1 << cm->log2_tile_rows;
3745   int tile_col, tile_row;
3746
3747   vp9_init_tile_data(cpi);
3748
3749   for (tile_row = 0; tile_row < tile_rows; ++tile_row)
3750     for (tile_col = 0; tile_col < tile_cols; ++tile_col)
3751       vp9_encode_tile(cpi, &cpi->td, tile_row, tile_col);
3752 }
3753
3754 #if CONFIG_FP_MB_STATS
3755 static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
3756                             VP9_COMMON *cm, uint8_t **this_frame_mb_stats) {
3757   uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
3758       cm->current_video_frame * cm->MBs * sizeof(uint8_t);
3759
3760   if (mb_stats_in > firstpass_mb_stats->mb_stats_end)
3761     return EOF;
3762
3763   *this_frame_mb_stats = mb_stats_in;
3764
3765   return 1;
3766 }
3767 #endif
3768
3769 static void encode_frame_internal(VP9_COMP *cpi) {
3770   SPEED_FEATURES *const sf = &cpi->sf;
3771   RD_OPT *const rd_opt = &cpi->rd;
3772   ThreadData *const td = &cpi->td;
3773   MACROBLOCK *const x = &td->mb;
3774   VP9_COMMON *const cm = &cpi->common;
3775   MACROBLOCKD *const xd = &x->e_mbd;
3776   RD_COUNTS *const rdc = &cpi->td.rd_counts;
3777
3778   xd->mi = cm->mi;
3779   xd->mi[0].src_mi = &xd->mi[0];
3780
3781   vp9_zero(*td->counts);
3782   vp9_zero(rdc->coef_counts);
3783   vp9_zero(rdc->comp_pred_diff);
3784   vp9_zero(rdc->filter_diff);
3785   vp9_zero(rdc->tx_select_diff);
3786   vp9_zero(rd_opt->tx_select_threshes);
3787
3788   xd->lossless = cm->base_qindex == 0 &&
3789                  cm->y_dc_delta_q == 0 &&
3790                  cm->uv_dc_delta_q == 0 &&
3791                  cm->uv_ac_delta_q == 0;
3792
3793 #if CONFIG_VP9_HIGHBITDEPTH
3794   if (cm->use_highbitdepth)
3795     x->fwd_txm4x4 = xd->lossless ? vp9_highbd_fwht4x4 : vp9_highbd_fdct4x4;
3796   else
3797     x->fwd_txm4x4 = xd->lossless ? vp9_fwht4x4 : vp9_fdct4x4;
3798   x->highbd_itxm_add = xd->lossless ? vp9_highbd_iwht4x4_add :
3799                                       vp9_highbd_idct4x4_add;
3800 #else
3801   x->fwd_txm4x4 = xd->lossless ? vp9_fwht4x4 : vp9_fdct4x4;
3802 #endif  // CONFIG_VP9_HIGHBITDEPTH
3803   x->itxm_add = xd->lossless ? vp9_iwht4x4_add : vp9_idct4x4_add;
3804
3805   if (xd->lossless)
3806     x->optimize = 0;
3807
3808   cm->tx_mode = select_tx_mode(cpi, xd);
3809
3810   vp9_frame_init_quantizer(cpi);
3811
3812   vp9_initialize_rd_consts(cpi);
3813   vp9_initialize_me_consts(cpi, x, cm->base_qindex);
3814   init_encode_frame_mb_context(cpi);
3815   cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
3816                            cm->width == cm->last_width &&
3817                            cm->height == cm->last_height &&
3818                            !cm->intra_only &&
3819                            cm->last_show_frame;
3820   // Special case: set prev_mi to NULL when the previous mode info
3821   // context cannot be used.
3822   cm->prev_mi = cm->use_prev_frame_mvs ?
3823                 cm->prev_mip + cm->mi_stride + 1 : NULL;
3824
3825   x->quant_fp = cpi->sf.use_quant_fp;
3826   vp9_zero(x->skip_txfm);
3827   if (sf->use_nonrd_pick_mode) {
3828     // Initialize internal buffer pointers for rtc coding, where non-RD
3829     // mode decision is used and hence no buffer pointer swap needed.
3830     int i;
3831     struct macroblock_plane *const p = x->plane;
3832     struct macroblockd_plane *const pd = xd->plane;
3833     PICK_MODE_CONTEXT *ctx = &cpi->td.pc_root->none;
3834
3835     for (i = 0; i < MAX_MB_PLANE; ++i) {
3836       p[i].coeff = ctx->coeff_pbuf[i][0];
3837       p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
3838       pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
3839       p[i].eobs = ctx->eobs_pbuf[i][0];
3840     }
3841     vp9_zero(x->zcoeff_blk);
3842
3843     if (sf->partition_search_type == SOURCE_VAR_BASED_PARTITION)
3844       source_var_based_partition_search_method(cpi);
3845   }
3846
3847   {
3848     struct vpx_usec_timer emr_timer;
3849     vpx_usec_timer_start(&emr_timer);
3850
3851 #if CONFIG_FP_MB_STATS
3852   if (cpi->use_fp_mb_stats) {
3853     input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
3854                      &cpi->twopass.this_frame_mb_stats);
3855   }
3856 #endif
3857
3858     // If allowed, encoding tiles in parallel with one thread handling one tile.
3859     if (MIN(cpi->oxcf.max_threads, 1 << cm->log2_tile_cols) > 1)
3860       vp9_encode_tiles_mt(cpi);
3861     else
3862       encode_tiles(cpi);
3863
3864     vpx_usec_timer_mark(&emr_timer);
3865     cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer);
3866   }
3867
3868   sf->skip_encode_frame = sf->skip_encode_sb ?
3869       get_skip_encode_frame(cm, td) : 0;
3870
3871 #if 0
3872   // Keep record of the total distortion this time around for future use
3873   cpi->last_frame_distortion = cpi->frame_distortion;
3874 #endif
3875 }
3876
3877 static INTERP_FILTER get_interp_filter(
3878     const int64_t threshes[SWITCHABLE_FILTER_CONTEXTS], int is_alt_ref) {
3879   if (!is_alt_ref &&
3880       threshes[EIGHTTAP_SMOOTH] > threshes[EIGHTTAP] &&
3881       threshes[EIGHTTAP_SMOOTH] > threshes[EIGHTTAP_SHARP] &&
3882       threshes[EIGHTTAP_SMOOTH] > threshes[SWITCHABLE - 1]) {
3883     return EIGHTTAP_SMOOTH;
3884   } else if (threshes[EIGHTTAP_SHARP] > threshes[EIGHTTAP] &&
3885              threshes[EIGHTTAP_SHARP] > threshes[SWITCHABLE - 1]) {
3886     return EIGHTTAP_SHARP;
3887   } else if (threshes[EIGHTTAP] > threshes[SWITCHABLE - 1]) {
3888     return EIGHTTAP;
3889   } else {
3890     return SWITCHABLE;
3891   }
3892 }
3893
3894 void vp9_encode_frame(VP9_COMP *cpi) {
3895   VP9_COMMON *const cm = &cpi->common;
3896
3897   // In the longer term the encoder should be generalized to match the
3898   // decoder such that we allow compound where one of the 3 buffers has a
3899   // different sign bias and that buffer is then the fixed ref. However, this
3900   // requires further work in the rd loop. For now the only supported encoder
3901   // side behavior is where the ALT ref buffer has opposite sign bias to
3902   // the other two.
3903   if (!frame_is_intra_only(cm)) {
3904     if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3905              cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
3906         (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3907              cm->ref_frame_sign_bias[LAST_FRAME])) {
3908       cpi->allow_comp_inter_inter = 0;
3909     } else {
3910       cpi->allow_comp_inter_inter = 1;
3911       cm->comp_fixed_ref = ALTREF_FRAME;
3912       cm->comp_var_ref[0] = LAST_FRAME;
3913       cm->comp_var_ref[1] = GOLDEN_FRAME;
3914     }
3915   }
3916
3917   if (cpi->sf.frame_parameter_update) {
3918     int i;
3919     RD_OPT *const rd_opt = &cpi->rd;
3920     FRAME_COUNTS *counts = cpi->td.counts;
3921     RD_COUNTS *const rdc = &cpi->td.rd_counts;
3922
3923     // This code does a single RD pass over the whole frame assuming
3924     // either compound, single or hybrid prediction as per whatever has
3925     // worked best for that type of frame in the past.
3926     // It also predicts whether another coding mode would have worked
3927     // better that this coding mode. If that is the case, it remembers
3928     // that for subsequent frames.
3929     // It does the same analysis for transform size selection also.
3930     const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
3931     int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
3932     int64_t *const filter_thrs = rd_opt->filter_threshes[frame_type];
3933     int *const tx_thrs = rd_opt->tx_select_threshes[frame_type];
3934     const int is_alt_ref = frame_type == ALTREF_FRAME;
3935
3936     /* prediction (compound, single or hybrid) mode selection */
3937     if (is_alt_ref || !cpi->allow_comp_inter_inter)
3938       cm->reference_mode = SINGLE_REFERENCE;
3939     else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
3940              mode_thrs[COMPOUND_REFERENCE] >
3941                  mode_thrs[REFERENCE_MODE_SELECT] &&
3942              check_dual_ref_flags(cpi) &&
3943              cpi->static_mb_pct == 100)
3944       cm->reference_mode = COMPOUND_REFERENCE;
3945     else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
3946       cm->reference_mode = SINGLE_REFERENCE;
3947     else
3948       cm->reference_mode = REFERENCE_MODE_SELECT;
3949
3950     if (cm->interp_filter == SWITCHABLE)
3951       cm->interp_filter = get_interp_filter(filter_thrs, is_alt_ref);
3952
3953     encode_frame_internal(cpi);
3954
3955     for (i = 0; i < REFERENCE_MODES; ++i)
3956       mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
3957
3958     for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
3959       filter_thrs[i] = (filter_thrs[i] + rdc->filter_diff[i] / cm->MBs) / 2;
3960
3961     for (i = 0; i < TX_MODES; ++i) {
3962       int64_t pd = rdc->tx_select_diff[i];
3963       if (i == TX_MODE_SELECT)
3964         pd -= RDCOST(cpi->td.mb.rdmult, cpi->td.mb.rddiv, 2048 * (TX_SIZES - 1),
3965                      0);
3966       tx_thrs[i] = (tx_thrs[i] + (int)(pd / cm->MBs)) / 2;
3967     }
3968
3969     if (cm->reference_mode == REFERENCE_MODE_SELECT) {
3970       int single_count_zero = 0;
3971       int comp_count_zero = 0;
3972
3973       for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
3974         single_count_zero += counts->comp_inter[i][0];
3975         comp_count_zero += counts->comp_inter[i][1];
3976       }
3977
3978       if (comp_count_zero == 0) {
3979         cm->reference_mode = SINGLE_REFERENCE;
3980         vp9_zero(counts->comp_inter);
3981       } else if (single_count_zero == 0) {
3982         cm->reference_mode = COMPOUND_REFERENCE;
3983         vp9_zero(counts->comp_inter);
3984       }
3985     }
3986
3987     if (cm->tx_mode == TX_MODE_SELECT) {
3988       int count4x4 = 0;
3989       int count8x8_lp = 0, count8x8_8x8p = 0;
3990       int count16x16_16x16p = 0, count16x16_lp = 0;
3991       int count32x32 = 0;
3992
3993       for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
3994         count4x4 += counts->tx.p32x32[i][TX_4X4];
3995         count4x4 += counts->tx.p16x16[i][TX_4X4];
3996         count4x4 += counts->tx.p8x8[i][TX_4X4];
3997
3998         count8x8_lp += counts->tx.p32x32[i][TX_8X8];
3999         count8x8_lp += counts->tx.p16x16[i][TX_8X8];
4000         count8x8_8x8p += counts->tx.p8x8[i][TX_8X8];
4001
4002         count16x16_16x16p += counts->tx.p16x16[i][TX_16X16];
4003         count16x16_lp += counts->tx.p32x32[i][TX_16X16];
4004         count32x32 += counts->tx.p32x32[i][TX_32X32];
4005       }
4006       if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
4007           count32x32 == 0) {
4008         cm->tx_mode = ALLOW_8X8;
4009         reset_skip_tx_size(cm, TX_8X8);
4010       } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
4011                  count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
4012         cm->tx_mode = ONLY_4X4;
4013         reset_skip_tx_size(cm, TX_4X4);
4014       } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
4015         cm->tx_mode = ALLOW_32X32;
4016       } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
4017         cm->tx_mode = ALLOW_16X16;
4018         reset_skip_tx_size(cm, TX_16X16);
4019       }
4020     }
4021   } else {
4022     cm->reference_mode = SINGLE_REFERENCE;
4023     encode_frame_internal(cpi);
4024   }
4025 }
4026
4027 static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
4028   const PREDICTION_MODE y_mode = mi->mbmi.mode;
4029   const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
4030   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
4031
4032   if (bsize < BLOCK_8X8) {
4033     int idx, idy;
4034     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
4035     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
4036     for (idy = 0; idy < 2; idy += num_4x4_h)
4037       for (idx = 0; idx < 2; idx += num_4x4_w)
4038         ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode];
4039   } else {
4040     ++counts->y_mode[size_group_lookup[bsize]][y_mode];
4041   }
4042
4043   ++counts->uv_mode[y_mode][uv_mode];
4044 }
4045
4046 static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
4047                               TOKENEXTRA **t, int output_enabled,
4048                               int mi_row, int mi_col, BLOCK_SIZE bsize,
4049                               PICK_MODE_CONTEXT *ctx) {
4050   VP9_COMMON *const cm = &cpi->common;
4051   MACROBLOCK *const x = &td->mb;
4052   MACROBLOCKD *const xd = &x->e_mbd;
4053   MODE_INFO *mi_8x8 = xd->mi;
4054   MODE_INFO *mi = mi_8x8;
4055   MB_MODE_INFO *mbmi = &mi->mbmi;
4056   const int seg_skip = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
4057                                              SEG_LVL_SKIP);
4058   const int mis = cm->mi_stride;
4059   const int mi_width = num_8x8_blocks_wide_lookup[bsize];
4060   const int mi_height = num_8x8_blocks_high_lookup[bsize];
4061
4062   x->skip_recode = !x->select_tx_size && mbmi->sb_type >= BLOCK_8X8 &&
4063                    cpi->oxcf.aq_mode != COMPLEXITY_AQ &&
4064                    cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ &&
4065                    cpi->sf.allow_skip_recode;
4066
4067   if (!x->skip_recode && !cpi->sf.use_nonrd_pick_mode)
4068     vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
4069
4070   x->skip_optimize = ctx->is_coded;
4071   ctx->is_coded = 1;
4072   x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
4073   x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame &&
4074                     x->q_index < QIDX_SKIP_THRESH);
4075
4076   if (x->skip_encode)
4077     return;
4078
4079   set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
4080
4081   if (!is_inter_block(mbmi)) {
4082     int plane;
4083     mbmi->skip = 1;
4084     for (plane = 0; plane < MAX_MB_PLANE; ++plane)
4085       vp9_encode_intra_block_plane(x, MAX(bsize, BLOCK_8X8), plane);
4086     if (output_enabled)
4087       sum_intra_stats(td->counts, mi);
4088     vp9_tokenize_sb(cpi, td, t, !output_enabled, MAX(bsize, BLOCK_8X8));
4089   } else {
4090     int ref;
4091     const int is_compound = has_second_ref(mbmi);
4092     for (ref = 0; ref < 1 + is_compound; ++ref) {
4093       YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
4094                                                      mbmi->ref_frame[ref]);
4095       assert(cfg != NULL);
4096       vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
4097                            &xd->block_refs[ref]->sf);
4098     }
4099     if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
4100       vp9_build_inter_predictors_sby(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
4101
4102     vp9_build_inter_predictors_sbuv(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
4103
4104     vp9_encode_sb(x, MAX(bsize, BLOCK_8X8));
4105     vp9_tokenize_sb(cpi, td, t, !output_enabled, MAX(bsize, BLOCK_8X8));
4106   }
4107
4108   if (output_enabled) {
4109     if (cm->tx_mode == TX_MODE_SELECT &&
4110         mbmi->sb_type >= BLOCK_8X8  &&
4111         !(is_inter_block(mbmi) && (mbmi->skip || seg_skip))) {
4112       ++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
4113                       &td->counts->tx)[mbmi->tx_size];
4114     } else {
4115       int x, y;
4116       TX_SIZE tx_size;
4117       // The new intra coding scheme requires no change of transform size
4118       if (is_inter_block(&mi->mbmi)) {
4119         tx_size = MIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
4120                       max_txsize_lookup[bsize]);
4121       } else {
4122         tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
4123       }
4124
4125       for (y = 0; y < mi_height; y++)
4126         for (x = 0; x < mi_width; x++)
4127           if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
4128             mi_8x8[mis * y + x].src_mi->mbmi.tx_size = tx_size;
4129     }
4130     ++td->counts->tx.tx_totals[mbmi->tx_size];
4131     ++td->counts->tx.tx_totals[get_uv_tx_size(mbmi, &xd->plane[1])];
4132   }
4133 }