]> granicus.if.org Git - libvpx/commitdiff
Merge branch 'master' into nextgenv2
authorYaowu Xu <yaowu@google.com>
Thu, 28 Jan 2016 15:32:05 +0000 (07:32 -0800)
committerYaowu Xu <yaowu@google.com>
Thu, 28 Jan 2016 15:32:05 +0000 (07:32 -0800)
1  2 
vp10/common/pred_common.c
vp9/common/vp9_pred_common.c
vp9/encoder/vp9_aq_cyclicrefresh.c

index 9c42794c744ec45c84afe67c609ac3044c54ef00,236ae54661119710e8ca0aaa350ba21c8990e594..f9aac8a9e2ec5ba219dce14424fa95fea8699338
@@@ -103,689 -103,9 +103,689 @@@ int vp10_get_reference_mode_context(con
    return ctx;
  }
  
 +#if CONFIG_EXT_REFS
 +
 +// TODO(zoeliu): Future work will be conducted to optimize the context design
 +// for the coding of the reference frames.
 +
 +#define CHECK_LAST_OR_LAST2(ref_frame) \
 +  ((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME))
 +
 +#define CHECK_GOLDEN_LAST3_LAST4(ref_frame) \
 +  ((ref_frame == GOLDEN_FRAME) || (ref_frame == LAST3_FRAME) || \
 +  (ref_frame == LAST4_FRAME))
 +
  // Returns a context number for the given MB prediction signal
 +// Signal the first reference frame for a compound mode is either
 +// GOLDEN/LAST3/LAST4, or LAST/LAST2.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is either
 +//               GOLDEN_FRAME/LAST3_FRAME/LAST4_FRAME.
  int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
 -                                    const MACROBLOCKD *xd) {
 +                                     const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int above_in_image = xd->up_available;
 +  const int left_in_image = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
 +  // left of the entries correpsonding to real macroblocks.
 +  // The prediction flags in these dummy entries are initialised to 0.
 +  const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
 +  const int var_ref_idx = !fix_ref_idx;
 +
 +  if (above_in_image && left_in_image) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra (2)
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +
 +      if (!has_second_ref(edge_mbmi))  // single pred (1/3)
 +        pred_context = 1 +
 +            2 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[0]));
 +      else  // comp pred (1/3)
 +        pred_context = 1 +
 +            2 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[var_ref_idx]));
 +    } else {  // inter/inter
 +      const int l_sg = !has_second_ref(left_mbmi);
 +      const int a_sg = !has_second_ref(above_mbmi);
 +      const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
 +                                           : above_mbmi->ref_frame[var_ref_idx];
 +      const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
 +                                           : left_mbmi->ref_frame[var_ref_idx];
 +
 +      if (vrfa == vrfl && CHECK_GOLDEN_LAST3_LAST4(vrfa)) {
 +        pred_context = 0;
 +      } else if (l_sg && a_sg) {  // single/single
 +        if ((vrfa == ALTREF_FRAME && CHECK_LAST_OR_LAST2(vrfl)) ||
 +            (vrfl == ALTREF_FRAME && CHECK_LAST_OR_LAST2(vrfa))) {
 +          pred_context = 4;
 +        } else if (vrfa == vrfl || (CHECK_LAST_OR_LAST2(vrfa) &&
 +                                    CHECK_LAST_OR_LAST2(vrfl))) {
 +          pred_context = 3;
 +        } else {  // Either vrfa or vrfl is GOLDEN / LAST3 / LAST4
 +          // NOTE(zoeliu): Following assert may be removed once confirmed.
 +          assert(CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
 +                 CHECK_GOLDEN_LAST3_LAST4(vrfl));
 +          pred_context = 1;
 +        }
 +      } else if (l_sg || a_sg) {  // single/comp
 +        const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
 +        const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
 +
 +        if (CHECK_GOLDEN_LAST3_LAST4(vrfc) && !CHECK_GOLDEN_LAST3_LAST4(rfs))
 +          pred_context = 1;
 +        else if (CHECK_GOLDEN_LAST3_LAST4(rfs) &&
 +                 !CHECK_GOLDEN_LAST3_LAST4(vrfc))
 +          pred_context = 2;
 +        else
 +          pred_context = 4;
 +      } else {  // comp/comp
 +        if ((CHECK_LAST_OR_LAST2(vrfa) && CHECK_LAST_OR_LAST2(vrfl))) {
 +          pred_context = 4;
 +        } else {
 +          // NOTE(zoeliu): Following assert may be removed once confirmed.
 +          assert(CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
 +                 CHECK_GOLDEN_LAST3_LAST4(vrfl));
 +          pred_context = 2;
 +        }
 +      }
 +    }
 +  } else if (above_in_image || left_in_image) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
 +
 +    if (!is_inter_block(edge_mbmi)) {
 +      pred_context = 2;
 +    } else {
 +      if (has_second_ref(edge_mbmi))
 +        pred_context =
 +            4 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[var_ref_idx]));
 +      else
 +        pred_context = 3 * (!CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[0]));
 +    }
 +  } else {  // no edges available (2)
 +    pred_context = 2;
 +  }
 +
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +
 +  return pred_context;
 +}
 +
 +// Returns a context number for the given MB prediction signal
 +// Signal the first reference frame for a compound mode is LAST,
 +// conditioning on that it is known either LAST/LAST2.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is LAST_FRAME,
 +// conditioning on it is either LAST_FRAME or LAST2_FRAME.
 +int vp10_get_pred_context_comp_ref_p1(const VP10_COMMON *cm,
 +                                      const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int above_in_image = xd->up_available;
 +  const int left_in_image = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
 +  // left of the entries correpsonding to real macroblocks.
 +  // The prediction flags in these dummy entries are initialised to 0.
 +  const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
 +  const int var_ref_idx = !fix_ref_idx;
 +
 +  if (above_in_image && left_in_image) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra (2)
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +
 +      if (!has_second_ref(edge_mbmi))  // single pred (1/3)
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != LAST_FRAME);
 +      else  // comp pred (1/3)
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
 +                                != LAST_FRAME);
 +    } else {  // inter/inter
 +      const int l_sg = !has_second_ref(left_mbmi);
 +      const int a_sg = !has_second_ref(above_mbmi);
 +      const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
 +                                           : above_mbmi->ref_frame[var_ref_idx];
 +      const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
 +                                           : left_mbmi->ref_frame[var_ref_idx];
 +
 +      if (vrfa == vrfl && vrfa == LAST_FRAME)
 +        pred_context = 0;
 +      else if (l_sg && a_sg) {  // single/single
 +        if (vrfa == LAST_FRAME || vrfl == LAST_FRAME)
 +          pred_context = 1;
 +        else if (CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
 +                 CHECK_GOLDEN_LAST3_LAST4(vrfl))
 +          pred_context = 2 + (vrfa != vrfl);
 +        else if (vrfa == vrfl)
 +          pred_context = 3;
 +        else
 +          pred_context = 4;
 +      } else if (l_sg || a_sg) {  // single/comp
 +        const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
 +        const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
 +
 +        if (vrfc == LAST_FRAME && rfs != LAST_FRAME)
 +          pred_context = 1;
 +        else if (rfs == LAST_FRAME && vrfc != LAST_FRAME)
 +          pred_context = 2;
 +        else
 +          pred_context = 3 +
 +              (vrfc == LAST2_FRAME || CHECK_GOLDEN_LAST3_LAST4(rfs));
 +      } else {  // comp/comp
 +        if (vrfa == LAST_FRAME || vrfl == LAST_FRAME)
 +          pred_context = 2;
 +        else
 +          pred_context = 3 + (CHECK_GOLDEN_LAST3_LAST4(vrfa) ||
 +                              CHECK_GOLDEN_LAST3_LAST4(vrfl));
 +      }
 +    }
 +  } else if (above_in_image || left_in_image) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
 +
 +    if (!is_inter_block(edge_mbmi)) {
 +      pred_context = 2;
 +    } else {
 +      if (has_second_ref(edge_mbmi)) {
 +        pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] != LAST_FRAME);
 +      } else {
 +        if (edge_mbmi->ref_frame[0] == LAST_FRAME)
 +          pred_context = 0;
 +        else
 +          pred_context = 2 + CHECK_GOLDEN_LAST3_LAST4(edge_mbmi->ref_frame[0]);
 +      }
 +    }
 +  } else {  // no edges available (2)
 +    pred_context = 2;
 +  }
 +
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +
 +  return pred_context;
 +}
 +
 +#define CHECK_LAST3_OR_LAST4(ref_frame) \
 +  ((ref_frame == LAST3_FRAME) || (ref_frame == LAST4_FRAME))
 +
 +// Returns a context number for the given MB prediction signal
 +// Signal the first reference frame for a compound mode is GOLDEN,
 +// conditioning on that it is known either GOLDEN/LAST3/LAST4.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is GOLDEN_FRAME,
 +// conditioning on it is either GOLDEN / LAST3 / LAST4.
 +int vp10_get_pred_context_comp_ref_p2(const VP10_COMMON *cm,
 +                                      const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int above_in_image = xd->up_available;
 +  const int left_in_image = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
 +  // left of the entries correpsonding to real macroblocks.
 +  // The prediction flags in these dummy entries are initialised to 0.
 +  const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
 +  const int var_ref_idx = !fix_ref_idx;
 +
 +  if (above_in_image && left_in_image) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra (2)
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +
 +      if (!has_second_ref(edge_mbmi))  // single pred (1/3)
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != GOLDEN_FRAME);
 +      else  // comp pred (1/3)
 +        pred_context = 1 +
 +            2 * (edge_mbmi->ref_frame[var_ref_idx] != GOLDEN_FRAME);
 +    } else {  // inter/inter
 +      const int l_sg = !has_second_ref(left_mbmi);
 +      const int a_sg = !has_second_ref(above_mbmi);
 +      const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
 +                                           : above_mbmi->ref_frame[var_ref_idx];
 +      const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
 +                                           : left_mbmi->ref_frame[var_ref_idx];
 +
 +      if (vrfa == vrfl && vrfa == GOLDEN_FRAME)
 +        pred_context = 0;
 +      else if (l_sg && a_sg) {  // single/single
 +        if (vrfa == GOLDEN_FRAME || vrfl == GOLDEN_FRAME)
 +          pred_context = 1;
 +        else if (CHECK_LAST_OR_LAST2(vrfa) || CHECK_LAST_OR_LAST2(vrfl))
 +          pred_context = 2 + (vrfa != vrfl);
 +        else if (vrfa == vrfl)
 +          pred_context = 3;
 +        else
 +          pred_context = 4;
 +      } else if (l_sg || a_sg) {  // single/comp
 +        const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
 +        const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
 +
 +        if (vrfc == GOLDEN_FRAME && rfs != GOLDEN_FRAME)
 +          pred_context = 1;
 +        else if (rfs == GOLDEN_FRAME && vrfc != GOLDEN_FRAME)
 +          pred_context = 2;
 +        else
 +          pred_context = 3 +
 +              (CHECK_LAST3_OR_LAST4(vrfc) || CHECK_LAST_OR_LAST2(rfs));
 +      } else {  // comp/comp
 +        if (vrfa == GOLDEN_FRAME || vrfl == GOLDEN_FRAME)
 +          pred_context = 2;
 +        else
 +          pred_context = 3 +
 +              (CHECK_LAST_OR_LAST2(vrfa) || CHECK_LAST_OR_LAST2(vrfl));
 +      }
 +    }
 +  } else if (above_in_image || left_in_image) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
 +
 +    if (!is_inter_block(edge_mbmi)) {
 +      pred_context = 2;
 +    } else {
 +      if (has_second_ref(edge_mbmi)) {
 +        pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] != GOLDEN_FRAME);
 +      } else {
 +        if (edge_mbmi->ref_frame[0] == GOLDEN_FRAME)
 +          pred_context = 0;
 +        else
 +          pred_context = 2 + CHECK_LAST_OR_LAST2(edge_mbmi->ref_frame[0]);
 +      }
 +    }
 +  } else {  // no edges available (2)
 +    pred_context = 2;
 +  }
 +
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +
 +  return pred_context;
 +}
 +
 +#define CHECK_LAST_LAST2_GOLDEN(ref_frame) \
 +  ((ref_frame == LAST_FRAME) || (ref_frame == LAST2_FRAME) || \
 +  (ref_frame == GOLDEN_FRAME))
 +
 +// Returns a context number for the given MB prediction signal
 +// Signal the first reference frame for a compound mode is LAST3,
 +// conditioning on that it is known either LAST3/LAST4.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is LAST3_FRAME,
 +// conditioning on it is either LAST3 / LAST4.
 +int vp10_get_pred_context_comp_ref_p3(const VP10_COMMON *cm,
 +                                      const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int above_in_image = xd->up_available;
 +  const int left_in_image = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
 +  // left of the entries correpsonding to real macroblocks.
 +  // The prediction flags in these dummy entries are initialised to 0.
 +  const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
 +  const int var_ref_idx = !fix_ref_idx;
 +
 +  if (above_in_image && left_in_image) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra (2)
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +
 +      if (!has_second_ref(edge_mbmi))  // single pred (1/3)
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != LAST3_FRAME);
 +      else  // comp pred (1/3)
 +        pred_context = 1 +
 +            2 * (edge_mbmi->ref_frame[var_ref_idx] != LAST3_FRAME);
 +    } else {  // inter/inter
 +      const int l_sg = !has_second_ref(left_mbmi);
 +      const int a_sg = !has_second_ref(above_mbmi);
 +      const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
 +                                           : above_mbmi->ref_frame[var_ref_idx];
 +      const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
 +                                           : left_mbmi->ref_frame[var_ref_idx];
 +
 +      if (vrfa == vrfl && vrfa == LAST3_FRAME)
 +        pred_context = 0;
 +      else if (l_sg && a_sg) {  // single/single
 +        if (vrfa == LAST3_FRAME || vrfl == LAST3_FRAME)
 +          pred_context = 1;
 +        else if (CHECK_LAST_LAST2_GOLDEN(vrfa) || CHECK_LAST_LAST2_GOLDEN(vrfl))
 +          pred_context = 2 + (vrfa != vrfl);
 +        else if (vrfa == vrfl)
 +          pred_context = 3;
 +        else
 +          pred_context = 4;
 +      } else if (l_sg || a_sg) {  // single/comp
 +        const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
 +        const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
 +
 +        if (vrfc == LAST3_FRAME && rfs != LAST3_FRAME)
 +          pred_context = 1;
 +        else if (rfs == LAST3_FRAME && vrfc != LAST3_FRAME)
 +          pred_context = 2;
 +        else
 +          pred_context = 3 +
 +              (vrfc == LAST4_FRAME || CHECK_LAST_LAST2_GOLDEN(rfs));
 +      } else {  // comp/comp
 +        if (vrfa == LAST3_FRAME || vrfl == LAST3_FRAME)
 +          pred_context = 2;
 +        else
 +          pred_context = 3 +
 +              (CHECK_LAST_LAST2_GOLDEN(vrfa) || CHECK_LAST_LAST2_GOLDEN(vrfl));
 +      }
 +    }
 +  } else if (above_in_image || left_in_image) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
 +
 +    if (!is_inter_block(edge_mbmi)) {
 +      pred_context = 2;
 +    } else {
 +      if (has_second_ref(edge_mbmi)) {
 +        pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx] != LAST3_FRAME);
 +      } else {
 +        if (edge_mbmi->ref_frame[0] == LAST3_FRAME)
 +          pred_context = 0;
 +        else
 +          pred_context = 2 + CHECK_LAST_LAST2_GOLDEN(edge_mbmi->ref_frame[0]);
 +      }
 +    }
 +  } else {  // no edges available (2)
 +    pred_context = 2;
 +  }
 +
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +
 +  return pred_context;
 +}
 +
 +#else  // CONFIG_EXT_REFS
 +
 +// Returns a context number for the given MB prediction signal
 +int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
 +                                     const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int above_in_image = xd->up_available;
 +  const int left_in_image = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
