Line data Source code
1 : /*
2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 : *
4 : * 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.
10 : */
11 :
12 : #include "av1/common/common.h"
13 : #include "av1/common/pred_common.h"
14 : #include "av1/common/reconinter.h"
15 : #if CONFIG_EXT_INTRA
16 : #include "av1/common/reconintra.h"
17 : #endif // CONFIG_EXT_INTRA
18 : #include "av1/common/seg_common.h"
19 :
20 : // Returns a context number for the given MB prediction signal
21 : #if CONFIG_DUAL_FILTER
22 0 : static InterpFilter get_ref_filter_type(const MODE_INFO *mi,
23 : const MACROBLOCKD *xd, int dir,
24 : MV_REFERENCE_FRAME ref_frame) {
25 0 : InterpFilter ref_type = SWITCHABLE_FILTERS;
26 0 : const MB_MODE_INFO *ref_mbmi = &mi->mbmi;
27 0 : int use_subpel[2] = {
28 0 : has_subpel_mv_component(mi, xd, dir),
29 0 : has_subpel_mv_component(mi, xd, dir + 2),
30 : };
31 :
32 0 : if (ref_mbmi->ref_frame[0] == ref_frame && use_subpel[0])
33 0 : ref_type = ref_mbmi->interp_filter[(dir & 0x01)];
34 0 : else if (ref_mbmi->ref_frame[1] == ref_frame && use_subpel[1])
35 0 : ref_type = ref_mbmi->interp_filter[(dir & 0x01) + 2];
36 :
37 0 : return ref_type;
38 : }
39 :
40 0 : int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir) {
41 0 : const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
42 0 : const int ctx_offset =
43 0 : (mbmi->ref_frame[1] > INTRA_FRAME) * INTER_FILTER_COMP_OFFSET;
44 0 : 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 0 : int filter_type_ctx = ctx_offset + (dir & 0x01) * INTER_FILTER_DIR_OFFSET;
51 0 : int left_type = SWITCHABLE_FILTERS;
52 0 : int above_type = SWITCHABLE_FILTERS;
53 :
54 0 : if (xd->left_available)
55 0 : left_type = get_ref_filter_type(xd->mi[-1], xd, dir, ref_frame);
56 :
57 0 : if (xd->up_available)
58 0 : above_type =
59 0 : get_ref_filter_type(xd->mi[-xd->mi_stride], xd, dir, ref_frame);
60 :
61 0 : if (left_type == above_type) {
62 0 : filter_type_ctx += left_type;
63 0 : } else if (left_type == SWITCHABLE_FILTERS) {
64 0 : assert(above_type != SWITCHABLE_FILTERS);
65 0 : filter_type_ctx += above_type;
66 0 : } else if (above_type == SWITCHABLE_FILTERS) {
67 0 : assert(left_type != SWITCHABLE_FILTERS);
68 0 : filter_type_ctx += left_type;
69 : } else {
70 0 : filter_type_ctx += SWITCHABLE_FILTERS;
71 : }
72 :
73 0 : return filter_type_ctx;
74 : }
75 : #else
76 : int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
77 : // 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 :
90 : if (left_type == above_type) {
91 : return left_type;
92 : } else if (left_type == SWITCHABLE_FILTERS) {
93 : assert(above_type != SWITCHABLE_FILTERS);
94 : return above_type;
95 : } else if (above_type == SWITCHABLE_FILTERS) {
96 : assert(left_type != SWITCHABLE_FILTERS);
97 : return left_type;
98 : } else {
99 : return SWITCHABLE_FILTERS;
100 : }
101 : }
102 : #endif
103 :
104 : #if CONFIG_EXT_INTRA
105 : #if CONFIG_INTRA_INTERP
106 : // Obtain the reference filter type from the above/left neighbor blocks.
107 : static 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) {
111 : const PREDICTION_MODE mode = ref_mbmi->mode;
112 : 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 {
125 : if (av1_is_directional_mode(mode, ref_mbmi->sb_type)) {
126 : const int p_angle =
127 : mode_to_angle_map[mode] + ref_mbmi->angle_delta[0] * ANGLE_STEP;
128 : if (av1_is_intra_filter_switchable(p_angle)) {
129 : ref_type = ref_mbmi->intra_filter;
130 : }
131 : }
132 : }
133 : }
134 : return ref_type;
135 : }
136 :
137 : int av1_get_pred_context_intra_interp(const MACROBLOCKD *xd) {
138 : 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 : }
153 : #endif // CONFIG_INTRA_INTERP
154 : #endif // CONFIG_EXT_INTRA
155 :
156 : #if CONFIG_PALETTE && CONFIG_PALETTE_DELTA_ENCODING
157 : int 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;
168 : 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;
171 : // 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 :
198 : // 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
205 0 : int av1_get_intra_inter_context(const MACROBLOCKD *xd) {
206 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
207 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
208 0 : const int has_above = xd->up_available;
209 0 : const int has_left = xd->left_available;
210 :
211 0 : if (has_above && has_left) { // both edges available
212 0 : const int above_intra = !is_inter_block(above_mbmi);
213 0 : const int left_intra = !is_inter_block(left_mbmi);
214 0 : return left_intra && above_intra ? 3 : left_intra || above_intra;
215 0 : } else if (has_above || has_left) { // one edge available
216 0 : return 2 * !is_inter_block(has_above ? above_mbmi : left_mbmi);
217 : } else {
218 0 : return 0;
219 : }
220 : }
221 :
222 : #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
230 : int 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 :
251 : #if CONFIG_EXT_REFS
252 : #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)
257 : #endif // CONFIG_EXT_REFS
258 :
259 0 : int av1_get_reference_mode_context(const AV1_COMMON *cm,
260 : const MACROBLOCKD *xd) {
261 : int ctx;
262 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
263 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
264 0 : const int has_above = xd->up_available;
265 0 : 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 0 : if (has_above && has_left) { // both edges available
276 0 : if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
277 : // neither edge uses comp pred (0/1)
278 0 : ctx = IS_BACKWARD_REF_FRAME(above_mbmi->ref_frame[0]) ^
279 0 : IS_BACKWARD_REF_FRAME(left_mbmi->ref_frame[0]);
280 0 : else if (!has_second_ref(above_mbmi))
281 : // one of two edges uses comp pred (2/3)
282 0 : ctx = 2 + (IS_BACKWARD_REF_FRAME(above_mbmi->ref_frame[0]) ||
283 0 : !is_inter_block(above_mbmi));
284 0 : else if (!has_second_ref(left_mbmi))
285 : // one of two edges uses comp pred (2/3)
286 0 : ctx = 2 + (IS_BACKWARD_REF_FRAME(left_mbmi->ref_frame[0]) ||
287 0 : !is_inter_block(left_mbmi));
288 : else // both edges use comp pred (4)
289 0 : ctx = 4;
290 0 : } else if (has_above || has_left) { // one edge available
291 0 : const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
292 :
293 0 : if (!has_second_ref(edge_mbmi))
294 : // edge does not use comp pred (0/1)
295 0 : ctx = IS_BACKWARD_REF_FRAME(edge_mbmi->ref_frame[0]);
296 : else
297 : // edge uses comp pred (3)
298 0 : ctx = 3;
299 : } else { // no edges available (1)
300 0 : ctx = 1;
301 : }
302 0 : assert(ctx >= 0 && ctx < COMP_INTER_CONTEXTS);
303 0 : return ctx;
304 : }
305 :
306 : #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.
323 : #if CONFIG_ONE_SIDED_COMPOUND
324 0 : int av1_get_pred_context_comp_ref_p(UNUSED const AV1_COMMON *cm,
325 : const MACROBLOCKD *xd) {
326 : #else
327 : int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
328 : const MACROBLOCKD *xd) {
329 : #endif
330 : int pred_context;
331 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
332 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
333 0 : const int above_in_image = xd->up_available;
334 0 : const int left_in_image = xd->left_available;
335 :
336 : // 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.
340 : #if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
341 : // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
342 0 : const int bwd_ref_sign_idx = 1;
343 : #else
344 : const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
345 : #endif
346 0 : const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
347 :
348 0 : if (above_in_image && left_in_image) { // both edges available
349 0 : const int above_intra = !is_inter_block(above_mbmi);
350 0 : const int left_intra = !is_inter_block(left_mbmi);
351 :
352 0 : if (above_intra && left_intra) { // intra/intra (2)
353 0 : pred_context = 2;
354 0 : } else if (above_intra || left_intra) { // intra/inter
355 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
356 :
357 0 : if (!has_second_ref(edge_mbmi)) // single pred (1/3)
358 0 : pred_context =
359 0 : 1 + 2 * (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]));
360 : else // comp pred (1/3)
361 0 : pred_context = 1 +
362 0 : 2 * (!CHECK_GOLDEN_OR_LAST3(
363 : edge_mbmi->ref_frame[fwd_ref_sign_idx]));
364 : } else { // inter/inter
365 0 : const int l_sg = !has_second_ref(left_mbmi);
366 0 : const int a_sg = !has_second_ref(above_mbmi);
367 0 : const MV_REFERENCE_FRAME frfa =
368 : a_sg ? above_mbmi->ref_frame[0]
369 : : above_mbmi->ref_frame[fwd_ref_sign_idx];
370 0 : const MV_REFERENCE_FRAME frfl =
371 : l_sg ? left_mbmi->ref_frame[0]
372 : : left_mbmi->ref_frame[fwd_ref_sign_idx];
373 :
374 0 : if (frfa == frfl && CHECK_GOLDEN_OR_LAST3(frfa)) {
375 0 : pred_context = 0;
376 0 : } else if (l_sg && a_sg) { // single/single
377 0 : if ((CHECK_BACKWARD_REFS(frfa) && CHECK_LAST_OR_LAST2(frfl)) ||
378 0 : (CHECK_BACKWARD_REFS(frfl) && CHECK_LAST_OR_LAST2(frfa))) {
379 0 : pred_context = 4;
380 0 : } else if (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl)) {
381 0 : pred_context = 1;
382 : } else {
383 0 : pred_context = 3;
384 : }
385 0 : } else if (l_sg || a_sg) { // single/comp
386 0 : const MV_REFERENCE_FRAME frfc = l_sg ? frfa : frfl;
387 0 : const MV_REFERENCE_FRAME rfs = a_sg ? frfa : frfl;
388 :
389 0 : if (CHECK_GOLDEN_OR_LAST3(frfc) && !CHECK_GOLDEN_OR_LAST3(rfs))
390 0 : pred_context = 1;
391 0 : else if (CHECK_GOLDEN_OR_LAST3(rfs) && !CHECK_GOLDEN_OR_LAST3(frfc))
392 0 : pred_context = 2;
393 : else
394 0 : pred_context = 4;
395 : } else { // comp/comp
396 0 : if ((CHECK_LAST_OR_LAST2(frfa) && CHECK_LAST_OR_LAST2(frfl))) {
397 0 : pred_context = 4;
398 : } else {
399 : // NOTE(zoeliu): Following assert may be removed once confirmed.
400 0 : assert(CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl));
401 0 : pred_context = 2;
402 : }
403 : }
404 : }
405 0 : } else if (above_in_image || left_in_image) { // one edge available
406 0 : const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
407 :
408 0 : if (!is_inter_block(edge_mbmi)) {
409 0 : pred_context = 2;
410 : } else {
411 0 : if (has_second_ref(edge_mbmi))
412 0 : pred_context =
413 : 4 *
414 0 : (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[fwd_ref_sign_idx]));
415 : else
416 0 : pred_context = 3 * (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]));
417 : }
418 : } else { // no edges available (2)
419 0 : pred_context = 2;
420 : }
421 :
422 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
423 :
424 0 : 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.
433 : #if CONFIG_ONE_SIDED_COMPOUND
434 0 : int av1_get_pred_context_comp_ref_p1(UNUSED const AV1_COMMON *cm,
435 : const MACROBLOCKD *xd) {
436 : #else
437 : int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
438 : const MACROBLOCKD *xd) {
439 : #endif
440 : int pred_context;
441 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
442 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
443 0 : const int above_in_image = xd->up_available;
444 0 : const int left_in_image = xd->left_available;
445 :
446 : // 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.
450 : #if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
451 : // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
452 0 : const int bwd_ref_sign_idx = 1;
453 : #else
454 : const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
455 : #endif
456 0 : const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
457 :
458 0 : if (above_in_image && left_in_image) { // both edges available
459 0 : const int above_intra = !is_inter_block(above_mbmi);
460 0 : const int left_intra = !is_inter_block(left_mbmi);
461 :
462 0 : if (above_intra && left_intra) { // intra/intra (2)
463 0 : pred_context = 2;
464 0 : } else if (above_intra || left_intra) { // intra/inter
465 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
466 :
467 0 : if (!has_second_ref(edge_mbmi)) // single pred (1/3)
468 0 : pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != LAST_FRAME);
469 : else // comp pred (1/3)
470 0 : pred_context =
471 0 : 1 + 2 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != LAST_FRAME);
472 : } else { // inter/inter
473 0 : const int l_sg = !has_second_ref(left_mbmi);
474 0 : const int a_sg = !has_second_ref(above_mbmi);
475 0 : const MV_REFERENCE_FRAME frfa =
476 : a_sg ? above_mbmi->ref_frame[0]
477 : : above_mbmi->ref_frame[fwd_ref_sign_idx];
478 0 : const MV_REFERENCE_FRAME frfl =
479 : l_sg ? left_mbmi->ref_frame[0]
480 : : left_mbmi->ref_frame[fwd_ref_sign_idx];
481 :
482 0 : if (frfa == frfl && frfa == LAST_FRAME)
483 0 : pred_context = 0;
484 0 : else if (l_sg && a_sg) { // single/single
485 0 : if (frfa == LAST_FRAME || frfl == LAST_FRAME)
486 0 : pred_context = 1;
487 0 : else if (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl))
488 0 : pred_context = 2 + (frfa != frfl);
489 0 : else if (frfa == frfl ||
490 0 : (CHECK_BACKWARD_REFS(frfa) && CHECK_BACKWARD_REFS(frfl)))
491 0 : pred_context = 3;
492 : else
493 0 : pred_context = 4;
494 0 : } else if (l_sg || a_sg) { // single/comp
495 0 : const MV_REFERENCE_FRAME frfc = l_sg ? frfa : frfl;
496 0 : const MV_REFERENCE_FRAME rfs = a_sg ? frfa : frfl;
497 :
498 0 : if (frfc == LAST_FRAME && rfs != LAST_FRAME)
499 0 : pred_context = 1;
500 0 : else if (rfs == LAST_FRAME && frfc != LAST_FRAME)
501 0 : pred_context = 2;
502 : else
503 0 : pred_context =
504 0 : 3 + (frfc == LAST2_FRAME || CHECK_GOLDEN_OR_LAST3(rfs));
505 : } else { // comp/comp
506 0 : if (frfa == LAST_FRAME || frfl == LAST_FRAME)
507 0 : pred_context = 2;
508 : else
509 0 : pred_context =
510 0 : 3 + (CHECK_GOLDEN_OR_LAST3(frfa) || CHECK_GOLDEN_OR_LAST3(frfl));
511 : }
512 : }
513 0 : } else if (above_in_image || left_in_image) { // one edge available
514 0 : const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
515 :
516 0 : if (!is_inter_block(edge_mbmi)) {
517 0 : pred_context = 2;
518 : } else {
519 0 : if (has_second_ref(edge_mbmi)) {
520 0 : pred_context =
521 0 : 4 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != LAST_FRAME);
522 : } else {
523 0 : if (edge_mbmi->ref_frame[0] == LAST_FRAME)
524 0 : pred_context = 0;
525 : else
526 0 : pred_context = 2 + CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]);
527 : }
528 : }
529 : } else { // no edges available (2)
530 0 : pred_context = 2;
531 : }
532 :
533 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
534 :
535 0 : 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.
544 : #if CONFIG_ONE_SIDED_COMPOUND
545 0 : int av1_get_pred_context_comp_ref_p2(UNUSED const AV1_COMMON *cm,
546 : const MACROBLOCKD *xd) {
547 : #else
548 : int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
549 : const MACROBLOCKD *xd) {
550 : #endif
551 : int pred_context;
552 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
553 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
554 0 : const int above_in_image = xd->up_available;
555 0 : const int left_in_image = xd->left_available;
556 :
557 : // 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.
561 : #if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
562 : // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
563 0 : const int bwd_ref_sign_idx = 1;
564 : #else
565 : const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
566 : #endif
567 0 : const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
568 :
569 0 : if (above_in_image && left_in_image) { // both edges available
570 0 : const int above_intra = !is_inter_block(above_mbmi);
571 0 : const int left_intra = !is_inter_block(left_mbmi);
572 :
573 0 : if (above_intra && left_intra) { // intra/intra (2)
574 0 : pred_context = 2;
575 0 : } else if (above_intra || left_intra) { // intra/inter
576 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
577 :
578 0 : if (!has_second_ref(edge_mbmi)) // single pred (1/3)
579 0 : pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != GOLDEN_FRAME);
580 : else // comp pred (1/3)
581 0 : pred_context =
582 0 : 1 + 2 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != GOLDEN_FRAME);
583 : } else { // inter/inter
584 0 : const int l_sg = !has_second_ref(left_mbmi);
585 0 : const int a_sg = !has_second_ref(above_mbmi);
586 0 : const MV_REFERENCE_FRAME frfa =
587 : a_sg ? above_mbmi->ref_frame[0]
588 : : above_mbmi->ref_frame[fwd_ref_sign_idx];
589 0 : const MV_REFERENCE_FRAME frfl =
590 : l_sg ? left_mbmi->ref_frame[0]
591 : : left_mbmi->ref_frame[fwd_ref_sign_idx];
592 :
593 0 : if (frfa == frfl && frfa == GOLDEN_FRAME)
594 0 : pred_context = 0;
595 0 : else if (l_sg && a_sg) { // single/single
596 0 : if (frfa == GOLDEN_FRAME || frfl == GOLDEN_FRAME)
597 0 : pred_context = 1;
598 0 : else if (CHECK_LAST_OR_LAST2(frfa) || CHECK_LAST_OR_LAST2(frfl))
599 0 : pred_context = 2 + (frfa != frfl);
600 0 : else if (frfa == frfl ||
601 0 : (CHECK_BACKWARD_REFS(frfa) && CHECK_BACKWARD_REFS(frfl)))
602 0 : pred_context = 3;
603 : else
604 0 : pred_context = 4;
605 0 : } else if (l_sg || a_sg) { // single/comp
606 0 : const MV_REFERENCE_FRAME frfc = l_sg ? frfa : frfl;
607 0 : const MV_REFERENCE_FRAME rfs = a_sg ? frfa : frfl;
608 :
609 0 : if (frfc == GOLDEN_FRAME && rfs != GOLDEN_FRAME)
610 0 : pred_context = 1;
611 0 : else if (rfs == GOLDEN_FRAME && frfc != GOLDEN_FRAME)
612 0 : pred_context = 2;
613 : else
614 0 : pred_context = 3 + (frfc == LAST3_FRAME || CHECK_LAST_OR_LAST2(rfs));
615 : } else { // comp/comp
616 0 : if (frfa == GOLDEN_FRAME || frfl == GOLDEN_FRAME)
617 0 : pred_context = 2;
618 : else
619 0 : pred_context =
620 0 : 3 + (CHECK_LAST_OR_LAST2(frfa) || CHECK_LAST_OR_LAST2(frfl));
621 : }
622 : }
623 0 : } else if (above_in_image || left_in_image) { // one edge available
624 0 : const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
625 :
626 0 : if (!is_inter_block(edge_mbmi)) {
627 0 : pred_context = 2;
628 : } else {
629 0 : if (has_second_ref(edge_mbmi)) {
630 0 : pred_context =
631 0 : 4 * (edge_mbmi->ref_frame[fwd_ref_sign_idx] != GOLDEN_FRAME);
632 : } else {
633 0 : if (edge_mbmi->ref_frame[0] == GOLDEN_FRAME)
634 0 : pred_context = 0;
635 : else
636 0 : pred_context = 2 + CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
637 : }
638 : }
639 : } else { // no edges available (2)
640 0 : pred_context = 2;
641 : }
642 :
643 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
644 :
645 0 : return pred_context;
646 : }
647 :
648 : // Returns a context number for the given MB prediction signal
649 : #if CONFIG_ONE_SIDED_COMPOUND
650 0 : int av1_get_pred_context_comp_bwdref_p(UNUSED const AV1_COMMON *cm,
651 : const MACROBLOCKD *xd) {
652 : #else
653 : int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
654 : const MACROBLOCKD *xd) {
655 : #endif
656 : int pred_context;
657 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
658 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
659 0 : const int above_in_image = xd->up_available;
660 0 : const int left_in_image = xd->left_available;
661 :
662 : // 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.
666 : #if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
667 : // Code seems to assume that signbias of cm->comp_bwd_ref[0] is always 1
668 0 : const int bwd_ref_sign_idx = 1;
669 : #else
670 : const int bwd_ref_sign_idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
671 : #endif
672 0 : const int fwd_ref_sign_idx = !bwd_ref_sign_idx;
673 :
674 0 : if (above_in_image && left_in_image) { // both edges available
675 0 : const int above_intra = !is_inter_block(above_mbmi);
676 0 : const int left_intra = !is_inter_block(left_mbmi);
677 :
678 0 : if (above_intra && left_intra) { // intra/intra (2)
679 0 : pred_context = 2;
680 0 : } else if (above_intra || left_intra) { // intra/inter
681 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
682 :
683 0 : if (!has_second_ref(edge_mbmi)) // single pred (1/3)
684 0 : pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_bwd_ref[1]);
685 : else // comp pred (1/3)
686 0 : pred_context =
687 0 : 1 +
688 0 : 2 * (edge_mbmi->ref_frame[bwd_ref_sign_idx] != cm->comp_bwd_ref[1]);
689 : } else { // inter/inter
690 0 : const int l_comp = has_second_ref(left_mbmi);
691 0 : const int a_comp = has_second_ref(above_mbmi);
692 :
693 0 : const MV_REFERENCE_FRAME l_brf =
694 : l_comp ? left_mbmi->ref_frame[bwd_ref_sign_idx] : NONE_FRAME;
695 0 : const MV_REFERENCE_FRAME a_brf =
696 : a_comp ? above_mbmi->ref_frame[bwd_ref_sign_idx] : NONE_FRAME;
697 :
698 0 : const MV_REFERENCE_FRAME l_frf =
699 : !l_comp ? left_mbmi->ref_frame[0]
700 : : left_mbmi->ref_frame[fwd_ref_sign_idx];
701 0 : 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 0 : if (l_comp && a_comp) { // comp/comp
706 0 : if (l_brf == a_brf && l_brf == cm->comp_bwd_ref[1]) {
707 0 : pred_context = 0;
708 0 : } else if (l_brf == cm->comp_bwd_ref[1] ||
709 0 : a_brf == cm->comp_bwd_ref[1]) {
710 0 : pred_context = 1;
711 : } else {
712 : // NOTE: Backward ref should be either BWDREF or ALTREF.
713 0 : assert(l_brf == a_brf && l_brf != cm->comp_bwd_ref[1]);
714 0 : pred_context = 3;
715 : }
716 0 : } else if (!l_comp && !a_comp) { // single/single
717 0 : if (l_frf == a_frf && l_frf == cm->comp_bwd_ref[1]) {
718 0 : pred_context = 0;
719 0 : } else if (l_frf == cm->comp_bwd_ref[1] ||
720 0 : a_frf == cm->comp_bwd_ref[1]) {
721 0 : pred_context = 1;
722 0 : } else if (l_frf == a_frf) {
723 0 : pred_context = 3;
724 : } else {
725 0 : assert(l_frf != a_frf && l_frf != cm->comp_bwd_ref[1] &&
726 : a_frf != cm->comp_bwd_ref[1]);
727 0 : pred_context = 4;
728 : }
729 : } else { // comp/single
730 0 : assert((l_comp && !a_comp) || (!l_comp && a_comp));
731 :
732 0 : if ((l_comp && l_brf == cm->comp_bwd_ref[1] &&
733 0 : a_frf == cm->comp_bwd_ref[1]) ||
734 0 : (a_comp && a_brf == cm->comp_bwd_ref[1] &&
735 0 : l_frf == cm->comp_bwd_ref[1])) {
736 0 : pred_context = 1;
737 0 : } else if ((l_comp && l_brf == cm->comp_bwd_ref[1]) ||
738 0 : (a_comp && a_brf == cm->comp_bwd_ref[1]) ||
739 0 : (!l_comp && l_frf == cm->comp_bwd_ref[1]) ||
740 0 : (!a_comp && a_frf == cm->comp_bwd_ref[1])) {
741 0 : pred_context = 2;
742 : } else {
743 0 : pred_context = 4;
744 : }
745 : }
746 : }
747 0 : } else if (above_in_image || left_in_image) { // one edge available
748 0 : const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
749 :
750 0 : if (!is_inter_block(edge_mbmi)) {
751 0 : pred_context = 2;
752 : } else {
753 0 : if (has_second_ref(edge_mbmi)) {
754 0 : pred_context =
755 0 : 4 * (edge_mbmi->ref_frame[bwd_ref_sign_idx] != cm->comp_bwd_ref[1]);
756 : } else {
757 0 : pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_bwd_ref[1]);
758 : }
759 : }
760 : } else { // no edges available (2)
761 0 : pred_context = 2;
762 : }
763 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
764 :
765 0 : return pred_context;
766 : }
767 :
768 : #else // CONFIG_EXT_REFS
769 :
770 : // Returns a context number for the given MB prediction signal
771 : int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
772 : const MACROBLOCKD *xd) {
773 : 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.
861 0 : int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
862 : int pred_context;
863 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
864 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
865 0 : const int has_above = xd->up_available;
866 0 : 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 0 : if (has_above && has_left) { // both edges available
873 0 : const int above_intra = !is_inter_block(above_mbmi);
874 0 : const int left_intra = !is_inter_block(left_mbmi);
875 :
876 0 : if (above_intra && left_intra) { // intra/intra
877 0 : pred_context = 2;
878 0 : } else if (above_intra || left_intra) { // intra/inter or inter/intra
879 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
880 :
881 0 : if (!has_second_ref(edge_mbmi)) // single
882 0 : pred_context = 4 * (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]));
883 : else // comp
884 0 : pred_context = 2;
885 : } else { // inter/inter
886 0 : const int above_has_second = has_second_ref(above_mbmi);
887 0 : const int left_has_second = has_second_ref(left_mbmi);
888 :
889 0 : const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
890 0 : const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
891 :
892 0 : if (above_has_second && left_has_second) { // comp/comp
893 0 : pred_context = 2;
894 0 : } else if (above_has_second || left_has_second) { // single/comp
895 0 : const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
896 :
897 0 : pred_context = (!CHECK_BACKWARD_REFS(rfs)) ? 4 : 1;
898 : } else { // single/single
899 0 : pred_context = 2 * (!CHECK_BACKWARD_REFS(above0)) +
900 0 : 2 * (!CHECK_BACKWARD_REFS(left0));
901 : }
902 : }
903 0 : } else if (has_above || has_left) { // one edge available
904 0 : const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
905 0 : if (!is_inter_block(edge_mbmi)) { // intra
906 0 : pred_context = 2;
907 : } else { // inter
908 0 : if (!has_second_ref(edge_mbmi)) // single
909 0 : pred_context = 4 * (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]));
910 : else // comp
911 0 : pred_context = 2;
912 : }
913 : } else { // no edges available
914 0 : pred_context = 2;
915 : }
916 :
917 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
918 0 : 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.
926 0 : int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
927 : int pred_context;
928 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
929 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
930 0 : const int has_above = xd->up_available;
931 0 : 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 0 : if (has_above && has_left) { // both edges available
938 0 : const int above_intra = !is_inter_block(above_mbmi);
939 0 : const int left_intra = !is_inter_block(left_mbmi);
940 :
941 0 : if (above_intra && left_intra) { // intra/intra
942 0 : pred_context = 2;
943 0 : } else if (above_intra || left_intra) { // intra/inter or inter/intra
944 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
945 0 : if (!has_second_ref(edge_mbmi)) { // single
946 0 : if (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]))
947 0 : pred_context = 3;
948 : else
949 0 : pred_context = 4 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME);
950 : } else { // comp
951 0 : pred_context = 1 +
952 0 : 2 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME ||
953 0 : edge_mbmi->ref_frame[1] == BWDREF_FRAME);
954 : }
955 : } else { // inter/inter
956 0 : const int above_has_second = has_second_ref(above_mbmi);
957 0 : const int left_has_second = has_second_ref(left_mbmi);
958 0 : const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
959 0 : const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
960 0 : const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
961 0 : const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
962 :
963 0 : if (above_has_second && left_has_second) { // comp/comp
964 0 : if (above0 == left0 && above1 == left1)
965 0 : pred_context =
966 0 : 3 * (above0 == BWDREF_FRAME || above1 == BWDREF_FRAME ||
967 0 : left0 == BWDREF_FRAME || left1 == BWDREF_FRAME);
968 : else
969 0 : pred_context = 2;
970 0 : } else if (above_has_second || left_has_second) { // single/comp
971 0 : const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
972 0 : const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
973 0 : const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
974 :
975 0 : if (rfs == BWDREF_FRAME)
976 0 : pred_context = 3 + (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
977 0 : else if (rfs == ALTREF_FRAME)
978 0 : pred_context = (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
979 : else
980 0 : pred_context = 1 + 2 * (crf1 == BWDREF_FRAME || crf2 == BWDREF_FRAME);
981 : } else { // single/single
982 0 : if (!CHECK_BACKWARD_REFS(above0) && !CHECK_BACKWARD_REFS(left0)) {
983 0 : pred_context = 2 + (above0 == left0);
984 0 : } else if (!CHECK_BACKWARD_REFS(above0) ||
985 0 : !CHECK_BACKWARD_REFS(left0)) {
986 0 : const MV_REFERENCE_FRAME edge0 =
987 0 : !CHECK_BACKWARD_REFS(above0) ? left0 : above0;
988 0 : pred_context = 4 * (edge0 == BWDREF_FRAME);
989 : } else {
990 0 : pred_context =
991 0 : 2 * (above0 == BWDREF_FRAME) + 2 * (left0 == BWDREF_FRAME);
992 : }
993 : }
994 : }
995 0 : } else if (has_above || has_left) { // one edge available
996 0 : const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
997 :
998 0 : if (!is_inter_block(edge_mbmi) ||
999 0 : (!CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) &&
1000 0 : !has_second_ref(edge_mbmi)))
1001 0 : pred_context = 2;
1002 0 : else if (!has_second_ref(edge_mbmi)) // single
1003 0 : pred_context = 4 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME);
1004 : else // comp
1005 0 : pred_context = 3 * (edge_mbmi->ref_frame[0] == BWDREF_FRAME ||
1006 0 : edge_mbmi->ref_frame[1] == BWDREF_FRAME);
1007 : } else { // no edges available (2)
1008 0 : pred_context = 2;
1009 : }
1010 :
1011 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1012 0 : 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.
1020 0 : int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
1021 : int pred_context;
1022 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1023 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1024 0 : const int has_above = xd->up_available;
1025 0 : 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 0 : if (has_above && has_left) { // both edges available
1032 0 : const int above_intra = !is_inter_block(above_mbmi);
1033 0 : const int left_intra = !is_inter_block(left_mbmi);
1034 :
1035 0 : if (above_intra && left_intra) { // intra/intra
1036 0 : pred_context = 2;
1037 0 : } else if (above_intra || left_intra) { // intra/inter or inter/intra
1038 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
1039 0 : if (!has_second_ref(edge_mbmi)) { // single
1040 0 : if (CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]))
1041 0 : pred_context = 3;
1042 : else
1043 0 : pred_context = 4 * CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
1044 : } else { // comp
1045 0 : pred_context = 1 +
1046 0 : 2 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
1047 0 : CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
1048 : }
1049 : } else { // inter/inter
1050 0 : const int above_has_second = has_second_ref(above_mbmi);
1051 0 : const int left_has_second = has_second_ref(left_mbmi);
1052 0 : const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1053 0 : const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1054 0 : const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1055 0 : const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1056 :
1057 0 : if (above_has_second && left_has_second) { // comp/comp
1058 0 : if (above0 == left0 && above1 == left1)
1059 0 : pred_context =
1060 0 : 3 * (CHECK_LAST_OR_LAST2(above0) || CHECK_LAST_OR_LAST2(above1) ||
1061 0 : CHECK_LAST_OR_LAST2(left0) || CHECK_LAST_OR_LAST2(left1));
1062 : else
1063 0 : pred_context = 2;
1064 0 : } else if (above_has_second || left_has_second) { // single/comp
1065 0 : const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1066 0 : const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1067 0 : const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1068 :
1069 0 : if (CHECK_LAST_OR_LAST2(rfs))
1070 0 : pred_context =
1071 0 : 3 + (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
1072 0 : else if (CHECK_GOLDEN_OR_LAST3(rfs))
1073 0 : pred_context =
1074 0 : (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
1075 : else
1076 0 : pred_context =
1077 0 : 1 + 2 * (CHECK_LAST_OR_LAST2(crf1) || CHECK_LAST_OR_LAST2(crf2));
1078 : } else { // single/single
1079 0 : if (CHECK_BACKWARD_REFS(above0) && CHECK_BACKWARD_REFS(left0)) {
1080 0 : pred_context = 2 + (above0 == left0);
1081 0 : } else if (CHECK_BACKWARD_REFS(above0) || CHECK_BACKWARD_REFS(left0)) {
1082 0 : const MV_REFERENCE_FRAME edge0 =
1083 0 : CHECK_BACKWARD_REFS(above0) ? left0 : above0;
1084 0 : pred_context = 4 * CHECK_LAST_OR_LAST2(edge0);
1085 : } else {
1086 0 : pred_context =
1087 0 : 2 * CHECK_LAST_OR_LAST2(above0) + 2 * CHECK_LAST_OR_LAST2(left0);
1088 : }
1089 : }
1090 : }
1091 0 : } else if (has_above || has_left) { // one edge available
1092 0 : const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1093 :
1094 0 : if (!is_inter_block(edge_mbmi) ||
1095 0 : (CHECK_BACKWARD_REFS(edge_mbmi->ref_frame[0]) &&
1096 0 : !has_second_ref(edge_mbmi)))
1097 0 : pred_context = 2;
1098 0 : else if (!has_second_ref(edge_mbmi)) // single
1099 0 : pred_context = 4 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]));
1100 : else // comp
1101 0 : pred_context = 3 * (CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) ||
1102 0 : CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[1]));
1103 : } else { // no edges available (2)
1104 0 : pred_context = 2;
1105 : }
1106 :
1107 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1108 0 : 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.
1116 0 : int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd) {
1117 : int pred_context;
1118 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1119 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1120 0 : const int has_above = xd->up_available;
1121 0 : 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 0 : if (has_above && has_left) { // both edges available
1128 0 : const int above_intra = !is_inter_block(above_mbmi);
1129 0 : const int left_intra = !is_inter_block(left_mbmi);
1130 :
1131 0 : if (above_intra && left_intra) { // intra/intra
1132 0 : pred_context = 2;
1133 0 : } else if (above_intra || left_intra) { // intra/inter or inter/intra
1134 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
1135 0 : if (!has_second_ref(edge_mbmi)) { // single
1136 0 : if (!CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]))
1137 0 : pred_context = 3;
1138 : else
1139 0 : pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
1140 : } else { // comp
1141 0 : pred_context = 1 +
1142 0 : 2 * (edge_mbmi->ref_frame[0] == LAST_FRAME ||
1143 0 : edge_mbmi->ref_frame[1] == LAST_FRAME);
1144 : }
1145 : } else { // inter/inter
1146 0 : const int above_has_second = has_second_ref(above_mbmi);
1147 0 : const int left_has_second = has_second_ref(left_mbmi);
1148 0 : const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1149 0 : const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1150 0 : const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1151 0 : const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1152 :
1153 0 : if (above_has_second && left_has_second) { // comp/comp
1154 0 : if (above0 == left0 && above1 == left1)
1155 0 : pred_context = 3 * (above0 == LAST_FRAME || above1 == LAST_FRAME ||
1156 0 : left0 == LAST_FRAME || left1 == LAST_FRAME);
1157 : else
1158 0 : pred_context = 2;
1159 0 : } else if (above_has_second || left_has_second) { // single/comp
1160 0 : const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1161 0 : const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1162 0 : const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1163 :
1164 0 : if (rfs == LAST_FRAME)
1165 0 : pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1166 0 : else if (rfs == LAST2_FRAME)
1167 0 : pred_context = (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1168 : else
1169 0 : pred_context = 1 + 2 * (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
1170 : } else { // single/single
1171 0 : if (!CHECK_LAST_OR_LAST2(above0) && !CHECK_LAST_OR_LAST2(left0)) {
1172 0 : pred_context = 2 + (above0 == left0);
1173 0 : } else if (!CHECK_LAST_OR_LAST2(above0) ||
1174 0 : !CHECK_LAST_OR_LAST2(left0)) {
1175 0 : const MV_REFERENCE_FRAME edge0 =
1176 0 : !CHECK_LAST_OR_LAST2(above0) ? left0 : above0;
1177 0 : pred_context = 4 * (edge0 == LAST_FRAME);
1178 : } else {
1179 0 : pred_context = 2 * (above0 == LAST_FRAME) + 2 * (left0 == LAST_FRAME);
1180 : }
1181 : }
1182 : }
1183 0 : } else if (has_above || has_left) { // one edge available
1184 0 : const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1185 :
1186 0 : if (!is_inter_block(edge_mbmi) ||
1187 0 : (!CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]) &&
1188 0 : !has_second_ref(edge_mbmi)))
1189 0 : pred_context = 2;
1190 0 : else if (!has_second_ref(edge_mbmi)) // single
1191 0 : pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
1192 : else // comp
1193 0 : pred_context = 3 * (edge_mbmi->ref_frame[0] == LAST_FRAME ||
1194 0 : edge_mbmi->ref_frame[1] == LAST_FRAME);
1195 : } else { // no edges available (2)
1196 0 : pred_context = 2;
1197 : }
1198 :
1199 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1200 0 : 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.
1208 0 : int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd) {
1209 : int pred_context;
1210 0 : const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
1211 0 : const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
1212 0 : const int has_above = xd->up_available;
1213 0 : 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 0 : if (has_above && has_left) { // both edges available
1220 0 : const int above_intra = !is_inter_block(above_mbmi);
1221 0 : const int left_intra = !is_inter_block(left_mbmi);
1222 :
1223 0 : if (above_intra && left_intra) { // intra/intra
1224 0 : pred_context = 2;
1225 0 : } else if (above_intra || left_intra) { // intra/inter or inter/intra
1226 0 : const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
1227 0 : if (!has_second_ref(edge_mbmi)) { // single
1228 0 : if (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]))
1229 0 : pred_context = 3;
1230 : else
1231 0 : pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST3_FRAME);
1232 : } else { // comp
1233 0 : pred_context = 1 +
1234 0 : 2 * (edge_mbmi->ref_frame[0] == LAST3_FRAME ||
1235 0 : edge_mbmi->ref_frame[1] == LAST3_FRAME);
1236 : }
1237 : } else { // inter/inter
1238 0 : const int above_has_second = has_second_ref(above_mbmi);
1239 0 : const int left_has_second = has_second_ref(left_mbmi);
1240 0 : const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
1241 0 : const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
1242 0 : const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
1243 0 : const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
1244 :
1245 0 : if (above_has_second && left_has_second) { // comp/comp
1246 0 : if (above0 == left0 && above1 == left1)
1247 0 : pred_context = 3 * (above0 == LAST3_FRAME || above1 == LAST3_FRAME ||
1248 0 : left0 == LAST3_FRAME || left1 == LAST3_FRAME);
1249 : else
1250 0 : pred_context = 2;
1251 0 : } else if (above_has_second || left_has_second) { // single/comp
1252 0 : const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
1253 0 : const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
1254 0 : const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
1255 :
1256 0 : if (rfs == LAST3_FRAME)
1257 0 : pred_context = 3 + (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
1258 0 : else if (rfs == GOLDEN_FRAME)
1259 0 : pred_context = (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
1260 : else
1261 0 : pred_context = 1 + 2 * (crf1 == LAST3_FRAME || crf2 == LAST3_FRAME);
1262 : } else { // single/single
1263 0 : if (!CHECK_GOLDEN_OR_LAST3(above0) && !CHECK_GOLDEN_OR_LAST3(left0)) {
1264 0 : pred_context = 2 + (above0 == left0);
1265 0 : } else if (!CHECK_GOLDEN_OR_LAST3(above0) ||
1266 0 : !CHECK_GOLDEN_OR_LAST3(left0)) {
1267 0 : const MV_REFERENCE_FRAME edge0 =
1268 0 : !CHECK_GOLDEN_OR_LAST3(above0) ? left0 : above0;
1269 0 : pred_context = 4 * (edge0 == LAST3_FRAME);
1270 : } else {
1271 0 : pred_context =
1272 0 : 2 * (above0 == LAST3_FRAME) + 2 * (left0 == LAST3_FRAME);
1273 : }
1274 : }
1275 : }
1276 0 : } else if (has_above || has_left) { // one edge available
1277 0 : const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
1278 :
1279 0 : if (!is_inter_block(edge_mbmi) ||
1280 0 : (!CHECK_GOLDEN_OR_LAST3(edge_mbmi->ref_frame[0]) &&
1281 0 : !has_second_ref(edge_mbmi)))
1282 0 : pred_context = 2;
1283 0 : else if (!has_second_ref(edge_mbmi)) // single
1284 0 : pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST3_FRAME);
1285 : else // comp
1286 0 : pred_context = 3 * (edge_mbmi->ref_frame[0] == LAST3_FRAME ||
1287 0 : edge_mbmi->ref_frame[1] == LAST3_FRAME);
1288 : } else { // no edges available (2)
1289 0 : pred_context = 2;
1290 : }
1291 :
1292 0 : assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
1293 0 : return pred_context;
1294 : }
1295 :
1296 : #else // CONFIG_EXT_REFS
1297 :
1298 : int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
1299 : 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 :
1364 : int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
1365 : 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
|