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