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_idct.h" 25 #include "vp9/common/vp9_mv.h" 26 #include "vp9/common/vp9_scale.h" 27 #include "vp9/common/vp9_seg_common.h" 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #define BLOCK_SIZE_GROUPS 4 34 #define SKIP_CONTEXTS 3 35 #define INTER_MODE_CONTEXTS 7 36 37 /* Segment Feature Masks */ 38 #define MAX_MV_REF_CANDIDATES 2 39 40 #define INTRA_INTER_CONTEXTS 4 41 #define COMP_INTER_CONTEXTS 5 42 #define REF_CONTEXTS 5 43 44 typedef enum { 45 PLANE_TYPE_Y = 0, 46 PLANE_TYPE_UV = 1, 47 PLANE_TYPES 48 } PLANE_TYPE; 49 50 typedef char ENTROPY_CONTEXT; 51 52 typedef char PARTITION_CONTEXT; 53 54 static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a, 55 ENTROPY_CONTEXT b) { 56 return (a != 0) + (b != 0); 57 } 58 59 typedef enum { 60 KEY_FRAME = 0, 61 INTER_FRAME = 1, 62 FRAME_TYPES, 63 } FRAME_TYPE; 64 65 typedef enum { 66 DC_PRED, // Average of above and left pixels 67 V_PRED, // Vertical 68 H_PRED, // Horizontal 69 D45_PRED, // Directional 45 deg = round(arctan(1/1) * 180/pi) 70 D135_PRED, // Directional 135 deg = 180 - 45 71 D117_PRED, // Directional 117 deg = 180 - 63 72 D153_PRED, // Directional 153 deg = 180 - 27 73 D207_PRED, // Directional 207 deg = 180 + 27 74 D63_PRED, // Directional 63 deg = round(arctan(2/1) * 180/pi) 75 TM_PRED, // True-motion 76 NEARESTMV, 77 NEARMV, 78 ZEROMV, 79 NEWMV, 80 MB_MODE_COUNT 81 } PREDICTION_MODE; 82 83 static INLINE int is_inter_mode(PREDICTION_MODE mode) { 84 return mode >= NEARESTMV && mode <= NEWMV; 85 } 86 87 #define INTRA_MODES (TM_PRED + 1) 88 89 #define INTER_MODES (1 + NEWMV - NEARESTMV) 90 91 #define INTER_OFFSET(mode) ((mode) - NEARESTMV) 92 93 /* For keyframes, intra block modes are predicted by the (already decoded) 94 modes for the Y blocks to the left and above us; for interframes, there 95 is a single probability table. */ 96 97 typedef struct { 98 PREDICTION_MODE as_mode; 99 int_mv as_mv[2]; // first, second inter predictor motion vectors 100 } b_mode_info; 101 102 // Note that the rate-distortion optimization loop, bit-stream writer, and 103 // decoder implementation modules critically rely on the enum entry values 104 // specified herein. They should be refactored concurrently. 105 typedef enum { 106 NONE = -1, 107 INTRA_FRAME = 0, 108 LAST_FRAME = 1, 109 GOLDEN_FRAME = 2, 110 ALTREF_FRAME = 3, 111 MAX_REF_FRAMES = 4 112 } MV_REFERENCE_FRAME; 113 114 static INLINE int b_width_log2(BLOCK_SIZE sb_type) { 115 return b_width_log2_lookup[sb_type]; 116 } 117 static INLINE int b_height_log2(BLOCK_SIZE sb_type) { 118 return b_height_log2_lookup[sb_type]; 119 } 120 121 static INLINE int mi_width_log2(BLOCK_SIZE sb_type) { 122 return mi_width_log2_lookup[sb_type]; 123 } 124 125 // This structure now relates to 8x8 block regions. 126 typedef struct { 127 // Common for both INTER and INTRA blocks 128 BLOCK_SIZE sb_type; 129 PREDICTION_MODE mode; 130 TX_SIZE tx_size; 131 int8_t skip; 132 int8_t segment_id; 133 int8_t seg_id_predicted; // valid only when temporal_update is enabled 134 135 // Only for INTRA blocks 136 PREDICTION_MODE uv_mode; 137 138 // Only for INTER blocks 139 MV_REFERENCE_FRAME ref_frame[2]; 140 int_mv mv[2]; 141 int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; 142 uint8_t mode_context[MAX_REF_FRAMES]; 143 INTERP_FILTER interp_filter; 144 } MB_MODE_INFO; 145 146 typedef struct MODE_INFO { 147 struct MODE_INFO *src_mi; 148 MB_MODE_INFO mbmi; 149 b_mode_info bmi[4]; 150 } MODE_INFO; 151 152 static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) { 153 return mi->mbmi.sb_type < BLOCK_8X8 ? mi->bmi[block].as_mode 154 : mi->mbmi.mode; 155 } 156 157 static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) { 158 return mbmi->ref_frame[0] > INTRA_FRAME; 159 } 160 161 static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) { 162 return mbmi->ref_frame[1] > INTRA_FRAME; 163 } 164 165 PREDICTION_MODE vp9_left_block_mode(const MODE_INFO *cur_mi, 166 const MODE_INFO *left_mi, int b); 167 168 PREDICTION_MODE vp9_above_block_mode(const MODE_INFO *cur_mi, 169 const MODE_INFO *above_mi, int b); 170 171 enum mv_precision { 172 MV_PRECISION_Q3, 173 MV_PRECISION_Q4 174 }; 175 176 enum { MAX_MB_PLANE = 3 }; 177 178 struct buf_2d { 179 uint8_t *buf; 180 int stride; 181 }; 182 183 struct macroblockd_plane { 184 tran_low_t *dqcoeff; 185 PLANE_TYPE plane_type; 186 int subsampling_x; 187 int subsampling_y; 188 struct buf_2d dst; 189 struct buf_2d pre[2]; 190 const int16_t *dequant; 191 ENTROPY_CONTEXT *above_context; 192 ENTROPY_CONTEXT *left_context; 193 }; 194 195 #define BLOCK_OFFSET(x, i) ((x) + (i) * 16) 196 197 typedef struct RefBuffer { 198 // TODO(dkovalev): idx is not really required and should be removed, now it 199 // is used in vp9_onyxd_if.c 200 int idx; 201 YV12_BUFFER_CONFIG *buf; 202 struct scale_factors sf; 203 } RefBuffer; 204 205 typedef struct macroblockd { 206 struct macroblockd_plane plane[MAX_MB_PLANE]; 207 208 int mi_stride; 209 210 MODE_INFO *mi; 211 212 int up_available; 213 int left_available; 214 215 /* Distance of MB away from frame edges */ 216 int mb_to_left_edge; 217 int mb_to_right_edge; 218 int mb_to_top_edge; 219 int mb_to_bottom_edge; 220 221 /* pointers to reference frames */ 222 RefBuffer *block_refs[2]; 223 224 /* pointer to current frame */ 225 const YV12_BUFFER_CONFIG *cur_buf; 226 227 /* mc buffer */ 228 DECLARE_ALIGNED(16, uint8_t, mc_buf[80 * 2 * 80 * 2]); 229 230 #if CONFIG_VP9_HIGHBITDEPTH 231 /* Bit depth: 8, 10, 12 */ 232 int bd; 233 DECLARE_ALIGNED(16, uint16_t, mc_buf_high[80 * 2 * 80 * 2]); 234 #endif 235 236 int lossless; 237 238 int corrupted; 239 240 DECLARE_ALIGNED(16, tran_low_t, dqcoeff[MAX_MB_PLANE][64 * 64]); 241 242 ENTROPY_CONTEXT *above_context[MAX_MB_PLANE]; 243 ENTROPY_CONTEXT left_context[MAX_MB_PLANE][16]; 244 245 PARTITION_CONTEXT *above_seg_context; 246 PARTITION_CONTEXT left_seg_context[8]; 247 } MACROBLOCKD; 248 249 static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, 250 PARTITION_TYPE partition) { 251 return subsize_lookup[partition][bsize]; 252 } 253 254 extern const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES]; 255 256 static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, 257 const MACROBLOCKD *xd) { 258 const MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi; 259 260 if (plane_type != PLANE_TYPE_Y || is_inter_block(mbmi)) 261 return DCT_DCT; 262 return intra_mode_to_tx_type_lookup[mbmi->mode]; 263 } 264 265 static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type, 266 const MACROBLOCKD *xd, int ib) { 267 const MODE_INFO *const mi = xd->mi[0].src_mi; 268 269 if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(&mi->mbmi)) 270 return DCT_DCT; 271 272 return intra_mode_to_tx_type_lookup[get_y_mode(mi, ib)]; 273 } 274 275 void vp9_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y); 276 277 static INLINE TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize, 278 int xss, int yss) { 279 if (bsize < BLOCK_8X8) { 280 return TX_4X4; 281 } else { 282 const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][xss][yss]; 283 return MIN(y_tx_size, max_txsize_lookup[plane_bsize]); 284 } 285 } 286 287 static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi, 288 const struct macroblockd_plane *pd) { 289 return get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type, pd->subsampling_x, 290 pd->subsampling_y); 291 } 292 293 static INLINE BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize, 294 const struct macroblockd_plane *pd) { 295 return ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y]; 296 } 297 298 typedef void (*foreach_transformed_block_visitor)(int plane, int block, 299 BLOCK_SIZE plane_bsize, 300 TX_SIZE tx_size, 301 void *arg); 302 303 void vp9_foreach_transformed_block_in_plane( 304 const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, 305 foreach_transformed_block_visitor visit, void *arg); 306 307 308 void vp9_foreach_transformed_block( 309 const MACROBLOCKD* const xd, BLOCK_SIZE bsize, 310 foreach_transformed_block_visitor visit, void *arg); 311 312 static INLINE void txfrm_block_to_raster_xy(BLOCK_SIZE plane_bsize, 313 TX_SIZE tx_size, int block, 314 int *x, int *y) { 315 const int bwl = b_width_log2(plane_bsize); 316 const int tx_cols_log2 = bwl - tx_size; 317 const int tx_cols = 1 << tx_cols_log2; 318 const int raster_mb = block >> (tx_size << 1); 319 *x = (raster_mb & (tx_cols - 1)) << tx_size; 320 *y = (raster_mb >> tx_cols_log2) << tx_size; 321 } 322 323 void vp9_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, 324 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob, 325 int aoff, int loff); 326 327 #ifdef __cplusplus 328 } // extern "C" 329 #endif 330 331 #endif // VP9_COMMON_VP9_BLOCKD_H_ 332