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 "vp9/common/vp9_common.h" 13 #include "vp9/common/vp9_pred_common.h" 14 #include "vp9/common/vp9_seg_common.h" 15 16 // Returns a context number for the given MB prediction signal vp9_get_pred_context_switchable_interp(const MACROBLOCKD * xd)17int vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) { 18 // Note: 19 // The mode info data structure has a one element border above and to the 20 // left of the entries correpsonding to real macroblocks. 21 // The prediction flags in these dummy entries are initialised to 0. 22 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 23 const int left_type = xd->left_available && is_inter_block(left_mbmi) ? 24 left_mbmi->interp_filter : SWITCHABLE_FILTERS; 25 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 26 const int above_type = xd->up_available && is_inter_block(above_mbmi) ? 27 above_mbmi->interp_filter : SWITCHABLE_FILTERS; 28 29 if (left_type == above_type) 30 return left_type; 31 else if (left_type == SWITCHABLE_FILTERS && above_type != SWITCHABLE_FILTERS) 32 return above_type; 33 else if (left_type != SWITCHABLE_FILTERS && above_type == SWITCHABLE_FILTERS) 34 return left_type; 35 else 36 return SWITCHABLE_FILTERS; 37 } 38 39 // The mode info data structure has a one element border above and to the 40 // left of the entries corresponding to real macroblocks. 41 // The prediction flags in these dummy entries are initialized to 0. 42 // 0 - inter/inter, inter/--, --/inter, --/-- 43 // 1 - intra/inter, inter/intra 44 // 2 - intra/--, --/intra 45 // 3 - intra/intra vp9_get_intra_inter_context(const MACROBLOCKD * xd)46int vp9_get_intra_inter_context(const MACROBLOCKD *xd) { 47 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 48 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 49 const int has_above = xd->up_available; 50 const int has_left = xd->left_available; 51 52 if (has_above && has_left) { // both edges available 53 const int above_intra = !is_inter_block(above_mbmi); 54 const int left_intra = !is_inter_block(left_mbmi); 55 return left_intra && above_intra ? 3 56 : left_intra || above_intra; 57 } else if (has_above || has_left) { // one edge available 58 return 2 * !is_inter_block(has_above ? above_mbmi : left_mbmi); 59 } else { 60 return 0; 61 } 62 } 63 vp9_get_reference_mode_context(const VP9_COMMON * cm,const MACROBLOCKD * xd)64int vp9_get_reference_mode_context(const VP9_COMMON *cm, 65 const MACROBLOCKD *xd) { 66 int ctx; 67 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 68 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 69 const int has_above = xd->up_available; 70 const int has_left = xd->left_available; 71 // Note: 72 // The mode info data structure has a one element border above and to the 73 // left of the entries correpsonding to real macroblocks. 74 // The prediction flags in these dummy entries are initialised to 0. 75 if (has_above && has_left) { // both edges available 76 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) 77 // neither edge uses comp pred (0/1) 78 ctx = (above_mbmi->ref_frame[0] == cm->comp_fixed_ref) ^ 79 (left_mbmi->ref_frame[0] == cm->comp_fixed_ref); 80 else if (!has_second_ref(above_mbmi)) 81 // one of two edges uses comp pred (2/3) 82 ctx = 2 + (above_mbmi->ref_frame[0] == cm->comp_fixed_ref || 83 !is_inter_block(above_mbmi)); 84 else if (!has_second_ref(left_mbmi)) 85 // one of two edges uses comp pred (2/3) 86 ctx = 2 + (left_mbmi->ref_frame[0] == cm->comp_fixed_ref || 87 !is_inter_block(left_mbmi)); 88 else // both edges use comp pred (4) 89 ctx = 4; 90 } else if (has_above || has_left) { // one edge available 91 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi; 92 93 if (!has_second_ref(edge_mbmi)) 94 // edge does not use comp pred (0/1) 95 ctx = edge_mbmi->ref_frame[0] == cm->comp_fixed_ref; 96 else 97 // edge uses comp pred (3) 98 ctx = 3; 99 } else { // no edges available (1) 100 ctx = 1; 101 } 102 assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS); 103 return ctx; 104 } 105 106 // Returns a context number for the given MB prediction signal vp9_get_pred_context_comp_ref_p(const VP9_COMMON * cm,const MACROBLOCKD * xd)107int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, 108 const MACROBLOCKD *xd) { 109 int pred_context; 110 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 111 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 112 const int above_in_image = xd->up_available; 113 const int left_in_image = xd->left_available; 114 115 // Note: 116 // The mode info data structure has a one element border above and to the 117 // left of the entries correpsonding to real macroblocks. 118 // The prediction flags in these dummy entries are initialised to 0. 119 const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; 120 const int var_ref_idx = !fix_ref_idx; 121 122 if (above_in_image && left_in_image) { // both edges available 123 const int above_intra = !is_inter_block(above_mbmi); 124 const int left_intra = !is_inter_block(left_mbmi); 125 126 if (above_intra && left_intra) { // intra/intra (2) 127 pred_context = 2; 128 } else if (above_intra || left_intra) { // intra/inter 129 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi; 130 131 if (!has_second_ref(edge_mbmi)) // single pred (1/3) 132 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]); 133 else // comp pred (1/3) 134 pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx] 135 != cm->comp_var_ref[1]); 136 } else { // inter/inter 137 const int l_sg = !has_second_ref(left_mbmi); 138 const int a_sg = !has_second_ref(above_mbmi); 139 const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0] 140 : above_mbmi->ref_frame[var_ref_idx]; 141 const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0] 142 : left_mbmi->ref_frame[var_ref_idx]; 143 144 if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) { 145 pred_context = 0; 146 } else if (l_sg && a_sg) { // single/single 147 if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) || 148 (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0])) 149 pred_context = 4; 150 else if (vrfa == vrfl) 151 pred_context = 3; 152 else 153 pred_context = 1; 154 } else if (l_sg || a_sg) { // single/comp 155 const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl; 156 const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl; 157 if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1]) 158 pred_context = 1; 159 else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1]) 160 pred_context = 2; 161 else 162 pred_context = 4; 163 } else if (vrfa == vrfl) { // comp/comp 164 pred_context = 4; 165 } else { 166 pred_context = 2; 167 } 168 } 169 } else if (above_in_image || left_in_image) { // one edge available 170 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi; 171 172 if (!is_inter_block(edge_mbmi)) { 173 pred_context = 2; 174 } else { 175 if (has_second_ref(edge_mbmi)) 176 pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] 177 != cm->comp_var_ref[1]); 178 else 179 pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]); 180 } 181 } else { // no edges available (2) 182 pred_context = 2; 183 } 184 assert(pred_context >= 0 && pred_context < REF_CONTEXTS); 185 186 return pred_context; 187 } 188 vp9_get_pred_context_single_ref_p1(const MACROBLOCKD * xd)189int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) { 190 int pred_context; 191 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 192 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 193 const int has_above = xd->up_available; 194 const int has_left = xd->left_available; 195 // Note: 196 // The mode info data structure has a one element border above and to the 197 // left of the entries correpsonding to real macroblocks. 198 // The prediction flags in these dummy entries are initialised to 0. 199 if (has_above && has_left) { // both edges available 200 const int above_intra = !is_inter_block(above_mbmi); 201 const int left_intra = !is_inter_block(left_mbmi); 202 203 if (above_intra && left_intra) { // intra/intra 204 pred_context = 2; 205 } else if (above_intra || left_intra) { // intra/inter or inter/intra 206 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi; 207 if (!has_second_ref(edge_mbmi)) 208 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME); 209 else 210 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME || 211 edge_mbmi->ref_frame[1] == LAST_FRAME); 212 } else { // inter/inter 213 const int above_has_second = has_second_ref(above_mbmi); 214 const int left_has_second = has_second_ref(left_mbmi); 215 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0]; 216 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1]; 217 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0]; 218 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1]; 219 220 if (above_has_second && left_has_second) { 221 pred_context = 1 + (above0 == LAST_FRAME || above1 == LAST_FRAME || 222 left0 == LAST_FRAME || left1 == LAST_FRAME); 223 } else if (above_has_second || left_has_second) { 224 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0; 225 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0; 226 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1; 227 228 if (rfs == LAST_FRAME) 229 pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME); 230 else 231 pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME); 232 } else { 233 pred_context = 2 * (above0 == LAST_FRAME) + 2 * (left0 == LAST_FRAME); 234 } 235 } 236 } else if (has_above || has_left) { // one edge available 237 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi; 238 if (!is_inter_block(edge_mbmi)) { // intra 239 pred_context = 2; 240 } else { // inter 241 if (!has_second_ref(edge_mbmi)) 242 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME); 243 else 244 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME || 245 edge_mbmi->ref_frame[1] == LAST_FRAME); 246 } 247 } else { // no edges available 248 pred_context = 2; 249 } 250 251 assert(pred_context >= 0 && pred_context < REF_CONTEXTS); 252 return pred_context; 253 } 254 vp9_get_pred_context_single_ref_p2(const MACROBLOCKD * xd)255int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) { 256 int pred_context; 257 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi; 258 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi; 259 const int has_above = xd->up_available; 260 const int has_left = xd->left_available; 261 262 // Note: 263 // The mode info data structure has a one element border above and to the 264 // left of the entries correpsonding to real macroblocks. 265 // The prediction flags in these dummy entries are initialised to 0. 266 if (has_above && has_left) { // both edges available 267 const int above_intra = !is_inter_block(above_mbmi); 268 const int left_intra = !is_inter_block(left_mbmi); 269 270 if (above_intra && left_intra) { // intra/intra 271 pred_context = 2; 272 } else if (above_intra || left_intra) { // intra/inter or inter/intra 273 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi; 274 if (!has_second_ref(edge_mbmi)) { 275 if (edge_mbmi->ref_frame[0] == LAST_FRAME) 276 pred_context = 3; 277 else 278 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME); 279 } else { 280 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME || 281 edge_mbmi->ref_frame[1] == GOLDEN_FRAME); 282 } 283 } else { // inter/inter 284 const int above_has_second = has_second_ref(above_mbmi); 285 const int left_has_second = has_second_ref(left_mbmi); 286 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0]; 287 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1]; 288 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0]; 289 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1]; 290 291 if (above_has_second && left_has_second) { 292 if (above0 == left0 && above1 == left1) 293 pred_context = 3 * (above0 == GOLDEN_FRAME || 294 above1 == GOLDEN_FRAME || 295 left0 == GOLDEN_FRAME || 296 left1 == GOLDEN_FRAME); 297 else 298 pred_context = 2; 299 } else if (above_has_second || left_has_second) { 300 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0; 301 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0; 302 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1; 303 304 if (rfs == GOLDEN_FRAME) 305 pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); 306 else if (rfs == ALTREF_FRAME) 307 pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME; 308 else 309 pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); 310 } else { 311 if (above0 == LAST_FRAME && left0 == LAST_FRAME) { 312 pred_context = 3; 313 } else if (above0 == LAST_FRAME || left0 == LAST_FRAME) { 314 const MV_REFERENCE_FRAME edge0 = (above0 == LAST_FRAME) ? left0 315 : above0; 316 pred_context = 4 * (edge0 == GOLDEN_FRAME); 317 } else { 318 pred_context = 2 * (above0 == GOLDEN_FRAME) + 319 2 * (left0 == GOLDEN_FRAME); 320 } 321 } 322 } 323 } else if (has_above || has_left) { // one edge available 324 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi; 325 326 if (!is_inter_block(edge_mbmi) || 327 (edge_mbmi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mbmi))) 328 pred_context = 2; 329 else if (!has_second_ref(edge_mbmi)) 330 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME); 331 else 332 pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME || 333 edge_mbmi->ref_frame[1] == GOLDEN_FRAME); 334 } else { // no edges available (2) 335 pred_context = 2; 336 } 337 assert(pred_context >= 0 && pred_context < REF_CONTEXTS); 338 return pred_context; 339 } 340