LCOV - code coverage report
Current view: top level - third_party/aom/av1/common - pred_common.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 591 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13