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->mode_info_stride * mi_row + mi_col;
167 xd->mi_8x8 = cm->mi_grid_visible + idx_str;
168 xd->mi_8x8[0] = cm->mi + idx_str;
171 static int is_block_in_mb_map(VP9_COMP *cpi, int mi_row, int mi_col,
173 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 void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
198 int mi_row, int mi_col, BLOCK_SIZE bsize) {
199 MACROBLOCK *const x = &cpi->mb;
200 VP9_COMMON *const cm = &cpi->common;
201 MACROBLOCKD *const xd = &x->e_mbd;
203 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
204 const int mi_height = num_8x8_blocks_high_lookup[bsize];
205 const int mb_row = mi_row >> 1;
206 const int mb_col = mi_col >> 1;
207 const int idx_map = mb_row * cm->mb_cols + mb_col;
208 const struct segmentation *const seg = &cm->seg;
210 set_skip_context(xd, xd->above_context, xd->left_context, mi_row, mi_col);
212 // Activity map pointer
213 x->mb_activity_ptr = &cpi->mb_activity_map[idx_map];
215 if (cpi->active_map_enabled && !x->e_mbd.lossless) {
216 x->in_active_map = is_block_in_mb_map(cpi, mi_row, mi_col, bsize);
218 x->in_active_map = 1;
221 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
223 mbmi = &xd->mi_8x8[0]->mbmi;
225 // Set up destination pointers.
226 vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
228 // Set up limit values for MV components.
229 // Mv beyond the range do not produce new/different prediction block.
230 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
231 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
232 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
233 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
235 // Set up distance of MB to edge of frame in 1/8th pel units.
236 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
237 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
238 cm->mi_rows, cm->mi_cols);
240 // Set up source buffers.
241 vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
244 x->rddiv = cpi->RDDIV;
245 x->rdmult = cpi->RDMULT;
249 if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
250 const uint8_t *const map = seg->update_map ? cpi->segmentation_map
251 : cm->last_frame_seg_map;
252 mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
254 vp9_init_plane_quantizers(cpi, x);
256 if (seg->enabled && cpi->seg0_cnt > 0 &&
257 !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) &&
258 vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) {
259 cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
261 const int y = mb_row & ~3;
262 const int x = mb_col & ~3;
263 const int p16 = ((mb_row & 1) << 1) + (mb_col & 1);
264 const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1);
265 const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1;
266 const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1;
268 cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
272 x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
274 mbmi->segment_id = 0;
275 x->encode_breakout = cpi->encode_breakout;
279 static void duplicate_mode_info_in_sb(VP9_COMMON * const cm,
280 MACROBLOCKD *const xd,
284 const int block_width = num_8x8_blocks_wide_lookup[bsize];
285 const int block_height = num_8x8_blocks_high_lookup[bsize];
286 const int mis = xd->mode_info_stride;
288 for (j = 0; j < block_height; ++j)
289 for (i = 0; i < block_width; ++i) {
290 if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols)
291 xd->mi_8x8[j * mis + i] = xd->mi_8x8[0];
295 static void set_block_size(VP9_COMP * const cpi,
296 const TileInfo *const tile,
297 int mi_row, int mi_col,
299 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
300 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
301 set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col);
302 xd->mi_8x8[0]->mbmi.sb_type = bsize;
303 duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize);
308 int64_t sum_square_error;
318 } partition_variance;
321 partition_variance part_variances;
326 partition_variance part_variances;
331 partition_variance part_variances;
336 partition_variance part_variances;
341 partition_variance *part_variances;
351 static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
355 v64x64 *vt = (v64x64 *) data;
356 node->part_variances = &vt->part_variances;
357 for (i = 0; i < 4; i++)
358 node->split[i] = &vt->split[i].part_variances.none;
362 v32x32 *vt = (v32x32 *) data;
363 node->part_variances = &vt->part_variances;
364 for (i = 0; i < 4; i++)
365 node->split[i] = &vt->split[i].part_variances.none;
369 v16x16 *vt = (v16x16 *) data;
370 node->part_variances = &vt->part_variances;
371 for (i = 0; i < 4; i++)
372 node->split[i] = &vt->split[i].part_variances.none;
376 v8x8 *vt = (v8x8 *) data;
377 node->part_variances = &vt->part_variances;
378 for (i = 0; i < 4; i++)
379 node->split[i] = &vt->split[i];
388 // Set variance values given sum square error, sum error, count.
389 static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
390 v->sum_square_error = s2;
394 v->variance = (int)(256 *
395 (v->sum_square_error - v->sum_error * v->sum_error /
396 v->count) / v->count);
401 void sum_2_variances(const var *a, const var *b, var *r) {
402 fill_variance(a->sum_square_error + b->sum_square_error,
403 a->sum_error + b->sum_error, a->count + b->count, r);
406 static void fill_variance_tree(void *data, BLOCK_SIZE bsize) {
408 tree_to_node(data, bsize, &node);
409 sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]);
410 sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]);
411 sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]);
412 sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]);
413 sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1],
414 &node.part_variances->none);
417 static int set_vt_partitioning(VP9_COMP *cpi,
419 const TileInfo *const tile,
424 VP9_COMMON * const cm = &cpi->common;
426 const int block_width = num_8x8_blocks_wide_lookup[bsize];
427 const int block_height = num_8x8_blocks_high_lookup[bsize];
428 // TODO(debargha): Choose this more intelligently.
429 const int64_t threshold_multiplier = 25;
430 int64_t threshold = threshold_multiplier * cpi->common.base_qindex;
431 assert(block_height == block_width);
433 tree_to_node(data, bsize, &vt);
435 // Split none is available only if we have more than half a block size
436 // in width and height inside the visible image.
437 if (mi_col + block_width / 2 < cm->mi_cols &&
438 mi_row + block_height / 2 < cm->mi_rows &&
439 vt.part_variances->none.variance < threshold) {
440 set_block_size(cpi, tile, mi_row, mi_col, bsize);
444 // Vertical split is available on all but the bottom border.
445 if (mi_row + block_height / 2 < cm->mi_rows &&
446 vt.part_variances->vert[0].variance < threshold &&
447 vt.part_variances->vert[1].variance < threshold) {
448 BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
449 set_block_size(cpi, tile, mi_row, mi_col, subsize);
450 set_block_size(cpi, tile, mi_row, mi_col + block_width / 2, subsize);
454 // Horizontal split is available on all but the right border.
455 if (mi_col + block_width / 2 < cm->mi_cols &&
456 vt.part_variances->horz[0].variance < threshold &&
457 vt.part_variances->horz[1].variance < threshold) {
458 BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
459 set_block_size(cpi, tile, mi_row, mi_col, subsize);
460 set_block_size(cpi, tile, mi_row + block_height / 2, mi_col, subsize);
466 // TODO(debargha): Fix this function and make it work as expected.
467 static void choose_partitioning(VP9_COMP *cpi,
468 const TileInfo *const tile,
469 int mi_row, int mi_col) {
470 VP9_COMMON * const cm = &cpi->common;
471 MACROBLOCK *x = &cpi->mb;
472 MACROBLOCKD *xd = &cpi->mb.e_mbd;
480 int pixels_wide = 64, pixels_high = 64;
481 int_mv nearest_mv, near_mv;
482 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
483 const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
486 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
488 if (xd->mb_to_right_edge < 0)
489 pixels_wide += (xd->mb_to_right_edge >> 3);
490 if (xd->mb_to_bottom_edge < 0)
491 pixels_high += (xd->mb_to_bottom_edge >> 3);
493 s = x->plane[0].src.buf;
494 sp = x->plane[0].src.stride;
496 if (cm->frame_type != KEY_FRAME) {
497 vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf);
499 xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME;
500 xd->mi_8x8[0]->mbmi.sb_type = BLOCK_64X64;
501 vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv,
502 xd->mi_8x8[0]->mbmi.ref_mvs[LAST_FRAME],
503 &nearest_mv, &near_mv);
505 xd->mi_8x8[0]->mbmi.mv[0] = nearest_mv;
506 vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64);
508 d = xd->plane[0].dst.buf;
509 dp = xd->plane[0].dst.stride;
515 // Fill in the entire tree of 8x8 variances for splits.
516 for (i = 0; i < 4; i++) {
517 const int x32_idx = ((i & 1) << 5);
518 const int y32_idx = ((i >> 1) << 5);
519 for (j = 0; j < 4; j++) {
520 const int x16_idx = x32_idx + ((j & 1) << 4);
521 const int y16_idx = y32_idx + ((j >> 1) << 4);
522 v16x16 *vst = &vt.split[i].split[j];
523 for (k = 0; k < 4; k++) {
524 int x_idx = x16_idx + ((k & 1) << 3);
525 int y_idx = y16_idx + ((k >> 1) << 3);
526 unsigned int sse = 0;
528 if (x_idx < pixels_wide && y_idx < pixels_high)
529 vp9_get_sse_sum_8x8(s + y_idx * sp + x_idx, sp,
530 d + y_idx * dp + x_idx, dp, &sse, &sum);
531 fill_variance(sse, sum, 64, &vst->split[k].part_variances.none);
535 // Fill the rest of the variance tree by summing split partition values.
536 for (i = 0; i < 4; i++) {
537 for (j = 0; j < 4; j++) {
538 fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
540 fill_variance_tree(&vt.split[i], BLOCK_32X32);
542 fill_variance_tree(&vt, BLOCK_64X64);
544 // Now go through the entire structure, splitting every block size until
545 // we get to one that's got a variance lower than our threshold, or we
547 if (!set_vt_partitioning(cpi, &vt, tile, BLOCK_64X64,
548 mi_row, mi_col, 8)) {
549 for (i = 0; i < 4; ++i) {
550 const int x32_idx = ((i & 1) << 2);
551 const int y32_idx = ((i >> 1) << 2);
552 if (!set_vt_partitioning(cpi, &vt.split[i], tile, BLOCK_32X32,
553 (mi_row + y32_idx), (mi_col + x32_idx), 4)) {
554 for (j = 0; j < 4; ++j) {
555 const int x16_idx = ((j & 1) << 1);
556 const int y16_idx = ((j >> 1) << 1);
557 // NOTE: This is a temporary hack to disable 8x8 partitions,
558 // since it works really bad - possibly due to a bug
559 #define DISABLE_8X8_VAR_BASED_PARTITION
560 #ifdef DISABLE_8X8_VAR_BASED_PARTITION
561 if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows &&
562 mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) {
563 set_block_size(cpi, tile,
564 (mi_row + y32_idx + y16_idx),
565 (mi_col + x32_idx + x16_idx),
568 for (k = 0; k < 4; ++k) {
569 const int x8_idx = (k & 1);
570 const int y8_idx = (k >> 1);
571 set_block_size(cpi, tile,
572 (mi_row + y32_idx + y16_idx + y8_idx),
573 (mi_col + x32_idx + x16_idx + x8_idx),
578 if (!set_vt_partitioning(cpi, &vt.split[i].split[j], tile,
580 (mi_row + y32_idx + y16_idx),
581 (mi_col + x32_idx + x16_idx), 2)) {
582 for (k = 0; k < 4; ++k) {
583 const int x8_idx = (k & 1);
584 const int y8_idx = (k >> 1);
585 set_block_size(cpi, tile,
586 (mi_row + y32_idx + y16_idx + y8_idx),
587 (mi_col + x32_idx + x16_idx + x8_idx),
598 // Original activity measure from Tim T's code.
599 static unsigned int tt_activity_measure(MACROBLOCK *x) {
601 // TODO: This could also be done over smaller areas (8x8), but that would
602 // require extensive changes elsewhere, as lambda is assumed to be fixed
603 // over an entire MB in most of the code.
604 // Another option is to compute four 8x8 variances, and pick a single
605 // lambda using a non-linear combination (e.g., the smallest, or second
607 const unsigned int act = vp9_variance16x16(x->plane[0].src.buf,
608 x->plane[0].src.stride,
609 VP9_VAR_OFFS, 0, &sse) << 4;
610 // If the region is flat, lower the activity some more.
611 return act < (8 << 12) ? MIN(act, 5 << 12) : act;
614 // Stub for alternative experimental activity measures.
615 static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) {
616 return vp9_encode_intra(x, use_dc_pred);
619 // Measure the activity of the current macroblock
620 // What we measure here is TBD so abstracted to this function
621 #define ALT_ACT_MEASURE 1
622 static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) {
623 unsigned int mb_activity;
625 if (ALT_ACT_MEASURE) {
626 const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
628 // Or use and alternative.
629 mb_activity = alt_activity_measure(x, use_dc_pred);
631 // Original activity measure from Tim T's code.
632 mb_activity = tt_activity_measure(x);
635 return MAX(mb_activity, ACTIVITY_AVG_MIN);
638 // Calculate an "average" mb activity value for the frame
640 static void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) {
642 // Find median: Simple n^2 algorithm for experimentation
646 unsigned int *sortlist;
649 // Create a list to sort to
650 CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int),
653 // Copy map to sort list
654 vpx_memcpy(sortlist, cpi->mb_activity_map,
655 sizeof(unsigned int) * cpi->common.MBs);
657 // Ripple each value down to its correct position
658 for (i = 1; i < cpi->common.MBs; i ++) {
659 for (j = i; j > 0; j --) {
660 if (sortlist[j] < sortlist[j - 1]) {
662 tmp = sortlist[j - 1];
663 sortlist[j - 1] = sortlist[j];
671 // Even number MBs so estimate median as mean of two either side.
672 median = (1 + sortlist[cpi->common.MBs >> 1] +
673 sortlist[(cpi->common.MBs >> 1) + 1]) >> 1;
675 cpi->activity_avg = median;
680 // Simple mean for now
681 cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs);
684 if (cpi->activity_avg < ACTIVITY_AVG_MIN)
685 cpi->activity_avg = ACTIVITY_AVG_MIN;
687 // Experimental code: return fixed value normalized for several clips
689 cpi->activity_avg = 100000;
692 #define USE_ACT_INDEX 0
693 #define OUTPUT_NORM_ACT_STATS 0
696 // Calculate an activity index for each mb
697 static void calc_activity_index(VP9_COMP *cpi, MACROBLOCK *x) {
698 VP9_COMMON *const cm = &cpi->common;
705 #if OUTPUT_NORM_ACT_STATS
706 FILE *f = fopen("norm_act.stt", "a");
707 fprintf(f, "\n%12d\n", cpi->activity_avg);
710 // Reset pointers to start of activity map
711 x->mb_activity_ptr = cpi->mb_activity_map;
713 // Calculate normalized mb activity number.
714 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
715 // for each macroblock col in image
716 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
717 // Read activity from the map
718 act = *(x->mb_activity_ptr);
720 // Calculate a normalized activity number
721 a = act + 4 * cpi->activity_avg;
722 b = 4 * act + cpi->activity_avg;
725 *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1;
727 *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b);
729 #if OUTPUT_NORM_ACT_STATS
730 fprintf(f, " %6d", *(x->mb_activity_ptr));
732 // Increment activity map pointers
733 x->mb_activity_ptr++;
736 #if OUTPUT_NORM_ACT_STATS
741 #if OUTPUT_NORM_ACT_STATS
745 #endif // USE_ACT_INDEX
747 // Loop through all MBs. Note activity of each, average activity and
748 // calculate a normalized activity for each
749 static void build_activity_map(VP9_COMP *cpi) {
750 MACROBLOCK *const x = &cpi->mb;
751 MACROBLOCKD *xd = &x->e_mbd;
752 VP9_COMMON *const cm = &cpi->common;
755 YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm);
757 int recon_y_stride = new_yv12->y_stride;
761 unsigned int mb_activity;
762 int64_t activity_sum = 0;
764 x->mb_activity_ptr = cpi->mb_activity_map;
766 // for each macroblock row in image
767 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) {
769 // reset above block coeffs
770 xd->up_available = (mb_row != 0);
771 recon_yoffset = (mb_row * recon_y_stride * 16);
773 // for each macroblock col in image
774 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) {
776 xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
777 xd->left_available = (mb_col != 0);
782 mb_activity = mb_activity_measure(x, mb_row, mb_col);
785 activity_sum += mb_activity;
787 // Store MB level activity details.
788 *x->mb_activity_ptr = mb_activity;
790 // Increment activity map pointer
791 x->mb_activity_ptr++;
793 // adjust to the next column of source macroblocks
794 x->plane[0].src.buf += 16;
797 // adjust to the next row of mbs
798 x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
801 // Calculate an "average" MB activity
802 calc_av_activity(cpi, activity_sum);
805 // Calculate an activity index number of each mb
806 calc_activity_index(cpi, x);
810 // Macroblock activity masking
811 static void activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
813 x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
814 x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
815 x->errorperbit += (x->errorperbit == 0);
817 const int64_t act = *(x->mb_activity_ptr);
819 // Apply the masking to the RD multiplier.
820 const int64_t a = act + (2 * cpi->activity_avg);
821 const int64_t b = (2 * act) + cpi->activity_avg;
823 x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a);
824 x->errorperbit = x->rdmult * 100 / (110 * x->rddiv);
825 x->errorperbit += (x->errorperbit == 0);
828 // Activity based Zbin adjustment
829 adjust_act_zbin(cpi, x);
832 static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
833 int mi_row, int mi_col, BLOCK_SIZE bsize,
834 int output_enabled) {
836 VP9_COMMON *const cm = &cpi->common;
837 MACROBLOCK *const x = &cpi->mb;
838 MACROBLOCKD *const xd = &x->e_mbd;
839 struct macroblock_plane *const p = x->plane;
840 struct macroblockd_plane *const pd = xd->plane;
841 MODE_INFO *mi = &ctx->mic;
842 MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
843 MODE_INFO *mi_addr = xd->mi_8x8[0];
844 const struct segmentation *const seg = &cm->seg;
846 const int mis = cm->mode_info_stride;
847 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
848 const int mi_height = num_8x8_blocks_high_lookup[bsize];
851 assert(mi->mbmi.sb_type == bsize);
855 // For in frame adaptive Q, check for reseting the segment_id and updating
856 // the cyclic refresh map.
857 if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled &&
859 vp9_cyclic_refresh_update_segment(cpi, &xd->mi_8x8[0]->mbmi,
860 mi_row, mi_col, bsize, 1);
861 vp9_init_plane_quantizers(cpi, x);
864 max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
865 for (i = 0; i < max_plane; ++i) {
866 p[i].coeff = ctx->coeff_pbuf[i][1];
867 p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
868 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
869 p[i].eobs = ctx->eobs_pbuf[i][1];
872 for (i = max_plane; i < MAX_MB_PLANE; ++i) {
873 p[i].coeff = ctx->coeff_pbuf[i][2];
874 p[i].qcoeff = ctx->qcoeff_pbuf[i][2];
875 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
876 p[i].eobs = ctx->eobs_pbuf[i][2];
879 // Restore the coding context of the MB to that that was in place
880 // when the mode was picked for it
881 for (y = 0; y < mi_height; y++)
882 for (x_idx = 0; x_idx < mi_width; x_idx++)
883 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
884 && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
885 xd->mi_8x8[x_idx + y * mis] = mi_addr;
888 if (cpi->oxcf.aq_mode)
889 vp9_init_plane_quantizers(cpi, x);
891 // FIXME(rbultje) I'm pretty sure this should go to the end of this block
892 // (i.e. after the output_enabled)
893 if (bsize < BLOCK_32X32) {
894 if (bsize < BLOCK_16X16)
895 ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
896 ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
899 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
900 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
901 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
905 vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk,
906 sizeof(uint8_t) * ctx->num_4x4_blk);
911 if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
912 for (i = 0; i < TX_MODES; i++)
913 cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i];
916 #if CONFIG_INTERNAL_STATS
917 if (frame_is_intra_only(cm)) {
918 static const int kf_mode_index[] = {
920 THR_V_PRED /*V_PRED*/,
921 THR_H_PRED /*H_PRED*/,
922 THR_D45_PRED /*D45_PRED*/,
923 THR_D135_PRED /*D135_PRED*/,
924 THR_D117_PRED /*D117_PRED*/,
925 THR_D153_PRED /*D153_PRED*/,
926 THR_D207_PRED /*D207_PRED*/,
927 THR_D63_PRED /*D63_PRED*/,
930 ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]];
932 // Note how often each mode chosen as best
933 ++cpi->mode_chosen_counts[ctx->best_mode_index];
936 if (!frame_is_intra_only(cm)) {
937 if (is_inter_block(mbmi)) {
938 vp9_update_mv_count(cm, xd);
940 if (cm->interp_filter == SWITCHABLE) {
941 const int ctx = vp9_get_pred_context_switchable_interp(xd);
942 ++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
946 cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
947 cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
948 cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
950 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
951 cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
955 void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
956 int mi_row, int mi_col) {
957 uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer,
959 const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride,
963 // Set current frame pointer.
964 x->e_mbd.cur_buf = src;
966 for (i = 0; i < MAX_MB_PLANE; i++)
967 setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col,
968 NULL, x->e_mbd.plane[i].subsampling_x,
969 x->e_mbd.plane[i].subsampling_y);
972 static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
973 int mi_row, int mi_col,
974 int *totalrate, int64_t *totaldist,
975 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
977 VP9_COMMON *const cm = &cpi->common;
978 MACROBLOCK *const x = &cpi->mb;
979 MACROBLOCKD *const xd = &x->e_mbd;
981 struct macroblock_plane *const p = x->plane;
982 struct macroblockd_plane *const pd = xd->plane;
983 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
987 vp9_clear_system_state();
988 rdmult_ratio = 1.0; // avoid uninitialized warnings
990 // Use the lower precision, but faster, 32x32 fdct for mode selection.
991 x->use_lp32x32fdct = 1;
993 if (bsize < BLOCK_8X8) {
994 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
995 // there is nothing to be done.
996 if (x->ab_index != 0) {
1003 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1004 mbmi = &xd->mi_8x8[0]->mbmi;
1005 mbmi->sb_type = bsize;
1007 for (i = 0; i < MAX_MB_PLANE; ++i) {
1008 p[i].coeff = ctx->coeff_pbuf[i][0];
1009 p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
1010 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
1011 p[i].eobs = ctx->eobs_pbuf[i][0];
1016 // Set to zero to make sure we do not use the previous encoded frame stats
1019 x->source_variance = get_sby_perpixel_variance(cpi, x, bsize);
1021 if (aq_mode == VARIANCE_AQ) {
1022 const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
1023 : vp9_block_energy(cpi, x, bsize);
1025 if (cm->frame_type == KEY_FRAME ||
1026 cpi->refresh_alt_ref_frame ||
1027 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
1028 mbmi->segment_id = vp9_vaq_segment_id(energy);
1030 const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1031 : cm->last_frame_seg_map;
1032 mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
1035 rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
1036 vp9_init_plane_quantizers(cpi, x);
1039 // Save rdmult before it might be changed, so it can be restored later.
1040 orig_rdmult = x->rdmult;
1041 if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
1042 activity_masking(cpi, x);
1044 if (aq_mode == VARIANCE_AQ) {
1045 vp9_clear_system_state();
1046 x->rdmult = (int)round(x->rdmult * rdmult_ratio);
1047 } else if (aq_mode == COMPLEXITY_AQ) {
1048 const int mi_offset = mi_row * cm->mi_cols + mi_col;
1049 unsigned char complexity = cpi->complexity_map[mi_offset];
1050 const int is_edge = (mi_row <= 1) || (mi_row >= (cm->mi_rows - 2)) ||
1051 (mi_col <= 1) || (mi_col >= (cm->mi_cols - 2));
1052 if (!is_edge && (complexity > 128))
1053 x->rdmult += ((x->rdmult * (complexity - 128)) / 256);
1054 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1055 const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
1056 : cm->last_frame_seg_map;
1057 // If segment 1, use rdmult for that segment.
1058 if (vp9_get_segment_id(cm, map, bsize, mi_row, mi_col))
1059 x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
1062 // Find best coding mode & reconstruct the MB so it is available
1063 // as a predictor for MBs that follow in the SB
1064 if (frame_is_intra_only(cm)) {
1065 vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
1068 if (bsize >= BLOCK_8X8)
1069 vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
1070 totalrate, totaldist, bsize, ctx, best_rd);
1072 vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
1073 totaldist, bsize, ctx, best_rd);
1076 if (aq_mode == VARIANCE_AQ) {
1077 x->rdmult = orig_rdmult;
1078 if (*totalrate != INT_MAX) {
1079 vp9_clear_system_state();
1080 *totalrate = (int)round(*totalrate * rdmult_ratio);
1082 } else if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) ||
1083 (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)) {
1084 x->rdmult = orig_rdmult;
1088 static void update_stats(VP9_COMP *cpi) {
1089 VP9_COMMON *const cm = &cpi->common;
1090 const MACROBLOCK *const x = &cpi->mb;
1091 const MACROBLOCKD *const xd = &x->e_mbd;
1092 const MODE_INFO *const mi = xd->mi_8x8[0];
1093 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1095 if (!frame_is_intra_only(cm)) {
1096 const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
1098 if (!seg_ref_active) {
1099 FRAME_COUNTS *const counts = &cm->counts;
1100 const int inter_block = is_inter_block(mbmi);
1102 counts->intra_inter[vp9_get_intra_inter_context(xd)][inter_block]++;
1104 // If the segment reference feature is enabled we have only a single
1105 // reference frame allowed for the segment so exclude it from
1106 // the reference frame counts used to work out probabilities.
1108 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1110 if (cm->reference_mode == REFERENCE_MODE_SELECT)
1111 counts->comp_inter[vp9_get_reference_mode_context(cm, xd)]
1112 [has_second_ref(mbmi)]++;
1114 if (has_second_ref(mbmi)) {
1115 counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
1116 [ref0 == GOLDEN_FRAME]++;
1118 counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0]
1119 [ref0 != LAST_FRAME]++;
1120 if (ref0 != LAST_FRAME)
1121 counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1]
1122 [ref0 != GOLDEN_FRAME]++;
1129 static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) {
1132 return &x->sb64_partitioning;
1134 return &x->sb_partitioning[x->sb_index];
1136 return &x->mb_partitioning[x->sb_index][x->mb_index];
1138 return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index];
1145 static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
1146 ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1147 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1148 PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1150 MACROBLOCK *const x = &cpi->mb;
1151 MACROBLOCKD *const xd = &x->e_mbd;
1153 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1154 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1155 int mi_width = num_8x8_blocks_wide_lookup[bsize];
1156 int mi_height = num_8x8_blocks_high_lookup[bsize];
1157 for (p = 0; p < MAX_MB_PLANE; p++) {
1159 xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
1160 a + num_4x4_blocks_wide * p,
1161 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1162 xd->plane[p].subsampling_x);
1165 + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1166 l + num_4x4_blocks_high * p,
1167 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1168 xd->plane[p].subsampling_y);
1170 vpx_memcpy(xd->above_seg_context + mi_col, sa,
1171 sizeof(*xd->above_seg_context) * mi_width);
1172 vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl,
1173 sizeof(xd->left_seg_context[0]) * mi_height);
1175 static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
1176 ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
1177 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
1178 PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
1180 const MACROBLOCK *const x = &cpi->mb;
1181 const MACROBLOCKD *const xd = &x->e_mbd;
1183 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1184 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1185 int mi_width = num_8x8_blocks_wide_lookup[bsize];
1186 int mi_height = num_8x8_blocks_high_lookup[bsize];
1188 // buffer the above/left context information of the block in search.
1189 for (p = 0; p < MAX_MB_PLANE; ++p) {
1191 a + num_4x4_blocks_wide * p,
1192 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
1193 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
1194 xd->plane[p].subsampling_x);
1196 l + num_4x4_blocks_high * p,
1198 + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y),
1199 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
1200 xd->plane[p].subsampling_y);
1202 vpx_memcpy(sa, xd->above_seg_context + mi_col,
1203 sizeof(*xd->above_seg_context) * mi_width);
1204 vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK),
1205 sizeof(xd->left_seg_context[0]) * mi_height);
1208 static void encode_b(VP9_COMP *cpi, const TileInfo *const tile,
1209 TOKENEXTRA **tp, int mi_row, int mi_col,
1210 int output_enabled, BLOCK_SIZE bsize) {
1211 MACROBLOCK *const x = &cpi->mb;
1213 if (bsize < BLOCK_8X8) {
1214 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1215 // there is nothing to be done.
1216 if (x->ab_index > 0)
1219 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1220 update_state(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize,
1222 encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
1224 if (output_enabled) {
1227 (*tp)->token = EOSB_TOKEN;
1232 static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile,
1233 TOKENEXTRA **tp, int mi_row, int mi_col,
1234 int output_enabled, BLOCK_SIZE bsize) {
1235 VP9_COMMON *const cm = &cpi->common;
1236 MACROBLOCK *const x = &cpi->mb;
1237 MACROBLOCKD *const xd = &x->e_mbd;
1239 const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
1241 PARTITION_TYPE partition;
1244 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1247 if (bsize >= BLOCK_8X8) {
1248 ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1249 subsize = *get_sb_partitioning(x, bsize);
1252 subsize = BLOCK_4X4;
1255 partition = partition_lookup[bsl][subsize];
1257 switch (partition) {
1258 case PARTITION_NONE:
1259 if (output_enabled && bsize >= BLOCK_8X8)
1260 cm->counts.partition[ctx][PARTITION_NONE]++;
1261 encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1263 case PARTITION_VERT:
1265 cm->counts.partition[ctx][PARTITION_VERT]++;
1266 *get_sb_index(x, subsize) = 0;
1267 encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1268 if (mi_col + hbs < cm->mi_cols) {
1269 *get_sb_index(x, subsize) = 1;
1270 encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
1273 case PARTITION_HORZ:
1275 cm->counts.partition[ctx][PARTITION_HORZ]++;
1276 *get_sb_index(x, subsize) = 0;
1277 encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1278 if (mi_row + hbs < cm->mi_rows) {
1279 *get_sb_index(x, subsize) = 1;
1280 encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
1283 case PARTITION_SPLIT:
1284 subsize = get_subsize(bsize, PARTITION_SPLIT);
1286 cm->counts.partition[ctx][PARTITION_SPLIT]++;
1288 *get_sb_index(x, subsize) = 0;
1289 encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1290 *get_sb_index(x, subsize) = 1;
1291 encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize);
1292 *get_sb_index(x, subsize) = 2;
1293 encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize);
1294 *get_sb_index(x, subsize) = 3;
1295 encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1299 assert("Invalid partition type.");
1302 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1303 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1306 // Check to see if the given partition size is allowed for a specified number
1307 // of 8x8 block rows and columns remaining in the image.
1308 // If not then return the largest allowed partition size
1309 static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize,
1310 int rows_left, int cols_left,
1312 if (rows_left <= 0 || cols_left <= 0) {
1313 return MIN(bsize, BLOCK_8X8);
1315 for (; bsize > 0; bsize -= 3) {
1316 *bh = num_8x8_blocks_high_lookup[bsize];
1317 *bw = num_8x8_blocks_wide_lookup[bsize];
1318 if ((*bh <= rows_left) && (*bw <= cols_left)) {
1326 // This function attempts to set all mode info entries in a given SB64
1327 // to the same block partition size.
1328 // However, at the bottom and right borders of the image the requested size
1329 // may not be allowed in which case this code attempts to choose the largest
1330 // allowable partition.
1331 static void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
1332 MODE_INFO **mi_8x8, int mi_row, int mi_col,
1334 VP9_COMMON *const cm = &cpi->common;
1335 const int mis = cm->mode_info_stride;
1336 int row8x8_remaining = tile->mi_row_end - mi_row;
1337 int col8x8_remaining = tile->mi_col_end - mi_col;
1338 int block_row, block_col;
1339 MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col;
1340 int bh = num_8x8_blocks_high_lookup[bsize];
1341 int bw = num_8x8_blocks_wide_lookup[bsize];
1343 assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
1345 // Apply the requested partition size to the SB64 if it is all "in image"
1346 if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
1347 (row8x8_remaining >= MI_BLOCK_SIZE)) {
1348 for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1349 for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1350 int index = block_row * mis + block_col;
1351 mi_8x8[index] = mi_upper_left + index;
1352 mi_8x8[index]->mbmi.sb_type = bsize;
1356 // Else this is a partial SB64.
1357 for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
1358 for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
1359 int index = block_row * mis + block_col;
1360 // Find a partition size that fits
1361 bsize = find_partition_size(bsize,
1362 (row8x8_remaining - block_row),
1363 (col8x8_remaining - block_col), &bh, &bw);
1364 mi_8x8[index] = mi_upper_left + index;
1365 mi_8x8[index]->mbmi.sb_type = bsize;
1371 static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8,
1372 MODE_INFO **prev_mi_8x8) {
1373 const int mis = cm->mode_info_stride;
1374 int block_row, block_col;
1376 for (block_row = 0; block_row < 8; ++block_row) {
1377 for (block_col = 0; block_col < 8; ++block_col) {
1378 MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col];
1379 const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
1381 const ptrdiff_t offset = prev_mi - cm->prev_mi;
1382 mi_8x8[block_row * mis + block_col] = cm->mi + offset;
1383 mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type;
1389 static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) {
1390 const int mis = cm->mode_info_stride;
1391 int block_row, block_col;
1394 for (block_row = 0; block_row < 8; ++block_row) {
1395 for (block_col = 0; block_col < 8; ++block_col) {
1396 const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col];
1398 if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 ||
1399 abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8)
1408 static void update_state_rt(VP9_COMP *cpi, const PICK_MODE_CONTEXT *ctx,
1409 int mi_row, int mi_col, int bsize) {
1410 VP9_COMMON *const cm = &cpi->common;
1411 MACROBLOCK *const x = &cpi->mb;
1412 MACROBLOCKD *const xd = &x->e_mbd;
1413 MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
1414 const struct segmentation *const seg = &cm->seg;
1416 // TODO(jingning) We might need PICK_MODE_CONTEXT to buffer coding modes
1417 // associated with variable block sizes. Otherwise, remove this ctx
1418 // from argument list.
1421 *(xd->mi_8x8[0]) = ctx->mic;
1423 // Check for reseting segment_id and update cyclic map.
1424 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && seg->enabled) {
1425 vp9_cyclic_refresh_update_segment(cpi, &xd->mi_8x8[0]->mbmi,
1426 mi_row, mi_col, bsize, 1);
1427 vp9_init_plane_quantizers(cpi, x);
1430 if (is_inter_block(mbmi)) {
1431 vp9_update_mv_count(cm, xd);
1433 if (cm->interp_filter == SWITCHABLE) {
1434 const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
1435 ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter];
1440 static void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile,
1441 TOKENEXTRA **tp, int mi_row, int mi_col,
1442 int output_enabled, BLOCK_SIZE bsize) {
1443 MACROBLOCK *const x = &cpi->mb;
1445 if (bsize < BLOCK_8X8) {
1446 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1447 // there is nothing to be done.
1448 if (x->ab_index > 0)
1451 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1452 update_state_rt(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize);
1454 encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
1457 (*tp)->token = EOSB_TOKEN;
1461 static void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile,
1462 TOKENEXTRA **tp, int mi_row, int mi_col,
1463 int output_enabled, BLOCK_SIZE bsize) {
1464 VP9_COMMON *const cm = &cpi->common;
1465 MACROBLOCK *const x = &cpi->mb;
1466 MACROBLOCKD *const xd = &x->e_mbd;
1468 const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
1470 PARTITION_TYPE partition;
1473 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1476 if (bsize >= BLOCK_8X8) {
1477 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1478 const int idx_str = xd->mode_info_stride * mi_row + mi_col;
1479 MODE_INFO ** mi_8x8 = cm->mi_grid_visible + idx_str;
1480 ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1481 subsize = mi_8x8[0]->mbmi.sb_type;
1484 subsize = BLOCK_4X4;
1487 partition = partition_lookup[bsl][subsize];
1489 switch (partition) {
1490 case PARTITION_NONE:
1491 if (output_enabled && bsize >= BLOCK_8X8)
1492 cm->counts.partition[ctx][PARTITION_NONE]++;
1493 encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1495 case PARTITION_VERT:
1497 cm->counts.partition[ctx][PARTITION_VERT]++;
1498 *get_sb_index(x, subsize) = 0;
1499 encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1500 if (mi_col + hbs < cm->mi_cols) {
1501 *get_sb_index(x, subsize) = 1;
1502 encode_b_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
1506 case PARTITION_HORZ:
1508 cm->counts.partition[ctx][PARTITION_HORZ]++;
1509 *get_sb_index(x, subsize) = 0;
1510 encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1511 if (mi_row + hbs < cm->mi_rows) {
1512 *get_sb_index(x, subsize) = 1;
1513 encode_b_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
1517 case PARTITION_SPLIT:
1518 subsize = get_subsize(bsize, PARTITION_SPLIT);
1520 cm->counts.partition[ctx][PARTITION_SPLIT]++;
1522 *get_sb_index(x, subsize) = 0;
1523 encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize);
1524 *get_sb_index(x, subsize) = 1;
1525 encode_sb_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled,
1527 *get_sb_index(x, subsize) = 2;
1528 encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled,
1530 *get_sb_index(x, subsize) = 3;
1531 encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled,
1535 assert("Invalid partition type.");
1538 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
1539 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
1542 static void rd_use_partition(VP9_COMP *cpi,
1543 const TileInfo *const tile,
1545 TOKENEXTRA **tp, int mi_row, int mi_col,
1546 BLOCK_SIZE bsize, int *rate, int64_t *dist,
1548 VP9_COMMON *const cm = &cpi->common;
1549 MACROBLOCK *const x = &cpi->mb;
1550 MACROBLOCKD *const xd = &x->e_mbd;
1551 const int mis = cm->mode_info_stride;
1552 const int bsl = b_width_log2(bsize);
1553 const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2;
1554 const int bss = (1 << bsl) / 4;
1556 PARTITION_TYPE partition = PARTITION_NONE;
1558 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1559 PARTITION_CONTEXT sl[8], sa[8];
1560 int last_part_rate = INT_MAX;
1561 int64_t last_part_dist = INT64_MAX;
1562 int64_t last_part_rd = INT64_MAX;
1563 int none_rate = INT_MAX;
1564 int64_t none_dist = INT64_MAX;
1565 int64_t none_rd = INT64_MAX;
1566 int chosen_rate = INT_MAX;
1567 int64_t chosen_dist = INT64_MAX;
1568 int64_t chosen_rd = INT64_MAX;
1569 BLOCK_SIZE sub_subsize = BLOCK_4X4;
1570 int splits_below = 0;
1571 BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type;
1572 int do_partition_search = 1;
1574 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
1577 assert(num_4x4_blocks_wide_lookup[bsize] ==
1578 num_4x4_blocks_high_lookup[bsize]);
1580 partition = partition_lookup[bsl][bs_type];
1581 subsize = get_subsize(bsize, partition);
1583 if (bsize < BLOCK_8X8) {
1584 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
1585 // there is nothing to be done.
1586 if (x->ab_index != 0) {
1592 *(get_sb_partitioning(x, bsize)) = subsize;
1594 save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1596 set_offsets(cpi, tile, mi_row, mi_col, bsize);
1597 if (bsize == BLOCK_16X16) {
1598 x->mb_energy = vp9_block_energy(cpi, x, bsize);
1601 if (!x->in_active_map) {
1602 do_partition_search = 0;
1603 if (mi_row + (mi_step >> 1) < cm->mi_rows &&
1604 mi_col + (mi_step >> 1) < cm->mi_cols) {
1605 *(get_sb_partitioning(x, bsize)) = bsize;
1606 bs_type = mi_8x8[0]->mbmi.sb_type = bsize;
1608 partition = PARTITION_NONE;
1611 if (do_partition_search &&
1612 cpi->sf.partition_search_type == SEARCH_PARTITION &&
1613 cpi->sf.adjust_partitioning_from_last_frame) {
1614 // Check if any of the sub blocks are further split.
1615 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
1616 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
1618 for (i = 0; i < 4; i++) {
1619 int jj = i >> 1, ii = i & 0x01;
1620 MODE_INFO * this_mi = mi_8x8[jj * bss * mis + ii * bss];
1621 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
1627 // If partition is not none try none unless each of the 4 splits are split
1629 if (partition != PARTITION_NONE && !splits_below &&
1630 mi_row + (mi_step >> 1) < cm->mi_rows &&
1631 mi_col + (mi_step >> 1) < cm->mi_cols) {
1632 *(get_sb_partitioning(x, bsize)) = bsize;
1633 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize,
1634 get_block_context(x, bsize), INT64_MAX);
1636 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1638 if (none_rate < INT_MAX) {
1639 none_rate += x->partition_cost[pl][PARTITION_NONE];
1640 none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist);
1643 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1644 mi_8x8[0]->mbmi.sb_type = bs_type;
1645 *(get_sb_partitioning(x, bsize)) = subsize;
1649 switch (partition) {
1650 case PARTITION_NONE:
1651 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1652 &last_part_dist, bsize,
1653 get_block_context(x, bsize), INT64_MAX);
1655 case PARTITION_HORZ:
1656 *get_sb_index(x, subsize) = 0;
1657 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1658 &last_part_dist, subsize,
1659 get_block_context(x, subsize), INT64_MAX);
1660 if (last_part_rate != INT_MAX &&
1661 bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
1664 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
1666 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
1667 *get_sb_index(x, subsize) = 1;
1668 rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt,
1669 subsize, get_block_context(x, subsize), INT64_MAX);
1670 if (rt == INT_MAX || dt == INT64_MAX) {
1671 last_part_rate = INT_MAX;
1672 last_part_dist = INT64_MAX;
1676 last_part_rate += rt;
1677 last_part_dist += dt;
1680 case PARTITION_VERT:
1681 *get_sb_index(x, subsize) = 0;
1682 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
1683 &last_part_dist, subsize,
1684 get_block_context(x, subsize), INT64_MAX);
1685 if (last_part_rate != INT_MAX &&
1686 bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
1689 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
1691 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
1692 *get_sb_index(x, subsize) = 1;
1693 rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt,
1694 subsize, get_block_context(x, subsize), INT64_MAX);
1695 if (rt == INT_MAX || dt == INT64_MAX) {
1696 last_part_rate = INT_MAX;
1697 last_part_dist = INT64_MAX;
1700 last_part_rate += rt;
1701 last_part_dist += dt;
1704 case PARTITION_SPLIT:
1708 for (i = 0; i < 4; i++) {
1709 int x_idx = (i & 1) * (mi_step >> 1);
1710 int y_idx = (i >> 1) * (mi_step >> 1);
1711 int jj = i >> 1, ii = i & 0x01;
1715 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1718 *get_sb_index(x, subsize) = i;
1720 rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
1721 mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt,
1723 if (rt == INT_MAX || dt == INT64_MAX) {
1724 last_part_rate = INT_MAX;
1725 last_part_dist = INT64_MAX;
1728 last_part_rate += rt;
1729 last_part_dist += dt;
1736 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1737 if (last_part_rate < INT_MAX) {
1738 last_part_rate += x->partition_cost[pl][partition];
1739 last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist);
1742 if (do_partition_search
1743 && cpi->sf.adjust_partitioning_from_last_frame
1744 && cpi->sf.partition_search_type == SEARCH_PARTITION
1745 && partition != PARTITION_SPLIT && bsize > BLOCK_8X8
1746 && (mi_row + mi_step < cm->mi_rows ||
1747 mi_row + (mi_step >> 1) == cm->mi_rows)
1748 && (mi_col + mi_step < cm->mi_cols ||
1749 mi_col + (mi_step >> 1) == cm->mi_cols)) {
1750 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
1753 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1756 for (i = 0; i < 4; i++) {
1757 int x_idx = (i & 1) * (mi_step >> 1);
1758 int y_idx = (i >> 1) * (mi_step >> 1);
1761 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1762 PARTITION_CONTEXT sl[8], sa[8];
1764 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
1767 *get_sb_index(x, split_subsize) = i;
1768 *get_sb_partitioning(x, bsize) = split_subsize;
1769 *get_sb_partitioning(x, split_subsize) = split_subsize;
1771 save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1773 rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt,
1774 split_subsize, get_block_context(x, split_subsize),
1777 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1779 if (rt == INT_MAX || dt == INT64_MAX) {
1780 chosen_rate = INT_MAX;
1781 chosen_dist = INT64_MAX;
1789 encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0,
1792 pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
1794 chosen_rate += x->partition_cost[pl][PARTITION_NONE];
1796 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
1797 if (chosen_rate < INT_MAX) {
1798 chosen_rate += x->partition_cost[pl][PARTITION_SPLIT];
1799 chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist);
1803 // If last_part is better set the partitioning to that...
1804 if (last_part_rd < chosen_rd) {
1805 mi_8x8[0]->mbmi.sb_type = bsize;
1806 if (bsize >= BLOCK_8X8)
1807 *(get_sb_partitioning(x, bsize)) = subsize;
1808 chosen_rate = last_part_rate;
1809 chosen_dist = last_part_dist;
1810 chosen_rd = last_part_rd;
1812 // If none was better set the partitioning to that...
1813 if (none_rd < chosen_rd) {
1814 if (bsize >= BLOCK_8X8)
1815 *(get_sb_partitioning(x, bsize)) = bsize;
1816 chosen_rate = none_rate;
1817 chosen_dist = none_dist;
1820 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
1822 // We must have chosen a partitioning and encoding or we'll fail later on.
1823 // No other opportunities for success.
1824 if ( bsize == BLOCK_64X64)
1825 assert(chosen_rate < INT_MAX && chosen_dist < INT64_MAX);
1828 int output_enabled = (bsize == BLOCK_64X64);
1830 // Check the projected output rate for this SB against it's target
1831 // and and if necessary apply a Q delta using segmentation to get
1832 // closer to the target.
1833 if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
1834 vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
1835 output_enabled, chosen_rate);
1838 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
1839 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
1840 chosen_rate, chosen_dist);
1842 encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
1845 *rate = chosen_rate;
1846 *dist = chosen_dist;
1849 static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
1850 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
1851 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
1852 BLOCK_8X8, BLOCK_8X8, BLOCK_8X8,
1853 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
1857 static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
1858 BLOCK_8X8, BLOCK_16X16, BLOCK_16X16,
1859 BLOCK_16X16, BLOCK_32X32, BLOCK_32X32,
1860 BLOCK_32X32, BLOCK_64X64, BLOCK_64X64,
1861 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64,
1865 // Look at all the mode_info entries for blocks that are part of this
1866 // partition and find the min and max values for sb_type.
1867 // At the moment this is designed to work on a 64x64 SB but could be
1868 // adjusted to use a size parameter.
1870 // The min and max are assumed to have been initialized prior to calling this
1871 // function so repeat calls can accumulate a min and max of more than one sb64.
1872 static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8,
1873 BLOCK_SIZE * min_block_size,
1874 BLOCK_SIZE * max_block_size ) {
1875 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1876 int sb_width_in_blocks = MI_BLOCK_SIZE;
1877 int sb_height_in_blocks = MI_BLOCK_SIZE;
1881 // Check the sb_type for each block that belongs to this region.
1882 for (i = 0; i < sb_height_in_blocks; ++i) {
1883 for (j = 0; j < sb_width_in_blocks; ++j) {
1884 MODE_INFO * mi = mi_8x8[index+j];
1885 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0;
1886 *min_block_size = MIN(*min_block_size, sb_type);
1887 *max_block_size = MAX(*max_block_size, sb_type);
1889 index += xd->mode_info_stride;
1893 // Next square block size less or equal than current block size.
1894 static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
1895 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
1896 BLOCK_8X8, BLOCK_8X8, BLOCK_8X8,
1897 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
1898 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32,
1902 // Look at neighboring blocks and set a min and max partition size based on
1904 static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
1905 int mi_row, int mi_col,
1906 BLOCK_SIZE *min_block_size,
1907 BLOCK_SIZE *max_block_size) {
1908 VP9_COMMON *const cm = &cpi->common;
1909 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1910 MODE_INFO **mi_8x8 = xd->mi_8x8;
1911 const int left_in_image = xd->left_available && mi_8x8[-1];
1912 const int above_in_image = xd->up_available &&
1913 mi_8x8[-xd->mode_info_stride];
1914 MODE_INFO **above_sb64_mi_8x8;
1915 MODE_INFO **left_sb64_mi_8x8;
1917 int row8x8_remaining = tile->mi_row_end - mi_row;
1918 int col8x8_remaining = tile->mi_col_end - mi_col;
1920 BLOCK_SIZE min_size = BLOCK_4X4;
1921 BLOCK_SIZE max_size = BLOCK_64X64;
1922 // Trap case where we do not have a prediction.
1923 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
1924 // Default "min to max" and "max to min"
1925 min_size = BLOCK_64X64;
1926 max_size = BLOCK_4X4;
1928 // NOTE: each call to get_sb_partition_size_range() uses the previous
1929 // passed in values for min and max as a starting point.
1930 // Find the min and max partition used in previous frame at this location
1931 if (cm->frame_type != KEY_FRAME) {
1932 MODE_INFO **const prev_mi =
1933 &cm->prev_mi_grid_visible[mi_row * xd->mode_info_stride + mi_col];
1934 get_sb_partition_size_range(cpi, prev_mi, &min_size, &max_size);
1936 // Find the min and max partition sizes used in the left SB64
1937 if (left_in_image) {
1938 left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE];
1939 get_sb_partition_size_range(cpi, left_sb64_mi_8x8,
1940 &min_size, &max_size);
1942 // Find the min and max partition sizes used in the above SB64.
1943 if (above_in_image) {
1944 above_sb64_mi_8x8 = &mi_8x8[-xd->mode_info_stride * MI_BLOCK_SIZE];
1945 get_sb_partition_size_range(cpi, above_sb64_mi_8x8,
1946 &min_size, &max_size);
1948 // adjust observed min and max
1949 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
1950 min_size = min_partition_size[min_size];
1951 max_size = max_partition_size[max_size];
1955 // Check border cases where max and min from neighbors may not be legal.
1956 max_size = find_partition_size(max_size,
1957 row8x8_remaining, col8x8_remaining,
1959 min_size = MIN(min_size, max_size);
1961 // When use_square_partition_only is true, make sure at least one square
1962 // partition is allowed by selecting the next smaller square size as
1964 if (cpi->sf.use_square_partition_only &&
1965 next_square_size[max_size] < min_size) {
1966 min_size = next_square_size[max_size];
1968 *min_block_size = min_size;
1969 *max_block_size = max_size;
1972 static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
1973 vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
1976 static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
1977 vpx_memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
1980 // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
1981 // unlikely to be selected depending on previous rate-distortion optimization
1982 // results, for encoding speed-up.
1983 static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
1984 TOKENEXTRA **tp, int mi_row,
1985 int mi_col, BLOCK_SIZE bsize, int *rate,
1986 int64_t *dist, int do_recon, int64_t best_rd) {
1987 VP9_COMMON *const cm = &cpi->common;
1988 MACROBLOCK *const x = &cpi->mb;
1989 MACROBLOCKD *const xd = &x->e_mbd;
1990 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
1991 ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
1992 PARTITION_CONTEXT sl[8], sa[8];
1993 TOKENEXTRA *tp_orig = *tp;
1994 PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
1997 int this_rate, sum_rate = 0, best_rate = INT_MAX;
1998 int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
2000 int do_split = bsize >= BLOCK_8X8;
2002 // Override skipping rectangular partition operations for edge blocks
2003 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
2004 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
2005 const int xss = x->e_mbd.plane[1].subsampling_x;
2006 const int yss = x->e_mbd.plane[1].subsampling_y;
2008 int partition_none_allowed = !force_horz_split && !force_vert_split;
2009 int partition_horz_allowed = !force_vert_split && yss <= xss &&
2011 int partition_vert_allowed = !force_horz_split && xss <= yss &&
2015 if (bsize < BLOCK_8X8) {
2016 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
2017 // there is nothing to be done.
2018 if (x->ab_index != 0) {
2024 assert(num_8x8_blocks_wide_lookup[bsize] ==
2025 num_8x8_blocks_high_lookup[bsize]);
2027 if (bsize == BLOCK_16X16) {
2028 set_offsets(cpi, tile, mi_row, mi_col, bsize);
2029 x->mb_energy = vp9_block_energy(cpi, x, bsize);
2032 // Determine partition types in search according to the speed features.
2033 // The threshold set here has to be of square block size.
2034 if (cpi->sf.auto_min_max_partition_size) {
2035 partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
2036 bsize >= cpi->sf.min_partition_size);
2037 partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2038 bsize > cpi->sf.min_partition_size) ||
2040 partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2041 bsize > cpi->sf.min_partition_size) ||
2043 do_split &= bsize > cpi->sf.min_partition_size;
2045 if (cpi->sf.use_square_partition_only) {
2046 partition_horz_allowed &= force_horz_split;
2047 partition_vert_allowed &= force_vert_split;
2050 save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2052 if (cpi->sf.disable_split_var_thresh && partition_none_allowed) {
2053 unsigned int source_variancey;
2054 vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col);
2055 source_variancey = get_sby_perpixel_variance(cpi, x, bsize);
2056 if (source_variancey < cpi->sf.disable_split_var_thresh) {
2058 if (source_variancey < cpi->sf.disable_split_var_thresh / 2)
2063 if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
2066 if (partition_none_allowed) {
2067 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize,
2069 if (this_rate != INT_MAX) {
2070 if (bsize >= BLOCK_8X8) {
2071 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2072 this_rate += x->partition_cost[pl][PARTITION_NONE];
2074 sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
2075 if (sum_rd < best_rd) {
2076 int64_t stop_thresh = 4096;
2077 int64_t stop_thresh_rd;
2079 best_rate = this_rate;
2080 best_dist = this_dist;
2082 if (bsize >= BLOCK_8X8)
2083 *(get_sb_partitioning(x, bsize)) = bsize;
2085 // Adjust threshold according to partition size.
2086 stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
2087 b_height_log2_lookup[bsize]);
2089 stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
2090 // If obtained distortion is very small, choose current partition
2091 // and stop splitting.
2092 if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
2098 if (!x->in_active_map) {
2102 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2105 // store estimated motion vector
2106 if (cpi->sf.adaptive_motion_search)
2107 store_pred_mv(x, ctx);
2111 // TODO(jingning): use the motion vectors given by the above search as
2112 // the starting point of motion search in the following partition type check.
2114 subsize = get_subsize(bsize, PARTITION_SPLIT);
2115 for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
2116 const int x_idx = (i & 1) * mi_step;
2117 const int y_idx = (i >> 1) * mi_step;
2119 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2122 *get_sb_index(x, subsize) = i;
2123 if (cpi->sf.adaptive_motion_search)
2124 load_pred_mv(x, ctx);
2125 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2126 partition_none_allowed)
2127 get_block_context(x, subsize)->pred_interp_filter =
2128 ctx->mic.mbmi.interp_filter;
2129 rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize,
2130 &this_rate, &this_dist, i != 3, best_rd - sum_rd);
2132 if (this_rate == INT_MAX) {
2135 sum_rate += this_rate;
2136 sum_dist += this_dist;
2137 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2140 if (sum_rd < best_rd && i == 4) {
2141 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2142 sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
2143 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2144 if (sum_rd < best_rd) {
2145 best_rate = sum_rate;
2146 best_dist = sum_dist;
2148 *(get_sb_partitioning(x, bsize)) = subsize;
2151 // skip rectangular partition test when larger block size
2152 // gives better rd cost
2153 if (cpi->sf.less_rectangular_check)
2154 do_rect &= !partition_none_allowed;
2156 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2160 if (partition_horz_allowed && do_rect) {
2161 subsize = get_subsize(bsize, PARTITION_HORZ);
2162 *get_sb_index(x, subsize) = 0;
2163 if (cpi->sf.adaptive_motion_search)
2164 load_pred_mv(x, ctx);
2165 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2166 partition_none_allowed)
2167 get_block_context(x, subsize)->pred_interp_filter =
2168 ctx->mic.mbmi.interp_filter;
2169 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
2170 get_block_context(x, subsize), best_rd);
2171 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2173 if (sum_rd < best_rd && mi_row + mi_step < cm->mi_rows) {
2174 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
2176 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
2178 *get_sb_index(x, subsize) = 1;
2179 if (cpi->sf.adaptive_motion_search)
2180 load_pred_mv(x, ctx);
2181 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2182 partition_none_allowed)
2183 get_block_context(x, subsize)->pred_interp_filter =
2184 ctx->mic.mbmi.interp_filter;
2185 rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rate,
2186 &this_dist, subsize, get_block_context(x, subsize),
2188 if (this_rate == INT_MAX) {
2191 sum_rate += this_rate;
2192 sum_dist += this_dist;
2193 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2196 if (sum_rd < best_rd) {
2197 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2198 sum_rate += x->partition_cost[pl][PARTITION_HORZ];
2199 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2200 if (sum_rd < best_rd) {
2202 best_rate = sum_rate;
2203 best_dist = sum_dist;
2204 *(get_sb_partitioning(x, bsize)) = subsize;
2207 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2211 if (partition_vert_allowed && do_rect) {
2212 subsize = get_subsize(bsize, PARTITION_VERT);
2214 *get_sb_index(x, subsize) = 0;
2215 if (cpi->sf.adaptive_motion_search)
2216 load_pred_mv(x, ctx);
2217 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2218 partition_none_allowed)
2219 get_block_context(x, subsize)->pred_interp_filter =
2220 ctx->mic.mbmi.interp_filter;
2221 rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
2222 get_block_context(x, subsize), best_rd);
2223 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2224 if (sum_rd < best_rd && mi_col + mi_step < cm->mi_cols) {
2225 update_state(cpi, get_block_context(x, subsize), mi_row, mi_col,
2227 encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
2229 *get_sb_index(x, subsize) = 1;
2230 if (cpi->sf.adaptive_motion_search)
2231 load_pred_mv(x, ctx);
2232 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
2233 partition_none_allowed)
2234 get_block_context(x, subsize)->pred_interp_filter =
2235 ctx->mic.mbmi.interp_filter;
2236 rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rate,
2237 &this_dist, subsize, get_block_context(x, subsize),
2239 if (this_rate == INT_MAX) {
2242 sum_rate += this_rate;
2243 sum_dist += this_dist;
2244 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2247 if (sum_rd < best_rd) {
2248 pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2249 sum_rate += x->partition_cost[pl][PARTITION_VERT];
2250 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2251 if (sum_rd < best_rd) {
2252 best_rate = sum_rate;
2253 best_dist = sum_dist;
2255 *(get_sb_partitioning(x, bsize)) = subsize;
2258 restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
2261 // TODO(jbb): This code added so that we avoid static analysis
2262 // warning related to the fact that best_rd isn't used after this
2263 // point. This code should be refactored so that the duplicate
2264 // checks occur in some sub function and thus are used...
2269 if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
2270 int output_enabled = (bsize == BLOCK_64X64);
2272 // Check the projected output rate for this SB against it's target
2273 // and and if necessary apply a Q delta using segmentation to get
2274 // closer to the target.
2275 if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
2276 vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
2280 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2281 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
2282 best_rate, best_dist);
2284 encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
2286 if (bsize == BLOCK_64X64) {
2287 assert(tp_orig < *tp);
2288 assert(best_rate < INT_MAX);
2289 assert(best_dist < INT64_MAX);
2291 assert(tp_orig == *tp);
2295 static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
2296 int mi_row, TOKENEXTRA **tp) {
2297 VP9_COMMON *const cm = &cpi->common;
2298 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
2301 // Initialize the left context for the new SB row
2302 vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
2303 vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
2305 // Code each SB in the row
2306 for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
2307 mi_col += MI_BLOCK_SIZE) {
2312 MACROBLOCK *x = &cpi->mb;
2314 if (cpi->sf.adaptive_pred_interp_filter) {
2315 for (i = BLOCK_4X4; i < BLOCK_8X8; ++i) {
2316 const int num_4x4_w = num_4x4_blocks_wide_lookup[i];
2317 const int num_4x4_h = num_4x4_blocks_high_lookup[i];
2318 const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h);
2319 for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index)
2320 for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index)
2321 for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index)
2322 get_block_context(x, i)->pred_interp_filter = SWITCHABLE;
2326 vp9_zero(cpi->mb.pred_mv);
2328 if ((cpi->sf.partition_search_type == SEARCH_PARTITION &&
2329 cpi->sf.use_lastframe_partitioning) ||
2330 cpi->sf.partition_search_type == FIXED_PARTITION ||
2331 cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
2332 const int idx_str = cm->mode_info_stride * mi_row + mi_col;
2333 MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
2334 MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
2335 cpi->mb.source_variance = UINT_MAX;
2336 if (cpi->sf.partition_search_type == FIXED_PARTITION) {
2337 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2338 set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
2339 cpi->sf.always_this_block_size);
2340 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2341 &dummy_rate, &dummy_dist, 1);
2342 } else if (cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) {
2344 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2345 bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
2346 set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
2347 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2348 &dummy_rate, &dummy_dist, 1);
2349 } else if (cpi->sf.partition_search_type == VAR_BASED_PARTITION) {
2350 choose_partitioning(cpi, tile, mi_row, mi_col);
2351 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2352 &dummy_rate, &dummy_dist, 1);
2354 if ((cm->current_video_frame
2355 % cpi->sf.last_partitioning_redo_frequency) == 0
2357 || cm->show_frame == 0
2358 || cm->frame_type == KEY_FRAME
2359 || cpi->rc.is_src_frame_alt_ref
2360 || ((cpi->sf.use_lastframe_partitioning ==
2361 LAST_FRAME_PARTITION_LOW_MOTION) &&
2362 sb_has_motion(cm, prev_mi_8x8))) {
2363 // If required set upper and lower partition size limits
2364 if (cpi->sf.auto_min_max_partition_size) {
2365 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2366 rd_auto_partition_range(cpi, tile, mi_row, mi_col,
2367 &cpi->sf.min_partition_size,
2368 &cpi->sf.max_partition_size);
2370 rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
2371 &dummy_rate, &dummy_dist, 1, INT64_MAX);
2373 copy_partitioning(cm, mi_8x8, prev_mi_8x8);
2374 rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
2375 &dummy_rate, &dummy_dist, 1);
2379 // If required set upper and lower partition size limits
2380 if (cpi->sf.auto_min_max_partition_size) {
2381 set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
2382 rd_auto_partition_range(cpi, tile, mi_row, mi_col,
2383 &cpi->sf.min_partition_size,
2384 &cpi->sf.max_partition_size);
2386 rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
2387 &dummy_rate, &dummy_dist, 1, INT64_MAX);
2392 static void init_encode_frame_mb_context(VP9_COMP *cpi) {
2393 MACROBLOCK *const x = &cpi->mb;
2394 VP9_COMMON *const cm = &cpi->common;
2395 MACROBLOCKD *const xd = &x->e_mbd;
2396 const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
2398 x->act_zbin_adj = 0;
2401 xd->mode_info_stride = cm->mode_info_stride;
2403 // Copy data over into macro block data structures.
2404 vp9_setup_src_planes(x, cpi->Source, 0, 0);
2406 // TODO(jkoleszar): are these initializations required?
2407 vp9_setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0,
2409 vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0);
2411 vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
2413 xd->mi_8x8[0]->mbmi.mode = DC_PRED;
2414 xd->mi_8x8[0]->mbmi.uv_mode = DC_PRED;
2416 vp9_zero(cm->counts.y_mode);
2417 vp9_zero(cm->counts.uv_mode);
2418 vp9_zero(cm->counts.inter_mode);
2419 vp9_zero(cm->counts.partition);
2420 vp9_zero(cm->counts.intra_inter);
2421 vp9_zero(cm->counts.comp_inter);
2422 vp9_zero(cm->counts.single_ref);
2423 vp9_zero(cm->counts.comp_ref);
2424 vp9_zero(cm->counts.tx);
2425 vp9_zero(cm->counts.skip);
2427 // Note: this memset assumes above_context[0], [1] and [2]
2428 // are allocated as part of the same buffer.
2429 vpx_memset(xd->above_context[0], 0,
2430 sizeof(*xd->above_context[0]) *
2431 2 * aligned_mi_cols * MAX_MB_PLANE);
2432 vpx_memset(xd->above_seg_context, 0,
2433 sizeof(*xd->above_seg_context) * aligned_mi_cols);
2436 static void switch_lossless_mode(VP9_COMP *cpi, int lossless) {
2438 // printf("Switching to lossless\n");
2439 cpi->mb.fwd_txm4x4 = vp9_fwht4x4;
2440 cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add;
2441 cpi->mb.optimize = 0;
2442 cpi->common.lf.filter_level = 0;
2443 cpi->zbin_mode_boost_enabled = 0;
2444 cpi->common.tx_mode = ONLY_4X4;
2446 // printf("Not lossless\n");
2447 cpi->mb.fwd_txm4x4 = vp9_fdct4x4;
2448 cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add;
2452 static int check_dual_ref_flags(VP9_COMP *cpi) {
2453 const int ref_flags = cpi->ref_frame_flags;
2455 if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
2458 return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG)
2459 + !!(ref_flags & VP9_ALT_FLAG)) >= 2;
2463 static int get_skip_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs) {
2466 for (y = 0; y < ymbs; y++) {
2467 for (x = 0; x < xmbs; x++) {
2468 if (!mi_8x8[y * mis + x]->mbmi.skip)
2476 static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) {
2478 const int mis = cm->mode_info_stride;
2479 MODE_INFO **mi_ptr = cm->mi_grid_visible;
2481 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
2482 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
2483 if (mi_ptr[mi_col]->mbmi.tx_size > txfm_max)
2484 mi_ptr[mi_col]->mbmi.tx_size = txfm_max;
2489 static MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) {
2490 if (frame_is_intra_only(&cpi->common))
2492 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
2493 return ALTREF_FRAME;
2494 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
2497 return GOLDEN_FRAME;
2500 static TX_MODE select_tx_mode(const VP9_COMP *cpi) {
2501 if (cpi->oxcf.lossless) {
2503 } else if (cpi->common.current_video_frame == 0) {
2504 return TX_MODE_SELECT;
2506 if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
2508 } else if (cpi->sf.tx_size_search_method == USE_FULL_RD) {
2509 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
2510 return cpi->rd_tx_select_threshes[frame_type][ALLOW_32X32] >
2511 cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ?
2512 ALLOW_32X32 : TX_MODE_SELECT;
2514 unsigned int total = 0;
2516 for (i = 0; i < TX_SIZES; ++i)
2517 total += cpi->tx_stepdown_count[i];
2520 const double fraction = (double)cpi->tx_stepdown_count[0] / total;
2521 return fraction > 0.90 ? ALLOW_32X32 : TX_MODE_SELECT;
2523 return cpi->common.tx_mode;
2529 // Start RTC Exploration
2532 ZERO_PLUS_PREDICTED = 1,
2534 NEW_PLUS_NON_INTRA = 3,
2536 INTRA_PLUS_NON_INTRA = 5,
2539 } motion_vector_context;
2541 static void set_mode_info(MB_MODE_INFO *mbmi, BLOCK_SIZE bsize,
2542 MB_PREDICTION_MODE mode) {
2544 mbmi->uv_mode = mode;
2545 mbmi->mv[0].as_int = 0;
2546 mbmi->mv[1].as_int = 0;
2547 mbmi->ref_frame[0] = INTRA_FRAME;
2548 mbmi->ref_frame[1] = NONE;
2549 mbmi->tx_size = max_txsize_lookup[bsize];
2551 mbmi->sb_type = bsize;
2552 mbmi->segment_id = 0;
2555 static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
2556 int mi_row, int mi_col,
2557 int *rate, int64_t *dist,
2559 VP9_COMMON *const cm = &cpi->common;
2560 MACROBLOCK *const x = &cpi->mb;
2561 MACROBLOCKD *const xd = &x->e_mbd;
2562 set_offsets(cpi, tile, mi_row, mi_col, bsize);
2563 xd->mi_8x8[0]->mbmi.sb_type = bsize;
2565 if (!frame_is_intra_only(cm)) {
2566 vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col,
2569 MB_PREDICTION_MODE intramode = DC_PRED;
2570 set_mode_info(&xd->mi_8x8[0]->mbmi, bsize, intramode);
2572 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2575 static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
2576 int mi_row, int mi_col,
2577 BLOCK_SIZE bsize, BLOCK_SIZE subsize) {
2578 MACROBLOCKD *xd = &x->e_mbd;
2579 int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
2580 PARTITION_TYPE partition = partition_lookup[bsl][subsize];
2582 assert(bsize >= BLOCK_8X8);
2584 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
2587 switch (partition) {
2588 case PARTITION_NONE:
2589 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2590 *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic;
2591 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2593 case PARTITION_VERT:
2594 *get_sb_index(x, subsize) = 0;
2595 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2596 *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic;
2597 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2599 if (mi_col + hbs < cm->mi_cols) {
2600 *get_sb_index(x, subsize) = 1;
2601 set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs);
2602 *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic;
2603 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize);
2606 case PARTITION_HORZ:
2607 *get_sb_index(x, subsize) = 0;
2608 set_modeinfo_offsets(cm, xd, mi_row, mi_col);
2609 *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic;
2610 duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
2611 if (mi_row + hbs < cm->mi_rows) {
2612 *get_sb_index(x, subsize) = 1;
2613 set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col);
2614 *(xd->mi_8x8[0]) = (get_block_context(x, subsize))->mic;
2615 duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize);
2618 case PARTITION_SPLIT:
2619 *get_sb_index(x, subsize) = 0;
2620 fill_mode_info_sb(cm, x, mi_row, mi_col, subsize,
2621 *(get_sb_partitioning(x, subsize)));
2622 *get_sb_index(x, subsize) = 1;
2623 fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize,
2624 *(get_sb_partitioning(x, subsize)));
2625 *get_sb_index(x, subsize) = 2;
2626 fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize,
2627 *(get_sb_partitioning(x, subsize)));
2628 *get_sb_index(x, subsize) = 3;
2629 fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize,
2630 *(get_sb_partitioning(x, subsize)));
2637 static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
2638 TOKENEXTRA **tp, int mi_row,
2639 int mi_col, BLOCK_SIZE bsize, int *rate,
2640 int64_t *dist, int do_recon, int64_t best_rd) {
2641 VP9_COMMON *const cm = &cpi->common;
2642 MACROBLOCK *const x = &cpi->mb;
2643 MACROBLOCKD *const xd = &x->e_mbd;
2644 const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
2645 TOKENEXTRA *tp_orig = *tp;
2646 PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
2649 int this_rate, sum_rate = 0, best_rate = INT_MAX;
2650 int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
2652 int do_split = bsize >= BLOCK_8X8;
2654 // Override skipping rectangular partition operations for edge blocks
2655 const int force_horz_split = (mi_row + ms >= cm->mi_rows);
2656 const int force_vert_split = (mi_col + ms >= cm->mi_cols);
2657 const int xss = x->e_mbd.plane[1].subsampling_x;
2658 const int yss = x->e_mbd.plane[1].subsampling_y;
2660 int partition_none_allowed = !force_horz_split && !force_vert_split;
2661 int partition_horz_allowed = !force_vert_split && yss <= xss &&
2663 int partition_vert_allowed = !force_horz_split && xss <= yss &&
2667 if (bsize < BLOCK_8X8) {
2668 // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
2669 // there is nothing to be done.
2670 if (x->ab_index != 0) {
2677 assert(num_8x8_blocks_wide_lookup[bsize] ==
2678 num_8x8_blocks_high_lookup[bsize]);
2680 // Determine partition types in search according to the speed features.
2681 // The threshold set here has to be of square block size.
2682 if (cpi->sf.auto_min_max_partition_size) {
2683 partition_none_allowed &= (bsize <= cpi->sf.max_partition_size &&
2684 bsize >= cpi->sf.min_partition_size);
2685 partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2686 bsize > cpi->sf.min_partition_size) ||
2688 partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size &&
2689 bsize > cpi->sf.min_partition_size) ||
2691 do_split &= bsize > cpi->sf.min_partition_size;
2693 if (cpi->sf.use_square_partition_only) {
2694 partition_horz_allowed &= force_horz_split;
2695 partition_vert_allowed &= force_vert_split;
2698 if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed))
2702 if (partition_none_allowed) {
2703 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2704 &this_rate, &this_dist, bsize);
2705 ctx->mic.mbmi = xd->mi_8x8[0]->mbmi;
2707 if (this_rate != INT_MAX) {
2708 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2709 this_rate += x->partition_cost[pl][PARTITION_NONE];
2710 sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
2711 if (sum_rd < best_rd) {
2712 int64_t stop_thresh = 4096;
2713 int64_t stop_thresh_rd;
2715 best_rate = this_rate;
2716 best_dist = this_dist;
2718 if (bsize >= BLOCK_8X8)
2719 *(get_sb_partitioning(x, bsize)) = bsize;
2721 // Adjust threshold according to partition size.
2722 stop_thresh >>= 8 - (b_width_log2_lookup[bsize] +
2723 b_height_log2_lookup[bsize]);
2725 stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh);
2726 // If obtained distortion is very small, choose current partition
2727 // and stop splitting.
2728 if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) {
2734 if (!x->in_active_map) {
2740 // store estimated motion vector
2741 store_pred_mv(x, ctx);
2746 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2747 sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
2748 subsize = get_subsize(bsize, PARTITION_SPLIT);
2749 for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
2750 const int x_idx = (i & 1) * ms;
2751 const int y_idx = (i >> 1) * ms;
2753 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
2756 *get_sb_index(x, subsize) = i;
2757 load_pred_mv(x, ctx);
2759 nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
2760 subsize, &this_rate, &this_dist, 0,
2763 if (this_rate == INT_MAX) {
2766 sum_rate += this_rate;
2767 sum_dist += this_dist;
2768 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2772 if (sum_rd < best_rd) {
2773 best_rate = sum_rate;
2774 best_dist = sum_dist;
2776 *(get_sb_partitioning(x, bsize)) = subsize;
2778 // skip rectangular partition test when larger block size
2779 // gives better rd cost
2780 if (cpi->sf.less_rectangular_check)
2781 do_rect &= !partition_none_allowed;
2786 if (partition_horz_allowed && do_rect) {
2787 subsize = get_subsize(bsize, PARTITION_HORZ);
2788 *get_sb_index(x, subsize) = 0;
2789 if (cpi->sf.adaptive_motion_search)
2790 load_pred_mv(x, ctx);
2792 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2793 &this_rate, &this_dist, subsize);
2795 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2797 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2799 if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
2800 *get_sb_index(x, subsize) = 1;
2802 load_pred_mv(x, ctx);
2804 nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col,
2805 &this_rate, &this_dist, subsize);
2807 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2809 if (this_rate == INT_MAX) {
2812 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2813 this_rate += x->partition_cost[pl][PARTITION_HORZ];
2814 sum_rate += this_rate;
2815 sum_dist += this_dist;
2816 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2819 if (sum_rd < best_rd) {
2821 best_rate = sum_rate;
2822 best_dist = sum_dist;
2823 *(get_sb_partitioning(x, bsize)) = subsize;
2828 if (partition_vert_allowed && do_rect) {
2829 subsize = get_subsize(bsize, PARTITION_VERT);
2831 *get_sb_index(x, subsize) = 0;
2832 if (cpi->sf.adaptive_motion_search)
2833 load_pred_mv(x, ctx);
2835 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
2836 &this_rate, &this_dist, subsize);
2837 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2838 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2839 if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
2840 *get_sb_index(x, subsize) = 1;
2842 load_pred_mv(x, ctx);
2844 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms,
2845 &this_rate, &this_dist, subsize);
2847 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2849 if (this_rate == INT_MAX) {
2852 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2853 this_rate += x->partition_cost[pl][PARTITION_VERT];
2854 sum_rate += this_rate;
2855 sum_dist += this_dist;
2856 sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
2859 if (sum_rd < best_rd) {
2860 best_rate = sum_rate;
2861 best_dist = sum_dist;
2863 *(get_sb_partitioning(x, bsize)) = subsize;
2870 if (best_rate == INT_MAX)
2873 // update mode info array
2874 fill_mode_info_sb(cm, x, mi_row, mi_col, bsize,
2875 *(get_sb_partitioning(x, bsize)));
2877 if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
2878 int output_enabled = (bsize == BLOCK_64X64);
2880 // Check the projected output rate for this SB against it's target
2881 // and and if necessary apply a Q delta using segmentation to get
2882 // closer to the target.
2883 if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
2884 vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
2888 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2889 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
2890 best_rate, best_dist);
2892 encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
2895 if (bsize == BLOCK_64X64) {
2896 assert(tp_orig < *tp);
2897 assert(best_rate < INT_MAX);
2898 assert(best_dist < INT64_MAX);
2900 assert(tp_orig == *tp);
2904 static void nonrd_use_partition(VP9_COMP *cpi,
2905 const TileInfo *const tile,
2908 int mi_row, int mi_col,
2909 BLOCK_SIZE bsize, int output_enabled,
2910 int *totrate, int64_t *totdist) {
2911 VP9_COMMON *const cm = &cpi->common;
2912 MACROBLOCK *const x = &cpi->mb;
2913 MACROBLOCKD *const xd = &x->e_mbd;
2914 const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4;
2915 const int mis = cm->mode_info_stride;
2916 PARTITION_TYPE partition;
2919 int64_t dist = INT64_MAX;
2921 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
2924 if (bsize >= BLOCK_8X8) {
2925 subsize = mi_8x8[0]->mbmi.sb_type;
2927 subsize = BLOCK_4X4;
2930 partition = partition_lookup[bsl][subsize];
2932 switch (partition) {
2933 case PARTITION_NONE:
2934 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
2935 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2937 case PARTITION_VERT:
2938 *get_sb_index(x, subsize) = 0;
2939 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
2940 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2941 if (mi_col + hbs < cm->mi_cols) {
2942 *get_sb_index(x, subsize) = 1;
2943 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
2944 &rate, &dist, subsize);
2945 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2946 if (rate != INT_MAX && dist != INT64_MAX &&
2947 *totrate != INT_MAX && *totdist != INT64_MAX) {
2953 case PARTITION_HORZ:
2954 *get_sb_index(x, subsize) = 0;
2955 nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize);
2956 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2957 if (mi_row + hbs < cm->mi_rows) {
2958 *get_sb_index(x, subsize) = 1;
2959 nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
2960 &rate, &dist, subsize);
2961 (get_block_context(x, subsize))->mic.mbmi = xd->mi_8x8[0]->mbmi;
2962 if (rate != INT_MAX && dist != INT64_MAX &&
2963 *totrate != INT_MAX && *totdist != INT64_MAX) {
2969 case PARTITION_SPLIT:
2970 subsize = get_subsize(bsize, PARTITION_SPLIT);
2971 *get_sb_index(x, subsize) = 0;
2972 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
2973 subsize, output_enabled, totrate, totdist);
2974 *get_sb_index(x, subsize) = 1;
2975 nonrd_use_partition(cpi, tile, mi_8x8 + hbs, tp,
2976 mi_row, mi_col + hbs, subsize, output_enabled,
2978 if (rate != INT_MAX && dist != INT64_MAX &&
2979 *totrate != INT_MAX && *totdist != INT64_MAX) {
2983 *get_sb_index(x, subsize) = 2;
2984 nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis, tp,
2985 mi_row + hbs, mi_col, subsize, output_enabled,
2987 if (rate != INT_MAX && dist != INT64_MAX &&
2988 *totrate != INT_MAX && *totdist != INT64_MAX) {
2992 *get_sb_index(x, subsize) = 3;
2993 nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis + hbs, tp,
2994 mi_row + hbs, mi_col + hbs, subsize, output_enabled,
2996 if (rate != INT_MAX && dist != INT64_MAX &&
2997 *totrate != INT_MAX && *totdist != INT64_MAX) {
3003 assert("Invalid partition type.");
3006 if (bsize == BLOCK_64X64 && output_enabled) {
3007 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
3008 vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
3009 *totrate, *totdist);
3010 encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize);
3014 static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
3015 int mi_row, TOKENEXTRA **tp) {
3016 VP9_COMMON *cm = &cpi->common;
3017 MACROBLOCKD *xd = &cpi->mb.e_mbd;
3020 // Initialize the left context for the new SB row
3021 vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
3022 vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
3024 // Code each SB in the row
3025 for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
3026 mi_col += MI_BLOCK_SIZE) {
3028 int64_t dummy_dist = 0;
3029 const int idx_str = cm->mode_info_stride * mi_row + mi_col;
3030 MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
3031 MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
3033 BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ?
3034 cpi->sf.always_this_block_size :
3035 get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
3037 cpi->mb.source_variance = UINT_MAX;
3038 vp9_zero(cpi->mb.pred_mv);
3040 // Set the partition type of the 64X64 block
3041 switch (cpi->sf.partition_search_type) {
3042 case VAR_BASED_PARTITION:
3043 choose_partitioning(cpi, tile, mi_row, mi_col);
3044 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3045 1, &dummy_rate, &dummy_dist);
3047 case VAR_BASED_FIXED_PARTITION:
3048 case FIXED_PARTITION:
3049 set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
3050 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
3051 1, &dummy_rate, &dummy_dist);
3053 case REFERENCE_PARTITION:
3054 if (cpi->sf.partition_check || sb_has_motion(cm, prev_mi_8x8)) {
3055 nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
3056 &dummy_rate, &dummy_dist, 1, INT64_MAX);
3058 copy_partitioning(cm, mi_8x8, prev_mi_8x8);
3059 nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col,
3060 BLOCK_64X64, 1, &dummy_rate, &dummy_dist);
3068 // end RTC play code
3070 static void encode_frame_internal(VP9_COMP *cpi) {
3072 MACROBLOCK *const x = &cpi->mb;
3073 VP9_COMMON *const cm = &cpi->common;
3074 MACROBLOCKD *const xd = &x->e_mbd;
3076 // fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n",
3077 // cpi->common.current_video_frame, cpi->common.show_frame,
3080 vp9_zero(cm->counts.switchable_interp);
3081 vp9_zero(cpi->tx_stepdown_count);
3083 xd->mi_8x8 = cm->mi_grid_visible;
3084 // required for vp9_frame_init_quantizer
3085 xd->mi_8x8[0] = cm->mi;
3087 vp9_zero(cm->counts.mv);
3088 vp9_zero(cpi->coef_counts);
3089 vp9_zero(cm->counts.eob_branch);
3091 // Set frame level transform size use case
3092 cm->tx_mode = select_tx_mode(cpi);
3094 cpi->mb.e_mbd.lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0
3095 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
3096 switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless);
3098 vp9_frame_init_quantizer(cpi);
3100 vp9_initialize_rd_consts(cpi);
3101 vp9_initialize_me_consts(cpi, cm->base_qindex);
3103 if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3104 // Initialize encode frame context.
3105 init_encode_frame_mb_context(cpi);
3107 // Build a frame level activity map
3108 build_activity_map(cpi);
3111 // Re-initialize encode frame context.
3112 init_encode_frame_mb_context(cpi);
3114 vp9_zero(cpi->rd_comp_pred_diff);
3115 vp9_zero(cpi->rd_filter_diff);
3116 vp9_zero(cpi->rd_tx_select_diff);
3117 vp9_zero(cpi->rd_tx_select_threshes);
3121 if (cpi->sf.use_nonrd_pick_mode) {
3122 // Initialize internal buffer pointers for rtc coding, where non-RD
3123 // mode decision is used and hence no buffer pointer swap needed.
3125 struct macroblock_plane *const p = x->plane;
3126 struct macroblockd_plane *const pd = xd->plane;
3127 PICK_MODE_CONTEXT *ctx = &cpi->mb.sb64_context;
3129 for (i = 0; i < MAX_MB_PLANE; ++i) {
3130 p[i].coeff = ctx->coeff_pbuf[i][0];
3131 p[i].qcoeff = ctx->qcoeff_pbuf[i][0];
3132 pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0];
3133 p[i].eobs = ctx->eobs_pbuf[i][0];
3135 vp9_zero(x->zcoeff_blk);
3139 struct vpx_usec_timer emr_timer;
3140 vpx_usec_timer_start(&emr_timer);
3143 // Take tiles into account and give start/end MB
3144 int tile_col, tile_row;
3145 TOKENEXTRA *tp = cpi->tok;
3146 const int tile_cols = 1 << cm->log2_tile_cols;
3147 const int tile_rows = 1 << cm->log2_tile_rows;
3149 for (tile_row = 0; tile_row < tile_rows; tile_row++) {
3150 for (tile_col = 0; tile_col < tile_cols; tile_col++) {
3152 TOKENEXTRA *tp_old = tp;
3154 // For each row of SBs in the frame
3155 vp9_tile_init(&tile, cm, tile_row, tile_col);
3156 for (mi_row = tile.mi_row_start;
3157 mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) {
3158 if (cpi->sf.use_nonrd_pick_mode && cm->frame_type != KEY_FRAME)
3159 encode_nonrd_sb_row(cpi, &tile, mi_row, &tp);
3161 encode_rd_sb_row(cpi, &tile, mi_row, &tp);
3163 cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old);
3164 assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols));
3169 vpx_usec_timer_mark(&emr_timer);
3170 cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer);
3173 if (cpi->sf.skip_encode_sb) {
3175 unsigned int intra_count = 0, inter_count = 0;
3176 for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) {
3177 intra_count += cm->counts.intra_inter[j][0];
3178 inter_count += cm->counts.intra_inter[j][1];
3180 cpi->sf.skip_encode_frame = (intra_count << 2) < inter_count &&
3181 cm->frame_type != KEY_FRAME &&
3184 cpi->sf.skip_encode_frame = 0;
3188 // Keep record of the total distortion this time around for future use
3189 cpi->last_frame_distortion = cpi->frame_distortion;
3193 void vp9_encode_frame(VP9_COMP *cpi) {
3194 VP9_COMMON *const cm = &cpi->common;
3196 // In the longer term the encoder should be generalized to match the
3197 // decoder such that we allow compound where one of the 3 buffers has a
3198 // different sign bias and that buffer is then the fixed ref. However, this
3199 // requires further work in the rd loop. For now the only supported encoder
3200 // side behavior is where the ALT ref buffer has opposite sign bias to
3202 if (!frame_is_intra_only(cm)) {
3203 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3204 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
3205 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
3206 cm->ref_frame_sign_bias[LAST_FRAME])) {
3207 cm->allow_comp_inter_inter = 0;
3209 cm->allow_comp_inter_inter = 1;
3210 cm->comp_fixed_ref = ALTREF_FRAME;
3211 cm->comp_var_ref[0] = LAST_FRAME;
3212 cm->comp_var_ref[1] = GOLDEN_FRAME;
3216 if (cpi->sf.frame_parameter_update) {
3218 REFERENCE_MODE reference_mode;
3220 * This code does a single RD pass over the whole frame assuming
3221 * either compound, single or hybrid prediction as per whatever has
3222 * worked best for that type of frame in the past.
3223 * It also predicts whether another coding mode would have worked
3224 * better that this coding mode. If that is the case, it remembers
3225 * that for subsequent frames.
3226 * It does the same analysis for transform size selection also.
3228 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
3229 const int64_t *mode_thresh = cpi->rd_prediction_type_threshes[frame_type];
3230 const int64_t *filter_thresh = cpi->rd_filter_threshes[frame_type];
3232 /* prediction (compound, single or hybrid) mode selection */
3233 if (frame_type == 3 || !cm->allow_comp_inter_inter)
3234 reference_mode = SINGLE_REFERENCE;
3235 else if (mode_thresh[COMPOUND_REFERENCE] > mode_thresh[SINGLE_REFERENCE] &&
3236 mode_thresh[COMPOUND_REFERENCE] >
3237 mode_thresh[REFERENCE_MODE_SELECT] &&
3238 check_dual_ref_flags(cpi) &&
3239 cpi->static_mb_pct == 100)
3240 reference_mode = COMPOUND_REFERENCE;
3241 else if (mode_thresh[SINGLE_REFERENCE] > mode_thresh[REFERENCE_MODE_SELECT])
3242 reference_mode = SINGLE_REFERENCE;
3244 reference_mode = REFERENCE_MODE_SELECT;
3246 if (cm->interp_filter == SWITCHABLE) {
3247 if (frame_type != ALTREF_FRAME &&
3248 filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP] &&
3249 filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP_SHARP] &&
3250 filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[SWITCHABLE - 1]) {
3251 cm->interp_filter = EIGHTTAP_SMOOTH;
3252 } else if (filter_thresh[EIGHTTAP_SHARP] > filter_thresh[EIGHTTAP] &&
3253 filter_thresh[EIGHTTAP_SHARP] > filter_thresh[SWITCHABLE - 1]) {
3254 cm->interp_filter = EIGHTTAP_SHARP;
3255 } else if (filter_thresh[EIGHTTAP] > filter_thresh[SWITCHABLE - 1]) {
3256 cm->interp_filter = EIGHTTAP;
3260 cpi->mb.e_mbd.lossless = cpi->oxcf.lossless;
3261 cm->reference_mode = reference_mode;
3263 encode_frame_internal(cpi);
3265 for (i = 0; i < REFERENCE_MODES; ++i) {
3266 const int diff = (int) (cpi->rd_comp_pred_diff[i] / cm->MBs);
3267 cpi->rd_prediction_type_threshes[frame_type][i] += diff;
3268 cpi->rd_prediction_type_threshes[frame_type][i] >>= 1;
3271 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
3272 const int64_t diff = cpi->rd_filter_diff[i] / cm->MBs;
3273 cpi->rd_filter_threshes[frame_type][i] =
3274 (cpi->rd_filter_threshes[frame_type][i] + diff) / 2;
3277 for (i = 0; i < TX_MODES; ++i) {
3278 int64_t pd = cpi->rd_tx_select_diff[i];
3280 if (i == TX_MODE_SELECT)
3281 pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZES - 1), 0);
3282 diff = (int) (pd / cm->MBs);
3283 cpi->rd_tx_select_threshes[frame_type][i] += diff;
3284 cpi->rd_tx_select_threshes[frame_type][i] /= 2;
3287 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
3288 int single_count_zero = 0;
3289 int comp_count_zero = 0;
3291 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
3292 single_count_zero += cm->counts.comp_inter[i][0];
3293 comp_count_zero += cm->counts.comp_inter[i][1];
3296 if (comp_count_zero == 0) {
3297 cm->reference_mode = SINGLE_REFERENCE;
3298 vp9_zero(cm->counts.comp_inter);
3299 } else if (single_count_zero == 0) {
3300 cm->reference_mode = COMPOUND_REFERENCE;
3301 vp9_zero(cm->counts.comp_inter);
3305 if (cm->tx_mode == TX_MODE_SELECT) {
3307 int count8x8_lp = 0, count8x8_8x8p = 0;
3308 int count16x16_16x16p = 0, count16x16_lp = 0;
3311 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
3312 count4x4 += cm->counts.tx.p32x32[i][TX_4X4];
3313 count4x4 += cm->counts.tx.p16x16[i][TX_4X4];
3314 count4x4 += cm->counts.tx.p8x8[i][TX_4X4];
3316 count8x8_lp += cm->counts.tx.p32x32[i][TX_8X8];
3317 count8x8_lp += cm->counts.tx.p16x16[i][TX_8X8];
3318 count8x8_8x8p += cm->counts.tx.p8x8[i][TX_8X8];
3320 count16x16_16x16p += cm->counts.tx.p16x16[i][TX_16X16];
3321 count16x16_lp += cm->counts.tx.p32x32[i][TX_16X16];
3322 count32x32 += cm->counts.tx.p32x32[i][TX_32X32];
3325 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
3327 cm->tx_mode = ALLOW_8X8;
3328 reset_skip_txfm_size(cm, TX_8X8);
3329 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
3330 count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) {
3331 cm->tx_mode = ONLY_4X4;
3332 reset_skip_txfm_size(cm, TX_4X4);
3333 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
3334 cm->tx_mode = ALLOW_32X32;
3335 } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) {
3336 cm->tx_mode = ALLOW_16X16;
3337 reset_skip_txfm_size(cm, TX_16X16);
3341 cpi->mb.e_mbd.lossless = cpi->oxcf.lossless;
3342 cm->reference_mode = SINGLE_REFERENCE;
3343 // Force the usage of the BILINEAR interp_filter.
3344 cm->interp_filter = BILINEAR;
3345 encode_frame_internal(cpi);
3349 static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
3350 const MB_PREDICTION_MODE y_mode = mi->mbmi.mode;
3351 const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
3352 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
3354 if (bsize < BLOCK_8X8) {
3356 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
3357 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
3358 for (idy = 0; idy < 2; idy += num_4x4_h)
3359 for (idx = 0; idx < 2; idx += num_4x4_w)
3360 ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode];
3362 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
3365 ++counts->uv_mode[y_mode][uv_mode];
3368 // Experimental stub function to create a per MB zbin adjustment based on
3369 // some previously calculated measure of MB activity.
3370 static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) {
3372 x->act_zbin_adj = *(x->mb_activity_ptr);
3374 // Apply the masking to the RD multiplier.
3375 const int64_t act = *(x->mb_activity_ptr);
3376 const int64_t a = act + 4 * cpi->activity_avg;
3377 const int64_t b = 4 * act + cpi->activity_avg;
3379 if (act > cpi->activity_avg)
3380 x->act_zbin_adj = (int) (((int64_t) b + (a >> 1)) / a) - 1;
3382 x->act_zbin_adj = 1 - (int) (((int64_t) a + (b >> 1)) / b);
3386 static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) {
3388 if (is_inter_block(mbmi)) {
3389 if (mbmi->mode == ZEROMV) {
3390 return mbmi->ref_frame[0] != LAST_FRAME ? GF_ZEROMV_ZBIN_BOOST
3391 : LF_ZEROMV_ZBIN_BOOST;
3393 return mbmi->sb_type < BLOCK_8X8 ? SPLIT_MV_ZBIN_BOOST
3397 return INTRA_ZBIN_BOOST;
3404 static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
3405 int mi_row, int mi_col, BLOCK_SIZE bsize) {
3406 VP9_COMMON *const cm = &cpi->common;
3407 MACROBLOCK *const x = &cpi->mb;
3408 MACROBLOCKD *const xd = &x->e_mbd;
3409 MODE_INFO **mi_8x8 = xd->mi_8x8;
3410 MODE_INFO *mi = mi_8x8[0];
3411 MB_MODE_INFO *mbmi = &mi->mbmi;
3412 PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize);
3413 unsigned int segment_id = mbmi->segment_id;
3414 const int mis = cm->mode_info_stride;
3415 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
3416 const int mi_height = num_8x8_blocks_high_lookup[bsize];
3418 x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 &&
3419 cpi->oxcf.aq_mode != COMPLEXITY_AQ &&
3420 cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ &&
3421 cpi->sf.allow_skip_recode;
3423 x->skip_optimize = ctx->is_coded;
3425 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
3426 x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame &&
3427 x->q_index < QIDX_SKIP_THRESH);
3432 if (cm->frame_type == KEY_FRAME) {
3433 if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3434 adjust_act_zbin(cpi, x);
3435 vp9_update_zbin_extra(cpi, x);
3438 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3439 xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
3441 if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
3442 // Adjust the zbin based on this MB rate.
3443 adjust_act_zbin(cpi, x);
3446 // Experimental code. Special case for gf and arf zeromv modes.
3447 // Increase zbin size to suppress noise
3448 cpi->zbin_mode_boost = get_zbin_mode_boost(mbmi,
3449 cpi->zbin_mode_boost_enabled);
3450 vp9_update_zbin_extra(cpi, x);
3453 if (!is_inter_block(mbmi)) {
3456 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
3457 vp9_encode_intra_block_plane(x, MAX(bsize, BLOCK_8X8), plane);
3459 sum_intra_stats(&cm->counts, mi);
3460 vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8));
3463 const int is_compound = has_second_ref(mbmi);
3464 for (ref = 0; ref < 1 + is_compound; ++ref) {
3465 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
3466 mbmi->ref_frame[ref]);
3467 vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
3468 &xd->block_refs[ref]->sf);
3470 vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
3474 vp9_encode_sb(x, MAX(bsize, BLOCK_8X8));
3475 vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8));
3479 cm->counts.skip[vp9_get_skip_context(xd)][1]++;
3480 reset_skip_context(xd, MAX(bsize, BLOCK_8X8));
3484 if (output_enabled) {
3485 if (cm->tx_mode == TX_MODE_SELECT &&
3486 mbmi->sb_type >= BLOCK_8X8 &&
3487 !(is_inter_block(mbmi) &&
3489 vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)))) {
3490 ++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
3491 &cm->counts.tx)[mbmi->tx_size];
3495 // The new intra coding scheme requires no change of transform size
3496 if (is_inter_block(&mi->mbmi)) {
3497 tx_size = MIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
3498 max_txsize_lookup[bsize]);
3500 tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
3503 for (y = 0; y < mi_height; y++)
3504 for (x = 0; x < mi_width; x++)
3505 if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
3506 mi_8x8[mis * y + x]->mbmi.tx_size = tx_size;