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); |
} |
} |
+ |