summaryrefslogtreecommitdiff
path: root/vp8/decoder/decodemv.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/decoder/decodemv.c')
-rw-r--r--vp8/decoder/decodemv.c113
1 files changed, 107 insertions, 6 deletions
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index d77340b0b..fc1098a44 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@@ -203,13 +203,13 @@ static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc)
static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc)
{
- mv->row = (short)(read_mvcomponent(r, mvc) << MV_SHIFT);
- mv->col = (short)(read_mvcomponent(r, ++mvc) << MV_SHIFT);
+ mv->row = (short)(read_mvcomponent(r, mvc) << 1);
+ mv->col = (short)(read_mvcomponent(r, ++mvc) << 1);
#ifdef DEBUG_DEC_MV
int i;
- printf("%d: %d %d\n", dec_mvcount++, mv->row, mv->col);
- for (i=0; i<MVPcount;++i) printf(" %d", (&mvc[-1])->prob[i]); printf("\n");
- for (i=0; i<MVPcount;++i) printf(" %d", (&mvc[0])->prob[i]); printf("\n");
+ printf("%d (np): %d %d\n", dec_mvcount++, mv->row, mv->col);
+ //for (i=0; i<MVPcount;++i) printf(" %d", (&mvc[-1])->prob[i]); printf("\n");
+ //for (i=0; i<MVPcount;++i) printf(" %d", (&mvc[0])->prob[i]); printf("\n");
#endif
}
@@ -238,6 +238,79 @@ static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc)
while (++i < 2);
}
+#if CONFIG_HIGH_PRECISION_MV
+static int read_mvcomponent_hp(vp8_reader *r, const MV_CONTEXT_HP *mvc)
+{
+ const vp8_prob *const p = (const vp8_prob *) mvc;
+ int x = 0;
+
+ if (vp8_read(r, p [mvpis_short_hp])) /* Large */
+ {
+ int i = 0;
+
+ do
+ {
+ x += vp8_read(r, p [MVPbits_hp + i]) << i;
+ }
+ while (++i < mvnum_short_bits_hp);
+
+ i = mvlong_width_hp - 1; /* Skip bit 3, which is sometimes implicit */
+
+ do
+ {
+ x += vp8_read(r, p [MVPbits_hp + i]) << i;
+ }
+ while (--i > mvnum_short_bits_hp);
+
+ if (!(x & ~((2<<mvnum_short_bits_hp)-1)) || vp8_read(r, p [MVPbits_hp + mvnum_short_bits_hp]))
+ x += (mvnum_short_hp);
+ }
+ else /* small */
+ x = vp8_treed_read(r, vp8_small_mvtree_hp, p + MVPshort_hp);
+
+ if (x && vp8_read(r, p [MVPsign_hp]))
+ x = -x;
+
+ return x;
+}
+
+static void read_mv_hp(vp8_reader *r, MV *mv, const MV_CONTEXT_HP *mvc)
+{
+ mv->row = (short)(read_mvcomponent_hp(r, mvc));
+ mv->col = (short)(read_mvcomponent_hp(r, ++mvc));
+#ifdef DEBUG_DEC_MV
+ int i;
+ printf("%d (hp): %d %d\n", dec_mvcount++, mv->row, mv->col);
+ //for (i=0; i<MVPcount_hp;++i) printf(" %d", (&mvc[-1])->prob[i]); printf("\n");
+ //for (i=0; i<MVPcount_hp;++i) printf(" %d", (&mvc[0])->prob[i]); printf("\n");
+#endif
+}
+
+static void read_mvcontexts_hp(vp8_reader *bc, MV_CONTEXT_HP *mvc)
+{
+ int i = 0;
+
+ do
+ {
+ const vp8_prob *up = vp8_mv_update_probs_hp[i].prob;
+ vp8_prob *p = (vp8_prob *)(mvc + i);
+ vp8_prob *const pstop = p + MVPcount_hp;
+
+ do
+ {
+ if (vp8_read(bc, *up++))
+ {
+ const vp8_prob x = (vp8_prob)vp8_read_literal(bc, 7);
+
+ *p = x ? x << 1 : 1;
+ }
+ }
+ while (++p < pstop);
+ }
+ while (++i < 2);
+}
+#endif /* CONFIG_HIGH_PRECISION_MV */
+
// Read the referncence frame
static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
vp8_reader *const bc,
@@ -406,6 +479,10 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
VP8_COMMON *const cm = & pbi->common;
vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc;
+#if CONFIG_HIGH_PRECISION_MV
+ MV_CONTEXT_HP *const mvc_hp = pbi->common.fc.mvc_hp;
+ MACROBLOCKD *const xd = & pbi->mb;
+#endif
pbi->prob_skip_false = 0;
if (pbi->common.mb_no_coeff_skip)
@@ -456,6 +533,11 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
while (++i < VP8_UV_MODES-1);
}
#endif /* CONFIG_UVINTRA */
+#if CONFIG_HIGH_PRECISION_MV
+ if (xd->allow_high_precision_mv)
+ read_mvcontexts_hp(bc, mvc_hp);
+ else
+#endif
read_mvcontexts(bc, mvc);
}
}
@@ -529,6 +611,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
VP8_COMMON *const cm = & pbi->common;
vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc;
+#if CONFIG_HIGH_PRECISION_MV
+ MV_CONTEXT_HP *const mvc_hp = pbi->common.fc.mvc_hp;
+#endif
const int mis = pbi->common.mode_info_stride;
MACROBLOCKD *const xd = & pbi->mb;
@@ -640,6 +725,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
switch (sub_mv_ref(bc, vp8_sub_mv_ref_prob2 [mv_contz])) /*pc->fc.sub_mv_ref_prob))*/
{
case NEW4X4:
+#if CONFIG_HIGH_PRECISION_MV
+ if (xd->allow_high_precision_mv)
+ read_mv_hp(bc, &blockmv.as_mv, (const MV_CONTEXT_HP *) mvc_hp);
+ else
+#endif
read_mv(bc, &blockmv.as_mv, (const MV_CONTEXT *) mvc);
blockmv.as_mv.row += best_mv.as_mv.row;
blockmv.as_mv.col += best_mv.as_mv.col;
@@ -717,6 +807,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
goto propagate_mv;
case NEWMV:
+#if CONFIG_HIGH_PRECISION_MV
+ if (xd->allow_high_precision_mv)
+ read_mv_hp(bc, &mv->as_mv, (const MV_CONTEXT_HP *) mvc_hp);
+ else
+#endif
read_mv(bc, &mv->as_mv, (const MV_CONTEXT *) mvc);
mv->as_mv.row += best_mv.as_mv.row;
mv->as_mv.col += best_mv.as_mv.col;
@@ -764,6 +859,12 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_top_edge, mb_to_bottom_edge);
break;
case NEWMV:
+#if CONFIG_HIGH_PRECISION_MV
+ if (xd->allow_high_precision_mv)
+ read_mv_hp(bc, &mbmi->second_mv.as_mv,
+ (const MV_CONTEXT_HP *) mvc_hp);
+ else
+#endif
read_mv(bc, &mbmi->second_mv.as_mv, (const MV_CONTEXT *) mvc);
mbmi->second_mv.as_mv.row += best_mv.as_mv.row;
mbmi->second_mv.as_mv.col += best_mv.as_mv.col;