2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
15 #include "./vp9_rtcd.h"
16 #include "./vpx_config.h"
18 #include "vpx_ports/vpx_timer.h"
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"
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"
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
51 static INLINE uint8_t *get_sb_index(MACROBLOCK *x, BLOCK_SIZE subsize) {
76 static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
77 int mi_row, int mi_col, BLOCK_SIZE bsize);
79 static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
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
87 // Motion vector component magnitude threshold for defining fast motion.
88 #define FAST_MOTION_MV_THRESH 24
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
105 static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi,
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]);
114 static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi,
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,
127 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
130 static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi,
133 unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
146 static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi,
149 unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb,
160 // Lighter version of set_offsets that only sets the mode info
162 static INLINE void set_modeinfo_offsets(VP9_COMMON *const cm,
163 MACROBLOCKD *const xd,
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;
171 static int is_block_in_mb_map(const VP9_COMP *cpi, int mi_row, int mi_col,
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;
181 if (bsize <= BLOCK_16X16) {
182 return cpi->active_map[mb_row * mb_cols + mb_col];
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)
190 if (cpi->active_map[row * mb_cols + col])
197 static int check_active_map(const VP9_COMP *cpi, const MACROBLOCK *x,
198 int mi_row, int mi_col,
200 if (cpi->active_map_enabled && !x->e_mbd.lossless) {
201 return is_block_in_mb_map(cpi, mi_row, mi_col, 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;
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;
220 set_skip_context(xd, mi_row, mi_col);
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);
226 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
228 mbmi = &xd->mi[0]->mbmi;
230 // Set up destination pointers.
231 vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
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;
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);
245 // Set up source buffers.
246 vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
249 x->rddiv = cpi->RDDIV;
250 x->rdmult = cpi->RDMULT;
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);
259 vp9_init_plane_quantizers(cpi, x);
261 x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
263 mbmi->segment_id = 0;
264 x->encode_breakout = cpi->encode_breakout;
268 static void duplicate_mode_info_in_sb(VP9_COMMON * const cm,
269 MACROBLOCKD *const xd,
273 const int block_width = num_8x8_blocks_wide_lookup[bsize];
274 const int block_height = num_8x8_blocks_high_lookup[bsize];
276 for (j = 0; j < block_height; ++j)
277 for (i = 0; i < block_width; ++i) {
278 if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols)
279 xd->mi[j * xd->mi_stride + i] = xd->mi[0];
283 static void set_block_size(VP9_COMP * const cpi,
284 const TileInfo *const tile,
285 int mi_row, int mi_col,
287 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
288 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
289 set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col);
290 xd->mi[0]->mbmi.sb_type = bsize;
291 duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize);
296 int64_t sum_square_error;
306 } partition_variance;
309 partition_variance part_variances;
314 partition_variance part_variances;
319 partition_variance part_variances;
324 partition_variance part_variances;
329 partition_variance *part_variances;
339 static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
343 v64x64 *vt = (v64x64 *) data;
344 node->part_variances = &vt->part_variances;
345 for (i = 0; i < 4; i++)
346 node->split[i] = &vt->split[i].part_variances.none;
350 v32x32 *vt = (v32x32 *) data;
351 node->part_variances = &vt->part_variances;
352 for (i = 0; i < 4; i++)
353 node->split[i] = &vt->split[i].part_variances.none;
357 v16x16 *vt = (v16x16 *) data;
358 node->part_variances = &vt->part_variances;
359 for (i = 0; i < 4; i++)
360 node->split[i] = &vt->split[i].part_variances.none;
364 v8x8 *vt = (v8x8 *) data;
365 node->part_variances = &vt->part_variances;
366 for (i = 0; i < 4; i++)
367 node->split[i] = &vt->split[i];
376 // Set variance values given sum square error, sum error, count.
377 static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
378 v->sum_square_error = s2;
382 v->variance = (int)(256 *
383 (v->sum_square_error - v->sum_error * v->sum_error /
384 v->count) / v->count);
389 void sum_2_variances(const var *a, const var *b, var *r) {
390 fill_variance(a->sum_square_error + b->sum_square_error,
391 a->sum_error + b->sum_error, a->count + b->count, r);
394 static void fill_variance_tree(void *data, BLOCK_SIZE bsize) {
396 tree_to_node(data, bsize, &node);
397 sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]);
398 sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]);
399 sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]);
400 sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]);
401 sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1],
402 &node.part_variances->none);
405 static int set_vt_partitioning(VP9_COMP *cpi,
407 const TileInfo *const tile,
412 VP9_COMMON * const cm = &cpi->common;
414 const int block_width = num_8x8_blocks_wide_lookup[bsize];
415 const int block_height = num_8x8_blocks_high_lookup[bsize];
416 // TODO(debargha): Choose this more intelligently.
417 const int64_t threshold_multiplier = 25;
418 int64_t threshold = threshold_multiplier * cpi->common.base_qindex;
419 assert(block_height == block_width);
421 tree_to_node(data, bsize, &vt);
423 // Split none is available only if we have more than half a block size
424 // in width and height inside the visible image.
425 if (mi_col + block_width / 2 < cm->mi_cols &&
426 mi_row + block_height / 2 < cm->mi_rows &&
427 vt.part_variances->none.variance < threshold) {
428 set_block_size(cpi, tile, mi_row, mi_col, bsize);
432 // Vertical split is available on all but the bottom border.
433 if (mi_row + block_height / 2 < cm->mi_rows &&
434 vt.part_variances->vert[0].variance < threshold &&
435 vt.part_variances->vert[1].variance < threshold) {
436 BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
437 set_block_size(cpi, tile, mi_row, mi_col, subsize);
438 set_block_size(cpi, tile, mi_row, mi_col + block_width / 2, subsize);
442 // Horizontal split is available on all but the right border.
443 if (mi_col + block_width / 2 < cm->mi_cols &&
444 vt.part_variances->horz[0].variance < threshold &&
445 vt.part_variances->horz[1].variance < threshold) {
446 BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
447 set_block_size(cpi, tile, mi_row, mi_col, subsize);
448 set_block_size(cpi, tile, mi_row + block_height / 2, mi_col, subsize);
454 // TODO(debargha): Fix this function and make it work as expected.
455 static void choose_partitioning(VP9_COMP *cpi,
456 const TileInfo *const tile,
457 int mi_row, int mi_col) {
458 VP9_COMMON * const cm = &cpi->common;
459 MACROBLOCK *x = &cpi->mb;
460 MACROBLOCKD *xd = &cpi->mb.e_mbd;
468 int pixels_wide = 64, pixels_high = 64;
469 int_mv nearest_mv, near_mv;
470 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
471 const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
474 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
476 if (xd->mb_to_right_edge < 0)
477 pixels_wide += (xd->mb_to_right_edge >> 3);
478 if (xd->mb_to_bottom_edge < 0)
479 pixels_high += (xd->mb_to_bottom_edge >> 3);
481 s = x->plane[0].src.buf;
482 sp = x->plane[0].src.stride;
484 if (cm->frame_type != KEY_FRAME) {
485 vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf);
487 xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
488 xd->mi[0]->mbmi.sb_type = BLOCK_64X64;
489 vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv,
490 xd->mi[0]->mbmi.ref_mvs[LAST_FRAME],
491 &nearest_mv, &near_mv);
493 xd->mi[0]->mbmi.mv[0] = nearest_mv;
494 vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64);
496 d = xd->plane[0].dst.buf;
497 dp = xd->plane[0].dst.stride;
503 // Fill in the entire tree of 8x8 variances for splits.
504 for (i = 0; i < 4; i++) {
505 const int x32_idx = ((i & 1) << 5);
506 const int y32_idx = ((i >> 1) << 5);
507 for (j = 0; j < 4; j++) {
508 const int x16_idx = x32_idx + ((j & 1) << 4);
509 const int y16_idx = y32_idx + ((j >> 1) << 4);
510 v16x16 *vst = &vt.split[i].split[j];
511 for (k = 0; k < 4; k++) {
512 int x_idx = x16_idx + ((k & 1) << 3);
513 int y_idx = y16_idx + ((k >> 1) << 3);
514 unsigned int sse = 0;
516 if (x_idx < pixels_wide && y_idx < pixels_high)
517 vp9_get_sse_sum_8x8(s + y_idx * sp + x_idx, sp,
518 d + y_idx * dp + x_idx, dp, &sse, &sum);
519 fill_variance(sse, sum, 64, &vst->split[k].part_variances.none);
523 // Fill the rest of the variance tree by summing split partition values.
524 for (i = 0; i < 4; i++) {
525 for (j = 0; j < 4; j++) {
526 fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
528 fill_variance_tree(&vt.split[i], BLOCK_32X32);
530 fill_variance_tree(&vt, BLOCK_64X64);
532 // Now go through the entire structure, splitting every block size until
533 // we get to one that's got a variance lower than our threshold, or we
535 if (!set_vt_partitioning(cpi, &vt, tile, BLOCK_64X64,
536 mi_row, mi_col, 8)) {
537 for (i = 0; i < 4; ++i) {
538 const int x32_idx = ((i & 1) << 2);
539 const int y32_idx = ((i >> 1) << 2);
540 if (!set_vt_partitioning(cpi, &vt.split[i], tile, BLOCK_32X32,
541 (mi_row + y32_idx), (mi_col + x32_idx), 4)) {
542 for (j = 0; j < 4; ++j) {
543 const int x16_idx = ((j & 1) << 1);
544 const int y16_idx = ((j >> 1) << 1);
545 // NOTE: This is a temporary hack to disable 8x8 partitions,
546 // since it works really bad - possibly due to a bug
547 #define DISABLE_8X8_VAR_BASED_PARTITION
548 #ifdef DISABLE_8X8_VAR_BASED_PARTITION
549 if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows &&
550 mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) {
551 set_block_size(cpi, tile,
552 (mi_row + y32_idx + y16_idx),
553 (mi_col + x32_idx + x16_idx),
556 for (k = 0; k < 4; ++k) {
557 const int x8_idx = (k & 1);
558 const int y8_idx = (k >> 1);
559 set_block_size(cpi, tile,
560 (mi_row + y32_idx + y16_idx + y8_idx),
561 (mi_col + x32_idx + x16_idx + x8_idx),
566 if (!set_vt_partitioning(cpi, &vt.split[i].split[j], tile,
568 (mi_row + y32_idx + y16_idx),
569 (mi_col + x32_idx + x16_idx), 2)) {
570 for (k = 0; k < 4; ++k) {
571 const int x8_idx = (k & 1);
572 const int y8_idx = (k >> 1);
573 set_block_size(cpi, tile,
574 (mi_row + y32_idx + y16_idx + y8_idx),
575 (mi_col + x32_idx + x16_idx + x8_idx),
586 // Original activity measure from Tim T's code.
587 static unsigned int tt_activity_measure(MACROBLOCK *x) {
589 // TODO: This could also be done over smaller areas (8x8), but that would
590 // require extensive changes elsewhere, as lambda is assumed to be fixed
591 // over an entire MB in most of the code.
592 // Another option is to compute four 8x8 variances, and pick a single
593 // lambda using a non-linear combination (e.g., the smallest, or second
595 const unsigned int act = vp9_variance16x16(x->plane[0].src.buf,
596 x->plane[0].src.stride,
597 VP9_VAR_OFFS, 0, &sse) << 4;
598 // If the region is flat, lower the activity some more.
599 return act < (8 << 12) ? MIN(act, 5 << 12) : act;
602 // Stub for alternative experimental activity measures.
603 static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) {
604 return vp9_encode_intra(x, use_dc_pred);
607 // Measure the activity of the current macroblock
608 // What we measure here is TBD so abstracted to this function
609 #define ALT_ACT_MEASURE 1
610 static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) {
611 unsigned int mb_activity;
613 if (ALT_ACT_MEASURE) {
614 const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
616 // Or use and alternative.
617 mb_activity = alt_activity_measure(x, use_dc_pred);
619 // Original activity measure from Tim T's code.
620 mb_activity = tt_activity_measure(x);
623 return MAX(mb_activity, ACTIVITY_AVG_MIN);
626 // Calculate an "average" mb activity value for the frame
628 static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
630 // Find median: Simple n^2 algorithm for experimentation
634 unsigned int *sortlist;
637 // Create a list to sort to
638 CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
641 // Copy map to sort list
642 vpx_memcpy(sortlist, cpi->mb_activity_map,
643 sizeof(unsigned int) * cpi->common.MBs);
645 // Ripple each value down to its correct position
646 for (i = 1; i < cpi->common.MBs; i ++) {
647 for (j = i; j > 0; j --) {
648 if (sortlist[j] < sortlist[j - 1]) {
650 tmp = sortlist[j - 1];
651 sortlist[j - 1] = sortlist[j];
659 // Even number MBs so estimate median as mean of two either side.
660 median = (1 + sortlist[cpi->common.MBs >> 1] +
661 sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
663 cpi->activity_avg = median;
668 // Simple mean for now
669 cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs);
672 if (cpi->activity_avg < ACTIVITY_AVG_MIN)
673 cpi->activity_avg = ACTIVITY_AVG_MIN;
675 // Experimental code: return fixed value normalized for several clips
677 cpi->activity_avg = 100000;
680 #define USE_ACT_INDEX 0
681 #define OUTPUT_NORM_ACT_STATS 0
684 // Calculate an activity index for each mb
685 static void calc_activity_index(VP9_COMP *cpi, MACROBLOCK *x) {
686 VP9_COMMON *const cm = &cpi->common;
693 #if OUTPUT_NORM_ACT_STATS
694 FILE *f = fopen("norm_act.stt", "a");
695 fprintf(f, "\n%12d\n", cpi->activity_avg);
698 // Reset pointers to start of activity map
699 x->mb_activity_ptr = cpi->mb_activity_map;
701 // Calculate normalized mb activity number.
702 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
703 // for each macroblock col in image
704 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
705 // Read activity from the map
706 act = *(x->mb_activity_ptr);
708 // Calculate a normalized activity number
709 a = act + 4 * cpi->activity_avg;
710 b = 4 * act + cpi->activity_avg;
713 *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
715 *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
717 #if OUTPUT_NORM_ACT_STATS
718 fprintf(f, " %6d", *(x->mb_activity_ptr));
720 // Increment activity map pointers
721 x->mb_activity_ptr++;
724 #if OUTPUT_NORM_ACT_STATS
729 #if OUTPUT_NORM_ACT_STATS
733 #endif // USE_ACT_INDEX
735 // Loop through all MBs. Note activity of each, average activity and
736 // calculate a normalized activity for each
737 static void build_activity_map(VP9_COMP *cpi) {
738 MACROBLOCK *const x = &cpi->mb;
739 MACROBLOCKD *xd = &x->e_mbd;
740 VP9_COMMON *const cm = &cpi->common;
743 YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm);
745 int recon_y_stride = new_yv12->y_stride;
749 unsigned int mb_activity;
750 int64_t activity_sum = 0;
752 x->mb_activity_ptr = cpi->mb_activity_map;
754 // for each macroblock row in image
755 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
757 // reset above block coeffs
758 xd->up_available = (mb_row != 0);
759 recon_yoffset = (mb_row * recon_y_stride * 16);
761 // for each macroblock col in image
762 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
764 xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
765 xd->left_available = (mb_col != 0);
770 mb_activity = mb_activity_measure(x, mb_row, mb_col);
773 activity_sum += mb_activity;
775 // Store MB level activity details.
776 *x->mb_activity_ptr = mb_activity;
778 // Increment activity map pointer
779 x->mb_activity_ptr++;
781 // adjust to the next column of source macroblocks
782 x->plane[0].src.buf += 16;
785 // adjust to the next row of mbs
786 x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
789 // Calculate an "average" MB activity
790 calc_av_activity(cpi, activity_sum);
793 // Calculate an activity index number of each mb
794 calc_activity_index(cpi, x);
798 // Macroblock activity masking
799 static void activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
801 x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
802 x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
803 x->errorperbit += (x->errorperbit == 0);
805 const int64_t act = *(x->mb_activity_ptr);
807 // Apply the masking to the RD multiplier.
808 const int64_t a = act + (2 * cpi->activity_avg);
809 const int64_t b = (2 * act) + cpi->activity_avg;
811 x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a);
812 x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
813 x->errorperbit += (x->errorperbit == 0);
816 // Activity based Zbin adjustment
817 adjust_act_zbin(cpi, x);
820 static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
821 int mi_row, int mi_col, BLOCK_SIZE bsize,
822 int output_enabled) {
824 VP9_COMMON *const cm = &cpi->common;
825 MACROBLOCK *const x = &cpi->mb;
826 MACROBLOCKD *const xd = &x->e_mbd;
827 struct macroblock_plane *const p = x->plane;
828 struct macroblockd_plane *const pd = xd->plane;
829 MODE_INFO *mi = &ctx->mic;
830 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
831 MODE_INFO *mi_addr = xd->mi[0];
832 const struct segmentation *const seg = &cm->seg;
834 const int mis = cm->mi_stride;
835 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
836 const int mi_height = num_8x8_blocks_high_lookup[bsize];
839 assert(mi->mbmi.sb_type == bsize);
843 // If segmentation in use
844 if (seg->enabled && output_enabled) {
845 // For in frame complexity AQ copy the segment id from the segment map.
846 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
847 const uint8_t *const map = seg->update_map ? cpi->segmentation_map
848 : cm->last_frame_seg_map;
849 mi_addr->mbmi.segment_id =
850 vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
852 // Else for cyclic refresh mode update the segment map, set the segment id
853 // and then update the quantizer.
854 else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
855 vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi,
856 mi_row, mi_col, bsize, 1);
857 vp9_init_plane_quantizers(cpi, x);
861 max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
862 for (i = 0; i < max_plane; ++i) {
863 p[i].coeff = ctx->coeff_pbuf[i][1];
864 p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
865 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
866 p[i].eobs = ctx->eobs_pbuf[i][1];
869 for (i = max_plane; i < MAX_MB_PLANE; ++i) {
870 p[i].coeff = ctx->coeff_pbuf[i][2];
871 p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
872 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
873 p[i].eobs = ctx->eobs_pbuf[i][2];
876 // Restore the coding context of the MB to that that was in place
877 // when the mode was picked for it
878 for (y = 0; y < mi_height; y++)
879 for (x_idx = 0; x_idx < mi_width; x_idx++)
880 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
881 && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
882 xd->mi[x_idx + y * mis] = mi_addr;
885 if (cpi->oxcf.aq_mode)
886 vp9_init_plane_quantizers(cpi, x);
888 // FIXME(rbultje) I'm pretty sure this should go to the end of this block
889 // (i.e. after the output_enabled)
890 if (bsize < BLOCK_32X32) {
891 if (bsize < BLOCK_16X16)
892 ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
893 ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
896 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
897 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
898 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
902 vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
903 sizeof(uint8_t) * ctx->num_4x4_blk);
908 if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
909 for (i = 0; i < TX_MODES; i++)
910 cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i];
913 #if CONFIG_INTERNAL_STATS
914 if (frame_is_intra_only(cm)) {
915 static const int kf_mode_index[] = {
917 THR_V_PRED /*V_PRED*/,
918 THR_H_PRED /*H_PRED*/,
919 THR_D45_PRED /*D45_PRED*/,
920 THR_D135_PRED /*D135_PRED*/,
921 THR_D117_PRED /*D117_PRED*/,
922 THR_D153_PRED /*D153_PRED*/,
923 THR_D207_PRED /*D207_PRED*/,
924 THR_D63_PRED /*D63_PRED*/,
927 ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]];
929 // Note how often each mode chosen as best
930 ++cpi->mode_chosen_counts[ctx->best_mode_index];
933 if (!frame_is_intra_only(cm)) {
934 if (is_inter_block(mbmi)) {
935 vp9_update_mv_count(cm, xd);
937 if (cm->interp_filter == SWITCHABLE) {
938 const int ctx = vp9_get_pred_context_switchable_interp(xd);
939 ++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
943 cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
944 cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
945 cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
947 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
948 cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
952 void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
953 int mi_row, int mi_col) {
954 uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
956 const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
960 // Set current frame pointer.
961 x->e_mbd.cur_buf = src;
963 for (i = 0; i < MAX_MB_PLANE; i++)
964 setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
965 NULL, x->e_mbd.plane[i].subsampling_x,
966 x->e_mbd.plane[i].subsampling_y);
969 static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
970 int mi_row, int mi_col,
971 int *totalrate, int64_t *totaldist,
972 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
974 VP9_COMMON *const cm = &cpi->common;
975 MACROBLOCK *const x = &cpi->mb;
976 MACROBLOCKD *const xd = &x->e_mbd;
978 struct macroblock_plane *const p = x->plane;
979 struct macroblockd_plane *const pd = xd->plane;
980 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
984 vp9_clear_system_state();
985 rdmult_ratio = 1.0; // avoid uninitialized warnings
987 // Use the lower precision, but faster, 32x32 fdct for mode selection.
988 x->use_lp32x32fdct = 1;
990 if (bsize < BLOCK_8X8) {
991 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
992 // there is nothing to be done.
993 if (x->ab_index != 0) {
1000 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1001 mbmi = &xd->mi[0]->mbmi;
1002 mbmi->sb_type = bsize;
1004 for (i = 0; i < MAX_MB_PLANE; ++i) {
1005 p[i].coeff = ctx->coeff_pbuf[i][0];
1006 p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
1007 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
1008 p[i].eobs = ctx->eobs_pbuf[i][0];
1013 // Set to zero to make sure we do not use the previous encoded frame stats
1016 x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
1018 // Save rdmult before it might be changed, so it can be restored later.
1019 orig_rdmult = x->rdmult;
1020 if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
1021 activity_masking(cpi, x);
1023 if (aq_mode == VARIANCE_AQ) {
1024 const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
1025 : vp9_block_energy(cpi, x, bsize);
1026 if (cm->frame_type == KEY_FRAME ||
1027 cpi->refresh_alt_ref_frame ||
1028 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
1029 mbmi->segment_id = vp9_vaq_segment_id(energy);
1031 const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1032 : cm->last_frame_seg_map;
1033 mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
1036 rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
1037 vp9_init_plane_quantizers(cpi, x);
1038 vp9_clear_system_state();
1039 x->rdmult = (int)round(x->rdmult * rdmult_ratio);
1040 } else if (aq_mode == COMPLEXITY_AQ) {
1041 const int mi_offset = mi_row * cm->mi_cols + mi_col;
1042 unsigned char complexity = cpi->complexity_map[mi_offset];
1043 const int is_edge = (mi_row <= 1) || (mi_row >= (cm->mi_rows - 2)) ||
1044 (mi_col <= 1) || (mi_col >= (cm->mi_cols - 2));
1045 if (!is_edge && (complexity > 128))
1046 x->rdmult += ((x->rdmult * (complexity - 128)) / 256);
1047 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1048 const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1049 : cm->last_frame_seg_map;
1050 // If segment 1, use rdmult for that segment.
1051 if (vp9_get_segment_id(cm, map, bsize, mi_row, mi_col))
1052 x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
1055 // Find best coding mode & reconstruct the MB so it is available
1056 // as a predictor for MBs that follow in the SB
1057 if (frame_is_intra_only(cm)) {
1058 vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
1061 if (bsize >= BLOCK_8X8)
1062 vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
1063 totalrate, totaldist, bsize, ctx, best_rd);
1065 vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
1066 totaldist, bsize, ctx, best_rd);
1069 x->rdmult = orig_rdmult;
1071 if (aq_mode == VARIANCE_AQ && *totalrate != INT_MAX) {
1072 vp9_clear_system_state();
1073 *totalrate = (int)round(*totalrate * rdmult_ratio);
1077 static void update_stats(VP9_COMP *cpi) {
1078 VP9_COMMON *const cm = &cpi->common;
1079 const MACROBLOCK *const x = &cpi->mb;
1080 const MACROBLOCKD *const xd = &x->e_mbd;
1081 const MODE_INFO *const mi = xd->mi[0];
1082 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1084 if (!frame_is_intra_only(cm)) {
1085 const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
1087 if (!seg_ref_active) {
1088 FRAME_COUNTS *const counts = &cm->counts;
1089 const int inter_block = is_inter_block(mbmi);
1091 counts->intra_inter[vp9_get_intra_inter_context(xd)][inter_block]++;
1093 // If the segment reference feature is enabled we have only a single
1094 // reference frame allowed for the segment so exclude it from
1095 // the reference frame counts used to work out probabilities.
1097 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1099 if (cm->reference_mode == REFERENCE_MODE_SELECT)
1100 counts->comp_inter[vp9_get_reference_mode_context(cm, xd)]
1101 [has_second_ref(mbmi)]++;
1103 if (has_second_ref(mbmi)) {
1104 counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
1105 [ref0 == GOLDEN_FRAME]++;
1107 counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
1108 [ref0 != LAST_FRAME]++;
1109 if (ref0 != LAST_FRAME)
1110 counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
1111 [ref0 != GOLDEN_FRAME]++;
1118 static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
1121 return &x->sb64_partitioning;
1123 return &x->sb_partitioning[x->sb_index];
1125 return &x->mb_partitioning[x->sb_index][x->mb_index];
1127 return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
1134 static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
1135 ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1136 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1137 PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1139 MACROBLOCK *const x = &cpi->mb;
1140 MACROBLOCKD *const xd = &x->e_mbd;
1142 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1143 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1144 int mi_width = num_8x8_blocks_wide_lookup[bsize];
1145 int mi_height = num_8x8_blocks_high_lookup[bsize];
1146 for (p = 0; p < MAX_MB_PLANE; p++) {
1148 xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
1149 a + num_4x4_blocks_wide * p,
1150 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1151 xd->plane[p].subsampling_x);
1154 + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1155 l + num_4x4_blocks_high * p,
1156 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1157 xd->plane[p].subsampling_y);
1159 vpx_memcpy(xd->above_seg_context + mi_col, sa,
1160 sizeof(*xd->above_seg_context) * mi_width);
1161 vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl,
1162 sizeof(xd->left_seg_context[0]) * mi_height);
1164 static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
1165 ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1166 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1167 PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1169 const MACROBLOCK *const x = &cpi->mb;
1170 const MACROBLOCKD *const xd = &x->e_mbd;
1172 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1173 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1174 int mi_width = num_8x8_blocks_wide_lookup[bsize];
1175 int mi_height = num_8x8_blocks_high_lookup[bsize];
1177 // buffer the above/left context information of the block in search.
1178 for (p = 0; p < MAX_MB_PLANE; ++p) {
1180 a + num_4x4_blocks_wide * p,
1181 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
1182 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1183 xd->plane[p].subsampling_x);
1185 l + num_4x4_blocks_high * p,
1187 + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1188 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1189 xd->plane[p].subsampling_y);
1191 vpx_memcpy(sa, xd->above_seg_context + mi_col,
1192 sizeof(*xd->above_seg_context) * mi_width);
1193 vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK),
1194 sizeof(xd->left_seg_context[0]) * mi_height);
1197 static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
1198 TOKENEXTRA **tp, int mi_row, int mi_col,
1199 int output_enabled, BLOCK_SIZE bsize) {
1200 MACROBLOCK *const x = &cpi->mb;
1202 if (bsize < BLOCK_8X8) {
1203 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1204 // there is nothing to be done.
1205 if (x->ab_index > 0)
1208 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1209 update_state(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize,
1211 encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
1213 if (output_enabled) {
1216 (*tp)->token = EOSB_TOKEN;
1221 static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
1222 TOKENEXTRA **tp, int mi_row, int mi_col,
1223 int output_enabled, BLOCK_SIZE bsize) {
1224 VP9_COMMON *const cm = &cpi->common;
1225 MACROBLOCK *const x = &cpi->mb;
1226 MACROBLOCKD *const xd = &x->e_mbd;
1228 const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
1230 PARTITION_TYPE partition;
1233 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1236 if (bsize >= BLOCK_8X8) {
1237 ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1238 subsize = *get_sb_partitioning(x, bsize);
1241 subsize = BLOCK_4X4;
1244 partition = partition_lookup[bsl][subsize];
1246 switch (partition) {
1247 case PARTITION_NONE:
1248 if (output_enabled && bsize >= BLOCK_8X8)
1249 cm->counts.partition[ctx][PARTITION_NONE]++;
1250 encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1252 case PARTITION_VERT:
1254 cm->counts.partition[ctx][PARTITION_VERT]++;
1255 *get_sb_index(x, subsize) = 0;
1256 encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1257 if (mi_col + hbs < cm->mi_cols) {
1258 *get_sb_index(x, subsize) = 1;
1259 encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
1262 case PARTITION_HORZ:
1264 cm->counts.partition[ctx][PARTITION_HORZ]++;
1265 *get_sb_index(x, subsize) = 0;
1266 encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1267 if (mi_row + hbs < cm->mi_rows) {
1268 *get_sb_index(x, subsize) = 1;
1269 encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
1272 case PARTITION_SPLIT:
1273 subsize = get_subsize(bsize, PARTITION_SPLIT);
1275 cm->counts.partition[ctx][PARTITION_SPLIT]++;
1277 *get_sb_index(x, subsize) = 0;
1278 encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1279 *get_sb_index(x, subsize) = 1;
1280 encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
1281 *get_sb_index(x, subsize) = 2;
1282 encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
1283 *get_sb_index(x, subsize) = 3;
1284 encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1288 assert("Invalid partition type.");
1291 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1292 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1295 // Check to see if the given partition size is allowed for a specified number
1296 // of 8x8 block rows and columns remaining in the image.
1297 // If not then return the largest allowed partition size
1298 static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize,
1299 int rows_left, int cols_left,
1301 if (rows_left <= 0 || cols_left <= 0) {
1302 return MIN(bsize, BLOCK_8X8);
1304 for (; bsize > 0; bsize -= 3) {
1305 *bh = num_8x8_blocks_high_lookup[bsize];
1306 *bw = num_8x8_blocks_wide_lookup[bsize];
1307 if ((*bh <= rows_left) && (*bw <= cols_left)) {
1315 // This function attempts to set all mode info entries in a given SB64
1316 // to the same block partition size.
1317 // However, at the bottom and right borders of the image the requested size
1318 // may not be allowed in which case this code attempts to choose the largest
1319 // allowable partition.
1320 static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
1321 MODE_INFO **mi_8x8, int mi_row, int mi_col,
1323 VP9_COMMON *const cm = &cpi->common;
1324 const int mis = cm->mi_stride;
1325 int row8x8_remaining = tile->mi_row_end - mi_row;
1326 int col8x8_remaining = tile->mi_col_end - mi_col;
1327 int block_row, block_col;
1328 MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
1329 int bh = num_8x8_blocks_high_lookup[bsize];
1330 int bw = num_8x8_blocks_wide_lookup[bsize];
1332 assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1334 // Apply the requested partition size to the SB64 if it is all "in image"
1335 if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1336 (row8x8_remaining >= MI_BLOCK_SIZE)) {
1337 for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1338 for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1339 int index = block_row * mis + block_col;
1340 mi_8x8[index] = mi_upper_left + index;
1341 mi_8x8[index]->mbmi.sb_type = bsize;
1345 // Else this is a partial SB64.
1346 for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1347 for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1348 int index = block_row * mis + block_col;
1349 // Find a partition size that fits
1350 bsize = find_partition_size(bsize,
1351 (row8x8_remaining - block_row),
1352 (col8x8_remaining - block_col), &bh, &bw);
1353 mi_8x8[index] = mi_upper_left + index;
1354 mi_8x8[index]->mbmi.sb_type = bsize;
1360 static void constrain_copy_partitioning(VP9_COMP *const cpi,
1361 const TileInfo *const tile,
1363 MODE_INFO **prev_mi_8x8,
1364 int mi_row, int mi_col,
1366 VP9_COMMON *const cm = &cpi->common;
1367 const int mis = cm->mi_stride;
1368 const int row8x8_remaining = tile->mi_row_end - mi_row;
1369 const int col8x8_remaining = tile->mi_col_end - mi_col;
1370 MODE_INFO *const mi_upper_left = cm->mi + mi_row * mis + mi_col;
1371 const int bh = num_8x8_blocks_high_lookup[bsize];
1372 const int bw = num_8x8_blocks_wide_lookup[bsize];
1373 int block_row, block_col;
1375 assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1377 // If the SB64 if it is all "in image".
1378 if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1379 (row8x8_remaining >= MI_BLOCK_SIZE)) {
1380 for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1381 for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1382 const int index = block_row * mis + block_col;
1383 MODE_INFO *prev_mi = prev_mi_8x8[index];
1384 const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
1385 // Use previous partition if block size is not larger than bsize.
1386 if (prev_mi && sb_type <= bsize) {
1387 int block_row2, block_col2;
1388 for (block_row2 = 0; block_row2 < bh; ++block_row2) {
1389 for (block_col2 = 0; block_col2 < bw; ++block_col2) {
1390 const int index2 = (block_row + block_row2) * mis +
1391 block_col + block_col2;
1392 prev_mi = prev_mi_8x8[index2];
1394 const ptrdiff_t offset = prev_mi - cm->prev_mi;
1395 mi_8x8[index2] = cm->mi + offset;
1396 mi_8x8[index2]->mbmi.sb_type = prev_mi->mbmi.sb_type;
1401 // Otherwise, use fixed partition of size bsize.
1402 mi_8x8[index] = mi_upper_left + index;
1403 mi_8x8[index]->mbmi.sb_type = bsize;
1408 // Else this is a partial SB64, copy previous partition.
1409 for (block_row = 0; block_row < 8; ++block_row) {
1410 for (block_col = 0; block_col < 8; ++block_col) {
1411 MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col];
1412 const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
1414 const ptrdiff_t offset = prev_mi - cm->prev_mi;
1415 mi_8x8[block_row * mis + block_col] = cm->mi + offset;
1416 mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type;
1423 static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8,
1424 MODE_INFO **prev_mi_8x8) {
1425 const int mis = cm->mi_stride;
1426 int block_row, block_col;
1428 for (block_row = 0; block_row < 8; ++block_row) {
1429 for (block_col = 0; block_col < 8; ++block_col) {
1430 MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col];
1431 const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
1434 const ptrdiff_t offset = prev_mi - cm->prev_mi;
1435 mi_8x8[block_row * mis + block_col] = cm->mi + offset;
1436 mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type;
1445 } coord_lookup[16] = {
1447 {0, 0}, {0, 2}, {2, 0}, {2, 2},
1449 {0, 4}, {0, 6}, {2, 4}, {2, 6},
1451 {4, 0}, {4, 2}, {6, 0}, {6, 2},
1453 {4, 4}, {4, 6}, {6, 4}, {6, 6},
1456 static void set_source_var_based_partition(VP9_COMP *cpi,
1457 const TileInfo *const tile,
1459 int mi_row, int mi_col) {
1460 VP9_COMMON *const cm = &cpi->common;
1461 MACROBLOCK *x = &cpi->mb;
1462 const int mis = cm->mi_stride;
1463 int row8x8_remaining = tile->mi_row_end - mi_row;
1464 int col8x8_remaining = tile->mi_col_end - mi_col;
1466 MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
1468 assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1471 if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1472 (row8x8_remaining >= MI_BLOCK_SIZE)) {
1473 const int src_stride = x->plane[0].src.stride;
1474 const int pre_stride = cpi->Last_Source->y_stride;
1475 const uint8_t *src = x->plane[0].src.buf;
1476 const int pre_offset = (mi_row * MI_SIZE) * pre_stride +
1478 const uint8_t *pre_src = cpi->Last_Source->y_buffer + pre_offset;
1479 const int thr_32x32 = cpi->sf.source_var_thresh;
1480 const int thr_64x64 = thr_32x32 << 1;
1486 for (i = 0; i < 4; i++) {
1489 for (j = 0; j < 4; j++) {
1490 int b_mi_row = coord_lookup[i * 4 + j].row;
1491 int b_mi_col = coord_lookup[i * 4 + j].col;
1492 int b_offset = b_mi_row * MI_SIZE * src_stride +
1495 vp9_get_sse_sum_16x16(src + b_offset,
1498 pre_stride, &d16[j].sse, &d16[j].sum);
1500 d16[j].var = d16[j].sse -
1501 (((uint32_t)d16[j].sum * d16[j].sum) >> 8);
1503 index = b_mi_row * mis + b_mi_col;
1504 mi_8x8[index] = mi_upper_left + index;
1505 mi_8x8[index]->mbmi.sb_type = BLOCK_16X16;
1507 // TODO(yunqingwang): If d16[j].var is very large, use 8x8 partition
1508 // size to further improve quality.
1511 if (d16[0].var < thr_32x32 && d16[1].var < thr_32x32 &&
1512 d16[2].var < thr_32x32 && d16[3].var < thr_32x32) {
1513 d32[i].sse = d16[0].sse;
1514 d32[i].sum = d16[0].sum;
1516 for (j = 1; j < 4; j++) {
1517 d32[i].sse += d16[j].sse;
1518 d32[i].sum += d16[j].sum;
1521 d32[i].var = d32[i].sse - (((int64_t)d32[i].sum * d32[i].sum) >> 10);
1523 index = coord_lookup[i*4].row * mis + coord_lookup[i*4].col;
1524 mi_8x8[index] = mi_upper_left + index;
1525 mi_8x8[index]->mbmi.sb_type = BLOCK_32X32;
1527 if (!((cm->current_video_frame - 1) %
1528 cpi->sf.search_type_check_frequency))
1529 cpi->use_large_partition_rate += 1;
1536 if (d32[0].var < thr_64x64 && d32[1].var < thr_64x64 &&
1537 d32[2].var < thr_64x64 && d32[3].var < thr_64x64) {
1538 mi_8x8[0] = mi_upper_left;
1539 mi_8x8[0]->mbmi.sb_type = BLOCK_64X64;
1542 } else { // partial in-image SB64
1543 BLOCK_SIZE bsize = BLOCK_16X16;
1544 int bh = num_8x8_blocks_high_lookup[bsize];
1545 int bw = num_8x8_blocks_wide_lookup[bsize];
1547 for (r = 0; r < MI_BLOCK_SIZE; r += bh) {
1548 for (c = 0; c < MI_BLOCK_SIZE; c += bw) {
1549 int index = r * mis + c;
1550 // Find a partition size that fits
1551 bsize = find_partition_size(bsize,
1552 (row8x8_remaining - r),
1553 (col8x8_remaining - c), &bh, &bw);
1554 mi_8x8[index] = mi_upper_left + index;
1555 mi_8x8[index]->mbmi.sb_type = bsize;
1561 static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
1562 const int mis = cm->mi_stride;
1563 int block_row, block_col;
1566 for (block_row = 0; block_row < 8; ++block_row) {
1567 for (block_col = 0; block_col < 8; ++block_col) {
1568 const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col];
1570 if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 ||
1571 abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8)
1580 static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
1581 int mi_row, int mi_col, int bsize) {
1582 VP9_COMMON *const cm = &cpi->common;
1583 MACROBLOCK *const x = &cpi->mb;
1584 MACROBLOCKD *const xd = &x->e_mbd;
1585 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1586 const struct segmentation *const seg = &cm->seg;
1588 *(xd->mi[0]) = ctx->mic;
1590 // For in frame adaptive Q, check for reseting the segment_id and updating
1591 // the cyclic refresh map.
1592 if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled) {
1593 vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi,
1594 mi_row, mi_col, bsize, 1);
1595 vp9_init_plane_quantizers(cpi, x);
1598 if (is_inter_block(mbmi)) {
1599 vp9_update_mv_count(cm, xd);
1601 if (cm->interp_filter == SWITCHABLE) {
1602 const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
1603 ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter];
1607 x->skip = ctx->skip;
1610 static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile,
1611 TOKENEXTRA **tp, int mi_row, int mi_col,
1612 int output_enabled, BLOCK_SIZE bsize) {
1613 MACROBLOCK *const x = &cpi->mb;
1615 if (bsize < BLOCK_8X8) {
1616 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1617 // there is nothing to be done.
1618 if (x->ab_index > 0)
1622 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1623 update_state_rt(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize);
1625 encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
1628 (*tp)->token = EOSB_TOKEN;
1632 static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
1633 TOKENEXTRA **tp, int mi_row, int mi_col,
1634 int output_enabled, BLOCK_SIZE bsize) {
1635 VP9_COMMON *const cm = &cpi->common;
1636 MACROBLOCK *const x = &cpi->mb;
1637 MACROBLOCKD *const xd = &x->e_mbd;
1639 const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
1641 PARTITION_TYPE partition;
1644 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1647 if (bsize >= BLOCK_8X8) {
1648 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1649 const int idx_str = xd->mi_stride * mi_row + mi_col;
1650 MODE_INFO ** mi_8x8 = cm->mi_grid_visible + idx_str;
1651 ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1652 subsize = mi_8x8[0]->mbmi.sb_type;
1655 subsize = BLOCK_4X4;
1658 partition = partition_lookup[bsl][subsize];
1660 switch (partition) {
1661 case PARTITION_NONE:
1662 if (output_enabled && bsize >= BLOCK_8X8)
1663 cm->counts.partition[ctx][PARTITION_NONE]++;
1664 encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1666 case PARTITION_VERT:
1668 cm->counts.partition[ctx][PARTITION_VERT]++;
1669 *get_sb_index(x, subsize) = 0;
1670 encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1671 if (mi_col + hbs < cm->mi_cols) {
1672 *get_sb_index(x, subsize) = 1;
1673 encode_b_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
1677 case PARTITION_HORZ:
1679 cm->counts.partition[ctx][PARTITION_HORZ]++;
1680 *get_sb_index(x, subsize) = 0;
1681 encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1682 if (mi_row + hbs < cm->mi_rows) {
1683 *get_sb_index(x, subsize) = 1;
1684 encode_b_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
1688 case PARTITION_SPLIT:
1689 subsize = get_subsize(bsize, PARTITION_SPLIT);
1691 cm->counts.partition[ctx][PARTITION_SPLIT]++;
1693 *get_sb_index(x, subsize) = 0;
1694 encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1695 *get_sb_index(x, subsize) = 1;
1696 encode_sb_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
1698 *get_sb_index(x, subsize) = 2;
1699 encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
1701 *get_sb_index(x, subsize) = 3;
1702 encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1706 assert("Invalid partition type.");
1709 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1710 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1713 static void rd_use_partition(VP9_COMP *cpi,
1714 const TileInfo *const tile,
1716 TOKENEXTRA **tp, int mi_row, int mi_col,
1717 BLOCK_SIZE bsize, int *rate, int64_t *dist,
1719 VP9_COMMON *const cm = &cpi->common;
1720 MACROBLOCK *const x = &cpi->mb;
1721 MACROBLOCKD *const xd = &x->e_mbd;
1722 const int mis = cm->mi_stride;
1723 const int bsl = b_width_log2(bsize);
1724 const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2;
1725 const int bss = (1 << bsl) / 4;
1727 PARTITION_TYPE partition = PARTITION_NONE;
1729 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1730 PARTITION_CONTEXT sl[8], sa[8];
1731 int last_part_rate = INT_MAX;
1732 int64_t last_part_dist = INT64_MAX;
1733 int64_t last_part_rd = INT64_MAX;
1734 int none_rate = INT_MAX;
1735 int64_t none_dist = INT64_MAX;
1736 int64_t none_rd = INT64_MAX;
1737 int chosen_rate = INT_MAX;
1738 int64_t chosen_dist = INT64_MAX;
1739 int64_t chosen_rd = INT64_MAX;
1740 BLOCK_SIZE sub_subsize = BLOCK_4X4;
1741 int splits_below = 0;
1742 BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
1743 int do_partition_search = 1;
1745 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1748 assert(num_4x4_blocks_wide_lookup[bsize] ==
1749 num_4x4_blocks_high_lookup[bsize]);
1751 partition = partition_lookup[bsl][bs_type];
1752 subsize = get_subsize(bsize, partition);
1754 if (bsize < BLOCK_8X8) {
1755 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1756 // there is nothing to be done.
1757 if (x->ab_index != 0) {
1763 *(get_sb_partitioning(x, bsize)) = subsize;
1765 save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1767 if (bsize == BLOCK_16X16) {
1768 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1769 x->mb_energy = vp9_block_energy(cpi, x, bsize);
1771 x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
1774 if (!x->in_active_map) {
1775 do_partition_search = 0;
1776 if (mi_row + (mi_step >> 1) < cm->mi_rows &&
1777 mi_col + (mi_step >> 1) < cm->mi_cols) {
1778 *(get_sb_partitioning(x, bsize)) = bsize;
1779 bs_type = mi_8x8[0]->mbmi.sb_type = bsize;
1781 partition = PARTITION_NONE;
1784 if (do_partition_search &&
1785 cpi->sf.partition_search_type == SEARCH_PARTITION &&
1786 cpi->sf.adjust_partitioning_from_last_frame) {
1787 // Check if any of the sub blocks are further split.
1788 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
1789 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
1791 for (i = 0; i < 4; i++) {
1792 int jj = i >> 1, ii = i & 0x01;
1793 MODE_INFO * this_mi = mi_8x8[jj * bss * mis + ii * bss];
1794 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
1800 // If partition is not none try none unless each of the 4 splits are split
1802 if (partition != PARTITION_NONE && !splits_below &&
1803 mi_row + (mi_step >> 1) < cm->mi_rows &&
1804 mi_col + (mi_step >> 1) < cm->mi_cols) {
1805 *(get_sb_partitioning(x, bsize)) = bsize;
1806 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize,
1807 get_block_context(x, bsize), INT64_MAX);
1809 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1811 if (none_rate < INT_MAX) {
1812 none_rate += x->partition_cost[pl][PARTITION_NONE];
1813 none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist);
1816 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1817 mi_8x8[0]->mbmi.sb_type = bs_type;
1818 *(get_sb_partitioning(x, bsize)) = subsize;
1822 switch (partition) {
1823 case PARTITION_NONE:
1824 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1825 &last_part_dist, bsize,
1826 get_block_context(x, bsize), INT64_MAX);
1828 case PARTITION_HORZ:
1829 *get_sb_index(x, subsize) = 0;
1830 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1831 &last_part_dist, subsize,
1832 get_block_context(x, subsize), INT64_MAX);
1833 if (last_part_rate != INT_MAX &&
1834 bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
1837 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
1839 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
1840 *get_sb_index(x, subsize) = 1;
1841 rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt,
1842 subsize, get_block_context(x, subsize), INT64_MAX);
1843 if (rt == INT_MAX || dt == INT64_MAX) {
1844 last_part_rate = INT_MAX;
1845 last_part_dist = INT64_MAX;
1849 last_part_rate += rt;
1850 last_part_dist += dt;
1853 case PARTITION_VERT:
1854 *get_sb_index(x, subsize) = 0;
1855 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1856 &last_part_dist, subsize,
1857 get_block_context(x, subsize), INT64_MAX);
1858 if (last_part_rate != INT_MAX &&
1859 bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
1862 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
1864 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
1865 *get_sb_index(x, subsize) = 1;
1866 rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt,
1867 subsize, get_block_context(x, subsize), INT64_MAX);
1868 if (rt == INT_MAX || dt == INT64_MAX) {
1869 last_part_rate = INT_MAX;
1870 last_part_dist = INT64_MAX;
1873 last_part_rate += rt;
1874 last_part_dist += dt;
1877 case PARTITION_SPLIT:
1881 for (i = 0; i < 4; i++) {
1882 int x_idx = (i & 1) * (mi_step >> 1);
1883 int y_idx = (i >> 1) * (mi_step >> 1);
1884 int jj = i >> 1, ii = i & 0x01;
1888 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1891 *get_sb_index(x, subsize) = i;
1893 rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
1894 mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt,
1896 if (rt == INT_MAX || dt == INT64_MAX) {
1897 last_part_rate = INT_MAX;
1898 last_part_dist = INT64_MAX;
1901 last_part_rate += rt;
1902 last_part_dist += dt;
1909 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1910 if (last_part_rate < INT_MAX) {
1911 last_part_rate += x->partition_cost[pl][partition];
1912 last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist);
1915 if (do_partition_search
1916 && cpi->sf.adjust_partitioning_from_last_frame
1917 && cpi->sf.partition_search_type == SEARCH_PARTITION
1918 && partition != PARTITION_SPLIT && bsize > BLOCK_8X8
1919 && (mi_row + mi_step < cm->mi_rows ||
1920 mi_row + (mi_step >> 1) == cm->mi_rows)
1921 && (mi_col + mi_step < cm->mi_cols ||
1922 mi_col + (mi_step >> 1) == cm->mi_cols)) {
1923 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
1926 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1929 for (i = 0; i < 4; i++) {
1930 int x_idx = (i & 1) * (mi_step >> 1);
1931 int y_idx = (i >> 1) * (mi_step >> 1);
1934 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1935 PARTITION_CONTEXT sl[8], sa[8];
1937 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1940 *get_sb_index(x, split_subsize) = i;
1941 *get_sb_partitioning(x, bsize) = split_subsize;
1942 *get_sb_partitioning(x, split_subsize) = split_subsize;
1944 save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1946 rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt,
1947 split_subsize, get_block_context(x, split_subsize),
1950 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1952 if (rt == INT_MAX || dt == INT64_MAX) {
1953 chosen_rate = INT_MAX;
1954 chosen_dist = INT64_MAX;
1962 encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0,
1965 pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
1967 chosen_rate += x->partition_cost[pl][PARTITION_NONE];
1969 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1970 if (chosen_rate < INT_MAX) {
1971 chosen_rate += x->partition_cost[pl][PARTITION_SPLIT];
1972 chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist);
1976 // If last_part is better set the partitioning to that...
1977 if (last_part_rd < chosen_rd) {
1978 mi_8x8[0]->mbmi.sb_type = bsize;
1979 if (bsize >= BLOCK_8X8)
1980 *(get_sb_partitioning(x, bsize)) = subsize;
1981 chosen_rate = last_part_rate;
1982 chosen_dist = last_part_dist;
1983 chosen_rd = last_part_rd;
1985 // If none was better set the partitioning to that...
1986 if (none_rd < chosen_rd) {
1987 if (bsize >= BLOCK_8X8)
1988 *(get_sb_partitioning(x, bsize)) = bsize;
1989 chosen_rate = none_rate;
1990 chosen_dist = none_dist;
1993 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1995 // We must have chosen a partitioning and encoding or we'll fail later on.
1996 // No other opportunities for success.
1997 if ( bsize == BLOCK_64X64)
1998 assert(chosen_rate < INT_MAX && chosen_dist < INT64_MAX);
2001 int output_enabled = (bsize == BLOCK_64X64);
2003 // Check the projected output rate for this SB against it's target
2004 // and and if necessary apply a Q delta using segmentation to get
2005 // closer to the target.
2006 if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
2007 vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
2008 output_enabled, chosen_rate);
2011 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2012 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
2013 chosen_rate, chosen_dist);
2015 encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
2018 *rate = chosen_rate;
2019 *dist = chosen_dist;
2022 static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
2023 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
2024 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
2025 BLOCK_8X8, BLOCK_8X8, BLOCK_8X8,
2026 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
2030 static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
2031 BLOCK_8X8, BLOCK_16X16, BLOCK_16X16,
2032 BLOCK_16X16, BLOCK_32X32, BLOCK_32X32,
2033 BLOCK_32X32, BLOCK_64X64, BLOCK_64X64,
2034 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64,
2038 // Look at all the mode_info entries for blocks that are part of this
2039 // partition and find the min and max values for sb_type.
2040 // At the moment this is designed to work on a 64x64 SB but could be
2041 // adjusted to use a size parameter.
2043 // The min and max are assumed to have been initialized prior to calling this
2044 // function so repeat calls can accumulate a min and max of more than one sb64.
2045 static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8,
2046 BLOCK_SIZE * min_block_size,
2047 BLOCK_SIZE * max_block_size ) {
2048 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
2049 int sb_width_in_blocks = MI_BLOCK_SIZE;
2050 int sb_height_in_blocks = MI_BLOCK_SIZE;
2054 // Check the sb_type for each block that belongs to this region.
2055 for (i = 0; i < sb_height_in_blocks; ++i) {
2056 for (j = 0; j < sb_width_in_blocks; ++j) {
2057 MODE_INFO * mi = mi_8x8[index+j];
2058 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0;
2059 *min_block_size = MIN(*min_block_size, sb_type);
2060 *max_block_size = MAX(*max_block_size, sb_type);
2062 index += xd->mi_stride;
2066 // Next square block size less or equal than current block size.
2067 static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2068 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
2069 BLOCK_8X8, BLOCK_8X8, BLOCK_8X8,
2070 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
2071 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32,
2075 // Look at neighboring blocks and set a min and max partition size based on
2077 static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
2078 int mi_row, int mi_col,
2079 BLOCK_SIZE *min_block_size,
2080 BLOCK_SIZE *max_block_size) {
2081 VP9_COMMON *const cm = &cpi->common;
2082 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
2083 MODE_INFO **mi_8x8 = xd->mi;
2084 const int left_in_image = xd->left_available && mi_8x8[-1];
2085 const int above_in_image = xd->up_available &&
2086 mi_8x8[-xd->mi_stride];
2087 MODE_INFO **above_sb64_mi_8x8;
2088 MODE_INFO **left_sb64_mi_8x8;
2090 int row8x8_remaining = tile->mi_row_end - mi_row;
2091 int col8x8_remaining = tile->mi_col_end - mi_col;
2093 BLOCK_SIZE min_size = BLOCK_4X4;
2094 BLOCK_SIZE max_size = BLOCK_64X64;
2095 // Trap case where we do not have a prediction.
2096 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
2097 // Default "min to max" and "max to min"
2098 min_size = BLOCK_64X64;
2099 max_size = BLOCK_4X4;
2101 // NOTE: each call to get_sb_partition_size_range() uses the previous
2102 // passed in values for min and max as a starting point.
2103 // Find the min and max partition used in previous frame at this location
2104 if (cm->frame_type != KEY_FRAME) {
2105 MODE_INFO **const prev_mi =
2106 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
2107 get_sb_partition_size_range(cpi, prev_mi, &min_size, &max_size);
2109 // Find the min and max partition sizes used in the left SB64
2110 if (left_in_image) {
2111 left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE];
2112 get_sb_partition_size_range(cpi, left_sb64_mi_8x8,
2113 &min_size, &max_size);
2115 // Find the min and max partition sizes used in the above SB64.
2116 if (above_in_image) {
2117 above_sb64_mi_8x8 = &mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE];
2118 get_sb_partition_size_range(cpi, above_sb64_mi_8x8,
2119 &min_size, &max_size);
2121 // adjust observed min and max
2122 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
2123 min_size = min_partition_size[min_size];
2124 max_size = max_partition_size[max_size];
2128 // Check border cases where max and min from neighbors may not be legal.
2129 max_size = find_partition_size(max_size,
2130 row8x8_remaining, col8x8_remaining,
2132 min_size = MIN(min_size, max_size);
2134 // When use_square_partition_only is true, make sure at least one square
2135 // partition is allowed by selecting the next smaller square size as
2137 if (cpi->sf.use_square_partition_only &&
2138 next_square_size[max_size] < min_size) {
2139 min_size = next_square_size[max_size];
2141 *min_block_size = min_size;
2142 *max_block_size = max_size;
2145 static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2146 vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
2149 static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
2150 vpx_memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
2153 // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
2154 // unlikely to be selected depending on previous rate-distortion optimization
2155 // results, for encoding speed-up.
2156 static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
2157 TOKENEXTRA **tp, int mi_row,
2158 int mi_col, BLOCK_SIZE bsize, int *rate,
2159 int64_t *dist, int do_recon, int64_t best_rd) {
2160 VP9_COMMON *const cm = &cpi->common;
2161 MACROBLOCK *const x = &cpi->mb;
2162 MACROBLOCKD *const xd = &x->e_mbd;
2163 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
2164 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
2165 PARTITION_CONTEXT sl[8], sa[8];
2166 TOKENEXTRA *tp_orig = *tp;
2167 PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
2170 int this_rate, sum_rate = 0, best_rate = INT_MAX;
2171 int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
2173 int do_split = bsize >= BLOCK_8X8;
2175 // Override skipping rectangular partition operations for edge blocks
2176 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
2177 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
2178 const int xss = x->e_mbd.plane[1].subsampling_x;
2179 const int yss = x->e_mbd.plane[1].subsampling_y;
2181 int partition_none_allowed = !force_horz_split && !force_vert_split;
2182 int partition_horz_allowed = !force_vert_split && yss <= xss &&
2184 int partition_vert_allowed = !force_horz_split && xss <= yss &&
2188 if (bsize < BLOCK_8X8) {
2189 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
2190 // there is nothing to be done.
2191 if (x->ab_index != 0) {
2197 assert(num_8x8_blocks_wide_lookup[bsize] ==
2198 num_8x8_blocks_high_lookup[bsize]);
2200 if (bsize == BLOCK_16X16) {
2201 set_offsets(cpi, tile, mi_row, mi_col, bsize);
2202 x->mb_energy = vp9_block_energy(cpi, x, bsize);
2204 x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
2207 // Determine partition types in search according to the speed features.
2208 // The threshold set here has to be of square block size.
2209 if (cpi->sf.auto_min_max_partition_size) {
2210 partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
2211 bsize >= cpi->sf.min_partition_size);
2212 partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2213 bsize > cpi->sf.min_partition_size) ||
2215 partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2216 bsize > cpi->sf.min_partition_size) ||
2218 do_split &= bsize > cpi->sf.min_partition_size;
2220 if (cpi->sf.use_square_partition_only) {
2221 partition_horz_allowed &= force_horz_split;
2222 partition_vert_allowed &= force_vert_split;
2225 save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2227 if (cpi->sf.disable_split_var_thresh && partition_none_allowed) {
2228 unsigned int source_variancey;
2229 vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
2230 source_variancey = get_sby_perpixel_variance(cpi, x, bsize);
2231 if (source_variancey < cpi->sf.disable_split_var_thresh) {
2233 if (source_variancey < cpi->sf.disable_split_var_thresh / 2)
2238 if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
2241 if (partition_none_allowed) {
2242 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize,
2244 if (this_rate != INT_MAX) {
2245 if (bsize >= BLOCK_8X8) {
2246 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2247 this_rate += x->partition_cost[pl][PARTITION_NONE];
2249 sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
2250 if (sum_rd < best_rd) {
2251 int64_t stop_thresh = 4096;
2252 int64_t stop_thresh_rd;
2254 best_rate = this_rate;
2255 best_dist = this_dist;
2257 if (bsize >= BLOCK_8X8)
2258 *(get_sb_partitioning(x, bsize)) = bsize;
2260 // Adjust threshold according to partition size.
2261 stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
2262 b_height_log2_lookup[bsize]);
2264 stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
2265 // If obtained distortion is very small, choose current partition
2266 // and stop splitting.
2267 if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
2273 if (!x->in_active_map) {
2277 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2280 // store estimated motion vector
2281 if (cpi->sf.adaptive_motion_search)
2282 store_pred_mv(x, ctx);
2286 // TODO(jingning): use the motion vectors given by the above search as
2287 // the starting point of motion search in the following partition type check.
2289 subsize = get_subsize(bsize, PARTITION_SPLIT);
2290 for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
2291 const int x_idx = (i & 1) * mi_step;
2292 const int y_idx = (i >> 1) * mi_step;
2294 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2297 *get_sb_index(x, subsize) = i;
2298 if (cpi->sf.adaptive_motion_search)
2299 load_pred_mv(x, ctx);
2300 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2301 partition_none_allowed)
2302 get_block_context(x, subsize)->pred_interp_filter =
2303 ctx->mic.mbmi.interp_filter;
2304 rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize,
2305 &this_rate, &this_dist, i != 3, best_rd - sum_rd);
2307 if (this_rate == INT_MAX) {
2310 sum_rate += this_rate;
2311 sum_dist += this_dist;
2312 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2315 if (sum_rd < best_rd && i == 4) {
2316 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2317 sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
2318 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2319 if (sum_rd < best_rd) {
2320 best_rate = sum_rate;
2321 best_dist = sum_dist;
2323 *(get_sb_partitioning(x, bsize)) = subsize;
2326 // skip rectangular partition test when larger block size
2327 // gives better rd cost
2328 if (cpi->sf.less_rectangular_check)
2329 do_rect &= !partition_none_allowed;
2331 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2335 if (partition_horz_allowed && do_rect) {
2336 subsize = get_subsize(bsize, PARTITION_HORZ);
2337 *get_sb_index(x, subsize) = 0;
2338 if (cpi->sf.adaptive_motion_search)
2339 load_pred_mv(x, ctx);
2340 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2341 partition_none_allowed)
2342 get_block_context(x, subsize)->pred_interp_filter =
2343 ctx->mic.mbmi.interp_filter;
2344 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
2345 get_block_context(x, subsize), best_rd);
2346 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2348 if (sum_rd < best_rd && mi_row + mi_step < cm->mi_rows) {
2349 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
2351 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
2353 *get_sb_index(x, subsize) = 1;
2354 if (cpi->sf.adaptive_motion_search)
2355 load_pred_mv(x, ctx);
2356 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2357 partition_none_allowed)
2358 get_block_context(x, subsize)->pred_interp_filter =
2359 ctx->mic.mbmi.interp_filter;
2360 rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rate,
2361 &this_dist, subsize, get_block_context(x, subsize),
2363 if (this_rate == INT_MAX) {
2366 sum_rate += this_rate;
2367 sum_dist += this_dist;
2368 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2371 if (sum_rd < best_rd) {
2372 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2373 sum_rate += x->partition_cost[pl][PARTITION_HORZ];
2374 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2375 if (sum_rd < best_rd) {
2377 best_rate = sum_rate;
2378 best_dist = sum_dist;
2379 *(get_sb_partitioning(x, bsize)) = subsize;
2382 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2386 if (partition_vert_allowed && do_rect) {
2387 subsize = get_subsize(bsize, PARTITION_VERT);
2389 *get_sb_index(x, subsize) = 0;
2390 if (cpi->sf.adaptive_motion_search)
2391 load_pred_mv(x, ctx);
2392 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2393 partition_none_allowed)
2394 get_block_context(x, subsize)->pred_interp_filter =
2395 ctx->mic.mbmi.interp_filter;
2396 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
2397 get_block_context(x, subsize), best_rd);
2398 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2399 if (sum_rd < best_rd && mi_col + mi_step < cm->mi_cols) {
2400 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
2402 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
2404 *get_sb_index(x, subsize) = 1;
2405 if (cpi->sf.adaptive_motion_search)
2406 load_pred_mv(x, ctx);
2407 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2408 partition_none_allowed)
2409 get_block_context(x, subsize)->pred_interp_filter =
2410 ctx->mic.mbmi.interp_filter;
2411 rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rate,
2412 &this_dist, subsize, get_block_context(x, subsize),
2414 if (this_rate == INT_MAX) {
2417 sum_rate += this_rate;
2418 sum_dist += this_dist;
2419 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2422 if (sum_rd < best_rd) {
2423 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2424 sum_rate += x->partition_cost[pl][PARTITION_VERT];
2425 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2426 if (sum_rd < best_rd) {
2427 best_rate = sum_rate;
2428 best_dist = sum_dist;
2430 *(get_sb_partitioning(x, bsize)) = subsize;
2433 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2436 // TODO(jbb): This code added so that we avoid static analysis
2437 // warning related to the fact that best_rd isn't used after this
2438 // point. This code should be refactored so that the duplicate
2439 // checks occur in some sub function and thus are used...
2444 if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
2445 int output_enabled = (bsize == BLOCK_64X64);
2447 // Check the projected output rate for this SB against it's target
2448 // and and if necessary apply a Q delta using segmentation to get
2449 // closer to the target.
2450 if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
2451 vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
2455 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2456 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
2457 best_rate, best_dist);
2459 encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
2461 if (bsize == BLOCK_64X64) {
2462 assert(tp_orig < *tp);
2463 assert(best_rate < INT_MAX);
2464 assert(best_dist < INT64_MAX);
2466 assert(tp_orig == *tp);
2470 static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
2471 int mi_row, TOKENEXTRA **tp) {
2472 VP9_COMMON *const cm = &cpi->common;
2473 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
2474 SPEED_FEATURES *const sf = &cpi->sf;
2477 // Initialize the left context for the new SB row
2478 vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
2479 vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
2481 // Code each SB in the row
2482 for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
2483 mi_col += MI_BLOCK_SIZE) {
2488 MACROBLOCK *x = &cpi->mb;
2490 if (sf->adaptive_pred_interp_filter) {
2491 for (i = BLOCK_4X4; i < BLOCK_8X8; ++i) {
2492 const int num_4x4_w = num_4x4_blocks_wide_lookup[i];
2493 const int num_4x4_h = num_4x4_blocks_high_lookup[i];
2494 const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h);
2495 for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index)
2496 for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index)
2497 for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index)
2498 get_block_context(x, i)->pred_interp_filter = SWITCHABLE;
2502 vp9_zero(cpi->mb.pred_mv);
2504 if ((sf->partition_search_type == SEARCH_PARTITION &&
2505 sf->use_lastframe_partitioning) ||
2506 sf->partition_search_type == FIXED_PARTITION ||
2507 sf->partition_search_type == VAR_BASED_PARTITION ||
2508 sf->partition_search_type == VAR_BASED_FIXED_PARTITION) {
2509 const int idx_str = cm->mi_stride * mi_row + mi_col;
2510 MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
2511 MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
2512 cpi->mb.source_variance = UINT_MAX;
2513 if (sf->partition_search_type == FIXED_PARTITION) {
2514 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2515 set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
2516 sf->always_this_block_size);
2517 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2518 &dummy_rate, &dummy_dist, 1);
2519 } else if (sf->partition_search_type == VAR_BASED_FIXED_PARTITION) {
2521 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2522 bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
2523 set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
2524 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2525 &dummy_rate, &dummy_dist, 1);
2526 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
2527 choose_partitioning(cpi, tile, mi_row, mi_col);
2528 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2529 &dummy_rate, &dummy_dist, 1);
2531 if ((cm->current_video_frame
2532 % sf->last_partitioning_redo_frequency) == 0
2534 || cm->show_frame == 0
2535 || cm->frame_type == KEY_FRAME
2536 || cpi->rc.is_src_frame_alt_ref
2537 || ((sf->use_lastframe_partitioning ==
2538 LAST_FRAME_PARTITION_LOW_MOTION) &&
2539 sb_has_motion(cm, prev_mi_8x8))) {
2540 // If required set upper and lower partition size limits
2541 if (sf->auto_min_max_partition_size) {
2542 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2543 rd_auto_partition_range(cpi, tile, mi_row, mi_col,
2544 &sf->min_partition_size,
2545 &sf->max_partition_size);
2547 rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
2548 &dummy_rate, &dummy_dist, 1, INT64_MAX);
2550 if (sf->constrain_copy_partition &&
2551 sb_has_motion(cm, prev_mi_8x8))
2552 constrain_copy_partitioning(cpi, tile, mi_8x8, prev_mi_8x8,
2553 mi_row, mi_col, BLOCK_16X16);
2555 copy_partitioning(cm, mi_8x8, prev_mi_8x8);
2556 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2557 &dummy_rate, &dummy_dist, 1);
2561 // If required set upper and lower partition size limits
2562 if (sf->auto_min_max_partition_size) {
2563 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2564 rd_auto_partition_range(cpi, tile, mi_row, mi_col,
2565 &sf->min_partition_size,
2566 &sf->max_partition_size);
2568 rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
2569 &dummy_rate, &dummy_dist, 1, INT64_MAX);
2574 static void init_encode_frame_mb_context(VP9_COMP *cpi) {
2575 MACROBLOCK *const x = &cpi->mb;
2576 VP9_COMMON *const cm = &cpi->common;
2577 MACROBLOCKD *const xd = &x->e_mbd;
2578 const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
2580 x->act_zbin_adj = 0;
2582 // Copy data over into macro block data structures.
2583 vp9_setup_src_planes(x, cpi->Source, 0, 0);
2585 // TODO(jkoleszar): are these initializations required?
2586 vp9_setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0,
2588 vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0);
2590 vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
2592 xd->mi[0]->mbmi.mode = DC_PRED;
2593 xd->mi[0]->mbmi.uv_mode = DC_PRED;
2595 // Note: this memset assumes above_context[0], [1] and [2]
2596 // are allocated as part of the same buffer.
2597 vpx_memset(xd->above_context[0], 0,
2598 sizeof(*xd->above_context[0]) *
2599 2 * aligned_mi_cols * MAX_MB_PLANE);
2600 vpx_memset(xd->above_seg_context, 0,
2601 sizeof(*xd->above_seg_context) * aligned_mi_cols);
2604 static void switch_lossless_mode(VP9_COMP *cpi, int lossless) {
2606 // printf("Switching to lossless\n");
2607 cpi->mb.fwd_txm4x4 = vp9_fwht4x4;
2608 cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add;
2609 cpi->mb.optimize = 0;
2610 cpi->common.lf.filter_level = 0;
2611 cpi->zbin_mode_boost_enabled = 0;
2612 cpi->common.tx_mode = ONLY_4X4;
2614 // printf("Not lossless\n");
2615 cpi->mb.fwd_txm4x4 = vp9_fdct4x4;
2616 cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add;
2620 static int check_dual_ref_flags(VP9_COMP *cpi) {
2621 const int ref_flags = cpi->ref_frame_flags;
2623 if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
2626 return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG)
2627 + !!(ref_flags & VP9_ALT_FLAG)) >= 2;
2631 static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) {
2633 const int mis = cm->mi_stride;
2634 MODE_INFO **mi_ptr = cm->mi_grid_visible;
2636 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
2637 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
2638 if (mi_ptr[mi_col]->mbmi.tx_size > txfm_max)
2639 mi_ptr[mi_col]->mbmi.tx_size = txfm_max;
2644 static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
2645 if (frame_is_intra_only(&cpi->common))
2647 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
2648 return ALTREF_FRAME;
2649 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
2652 return GOLDEN_FRAME;
2655 static TX_MODE select_tx_mode(const VP9_COMP *cpi) {
2656 if (cpi->oxcf.lossless) {
2658 } else if (cpi->common.current_video_frame == 0) {
2659 return TX_MODE_SELECT;
2661 if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
2663 } else if (cpi->sf.tx_size_search_method == USE_FULL_RD) {
2664 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
2665 return cpi->rd_tx_select_threshes[frame_type][ALLOW_32X32] >
2666 cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ?
2667 ALLOW_32X32 : TX_MODE_SELECT;
2669 unsigned int total = 0;
2671 for (i = 0; i < TX_SIZES; ++i)
2672 total += cpi->tx_stepdown_count[i];
2675 const double fraction = (double)cpi->tx_stepdown_count[0] / total;
2676 return fraction > 0.90 ? ALLOW_32X32 : TX_MODE_SELECT;
2678 return cpi->common.tx_mode;
2684 // Start RTC Exploration
2687 ZERO_PLUS_PREDICTED = 1,
2689 NEW_PLUS_NON_INTRA = 3,
2691 INTRA_PLUS_NON_INTRA = 5,
2694 } motion_vector_context;
2696 static void set_mode_info(MB_MODE_INFO *mbmi, BLOCK_SIZE bsize,
2697 MB_PREDICTION_MODE mode) {
2699 mbmi->uv_mode = mode;
2700 mbmi->mv[0].as_int = 0;
2701 mbmi->mv[1].as_int = 0;
2702 mbmi->ref_frame[0] = INTRA_FRAME;
2703 mbmi->ref_frame[1] = NONE;
2704 mbmi->tx_size = max_txsize_lookup[bsize];
2706 mbmi->sb_type = bsize;
2707 mbmi->segment_id = 0;
2710 static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
2711 int mi_row, int mi_col,
2712 int *rate, int64_t *dist,
2714 VP9_COMMON *const cm = &cpi->common;
2715 MACROBLOCK *const x = &cpi->mb;
2716 MACROBLOCKD *const xd = &x->e_mbd;
2717 set_offsets(cpi, tile, mi_row, mi_col, bsize);
2718 xd->mi[0]->mbmi.sb_type = bsize;
2720 if (!frame_is_intra_only(cm)) {
2721 vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col,
2724 MB_PREDICTION_MODE intramode = DC_PRED;
2725 set_mode_info(&xd->mi[0]->mbmi, bsize, intramode);
2727 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2730 static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
2731 int mi_row, int mi_col,
2732 BLOCK_SIZE bsize, BLOCK_SIZE subsize) {
2733 MACROBLOCKD *xd = &x->e_mbd;
2734 int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
2735 PARTITION_TYPE partition = partition_lookup[bsl][subsize];
2737 assert(bsize >= BLOCK_8X8);
2739 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
2742 switch (partition) {
2743 case PARTITION_NONE:
2744 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2745 *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2746 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2748 case PARTITION_VERT:
2749 *get_sb_index(x, subsize) = 0;
2750 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2751 *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2752 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2754 if (mi_col + hbs < cm->mi_cols) {
2755 *get_sb_index(x, subsize) = 1;
2756 set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs);
2757 *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2758 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize);
2761 case PARTITION_HORZ:
2762 *get_sb_index(x, subsize) = 0;
2763 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2764 *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2765 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2766 if (mi_row + hbs < cm->mi_rows) {
2767 *get_sb_index(x, subsize) = 1;
2768 set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col);
2769 *(xd->mi[0]) = get_block_context(x, subsize)->mic;
2770 duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize);
2773 case PARTITION_SPLIT:
2774 *get_sb_index(x, subsize) = 0;
2775 fill_mode_info_sb(cm, x, mi_row, mi_col, subsize,
2776 *(get_sb_partitioning(x, subsize)));
2777 *get_sb_index(x, subsize) = 1;
2778 fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize,
2779 *(get_sb_partitioning(x, subsize)));
2780 *get_sb_index(x, subsize) = 2;
2781 fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize,
2782 *(get_sb_partitioning(x, subsize)));
2783 *get_sb_index(x, subsize) = 3;
2784 fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize,
2785 *(get_sb_partitioning(x, subsize)));
2792 static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
2793 TOKENEXTRA **tp, int mi_row,
2794 int mi_col, BLOCK_SIZE bsize, int *rate,
2795 int64_t *dist, int do_recon, int64_t best_rd) {
2796 VP9_COMMON *const cm = &cpi->common;
2797 MACROBLOCK *const x = &cpi->mb;
2798 MACROBLOCKD *const xd = &x->e_mbd;
2799 const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
2800 TOKENEXTRA *tp_orig = *tp;
2801 PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
2804 int this_rate, sum_rate = 0, best_rate = INT_MAX;
2805 int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
2807 int do_split = bsize >= BLOCK_8X8;
2809 // Override skipping rectangular partition operations for edge blocks
2810 const int force_horz_split = (mi_row + ms >= cm->mi_rows);
2811 const int force_vert_split = (mi_col + ms >= cm->mi_cols);
2812 const int xss = x->e_mbd.plane[1].subsampling_x;
2813 const int yss = x->e_mbd.plane[1].subsampling_y;
2815 int partition_none_allowed = !force_horz_split && !force_vert_split;
2816 int partition_horz_allowed = !force_vert_split && yss <= xss &&
2818 int partition_vert_allowed = !force_horz_split && xss <= yss &&
2822 if (bsize < BLOCK_8X8) {
2823 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
2824 // there is nothing to be done.
2825 if (x->ab_index != 0) {
2832 assert(num_8x8_blocks_wide_lookup[bsize] ==
2833 num_8x8_blocks_high_lookup[bsize]);
2835 x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize);
2837 // Determine partition types in search according to the speed features.
2838 // The threshold set here has to be of square block size.
2839 if (cpi->sf.auto_min_max_partition_size) {
2840 partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
2841 bsize >= cpi->sf.min_partition_size);
2842 partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2843 bsize > cpi->sf.min_partition_size) ||
2845 partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2846 bsize > cpi->sf.min_partition_size) ||
2848 do_split &= bsize > cpi->sf.min_partition_size;
2850 if (cpi->sf.use_square_partition_only) {
2851 partition_horz_allowed &= force_horz_split;
2852 partition_vert_allowed &= force_vert_split;
2855 if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
2859 if (partition_none_allowed) {
2860 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2861 &this_rate, &this_dist, bsize);
2862 ctx->mic.mbmi = xd->mi[0]->mbmi;
2864 if (this_rate != INT_MAX) {
2865 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2866 this_rate += x->partition_cost[pl][PARTITION_NONE];
2867 sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
2868 if (sum_rd < best_rd) {
2869 int64_t stop_thresh = 4096;
2870 int64_t stop_thresh_rd;
2872 best_rate = this_rate;
2873 best_dist = this_dist;
2875 if (bsize >= BLOCK_8X8)
2876 *(get_sb_partitioning(x, bsize)) = bsize;
2878 // Adjust threshold according to partition size.
2879 stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
2880 b_height_log2_lookup[bsize]);
2882 stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
2883 // If obtained distortion is very small, choose current partition
2884 // and stop splitting.
2885 if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
2891 if (!x->in_active_map) {
2897 // store estimated motion vector
2898 store_pred_mv(x, ctx);
2903 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2904 sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
2905 subsize = get_subsize(bsize, PARTITION_SPLIT);
2906 for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
2907 const int x_idx = (i & 1) * ms;
2908 const int y_idx = (i >> 1) * ms;
2910 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2913 *get_sb_index(x, subsize) = i;
2914 load_pred_mv(x, ctx);
2916 nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
2917 subsize, &this_rate, &this_dist, 0,
2920 if (this_rate == INT_MAX) {
2923 sum_rate += this_rate;
2924 sum_dist += this_dist;
2925 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2929 if (sum_rd < best_rd) {
2930 best_rate = sum_rate;
2931 best_dist = sum_dist;
2933 *(get_sb_partitioning(x, bsize)) = subsize;
2935 // skip rectangular partition test when larger block size
2936 // gives better rd cost
2937 if (cpi->sf.less_rectangular_check)
2938 do_rect &= !partition_none_allowed;
2943 if (partition_horz_allowed && do_rect) {
2944 subsize = get_subsize(bsize, PARTITION_HORZ);
2945 *get_sb_index(x, subsize) = 0;
2946 if (cpi->sf.adaptive_motion_search)
2947 load_pred_mv(x, ctx);
2949 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2950 &this_rate, &this_dist, subsize);
2952 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2954 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2956 if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
2957 *get_sb_index(x, subsize) = 1;
2959 load_pred_mv(x, ctx);
2961 nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col,
2962 &this_rate, &this_dist, subsize);
2964 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2966 if (this_rate == INT_MAX) {
2969 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2970 this_rate += x->partition_cost[pl][PARTITION_HORZ];
2971 sum_rate += this_rate;
2972 sum_dist += this_dist;
2973 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2976 if (sum_rd < best_rd) {
2978 best_rate = sum_rate;
2979 best_dist = sum_dist;
2980 *(get_sb_partitioning(x, bsize)) = subsize;
2985 if (partition_vert_allowed && do_rect) {
2986 subsize = get_subsize(bsize, PARTITION_VERT);
2988 *get_sb_index(x, subsize) = 0;
2989 if (cpi->sf.adaptive_motion_search)
2990 load_pred_mv(x, ctx);
2992 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2993 &this_rate, &this_dist, subsize);
2994 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
2995 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2996 if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
2997 *get_sb_index(x, subsize) = 1;
2999 load_pred_mv(x, ctx);
3001 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms,
3002 &this_rate, &this_dist, subsize);
3004 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
3006 if (this_rate == INT_MAX) {
3009 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3010 this_rate += x->partition_cost[pl][PARTITION_VERT];
3011 sum_rate += this_rate;
3012 sum_dist += this_dist;
3013 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
3016 if (sum_rd < best_rd) {
3017 best_rate = sum_rate;
3018 best_dist = sum_dist;
3020 *(get_sb_partitioning(x, bsize)) = subsize;
3027 if (best_rate == INT_MAX)
3030 // update mode info array
3031 fill_mode_info_sb(cm, x, mi_row, mi_col, bsize,
3032 *(get_sb_partitioning(x, bsize)));
3034 if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
3035 int output_enabled = (bsize == BLOCK_64X64);
3037 // Check the projected output rate for this SB against it's target
3038 // and and if necessary apply a Q delta using segmentation to get
3039 // closer to the target.
3040 if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
3041 vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
3045 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
3046 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
3047 best_rate, best_dist);
3049 encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
3052 if (bsize == BLOCK_64X64) {
3053 assert(tp_orig < *tp);
3054 assert(best_rate < INT_MAX);
3055 assert(best_dist < INT64_MAX);
3057 assert(tp_orig == *tp);
3061 static void nonrd_use_partition(VP9_COMP *cpi,
3062 const TileInfo *const tile,
3065 int mi_row, int mi_col,
3066 BLOCK_SIZE bsize, int output_enabled,
3067 int *totrate, int64_t *totdist) {
3068 VP9_COMMON *const cm = &cpi->common;
3069 MACROBLOCK *const x = &cpi->mb;
3070 MACROBLOCKD *const xd = &x->e_mbd;
3071 const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
3072 const int mis = cm->mi_stride;
3073 PARTITION_TYPE partition;
3076 int64_t dist = INT64_MAX;
3078 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
3081 subsize = (bsize >= BLOCK_8X8) ? mi_8x8[0]->mbmi.sb_type : BLOCK_4X4;
3082 partition = partition_lookup[bsl][subsize];
3084 switch (partition) {
3085 case PARTITION_NONE:
3086 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
3087 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
3089 case PARTITION_VERT:
3090 *get_sb_index(x, subsize) = 0;
3091 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
3092 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
3093 if (mi_col + hbs < cm->mi_cols) {
3094 *get_sb_index(x, subsize) = 1;
3095 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
3096 &rate, &dist, subsize);
3097 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
3098 if (rate != INT_MAX && dist != INT64_MAX &&
3099 *totrate != INT_MAX && *totdist != INT64_MAX) {
3105 case PARTITION_HORZ:
3106 *get_sb_index(x, subsize) = 0;
3107 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
3108 get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi;
3109 if (mi_row + hbs < cm->mi_rows) {
3110 *get_sb_index(x, subsize) = 1;
3111 nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
3112 &rate, &dist, subsize);
3113 get_block_context(x, subsize)->mic.mbmi = mi_8x8[0]->mbmi;
3114 if (rate != INT_MAX && dist != INT64_MAX &&
3115 *totrate != INT_MAX && *totdist != INT64_MAX) {
3121 case PARTITION_SPLIT:
3122 subsize = get_subsize(bsize, PARTITION_SPLIT);
3123 *get_sb_index(x, subsize) = 0;
3124 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
3125 subsize, output_enabled, totrate, totdist);
3126 *get_sb_index(x, subsize) = 1;
3127 nonrd_use_partition(cpi, tile, mi_8x8 + hbs, tp,
3128 mi_row, mi_col + hbs, subsize, output_enabled,
3130 if (rate != INT_MAX && dist != INT64_MAX &&
3131 *totrate != INT_MAX && *totdist != INT64_MAX) {
3135 *get_sb_index(x, subsize) = 2;
3136 nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis, tp,
3137 mi_row + hbs, mi_col, subsize, output_enabled,
3139 if (rate != INT_MAX && dist != INT64_MAX &&
3140 *totrate != INT_MAX && *totdist != INT64_MAX) {
3144 *get_sb_index(x, subsize) = 3;
3145 nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis + hbs, tp,
3146 mi_row + hbs, mi_col + hbs, subsize, output_enabled,
3148 if (rate != INT_MAX && dist != INT64_MAX &&
3149 *totrate != INT_MAX && *totdist != INT64_MAX) {
3155 assert("Invalid partition type.");
3158 if (bsize == BLOCK_64X64 && output_enabled) {
3159 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
3160 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
3161 *totrate, *totdist);
3162 encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize);
3166 static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
3167 int mi_row, TOKENEXTRA **tp) {
3168 VP9_COMMON *cm = &cpi->common;
3169 MACROBLOCKD *xd = &cpi->mb.e_mbd;
3172 // Initialize the left context for the new SB row
3173 vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
3174 vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
3176 // Code each SB in the row
3177 for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
3178 mi_col += MI_BLOCK_SIZE) {
3180 int64_t dummy_dist = 0;
3181 const int idx_str = cm->mi_stride * mi_row + mi_col;
3182 MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
3183 MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
3186 cpi->mb.source_variance = UINT_MAX;
3187 vp9_zero(cpi->mb.pred_mv);
3189 // Set the partition type of the 64X64 block
3190 switch (cpi->sf.partition_search_type) {
3191 case VAR_BASED_PARTITION:
3192 choose_partitioning(cpi, tile, mi_row, mi_col);
3193 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3194 1, &dummy_rate, &dummy_dist);
3196 case SOURCE_VAR_BASED_PARTITION:
3197 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
3198 set_source_var_based_partition(cpi, tile, mi_8x8, mi_row, mi_col);
3199 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3200 1, &dummy_rate, &dummy_dist);
3202 case VAR_BASED_FIXED_PARTITION:
3203 case FIXED_PARTITION:
3204 bsize = cpi->sf.partition_search_type == FIXED_PARTITION ?
3205 cpi->sf.always_this_block_size :
3206 get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
3207 set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
3208 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3209 1, &dummy_rate, &dummy_dist);
3211 case REFERENCE_PARTITION:
3212 if (cpi->sf.partition_check || sb_has_motion(cm, prev_mi_8x8)) {
3213 nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
3214 &dummy_rate, &dummy_dist, 1, INT64_MAX);
3216 copy_partitioning(cm, mi_8x8, prev_mi_8x8);
3217 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
3218 BLOCK_64X64, 1, &dummy_rate, &dummy_dist);
3226 // end RTC play code
3228 static void encode_frame_internal(VP9_COMP *cpi) {
3229 SPEED_FEATURES *const sf = &cpi->sf;
3230 MACROBLOCK *const x = &cpi->mb;
3231 VP9_COMMON *const cm = &cpi->common;
3232 MACROBLOCKD *const xd = &x->e_mbd;
3234 xd->mi = cm->mi_grid_visible;
3237 vp9_zero(cm->counts);
3238 vp9_zero(cpi->coef_counts);
3239 vp9_zero(cpi->tx_stepdown_count);
3240 vp9_zero(cpi->rd_comp_pred_diff);
3241 vp9_zero(cpi->rd_filter_diff);
3242 vp9_zero(cpi->rd_tx_select_diff);
3243 vp9_zero(cpi->rd_tx_select_threshes);
3245 cm->tx_mode = select_tx_mode(cpi);
3247 cpi->mb.e_mbd.lossless = cm->base_qindex == 0 &&
3248 cm->y_dc_delta_q == 0 &&
3249 cm->uv_dc_delta_q == 0 &&
3250 cm->uv_ac_delta_q == 0;
3251 switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless);
3253 vp9_frame_init_quantizer(cpi);
3255 vp9_initialize_rd_consts(cpi);
3256 vp9_initialize_me_consts(cpi, cm->base_qindex);
3257 init_encode_frame_mb_context(cpi);
3259 if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
3260 build_activity_map(cpi);
3262 cm->prev_mi = get_prev_mi(cm);
3264 if (sf->use_nonrd_pick_mode) {
3265 // Initialize internal buffer pointers for rtc coding, where non-RD
3266 // mode decision is used and hence no buffer pointer swap needed.
3268 struct macroblock_plane *const p = x->plane;
3269 struct macroblockd_plane *const pd = xd->plane;
3270 PICK_MODE_CONTEXT *ctx = &cpi->mb.sb64_context;
3272 for (i = 0; i < MAX_MB_PLANE; ++i) {
3273 p[i].coeff = ctx->coeff_pbuf[i][0];
3274 p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
3275 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
3276 p[i].eobs = ctx->eobs_pbuf[i][0];
3278 vp9_zero(x->zcoeff_blk);
3280 if (cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION &&
3281 cm->current_video_frame > 0) {
3282 int check_freq = cpi->sf.search_type_check_frequency;
3284 if ((cm->current_video_frame - 1) % check_freq == 0) {
3285 cpi->use_large_partition_rate = 0;
3288 if ((cm->current_video_frame - 1) % check_freq == 1) {
3289 const int mbs_in_b32x32 = 1 << ((b_width_log2_lookup[BLOCK_32X32] -
3290 b_width_log2_lookup[BLOCK_16X16]) +
3291 (b_height_log2_lookup[BLOCK_32X32] -
3292 b_height_log2_lookup[BLOCK_16X16]));
3293 cpi->use_large_partition_rate = cpi->use_large_partition_rate * 100 *
3294 mbs_in_b32x32 / cm->MBs;
3297 if ((cm->current_video_frame - 1) % check_freq >= 1) {
3298 if (cpi->use_large_partition_rate < 15)
3299 cpi->sf.partition_search_type = FIXED_PARTITION;
3305 struct vpx_usec_timer emr_timer;
3306 vpx_usec_timer_start(&emr_timer);
3309 // Take tiles into account and give start/end MB
3310 int tile_col, tile_row;
3311 TOKENEXTRA *tp = cpi->tok;
3312 const int tile_cols = 1 << cm->log2_tile_cols;
3313 const int tile_rows = 1 << cm->log2_tile_rows;
3315 for (tile_row = 0; tile_row < tile_rows; tile_row++) {
3316 for (tile_col = 0; tile_col < tile_cols; tile_col++) {
3318 TOKENEXTRA *tp_old = tp;
3321 // For each row of SBs in the frame
3322 vp9_tile_init(&tile, cm, tile_row, tile_col);
3323 for (mi_row = tile.mi_row_start;
3324 mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) {
3325 if (sf->use_nonrd_pick_mode && cm->frame_type != KEY_FRAME)
3326 encode_nonrd_sb_row(cpi, &tile, mi_row, &tp);
3328 encode_rd_sb_row(cpi, &tile, mi_row, &tp);
3330 cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old);
3331 assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols));
3336 vpx_usec_timer_mark(&emr_timer);
3337 cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer);
3340 if (sf->skip_encode_sb) {
3342 unsigned int intra_count = 0, inter_count = 0;
3343 for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) {
3344 intra_count += cm->counts.intra_inter[j][0];
3345 inter_count += cm->counts.intra_inter[j][1];
3347 sf->skip_encode_frame = (intra_count << 2) < inter_count &&
3348 cm->frame_type != KEY_FRAME &&
3351 sf->skip_encode_frame = 0;
3355 // Keep record of the total distortion this time around for future use
3356 cpi->last_frame_distortion = cpi->frame_distortion;
3360 void vp9_encode_frame(VP9_COMP *cpi) {
3361 VP9_COMMON *const cm = &cpi->common;
3363 // In the longer term the encoder should be generalized to match the
3364 // decoder such that we allow compound where one of the 3 buffers has a
3365 // different sign bias and that buffer is then the fixed ref. However, this
3366 // requires further work in the rd loop. For now the only supported encoder
3367 // side behavior is where the ALT ref buffer has opposite sign bias to
3369 if (!frame_is_intra_only(cm)) {
3370 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3371 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
3372 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3373 cm->ref_frame_sign_bias[LAST_FRAME])) {
3374 cm->allow_comp_inter_inter = 0;
3376 cm->allow_comp_inter_inter = 1;
3377 cm->comp_fixed_ref = ALTREF_FRAME;
3378 cm->comp_var_ref[0] = LAST_FRAME;
3379 cm->comp_var_ref[1] = GOLDEN_FRAME;
3383 if (cpi->sf.frame_parameter_update) {
3386 // This code does a single RD pass over the whole frame assuming
3387 // either compound, single or hybrid prediction as per whatever has
3388 // worked best for that type of frame in the past.
3389 // It also predicts whether another coding mode would have worked
3390 // better that this coding mode. If that is the case, it remembers
3391 // that for subsequent frames.
3392 // It does the same analysis for transform size selection also.
3393 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
3394 const int64_t *mode_thresh = cpi->rd_prediction_type_threshes[frame_type];
3395 const int64_t *filter_thresh = cpi->rd_filter_threshes[frame_type];
3397 /* prediction (compound, single or hybrid) mode selection */
3398 if (frame_type == ALTREF_FRAME || !cm->allow_comp_inter_inter)
3399 cm->reference_mode = SINGLE_REFERENCE;
3400 else if (mode_thresh[COMPOUND_REFERENCE] > mode_thresh[SINGLE_REFERENCE] &&
3401 mode_thresh[COMPOUND_REFERENCE] >
3402 mode_thresh[REFERENCE_MODE_SELECT] &&
3403 check_dual_ref_flags(cpi) &&
3404 cpi->static_mb_pct == 100)
3405 cm->reference_mode = COMPOUND_REFERENCE;
3406 else if (mode_thresh[SINGLE_REFERENCE] > mode_thresh[REFERENCE_MODE_SELECT])
3407 cm->reference_mode = SINGLE_REFERENCE;
3409 cm->reference_mode = REFERENCE_MODE_SELECT;
3411 if (cm->interp_filter == SWITCHABLE) {
3412 if (frame_type != ALTREF_FRAME &&
3413 filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP] &&
3414 filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP_SHARP] &&
3415 filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[SWITCHABLE - 1]) {
3416 cm->interp_filter = EIGHTTAP_SMOOTH;
3417 } else if (filter_thresh[EIGHTTAP_SHARP] > filter_thresh[EIGHTTAP] &&
3418 filter_thresh[EIGHTTAP_SHARP] > filter_thresh[SWITCHABLE - 1]) {
3419 cm->interp_filter = EIGHTTAP_SHARP;
3420 } else if (filter_thresh[EIGHTTAP] > filter_thresh[SWITCHABLE - 1]) {
3421 cm->interp_filter = EIGHTTAP;
3425 encode_frame_internal(cpi);
3427 for (i = 0; i < REFERENCE_MODES; ++i) {
3428 const int diff = (int) (cpi->rd_comp_pred_diff[i] / cm->MBs);
3429 cpi->rd_prediction_type_threshes[frame_type][i] += diff;
3430 cpi->rd_prediction_type_threshes[frame_type][i] >>= 1;
3433 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
3434 const int64_t diff = cpi->rd_filter_diff[i] / cm->MBs;
3435 cpi->rd_filter_threshes[frame_type][i] =
3436 (cpi->rd_filter_threshes[frame_type][i] + diff) / 2;
3439 for (i = 0; i < TX_MODES; ++i) {
3440 int64_t pd = cpi->rd_tx_select_diff[i];
3442 if (i == TX_MODE_SELECT)
3443 pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZES - 1), 0);
3444 diff = (int) (pd / cm->MBs);
3445 cpi->rd_tx_select_threshes[frame_type][i] += diff;
3446 cpi->rd_tx_select_threshes[frame_type][i] /= 2;
3449 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
3450 int single_count_zero = 0;
3451 int comp_count_zero = 0;
3453 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
3454 single_count_zero += cm->counts.comp_inter[i][0];
3455 comp_count_zero += cm->counts.comp_inter[i][1];
3458 if (comp_count_zero == 0) {
3459 cm->reference_mode = SINGLE_REFERENCE;
3460 vp9_zero(cm->counts.comp_inter);
3461 } else if (single_count_zero == 0) {
3462 cm->reference_mode = COMPOUND_REFERENCE;
3463 vp9_zero(cm->counts.comp_inter);
3467 if (cm->tx_mode == TX_MODE_SELECT) {
3469 int count8x8_lp = 0, count8x8_8x8p = 0;
3470 int count16x16_16x16p = 0, count16x16_lp = 0;
3473 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
3474 count4x4 += cm->counts.tx.p32x32[i][TX_4X4];
3475 count4x4 += cm->counts.tx.p16x16[i][TX_4X4];
3476 count4x4 += cm->counts.tx.p8x8[i][TX_4X4];
3478 count8x8_lp += cm->counts.tx.p32x32[i][TX_8X8];
3479 count8x8_lp += cm->counts.tx.p16x16[i][TX_8X8];
3480 count8x8_8x8p += cm->counts.tx.p8x8[i][TX_8X8];
3482 count16x16_16x16p += cm->counts.tx.p16x16[i][TX_16X16];
3483 count16x16_lp += cm->counts.tx.p32x32[i][TX_16X16];
3484 count32x32 += cm->counts.tx.p32x32[i][TX_32X32];
3487 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
3489 cm->tx_mode = ALLOW_8X8;
3490 reset_skip_txfm_size(cm, TX_8X8);
3491 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
3492 count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
3493 cm->tx_mode = ONLY_4X4;
3494 reset_skip_txfm_size(cm, TX_4X4);
3495 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
3496 cm->tx_mode = ALLOW_32X32;
3497 } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
3498 cm->tx_mode = ALLOW_16X16;
3499 reset_skip_txfm_size(cm, TX_16X16);
3503 cm->reference_mode = SINGLE_REFERENCE;
3504 cm->interp_filter = SWITCHABLE;
3505 encode_frame_internal(cpi);
3509 static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
3510 const MB_PREDICTION_MODE y_mode = mi->mbmi.mode;
3511 const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
3512 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
3514 if (bsize < BLOCK_8X8) {
3516 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
3517 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
3518 for (idy = 0; idy < 2; idy += num_4x4_h)
3519 for (idx = 0; idx < 2; idx += num_4x4_w)
3520 ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode];
3522 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
3525 ++counts->uv_mode[y_mode][uv_mode];
3528 // Experimental stub function to create a per MB zbin adjustment based on
3529 // some previously calculated measure of MB activity.
3530 static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) {
3532 x->act_zbin_adj = *(x->mb_activity_ptr);
3534 // Apply the masking to the RD multiplier.
3535 const int64_t act = *(x->mb_activity_ptr);
3536 const int64_t a = act + 4 * cpi->activity_avg;
3537 const int64_t b = 4 * act + cpi->activity_avg;
3539 if (act > cpi->activity_avg)
3540 x->act_zbin_adj = (int) (((int64_t) b + (a >> 1)) / a) - 1;
3542 x->act_zbin_adj = 1 - (int) (((int64_t) a + (b >> 1)) / b);
3546 static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) {
3548 if (is_inter_block(mbmi)) {
3549 if (mbmi->mode == ZEROMV) {
3550 return mbmi->ref_frame[0] != LAST_FRAME ? GF_ZEROMV_ZBIN_BOOST
3551 : LF_ZEROMV_ZBIN_BOOST;
3553 return mbmi->sb_type < BLOCK_8X8 ? SPLIT_MV_ZBIN_BOOST
3557 return INTRA_ZBIN_BOOST;
3564 static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
3565 int mi_row, int mi_col, BLOCK_SIZE bsize) {
3566 VP9_COMMON *const cm = &cpi->common;
3567 MACROBLOCK *const x = &cpi->mb;
3568 MACROBLOCKD *const xd = &x->e_mbd;
3569 MODE_INFO **mi_8x8 = xd->mi;
3570 MODE_INFO *mi = mi_8x8[0];
3571 MB_MODE_INFO *mbmi = &mi->mbmi;
3572 PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
3573 unsigned int segment_id = mbmi->segment_id;
3574 const int mis = cm->mi_stride;
3575 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
3576 const int mi_height = num_8x8_blocks_high_lookup[bsize];
3578 x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 &&
3579 cpi->oxcf.aq_mode != COMPLEXITY_AQ &&
3580 cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ &&
3581 cpi->sf.allow_skip_recode;
3583 x->skip_optimize = ctx->is_coded;
3585 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
3586 x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame &&
3587 x->q_index < QIDX_SKIP_THRESH);
3592 if (cm->frame_type == KEY_FRAME) {
3593 if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3594 adjust_act_zbin(cpi, x);
3595 vp9_update_zbin_extra(cpi, x);
3598 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3600 if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3601 // Adjust the zbin based on this MB rate.
3602 adjust_act_zbin(cpi, x);
3605 // Experimental code. Special case for gf and arf zeromv modes.
3606 // Increase zbin size to suppress noise
3607 cpi->zbin_mode_boost = get_zbin_mode_boost(mbmi,
3608 cpi->zbin_mode_boost_enabled);
3609 vp9_update_zbin_extra(cpi, x);
3612 if (!is_inter_block(mbmi)) {
3615 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
3616 vp9_encode_intra_block_plane(x, MAX(bsize, BLOCK_8X8), plane);
3618 sum_intra_stats(&cm->counts, mi);
3619 vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8));
3622 const int is_compound = has_second_ref(mbmi);
3623 for (ref = 0; ref < 1 + is_compound; ++ref) {
3624 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
3625 mbmi->ref_frame[ref]);
3626 vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
3627 &xd->block_refs[ref]->sf);
3629 vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
3633 vp9_encode_sb(x, MAX(bsize, BLOCK_8X8));
3634 vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8));
3638 cm->counts.skip[vp9_get_skip_context(xd)][1]++;
3639 reset_skip_context(xd, MAX(bsize, BLOCK_8X8));
3643 if (output_enabled) {
3644 if (cm->tx_mode == TX_MODE_SELECT &&
3645 mbmi->sb_type >= BLOCK_8X8 &&
3646 !(is_inter_block(mbmi) &&
3648 vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)))) {
3649 ++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
3650 &cm->counts.tx)[mbmi->tx_size];
3654 // The new intra coding scheme requires no change of transform size
3655 if (is_inter_block(&mi->mbmi)) {
3656 tx_size = MIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
3657 max_txsize_lookup[bsize]);
3659 tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
3662 for (y = 0; y < mi_height; y++)
3663 for (x = 0; x < mi_width; x++)
3664 if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
3665 mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;