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