blob: 51c343d19aefa05b385ee14b8b51ffed86ec346a [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xubde4ac82016-11-28 15:26:06 -08002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xubde4ac82016-11-28 15:26:06 -08004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include "av1/common/common.h"
13#include "av1/common/pred_common.h"
14#include "av1/common/reconinter.h"
hui su0c628e62016-11-30 15:20:48 -080015#if CONFIG_EXT_INTRA
16#include "av1/common/reconintra.h"
17#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070018#include "av1/common/seg_common.h"
19
20// Returns a context number for the given MB prediction signal
21#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070022static InterpFilter get_ref_filter_type(const MODE_INFO *mi,
23 const MACROBLOCKD *xd, int dir,
24 MV_REFERENCE_FRAME ref_frame) {
25 InterpFilter ref_type = SWITCHABLE_FILTERS;
Yaowu Xuc27fc142016-08-22 16:08:15 -070026 const MB_MODE_INFO *ref_mbmi = &mi->mbmi;
27 int use_subpel[2] = {
28 has_subpel_mv_component(mi, xd, dir),
29 has_subpel_mv_component(mi, xd, dir + 2),
30 };
31
32 if (ref_mbmi->ref_frame[0] == ref_frame && use_subpel[0])
33 ref_type = ref_mbmi->interp_filter[(dir & 0x01)];
34 else if (ref_mbmi->ref_frame[1] == ref_frame && use_subpel[1])
35 ref_type = ref_mbmi->interp_filter[(dir & 0x01) + 2];
36
37 return ref_type;
38}
39
Yaowu Xuf883b422016-08-30 14:01:10 -070040int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070041 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
42 const int ctx_offset =
43 (mbmi->ref_frame[1] > INTRA_FRAME) * INTER_FILTER_COMP_OFFSET;
44 MV_REFERENCE_FRAME ref_frame =
45 (dir < 2) ? mbmi->ref_frame[0] : mbmi->ref_frame[1];
46 // Note:
47 // The mode info data structure has a one element border above and to the
48 // left of the entries corresponding to real macroblocks.
49 // The prediction flags in these dummy entries are initialized to 0.
50 int filter_type_ctx = ctx_offset + (dir & 0x01) * INTER_FILTER_DIR_OFFSET;
51 int left_type = SWITCHABLE_FILTERS;
52 int above_type = SWITCHABLE_FILTERS;
53
54 if (xd->left_available)
55 left_type = get_ref_filter_type(xd->mi[-1], xd, dir, ref_frame);
56
57 if (xd->up_available)
58 above_type =
59 get_ref_filter_type(xd->mi[-xd->mi_stride], xd, dir, ref_frame);
60
Urvang Joshie06132e2017-02-17 15:36:03 -080061 if (left_type == above_type) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070062 filter_type_ctx += left_type;
Urvang Joshie06132e2017-02-17 15:36:03 -080063 } else if (left_type == SWITCHABLE_FILTERS) {
64 assert(above_type != SWITCHABLE_FILTERS);
Yaowu Xuc27fc142016-08-22 16:08:15 -070065 filter_type_ctx += above_type;
Urvang Joshie06132e2017-02-17 15:36:03 -080066 } else if (above_type == SWITCHABLE_FILTERS) {
67 assert(left_type != SWITCHABLE_FILTERS);
Yaowu Xuc27fc142016-08-22 16:08:15 -070068 filter_type_ctx += left_type;
Urvang Joshie06132e2017-02-17 15:36:03 -080069 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070070 filter_type_ctx += SWITCHABLE_FILTERS;
Urvang Joshie06132e2017-02-17 15:36:03 -080071 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070072
73 return filter_type_ctx;
74}
75#else
Yaowu Xuf883b422016-08-30 14:01:10 -070076int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070077 // Note:
78 // The mode info data structure has a one element border above and to the
79 // left of the entries corresponding to real macroblocks.
80 // The prediction flags in these dummy entries are initialized to 0.
81 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
82 const int left_type = xd->left_available && is_inter_block(left_mbmi)
83 ? left_mbmi->interp_filter
84 : SWITCHABLE_FILTERS;
85 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
86 const int above_type = xd->up_available && is_inter_block(above_mbmi)
87 ? above_mbmi->interp_filter
88 : SWITCHABLE_FILTERS;
89
Urvang Joshie06132e2017-02-17 15:36:03 -080090 if (left_type == above_type) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 return left_type;
Urvang Joshie06132e2017-02-17 15:36:03 -080092 } else if (left_type == SWITCHABLE_FILTERS) {
93 assert(above_type != SWITCHABLE_FILTERS);
Yaowu Xuc27fc142016-08-22 16:08:15 -070094 return above_type;
Urvang Joshie06132e2017-02-17 15:36:03 -080095 } else if (above_type == SWITCHABLE_FILTERS) {
96 assert(left_type != SWITCHABLE_FILTERS);
Yaowu Xuc27fc142016-08-22 16:08:15 -070097 return left_type;
Urvang Joshie06132e2017-02-17 15:36:03 -080098 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070099 return SWITCHABLE_FILTERS;
Urvang Joshie06132e2017-02-17 15:36:03 -0800100 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700101}
102#endif
103
104#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -0800105#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -0700106// Obtain the reference filter type from the above/left neighbor blocks.
107static INTRA_FILTER get_ref_intra_filter(const MB_MODE_INFO *ref_mbmi) {
108 INTRA_FILTER ref_type = INTRA_FILTERS;
109
110 if (ref_mbmi->sb_type >= BLOCK_8X8) {
hui su0a6731f2017-04-26 15:23:47 -0700111 const PREDICTION_MODE mode = ref_mbmi->mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700112 if (is_inter_block(ref_mbmi)) {
113#if CONFIG_DUAL_FILTER
114 switch (ref_mbmi->interp_filter[0]) {
115#else
116 switch (ref_mbmi->interp_filter) {
117#endif
118 case EIGHTTAP_REGULAR: ref_type = INTRA_FILTER_8TAP; break;
119 case EIGHTTAP_SMOOTH: ref_type = INTRA_FILTER_8TAP_SMOOTH; break;
120 case MULTITAP_SHARP: ref_type = INTRA_FILTER_8TAP_SHARP; break;
121 case BILINEAR: ref_type = INTRA_FILTERS; break;
122 default: break;
123 }
124 } else {
hui su0c628e62016-11-30 15:20:48 -0800125 if (av1_is_directional_mode(mode, ref_mbmi->sb_type)) {
hui su0a6731f2017-04-26 15:23:47 -0700126 const int p_angle =
127 mode_to_angle_map[mode] + ref_mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -0700128 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700129 ref_type = ref_mbmi->intra_filter;
130 }
131 }
132 }
133 }
134 return ref_type;
135}
136
Yaowu Xuf883b422016-08-30 14:01:10 -0700137int av1_get_pred_context_intra_interp(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138 int left_type = INTRA_FILTERS, above_type = INTRA_FILTERS;
139
140 if (xd->left_available) left_type = get_ref_intra_filter(xd->left_mbmi);
141
142 if (xd->up_available) above_type = get_ref_intra_filter(xd->above_mbmi);
143
144 if (left_type == above_type)
145 return left_type;
146 else if (left_type == INTRA_FILTERS && above_type != INTRA_FILTERS)
147 return above_type;
148 else if (left_type != INTRA_FILTERS && above_type == INTRA_FILTERS)
149 return left_type;
150 else
151 return INTRA_FILTERS;
152}
hui sueda3d762016-12-06 16:58:23 -0800153#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154#endif // CONFIG_EXT_INTRA
155
hui su33567b22017-04-30 16:40:19 -0700156#if CONFIG_PALETTE && CONFIG_PALETTE_DELTA_ENCODING
157int av1_get_palette_cache(const MODE_INFO *above_mi, const MODE_INFO *left_mi,
158 int plane, uint16_t *cache) {
159 int above_n = 0, left_n = 0;
160 if (above_mi)
161 above_n = above_mi->mbmi.palette_mode_info.palette_size[plane != 0];
162 if (left_mi)
163 left_n = left_mi->mbmi.palette_mode_info.palette_size[plane != 0];
164 if (above_n == 0 && left_n == 0) return 0;
165 int above_idx = plane * PALETTE_MAX_SIZE;
166 int left_idx = plane * PALETTE_MAX_SIZE;
167 int n = 0;
hui su33567b22017-04-30 16:40:19 -0700168 const uint16_t *above_colors =
169 above_mi->mbmi.palette_mode_info.palette_colors;
170 const uint16_t *left_colors = left_mi->mbmi.palette_mode_info.palette_colors;
hui su33567b22017-04-30 16:40:19 -0700171 // Merge the sorted lists of base colors from above and left to get
172 // combined sorted color cache.
173 while (above_n > 0 && left_n > 0) {
174 uint16_t v_above = above_colors[above_idx];
175 uint16_t v_left = left_colors[left_idx];
176 if (v_left < v_above) {
177 if (n == 0 || v_left != cache[n - 1]) cache[n++] = v_left;
178 ++left_idx, --left_n;
179 } else {
180 if (n == 0 || v_above != cache[n - 1]) cache[n++] = v_above;
181 ++above_idx, --above_n;
182 if (v_left == v_above) ++left_idx, --left_n;
183 }
184 }
185 while (above_n-- > 0) {
186 uint16_t val = above_colors[above_idx++];
187 if (n == 0 || val != cache[n - 1]) cache[n++] = val;
188 }
189 while (left_n-- > 0) {
190 uint16_t val = left_colors[left_idx++];
191 if (n == 0 || val != cache[n - 1]) cache[n++] = val;
192 }
193 assert(n <= 2 * PALETTE_MAX_SIZE);
194 return n;
195}
196#endif // CONFIG_PALETTE && CONFIG_PALETTE_DELTA_ENCODING
197
Yaowu Xuc27fc142016-08-22 16:08:15 -0700198// The mode info data structure has a one element border above and to the
199// left of the entries corresponding to real macroblocks.
200// The prediction flags in these dummy entries are initialized to 0.
201// 0 - inter/inter, inter/--, --/inter, --/--
202// 1 - intra/inter, inter/intra
203// 2 - intra/--, --/intra
204// 3 - intra/intra
Yaowu Xuf883b422016-08-30 14:01:10 -0700205int av1_get_intra_inter_context(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700206 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
207 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
208 const int has_above = xd->up_available;
209 const int has_left = xd->left_available;
210
211 if (has_above && has_left) { // both edges available
212 const int above_intra = !is_inter_block(above_mbmi);
213 const int left_intra = !is_inter_block(left_mbmi);
214 return left_intra && above_intra ? 3 : left_intra || above_intra;
215 } else if (has_above || has_left) { // one edge available
216 return 2 * !is_inter_block(has_above ? above_mbmi : left_mbmi);
217 } else {
218 return 0;
219 }
220}
221
Zoe Liu239f06b2017-04-20 13:10:55 -0700222#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
223// The compound/single mode info data structure has one element border above and
224// to the left of the entries corresponding to real macroblocks.
225// The prediction flags in these dummy entries are initialized to 0.
226// 0 - single/single
227// 1 - single/--, --/single, --/--
228// 2 - single/comp, comp/single
229// 3 - comp/comp, comp/--, --/comp
230int av1_get_inter_mode_context(const MACROBLOCKD *xd) {
231 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
232 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
233 const int has_above = xd->up_available;
234 const int has_left = xd->left_available;
235
236 if (has_above && has_left) { // both edges available (0/2/3)
237 const int above_inter_comp_mode = is_inter_compound_mode(above_mbmi->mode);
238 const int left_inter_comp_mode = is_inter_compound_mode(left_mbmi->mode);
239 return (above_inter_comp_mode && left_inter_comp_mode)
240 ? 3
241 : (above_inter_comp_mode || left_inter_comp_mode) * 2;
242 } else if (has_above || has_left) { // one edge available (1/3)
243 const MB_MODE_INFO *const edge_mbmi = has_above ? above_mbmi : left_mbmi;
244 return is_inter_compound_mode(edge_mbmi->mode) ? 3 : 1;
245 } else { // no edge available (1)
246 return 1;
247 }
248}
249#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
250
Yaowu Xuc27fc142016-08-22 16:08:15 -0700251#if CONFIG_EXT_REFS
Zoe Liu6cfaff92016-10-18 17:12:11 -0700252#define CHECK_BACKWARD_REFS(ref_frame) \
253 (((ref_frame) >= BWDREF_FRAME) && ((ref_frame) <= ALTREF_FRAME))
254#define IS_BACKWARD_REF_FRAME(ref_frame) CHECK_BACKWARD_REFS(ref_frame)
255#else
256#define IS_BACKWARD_REF_FRAME(ref_frame) ((ref_frame) == cm->comp_fixed_ref)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700257#endif // CONFIG_EXT_REFS
258
Zoe Liu6cfaff92016-10-18 17:12:11 -0700259int av1_get_reference_mode_context(const AV1_COMMON *cm,
260 const MACROBLOCKD *xd) {
261 int ctx;
262 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
263 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
264 const int has_above = xd->up_available;
265 const int has_left = xd->left_available;
266
267#if CONFIG_EXT_REFS
268 (void)cm;
269#endif // CONFIG_EXT_REFS
270
271 // Note:
272 // The mode info data structure has a one element border above and to the
273 // left of the entries corresponding to real macroblocks.
274 // The prediction flags in these dummy entries are initialized to 0.
275 if (has_above && has_left) { // both edges available
276 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
277 // neither edge uses comp pred (0/1)
278 ctx = IS_BACKWARD_REF_FRAME(above_mbmi->ref_frame[0]) ^
279 IS_BACKWARD_REF_FRAME(left_mbmi->ref_frame[0]);
280 else if (!has_second_ref(above_mbmi))
281 // one of two edges uses comp pred (2/3)
282 ctx = 2 + (IS_BACKWARD_REF_FRAME(above_mbmi->ref_frame[0]) ||
283 !is_inter_block(above_mbmi));
284 else if (!has_second_ref(left_mbmi))
285 // one of two edges uses comp pred (2/3)
286 ctx = 2 + (IS_BACKWARD_REF_FRAME(left_mbmi->ref_frame[0]) ||
287 !is_inter_block(left_mbmi));
288 else // both edges use comp pred (4)
289 ctx = 4;
290 } else if (has_above || has_left) { // one edge available
291 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
292
293 if (!has_second_ref(edge_mbmi))
294 // edge does not use comp pred (0/1)
295 ctx = IS_BACKWARD_REF_FRAME(edge_mbmi->ref_frame[0]);
296 else
297 // edge uses comp pred (3)
298 ctx = 3;
299 } else { // no edges available (1)
300 ctx = 1;
301 }
302 assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
303 return ctx;
304}
305
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306#if CONFIG_EXT_REFS
307
308// TODO(zoeliu): Future work will be conducted to optimize the context design
309// for the coding of the reference frames.
310
311#define CHECK_LAST_OR_LAST2(ref_frame) \
312 ((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME))
313
314#define CHECK_GOLDEN_OR_LAST3(ref_frame) \
315 ((ref_frame == GOLDEN_FRAME) || (ref_frame == LAST3_FRAME))
316
317// Returns a context number for the given MB prediction signal
318// Signal the first reference frame for a compound mode be either
319// GOLDEN/LAST3, or LAST/LAST2.
320//
321// NOTE(zoeliu): The probability of ref_frame[0] is either
322// GOLDEN_FRAME or LAST3_FRAME.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200323#if CONFIG_ONE_SIDED_COMPOUND
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200324int av1_get_pred_context_comp_ref_p(UNUSED const AV1_COMMON *cm,
325 const MACROBLOCKD *xd) {
326#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700327int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
328 const MACROBLOCKD *xd) {
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200329#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700330 int pred_context;
331 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
332 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
333 const int above_in_image = xd->up_available;
334 const int left_in_image = xd->left_available;
335
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200336// Note:
337// The mode info data structure has a one element border above and to the
338// left of the entries correpsonding to real macroblocks.
339// The prediction flags in these dummy entries are initialised to 0.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200340#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200341 // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
342 const int bwd_ref_sign_idx = 1;
343#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700344 const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200345#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
347
348 if (above_in_image && left_in_image) { // both edges available
349 const int above_intra = !is_inter_block(above_mbmi);
350 const int left_intra = !is_inter_block(left_mbmi);
351
352 if (above_intra && left_intra) { // intra/intra (2)
353 pred_context = 2;
354 } else if (above_intra || left_intra) { // intra/inter
355 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
356
357 if (!has_second_ref(edge_mbmi)) // single pred (1/3)
358 pred_context =
359 1 + 2 * (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]));
360 else // comp pred (1/3)
361 pred_context = 1 +
362 2 * (!CHECK_GOLDEN_OR_LAST3(
363 edge_mbmi->ref_frame[fwd_ref_sign_idx]));
364 } else { // inter/inter
365 const int l_sg = !has_second_ref(left_mbmi);
366 const int a_sg = !has_second_ref(above_mbmi);
367 const MV_REFERENCE_FRAME frfa =
368 a_sg ? above_mbmi->ref_frame[0]
369 : above_mbmi->ref_frame[fwd_ref_sign_idx];
370 const MV_REFERENCE_FRAME frfl =
371 l_sg ? left_mbmi->ref_frame[0]
372 : left_mbmi->ref_frame[fwd_ref_sign_idx];
373
374 if (frfa == frfl && CHECK_GOLDEN_OR_LAST3(frfa)) {
375 pred_context = 0;
376 } else if (l_sg && a_sg) { // single/single
Zoe Liu6cfaff92016-10-18 17:12:11 -0700377 if ((CHECK_BACKWARD_REFS(frfa) && CHECK_LAST_OR_LAST2(frfl)) ||
378 (CHECK_BACKWARD_REFS(frfl) && CHECK_LAST_OR_LAST2(frfa))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700379 pred_context = 4;
380 } else if (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl)) {
381 pred_context = 1;
382 } else {
383 pred_context = 3;
384 }
385 } else if (l_sg || a_sg) { // single/comp
386 const MV_REFERENCE_FRAME frfc = l_sg ? frfa : frfl;
387 const MV_REFERENCE_FRAME rfs = a_sg ? frfa : frfl;
388
389 if (CHECK_GOLDEN_OR_LAST3(frfc) && !CHECK_GOLDEN_OR_LAST3(rfs))
390 pred_context = 1;
391 else if (CHECK_GOLDEN_OR_LAST3(rfs) && !CHECK_GOLDEN_OR_LAST3(frfc))
392 pred_context = 2;
393 else
394 pred_context = 4;
395 } else { // comp/comp
396 if ((CHECK_LAST_OR_LAST2(frfa) && CHECK_LAST_OR_LAST2(frfl))) {
397 pred_context = 4;
398 } else {
399 // NOTE(zoeliu): Following assert may be removed once confirmed.
400 assert(CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl));
401 pred_context = 2;
402 }
403 }
404 }
405 } else if (above_in_image || left_in_image) { // one edge available
406 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
407
408 if (!is_inter_block(edge_mbmi)) {
409 pred_context = 2;
410 } else {
411 if (has_second_ref(edge_mbmi))
412 pred_context =
413 4 *
414 (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[fwd_ref_sign_idx]));
415 else
416 pred_context = 3 * (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]));
417 }
418 } else { // no edges available (2)
419 pred_context = 2;
420 }
421
422 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
423
424 return pred_context;
425}
426
427// Returns a context number for the given MB prediction signal
428// Signal the first reference frame for a compound mode be LAST,
429// conditioning on that it is known either LAST/LAST2.
430//
431// NOTE(zoeliu): The probability of ref_frame[0] is LAST_FRAME,
432// conditioning on it is either LAST_FRAME or LAST2_FRAME.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200433#if CONFIG_ONE_SIDED_COMPOUND
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200434int av1_get_pred_context_comp_ref_p1(UNUSED const AV1_COMMON *cm,
435 const MACROBLOCKD *xd) {
436#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700437int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
438 const MACROBLOCKD *xd) {
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200439#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700440 int pred_context;
441 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
442 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
443 const int above_in_image = xd->up_available;
444 const int left_in_image = xd->left_available;
445
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200446// Note:
447// The mode info data structure has a one element border above and to the
448// left of the entries correpsonding to real macroblocks.
449// The prediction flags in these dummy entries are initialised to 0.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200450#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200451 // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
452 const int bwd_ref_sign_idx = 1;
453#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700454 const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200455#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700456 const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
457
458 if (above_in_image && left_in_image) { // both edges available
459 const int above_intra = !is_inter_block(above_mbmi);
460 const int left_intra = !is_inter_block(left_mbmi);
461
462 if (above_intra && left_intra) { // intra/intra (2)
463 pred_context = 2;
464 } else if (above_intra || left_intra) { // intra/inter
465 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
466
467 if (!has_second_ref(edge_mbmi)) // single pred (1/3)
468 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != LAST_FRAME);
469 else // comp pred (1/3)
470 pred_context =
471 1 + 2 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != LAST_FRAME);
472 } else { // inter/inter
473 const int l_sg = !has_second_ref(left_mbmi);
474 const int a_sg = !has_second_ref(above_mbmi);
475 const MV_REFERENCE_FRAME frfa =
476 a_sg ? above_mbmi->ref_frame[0]
477 : above_mbmi->ref_frame[fwd_ref_sign_idx];
478 const MV_REFERENCE_FRAME frfl =
479 l_sg ? left_mbmi->ref_frame[0]
480 : left_mbmi->ref_frame[fwd_ref_sign_idx];
481
482 if (frfa == frfl && frfa == LAST_FRAME)
483 pred_context = 0;
484 else if (l_sg && a_sg) { // single/single
485 if (frfa == LAST_FRAME || frfl == LAST_FRAME)
486 pred_context = 1;
487 else if (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl))
488 pred_context = 2 + (frfa != frfl);
489 else if (frfa == frfl ||
Zoe Liu6cfaff92016-10-18 17:12:11 -0700490 (CHECK_BACKWARD_REFS(frfa) && CHECK_BACKWARD_REFS(frfl)))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700491 pred_context = 3;
492 else
493 pred_context = 4;
494 } else if (l_sg || a_sg) { // single/comp
495 const MV_REFERENCE_FRAME frfc = l_sg ? frfa : frfl;
496 const MV_REFERENCE_FRAME rfs = a_sg ? frfa : frfl;
497
498 if (frfc == LAST_FRAME && rfs != LAST_FRAME)
499 pred_context = 1;
500 else if (rfs == LAST_FRAME && frfc != LAST_FRAME)
501 pred_context = 2;
502 else
503 pred_context =
504 3 + (frfc == LAST2_FRAME || CHECK_GOLDEN_OR_LAST3(rfs));
505 } else { // comp/comp
506 if (frfa == LAST_FRAME || frfl == LAST_FRAME)
507 pred_context = 2;
508 else
509 pred_context =
510 3 + (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl));
511 }
512 }
513 } else if (above_in_image || left_in_image) { // one edge available
514 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
515
516 if (!is_inter_block(edge_mbmi)) {
517 pred_context = 2;
518 } else {
519 if (has_second_ref(edge_mbmi)) {
520 pred_context =
521 4 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != LAST_FRAME);
522 } else {
523 if (edge_mbmi->ref_frame[0] == LAST_FRAME)
524 pred_context = 0;
525 else
526 pred_context = 2 + CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]);
527 }
528 }
529 } else { // no edges available (2)
530 pred_context = 2;
531 }
532
533 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
534
535 return pred_context;
536}
537
538// Returns a context number for the given MB prediction signal
539// Signal the first reference frame for a compound mode be GOLDEN,
540// conditioning on that it is known either GOLDEN or LAST3.
541//
542// NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME,
543// conditioning on it is either GOLDEN or LAST3.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200544#if CONFIG_ONE_SIDED_COMPOUND
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200545int av1_get_pred_context_comp_ref_p2(UNUSED const AV1_COMMON *cm,
546 const MACROBLOCKD *xd) {
547#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700548int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
549 const MACROBLOCKD *xd) {
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200550#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700551 int pred_context;
552 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
553 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
554 const int above_in_image = xd->up_available;
555 const int left_in_image = xd->left_available;
556
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200557// Note:
558// The mode info data structure has a one element border above and to the
559// left of the entries correpsonding to real macroblocks.
560// The prediction flags in these dummy entries are initialised to 0.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200561#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200562 // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
563 const int bwd_ref_sign_idx = 1;
564#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700565 const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200566#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700567 const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
568
569 if (above_in_image && left_in_image) { // both edges available
570 const int above_intra = !is_inter_block(above_mbmi);
571 const int left_intra = !is_inter_block(left_mbmi);
572
573 if (above_intra && left_intra) { // intra/intra (2)
574 pred_context = 2;
575 } else if (above_intra || left_intra) { // intra/inter
576 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
577
578 if (!has_second_ref(edge_mbmi)) // single pred (1/3)
579 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != GOLDEN_FRAME);
580 else // comp pred (1/3)
581 pred_context =
582 1 + 2 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != GOLDEN_FRAME);
583 } else { // inter/inter
584 const int l_sg = !has_second_ref(left_mbmi);
585 const int a_sg = !has_second_ref(above_mbmi);
586 const MV_REFERENCE_FRAME frfa =
587 a_sg ? above_mbmi->ref_frame[0]
588 : above_mbmi->ref_frame[fwd_ref_sign_idx];
589 const MV_REFERENCE_FRAME frfl =
590 l_sg ? left_mbmi->ref_frame[0]
591 : left_mbmi->ref_frame[fwd_ref_sign_idx];
592
593 if (frfa == frfl && frfa == GOLDEN_FRAME)
594 pred_context = 0;
595 else if (l_sg && a_sg) { // single/single
596 if (frfa == GOLDEN_FRAME || frfl == GOLDEN_FRAME)
597 pred_context = 1;
598 else if (CHECK_LAST_OR_LAST2(frfa) || CHECK_LAST_OR_LAST2(frfl))
599 pred_context = 2 + (frfa != frfl);
600 else if (frfa == frfl ||
Zoe Liu6cfaff92016-10-18 17:12:11 -0700601 (CHECK_BACKWARD_REFS(frfa) && CHECK_BACKWARD_REFS(frfl)))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700602 pred_context = 3;
603 else
604 pred_context = 4;
605 } else if (l_sg || a_sg) { // single/comp
606 const MV_REFERENCE_FRAME frfc = l_sg ? frfa : frfl;
607 const MV_REFERENCE_FRAME rfs = a_sg ? frfa : frfl;
608
609 if (frfc == GOLDEN_FRAME && rfs != GOLDEN_FRAME)
610 pred_context = 1;
611 else if (rfs == GOLDEN_FRAME && frfc != GOLDEN_FRAME)
612 pred_context = 2;
613 else
614 pred_context = 3 + (frfc == LAST3_FRAME || CHECK_LAST_OR_LAST2(rfs));
615 } else { // comp/comp
616 if (frfa == GOLDEN_FRAME || frfl == GOLDEN_FRAME)
617 pred_context = 2;
618 else
619 pred_context =
620 3 + (CHECK_LAST_OR_LAST2(frfa) || CHECK_LAST_OR_LAST2(frfl));
621 }
622 }
623 } else if (above_in_image || left_in_image) { // one edge available
624 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
625
626 if (!is_inter_block(edge_mbmi)) {
627 pred_context = 2;
628 } else {
629 if (has_second_ref(edge_mbmi)) {
630 pred_context =
631 4 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != GOLDEN_FRAME);
632 } else {
633 if (edge_mbmi->ref_frame[0] == GOLDEN_FRAME)
634 pred_context = 0;
635 else
636 pred_context = 2 + CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
637 }
638 }
639 } else { // no edges available (2)
640 pred_context = 2;
641 }
642
643 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
644
645 return pred_context;
646}
647
648// Returns a context number for the given MB prediction signal
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200649#if CONFIG_ONE_SIDED_COMPOUND
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200650int av1_get_pred_context_comp_bwdref_p(UNUSED const AV1_COMMON *cm,
651 const MACROBLOCKD *xd) {
652#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700653int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
654 const MACROBLOCKD *xd) {
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200655#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700656 int pred_context;
657 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
658 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
659 const int above_in_image = xd->up_available;
660 const int left_in_image = xd->left_available;
661
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200662// Note:
663// The mode info data structure has a one element border above and to the
664// left of the entries corresponding to real macroblocks.
665// The prediction flags in these dummy entries are initialized to 0.
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200666#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200667 // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
668 const int bwd_ref_sign_idx = 1;
669#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700670 const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
Arild Fuldseth (arilfuld)38897302017-04-27 20:03:03 +0200671#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672 const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
673
674 if (above_in_image && left_in_image) { // both edges available
675 const int above_intra = !is_inter_block(above_mbmi);
676 const int left_intra = !is_inter_block(left_mbmi);
677
678 if (above_intra && left_intra) { // intra/intra (2)
679 pred_context = 2;
680 } else if (above_intra || left_intra) { // intra/inter
681 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
682
683 if (!has_second_ref(edge_mbmi)) // single pred (1/3)
684 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_bwd_ref[1]);
685 else // comp pred (1/3)
686 pred_context =
687 1 +
688 2 * (edge_mbmi->ref_frame[bwd_ref_sign_idx] != cm->comp_bwd_ref[1]);
689 } else { // inter/inter
690 const int l_comp = has_second_ref(left_mbmi);
691 const int a_comp = has_second_ref(above_mbmi);
692
693 const MV_REFERENCE_FRAME l_brf =
Emil Keyder01770b32017-01-20 18:03:11 -0500694 l_comp ? left_mbmi->ref_frame[bwd_ref_sign_idx] : NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695 const MV_REFERENCE_FRAME a_brf =
Emil Keyder01770b32017-01-20 18:03:11 -0500696 a_comp ? above_mbmi->ref_frame[bwd_ref_sign_idx] : NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700697
698 const MV_REFERENCE_FRAME l_frf =
699 !l_comp ? left_mbmi->ref_frame[0]
700 : left_mbmi->ref_frame[fwd_ref_sign_idx];
701 const MV_REFERENCE_FRAME a_frf =
702 !a_comp ? above_mbmi->ref_frame[0]
703 : above_mbmi->ref_frame[fwd_ref_sign_idx];
704
705 if (l_comp && a_comp) { // comp/comp
706 if (l_brf == a_brf && l_brf == cm->comp_bwd_ref[1]) {
707 pred_context = 0;
708 } else if (l_brf == cm->comp_bwd_ref[1] ||
709 a_brf == cm->comp_bwd_ref[1]) {
710 pred_context = 1;
711 } else {
712 // NOTE: Backward ref should be either BWDREF or ALTREF.
713 assert(l_brf == a_brf && l_brf != cm->comp_bwd_ref[1]);
714 pred_context = 3;
715 }
716 } else if (!l_comp && !a_comp) { // single/single
717 if (l_frf == a_frf && l_frf == cm->comp_bwd_ref[1]) {
718 pred_context = 0;
719 } else if (l_frf == cm->comp_bwd_ref[1] ||
720 a_frf == cm->comp_bwd_ref[1]) {
721 pred_context = 1;
722 } else if (l_frf == a_frf) {
723 pred_context = 3;
724 } else {
725 assert(l_frf != a_frf && l_frf != cm->comp_bwd_ref[1] &&
726 a_frf != cm->comp_bwd_ref[1]);
727 pred_context = 4;
728 }
729 } else { // comp/single
730 assert((l_comp && !a_comp) || (!l_comp && a_comp));
731
732 if ((l_comp && l_brf == cm->comp_bwd_ref[1] &&
733 a_frf == cm->comp_bwd_ref[1]) ||
734 (a_comp && a_brf == cm->comp_bwd_ref[1] &&
735 l_frf == cm->comp_bwd_ref[1])) {
736 pred_context = 1;
737 } else if ((l_comp && l_brf == cm->comp_bwd_ref[1]) ||
738 (a_comp && a_brf == cm->comp_bwd_ref[1]) ||
739 (!l_comp && l_frf == cm->comp_bwd_ref[1]) ||
740 (!a_comp && a_frf == cm->comp_bwd_ref[1])) {
741 pred_context = 2;
742 } else {
743 pred_context = 4;
744 }
745 }
746 }
747 } else if (above_in_image || left_in_image) { // one edge available
748 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
749
750 if (!is_inter_block(edge_mbmi)) {
751 pred_context = 2;
752 } else {
753 if (has_second_ref(edge_mbmi)) {
754 pred_context =
755 4 * (edge_mbmi->ref_frame[bwd_ref_sign_idx] != cm->comp_bwd_ref[1]);
756 } else {
757 pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_bwd_ref[1]);
758 }
759 }
760 } else { // no edges available (2)
761 pred_context = 2;
762 }
763 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
764
765 return pred_context;
766}
767
768#else // CONFIG_EXT_REFS
769
770// Returns a context number for the given MB prediction signal
Yaowu Xuf883b422016-08-30 14:01:10 -0700771int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
772 const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773 int pred_context;
774 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
775 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
776 const int above_in_image = xd->up_available;
777 const int left_in_image = xd->left_available;
778
779 // Note:
780 // The mode info data structure has a one element border above and to the
781 // left of the entries corresponding to real macroblocks.
782 // The prediction flags in these dummy entries are initialized to 0.
783 const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
784 const int var_ref_idx = !fix_ref_idx;
785
786 if (above_in_image && left_in_image) { // both edges available
787 const int above_intra = !is_inter_block(above_mbmi);
788 const int left_intra = !is_inter_block(left_mbmi);
789
790 if (above_intra && left_intra) { // intra/intra (2)
791 pred_context = 2;
792 } else if (above_intra || left_intra) { // intra/inter
793 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
794
795 if (!has_second_ref(edge_mbmi)) // single pred (1/3)
796 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
797 else // comp pred (1/3)
798 pred_context =
799 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx] != cm->comp_var_ref[1]);
800 } else { // inter/inter
801 const int l_sg = !has_second_ref(left_mbmi);
802 const int a_sg = !has_second_ref(above_mbmi);
803 const MV_REFERENCE_FRAME vrfa =
804 a_sg ? above_mbmi->ref_frame[0] : above_mbmi->ref_frame[var_ref_idx];
805 const MV_REFERENCE_FRAME vrfl =
806 l_sg ? left_mbmi->ref_frame[0] : left_mbmi->ref_frame[var_ref_idx];
807
808 if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
809 pred_context = 0;
810 } else if (l_sg && a_sg) { // single/single
811 if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
812 (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0]))
813 pred_context = 4;
814 else if (vrfa == vrfl)
815 pred_context = 3;
816 else
817 pred_context = 1;
818 } else if (l_sg || a_sg) { // single/comp
819 const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
820 const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
821 if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1])
822 pred_context = 1;
823 else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1])
824 pred_context = 2;
825 else
826 pred_context = 4;
827 } else if (vrfa == vrfl) { // comp/comp
828 pred_context = 4;
829 } else {
830 pred_context = 2;
831 }
832 }
833 } else if (above_in_image || left_in_image) { // one edge available
834 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
835
836 if (!is_inter_block(edge_mbmi)) {
837 pred_context = 2;
838 } else {
839 if (has_second_ref(edge_mbmi))
840 pred_context =
841 4 * (edge_mbmi->ref_frame[var_ref_idx] != cm->comp_var_ref[1]);
842 else
843 pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
844 }
845 } else { // no edges available (2)
846 pred_context = 2;
847 }
848 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
849
850 return pred_context;
851}
852
853#endif // CONFIG_EXT_REFS
854
855#if CONFIG_EXT_REFS
856
857// For the bit to signal whether the single reference is a ALTREF_FRAME
858// or a BWDREF_FRAME.
859//
860// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF/BWDREF.
Yaowu Xuf883b422016-08-30 14:01:10 -0700861int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700862 int pred_context;
863 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
864 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
865 const int has_above = xd->up_available;
866 const int has_left = xd->left_available;
867
868 // Note:
869 // The mode info data structure has a one element border above and to the
870 // left of the entries correpsonding to real macroblocks.
871 // The prediction flags in these dummy entries are initialised to 0.
872 if (has_above && has_left) { // both edges available
873 const int above_intra = !is_inter_block(above_mbmi);
874 const int left_intra = !is_inter_block(left_mbmi);
875
876 if (above_intra && left_intra) { // intra/intra
877 pred_context = 2;
878 } else if (above_intra || left_intra) { // intra/inter or inter/intra
879 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
880
Zoe Liu782c9642016-10-21 16:18:58 -0700881 if (!has_second_ref(edge_mbmi)) // single
Zoe Liu6cfaff92016-10-18 17:12:11 -0700882 pred_context = 4 * (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]));
Zoe Liu782c9642016-10-21 16:18:58 -0700883 else // comp
884 pred_context = 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700885 } else { // inter/inter
886 const int above_has_second = has_second_ref(above_mbmi);
887 const int left_has_second = has_second_ref(left_mbmi);
888
889 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700890 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700891
Zoe Liu782c9642016-10-21 16:18:58 -0700892 if (above_has_second && left_has_second) { // comp/comp
893 pred_context = 2;
894 } else if (above_has_second || left_has_second) { // single/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -0700895 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700896
Zoe Liu782c9642016-10-21 16:18:58 -0700897 pred_context = (!CHECK_BACKWARD_REFS(rfs)) ? 4 : 1;
898 } else { // single/single
Zoe Liu6cfaff92016-10-18 17:12:11 -0700899 pred_context = 2 * (!CHECK_BACKWARD_REFS(above0)) +
900 2 * (!CHECK_BACKWARD_REFS(left0));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700901 }
902 }
903 } else if (has_above || has_left) { // one edge available
904 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
905 if (!is_inter_block(edge_mbmi)) { // intra
906 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -0700907 } else { // inter
908 if (!has_second_ref(edge_mbmi)) // single
Zoe Liu6cfaff92016-10-18 17:12:11 -0700909 pred_context = 4 * (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]));
Zoe Liu782c9642016-10-21 16:18:58 -0700910 else // comp
911 pred_context = 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700912 }
913 } else { // no edges available
914 pred_context = 2;
915 }
916
917 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
918 return pred_context;
919}
920
921// For the bit to signal whether the single reference is ALTREF_FRAME or
922// BWDREF_FRAME, knowing that it shall be either of these 2 choices.
923//
924// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF_FRAME, conditioning
925// on it is either ALTREF_FRAME/BWDREF_FRAME.
Yaowu Xuf883b422016-08-30 14:01:10 -0700926int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927 int pred_context;
928 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
929 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
930 const int has_above = xd->up_available;
931 const int has_left = xd->left_available;
932
933 // Note:
934 // The mode info data structure has a one element border above and to the
935 // left of the entries correpsonding to real macroblocks.
936 // The prediction flags in these dummy entries are initialised to 0.
937 if (has_above && has_left) { // both edges available
938 const int above_intra = !is_inter_block(above_mbmi);
939 const int left_intra = !is_inter_block(left_mbmi);
940
941 if (above_intra && left_intra) { // intra/intra
942 pred_context = 2;
943 } else if (above_intra || left_intra) { // intra/inter or inter/intra
944 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
Zoe Liu782c9642016-10-21 16:18:58 -0700945 if (!has_second_ref(edge_mbmi)) { // single
Zoe Liu6cfaff92016-10-18 17:12:11 -0700946 if (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700947 pred_context = 3;
948 else
949 pred_context = 4 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -0700950 } else { // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951 pred_context = 1 +
952 2 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME ||
953 edge_mbmi->ref_frame[1] == BWDREF_FRAME);
954 }
955 } else { // inter/inter
956 const int above_has_second = has_second_ref(above_mbmi);
957 const int left_has_second = has_second_ref(left_mbmi);
958 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
959 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
960 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
961 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
962
Zoe Liu782c9642016-10-21 16:18:58 -0700963 if (above_has_second && left_has_second) { // comp/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -0700964 if (above0 == left0 && above1 == left1)
965 pred_context =
966 3 * (above0 == BWDREF_FRAME || above1 == BWDREF_FRAME ||
967 left0 == BWDREF_FRAME || left1 == BWDREF_FRAME);
968 else
969 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -0700970 } else if (above_has_second || left_has_second) { // single/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -0700971 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
972 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
973 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
974
975 if (rfs == BWDREF_FRAME)
976 pred_context = 3 + (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
977 else if (rfs == ALTREF_FRAME)
978 pred_context = (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
979 else
980 pred_context = 1 + 2 * (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -0700981 } else { // single/single
Zoe Liu6cfaff92016-10-18 17:12:11 -0700982 if (!CHECK_BACKWARD_REFS(above0) && !CHECK_BACKWARD_REFS(left0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700983 pred_context = 2 + (above0 == left0);
Zoe Liu6cfaff92016-10-18 17:12:11 -0700984 } else if (!CHECK_BACKWARD_REFS(above0) ||
985 !CHECK_BACKWARD_REFS(left0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700986 const MV_REFERENCE_FRAME edge0 =
Zoe Liu6cfaff92016-10-18 17:12:11 -0700987 !CHECK_BACKWARD_REFS(above0) ? left0 : above0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700988 pred_context = 4 * (edge0 == BWDREF_FRAME);
989 } else {
990 pred_context =
991 2 * (above0 == BWDREF_FRAME) + 2 * (left0 == BWDREF_FRAME);
992 }
993 }
994 }
995 } else if (has_above || has_left) { // one edge available
996 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
997
998 if (!is_inter_block(edge_mbmi) ||
Zoe Liu6cfaff92016-10-18 17:12:11 -0700999 (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001000 !has_second_ref(edge_mbmi)))
1001 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001002 else if (!has_second_ref(edge_mbmi)) // single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001003 pred_context = 4 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001004 else // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001005 pred_context = 3 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME ||
1006 edge_mbmi->ref_frame[1] == BWDREF_FRAME);
1007 } else { // no edges available (2)
1008 pred_context = 2;
1009 }
1010
1011 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1012 return pred_context;
1013}
1014
1015// For the bit to signal whether the single reference is LAST3/GOLDEN or
1016// LAST2/LAST, knowing that it shall be either of these 2 choices.
1017//
1018// NOTE(zoeliu): The probability of ref_frame[0] is LAST3/GOLDEN, conditioning
1019// on it is either LAST3/GOLDEN/LAST2/LAST.
Yaowu Xuf883b422016-08-30 14:01:10 -07001020int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001021 int pred_context;
1022 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1023 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1024 const int has_above = xd->up_available;
1025 const int has_left = xd->left_available;
1026
1027 // Note:
1028 // The mode info data structure has a one element border above and to the
1029 // left of the entries correpsonding to real macroblocks.
1030 // The prediction flags in these dummy entries are initialised to 0.
1031 if (has_above && has_left) { // both edges available
1032 const int above_intra = !is_inter_block(above_mbmi);
1033 const int left_intra = !is_inter_block(left_mbmi);
1034
1035 if (above_intra && left_intra) { // intra/intra
1036 pred_context = 2;
1037 } else if (above_intra || left_intra) { // intra/inter or inter/intra
1038 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
Zoe Liu782c9642016-10-21 16:18:58 -07001039 if (!has_second_ref(edge_mbmi)) { // single
Zoe Liu6cfaff92016-10-18 17:12:11 -07001040 if (CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001041 pred_context = 3;
1042 else
1043 pred_context = 4 * CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
Zoe Liu782c9642016-10-21 16:18:58 -07001044 } else { // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001045 pred_context = 1 +
1046 2 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
1047 CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
1048 }
1049 } else { // inter/inter
1050 const int above_has_second = has_second_ref(above_mbmi);
1051 const int left_has_second = has_second_ref(left_mbmi);
1052 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1053 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1054 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1055 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1056
Zoe Liu782c9642016-10-21 16:18:58 -07001057 if (above_has_second && left_has_second) { // comp/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001058 if (above0 == left0 && above1 == left1)
1059 pred_context =
1060 3 * (CHECK_LAST_OR_LAST2(above0) || CHECK_LAST_OR_LAST2(above1) ||
1061 CHECK_LAST_OR_LAST2(left0) || CHECK_LAST_OR_LAST2(left1));
1062 else
1063 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001064 } else if (above_has_second || left_has_second) { // single/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001065 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1066 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1067 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1068
1069 if (CHECK_LAST_OR_LAST2(rfs))
1070 pred_context =
1071 3 + (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
1072 else if (CHECK_GOLDEN_OR_LAST3(rfs))
1073 pred_context =
1074 (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
1075 else
1076 pred_context =
1077 1 + 2 * (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
Zoe Liu782c9642016-10-21 16:18:58 -07001078 } else { // single/single
Zoe Liu6cfaff92016-10-18 17:12:11 -07001079 if (CHECK_BACKWARD_REFS(above0) && CHECK_BACKWARD_REFS(left0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001080 pred_context = 2 + (above0 == left0);
Zoe Liu6cfaff92016-10-18 17:12:11 -07001081 } else if (CHECK_BACKWARD_REFS(above0) || CHECK_BACKWARD_REFS(left0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001082 const MV_REFERENCE_FRAME edge0 =
Zoe Liu6cfaff92016-10-18 17:12:11 -07001083 CHECK_BACKWARD_REFS(above0) ? left0 : above0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001084 pred_context = 4 * CHECK_LAST_OR_LAST2(edge0);
1085 } else {
1086 pred_context =
1087 2 * CHECK_LAST_OR_LAST2(above0) + 2 * CHECK_LAST_OR_LAST2(left0);
1088 }
1089 }
1090 }
1091 } else if (has_above || has_left) { // one edge available
1092 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1093
1094 if (!is_inter_block(edge_mbmi) ||
Zoe Liu6cfaff92016-10-18 17:12:11 -07001095 (CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 !has_second_ref(edge_mbmi)))
1097 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001098 else if (!has_second_ref(edge_mbmi)) // single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001099 pred_context = 4 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]));
Zoe Liu782c9642016-10-21 16:18:58 -07001100 else // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001101 pred_context = 3 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
1102 CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
1103 } else { // no edges available (2)
1104 pred_context = 2;
1105 }
1106
1107 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1108 return pred_context;
1109}
1110
1111// For the bit to signal whether the single reference is LAST2_FRAME or
1112// LAST_FRAME, knowing that it shall be either of these 2 choices.
1113//
1114// NOTE(zoeliu): The probability of ref_frame[0] is LAST2_FRAME, conditioning
1115// on it is either LAST2_FRAME/LAST_FRAME.
Yaowu Xuf883b422016-08-30 14:01:10 -07001116int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001117 int pred_context;
1118 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1119 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1120 const int has_above = xd->up_available;
1121 const int has_left = xd->left_available;
1122
1123 // Note:
1124 // The mode info data structure has a one element border above and to the
1125 // left of the entries correpsonding to real macroblocks.
1126 // The prediction flags in these dummy entries are initialised to 0.
1127 if (has_above && has_left) { // both edges available
1128 const int above_intra = !is_inter_block(above_mbmi);
1129 const int left_intra = !is_inter_block(left_mbmi);
1130
1131 if (above_intra && left_intra) { // intra/intra
1132 pred_context = 2;
1133 } else if (above_intra || left_intra) { // intra/inter or inter/intra
1134 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
Zoe Liu782c9642016-10-21 16:18:58 -07001135 if (!has_second_ref(edge_mbmi)) { // single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 if (!CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]))
1137 pred_context = 3;
1138 else
1139 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001140 } else { // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001141 pred_context = 1 +
1142 2 * (edge_mbmi->ref_frame[0] == LAST_FRAME ||
1143 edge_mbmi->ref_frame[1] == LAST_FRAME);
1144 }
1145 } else { // inter/inter
1146 const int above_has_second = has_second_ref(above_mbmi);
1147 const int left_has_second = has_second_ref(left_mbmi);
1148 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1149 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1150 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1151 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1152
Zoe Liu782c9642016-10-21 16:18:58 -07001153 if (above_has_second && left_has_second) { // comp/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154 if (above0 == left0 && above1 == left1)
1155 pred_context = 3 * (above0 == LAST_FRAME || above1 == LAST_FRAME ||
1156 left0 == LAST_FRAME || left1 == LAST_FRAME);
1157 else
1158 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001159 } else if (above_has_second || left_has_second) { // single/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1161 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1162 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1163
1164 if (rfs == LAST_FRAME)
1165 pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1166 else if (rfs == LAST2_FRAME)
1167 pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1168 else
1169 pred_context = 1 + 2 * (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001170 } else { // single/single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001171 if (!CHECK_LAST_OR_LAST2(above0) && !CHECK_LAST_OR_LAST2(left0)) {
1172 pred_context = 2 + (above0 == left0);
1173 } else if (!CHECK_LAST_OR_LAST2(above0) ||
1174 !CHECK_LAST_OR_LAST2(left0)) {
1175 const MV_REFERENCE_FRAME edge0 =
1176 !CHECK_LAST_OR_LAST2(above0) ? left0 : above0;
1177 pred_context = 4 * (edge0 == LAST_FRAME);
1178 } else {
1179 pred_context = 2 * (above0 == LAST_FRAME) + 2 * (left0 == LAST_FRAME);
1180 }
1181 }
1182 }
1183 } else if (has_above || has_left) { // one edge available
1184 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1185
1186 if (!is_inter_block(edge_mbmi) ||
1187 (!CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) &&
1188 !has_second_ref(edge_mbmi)))
1189 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001190 else if (!has_second_ref(edge_mbmi)) // single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001191 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001192 else // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001193 pred_context = 3 * (edge_mbmi->ref_frame[0] == LAST_FRAME ||
1194 edge_mbmi->ref_frame[1] == LAST_FRAME);
1195 } else { // no edges available (2)
1196 pred_context = 2;
1197 }
1198
1199 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1200 return pred_context;
1201}
1202
1203// For the bit to signal whether the single reference is GOLDEN_FRAME or
1204// LAST3_FRAME, knowing that it shall be either of these 2 choices.
1205//
1206// NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME, conditioning
1207// on it is either GOLDEN_FRAME/LAST3_FRAME.
Yaowu Xuf883b422016-08-30 14:01:10 -07001208int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001209 int pred_context;
1210 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1211 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1212 const int has_above = xd->up_available;
1213 const int has_left = xd->left_available;
1214
1215 // Note:
1216 // The mode info data structure has a one element border above and to the
1217 // left of the entries correpsonding to real macroblocks.
1218 // The prediction flags in these dummy entries are initialised to 0.
1219 if (has_above && has_left) { // both edges available
1220 const int above_intra = !is_inter_block(above_mbmi);
1221 const int left_intra = !is_inter_block(left_mbmi);
1222
1223 if (above_intra && left_intra) { // intra/intra
1224 pred_context = 2;
1225 } else if (above_intra || left_intra) { // intra/inter or inter/intra
1226 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
Zoe Liu782c9642016-10-21 16:18:58 -07001227 if (!has_second_ref(edge_mbmi)) { // single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001228 if (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]))
1229 pred_context = 3;
1230 else
1231 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST3_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001232 } else { // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001233 pred_context = 1 +
1234 2 * (edge_mbmi->ref_frame[0] == LAST3_FRAME ||
1235 edge_mbmi->ref_frame[1] == LAST3_FRAME);
1236 }
1237 } else { // inter/inter
1238 const int above_has_second = has_second_ref(above_mbmi);
1239 const int left_has_second = has_second_ref(left_mbmi);
1240 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1241 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1242 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1243 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1244
Zoe Liu782c9642016-10-21 16:18:58 -07001245 if (above_has_second && left_has_second) { // comp/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001246 if (above0 == left0 && above1 == left1)
1247 pred_context = 3 * (above0 == LAST3_FRAME || above1 == LAST3_FRAME ||
1248 left0 == LAST3_FRAME || left1 == LAST3_FRAME);
1249 else
1250 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001251 } else if (above_has_second || left_has_second) { // single/comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001252 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1253 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1254 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1255
1256 if (rfs == LAST3_FRAME)
1257 pred_context = 3 + (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
1258 else if (rfs == GOLDEN_FRAME)
1259 pred_context = (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
1260 else
1261 pred_context = 1 + 2 * (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001262 } else { // single/single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001263 if (!CHECK_GOLDEN_OR_LAST3(above0) && !CHECK_GOLDEN_OR_LAST3(left0)) {
1264 pred_context = 2 + (above0 == left0);
1265 } else if (!CHECK_GOLDEN_OR_LAST3(above0) ||
1266 !CHECK_GOLDEN_OR_LAST3(left0)) {
1267 const MV_REFERENCE_FRAME edge0 =
1268 !CHECK_GOLDEN_OR_LAST3(above0) ? left0 : above0;
1269 pred_context = 4 * (edge0 == LAST3_FRAME);
1270 } else {
1271 pred_context =
1272 2 * (above0 == LAST3_FRAME) + 2 * (left0 == LAST3_FRAME);
1273 }
1274 }
1275 }
1276 } else if (has_above || has_left) { // one edge available
1277 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1278
1279 if (!is_inter_block(edge_mbmi) ||
1280 (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]) &&
1281 !has_second_ref(edge_mbmi)))
1282 pred_context = 2;
Zoe Liu782c9642016-10-21 16:18:58 -07001283 else if (!has_second_ref(edge_mbmi)) // single
Yaowu Xuc27fc142016-08-22 16:08:15 -07001284 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST3_FRAME);
Zoe Liu782c9642016-10-21 16:18:58 -07001285 else // comp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001286 pred_context = 3 * (edge_mbmi->ref_frame[0] == LAST3_FRAME ||
1287 edge_mbmi->ref_frame[1] == LAST3_FRAME);
1288 } else { // no edges available (2)
1289 pred_context = 2;
1290 }
1291
1292 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1293 return pred_context;
1294}
1295
1296#else // CONFIG_EXT_REFS
1297
Yaowu Xuf883b422016-08-30 14:01:10 -07001298int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001299 int pred_context;
1300 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1301 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1302 const int has_above = xd->up_available;
1303 const int has_left = xd->left_available;
1304 // Note:
1305 // The mode info data structure has a one element border above and to the
1306 // left of the entries corresponding to real macroblocks.
1307 // The prediction flags in these dummy entries are initialized to 0.
1308 if (has_above && has_left) { // both edges available
1309 const int above_intra = !is_inter_block(above_mbmi);
1310 const int left_intra = !is_inter_block(left_mbmi);
1311
1312 if (above_intra && left_intra) { // intra/intra
1313 pred_context = 2;
1314 } else if (above_intra || left_intra) { // intra/inter or inter/intra
1315 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
1316 if (!has_second_ref(edge_mbmi))
1317 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
1318 else
1319 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
1320 edge_mbmi->ref_frame[1] == LAST_FRAME);
1321 } else { // inter/inter
1322 const int above_has_second = has_second_ref(above_mbmi);
1323 const int left_has_second = has_second_ref(left_mbmi);
1324 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1325 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1326 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1327 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1328
1329 if (above_has_second && left_has_second) {
1330 pred_context = 1 + (above0 == LAST_FRAME || above1 == LAST_FRAME ||
1331 left0 == LAST_FRAME || left1 == LAST_FRAME);
1332 } else if (above_has_second || left_has_second) {
1333 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1334 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1335 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1336
1337 if (rfs == LAST_FRAME)
1338 pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1339 else
1340 pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1341 } else {
1342 pred_context = 2 * (above0 == LAST_FRAME) + 2 * (left0 == LAST_FRAME);
1343 }
1344 }
1345 } else if (has_above || has_left) { // one edge available
1346 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1347 if (!is_inter_block(edge_mbmi)) { // intra
1348 pred_context = 2;
1349 } else { // inter
1350 if (!has_second_ref(edge_mbmi))
1351 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
1352 else
1353 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
1354 edge_mbmi->ref_frame[1] == LAST_FRAME);
1355 }
1356 } else { // no edges available
1357 pred_context = 2;
1358 }
1359
1360 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1361 return pred_context;
1362}
1363
Yaowu Xuf883b422016-08-30 14:01:10 -07001364int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001365 int pred_context;
1366 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1367 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1368 const int has_above = xd->up_available;
1369 const int has_left = xd->left_available;
1370
1371 // Note:
1372 // The mode info data structure has a one element border above and to the
1373 // left of the entries corresponding to real macroblocks.
1374 // The prediction flags in these dummy entries are initialized to 0.
1375 if (has_above && has_left) { // both edges available
1376 const int above_intra = !is_inter_block(above_mbmi);
1377 const int left_intra = !is_inter_block(left_mbmi);
1378
1379 if (above_intra && left_intra) { // intra/intra
1380 pred_context = 2;
1381 } else if (above_intra || left_intra) { // intra/inter or inter/intra
1382 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
1383 if (!has_second_ref(edge_mbmi)) {
1384 if (edge_mbmi->ref_frame[0] == LAST_FRAME)
1385 pred_context = 3;
1386 else
1387 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
1388 } else {
1389 pred_context = 1 +
1390 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
1391 edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
1392 }
1393 } else { // inter/inter
1394 const int above_has_second = has_second_ref(above_mbmi);
1395 const int left_has_second = has_second_ref(left_mbmi);
1396 const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1397 const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1398 const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1399 const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1400
1401 if (above_has_second && left_has_second) {
1402 if (above0 == left0 && above1 == left1)
1403 pred_context =
1404 3 * (above0 == GOLDEN_FRAME || above1 == GOLDEN_FRAME ||
1405 left0 == GOLDEN_FRAME || left1 == GOLDEN_FRAME);
1406 else
1407 pred_context = 2;
1408 } else if (above_has_second || left_has_second) {
1409 const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1410 const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1411 const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1412
1413 if (rfs == GOLDEN_FRAME)
1414 pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
1415 else if (rfs != GOLDEN_FRAME && rfs != LAST_FRAME)
1416 pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME;
1417 else
1418 pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
1419 } else {
1420 if (above0 == LAST_FRAME && left0 == LAST_FRAME) {
1421 pred_context = 3;
1422 } else if (above0 == LAST_FRAME || left0 == LAST_FRAME) {
1423 const MV_REFERENCE_FRAME edge0 =
1424 (above0 == LAST_FRAME) ? left0 : above0;
1425 pred_context = 4 * (edge0 == GOLDEN_FRAME);
1426 } else {
1427 pred_context =
1428 2 * (above0 == GOLDEN_FRAME) + 2 * (left0 == GOLDEN_FRAME);
1429 }
1430 }
1431 }
1432 } else if (has_above || has_left) { // one edge available
1433 const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1434
1435 if (!is_inter_block(edge_mbmi) ||
1436 (edge_mbmi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mbmi)))
1437 pred_context = 2;
1438 else if (!has_second_ref(edge_mbmi))
1439 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
1440 else
1441 pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
1442 edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
1443 } else { // no edges available (2)
1444 pred_context = 2;
1445 }
1446 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1447 return pred_context;
1448}
1449
1450#endif // CONFIG_EXT_REFS