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_enums.h" 23 #include "vp9/common/vp9_filter.h" 24 #include "vp9/common/vp9_mv.h" 25 #include "vp9/common/vp9_scale.h" 26 #include "vp9/common/vp9_seg_common.h" 27 #include "vp9/common/vp9_treecoder.h" 28 29 #define BLOCK_SIZE_GROUPS 4 30 #define MBSKIP_CONTEXTS 3 31 32 /* Segment Feature Masks */ 33 #define MAX_MV_REF_CANDIDATES 2 34 35 #define INTRA_INTER_CONTEXTS 4 36 #define COMP_INTER_CONTEXTS 5 37 #define REF_CONTEXTS 5 38 39 typedef enum { 40 PLANE_TYPE_Y_WITH_DC, 41 PLANE_TYPE_UV, 42 } PLANE_TYPE; 43 44 typedef char ENTROPY_CONTEXT; 45 46 typedef char PARTITION_CONTEXT; 47 48 static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a, 49 ENTROPY_CONTEXT b) { 50 return (a != 0) + (b != 0); 51 } 52 53 typedef enum { 54 KEY_FRAME = 0, 55 INTER_FRAME = 1, 56 FRAME_TYPES, 57 } FRAME_TYPE; 58 59 typedef enum { 60 DC_PRED, // Average of above and left pixels 61 V_PRED, // Vertical 62 H_PRED, // Horizontal 63 D45_PRED, // Directional 45 deg = round(arctan(1/1) * 180/pi) 64 D135_PRED, // Directional 135 deg = 180 - 45 65 D117_PRED, // Directional 117 deg = 180 - 63 66 D153_PRED, // Directional 153 deg = 180 - 27 67 D207_PRED, // Directional 207 deg = 180 + 27 68 D63_PRED, // Directional 63 deg = round(arctan(2/1) * 180/pi) 69 TM_PRED, // True-motion 70 NEARESTMV, 71 NEARMV, 72 ZEROMV, 73 NEWMV, 74 MB_MODE_COUNT 75 } MB_PREDICTION_MODE; 76 77 static INLINE int is_inter_mode(MB_PREDICTION_MODE mode) { 78 return mode >= NEARESTMV && mode <= NEWMV; 79 } 80 81 #define INTRA_MODES (TM_PRED + 1) 82 83 #define INTER_MODES (1 + NEWMV - NEARESTMV) 84 85 #define INTER_OFFSET(mode) ((mode) - NEARESTMV) 86 87 88 /* For keyframes, intra block modes are predicted by the (already decoded) 89 modes for the Y blocks to the left and above us; for interframes, there 90 is a single probability table. */ 91 92 typedef struct { 93 MB_PREDICTION_MODE as_mode; 94 int_mv as_mv[2]; // first, second inter predictor motion vectors 95 } b_mode_info; 96 97 typedef enum { 98 NONE = -1, 99 INTRA_FRAME = 0, 100 LAST_FRAME = 1, 101 GOLDEN_FRAME = 2, 102 ALTREF_FRAME = 3, 103 MAX_REF_FRAMES = 4 104 } MV_REFERENCE_FRAME; 105 106 static INLINE int b_width_log2(BLOCK_SIZE sb_type) { 107 return b_width_log2_lookup[sb_type]; 108 } 109 static INLINE int b_height_log2(BLOCK_SIZE sb_type) { 110 return b_height_log2_lookup[sb_type]; 111 } 112 113 static INLINE int mi_width_log2(BLOCK_SIZE sb_type) { 114 return mi_width_log2_lookup[sb_type]; 115 } 116 117 static INLINE int mi_height_log2(BLOCK_SIZE sb_type) { 118 return mi_height_log2_lookup[sb_type]; 119 } 120 121 // This structure now relates to 8x8 block regions. 122 typedef struct { 123 MB_PREDICTION_MODE mode, uv_mode; 124 MV_REFERENCE_FRAME ref_frame[2]; 125 TX_SIZE tx_size; 126 int_mv mv[2]; // for each reference frame used 127 int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; 128 int_mv best_mv[2]; 129 130 uint8_t mode_context[MAX_REF_FRAMES]; 131 132 unsigned char skip_coeff; // 0=need to decode coeffs, 1=no coefficients 133 unsigned char segment_id; // Segment id for this block. 134 135 // Flags used for prediction status of various bit-stream signals 136 unsigned char seg_id_predicted; 137 138 INTERPOLATION_TYPE interp_filter; 139 140 BLOCK_SIZE sb_type; 141 } MB_MODE_INFO; 142 143 typedef struct { 144 MB_MODE_INFO mbmi; 145 b_mode_info bmi[4]; 146 } MODE_INFO; 147 148 static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) { 149 return mbmi->ref_frame[0] > INTRA_FRAME; 150 } 151 152 static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) { 153 return mbmi->ref_frame[1] > INTRA_FRAME; 154 } 155 156 enum mv_precision { 157 MV_PRECISION_Q3, 158 MV_PRECISION_Q4 159 }; 160 161 #if CONFIG_ALPHA 162 enum { MAX_MB_PLANE = 4 }; 163 #else 164 enum { MAX_MB_PLANE = 3 }; 165 #endif 166 167 struct buf_2d { 168 uint8_t *buf; 169 int stride; 170 }; 171 172 struct macroblockd_plane { 173 int16_t *qcoeff; 174 int16_t *dqcoeff; 175 uint16_t *eobs; 176 PLANE_TYPE plane_type; 177 int subsampling_x; 178 int subsampling_y; 179 struct buf_2d dst; 180 struct buf_2d pre[2]; 181 int16_t *dequant; 182 ENTROPY_CONTEXT *above_context; 183 ENTROPY_CONTEXT *left_context; 184 }; 185 186 #define BLOCK_OFFSET(x, i) ((x) + (i) * 16) 187 188 typedef struct macroblockd { 189 struct macroblockd_plane plane[MAX_MB_PLANE]; 190 191 struct scale_factors scale_factor[2]; 192 193 MODE_INFO *last_mi; 194 int mode_info_stride; 195 196 // A NULL indicates that the 8x8 is not part of the image 197 MODE_INFO **mi_8x8; 198 MODE_INFO **prev_mi_8x8; 199 MODE_INFO *mi_stream; 200 201 int up_available; 202 int left_available; 203 204 /* Distance of MB away from frame edges */ 205 int mb_to_left_edge; 206 int mb_to_right_edge; 207 int mb_to_top_edge; 208 int mb_to_bottom_edge; 209 210 int lossless; 211 /* Inverse transform function pointers. */ 212 void (*itxm_add)(const int16_t *input, uint8_t *dest, int stride, int eob); 213 214 struct subpix_fn_table subpix; 215 216 int corrupted; 217 218 /* Y,U,V,(A) */ 219 ENTROPY_CONTEXT *above_context[MAX_MB_PLANE]; 220 ENTROPY_CONTEXT left_context[MAX_MB_PLANE][16]; 221 222 PARTITION_CONTEXT *above_seg_context; 223 PARTITION_CONTEXT left_seg_context[8]; 224 } MACROBLOCKD; 225 226 227 228 static BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, PARTITION_TYPE partition) { 229 const BLOCK_SIZE subsize = subsize_lookup[partition][bsize]; 230 assert(subsize < BLOCK_SIZES); 231 return subsize; 232 } 233 234 extern const TX_TYPE mode2txfm_map[MB_MODE_COUNT]; 235 236 static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type, 237 const MACROBLOCKD *xd, int ib) { 238 const MODE_INFO *const mi = xd->mi_8x8[0]; 239 const MB_MODE_INFO *const mbmi = &mi->mbmi; 240 241 if (plane_type != PLANE_TYPE_Y_WITH_DC || 242 xd->lossless || 243 is_inter_block(mbmi)) 244 return DCT_DCT; 245 246 return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ? 247 mi->bmi[ib].as_mode : mbmi->mode]; 248 } 249 250 static INLINE TX_TYPE get_tx_type_8x8(PLANE_TYPE plane_type, 251 const MACROBLOCKD *xd) { 252 return plane_type == PLANE_TYPE_Y_WITH_DC ? 253 mode2txfm_map[xd->mi_8x8[0]->mbmi.mode] : DCT_DCT; 254 } 255 256 static INLINE TX_TYPE get_tx_type_16x16(PLANE_TYPE plane_type, 257 const MACROBLOCKD *xd) { 258 return plane_type == PLANE_TYPE_Y_WITH_DC ? 259 mode2txfm_map[xd->mi_8x8[0]->mbmi.mode] : DCT_DCT; 260 } 261 262 static void setup_block_dptrs(MACROBLOCKD *xd, int ss_x, int ss_y) { 263 int i; 264 265 for (i = 0; i < MAX_MB_PLANE; i++) { 266 xd->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y_WITH_DC; 267 xd->plane[i].subsampling_x = i ? ss_x : 0; 268 xd->plane[i].subsampling_y = i ? ss_y : 0; 269 } 270 #if CONFIG_ALPHA 271 // TODO(jkoleszar): Using the Y w/h for now 272 xd->plane[3].subsampling_x = 0; 273 xd->plane[3].subsampling_y = 0; 274 #endif 275 } 276 277 278 static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi) { 279 return MIN(mbmi->tx_size, max_uv_txsize_lookup[mbmi->sb_type]); 280 } 281 282 static BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize, 283 const struct macroblockd_plane *pd) { 284 BLOCK_SIZE bs = ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y]; 285 assert(bs < BLOCK_SIZES); 286 return bs; 287 } 288 289 static INLINE int plane_block_width(BLOCK_SIZE bsize, 290 const struct macroblockd_plane* plane) { 291 return 4 << (b_width_log2(bsize) - plane->subsampling_x); 292 } 293 294 static INLINE int plane_block_height(BLOCK_SIZE bsize, 295 const struct macroblockd_plane* plane) { 296 return 4 << (b_height_log2(bsize) - plane->subsampling_y); 297 } 298 299 typedef void (*foreach_transformed_block_visitor)(int plane, int block, 300 BLOCK_SIZE plane_bsize, 301 TX_SIZE tx_size, 302 void *arg); 303 304 static INLINE void foreach_transformed_block_in_plane( 305 const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, 306 foreach_transformed_block_visitor visit, void *arg) { 307 const struct macroblockd_plane *const pd = &xd->plane[plane]; 308 const MB_MODE_INFO* mbmi = &xd->mi_8x8[0]->mbmi; 309 // block and transform sizes, in number of 4x4 blocks log 2 ("*_b") 310 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 311 // transform size varies per plane, look it up in a common way. 312 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi) 313 : mbmi->tx_size; 314 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); 315 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; 316 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; 317 const int step = 1 << (tx_size << 1); 318 int i; 319 320 // If mb_to_right_edge is < 0 we are in a situation in which 321 // the current block size extends into the UMV and we won't 322 // visit the sub blocks that are wholly within the UMV. 323 if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) { 324 int r, c; 325 326 int max_blocks_wide = num_4x4_w; 327 int max_blocks_high = num_4x4_h; 328 329 // xd->mb_to_right_edge is in units of pixels * 8. This converts 330 // it to 4x4 block sizes. 331 if (xd->mb_to_right_edge < 0) 332 max_blocks_wide += (xd->mb_to_right_edge >> (5 + pd->subsampling_x)); 333 334 if (xd->mb_to_bottom_edge < 0) 335 max_blocks_high += (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); 336 337 i = 0; 338 // Unlike the normal case - in here we have to keep track of the 339 // row and column of the blocks we use so that we know if we are in 340 // the unrestricted motion border. 341 for (r = 0; r < num_4x4_h; r += (1 << tx_size)) { 342 for (c = 0; c < num_4x4_w; c += (1 << tx_size)) { 343 if (r < max_blocks_high && c < max_blocks_wide) 344 visit(plane, i, plane_bsize, tx_size, arg); 345 i += step; 346 } 347 } 348 } else { 349 for (i = 0; i < num_4x4_w * num_4x4_h; i += step) 350 visit(plane, i, plane_bsize, tx_size, arg); 351 } 352 } 353 354 static INLINE void foreach_transformed_block( 355 const MACROBLOCKD* const xd, BLOCK_SIZE bsize, 356 foreach_transformed_block_visitor visit, void *arg) { 357 int plane; 358 359 for (plane = 0; plane < MAX_MB_PLANE; plane++) 360 foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg); 361 } 362 363 static INLINE void foreach_transformed_block_uv( 364 const MACROBLOCKD* const xd, BLOCK_SIZE bsize, 365 foreach_transformed_block_visitor visit, void *arg) { 366 int plane; 367 368 for (plane = 1; plane < MAX_MB_PLANE; plane++) 369 foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg); 370 } 371 372 static int raster_block_offset(BLOCK_SIZE plane_bsize, 373 int raster_block, int stride) { 374 const int bw = b_width_log2(plane_bsize); 375 const int y = 4 * (raster_block >> bw); 376 const int x = 4 * (raster_block & ((1 << bw) - 1)); 377 return y * stride + x; 378 } 379 static int16_t* raster_block_offset_int16(BLOCK_SIZE plane_bsize, 380 int raster_block, int16_t *base) { 381 const int stride = 4 << b_width_log2(plane_bsize); 382 return base + raster_block_offset(plane_bsize, raster_block, stride); 383 } 384 static uint8_t* raster_block_offset_uint8(BLOCK_SIZE plane_bsize, 385 int raster_block, uint8_t *base, 386 int stride) { 387 return base + raster_block_offset(plane_bsize, raster_block, stride); 388 } 389 390 static int txfrm_block_to_raster_block(BLOCK_SIZE plane_bsize, 391 TX_SIZE tx_size, int block) { 392 const int bwl = b_width_log2(plane_bsize); 393 const int tx_cols_log2 = bwl - tx_size; 394 const int tx_cols = 1 << tx_cols_log2; 395 const int raster_mb = block >> (tx_size << 1); 396 const int x = (raster_mb & (tx_cols - 1)) << tx_size; 397 const int y = (raster_mb >> tx_cols_log2) << tx_size; 398 return x + (y << bwl); 399 } 400 401 static void txfrm_block_to_raster_xy(BLOCK_SIZE plane_bsize, 402 TX_SIZE tx_size, int block, 403 int *x, int *y) { 404 const int bwl = b_width_log2(plane_bsize); 405 const int tx_cols_log2 = bwl - tx_size; 406 const int tx_cols = 1 << tx_cols_log2; 407 const int raster_mb = block >> (tx_size << 1); 408 *x = (raster_mb & (tx_cols - 1)) << tx_size; 409 *y = (raster_mb >> tx_cols_log2) << tx_size; 410 } 411 412 static void extend_for_intra(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, 413 int plane, int block, TX_SIZE tx_size) { 414 struct macroblockd_plane *const pd = &xd->plane[plane]; 415 uint8_t *const buf = pd->dst.buf; 416 const int stride = pd->dst.stride; 417 418 int x, y; 419 txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y); 420 x = x * 4 - 1; 421 y = y * 4 - 1; 422 // Copy a pixel into the umv if we are in a situation where the block size 423 // extends into the UMV. 424 // TODO(JBB): Should be able to do the full extend in place so we don't have 425 // to do this multiple times. 426 if (xd->mb_to_right_edge < 0) { 427 const int bw = 4 << b_width_log2(plane_bsize); 428 const int umv_border_start = bw + (xd->mb_to_right_edge >> 429 (3 + pd->subsampling_x)); 430 431 if (x + bw > umv_border_start) 432 vpx_memset(&buf[y * stride + umv_border_start], 433 buf[y * stride + umv_border_start - 1], bw); 434 } 435 436 if (xd->mb_to_bottom_edge < 0) { 437 if (xd->left_available || x >= 0) { 438 const int bh = 4 << b_height_log2(plane_bsize); 439 const int umv_border_start = 440 bh + (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)); 441 442 if (y + bh > umv_border_start) { 443 const uint8_t c = buf[(umv_border_start - 1) * stride + x]; 444 uint8_t *d = &buf[umv_border_start * stride + x]; 445 int i; 446 for (i = 0; i < bh; ++i, d += stride) 447 *d = c; 448 } 449 } 450 } 451 } 452 453 static void set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, 454 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, 455 int has_eob, int aoff, int loff) { 456 ENTROPY_CONTEXT *const a = pd->above_context + aoff; 457 ENTROPY_CONTEXT *const l = pd->left_context + loff; 458 const int tx_size_in_blocks = 1 << tx_size; 459 460 // above 461 if (has_eob && xd->mb_to_right_edge < 0) { 462 int i; 463 const int blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize] + 464 (xd->mb_to_right_edge >> (5 + pd->subsampling_x)); 465 int above_contexts = tx_size_in_blocks; 466 if (above_contexts + aoff > blocks_wide) 467 above_contexts = blocks_wide - aoff; 468 469 for (i = 0; i < above_contexts; ++i) 470 a[i] = has_eob; 471 for (i = above_contexts; i < tx_size_in_blocks; ++i) 472 a[i] = 0; 473 } else { 474 vpx_memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); 475 } 476 477 // left 478 if (has_eob && xd->mb_to_bottom_edge < 0) { 479 int i; 480 const int blocks_high = num_4x4_blocks_high_lookup[plane_bsize] + 481 (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); 482 int left_contexts = tx_size_in_blocks; 483 if (left_contexts + loff > blocks_high) 484 left_contexts = blocks_high - loff; 485 486 for (i = 0; i < left_contexts; ++i) 487 l[i] = has_eob; 488 for (i = left_contexts; i < tx_size_in_blocks; ++i) 489 l[i] = 0; 490 } else { 491 vpx_memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); 492 } 493 } 494 495 static int get_tx_eob(const struct segmentation *seg, int segment_id, 496 TX_SIZE tx_size) { 497 const int eob_max = 16 << (tx_size << 1); 498 return vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max; 499 } 500 501 #endif // VP9_COMMON_VP9_BLOCKD_H_ 502