-   // left of the entries correpsonding to real macroblocks.
-   // The prediction flags in these dummy entries are initialised to 0.
++  // left of the entries corresponding to real macroblocks.
++  // The prediction flags in these dummy entries are initialized to 0.
 +  const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
 +  const int var_ref_idx = !fix_ref_idx;
 +
 +  if (above_in_image && left_in_image) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra (2)
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +
 +      if (!has_second_ref(edge_mbmi))  // single pred (1/3)
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
 +      else  // comp pred (1/3)
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
 +                                    != cm->comp_var_ref[1]);
 +    } else {  // inter/inter
 +      const int l_sg = !has_second_ref(left_mbmi);
 +      const int a_sg = !has_second_ref(above_mbmi);
 +      const MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
 +                                           : above_mbmi->ref_frame[var_ref_idx];
 +      const MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
 +                                           : left_mbmi->ref_frame[var_ref_idx];
 +
 +      if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
 +        pred_context = 0;
 +      } else if (l_sg && a_sg) {  // single/single
 +        if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
 +            (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0]))
 +          pred_context = 4;
 +        else if (vrfa == vrfl)
 +          pred_context = 3;
 +        else
 +          pred_context = 1;
 +      } else if (l_sg || a_sg) {  // single/comp
 +        const MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
 +        const MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
 +        if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1])
 +          pred_context = 1;
 +        else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1])
 +          pred_context = 2;
 +        else
 +          pred_context = 4;
 +      } else if (vrfa == vrfl) {  // comp/comp
 +        pred_context = 4;
 +      } else {
 +        pred_context = 2;
 +      }
 +    }
 +  } else if (above_in_image || left_in_image) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
 +
 +    if (!is_inter_block(edge_mbmi)) {
 +      pred_context = 2;
 +    } else {
 +      if (has_second_ref(edge_mbmi))
 +        pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx]
 +                              != cm->comp_var_ref[1]);
 +      else
 +        pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
 +    }
 +  } else {  // no edges available (2)
 +    pred_context = 2;
 +  }
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +
 +  return pred_context;
 +}
 +
 +#endif  // CONFIG_EXT_REFS
 +
 +#if CONFIG_EXT_REFS
 +
 +#define CHECK_GOLDEN_OR_ALTREF(ref_frame) \
 +  ((ref_frame == GOLDEN_FRAME) || (ref_frame == ALTREF_FRAME))
 +
 +// For the bit to signal whether the single reference is a ALTREF_FRAME
 +// or a GOLDEN_FRAME.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF/GOLDEN.
 +int vp10_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int has_above = xd->up_available;
 +  const int has_left = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
 +  // left of the entries correpsonding to real macroblocks.
 +  // The prediction flags in these dummy entries are initialised to 0.
 +  if (has_above && has_left) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter or inter/intra
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +
 +      if (!has_second_ref(edge_mbmi))
 +        pred_context = 4 * (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]));
 +      else
 +        pred_context = 1 + (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]) ||
 +                            !CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[1]));
 +    } else {  // inter/inter
 +      const int above_has_second = has_second_ref(above_mbmi);
 +      const int left_has_second  = has_second_ref(left_mbmi);
 +
 +      const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
 +      const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
 +      const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
 +      const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
 +
 +      if (above_has_second && left_has_second) {
 +        pred_context = 1 + (!CHECK_GOLDEN_OR_ALTREF(above0) ||
 +                            !CHECK_GOLDEN_OR_ALTREF(above1) ||
 +                            !CHECK_GOLDEN_OR_ALTREF(left0) ||
 +                            !CHECK_GOLDEN_OR_ALTREF(left1));
 +      } else if (above_has_second || left_has_second) {
 +        const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
 +        const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
 +        const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
 +
 +        if (!CHECK_GOLDEN_OR_ALTREF(rfs))
 +          pred_context = 3 + (!CHECK_GOLDEN_OR_ALTREF(crf1) ||
 +                              !CHECK_GOLDEN_OR_ALTREF(crf2));
 +        else
 +          pred_context = !CHECK_GOLDEN_OR_ALTREF(crf1) ||
 +                         !CHECK_GOLDEN_OR_ALTREF(crf2);
 +      } else {
 +        pred_context = 2 * (!CHECK_GOLDEN_OR_ALTREF(above0)) +
 +                       2 * (!CHECK_GOLDEN_OR_ALTREF(left0));
 +      }
 +    }
 +  } else if (has_above || has_left) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
 +    if (!is_inter_block(edge_mbmi)) {  // intra
 +      pred_context = 2;
 +    } else {  // inter
 +      if (!has_second_ref(edge_mbmi))
 +        pred_context = 4 * (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]));
 +      else
 +        pred_context = 1 + (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]) ||
 +                            !CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[1]));
 +    }
 +  } else {  // no edges available
 +    pred_context = 2;
 +  }
 +
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +  return pred_context;
 +}
 +
 +// For the bit to signal whether the single reference is ALTREF_FRAME or
 +// GOLDEN_FRAME, knowing that it shall be either of these 2 choices.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF_FRAME, conditioning
 +// on it is either ALTREF_FRAME/GOLDEN_FRAME.
 +int vp10_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
 +  int pred_context;
 +  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
 +  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
 +  const int has_above = xd->up_available;
 +  const int has_left = xd->left_available;
 +
 +  // Note:
 +  // The mode info data structure has a one element border above and to the
 +  // left of the entries correpsonding to real macroblocks.
 +  // The prediction flags in these dummy entries are initialised to 0.
 +  if (has_above && has_left) {  // both edges available
 +    const int above_intra = !is_inter_block(above_mbmi);
 +    const int left_intra = !is_inter_block(left_mbmi);
 +
 +    if (above_intra && left_intra) {  // intra/intra
 +      pred_context = 2;
 +    } else if (above_intra || left_intra) {  // intra/inter or inter/intra
 +      const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
 +      if (!has_second_ref(edge_mbmi)) {
 +        if (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]))
 +          pred_context = 3;
 +        else
 +          pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
 +      } else {
 +        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
 +                                edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
 +      }
 +    } else {  // inter/inter
 +      const int above_has_second = has_second_ref(above_mbmi);
 +      const int left_has_second  = has_second_ref(left_mbmi);
 +      const MV_REFERENCE_FRAME above0 = above_mbmi->ref_frame[0];
 +      const MV_REFERENCE_FRAME above1 = above_mbmi->ref_frame[1];
 +      const MV_REFERENCE_FRAME left0 = left_mbmi->ref_frame[0];
 +      const MV_REFERENCE_FRAME left1 = left_mbmi->ref_frame[1];
 +
 +      if (above_has_second && left_has_second) {
 +        if (above0 == left0 && above1 == left1)
 +          pred_context = 3 * (above0 == GOLDEN_FRAME ||
 +                              above1 == GOLDEN_FRAME ||
 +                              left0 == GOLDEN_FRAME ||
 +                              left1 == GOLDEN_FRAME);
 +        else
 +          pred_context = 2;
 +      } else if (above_has_second || left_has_second) {
 +        const MV_REFERENCE_FRAME rfs = !above_has_second ? above0 : left0;
 +        const MV_REFERENCE_FRAME crf1 = above_has_second ? above0 : left0;
 +        const MV_REFERENCE_FRAME crf2 = above_has_second ? above1 : left1;
 +
 +        if (rfs == GOLDEN_FRAME)
 +          pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
 +        else if (rfs == ALTREF_FRAME)
 +          pred_context = (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
 +        else
 +          pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
 +      } else {
 +        if (!CHECK_GOLDEN_OR_ALTREF(above0) && !CHECK_GOLDEN_OR_ALTREF(left0)) {
 +          pred_context = 2 + (above0 == left0);
 +        } else if (!CHECK_GOLDEN_OR_ALTREF(above0) ||
 +                   !CHECK_GOLDEN_OR_ALTREF(left0)) {
 +          const MV_REFERENCE_FRAME edge0 =
 +              !CHECK_GOLDEN_OR_ALTREF(above0) ? left0 : above0;
 +          pred_context = 4 * (edge0 == GOLDEN_FRAME);
 +        } else {
 +          pred_context = 2 * (above0 == GOLDEN_FRAME) +
 +                         2 * (left0  == GOLDEN_FRAME);
 +        }
 +      }
 +    }
 +  } else if (has_above || has_left) {  // one edge available
 +    const MB_MODE_INFO *edge_mbmi = has_above ? above_mbmi : left_mbmi;
 +
 +    if (!is_inter_block(edge_mbmi) ||
 +        (!CHECK_GOLDEN_OR_ALTREF(edge_mbmi->ref_frame[0]) &&
 +         !has_second_ref(edge_mbmi)))
 +      pred_context = 2;
 +    else if (!has_second_ref(edge_mbmi))
 +      pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
 +    else
 +      pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
 +                          edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
 +  } else {  // no edges available (2)
 +    pred_context = 2;
 +  }
 +
 +  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
 +  return pred_context;
 +}
 +
 +// For the bit to signal whether the single reference is LAST3/LAST4 or
 +// LAST2/LAST, knowing that it shall be either of these 2 choices.
 +//
 +// NOTE(zoeliu): The probability of ref_frame[0] is LAST3/LAST4, conditioning
 +// on it is either LAST3/LAST4/LAST2/LAST.
 +int vp10_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
    int pred_context;
    const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
    const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
index e0eb0e377fa9f26285ba0b68f53a9294224cd0e9,c201890a8b7a6d1a5ad04fc21676c08f4667eb3d..0a36dba3375b79a2b3720c7df3def18dd39f8f73
@@@ -192,11 -192,10 +192,11 @@@ int vp9_get_pred_context_single_ref_p1(
    const MODE_INFO *const left_mi = xd->left_mi;
    const int has_above = xd->up_available;
    const int has_left = xd->left_available;
 +
    // Note:
    // The mode info data structure has a one element border above and to the
-   // left of the entries correpsonding to real macroblocks.
-   // The prediction flags in these dummy entries are initialised to 0.
+   // left of the entries corresponding to real macroblocks.
+   // The prediction flags in these dummy entries are initialized to 0.
    if (has_above && has_left) {  // both edges available
      const int above_intra = !is_inter_block(above_mi);
      const int left_intra = !is_inter_block(left_mi);
Simple merge