| Index: source/libvpx/vp9/encoder/vp9_encodemv.c
 | 
| ===================================================================
 | 
| --- source/libvpx/vp9/encoder/vp9_encodemv.c	(revision 240950)
 | 
| +++ source/libvpx/vp9/encoder/vp9_encodemv.c	(working copy)
 | 
| @@ -15,11 +15,22 @@
 | 
|  #include "vp9/common/vp9_systemdependent.h"
 | 
|  #include "vp9/encoder/vp9_encodemv.h"
 | 
|  
 | 
| -
 | 
|  #ifdef ENTROPY_STATS
 | 
|  extern unsigned int active_section;
 | 
|  #endif
 | 
|  
 | 
| +static struct vp9_token mv_joint_encodings[MV_JOINTS];
 | 
| +static struct vp9_token mv_class_encodings[MV_CLASSES];
 | 
| +static struct vp9_token mv_fp_encodings[MV_FP_SIZE];
 | 
| +static struct vp9_token mv_class0_encodings[CLASS0_SIZE];
 | 
| +
 | 
| +void vp9_entropy_mv_init() {
 | 
| +  vp9_tokens_from_tree(mv_joint_encodings, vp9_mv_joint_tree);
 | 
| +  vp9_tokens_from_tree(mv_class_encodings, vp9_mv_class_tree);
 | 
| +  vp9_tokens_from_tree(mv_class0_encodings, vp9_mv_class0_tree);
 | 
| +  vp9_tokens_from_tree(mv_fp_encodings, vp9_mv_fp_tree);
 | 
| +}
 | 
| +
 | 
|  static void encode_mv_component(vp9_writer* w, int comp,
 | 
|                                  const nmv_component* mvcomp, int usehp) {
 | 
|    int offset;
 | 
| @@ -36,13 +47,13 @@
 | 
|    vp9_write(w, sign, mvcomp->sign);
 | 
|  
 | 
|    // Class
 | 
| -  write_token(w, vp9_mv_class_tree, mvcomp->classes,
 | 
| -              &vp9_mv_class_encodings[mv_class]);
 | 
| +  vp9_write_token(w, vp9_mv_class_tree, mvcomp->classes,
 | 
| +                  &mv_class_encodings[mv_class]);
 | 
|  
 | 
|    // Integer bits
 | 
|    if (mv_class == MV_CLASS_0) {
 | 
| -    write_token(w, vp9_mv_class0_tree, mvcomp->class0,
 | 
| -                &vp9_mv_class0_encodings[d]);
 | 
| +    vp9_write_token(w, vp9_mv_class0_tree, mvcomp->class0,
 | 
| +                    &mv_class0_encodings[d]);
 | 
|    } else {
 | 
|      int i;
 | 
|      const int n = mv_class + CLASS0_BITS - 1;  // number of bits
 | 
| @@ -51,9 +62,9 @@
 | 
|    }
 | 
|  
 | 
|    // Fractional bits
 | 
| -  write_token(w, vp9_mv_fp_tree,
 | 
| -              mv_class == MV_CLASS_0 ?  mvcomp->class0_fp[d] : mvcomp->fp,
 | 
| -              &vp9_mv_fp_encodings[fr]);
 | 
| +  vp9_write_token(w, vp9_mv_fp_tree,
 | 
| +                  mv_class == MV_CLASS_0 ?  mvcomp->class0_fp[d] : mvcomp->fp,
 | 
| +                  &mv_fp_encodings[fr]);
 | 
|  
 | 
|    // High precision bit
 | 
|    if (usehp)
 | 
| @@ -68,7 +79,7 @@
 | 
|    int i, v;
 | 
|    int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE];
 | 
|    int bits_cost[MV_OFFSET_BITS][2];
 | 
| -  int class0_fp_cost[CLASS0_SIZE][4], fp_cost[4];
 | 
| +  int class0_fp_cost[CLASS0_SIZE][MV_FP_SIZE], fp_cost[MV_FP_SIZE];
 | 
|    int class0_hp_cost[2], hp_cost[2];
 | 
|  
 | 
|    sign_cost[0] = vp9_cost_zero(mvcomp->sign);
 | 
