pred_common.h (13473B)
1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #ifndef AOM_AV1_COMMON_PRED_COMMON_H_ 13 #define AOM_AV1_COMMON_PRED_COMMON_H_ 14 15 #include <stdint.h> 16 17 #include "av1/common/av1_common_int.h" 18 #include "av1/common/blockd.h" 19 #include "av1/common/mvref_common.h" 20 #include "aom_dsp/aom_dsp_common.h" 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 static inline uint8_t get_segment_id( 27 const CommonModeInfoParams *const mi_params, const uint8_t *segment_ids, 28 BLOCK_SIZE bsize, int mi_row, int mi_col) { 29 const int mi_offset = mi_row * mi_params->mi_cols + mi_col; 30 const int bw = mi_size_wide[bsize]; 31 const int bh = mi_size_high[bsize]; 32 const int xmis = AOMMIN(mi_params->mi_cols - mi_col, bw); 33 const int ymis = AOMMIN(mi_params->mi_rows - mi_row, bh); 34 const int seg_stride = mi_params->mi_cols; 35 uint8_t segment_id = MAX_SEGMENTS; 36 37 for (int y = 0; y < ymis; ++y) { 38 for (int x = 0; x < xmis; ++x) { 39 segment_id = 40 AOMMIN(segment_id, segment_ids[mi_offset + y * seg_stride + x]); 41 } 42 } 43 44 assert(segment_id < MAX_SEGMENTS); 45 return segment_id; 46 } 47 48 static inline uint8_t av1_get_spatial_seg_pred(const AV1_COMMON *const cm, 49 const MACROBLOCKD *const xd, 50 int *cdf_index, 51 int skip_over4x4) { 52 const int step_size = skip_over4x4 ? 2 : 1; 53 uint8_t prev_ul = UINT8_MAX; // top left segment_id 54 uint8_t prev_l = UINT8_MAX; // left segment_id 55 uint8_t prev_u = UINT8_MAX; // top segment_id 56 const int mi_row = xd->mi_row; 57 const int mi_col = xd->mi_col; 58 const CommonModeInfoParams *const mi_params = &cm->mi_params; 59 const uint8_t *seg_map = cm->cur_frame->seg_map; 60 if ((xd->up_available) && (xd->left_available)) { 61 prev_ul = get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - step_size, 62 mi_col - step_size); 63 } 64 if (xd->up_available) { 65 prev_u = get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - step_size, 66 mi_col - 0); 67 } 68 if (xd->left_available) { 69 prev_l = get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 0, 70 mi_col - step_size); 71 } 72 assert(IMPLIES(prev_ul != UINT8_MAX, 73 prev_u != UINT8_MAX && prev_l != UINT8_MAX)); 74 75 // Pick CDF index based on number of matching/out-of-bounds segment IDs. 76 if (prev_ul == UINT8_MAX) /* Edge cases */ 77 *cdf_index = 0; 78 else if ((prev_ul == prev_u) && (prev_ul == prev_l)) 79 *cdf_index = 2; 80 else if ((prev_ul == prev_u) || (prev_ul == prev_l) || (prev_u == prev_l)) 81 *cdf_index = 1; 82 else 83 *cdf_index = 0; 84 85 // If 2 or more are identical returns that as predictor, otherwise prev_l. 86 if (prev_u == UINT8_MAX) // edge case 87 return prev_l == UINT8_MAX ? 0 : prev_l; 88 if (prev_l == UINT8_MAX) // edge case 89 return prev_u; 90 return (prev_ul == prev_u) ? prev_u : prev_l; 91 } 92 93 static inline uint8_t av1_get_pred_context_seg_id(const MACROBLOCKD *xd) { 94 const MB_MODE_INFO *const above_mi = xd->above_mbmi; 95 const MB_MODE_INFO *const left_mi = xd->left_mbmi; 96 const int above_sip = (above_mi != NULL) ? above_mi->seg_id_predicted : 0; 97 const int left_sip = (left_mi != NULL) ? left_mi->seg_id_predicted : 0; 98 99 return above_sip + left_sip; 100 } 101 102 static inline int get_comp_index_context(const AV1_COMMON *cm, 103 const MACROBLOCKD *xd) { 104 MB_MODE_INFO *mbmi = xd->mi[0]; 105 const RefCntBuffer *const bck_buf = get_ref_frame_buf(cm, mbmi->ref_frame[0]); 106 const RefCntBuffer *const fwd_buf = get_ref_frame_buf(cm, mbmi->ref_frame[1]); 107 int bck_frame_index = 0, fwd_frame_index = 0; 108 int cur_frame_index = cm->cur_frame->order_hint; 109 110 if (bck_buf != NULL) bck_frame_index = bck_buf->order_hint; 111 if (fwd_buf != NULL) fwd_frame_index = fwd_buf->order_hint; 112 113 int fwd = abs(get_relative_dist(&cm->seq_params->order_hint_info, 114 fwd_frame_index, cur_frame_index)); 115 int bck = abs(get_relative_dist(&cm->seq_params->order_hint_info, 116 cur_frame_index, bck_frame_index)); 117 118 const MB_MODE_INFO *const above_mi = xd->above_mbmi; 119 const MB_MODE_INFO *const left_mi = xd->left_mbmi; 120 121 int above_ctx = 0, left_ctx = 0; 122 const int offset = (fwd == bck); 123 124 if (above_mi != NULL) { 125 if (has_second_ref(above_mi)) 126 above_ctx = above_mi->compound_idx; 127 else if (above_mi->ref_frame[0] == ALTREF_FRAME) 128 above_ctx = 1; 129 } 130 131 if (left_mi != NULL) { 132 if (has_second_ref(left_mi)) 133 left_ctx = left_mi->compound_idx; 134 else if (left_mi->ref_frame[0] == ALTREF_FRAME) 135 left_ctx = 1; 136 } 137 138 return above_ctx + left_ctx + 3 * offset; 139 } 140 141 static inline int get_comp_group_idx_context(const MACROBLOCKD *xd) { 142 const MB_MODE_INFO *const above_mi = xd->above_mbmi; 143 const MB_MODE_INFO *const left_mi = xd->left_mbmi; 144 int above_ctx = 0, left_ctx = 0; 145 146 if (above_mi) { 147 if (has_second_ref(above_mi)) 148 above_ctx = above_mi->comp_group_idx; 149 else if (above_mi->ref_frame[0] == ALTREF_FRAME) 150 above_ctx = 3; 151 } 152 if (left_mi) { 153 if (has_second_ref(left_mi)) 154 left_ctx = left_mi->comp_group_idx; 155 else if (left_mi->ref_frame[0] == ALTREF_FRAME) 156 left_ctx = 3; 157 } 158 159 return AOMMIN(5, above_ctx + left_ctx); 160 } 161 162 static inline aom_cdf_prob *av1_get_pred_cdf_seg_id( 163 struct segmentation_probs *segp, const MACROBLOCKD *xd) { 164 return segp->pred_cdf[av1_get_pred_context_seg_id(xd)]; 165 } 166 167 static inline int av1_get_skip_mode_context(const MACROBLOCKD *xd) { 168 const MB_MODE_INFO *const above_mi = xd->above_mbmi; 169 const MB_MODE_INFO *const left_mi = xd->left_mbmi; 170 const int above_skip_mode = above_mi ? above_mi->skip_mode : 0; 171 const int left_skip_mode = left_mi ? left_mi->skip_mode : 0; 172 return above_skip_mode + left_skip_mode; 173 } 174 175 static inline int av1_get_skip_txfm_context(const MACROBLOCKD *xd) { 176 const MB_MODE_INFO *const above_mi = xd->above_mbmi; 177 const MB_MODE_INFO *const left_mi = xd->left_mbmi; 178 const int above_skip_txfm = above_mi ? above_mi->skip_txfm : 0; 179 const int left_skip_txfm = left_mi ? left_mi->skip_txfm : 0; 180 return above_skip_txfm + left_skip_txfm; 181 } 182 183 int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir); 184 185 // Get a list of palette base colors that are used in the above and left blocks, 186 // referred to as "color cache". The return value is the number of colors in the 187 // cache (<= 2 * PALETTE_MAX_SIZE). The color values are stored in "cache" 188 // in ascending order. 189 int av1_get_palette_cache(const MACROBLOCKD *const xd, int plane, 190 uint16_t *cache); 191 192 static inline int av1_get_palette_bsize_ctx(BLOCK_SIZE bsize) { 193 assert(bsize < BLOCK_SIZES_ALL); 194 return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_8X8]; 195 } 196 197 static inline int av1_get_palette_mode_ctx(const MACROBLOCKD *xd) { 198 const MB_MODE_INFO *const above_mi = xd->above_mbmi; 199 const MB_MODE_INFO *const left_mi = xd->left_mbmi; 200 int ctx = 0; 201 if (above_mi) ctx += (above_mi->palette_mode_info.palette_size[0] > 0); 202 if (left_mi) ctx += (left_mi->palette_mode_info.palette_size[0] > 0); 203 return ctx; 204 } 205 206 int av1_get_intra_inter_context(const MACROBLOCKD *xd); 207 208 int av1_get_reference_mode_context(const MACROBLOCKD *xd); 209 210 static inline aom_cdf_prob *av1_get_reference_mode_cdf(const MACROBLOCKD *xd) { 211 return xd->tile_ctx->comp_inter_cdf[av1_get_reference_mode_context(xd)]; 212 } 213 214 static inline aom_cdf_prob *av1_get_skip_txfm_cdf(const MACROBLOCKD *xd) { 215 return xd->tile_ctx->skip_txfm_cdfs[av1_get_skip_txfm_context(xd)]; 216 } 217 218 int av1_get_comp_reference_type_context(const MACROBLOCKD *xd); 219 220 // == Uni-directional contexts == 221 222 int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd); 223 224 int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd); 225 226 int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd); 227 228 static inline aom_cdf_prob *av1_get_comp_reference_type_cdf( 229 const MACROBLOCKD *xd) { 230 const int pred_context = av1_get_comp_reference_type_context(xd); 231 return xd->tile_ctx->comp_ref_type_cdf[pred_context]; 232 } 233 234 static inline aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p( 235 const MACROBLOCKD *xd) { 236 const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd); 237 return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0]; 238 } 239 240 static inline aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p1( 241 const MACROBLOCKD *xd) { 242 const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd); 243 return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1]; 244 } 245 246 static inline aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p2( 247 const MACROBLOCKD *xd) { 248 const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd); 249 return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2]; 250 } 251 252 // == Bi-directional contexts == 253 254 int av1_get_pred_context_comp_ref_p(const MACROBLOCKD *xd); 255 256 int av1_get_pred_context_comp_ref_p1(const MACROBLOCKD *xd); 257 258 int av1_get_pred_context_comp_ref_p2(const MACROBLOCKD *xd); 259 260 int av1_get_pred_context_comp_bwdref_p(const MACROBLOCKD *xd); 261 262 int av1_get_pred_context_comp_bwdref_p1(const MACROBLOCKD *xd); 263 264 static inline aom_cdf_prob *av1_get_pred_cdf_comp_ref_p(const MACROBLOCKD *xd) { 265 const int pred_context = av1_get_pred_context_comp_ref_p(xd); 266 return xd->tile_ctx->comp_ref_cdf[pred_context][0]; 267 } 268 269 static inline aom_cdf_prob *av1_get_pred_cdf_comp_ref_p1( 270 const MACROBLOCKD *xd) { 271 const int pred_context = av1_get_pred_context_comp_ref_p1(xd); 272 return xd->tile_ctx->comp_ref_cdf[pred_context][1]; 273 } 274 275 static inline aom_cdf_prob *av1_get_pred_cdf_comp_ref_p2( 276 const MACROBLOCKD *xd) { 277 const int pred_context = av1_get_pred_context_comp_ref_p2(xd); 278 return xd->tile_ctx->comp_ref_cdf[pred_context][2]; 279 } 280 281 static inline aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p( 282 const MACROBLOCKD *xd) { 283 const int pred_context = av1_get_pred_context_comp_bwdref_p(xd); 284 return xd->tile_ctx->comp_bwdref_cdf[pred_context][0]; 285 } 286 287 static inline aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p1( 288 const MACROBLOCKD *xd) { 289 const int pred_context = av1_get_pred_context_comp_bwdref_p1(xd); 290 return xd->tile_ctx->comp_bwdref_cdf[pred_context][1]; 291 } 292 293 // == Single contexts == 294 295 int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd); 296 297 int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd); 298 299 int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd); 300 301 int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd); 302 303 int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd); 304 305 int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd); 306 307 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p1( 308 const MACROBLOCKD *xd) { 309 return xd->tile_ctx 310 ->single_ref_cdf[av1_get_pred_context_single_ref_p1(xd)][0]; 311 } 312 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p2( 313 const MACROBLOCKD *xd) { 314 return xd->tile_ctx 315 ->single_ref_cdf[av1_get_pred_context_single_ref_p2(xd)][1]; 316 } 317 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p3( 318 const MACROBLOCKD *xd) { 319 return xd->tile_ctx 320 ->single_ref_cdf[av1_get_pred_context_single_ref_p3(xd)][2]; 321 } 322 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p4( 323 const MACROBLOCKD *xd) { 324 return xd->tile_ctx 325 ->single_ref_cdf[av1_get_pred_context_single_ref_p4(xd)][3]; 326 } 327 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p5( 328 const MACROBLOCKD *xd) { 329 return xd->tile_ctx 330 ->single_ref_cdf[av1_get_pred_context_single_ref_p5(xd)][4]; 331 } 332 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p6( 333 const MACROBLOCKD *xd) { 334 return xd->tile_ctx 335 ->single_ref_cdf[av1_get_pred_context_single_ref_p6(xd)][5]; 336 } 337 338 // Returns a context number for the given MB prediction signal 339 // The mode info data structure has a one element border above and to the 340 // left of the entries corresponding to real blocks. 341 // The prediction flags in these dummy entries are initialized to 0. 342 static inline int get_tx_size_context(const MACROBLOCKD *xd) { 343 const MB_MODE_INFO *mbmi = xd->mi[0]; 344 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 345 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 346 const TX_SIZE max_tx_size = max_txsize_rect_lookup[mbmi->bsize]; 347 const int max_tx_wide = tx_size_wide[max_tx_size]; 348 const int max_tx_high = tx_size_high[max_tx_size]; 349 const int has_above = xd->up_available; 350 const int has_left = xd->left_available; 351 352 int above = xd->above_txfm_context[0] >= max_tx_wide; 353 int left = xd->left_txfm_context[0] >= max_tx_high; 354 355 if (has_above) 356 if (is_inter_block(above_mbmi)) 357 above = block_size_wide[above_mbmi->bsize] >= max_tx_wide; 358 359 if (has_left) 360 if (is_inter_block(left_mbmi)) 361 left = block_size_high[left_mbmi->bsize] >= max_tx_high; 362 363 if (has_above && has_left) 364 return (above + left); 365 else if (has_above) 366 return above; 367 else if (has_left) 368 return left; 369 else 370 return 0; 371 } 372 373 #ifdef __cplusplus 374 } // extern "C" 375 #endif 376 377 #endif // AOM_AV1_COMMON_PRED_COMMON_H_