vp9_blockd.h revision 91037db265ecdd914a26e056cf69207b4f50924e
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 12#ifndef VP9_COMMON_VP9_BLOCKD_H_ 13#define VP9_COMMON_VP9_BLOCKD_H_ 14 15#include "./vpx_config.h" 16 17#include "vpx_ports/mem.h" 18#include "vpx_scale/yv12config.h" 19 20#include "vp9/common/vp9_common.h" 21#include "vp9/common/vp9_common_data.h" 22#include "vp9/common/vp9_convolve.h" 23#include "vp9/common/vp9_enums.h" 24#include "vp9/common/vp9_mv.h" 25#include "vp9/common/vp9_seg_common.h" 26#include "vp9/common/vp9_treecoder.h" 27 28#define BLOCK_SIZE_GROUPS 4 29 30#define PREDICTION_PROBS 3 31 32#define MBSKIP_CONTEXTS 3 33 34/* Segment Feature Masks */ 35#define MAX_MV_REF_CANDIDATES 2 36 37#define INTRA_INTER_CONTEXTS 4 38#define COMP_INTER_CONTEXTS 5 39#define REF_CONTEXTS 5 40 41typedef enum { 42 PLANE_TYPE_Y_WITH_DC, 43 PLANE_TYPE_UV, 44} PLANE_TYPE; 45 46typedef char ENTROPY_CONTEXT; 47 48typedef char PARTITION_CONTEXT; 49 50static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a, 51 ENTROPY_CONTEXT b) { 52 return (a != 0) + (b != 0); 53} 54 55typedef enum { 56 KEY_FRAME = 0, 57 INTER_FRAME = 1, 58 NUM_FRAME_TYPES, 59} FRAME_TYPE; 60 61typedef enum { 62 EIGHTTAP_SMOOTH, 63 EIGHTTAP, 64 EIGHTTAP_SHARP, 65 BILINEAR, 66 SWITCHABLE /* should be the last one */ 67} INTERPOLATIONFILTERTYPE; 68 69typedef enum { 70 DC_PRED, // Average of above and left pixels 71 V_PRED, // Vertical 72 H_PRED, // Horizontal 73 D45_PRED, // Directional 45 deg = round(arctan(1/1) * 180/pi) 74 D135_PRED, // Directional 135 deg = 180 - 45 75 D117_PRED, // Directional 117 deg = 180 - 63 76 D153_PRED, // Directional 153 deg = 180 - 27 77 D27_PRED, // Directional 27 deg = round(arctan(1/2) * 180/pi) 78 D63_PRED, // Directional 63 deg = round(arctan(2/1) * 180/pi) 79 TM_PRED, // True-motion 80 NEARESTMV, 81 NEARMV, 82 ZEROMV, 83 NEWMV, 84 MB_MODE_COUNT 85} MB_PREDICTION_MODE; 86 87static INLINE int is_intra_mode(MB_PREDICTION_MODE mode) { 88 return mode <= TM_PRED; 89} 90 91static INLINE int is_inter_mode(MB_PREDICTION_MODE mode) { 92 return mode >= NEARESTMV && mode <= NEWMV; 93} 94 95#define VP9_INTRA_MODES (TM_PRED + 1) 96 97#define VP9_INTER_MODES (1 + NEWMV - NEARESTMV) 98 99static INLINE int inter_mode_offset(MB_PREDICTION_MODE mode) { 100 return (mode - NEARESTMV); 101} 102 103/* For keyframes, intra block modes are predicted by the (already decoded) 104 modes for the Y blocks to the left and above us; for interframes, there 105 is a single probability table. */ 106 107union b_mode_info { 108 MB_PREDICTION_MODE as_mode; 109 int_mv as_mv[2]; // first, second inter predictor motion vectors 110}; 111 112typedef enum { 113 NONE = -1, 114 INTRA_FRAME = 0, 115 LAST_FRAME = 1, 116 GOLDEN_FRAME = 2, 117 ALTREF_FRAME = 3, 118 MAX_REF_FRAMES = 4 119} MV_REFERENCE_FRAME; 120 121static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) { 122 return b_width_log2_lookup[sb_type]; 123} 124static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) { 125 return b_height_log2_lookup[sb_type]; 126} 127 128static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) { 129 return mi_width_log2_lookup[sb_type]; 130} 131 132static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) { 133 return mi_height_log2_lookup[sb_type]; 134} 135 136typedef struct { 137 MB_PREDICTION_MODE mode, uv_mode; 138 MV_REFERENCE_FRAME ref_frame[2]; 139 TX_SIZE txfm_size; 140 int_mv mv[2]; // for each reference frame used 141 int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; 142 int_mv best_mv, best_second_mv; 143 144 uint8_t mb_mode_context[MAX_REF_FRAMES]; 145 146 unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ 147 unsigned char segment_id; // Segment id for current frame 148 149 // Flags used for prediction status of various bistream signals 150 unsigned char seg_id_predicted; 151 152 // Indicates if the mb is part of the image (1) vs border (0) 153 // This can be useful in determining whether the MB provides 154 // a valid predictor 155 unsigned char mb_in_image; 156 157 INTERPOLATIONFILTERTYPE interp_filter; 158 159 BLOCK_SIZE_TYPE sb_type; 160} MB_MODE_INFO; 161 162typedef struct { 163 MB_MODE_INFO mbmi; 164 union b_mode_info bmi[4]; 165} MODE_INFO; 166 167enum mv_precision { 168 MV_PRECISION_Q3, 169 MV_PRECISION_Q4 170}; 171 172#define VP9_REF_SCALE_SHIFT 14 173#define VP9_REF_NO_SCALE (1 << VP9_REF_SCALE_SHIFT) 174 175struct scale_factors { 176 int x_scale_fp; // horizontal fixed point scale factor 177 int y_scale_fp; // vertical fixed point scale factor 178 int x_offset_q4; 179 int x_step_q4; 180 int y_offset_q4; 181 int y_step_q4; 182 183 int (*scale_value_x)(int val, const struct scale_factors *scale); 184 int (*scale_value_y)(int val, const struct scale_factors *scale); 185 void (*set_scaled_offsets)(struct scale_factors *scale, int row, int col); 186 MV32 (*scale_mv_q3_to_q4)(const MV *mv, const struct scale_factors *scale); 187 MV32 (*scale_mv_q4)(const MV *mv, const struct scale_factors *scale); 188 189 convolve_fn_t predict[2][2][2]; // horiz, vert, avg 190}; 191 192#if CONFIG_ALPHA 193enum { MAX_MB_PLANE = 4 }; 194#else 195enum { MAX_MB_PLANE = 3 }; 196#endif 197 198struct buf_2d { 199 uint8_t *buf; 200 int stride; 201}; 202 203struct macroblockd_plane { 204 DECLARE_ALIGNED(16, int16_t, qcoeff[64 * 64]); 205 DECLARE_ALIGNED(16, int16_t, dqcoeff[64 * 64]); 206 DECLARE_ALIGNED(16, uint16_t, eobs[256]); 207 PLANE_TYPE plane_type; 208 int subsampling_x; 209 int subsampling_y; 210 struct buf_2d dst; 211 struct buf_2d pre[2]; 212 int16_t *dequant; 213 ENTROPY_CONTEXT *above_context; 214 ENTROPY_CONTEXT *left_context; 215}; 216 217#define BLOCK_OFFSET(x, i, n) ((x) + (i) * (n)) 218 219#define MAX_REF_LF_DELTAS 4 220#define MAX_MODE_LF_DELTAS 2 221 222struct loopfilter { 223 int filter_level; 224 225 int sharpness_level; 226 int last_sharpness_level; 227 228 uint8_t mode_ref_delta_enabled; 229 uint8_t mode_ref_delta_update; 230 231 // 0 = Intra, Last, GF, ARF 232 signed char ref_deltas[MAX_REF_LF_DELTAS]; 233 signed char last_ref_deltas[MAX_REF_LF_DELTAS]; 234 235 // 0 = ZERO_MV, MV 236 signed char mode_deltas[MAX_MODE_LF_DELTAS]; 237 signed char last_mode_deltas[MAX_MODE_LF_DELTAS]; 238}; 239 240typedef struct macroblockd { 241 struct macroblockd_plane plane[MAX_MB_PLANE]; 242 243 struct scale_factors scale_factor[2]; 244 245 MODE_INFO *prev_mode_info_context; 246 MODE_INFO *mode_info_context; 247 int mode_info_stride; 248 249 int up_available; 250 int left_available; 251 int right_available; 252 253 struct segmentation seg; 254 struct loopfilter lf; 255 256 // partition contexts 257 PARTITION_CONTEXT *above_seg_context; 258 PARTITION_CONTEXT *left_seg_context; 259 260 /* Distance of MB away from frame edges */ 261 int mb_to_left_edge; 262 int mb_to_right_edge; 263 int mb_to_top_edge; 264 int mb_to_bottom_edge; 265 266 int lossless; 267 /* Inverse transform function pointers. */ 268 void (*inv_txm4x4_1_add)(int16_t *input, uint8_t *dest, int stride); 269 void (*inv_txm4x4_add)(int16_t *input, uint8_t *dest, int stride); 270 void (*itxm_add)(int16_t *input, uint8_t *dest, int stride, int eob); 271 272 struct subpix_fn_table subpix; 273 274 int allow_high_precision_mv; 275 276 int corrupted; 277 278 unsigned char sb_index; // index of 32x32 block inside the 64x64 block 279 unsigned char mb_index; // index of 16x16 block inside the 32x32 block 280 unsigned char b_index; // index of 8x8 block inside the 16x16 block 281 unsigned char ab_index; // index of 4x4 block inside the 8x8 block 282 283 int q_index; 284 285} MACROBLOCKD; 286 287static INLINE unsigned char *get_sb_index(MACROBLOCKD *xd, BLOCK_SIZE_TYPE subsize) { 288 switch (subsize) { 289 case BLOCK_SIZE_SB64X64: 290 case BLOCK_SIZE_SB64X32: 291 case BLOCK_SIZE_SB32X64: 292 case BLOCK_SIZE_SB32X32: 293 return &xd->sb_index; 294 case BLOCK_SIZE_SB32X16: 295 case BLOCK_SIZE_SB16X32: 296 case BLOCK_SIZE_MB16X16: 297 return &xd->mb_index; 298 case BLOCK_SIZE_SB16X8: 299 case BLOCK_SIZE_SB8X16: 300 case BLOCK_SIZE_SB8X8: 301 return &xd->b_index; 302 case BLOCK_SIZE_SB8X4: 303 case BLOCK_SIZE_SB4X8: 304 case BLOCK_SIZE_AB4X4: 305 return &xd->ab_index; 306 default: 307 assert(0); 308 return NULL; 309 } 310} 311 312static INLINE void update_partition_context(MACROBLOCKD *xd, 313 BLOCK_SIZE_TYPE sb_type, 314 BLOCK_SIZE_TYPE sb_size) { 315 const int bsl = b_width_log2(sb_size), bs = (1 << bsl) / 2; 316 const int bwl = b_width_log2(sb_type); 317 const int bhl = b_height_log2(sb_type); 318 const int boffset = b_width_log2(BLOCK_SIZE_SB64X64) - bsl; 319 const char pcval0 = ~(0xe << boffset); 320 const char pcval1 = ~(0xf << boffset); 321 const char pcvalue[2] = {pcval0, pcval1}; 322 323 assert(MAX(bwl, bhl) <= bsl); 324 325 // update the partition context at the end notes. set partition bits 326 // of block sizes larger than the current one to be one, and partition 327 // bits of smaller block sizes to be zero. 328 vpx_memset(xd->above_seg_context, pcvalue[bwl == bsl], bs); 329 vpx_memset(xd->left_seg_context, pcvalue[bhl == bsl], bs); 330} 331 332static INLINE int partition_plane_context(MACROBLOCKD *xd, 333 BLOCK_SIZE_TYPE sb_type) { 334 int bsl = mi_width_log2(sb_type), bs = 1 << bsl; 335 int above = 0, left = 0, i; 336 int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl; 337 338 assert(mi_width_log2(sb_type) == mi_height_log2(sb_type)); 339 assert(bsl >= 0); 340 assert(boffset >= 0); 341 342 for (i = 0; i < bs; i++) 343 above |= (xd->above_seg_context[i] & (1 << boffset)); 344 for (i = 0; i < bs; i++) 345 left |= (xd->left_seg_context[i] & (1 << boffset)); 346 347 above = (above > 0); 348 left = (left > 0); 349 350 return (left * 2 + above) + bsl * PARTITION_PLOFFSET; 351} 352 353static BLOCK_SIZE_TYPE get_subsize(BLOCK_SIZE_TYPE bsize, 354 PARTITION_TYPE partition) { 355 BLOCK_SIZE_TYPE subsize = subsize_lookup[partition][bsize]; 356 assert(subsize != BLOCK_SIZE_TYPES); 357 return subsize; 358} 359 360extern const TX_TYPE mode2txfm_map[MB_MODE_COUNT]; 361 362static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type, 363 const MACROBLOCKD *xd, int ib) { 364 const MODE_INFO *const mi = xd->mode_info_context; 365 const MB_MODE_INFO *const mbmi = &mi->mbmi; 366 367 if (plane_type != PLANE_TYPE_Y_WITH_DC || 368 xd->lossless || 369 mbmi->ref_frame[0] != INTRA_FRAME) 370 return DCT_DCT; 371 372 return mode2txfm_map[mbmi->sb_type < BLOCK_SIZE_SB8X8 ? 373 mi->bmi[ib].as_mode : mbmi->mode]; 374} 375 376static INLINE TX_TYPE get_tx_type_8x8(PLANE_TYPE plane_type, 377 const MACROBLOCKD *xd) { 378 return plane_type == PLANE_TYPE_Y_WITH_DC ? 379 mode2txfm_map[xd->mode_info_context->mbmi.mode] : DCT_DCT; 380} 381 382static INLINE TX_TYPE get_tx_type_16x16(PLANE_TYPE plane_type, 383 const MACROBLOCKD *xd) { 384 return plane_type == PLANE_TYPE_Y_WITH_DC ? 385 mode2txfm_map[xd->mode_info_context->mbmi.mode] : DCT_DCT; 386} 387 388static void setup_block_dptrs(MACROBLOCKD *xd, int ss_x, int ss_y) { 389 int i; 390 391 for (i = 0; i < MAX_MB_PLANE; i++) { 392 xd->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y_WITH_DC; 393 xd->plane[i].subsampling_x = i ? ss_x : 0; 394 xd->plane[i].subsampling_y = i ? ss_y : 0; 395 } 396#if CONFIG_ALPHA 397 // TODO(jkoleszar): Using the Y w/h for now 398 xd->plane[3].subsampling_x = 0; 399 xd->plane[3].subsampling_y = 0; 400#endif 401} 402 403 404static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi) { 405 return MIN(mbmi->txfm_size, max_uv_txsize_lookup[mbmi->sb_type]); 406} 407 408struct plane_block_idx { 409 int plane; 410 int block; 411}; 412 413// TODO(jkoleszar): returning a struct so it can be used in a const context, 414// expect to refactor this further later. 415static INLINE struct plane_block_idx plane_block_idx(int y_blocks, 416 int b_idx) { 417 const int v_offset = y_blocks * 5 / 4; 418 struct plane_block_idx res; 419 420 if (b_idx < y_blocks) { 421 res.plane = 0; 422 res.block = b_idx; 423 } else if (b_idx < v_offset) { 424 res.plane = 1; 425 res.block = b_idx - y_blocks; 426 } else { 427 assert(b_idx < y_blocks * 3 / 2); 428 res.plane = 2; 429 res.block = b_idx - v_offset; 430 } 431 return res; 432} 433 434static INLINE int plane_block_width(BLOCK_SIZE_TYPE bsize, 435 const struct macroblockd_plane* plane) { 436 return 4 << (b_width_log2(bsize) - plane->subsampling_x); 437} 438 439static INLINE int plane_block_height(BLOCK_SIZE_TYPE bsize, 440 const struct macroblockd_plane* plane) { 441 return 4 << (b_height_log2(bsize) - plane->subsampling_y); 442} 443 444static INLINE int plane_block_width_log2by4( 445 BLOCK_SIZE_TYPE bsize, const struct macroblockd_plane* plane) { 446 return (b_width_log2(bsize) - plane->subsampling_x); 447} 448 449static INLINE int plane_block_height_log2by4( 450 BLOCK_SIZE_TYPE bsize, const struct macroblockd_plane* plane) { 451 return (b_height_log2(bsize) - plane->subsampling_y); 452} 453 454typedef void (*foreach_transformed_block_visitor)(int plane, int block, 455 BLOCK_SIZE_TYPE bsize, 456 int ss_txfrm_size, 457 void *arg); 458 459static INLINE void foreach_transformed_block_in_plane( 460 const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane, 461 foreach_transformed_block_visitor visit, void *arg) { 462 const int bw = b_width_log2(bsize), bh = b_height_log2(bsize); 463 464 // block and transform sizes, in number of 4x4 blocks log 2 ("*_b") 465 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 466 // transform size varies per plane, look it up in a common way. 467 const MB_MODE_INFO* mbmi = &xd->mode_info_context->mbmi; 468 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi) 469 : mbmi->txfm_size; 470 const int block_size_b = bw + bh; 471 const int txfrm_size_b = tx_size * 2; 472 473 // subsampled size of the block 474 const int ss_sum = xd->plane[plane].subsampling_x 475 + xd->plane[plane].subsampling_y; 476 const int ss_block_size = block_size_b - ss_sum; 477 478 const int step = 1 << txfrm_size_b; 479 480 int i; 481 482 assert(txfrm_size_b <= block_size_b); 483 assert(txfrm_size_b <= ss_block_size); 484 485 // If mb_to_right_edge is < 0 we are in a situation in which 486 // the current block size extends into the UMV and we won't 487 // visit the sub blocks that are wholly within the UMV. 488 if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) { 489 int r, c; 490 const int sw = bw - xd->plane[plane].subsampling_x; 491 const int sh = bh - xd->plane[plane].subsampling_y; 492 int max_blocks_wide = 1 << sw; 493 int max_blocks_high = 1 << sh; 494 495 // xd->mb_to_right_edge is in units of pixels * 8. This converts 496 // it to 4x4 block sizes. 497 if (xd->mb_to_right_edge < 0) 498 max_blocks_wide += 499 + (xd->mb_to_right_edge >> (5 + xd->plane[plane].subsampling_x)); 500 501 if (xd->mb_to_bottom_edge < 0) 502 max_blocks_high += 503 + (xd->mb_to_bottom_edge >> (5 + xd->plane[plane].subsampling_y)); 504 505 i = 0; 506 // Unlike the normal case - in here we have to keep track of the 507 // row and column of the blocks we use so that we know if we are in 508 // the unrestricted motion border.. 509 for (r = 0; r < (1 << sh); r += (1 << tx_size)) { 510 for (c = 0; c < (1 << sw); c += (1 << tx_size)) { 511 if (r < max_blocks_high && c < max_blocks_wide) 512 visit(plane, i, bsize, txfrm_size_b, arg); 513 i += step; 514 } 515 } 516 } else { 517 for (i = 0; i < (1 << ss_block_size); i += step) { 518 visit(plane, i, bsize, txfrm_size_b, arg); 519 } 520 } 521} 522 523static INLINE void foreach_transformed_block( 524 const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, 525 foreach_transformed_block_visitor visit, void *arg) { 526 int plane; 527 528 for (plane = 0; plane < MAX_MB_PLANE; plane++) { 529 foreach_transformed_block_in_plane(xd, bsize, plane, 530 visit, arg); 531 } 532} 533 534static INLINE void foreach_transformed_block_uv( 535 const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, 536 foreach_transformed_block_visitor visit, void *arg) { 537 int plane; 538 539 for (plane = 1; plane < MAX_MB_PLANE; plane++) { 540 foreach_transformed_block_in_plane(xd, bsize, plane, 541 visit, arg); 542 } 543} 544 545// TODO(jkoleszar): In principle, pred_w, pred_h are unnecessary, as we could 546// calculate the subsampled BLOCK_SIZE_TYPE, but that type isn't defined for 547// sizes smaller than 16x16 yet. 548typedef void (*foreach_predicted_block_visitor)(int plane, int block, 549 BLOCK_SIZE_TYPE bsize, 550 int pred_w, int pred_h, 551 void *arg); 552static INLINE void foreach_predicted_block_in_plane( 553 const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane, 554 foreach_predicted_block_visitor visit, void *arg) { 555 int i, x, y; 556 557 // block sizes in number of 4x4 blocks log 2 ("*_b") 558 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 559 // subsampled size of the block 560 const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; 561 const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y; 562 563 // size of the predictor to use. 564 int pred_w, pred_h; 565 566 if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) { 567 assert(bsize == BLOCK_SIZE_SB8X8); 568 pred_w = 0; 569 pred_h = 0; 570 } else { 571 pred_w = bwl; 572 pred_h = bhl; 573 } 574 assert(pred_w <= bwl); 575 assert(pred_h <= bhl); 576 577 // visit each subblock in raster order 578 i = 0; 579 for (y = 0; y < 1 << bhl; y += 1 << pred_h) { 580 for (x = 0; x < 1 << bwl; x += 1 << pred_w) { 581 visit(plane, i, bsize, pred_w, pred_h, arg); 582 i += 1 << pred_w; 583 } 584 i += (1 << (bwl + pred_h)) - (1 << bwl); 585 } 586} 587static INLINE void foreach_predicted_block( 588 const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, 589 foreach_predicted_block_visitor visit, void *arg) { 590 int plane; 591 592 for (plane = 0; plane < MAX_MB_PLANE; plane++) { 593 foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg); 594 } 595} 596static INLINE void foreach_predicted_block_uv( 597 const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, 598 foreach_predicted_block_visitor visit, void *arg) { 599 int plane; 600 601 for (plane = 1; plane < MAX_MB_PLANE; plane++) { 602 foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg); 603 } 604} 605static int raster_block_offset(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, 606 int plane, int block, int stride) { 607 const int bw = b_width_log2(bsize) - xd->plane[plane].subsampling_x; 608 const int y = 4 * (block >> bw), x = 4 * (block & ((1 << bw) - 1)); 609 return y * stride + x; 610} 611static int16_t* raster_block_offset_int16(MACROBLOCKD *xd, 612 BLOCK_SIZE_TYPE bsize, 613 int plane, int block, int16_t *base) { 614 const int stride = plane_block_width(bsize, &xd->plane[plane]); 615 return base + raster_block_offset(xd, bsize, plane, block, stride); 616} 617static uint8_t* raster_block_offset_uint8(MACROBLOCKD *xd, 618 BLOCK_SIZE_TYPE bsize, 619 int plane, int block, 620 uint8_t *base, int stride) { 621 return base + raster_block_offset(xd, bsize, plane, block, stride); 622} 623 624static int txfrm_block_to_raster_block(MACROBLOCKD *xd, 625 BLOCK_SIZE_TYPE bsize, 626 int plane, int block, 627 int ss_txfrm_size) { 628 const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; 629 const int txwl = ss_txfrm_size / 2; 630 const int tx_cols_log2 = bwl - txwl; 631 const int tx_cols = 1 << tx_cols_log2; 632 const int raster_mb = block >> ss_txfrm_size; 633 const int x = (raster_mb & (tx_cols - 1)) << (txwl); 634 const int y = raster_mb >> tx_cols_log2 << (txwl); 635 return x + (y << bwl); 636} 637 638static void txfrm_block_to_raster_xy(MACROBLOCKD *xd, 639 BLOCK_SIZE_TYPE bsize, 640 int plane, int block, 641 int ss_txfrm_size, 642 int *x, int *y) { 643 const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; 644 const int txwl = ss_txfrm_size / 2; 645 const int tx_cols_log2 = bwl - txwl; 646 const int tx_cols = 1 << tx_cols_log2; 647 const int raster_mb = block >> ss_txfrm_size; 648 *x = (raster_mb & (tx_cols - 1)) << (txwl); 649 *y = raster_mb >> tx_cols_log2 << (txwl); 650} 651 652static void extend_for_intra(MACROBLOCKD* const xd, int plane, int block, 653 BLOCK_SIZE_TYPE bsize, int ss_txfrm_size) { 654 const int bw = plane_block_width(bsize, &xd->plane[plane]); 655 const int bh = plane_block_height(bsize, &xd->plane[plane]); 656 int x, y; 657 txfrm_block_to_raster_xy(xd, bsize, plane, block, ss_txfrm_size, &x, &y); 658 x = x * 4 - 1; 659 y = y * 4 - 1; 660 // Copy a pixel into the umv if we are in a situation where the block size 661 // extends into the UMV. 662 // TODO(JBB): Should be able to do the full extend in place so we don't have 663 // to do this multiple times. 664 if (xd->mb_to_right_edge < 0) { 665 int umv_border_start = bw 666 + (xd->mb_to_right_edge >> (3 + xd->plane[plane].subsampling_x)); 667 668 if (x + bw > umv_border_start) 669 vpx_memset( 670 xd->plane[plane].dst.buf + y * xd->plane[plane].dst.stride 671 + umv_border_start, 672 *(xd->plane[plane].dst.buf + y * xd->plane[plane].dst.stride 673 + umv_border_start - 1), 674 bw); 675 } 676 if (xd->mb_to_bottom_edge < 0) { 677 int umv_border_start = bh 678 + (xd->mb_to_bottom_edge >> (3 + xd->plane[plane].subsampling_y)); 679 int i; 680 uint8_t c = *(xd->plane[plane].dst.buf 681 + (umv_border_start - 1) * xd->plane[plane].dst.stride + x); 682 683 uint8_t *d = xd->plane[plane].dst.buf 684 + umv_border_start * xd->plane[plane].dst.stride + x; 685 686 if (y + bh > umv_border_start) 687 for (i = 0; i < bh; i++, d += xd->plane[plane].dst.stride) 688 *d = c; 689 } 690} 691static void set_contexts_on_border(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, 692 int plane, int ss_tx_size, int eob, int aoff, 693 int loff, ENTROPY_CONTEXT *A, 694 ENTROPY_CONTEXT *L) { 695 const int bw = b_width_log2(bsize), bh = b_height_log2(bsize); 696 const int sw = bw - xd->plane[plane].subsampling_x; 697 const int sh = bh - xd->plane[plane].subsampling_y; 698 int mi_blocks_wide = 1 << sw; 699 int mi_blocks_high = 1 << sh; 700 int tx_size_in_blocks = (1 << ss_tx_size); 701 int above_contexts = tx_size_in_blocks; 702 int left_contexts = tx_size_in_blocks; 703 int pt; 704 705 // xd->mb_to_right_edge is in units of pixels * 8. This converts 706 // it to 4x4 block sizes. 707 if (xd->mb_to_right_edge < 0) { 708 mi_blocks_wide += (xd->mb_to_right_edge 709 >> (5 + xd->plane[plane].subsampling_x)); 710 } 711 712 // this code attempts to avoid copying into contexts that are outside 713 // our border. Any blocks that do are set to 0... 714 if (above_contexts + aoff > mi_blocks_wide) 715 above_contexts = mi_blocks_wide - aoff; 716 717 if (xd->mb_to_bottom_edge < 0) { 718 mi_blocks_high += (xd->mb_to_bottom_edge 719 >> (5 + xd->plane[plane].subsampling_y)); 720 } 721 if (left_contexts + loff > mi_blocks_high) { 722 left_contexts = mi_blocks_high - loff; 723 } 724 725 for (pt = 0; pt < above_contexts; pt++) 726 A[pt] = eob > 0; 727 for (pt = above_contexts; pt < (1 << ss_tx_size); pt++) 728 A[pt] = 0; 729 for (pt = 0; pt < left_contexts; pt++) 730 L[pt] = eob > 0; 731 for (pt = left_contexts; pt < (1 << ss_tx_size); pt++) 732 L[pt] = 0; 733} 734 735 736#endif // VP9_COMMON_VP9_BLOCKD_H_ 737