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