| @@ -124,155 +135,68 @@
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -static int update_mv(vp9_writer *w, const unsigned int ct[2],
 | 
| -                     vp9_prob *cur_p, vp9_prob new_p, vp9_prob upd_p) {
 | 
| -  vp9_prob mod_p = new_p | 1;
 | 
| -  const int cur_b = cost_branch256(ct, *cur_p);
 | 
| -  const int mod_b = cost_branch256(ct, mod_p);
 | 
| -  const int cost = 7 * 256 + (vp9_cost_one(upd_p) - vp9_cost_zero(upd_p));
 | 
| -  if (cur_b - mod_b > cost) {
 | 
| -    *cur_p = mod_p;
 | 
| -    vp9_write(w, 1, upd_p);
 | 
| -    vp9_write_literal(w, mod_p >> 1, 7);
 | 
| -    return 1;
 | 
| -  } else {
 | 
| -    vp9_write(w, 0, upd_p);
 | 
| -    return 0;
 | 
| +static int update_mv(vp9_writer *w, const unsigned int ct[2], vp9_prob *cur_p,
 | 
| +                     vp9_prob upd_p) {
 | 
| +  const vp9_prob new_p = get_binary_prob(ct[0], ct[1]) | 1;
 | 
| +  const int update = cost_branch256(ct, *cur_p) + vp9_cost_zero(upd_p) >
 | 
| +                     cost_branch256(ct, new_p) + vp9_cost_one(upd_p) + 7 * 256;
 | 
| +  vp9_write(w, update, upd_p);
 | 
| +  if (update) {
 | 
| +    *cur_p = new_p;
 | 
| +    vp9_write_literal(w, new_p >> 1, 7);
 | 
|    }
 | 
| +  return update;
 | 
|  }
 | 
|  
 | 
| -static void counts_to_nmv_context(
 | 
| -    nmv_context_counts *nmv_count,
 | 
| -    nmv_context *prob,
 | 
| -    int usehp,
 | 
| -    unsigned int (*branch_ct_joint)[2],
 | 
| -    unsigned int (*branch_ct_sign)[2],
 | 
| -    unsigned int (*branch_ct_classes)[MV_CLASSES - 1][2],
 | 
| -    unsigned int (*branch_ct_class0)[CLASS0_SIZE - 1][2],
 | 
| -    unsigned int (*branch_ct_bits)[MV_OFFSET_BITS][2],
 | 
| -    unsigned int (*branch_ct_class0_fp)[CLASS0_SIZE][4 - 1][2],
 | 
| -    unsigned int (*branch_ct_fp)[4 - 1][2],
 | 
| -    unsigned int (*branch_ct_class0_hp)[2],
 | 
| -    unsigned int (*branch_ct_hp)[2]) {
 | 
| -  int i, j, k;
 | 
| -  vp9_tree_probs_from_distribution(vp9_mv_joint_tree,
 | 
| -                                   prob->joints,
 | 
| -                                   branch_ct_joint,
 | 
| -                                   nmv_count->joints, 0);
 | 
| -  for (i = 0; i < 2; ++i) {
 | 
| -    const uint32_t s0 = nmv_count->comps[i].sign[0];
 | 
| -    const uint32_t s1 = nmv_count->comps[i].sign[1];
 | 
| +static void write_mv_update(const vp9_tree_index *tree,
 | 
| +                            vp9_prob probs[/*n - 1*/],
 | 
| +                            const unsigned int counts[/*n - 1*/],
 | 
| +                            int n, vp9_writer *w) {
 | 
| +  int i;
 | 
| +  unsigned int branch_ct[32][2];
 | 
|  
 | 
| -    prob->comps[i].sign = get_binary_prob(s0, s1);
 | 
| -    branch_ct_sign[i][0] = s0;
 | 
| -    branch_ct_sign[i][1] = s1;
 | 
| -    vp9_tree_probs_from_distribution(vp9_mv_class_tree,
 | 
| -                                     prob->comps[i].classes,
 | 
| -                                     branch_ct_classes[i],
 | 
| -                                     nmv_count->comps[i].classes, 0);
 | 
| -    vp9_tree_probs_from_distribution(vp9_mv_class0_tree,
 | 
| -                                     prob->comps[i].class0,
 | 
| -                                     branch_ct_class0[i],
 | 
| -                                     nmv_count->comps[i].class0, 0);
 | 
| -    for (j = 0; j < MV_OFFSET_BITS; ++j) {
 | 
| -      const uint32_t b0 = nmv_count->comps[i].bits[j][0];
 | 
| -      const uint32_t b1 = nmv_count->comps[i].bits[j][1];
 | 
| +  // Assuming max number of probabilities <= 32
 | 
| +  assert(n <= 32);
 | 
|  
 | 
| -      prob->comps[i].bits[j] = get_binary_prob(b0, b1);
 | 
| -      branch_ct_bits[i][j][0] = b0;
 | 
| -      branch_ct_bits[i][j][1] = b1;
 | 
| -    }
 | 
| -  }
 | 
| -  for (i = 0; i < 2; ++i) {
 | 
| -    for (k = 0; k < CLASS0_SIZE; ++k) {
 | 
| -      vp9_tree_probs_from_distribution(vp9_mv_fp_tree,
 | 
| -                                       prob->comps[i].class0_fp[k],
 | 
| -                                       branch_ct_class0_fp[i][k],
 | 
| -                                       nmv_count->comps[i].class0_fp[k], 0);
 | 
| -    }
 | 
| -    vp9_tree_probs_from_distribution(vp9_mv_fp_tree,
 | 
| -                                     prob->comps[i].fp,
 | 
| -                                     branch_ct_fp[i],
 | 
| -                                     nmv_count->comps[i].fp, 0);
 | 
| -  }
 | 
| -  if (usehp) {
 | 
| -    for (i = 0; i < 2; ++i) {
 | 
| -      const uint32_t c0_hp0 = nmv_count->comps[i].class0_hp[0];
 | 
| -      const uint32_t c0_hp1 = nmv_count->comps[i].class0_hp[1];
 | 
| -      const uint32_t hp0 = nmv_count->comps[i].hp[0];
 | 
| -      const uint32_t hp1 = nmv_count->comps[i].hp[1];
 | 
| -
 | 
| -      prob->comps[i].class0_hp = get_binary_prob(c0_hp0, c0_hp1);
 | 
| -      branch_ct_class0_hp[i][0] = c0_hp0;
 | 
| -      branch_ct_class0_hp[i][1] = c0_hp1;
 | 
| -
 | 
| -      prob->comps[i].hp = get_binary_prob(hp0, hp1);
 | 
| -      branch_ct_hp[i][0] = hp0;
 | 
| -      branch_ct_hp[i][1] = hp1;
 | 
| -    }
 | 
| -  }
 | 
| +  vp9_tree_probs_from_distribution(tree, branch_ct, counts);
 | 
| +  for (i = 0; i < n - 1; ++i)
 | 
| +    update_mv(w, branch_ct[i], &probs[i], NMV_UPDATE_PROB);
 | 
|  }
 | 
|  
 | 
| -void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
 | 
| +void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer *w) {
 | 
|    int i, j;
 | 
| -  nmv_context prob;
 | 
| -  unsigned int branch_ct_joint[MV_JOINTS - 1][2];
 | 
| -  unsigned int branch_ct_sign[2][2];
 | 
| -  unsigned int branch_ct_classes[2][MV_CLASSES - 1][2];
 | 
| -  unsigned int branch_ct_class0[2][CLASS0_SIZE - 1][2];
 | 
| -  unsigned int branch_ct_bits[2][MV_OFFSET_BITS][2];
 | 
| -  unsigned int branch_ct_class0_fp[2][CLASS0_SIZE][4 - 1][2];
 | 
| -  unsigned int branch_ct_fp[2][4 - 1][2];
 | 
| -  unsigned int branch_ct_class0_hp[2][2];
 | 
| -  unsigned int branch_ct_hp[2][2];
 | 
|    nmv_context *mvc = &cpi->common.fc.nmvc;
 | 
| +  nmv_context_counts *counts = &cpi->NMVcount;
 | 
|  
 | 
| -  counts_to_nmv_context(&cpi->NMVcount, &prob, usehp,
 | 
| -                        branch_ct_joint, branch_ct_sign, branch_ct_classes,
 | 
| -                        branch_ct_class0, branch_ct_bits,
 | 
| -                        branch_ct_class0_fp, branch_ct_fp,
 | 
| -                        branch_ct_class0_hp, branch_ct_hp);
 | 
| +  write_mv_update(vp9_mv_joint_tree, mvc->joints, counts->joints, MV_JOINTS, w);
 | 
|  
 | 
| -  for (j = 0; j < MV_JOINTS - 1; ++j)
 | 
| -    update_mv(bc, branch_ct_joint[j], &mvc->joints[j], prob.joints[j],
 | 
| -              NMV_UPDATE_PROB);
 | 
| -
 | 
|    for (i = 0; i < 2; ++i) {
 | 
| -    update_mv(bc, branch_ct_sign[i], &mvc->comps[i].sign,
 | 
| -              prob.comps[i].sign, NMV_UPDATE_PROB);
 | 
| -    for (j = 0; j < MV_CLASSES - 1; ++j)
 | 
| -      update_mv(bc, branch_ct_classes[i][j], &mvc->comps[i].classes[j],
 | 
| -                prob.comps[i].classes[j], NMV_UPDATE_PROB);
 | 
| +    nmv_component *comp = &mvc->comps[i];
 | 
| +    nmv_component_counts *comp_counts = &counts->comps[i];
 | 
|  
 | 
| -    for (j = 0; j < CLASS0_SIZE - 1; ++j)
 | 
| -      update_mv(bc, branch_ct_class0[i][j], &mvc->comps[i].class0[j],
 | 
| -                prob.comps[i].class0[j], NMV_UPDATE_PROB);
 | 
| -
 | 
| +    update_mv(w, comp_counts->sign, &comp->sign, NMV_UPDATE_PROB);
 | 
| +    write_mv_update(vp9_mv_class_tree, comp->classes, comp_counts->classes,
 | 
| +                    MV_CLASSES, w);
 | 
| +    write_mv_update(vp9_mv_class0_tree, comp->class0, comp_counts->class0,
 | 
| +                    CLASS0_SIZE, w);
 | 
|      for (j = 0; j < MV_OFFSET_BITS; ++j)
 | 
| -      update_mv(bc, branch_ct_bits[i][j], &mvc->comps[i].bits[j],
 | 
| -                prob.comps[i].bits[j], NMV_UPDATE_PROB);
 | 
| +      update_mv(w, comp_counts->bits[j], &comp->bits[j], NMV_UPDATE_PROB);
 | 
|    }
 | 
|  
 | 
|    for (i = 0; i < 2; ++i) {
 | 
| -    for (j = 0; j < CLASS0_SIZE; ++j) {
 | 
| -      int k;
 | 
| -      for (k = 0; k < 3; ++k)
 | 
| -        update_mv(bc, branch_ct_class0_fp[i][j][k],
 | 
| -                  &mvc->comps[i].class0_fp[j][k],
 | 
| -                  prob.comps[i].class0_fp[j][k], NMV_UPDATE_PROB);
 | 
| -    }
 | 
| +    for (j = 0; j < CLASS0_SIZE; ++j)
 | 
| +      write_mv_update(vp9_mv_fp_tree, mvc->comps[i].class0_fp[j],
 | 
| +                      counts->comps[i].class0_fp[j], MV_FP_SIZE, w);
 | 
|  
 | 
| -    for (j = 0; j < 3; ++j)
 | 
| -      update_mv(bc, branch_ct_fp[i][j], &mvc->comps[i].fp[j],
 | 
| -                prob.comps[i].fp[j], NMV_UPDATE_PROB);
 | 
| +    write_mv_update(vp9_mv_fp_tree, mvc->comps[i].fp, counts->comps[i].fp,
 | 
| +                    MV_FP_SIZE, w);
 | 
|    }
 | 
|  
 | 
|    if (usehp) {
 | 
|      for (i = 0; i < 2; ++i) {
 | 
| -      update_mv(bc, branch_ct_class0_hp[i], &mvc->comps[i].class0_hp,
 | 
| -                prob.comps[i].class0_hp, NMV_UPDATE_PROB);
 | 
| -      update_mv(bc, branch_ct_hp[i], &mvc->comps[i].hp,
 | 
| -                prob.comps[i].hp, NMV_UPDATE_PROB);
 | 
| +      update_mv(w, counts->comps[i].class0_hp, &mvc->comps[i].class0_hp,
 | 
| +                NMV_UPDATE_PROB);
 | 
| +      update_mv(w, counts->comps[i].hp, &mvc->comps[i].hp, NMV_UPDATE_PROB);
 | 
|      }
 | 
|    }
 | 
|  }
 | 
| @@ -285,7 +209,7 @@
 | 
|    const MV_JOINT_TYPE j = vp9_get_mv_joint(&diff);
 | 
|    usehp = usehp && vp9_use_mv_hp(ref);
 | 
|  
 | 
| -  write_token(w, vp9_mv_joint_tree, mvctx->joints, &vp9_mv_joint_encodings[j]);
 | 
| +  vp9_write_token(w, vp9_mv_joint_tree, mvctx->joints, &mv_joint_encodings[j]);
 | 
|    if (mv_joint_vertical(j))
 | 
|      encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
 | 
|  
 | 
| @@ -345,3 +269,4 @@
 | 
|      inc_mvs(mbmi->mv, best_ref_mv, is_compound, &cpi->NMVcount);
 | 
|    }
 | 
|  }
 | 
| +
 | 
| 
 |