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