1 2/* 3 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 4 * 5 * Use of this source code is governed by a BSD-style license 6 * that can be found in the LICENSE file in the root of the source 7 * tree. An additional intellectual property rights grant can be found 8 * in the file PATENTS. All contributing project authors may 9 * be found in the AUTHORS file in the root of the source tree. 10 */ 11 12#include <limits.h> 13 14#include "vp9/common/vp9_common.h" 15#include "vp9/common/vp9_pred_common.h" 16#include "vp9/common/vp9_seg_common.h" 17#include "vp9/common/vp9_treecoder.h" 18 19static INLINE const MB_MODE_INFO *get_above_mbmi(const MODE_INFO *const above) { 20 return (above != NULL) ? &above->mbmi : NULL; 21} 22 23static INLINE const MB_MODE_INFO *get_left_mbmi(const MODE_INFO *const left) { 24 return (left != NULL) ? &left->mbmi : NULL; 25} 26 27// Returns a context number for the given MB prediction signal 28unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) { 29 const MODE_INFO *const above_mi = get_above_mi(xd); 30 const MODE_INFO *const left_mi = get_left_mi(xd); 31 const int above_in_image = above_mi != NULL; 32 const int left_in_image = left_mi != NULL; 33 // Note: 34 // The mode info data structure has a one element border above and to the 35 // left of the entries correpsonding to real macroblocks. 36 // The prediction flags in these dummy entries are initialised to 0. 37 // left 38 const int left_mv_pred = left_in_image ? is_inter_block(&left_mi->mbmi) 39 : 0; 40 const int left_interp = left_in_image && left_mv_pred 41 ? left_mi->mbmi.interp_filter 42 : SWITCHABLE_FILTERS; 43 44 // above 45 const int above_mv_pred = above_in_image ? is_inter_block(&above_mi->mbmi) 46 : 0; 47 const int above_interp = above_in_image && above_mv_pred 48 ? above_mi->mbmi.interp_filter 49 : SWITCHABLE_FILTERS; 50 51 if (left_interp == above_interp) 52 return left_interp; 53 else if (left_interp == SWITCHABLE_FILTERS && 54 above_interp != SWITCHABLE_FILTERS) 55 return above_interp; 56 else if (left_interp != SWITCHABLE_FILTERS && 57 above_interp == SWITCHABLE_FILTERS) 58 return left_interp; 59 else 60 return SWITCHABLE_FILTERS; 61} 62// Returns a context number for the given MB prediction signal 63unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) { 64 const MODE_INFO *const above_mi = get_above_mi(xd); 65 const MODE_INFO *const left_mi = get_left_mi(xd); 66 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); 67 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); 68 const int above_in_image = above_mi != NULL; 69 const int left_in_image = left_mi != NULL; 70 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; 71 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; 72 73 // The mode info data structure has a one element border above and to the 74 // left of the entries corresponding to real macroblocks. 75 // The prediction flags in these dummy entries are initialized to 0. 76 // 0 - inter/inter, inter/--, --/inter, --/-- 77 // 1 - intra/inter, inter/intra 78 // 2 - intra/--, --/intra 79 // 3 - intra/intra 80 if (above_in_image && left_in_image) // both edges available 81 return left_intra && above_intra ? 3 82 : left_intra || above_intra; 83 else if (above_in_image || left_in_image) // one edge available 84 return 2 * (above_in_image ? above_intra : left_intra); 85 else 86 return 0; 87} 88// Returns a context number for the given MB prediction signal 89unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm, 90 const MACROBLOCKD *xd) { 91 int pred_context; 92 const MODE_INFO *const above_mi = get_above_mi(xd); 93 const MODE_INFO *const left_mi = get_left_mi(xd); 94 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); 95 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); 96 const int above_in_image = above_mi != NULL; 97 const int left_in_image = left_mi != NULL; 98 // Note: 99 // The mode info data structure has a one element border above and to the 100 // left of the entries correpsonding to real macroblocks. 101 // The prediction flags in these dummy entries are initialised to 0. 102 if (above_in_image && left_in_image) { // both edges available 103 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) 104 // neither edge uses comp pred (0/1) 105 pred_context = (above_mbmi->ref_frame[0] == cm->comp_fixed_ref) ^ 106 (left_mbmi->ref_frame[0] == cm->comp_fixed_ref); 107 else if (!has_second_ref(above_mbmi)) 108 // one of two edges uses comp pred (2/3) 109 pred_context = 2 + (above_mbmi->ref_frame[0] == cm->comp_fixed_ref || 110 !is_inter_block(above_mbmi)); 111 else if (!has_second_ref(left_mbmi)) 112 // one of two edges uses comp pred (2/3) 113 pred_context = 2 + (left_mbmi->ref_frame[0] == cm->comp_fixed_ref || 114 !is_inter_block(left_mbmi)); 115 else // both edges use comp pred (4) 116 pred_context = 4; 117 } else if (above_in_image || left_in_image) { // one edge available 118 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi; 119 120 if (!has_second_ref(edge_mbmi)) 121 // edge does not use comp pred (0/1) 122 pred_context = edge_mbmi->ref_frame[0] == cm->comp_fixed_ref; 123 else 124 // edge uses comp pred (3) 125 pred_context = 3; 126 } else { // no edges available (1) 127 pred_context = 1; 128 } 129 assert(pred_context >= 0 && pred_context < COMP_INTER_CONTEXTS); 130 return pred_context; 131} 132 133// Returns a context number for the given MB prediction signal 134unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, 135 const MACROBLOCKD *xd) { 136 int pred_context; 137 const MODE_INFO *const above_mi = get_above_mi(xd); 138 const MODE_INFO *const left_mi = get_left_mi(xd); 139 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); 140 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); 141 const int above_in_image = above_mi != NULL; 142 const int left_in_image = left_mi != NULL; 143 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; 144 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; 145 // Note: 146 // The mode info data structure has a one element border above and to the 147 // left of the entries correpsonding to real macroblocks. 148 // The prediction flags in these dummy entries are initialised to 0. 149 const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; 150 const int var_ref_idx = !fix_ref_idx; 151 152 if (above_in_image && left_in_image) { // both edges available 153 if (above_intra && left_intra) { // intra/intra (2) 154 pred_context = 2; 155 } else if (above_intra || left_intra) { // intra/inter 156 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi; 157 158 if (!has_second_ref(edge_mbmi)) // single pred (1/3) 159 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]); 160 else // comp pred (1/3) 161 pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx] 162 != cm->comp_var_ref[1]); 163 } else { // inter/inter 164 const int l_sg = !has_second_ref(left_mbmi); 165 const int a_sg = !has_second_ref(above_mbmi); 166 MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0] 167 : above_mbmi->ref_frame[var_ref_idx]; 168 MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0] 169 : left_mbmi->ref_frame[var_ref_idx]; 170 171 if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) { 172 pred_context = 0; 173 } else if (l_sg && a_sg) { // single/single 174 if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) || 175 (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0])) 176 pred_context = 4; 177 else if (vrfa == vrfl) 178 pred_context = 3; 179 else 180 pred_context = 1; 181 } else if (l_sg || a_sg) { // single/comp 182 MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl; 183 MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl; 184 if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1]) 185 pred_context = 1; 186 else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1]) 187 pred_context = 2; 188 else 189 pred_context = 4; 190 } else if (vrfa == vrfl) { // comp/comp 191 pred_context = 4; 192 } else { 193 pred_context = 2; 194 } 195 } 196 } else if (above_in_image || left_in_image) { // one edge available 197 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi; 198 199 if (!is_inter_block(edge_mbmi)) { 200 pred_context = 2; 201 } else { 202 if (has_second_ref(edge_mbmi)) 203 pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] 204 != cm->comp_var_ref[1]); 205 else 206 pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]); 207 } 208 } else { // no edges available (2) 209 pred_context = 2; 210 } 211 assert(pred_context >= 0 && pred_context < REF_CONTEXTS); 212 213 return pred_context; 214} 215unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) { 216 int pred_context; 217 const MODE_INFO *const above_mi = get_above_mi(xd); 218 const MODE_INFO *const left_mi = get_left_mi(xd); 219 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); 220 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); 221 const int above_in_image = above_mi != NULL; 222 const int left_in_image = left_mi != NULL; 223 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; 224 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; 225 // Note: 226 // The mode info data structure has a one element border above and to the 227 // left of the entries correpsonding to real macroblocks. 228 // The prediction flags in these dummy entries are initialised to 0. 229 if (above_in_image && left_in_image) { // both edges available 230 if (above_intra && left_intra) { // intra/intra 231 pred_context = 2; 232 } else if (above_intra || left_intra) { // intra/inter or inter/intra 233 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi; 234 if (!has_second_ref(edge_mbmi)) 235 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME); 236 else 237 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME || 238 edge_mbmi->ref_frame[1] == LAST_FRAME); 239 } else { // inter/inter 240 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) { 241 pred_context = 2 * (above_mbmi->ref_frame[0] == LAST_FRAME) + 242 2 * (left_mbmi->ref_frame[0] == LAST_FRAME); 243 } else if (has_second_ref(above_mbmi) && has_second_ref(left_mbmi)) { 244 pred_context = 1 + (above_mbmi->ref_frame[0] == LAST_FRAME || 245 above_mbmi->ref_frame[1] == LAST_FRAME || 246 left_mbmi->ref_frame[0] == LAST_FRAME || 247 left_mbmi->ref_frame[1] == LAST_FRAME); 248 } else { 249 const MV_REFERENCE_FRAME rfs = !has_second_ref(above_mbmi) ? 250 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0]; 251 const MV_REFERENCE_FRAME crf1 = has_second_ref(above_mbmi) ? 252 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0]; 253 const MV_REFERENCE_FRAME crf2 = has_second_ref(above_mbmi) ? 254 above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1]; 255 256 if (rfs == LAST_FRAME) 257 pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME); 258 else 259 pred_context = crf1 == LAST_FRAME || crf2 == LAST_FRAME; 260 } 261 } 262 } else if (above_in_image || left_in_image) { // one edge available 263 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi; 264 if (!is_inter_block(edge_mbmi)) { // intra 265 pred_context = 2; 266 } else { // inter 267 if (!has_second_ref(edge_mbmi)) 268 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME); 269 else 270 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME || 271 edge_mbmi->ref_frame[1] == LAST_FRAME); 272 } 273 } else { // no edges available 274 pred_context = 2; 275 } 276 277 assert(pred_context >= 0 && pred_context < REF_CONTEXTS); 278 return pred_context; 279} 280 281unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) { 282 int pred_context; 283 const MODE_INFO *const above_mi = get_above_mi(xd); 284 const MODE_INFO *const left_mi = get_left_mi(xd); 285 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); 286 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); 287 const int above_in_image = above_mi != NULL; 288 const int left_in_image = left_mi != NULL; 289 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; 290 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; 291 292 // Note: 293 // The mode info data structure has a one element border above and to the 294 // left of the entries correpsonding to real macroblocks. 295 // The prediction flags in these dummy entries are initialised to 0. 296 if (above_in_image && left_in_image) { // both edges available 297 if (above_intra && left_intra) { // intra/intra 298 pred_context = 2; 299 } else if (above_intra || left_intra) { // intra/inter or inter/intra 300 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi; 301 if (!has_second_ref(edge_mbmi)) { 302 if (edge_mbmi->ref_frame[0] == LAST_FRAME) 303 pred_context = 3; 304 else 305 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME); 306 } else { 307 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME || 308 edge_mbmi->ref_frame[1] == GOLDEN_FRAME); 309 } 310 } else { // inter/inter 311 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) { 312 if (above_mbmi->ref_frame[0] == LAST_FRAME && 313 left_mbmi->ref_frame[0] == LAST_FRAME) { 314 pred_context = 3; 315 } else if (above_mbmi->ref_frame[0] == LAST_FRAME || 316 left_mbmi->ref_frame[0] == LAST_FRAME) { 317 const MB_MODE_INFO *edge_mbmi = 318 above_mbmi->ref_frame[0] == LAST_FRAME ? left_mbmi : above_mbmi; 319 320 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME); 321 } else { 322 pred_context = 2 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME) + 323 2 * (left_mbmi->ref_frame[0] == GOLDEN_FRAME); 324 } 325 } else if (has_second_ref(above_mbmi) && has_second_ref(left_mbmi)) { 326 if (above_mbmi->ref_frame[0] == left_mbmi->ref_frame[0] && 327 above_mbmi->ref_frame[1] == left_mbmi->ref_frame[1]) 328 pred_context = 3 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME || 329 above_mbmi->ref_frame[1] == GOLDEN_FRAME || 330 left_mbmi->ref_frame[0] == GOLDEN_FRAME || 331 left_mbmi->ref_frame[1] == GOLDEN_FRAME); 332 else 333 pred_context = 2; 334 } else { 335 const MV_REFERENCE_FRAME rfs = !has_second_ref(above_mbmi) ? 336 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0]; 337 const MV_REFERENCE_FRAME crf1 = has_second_ref(above_mbmi) ? 338 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0]; 339 const MV_REFERENCE_FRAME crf2 = has_second_ref(above_mbmi) ? 340 above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1]; 341 342 if (rfs == GOLDEN_FRAME) 343 pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); 344 else if (rfs == ALTREF_FRAME) 345 pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME; 346 else 347 pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); 348 } 349 } 350 } else if (above_in_image || left_in_image) { // one edge available 351 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi; 352 353 if (!is_inter_block(edge_mbmi) || 354 (edge_mbmi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mbmi))) 355 pred_context = 2; 356 else if (!has_second_ref(edge_mbmi)) 357 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME); 358 else 359 pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME || 360 edge_mbmi->ref_frame[1] == GOLDEN_FRAME); 361 } else { // no edges available (2) 362 pred_context = 2; 363 } 364 assert(pred_context >= 0 && pred_context < REF_CONTEXTS); 365 return pred_context; 366} 367// Returns a context number for the given MB prediction signal 368// The mode info data structure has a one element border above and to the 369// left of the entries corresponding to real blocks. 370// The prediction flags in these dummy entries are initialized to 0. 371unsigned char vp9_get_pred_context_tx_size(const MACROBLOCKD *xd) { 372 const MODE_INFO *const above_mi = get_above_mi(xd); 373 const MODE_INFO *const left_mi = get_left_mi(xd); 374 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); 375 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); 376 const int above_in_image = above_mi != NULL; 377 const int left_in_image = left_mi != NULL; 378 const int max_tx_size = max_txsize_lookup[xd->mi_8x8[0]->mbmi.sb_type]; 379 int above_context = max_tx_size; 380 int left_context = max_tx_size; 381 382 if (above_in_image) 383 above_context = above_mbmi->skip_coeff ? max_tx_size 384 : above_mbmi->tx_size; 385 386 if (left_in_image) 387 left_context = left_mbmi->skip_coeff ? max_tx_size 388 : left_mbmi->tx_size; 389 390 if (!left_in_image) 391 left_context = above_context; 392 393 if (!above_in_image) 394 above_context = left_context; 395 396 return above_context + left_context > max_tx_size; 397} 398 399void vp9_set_pred_flag_seg_id(MACROBLOCKD *xd, uint8_t pred_flag) { 400 xd->mi_8x8[0]->mbmi.seg_id_predicted = pred_flag; 401} 402 403int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids, 404 BLOCK_SIZE bsize, int mi_row, int mi_col) { 405 const int mi_offset = mi_row * cm->mi_cols + mi_col; 406 const int bw = num_8x8_blocks_wide_lookup[bsize]; 407 const int bh = num_8x8_blocks_high_lookup[bsize]; 408 const int xmis = MIN(cm->mi_cols - mi_col, bw); 409 const int ymis = MIN(cm->mi_rows - mi_row, bh); 410 int x, y, segment_id = INT_MAX; 411 412 for (y = 0; y < ymis; y++) 413 for (x = 0; x < xmis; x++) 414 segment_id = MIN(segment_id, 415 segment_ids[mi_offset + y * cm->mi_cols + x]); 416 417 assert(segment_id >= 0 && segment_id < MAX_SEGMENTS); 418 return segment_id; 419} 420