diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
index 540da33ed147ef6c54e3ed93516c4b80f2166b4d..f220a6ba0afdec6aa59f5184e46039a999d2f9ad 100644
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -226,7 +226,7 @@ struct vp8_token_struct vp8_mv_ref_encoding_array    [VP8_MVREFS];
 struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
 
 #if CONFIG_HIGH_PRECISION_MV
-const vp8_tree_index vp8_small_mvtree [30] =
+const vp8_tree_index vp8_small_mvtree_hp [30] =
 {
      2,  16,
      4,  10,
@@ -244,9 +244,8 @@ const vp8_tree_index vp8_small_mvtree [30] =
    -12, -13,
    -14, -15
 };
-struct vp8_token_struct vp8_small_mvencodings [16];
-
-#else
+struct vp8_token_struct vp8_small_mvencodings_hp [16];
+#endif  /* CONFIG_HIGH_PRECISION_MV */
 
 const vp8_tree_index vp8_small_mvtree [14] =
 {
@@ -260,7 +259,6 @@ const vp8_tree_index vp8_small_mvtree [14] =
 };
 struct vp8_token_struct vp8_small_mvencodings [8];
 
-#endif  /* CONFIG_HIGH_PRECISION_MV */
 
 
 void vp8_init_mbmode_probs(VP8_COMMON *x)
@@ -381,6 +379,9 @@ void vp8_entropy_mode_init()
                                 vp8_sub_mv_ref_tree, LEFT4X4);
 
     vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree);
+#if CONFIG_HIGH_PRECISION_MV
+    vp8_tokens_from_tree(vp8_small_mvencodings_hp, vp8_small_mvtree_hp);
+#endif
 }
 
 void vp8_init_mode_contexts(VP8_COMMON *pc)
diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h
index 31170677c281d3b8287a34708b25a3df8c91a907..5c14ccaded9ba659d58e5464214cf8f79e915b81 100644
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -56,11 +56,10 @@ extern struct vp8_token_struct vp8_mv_ref_encoding_array    [VP8_MVREFS];
 extern struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
 
 extern const vp8_tree_index vp8_small_mvtree[];
-
-#if CONFIG_HIGH_PRECISION_MV
-extern struct vp8_token_struct vp8_small_mvencodings [16];
-#else
 extern struct vp8_token_struct vp8_small_mvencodings [8];
+#if CONFIG_HIGH_PRECISION_MV
+extern const vp8_tree_index vp8_small_mvtree_hp[];
+extern struct vp8_token_struct vp8_small_mvencodings_hp [16];
 #endif
 
 void vp8_entropy_mode_init(void);
diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c
index 4959fe92e94838e8271f89f856a9301a9e96edfd..90195f7bccdeb2c2de6413f5c10aa587ccca23f6 100644
--- a/vp8/common/entropymv.c
+++ b/vp8/common/entropymv.c
@@ -12,7 +12,7 @@
 #include "entropymv.h"
 
 #if CONFIG_HIGH_PRECISION_MV
-const MV_CONTEXT vp8_mv_update_probs[2] =
+const MV_CONTEXT_HP vp8_mv_update_probs_hp[2] =
 {
     {{
         237,
@@ -27,7 +27,7 @@ const MV_CONTEXT vp8_mv_update_probs[2] =
         254, 254, 254, 254, 254, 251, 251, 254, 254, 254, 254
     }}
 };
-const MV_CONTEXT vp8_default_mv_context[2] =
+const MV_CONTEXT_HP vp8_default_mv_context_hp[2] =
 {
     {{
         /* row */
@@ -44,7 +44,8 @@ const MV_CONTEXT vp8_default_mv_context[2] =
         128, 130, 130,  74, 148, 180, 203, 236, 254, 254, 254 /* long bits */
     }}
 };
-#else
+#endif  /* CONFIG_HIGH_PRECISION_MV */
+
 const MV_CONTEXT vp8_mv_update_probs[2] =
 {
     {{
@@ -77,4 +78,3 @@ const MV_CONTEXT vp8_default_mv_context[2] =
         128, 130, 130,  74, 148, 180, 203, 236, 254, 254 /* long bits */
     }}
 };
-#endif  /* CONFIG_HIGH_PRECISION_MV */
diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h
index 390c4f4a28b52935e659272ed2b103d3cfd0ff5a..d97c12eab61caf883f746080ee83cab3b8ec9e77 100644
--- a/vp8/common/entropymv.h
+++ b/vp8/common/entropymv.h
@@ -15,27 +15,13 @@
 #include "treecoder.h"
 #include "vpx_config.h"
 
-#if CONFIG_HIGH_PRECISION_MV
-#define MV_SHIFT 0
-#else
-#define MV_SHIFT 1
-#endif
-
 enum
 {
-#if CONFIG_HIGH_PRECISION_MV
-    mv_max  = 2047,              /* max absolute value of a MV component */
-    MVvals = (2 * mv_max) + 1,   /* # possible values "" */
-    mvlong_width = 11,       /* Large MVs have 9 bit magnitudes */
-    mvnum_short = 16,         /* magnitudes 0 through 15 */
-    mvnum_short_bits = 4,         /* number of bits for short mvs */
-#else
     mv_max  = 1023,              /* max absolute value of a MV component */
     MVvals = (2 * mv_max) + 1,   /* # possible values "" */
     mvlong_width = 10,       /* Large MVs have 9 bit magnitudes */
     mvnum_short = 8,         /* magnitudes 0 through 7 */
     mvnum_short_bits = 3,         /* number of bits for short mvs */
-#endif
 
     mvfp_max  = 255,              /* max absolute value of a full pixel MV component */
     MVfpvals = (2 * mvfp_max) + 1, /* # possible full pixel MV values */
@@ -57,4 +43,34 @@ typedef struct mv_context
 
 extern const MV_CONTEXT vp8_mv_update_probs[2], vp8_default_mv_context[2];
 
+#if CONFIG_HIGH_PRECISION_MV
+enum
+{
+    mv_max_hp  = 2047,              /* max absolute value of a MV component */
+    MVvals_hp = (2 * mv_max_hp) + 1,   /* # possible values "" */
+    mvlong_width_hp = 11,       /* Large MVs have 9 bit magnitudes */
+    mvnum_short_hp = 16,         /* magnitudes 0 through 15 */
+    mvnum_short_bits_hp = 4,         /* number of bits for short mvs */
+
+    mvfp_max_hp  = 255,              /* max absolute value of a full pixel MV component */
+    MVfpvals_hp = (2 * mvfp_max_hp) + 1, /* # possible full pixel MV values */
+
+    /* probability offsets for coding each MV component */
+
+    mvpis_short_hp = 0,         /* short (<= 7) vs long (>= 8) */
+    MVPsign_hp,                /* sign for non-zero */
+    MVPshort_hp,               /* 8 short values = 7-position tree */
+
+    MVPbits_hp = MVPshort_hp + mvnum_short_hp - 1, /* mvlong_width long value bits */
+    MVPcount_hp = MVPbits_hp + mvlong_width_hp    /* (with independent probabilities) */
+};
+
+typedef struct mv_context_hp
+{
+    vp8_prob prob[MVPcount_hp];  /* often come in row, col pairs */
+} MV_CONTEXT_HP;
+
+extern const MV_CONTEXT_HP vp8_mv_update_probs_hp[2], vp8_default_mv_context_hp[2];
+#endif /* CONFIG_HIGH_PRECISION_MV */
+
 #endif
diff --git a/vp8/common/filter.c b/vp8/common/filter.c
index 2e3acc29ceb492c8ebf9c5ba055af9cfbe9e79d7..d1ef79666df9c4ae5ed726df8c2184e94f4b28b6 100644
--- a/vp8/common/filter.c
+++ b/vp8/common/filter.c
@@ -45,7 +45,7 @@ DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[SUBPEL_SHIFTS][2]) =
 };
 
 #if CONFIG_ENHANCED_INTERP
-#define FILTER_ALPHA 0
+#define FILTER_ALPHA 60
 DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[SUBPEL_SHIFTS][2*INTERP_EXTEND]) =
 {
     /* Generated using MATLAB:
diff --git a/vp8/common/findnearmv.c b/vp8/common/findnearmv.c
index 2023a1910e7fe5a68322e2693353a2740ecd4dd7..a741471064dc630e92cfe2a07929fa7e31179d06 100644
--- a/vp8/common/findnearmv.c
+++ b/vp8/common/findnearmv.c
@@ -21,6 +21,7 @@ const unsigned char vp8_mbsplit_offset[4][16] = {
 /* Predict motion vectors using those from already-decoded nearby blocks.
    Note that we only consider one 4x4 subblock from each candidate 16x16
    macroblock.   */
+
 void vp8_find_near_mvs
 (
     MACROBLOCKD *xd,
@@ -145,6 +146,27 @@ void vp8_find_near_mvs
     nearest->as_int = near_mvs[CNT_NEAREST].as_int;
     nearby->as_int = near_mvs[CNT_NEAR].as_int;
 
+    /* Make sure that the 1/8th bits of the Mvs are zero if high_precision
+     * is not being used, by truncating the last bit towards 0
+     */
+#if CONFIG_HIGH_PRECISION_MV
+    if (!xd->allow_high_precision_mv)
+    {
+        if (best_mv->as_mv.row & 1)
+            best_mv->as_mv.row += (best_mv->as_mv.row > 0 ? -1 : 1);
+        if (best_mv->as_mv.col & 1)
+            best_mv->as_mv.col += (best_mv->as_mv.col > 0 ? -1 : 1);
+        if (nearest->as_mv.row & 1)
+            nearest->as_mv.row += (nearest->as_mv.row > 0 ? -1 : 1);
+        if (nearest->as_mv.col & 1)
+            nearest->as_mv.col += (nearest->as_mv.col > 0 ? -1 : 1);
+        if (nearby->as_mv.row & 1)
+            nearby->as_mv.row += (nearby->as_mv.row > 0 ? -1 : 1);
+        if (nearby->as_mv.col & 1)
+            nearby->as_mv.col += (nearby->as_mv.col > 0 ? -1 : 1);
+    }
+#endif
+
     //TODO: move clamp outside findnearmv
     vp8_clamp_mv2(nearest, xd);
     vp8_clamp_mv2(nearby, xd);
@@ -161,4 +183,3 @@ vp8_prob *vp8_mv_ref_probs(VP8_COMMON *pc,
     p[3] = pc->vp8_mode_contexts [near_mv_ref_ct[3]] [3];
     return p;
 }
-
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index ba500cf160732fb4d758404151f398a1d6adf0ac..b7ce29e9a2abd45aa3ee1fa5a586e70e1f5b040a 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -58,6 +58,10 @@ typedef struct frame_contexts
 #endif
     MV_CONTEXT mvc[2];
     MV_CONTEXT pre_mvc[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
+#if CONFIG_HIGH_PRECISION_MV
+    MV_CONTEXT_HP mvc_hp[2];
+    MV_CONTEXT_HP pre_mvc_hp[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
+#endif
 } FRAME_CONTEXT;
 
 typedef enum
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index d77340b0bcd533a16ee346fe5cf3ee065a82f535..fc1098a44dc92dccbcfd258b283cd3ddc7dd6cdd 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;
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 0cb1d0e4881ee990a9d08b70967dcaa4d5a402d4..06673b4c2d3a599d26f1563fe62fa1a2209efc0a 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -738,6 +738,10 @@ static void init_frame(VP8D_COMP *pbi)
     {
         /* Various keyframe initializations */
         vpx_memcpy(pc->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
+#if CONFIG_HIGH_PRECISION_MV
+        vpx_memcpy(pc->fc.mvc_hp, vp8_default_mv_context_hp,
+                   sizeof(vp8_default_mv_context_hp));
+#endif
 
         vp8_init_mbmode_probs(pc);
 
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 2531e02735725293fa82732f13c663b6ed2e48d5..1a62e44ae6e1b84c82d6b93aedd657174aa48e99 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -46,7 +46,6 @@ extern unsigned int active_section;
 int count_mb_seg[4] = { 0, 0, 0, 0 };
 #endif
 
-
 static void update_mode(
     vp8_writer *const w,
     int n,
@@ -389,6 +388,20 @@ static void write_mv
     vp8_encode_motion_vector(w, &e, mvc);
 }
 
+#if CONFIG_HIGH_PRECISION_MV
+static void write_mv_hp
+(
+    vp8_writer *w, const MV *mv, const int_mv *ref, const MV_CONTEXT_HP *mvc
+)
+{
+    MV e;
+    e.row = mv->row - ref->as_mv.row;
+    e.col = mv->col - ref->as_mv.col;
+
+    vp8_encode_motion_vector_hp(w, &e, mvc);
+}
+#endif
+
 // This function writes the current macro block's segnment id to the bitstream
 // It should only be called if a segment map update is indicated.
 static void write_mb_segid(vp8_writer *w,
@@ -556,6 +569,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
     VP8_COMMON *const pc = & cpi->common;
     vp8_writer *const w = & cpi->bc;
     const MV_CONTEXT *mvc = pc->fc.mvc;
+#if CONFIG_HIGH_PRECISION_MV
+    const MV_CONTEXT_HP *mvc_hp = pc->fc.mvc_hp;
+#endif
     MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
     int i;
@@ -643,6 +659,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
     update_mbintra_mode_probs(cpi);
 
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+        vp8_write_mvprobs_hp(cpi);
+    else
+#endif
     vp8_write_mvprobs(cpi);
 
     mb_row = 0;
@@ -806,6 +827,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                             active_section = 5;
 #endif
 
+#if CONFIG_HIGH_PRECISION_MV
+                            if (xd->allow_high_precision_mv)
+                                write_mv_hp(w, &mi->mv.as_mv, &best_mv, mvc_hp);
+                            else
+#endif
                             write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
 
                             if (cpi->common.dual_pred_mode == HYBRID_PREDICTION)
@@ -824,7 +850,14 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                                                   &n1, &n2, &best_mv,
                                                   ct, second_rf,
                                                   cpi->common.ref_frame_sign_bias);
-                                write_mv(w, &mi->second_mv.as_mv, &best_mv, mvc);
+#if CONFIG_HIGH_PRECISION_MV
+                                if (xd->allow_high_precision_mv)
+                                    write_mv_hp(w, &mi->second_mv.as_mv,
+                                                &best_mv, mvc_hp);
+                                else
+#endif
+                                write_mv(w, &mi->second_mv.as_mv, &best_mv,
+                                         mvc);
                             }
                             break;
 
@@ -867,7 +900,15 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 #ifdef ENTROPY_STATS
                                     active_section = 11;
 #endif
-                                    write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *) mvc);
+#if CONFIG_HIGH_PRECISION_MV
+                                    if (xd->allow_high_precision_mv)
+                                        write_mv_hp(w, &blockmv.as_mv, &best_mv,
+                                                    (const MV_CONTEXT_HP *)
+                                                    mvc_hp);
+                                    else
+#endif
+                                    write_mv(w, &blockmv.as_mv, &best_mv,
+                                             (const MV_CONTEXT *) mvc);
                                 }
                             }
                             while (++j < cpi->mb.partition_info->count);
@@ -908,6 +949,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
     VP8_COMMON *const pc = & cpi->common;
     vp8_writer *const w = & cpi->bc;
     const MV_CONTEXT *mvc = pc->fc.mvc;
+#if CONFIG_HIGH_PRECISION_MV
+    const MV_CONTEXT_HP *mvc_hp = pc->fc.mvc_hp;
+#endif
     MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
     int i;
@@ -992,6 +1036,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
     update_mbintra_mode_probs(cpi);
 
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+        vp8_write_mvprobs_hp(cpi);
+    else
+#endif
     vp8_write_mvprobs(cpi);
 
     while (++mb_row < pc->mb_rows)
@@ -1058,9 +1107,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
             if (rf == INTRA_FRAME)
             {
-    #ifdef ENTROPY_STATS
+#ifdef ENTROPY_STATS
                 active_section = 6;
-    #endif
+#endif
 
                 if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE ) )
                     write_ymode(w, mode, pc->fc.ymode_prob);
@@ -1131,12 +1180,18 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                     switch (mode)   /* new, split require MVs */
                     {
                     case NEWMV:
-    #ifdef ENTROPY_STATS
+#ifdef ENTROPY_STATS
                         active_section = 5;
-    #endif
+#endif
 
+#if CONFIG_HIGH_PRECISION_MV
+                        if (xd->allow_high_precision_mv)
+                            write_mv_hp(w, &mi->mv.as_mv, &best_mv, mvc_hp);
+                        else
+#endif
                         write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
 
+
                         if (cpi->common.dual_pred_mode == HYBRID_PREDICTION)
                         {
                             vp8_write(w, mi->second_ref_frame != INTRA_FRAME,
@@ -1152,6 +1207,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                                               &n1, &n2, &best_mv,
                                               ct, second_rf,
                                               cpi->common.ref_frame_sign_bias);
+#if CONFIG_HIGH_PRECISION_MV
+                            if (xd->allow_high_precision_mv)
+                                write_mv_hp(w, &mi->second_mv.as_mv, &best_mv, mvc_hp);
+                            else
+#endif
                             write_mv(w, &mi->second_mv.as_mv, &best_mv, mvc);
                         }
                         break;
@@ -1159,9 +1219,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                     {
                         int j = 0;
 
-    #ifdef MODE_STATS
+#ifdef MODE_STATS
                         ++count_mb_seg [mi->partitioning];
-    #endif
+#endif
 
                         write_split(w, mi->partitioning);
 
@@ -1176,13 +1236,13 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
                             blockmode =  cpi->mb.partition_info->bmi[j].mode;
                             blockmv =  cpi->mb.partition_info->bmi[j].mv;
-    #if CONFIG_DEBUG
+#if CONFIG_DEBUG
                             while (j != L[++k])
                                 if (k >= 16)
                                     assert(0);
-    #else
+#else
                             while (j != L[++k]);
-    #endif
+#endif
                             leftmv.as_int = left_block_mv(m, k);
                             abovemv.as_int = above_block_mv(m, k, mis);
                             mv_contz = vp8_mv_cont(&leftmv, &abovemv);
@@ -1191,9 +1251,14 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
 
                             if (blockmode == NEW4X4)
                             {
-    #ifdef ENTROPY_STATS
+#ifdef ENTROPY_STATS
                                 active_section = 11;
-    #endif
+#endif
+#if CONFIG_HIGH_PRECISION_MV
+                                if (xd->allow_high_precision_mv)
+                                    write_mv_hp(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT_HP *) mvc_hp);
+                                else
+#endif
                                 write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *) mvc);
                             }
                         }
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index e197490529029dfbd55275744189fa439386512a..54f38590c6cd046157d78c2b84c629b9f9d10f8d 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -97,6 +97,12 @@ typedef struct
     int *mvcost[2];
     int mvsadcosts[2][MVfpvals+1];
     int *mvsadcost[2];
+#if CONFIG_HIGH_PRECISION_MV
+    int mvcosts_hp[2][MVvals_hp+1];
+    int *mvcost_hp[2];
+    int mvsadcosts_hp[2][MVfpvals_hp+1];
+    int *mvsadcost_hp[2];
+#endif
     int mbmode_cost[2][MB_MODE_COUNT];
     int intra_uv_mode_cost[2][MB_MODE_COUNT];
     unsigned int bmode_costs[10][10][10];
@@ -119,6 +125,9 @@ typedef struct
 
     unsigned char *active_ptr;
     MV_CONTEXT *mvc;
+#if CONFIG_HIGH_PRECISION_MV
+    MV_CONTEXT_HP *mvc_hp;
+#endif
 
     unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS]
                             [PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index e33e6ce6219b5182fcddfc28f3e6757700c55d6f..6c9c4f0420c7dd267438ad40040e0fdcd2702fcc 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -605,7 +605,7 @@ void encode_sb_row (VP8_COMP *cpi,
                                   xd->mode_info_stride + col_delta[(i+1) & 0x3];
             int offset_unextended = row_delta[(i+1) & 0x3] *
                                     cm->mb_cols + col_delta[(i+1) & 0x3];
-           int dy = row_delta[i];
+            int dy = row_delta[i];
             int dx = col_delta[i];
 
             mb_row += dy;
@@ -1108,6 +1108,9 @@ static void encode_frame_internal(VP8_COMP *cpi)
     xd->prev_mode_info_context = cm->prev_mi;
 
     vp8_zero(cpi->MVcount);
+#if CONFIG_HIGH_PRECISION_MV
+    vp8_zero(cpi->MVcount_hp);
+#endif
     vp8_zero(cpi->coef_counts);
 
     vp8cx_frame_init_quantizer(cpi);
diff --git a/vp8/encoder/encodemv.c b/vp8/encoder/encodemv.c
index 4d5d8cb813202ecdf412693516cd4c744b6fbba2..e3ddc2d54c00c2090452da8364c976f9efb8fdd9 100644
--- a/vp8/encoder/encodemv.c
+++ b/vp8/encoder/encodemv.c
@@ -95,14 +95,17 @@ void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, const MV_CONTEXT *mvc
         }
     }
 #endif
-    encode_mvcomponent(w, mv->row >> MV_SHIFT, &mvc[0]);
-    encode_mvcomponent(w, mv->col >> MV_SHIFT, &mvc[1]);
+    encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
+    encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
 #ifdef DEBUG_ENC_MV
     {
     int i;
-    printf("%d: %d %d\n", enc_mvcount++, mv->row, mv->col);
-    for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[0])->prob[i]); printf("\n");
-    for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[1])->prob[i]); printf("\n");
+    printf("%d (np): %d %d\n", enc_mvcount++,
+           (mv->row >> 1)<<1, (mv->col >> 1)<<1);
+    //for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[0])->prob[i]);
+    //printf("\n");
+    //for (i=0; i<MVPcount;++i) printf("  %d", (&mvc[1])->prob[i]);
+    //printf("\n");
     fflush(stdout);
     }
 #endif
@@ -410,29 +413,362 @@ void vp8_write_mvprobs(VP8_COMP *cpi)
     vp8_writer *const w  = & cpi->bc;
     MV_CONTEXT *mvc = cpi->common.fc.mvc;
     int flags[2] = {0, 0};
+#ifdef ENTROPY_STATS
+    active_section = 4;
+#endif
+    write_component_probs(
+        w, &mvc[0], &vp8_default_mv_context[0], &vp8_mv_update_probs[0], cpi->MVcount[0], 0, &flags[0]
+    );
+    write_component_probs(
+        w, &mvc[1], &vp8_default_mv_context[1], &vp8_mv_update_probs[1], cpi->MVcount[1], 1, &flags[1]
+    );
+
+    if (flags[0] || flags[1])
+        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flags);
+
+#ifdef ENTROPY_STATS
+    active_section = 5;
+#endif
+}
+
+#if CONFIG_HIGH_PRECISION_MV
+
+static void encode_mvcomponent_hp(
+    vp8_writer *const w,
+    const int v,
+    const struct mv_context_hp *mvc
+)
+{
+    const vp8_prob *p = mvc->prob;
+    const int x = v < 0 ? -v : v;
+
+    if (x < mvnum_short_hp)     // Small
+    {
+        vp8_write(w, 0, p [mvpis_short_hp]);
+        vp8_treed_write(w, vp8_small_mvtree_hp, p + MVPshort_hp, x,
+                        mvnum_short_bits_hp);
+        if (!x)
+            return;         // no sign bit
+    }
+    else                    // Large
+    {
+        int i = 0;
+
+        vp8_write(w, 1, p [mvpis_short_hp]);
+
+        do
+            vp8_write(w, (x >> i) & 1, p [MVPbits_hp + i]);
+
+        while (++i < mvnum_short_bits_hp);
+
+        i = mvlong_width_hp - 1;  /* Skip bit 3, which is sometimes implicit */
+
+        do
+            vp8_write(w, (x >> i) & 1, p [MVPbits_hp + i]);
+
+        while (--i > mvnum_short_bits_hp);
+
+        if (x & ~((2<<mvnum_short_bits_hp)-1))
+            vp8_write(w, (x >> mvnum_short_bits_hp) & 1,
+                      p [MVPbits_hp + mvnum_short_bits_hp]);
+    }
+
+    vp8_write(w, v < 0, p [MVPsign_hp]);
+}
+#if 0
+static int max_mv_r = 0;
+static int max_mv_c = 0;
+#endif
+void vp8_encode_motion_vector_hp(vp8_writer *w, const MV *mv,
+                                 const MV_CONTEXT_HP *mvc)
+{
+
+#if 0
+    {
+        if (abs(mv->row >> 1) > max_mv_r)
+        {
+            FILE *f = fopen("maxmv.stt", "a");
+            max_mv_r = abs(mv->row >> 1);
+            fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
+
+            if ((abs(mv->row) / 2) != max_mv_r)
+                fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
+
+            fclose(f);
+        }
+
+        if (abs(mv->col >> 1) > max_mv_c)
+        {
+            FILE *f = fopen("maxmv.stt", "a");
+            fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
+            max_mv_c = abs(mv->col >> 1);
+            fclose(f);
+        }
+    }
+#endif
+    encode_mvcomponent_hp(w, mv->row, &mvc[0]);
+    encode_mvcomponent_hp(w, mv->col, &mvc[1]);
 #ifdef DEBUG_ENC_MV
     {
     int i;
-    printf("Writing probs\n");
-    for (i=0; i<MVPcount;++i) printf("  %d", vp8_default_mv_context[0].prob[i]); printf("\n");
-    for (i=0; i<MVPcount;++i) printf("  %d", vp8_default_mv_context[1].prob[i]); printf("\n");
+    printf("%d (hp): %d %d\n", enc_mvcount++, mv->row, mv->col);
+    //for (i=0; i<MVPcount_hp;++i) printf("  %d", (&mvc[0])->prob[i]);
+    //printf("\n");
+    //for (i=0; i<MVPcount_hp;++i) printf("  %d", (&mvc[1])->prob[i]);
+    //printf("\n");
     fflush(stdout);
     }
 #endif
+}
+
+
+static unsigned int cost_mvcomponent_hp(const int v,
+                                        const struct mv_context_hp *mvc)
+{
+    const vp8_prob *p = mvc->prob;
+    const int x = v;   //v<0? -v:v;
+    unsigned int cost;
+
+    if (x < mvnum_short_hp)
+    {
+        cost = vp8_cost_zero(p [mvpis_short_hp])
+               + vp8_treed_cost(vp8_small_mvtree_hp, p + MVPshort_hp, x,
+                                mvnum_short_bits_hp);
+
+        if (!x)
+            return cost;
+    }
+    else
+    {
+        int i = 0;
+        cost = vp8_cost_one(p [mvpis_short_hp]);
+
+        do
+            cost += vp8_cost_bit(p [MVPbits_hp + i], (x >> i) & 1);
+
+        while (++i < mvnum_short_bits_hp);
+
+        i = mvlong_width_hp - 1;  /* Skip bit 3, which is sometimes implicit */
+
+        do
+            cost += vp8_cost_bit(p [MVPbits_hp + i], (x >> i) & 1);
+
+        while (--i > mvnum_short_bits_hp);
+
+        if (x & ~((2<<mvnum_short_bits_hp)-1))
+            cost += vp8_cost_bit(p [MVPbits_hp + mvnum_short_bits_hp],
+                                 (x >> mvnum_short_bits_hp) & 1);
+    }
+
+    return cost;   // + vp8_cost_bit( p [MVPsign], v < 0);
+}
+
+void vp8_build_component_cost_table_hp(int *mvcost[2],
+                                       const MV_CONTEXT_HP *mvc,
+                                       int mvc_flag[2])
+{
+    int i = 1;   //-mv_max;
+    unsigned int cost0 = 0;
+    unsigned int cost1 = 0;
+
+    vp8_clear_system_state();
+
+    i = 1;
+
+    if (mvc_flag[0])
+    {
+        mvcost [0] [0] = cost_mvcomponent_hp(0, &mvc[0]);
+
+        do
+        {
+            //mvcost [0] [i] = cost_mvcomponent( i, &mvc[0]);
+            cost0 = cost_mvcomponent_hp(i, &mvc[0]);
+
+            mvcost [0] [i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign_hp]);
+            mvcost [0] [-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign_hp]);
+        }
+        while (++i <= mv_max_hp);
+    }
+
+    i = 1;
+
+    if (mvc_flag[1])
+    {
+        mvcost [1] [0] = cost_mvcomponent_hp(0, &mvc[1]);
+
+        do
+        {
+            //mvcost [1] [i] = cost_mvcomponent( i, mvc[1]);
+            cost1 = cost_mvcomponent_hp(i, &mvc[1]);
+
+            mvcost [1] [i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign_hp]);
+            mvcost [1] [-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign_hp]);
+        }
+        while (++i <= mv_max_hp);
+    }
+}
+
+
+static void write_component_probs_hp(
+    vp8_writer *const w,
+    struct mv_context_hp *cur_mvc,
+    const struct mv_context_hp *default_mvc_,
+    const struct mv_context_hp *update_mvc,
+    const unsigned int events [MVvals_hp],
+    unsigned int rc,
+    int *updated
+)
+{
+    vp8_prob *Pcur = cur_mvc->prob;
+    const vp8_prob *default_mvc = default_mvc_->prob;
+    const vp8_prob *Pupdate = update_mvc->prob;
+    unsigned int is_short_ct[2], sign_ct[2];
+
+    unsigned int bit_ct [mvlong_width_hp] [2];
+
+    unsigned int short_ct  [mvnum_short_hp];
+    unsigned int short_bct [mvnum_short_hp-1] [2];
+
+    vp8_prob Pnew [MVPcount_hp];
+
+    (void) rc;
+    vp8_copy_array(Pnew, default_mvc, MVPcount_hp);
+
+    vp8_zero(is_short_ct)
+    vp8_zero(sign_ct)
+    vp8_zero(bit_ct)
+    vp8_zero(short_ct)
+    vp8_zero(short_bct)
+
+
+    //j=0
+    {
+        const int c = events [mv_max];
+
+        is_short_ct [0] += c;    // Short vector
+        short_ct [0] += c;       // Magnitude distribution
+    }
+
+    //j: 1 ~ mv_max (1023)
+    {
+        int j = 1;
+
+        do
+        {
+            const int c1 = events [mv_max_hp + j];  //positive
+            const int c2 = events [mv_max_hp - j];  //negative
+            const int c  = c1 + c2;
+            int a = j;
+
+            sign_ct [0] += c1;
+            sign_ct [1] += c2;
+
+            if (a < mvnum_short_hp)
+            {
+                is_short_ct [0] += c;     // Short vector
+                short_ct [a] += c;       // Magnitude distribution
+            }
+            else
+            {
+                int k = mvlong_width_hp - 1;
+                is_short_ct [1] += c;     // Long vector
+
+                /*  bit 3 not always encoded. */
+                do
+                    bit_ct [k] [(a >> k) & 1] += c;
+
+                while (--k >= 0);
+            }
+        }
+        while (++j <= mv_max_hp);
+    }
+
+    calc_prob(Pnew + mvpis_short_hp, is_short_ct);
+
+    calc_prob(Pnew + MVPsign_hp, sign_ct);
+
+    {
+        vp8_prob p [mvnum_short_hp - 1];    /* actually only need branch ct */
+        int j = 0;
+
+        vp8_tree_probs_from_distribution(
+            mvnum_short_hp, vp8_small_mvencodings_hp, vp8_small_mvtree_hp,
+            p, short_bct, short_ct,
+            256, 1
+        );
+
+        do
+            calc_prob(Pnew + MVPshort_hp + j, short_bct[j]);
+
+        while (++j < mvnum_short_hp - 1);
+    }
+
+    {
+        int j = 0;
+
+        do
+            calc_prob(Pnew + MVPbits_hp + j, bit_ct[j]);
+
+        while (++j < mvlong_width_hp);
+    }
+
+    update(w, is_short_ct, Pcur + mvpis_short_hp, Pnew[mvpis_short_hp],
+           *Pupdate++, updated);
+
+    update(w, sign_ct, Pcur + MVPsign_hp, Pnew[MVPsign_hp], *Pupdate++,
+           updated);
+
+    {
+        const vp8_prob *const new_p = Pnew + MVPshort_hp;
+        vp8_prob *const cur_p = Pcur + MVPshort_hp;
+
+        int j = 0;
+
+        do
+
+            update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
+
+        while (++j < mvnum_short_hp - 1);
+    }
+
+    {
+        const vp8_prob *const new_p = Pnew + MVPbits_hp;
+        vp8_prob *const cur_p = Pcur + MVPbits_hp;
+
+        int j = 0;
+
+        do
+
+            update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
+
+        while (++j < mvlong_width_hp);
+    }
+}
+
+void vp8_write_mvprobs_hp(VP8_COMP *cpi)
+{
+    vp8_writer *const w  = & cpi->bc;
+    MV_CONTEXT_HP *mvc = cpi->common.fc.mvc_hp;
+    int flags[2] = {0, 0};
 #ifdef ENTROPY_STATS
     active_section = 4;
 #endif
-    write_component_probs(
-        w, &mvc[0], &vp8_default_mv_context[0], &vp8_mv_update_probs[0], cpi->MVcount[0], 0, &flags[0]
+    write_component_probs_hp(
+        w, &mvc[0], &vp8_default_mv_context_hp[0], &vp8_mv_update_probs_hp[0],
+        cpi->MVcount_hp[0], 0, &flags[0]
     );
-    write_component_probs(
-        w, &mvc[1], &vp8_default_mv_context[1], &vp8_mv_update_probs[1], cpi->MVcount[1], 1, &flags[1]
+    write_component_probs_hp(
+        w, &mvc[1], &vp8_default_mv_context_hp[1], &vp8_mv_update_probs_hp[1],
+        cpi->MVcount_hp[1], 1, &flags[1]
     );
 
     if (flags[0] || flags[1])
-        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flags);
+        vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp,
+                                          (const MV_CONTEXT_HP *)
+                                          cpi->common.fc.mvc_hp, flags);
 
 #ifdef ENTROPY_STATS
     active_section = 5;
 #endif
 }
+#endif  /* CONFIG_HIGH_PRECISION_MV */
diff --git a/vp8/encoder/encodemv.h b/vp8/encoder/encodemv.h
index a6116c133d01a6dc36b4eb3046d48f2f4d8eb9bf..09b0935cbf493f272c0c876bcf19fb4dbed1e34b 100644
--- a/vp8/encoder/encodemv.h
+++ b/vp8/encoder/encodemv.h
@@ -17,5 +17,10 @@
 void vp8_write_mvprobs(VP8_COMP *);
 void vp8_encode_motion_vector(vp8_writer *, const MV *, const MV_CONTEXT *);
 void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, int mvc_flag[2]);
+#if CONFIG_HIGH_PRECISION_MV
+void vp8_write_mvprobs_hp(VP8_COMP *);
+void vp8_encode_motion_vector_hp(vp8_writer *, const MV *, const MV_CONTEXT_HP *);
+void vp8_build_component_cost_table_hp(int *mvcost[2], const MV_CONTEXT_HP *mvc, int mvc_flag[2]);
+#endif  /* CONFIG_HIGH_PRECISION_MV */
 
 #endif
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 7d9c386655d68a01a42da9958a5bf9deca9a61b7..9cf875c4c7a6628b2a61e34c351518e9337f6af9 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -420,7 +420,12 @@ static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
     ref_mv_full.as_mv.row = ref_mv->as_mv.row>>3;
     tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, step_param,
                                       x->sadperbit16, &num00, &v_fn_ptr,
-                                      x->mvcost, ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                                      x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                      x->mvcost,
+#endif
+                                      ref_mv);
     if ( tmp_err < INT_MAX-new_mv_mode_penalty )
         tmp_err += new_mv_mode_penalty;
 
@@ -445,7 +450,12 @@ static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
         {
             tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv,
                                               step_param + n, x->sadperbit16,
-                                              &num00, &v_fn_ptr, x->mvcost,
+                                              &num00, &v_fn_ptr,
+#if CONFIG_HIGH_PRECISION_MV
+                                              x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                              x->mvcost,
+#endif
                                               ref_mv);
             if ( tmp_err < INT_MAX-new_mv_mode_penalty )
                 tmp_err += new_mv_mode_penalty;
@@ -520,6 +530,10 @@ void vp8_first_pass(VP8_COMP *cpi)
         vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
         vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
         vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
+#if CONFIG_HIGH_PRECISION_MV
+        vpx_memcpy(cm->fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp));
+        vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cm->fc.mvc_hp, flag);
+#endif
     }
 
     // for each macroblock row in image
diff --git a/vp8/encoder/mbgraph.c b/vp8/encoder/mbgraph.c
index e0fed4a4741ff52f65d270c36839ae358d860bcc..3779f0622de0c7b29428f4ce7611dece470d2375 100644
--- a/vp8/encoder/mbgraph.c
+++ b/vp8/encoder/mbgraph.c
@@ -35,6 +35,11 @@ static unsigned int do_16x16_motion_iteration
     static int dummy_cost[2*mv_max+1];
     int *mvcost[2]    = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
     int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
+#if CONFIG_HIGH_PRECISION_MV
+    static int dummy_cost_hp[2*mv_max_hp+1];
+    int *mvcost_hp[2]    = { &dummy_cost_hp[mv_max_hp+1], &dummy_cost[mv_max_hp+1] };
+    int *mvsadcost_hp[2] = { &dummy_cost_hp[mv_max_hp+1], &dummy_cost[mv_max_hp+1] };
+#endif
     int col_min = (ref_mv->as_mv.col>>3) - MAX_FULL_PEL_VAL + ((ref_mv->as_mv.col & 7)?1:0);
     int row_min = (ref_mv->as_mv.row>>3) - MAX_FULL_PEL_VAL + ((ref_mv->as_mv.row & 7)?1:0);
     int col_max = (ref_mv->as_mv.col>>3) + MAX_FULL_PEL_VAL;
@@ -76,7 +81,12 @@ static unsigned int do_16x16_motion_iteration
                              step_param,
                              x->errorperbit,
                              &v_fn_ptr,
-                             mvsadcost, mvcost, ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                             xd->allow_high_precision_mv?mvsadcost_hp:mvsadcost, xd->allow_high_precision_mv?mvcost_hp:mvcost,
+#else
+                             mvsadcost, mvcost,
+#endif
+                             ref_mv);
 
     // Try sub-pixel MC
     //if (bestsme > error_thresh && bestsme < INT_MAX)
@@ -86,7 +96,12 @@ static unsigned int do_16x16_motion_iteration
         best_err = cpi->find_fractional_mv_step(x, b, d,
                                                dst_mv, ref_mv,
                                                x->errorperbit, &v_fn_ptr,
-                                               mvcost, &distortion, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+                                               xd->allow_high_precision_mv?mvcost_hp:mvcost,
+#else
+                                               mvcost,
+#endif
+                                               &distortion, &sse);
     }
 
     vp8_set_mbmode_and_mvs(x, NEWMV, dst_mv);
diff --git a/vp8/encoder/mcomp.c b/vp8/encoder/mcomp.c
index 093ac3354c6d7d29756263ca235c8c31ef5d93e6..9f522279fcbad0ead67a6e630e021170012f3561 100644
--- a/vp8/encoder/mcomp.c
+++ b/vp8/encoder/mcomp.c
@@ -28,15 +28,35 @@ int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight)
     // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
     // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
     // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
-    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> MV_SHIFT] + mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> MV_SHIFT]) * Weight) >> 7;
+    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] + mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1]) * Weight) >> 7;
 }
+#if CONFIG_HIGH_PRECISION_MV
+int vp8_mv_bit_cost_hp(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight)
+{
+    // MV costing is based on the distribution of vectors in the previous frame and as such will tend to
+    // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
+    // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
+    // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
+    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row)] + mvcost[1][(mv->as_mv.col - ref->as_mv.col)]) * Weight) >> 7;
+}
+#endif
 
+#if CONFIG_HIGH_PRECISION_MV
+static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit, int ishp)
+{
+    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> (ishp==0)] +
+        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> (ishp==0)])
+        * error_per_bit + 128) >> 8;
+}
+#else
 static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit)
 {
-    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> MV_SHIFT] +
-        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> MV_SHIFT])
+    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
+        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
         * error_per_bit + 128) >> 8;
 }
+#endif
+
 
 static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit)
 {
@@ -46,6 +66,7 @@ static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_
         * error_per_bit + 128) >> 8;
 }
 
+
 void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride)
 {
     int Len;
@@ -176,31 +197,30 @@ void vp8_init3smotion_compensation(MACROBLOCK *x, int stride)
  * could reduce the area.
  */
 
-#if CONFIG_HIGH_PRECISION_MV
-
-#define PRE(r,c) (y + (((r)>>3) * y_stride + ((c)>>3) -(offset))) // pointer to predictor base of a motionvector
-#if CONFIG_SIXTEENTH_SUBPEL_UV
-#define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
-#else
-#define SP(x) ((x)&7) // convert motion vector component to offset for svf calc
-#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
-
-#else   /* CONFIG_HIGH_PRECISION_MV */
-
 #define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
 #if CONFIG_SIXTEENTH_SUBPEL_UV
 #define SP(x) (((x)&3)<<2) // convert motion vector component to offset for svf calc
 #else
 #define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
 #endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
-
-#endif  /* CONFIG_HIGH_PRECISION_MV */
-
 #define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c)-rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
 #define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
-#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
 #define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
+#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
+
+#if CONFIG_HIGH_PRECISION_MV
+#define PREHP(r,c) (y + (((r)>>3) * y_stride + ((c)>>3) -(offset))) // pointer to predictor base of a motionvector
+#if CONFIG_SIXTEENTH_SUBPEL_UV
+#define SPHP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
+#else /* CONFIG_SIXTEENTH_SUBPEL_UV */
+#define SPHP(x) ((x)&7) // convert motion vector component to offset for svf calc
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
+#define DISTHP(r,c) vfp->svf( PREHP(r,c), y_stride, SPHP(c),SPHP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
+#define ERRHP(r,c) (MVC(r,c)+DISTHP(r,c)) // returns distortion + motion vector cost
+#define CHECK_BETTER(v,r,c) IFMVCV(r,c,{thismse = ((xd->allow_high_precision_mv)?DISTHP(r,c):DIST(r,c)); if((v = (MVC(r,c)+thismse)) < besterr) { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
+#else
 #define CHECK_BETTER(v,r,c) IFMVCV(r,c,{thismse = DIST(r,c); if((v = (MVC(r,c)+thismse)) < besterr) { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
+#endif /* CONFIG_HIGH_PRECISION_MV */
 
 #define MIN(x,y) (((x)<(y))?(x):(y))
 #define MAX(x,y) (((x)>(y))?(x):(y))
@@ -213,17 +233,10 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                              unsigned int *sse1)
 {
     unsigned char *z = (*(b->base_src) + b->src);
+    MACROBLOCKD *xd = &x->e_mbd;
 
-#if CONFIG_HIGH_PRECISION_MV
-    int rr = ref_mv->as_mv.row, rc = ref_mv->as_mv.col;
-    int br = bestmv->as_mv.row << 3, bc = bestmv->as_mv.col << 3;
-    int hstep = 4;
-#else
-    int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
-    int br = bestmv->as_mv.row << 2, bc = bestmv->as_mv.col << 2;
-    int hstep = 2;
-#endif
-    int tr = br, tc = bc;
+    int rr, rc, br, bc, hstep;
+    int tr, tc;
     unsigned int besterr = INT_MAX;
     unsigned int left, right, up, down, diag;
     unsigned int sse;
@@ -234,24 +247,37 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     unsigned int eighthiters = 4;
 #endif
     int thismse;
+    int maxc, minc, maxr, minr;
+    int y_stride;
+    int offset;
 
 #if CONFIG_HIGH_PRECISION_MV
-    int minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << mvlong_width) - 1));
-    int maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << mvlong_width) - 1));
-    int minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << mvlong_width) - 1));
-    int maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << mvlong_width) - 1));
-#else
-    int minc = MAX(x->mv_col_min << 2, (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
-    int maxc = MIN(x->mv_col_max << 2, (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
-    int minr = MAX(x->mv_row_min << 2, (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
-    int maxr = MIN(x->mv_row_max << 2, (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
+    if (xd->allow_high_precision_mv)
+    {
+        rr = ref_mv->as_mv.row; rc = ref_mv->as_mv.col;
+        br = bestmv->as_mv.row << 3; bc = bestmv->as_mv.col << 3;
+        hstep = 4;
+        minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << mvlong_width) - 1));
+        maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << mvlong_width) - 1));
+        minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << mvlong_width) - 1));
+        maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << mvlong_width) - 1));
+    }
+    else
 #endif
+    {
+        rr = ref_mv->as_mv.row >> 1; rc = ref_mv->as_mv.col >> 1;
+        br = bestmv->as_mv.row << 2; bc = bestmv->as_mv.col << 2;
+        hstep = 2;
+        minc = MAX(x->mv_col_min << 2, (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
+        maxc = MIN(x->mv_col_max << 2, (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
+        minr = MAX(x->mv_row_min << 2, (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
+        maxr = MIN(x->mv_row_max << 2, (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
+    }
 
-    int y_stride;
-    int offset;
+    tr = br;
+    tc = bc;
 
 #if ARCH_X86 || ARCH_X86_64
-    MACROBLOCKD *xd = &x->e_mbd;
     unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
     unsigned char *y;
     int buf_r1, buf_r2, buf_c1, buf_c2;
@@ -280,7 +306,11 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     // calculate central point error
     besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
     *distortion = besterr;
+#if CONFIG_HIGH_PRECISION_MV
+    besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+#endif
 
     // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
     while (--halfiters)
@@ -390,12 +420,19 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
             tc = bc;
         }
     }
-    bestmv->as_mv.row = br;
-    bestmv->as_mv.col = bc;
-#else
-    bestmv->as_mv.row = br << 1;
-    bestmv->as_mv.col = bc << 1;
+#endif
+#if CONFIG_HIGH_PRECISION_MV
+    if (x->e_mbd.allow_high_precision_mv)
+    {
+        bestmv->as_mv.row = br;
+        bestmv->as_mv.col = bc;
+    }
+    else
 #endif  /* CONFIG_HIGH_PRECISION_MV */
+    {
+        bestmv->as_mv.row = br << 1;
+        bestmv->as_mv.col = bc << 1;
+    }
 
     if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL<<3)) ||
         (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL<<3)))
@@ -413,11 +450,18 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 #undef MIN
 #undef MAX
 
+#if CONFIG_HIGH_PRECISION_MV
+#undef PREHP
+#undef DPHP
+#undef DISTHP
+#undef ERRHP
+#endif
+
 #if CONFIG_SIXTEENTH_SUBPEL_UV
 #define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
 #else
 #define SP(x) ((x)&7) // convert motion vector component to offset for svf calc
-#endif  /* CONFIG_HIGH_PRECISION_MV */
+#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
 int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                  int_mv *bestmv, int_mv *ref_mv,
                                  int error_per_bit,
@@ -438,9 +482,9 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     int whichdir ;
     int thismse;
     int y_stride;
+    MACROBLOCKD *xd = &x->e_mbd;
 
 #if ARCH_X86 || ARCH_X86_64
-    MACROBLOCKD *xd = &x->e_mbd;
     unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
     unsigned char *y;
 
@@ -464,13 +508,21 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     // calculate central point error
     bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
     *distortion = bestmse;
+#if CONFIG_HIGH_PRECISION_MV
+    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+#endif
 
     // go left then right and check error
     this_mv.as_mv.row = startmv.as_mv.row;
     this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
     thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (left < bestmse)
     {
@@ -482,7 +534,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.col += 8;
     thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (right < bestmse)
     {
@@ -496,7 +552,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     this_mv.as_mv.col = startmv.as_mv.col;
     this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
     thismse =  vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (up < bestmse)
     {
@@ -508,7 +568,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.row += 8;
     thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (down < bestmse)
     {
@@ -550,7 +614,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         break;
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (diag < bestmse)
     {
@@ -598,7 +666,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (left < bestmse)
     {
@@ -610,7 +682,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.col += 4;
     thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (right < bestmse)
     {
@@ -634,7 +710,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (up < bestmse)
     {
@@ -646,7 +726,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.row += 4;
     thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (down < bestmse)
     {
@@ -737,7 +821,11 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         break;
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (diag < bestmse)
     {
@@ -780,7 +868,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
     }
 
-    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
 
     if (left < bestmse)
     {
@@ -792,7 +880,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.col += 2;
     thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
-    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
 
     if (right < bestmse)
     {
@@ -816,7 +904,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
     }
 
-    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
 
     if (up < bestmse)
     {
@@ -828,7 +916,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.row += 2;
     thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
-    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
 
     if (down < bestmse)
     {
@@ -919,7 +1007,7 @@ int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         break;
     }
 
-    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
 
     if (diag < bestmse)
     {
@@ -952,9 +1040,9 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     int whichdir ;
     int thismse;
     int y_stride;
+    MACROBLOCKD *xd = &x->e_mbd;
 
 #if ARCH_X86 || ARCH_X86_64
-    MACROBLOCKD *xd = &x->e_mbd;
     unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
     unsigned char *y;
 
@@ -975,13 +1063,21 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     // calculate central point error
     bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
     *distortion = bestmse;
+#if CONFIG_HIGH_PRECISION_MV
+    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+#endif
 
     // go left then right and check error
     this_mv.as_mv.row = startmv.as_mv.row;
     this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
     thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (left < bestmse)
     {
@@ -993,7 +1089,11 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.col += 8;
     thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (right < bestmse)
     {
@@ -1007,7 +1107,11 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     this_mv.as_mv.col = startmv.as_mv.col;
     this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
     thismse = vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (up < bestmse)
     {
@@ -1019,7 +1123,11 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     this_mv.as_mv.row += 8;
     thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (down < bestmse)
     {
@@ -1058,7 +1166,11 @@ int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
         break;
     }
 
+#if CONFIG_HIGH_PRECISION_MV
+    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
+#else
     diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+#endif
 
     if (diag < bestmse)
     {
@@ -1142,6 +1254,7 @@ int vp8_hex_search
     int k = -1;
     int all_in;
     int best_site = -1;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int_mv fcenter_mv;
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
@@ -1323,8 +1436,16 @@ int vp8_diamond_search_sad
 
     unsigned char *check_here;
     int thissad;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
     fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
@@ -1403,7 +1524,11 @@ int vp8_diamond_search_sad
         return INT_MAX;
 
     return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
 }
 
 int vp8_diamond_search_sadx4
@@ -1444,8 +1569,16 @@ int vp8_diamond_search_sadx4
 
     unsigned char *check_here;
     unsigned int thissad;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
     fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
@@ -1565,7 +1698,11 @@ int vp8_diamond_search_sadx4
         return INT_MAX;
 
     return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
 }
 
 int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
@@ -1586,6 +1723,7 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     unsigned char *check_here;
     int thissad;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int ref_row = ref_mv->as_mv.row;
     int ref_col = ref_mv->as_mv.col;
@@ -1596,6 +1734,13 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
     int col_max = ref_col + distance;
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
     fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
@@ -1655,7 +1800,11 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     if (bestsad < INT_MAX)
         return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
     else
         return INT_MAX;
 }
@@ -1678,6 +1827,7 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     unsigned char *check_here;
     unsigned int thissad;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int ref_row = ref_mv->as_mv.row;
     int ref_col = ref_mv->as_mv.col;
@@ -1690,6 +1840,13 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
     unsigned int sad_array[3];
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
     fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
@@ -1785,7 +1942,11 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     if (bestsad < INT_MAX)
         return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
     else
         return INT_MAX;
 }
@@ -1808,6 +1969,7 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     unsigned char *check_here;
     unsigned int thissad;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int ref_row = ref_mv->as_mv.row;
     int ref_col = ref_mv->as_mv.col;
@@ -1821,6 +1983,13 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
     unsigned int sad_array[3];
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
     fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
@@ -1945,7 +2114,11 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     if (bestsad < INT_MAX)
         return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
     else
         return INT_MAX;
 }
@@ -1968,8 +2141,16 @@ int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
     unsigned int thissad;
     int_mv this_mv;
     unsigned int bestsad = INT_MAX;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
 
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
@@ -2022,7 +2203,11 @@ int vp8_refining_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
 
     if (bestsad < INT_MAX)
         return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
     else
         return INT_MAX;
 }
@@ -2045,8 +2230,16 @@ int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     unsigned int thissad;
     int_mv this_mv;
     unsigned int bestsad = INT_MAX;
+    MACROBLOCKD *xd = &x->e_mbd;
 
     int *mvsadcost[2] = {x->mvsadcost[0], x->mvsadcost[1]};
+#if CONFIG_HIGH_PRECISION_MV
+    if (xd->allow_high_precision_mv)
+    {
+        mvsadcost[0] = x->mvsadcost_hp[0];
+        mvsadcost[1] = x->mvsadcost_hp[1];
+    }
+#endif
     int_mv fcenter_mv;
 
     fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
@@ -2135,7 +2328,11 @@ int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
 
     if (bestsad < INT_MAX)
         return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+#if CONFIG_HIGH_PRECISION_MV
+        + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit, xd->allow_high_precision_mv);
+#else
         + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
+#endif
     else
         return INT_MAX;
 }
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 285a8a2a5ca4048522a88b76be0a822e5fb12509..dcae1196faee9a3d693f7a865f91f1f00e872508 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -79,6 +79,14 @@ static void set_default_lf_deltas(VP8_COMP *cpi);
 
 extern const int vp8_gf_interval_table[101];
 
+#if CONFIG_HIGH_PRECISION_MV
+#define ALTREF_HIGH_PRECISION_MV 1      /* whether to use high precision mv for altref computation */
+#define HIGH_PRECISION_MV_QTHRESH 200   /* Q threshold for use of high precision mv */
+                                        /* Choose a very high value for now so
+                                         * that HIGH_PRECISION is always chosen
+                                         */
+#endif
+
 #if CONFIG_INTERNAL_STATS
 #include "math.h"
 
@@ -1334,7 +1342,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
 
     setup_features(cpi);
 #if CONFIG_HIGH_PRECISION_MV
-    cpi->mb.e_mbd.allow_high_precision_mv = 1;   // Default mv precision adaptation
+    cpi->mb.e_mbd.allow_high_precision_mv = 0;   // Default mv precision adaptation
 #endif
 
     {
@@ -1473,7 +1481,6 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
     cpi->alt_ref_source = NULL;
     cpi->is_src_frame_alt_ref = 0;
 
-
 #if 0
     // Experimental RD Code
     cpi->frame_distortion = 0;
@@ -1502,6 +1509,26 @@ static void cal_mvsadcosts(int *mvsadcost[2])
     while (++i <= mvfp_max);
 }
 
+#if CONFIG_HIGH_PRECISION_MV
+static void cal_mvsadcosts_hp(int *mvsadcost[2])
+{
+    int i = 1;
+
+    mvsadcost [0] [0] = 300;
+    mvsadcost [1] [0] = 300;
+
+    do
+    {
+        double z = 256 * (2 * (log2f(8 * i) + .6));
+        mvsadcost [0][i] = (int) z;
+        mvsadcost [1][i] = (int) z;
+        mvsadcost [0][-i] = (int) z;
+        mvsadcost [1][-i] = (int) z;
+    }
+    while (++i <= mvfp_max_hp);
+}
+#endif
+
 VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
 {
     int i;
@@ -1673,6 +1700,15 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
 
     cal_mvsadcosts(cpi->mb.mvsadcost);
 
+#if CONFIG_HIGH_PRECISION_MV
+    cpi->mb.mvcost_hp[0] = &cpi->mb.mvcosts_hp[0][mv_max_hp+1];
+    cpi->mb.mvcost_hp[1] = &cpi->mb.mvcosts_hp[1][mv_max_hp+1];
+    cpi->mb.mvsadcost_hp[0] = &cpi->mb.mvsadcosts_hp[0][mvfp_max_hp+1];
+    cpi->mb.mvsadcost_hp[1] = &cpi->mb.mvsadcosts_hp[1][mvfp_max_hp+1];
+
+    cal_mvsadcosts_hp(cpi->mb.mvsadcost_hp);
+#endif
+
     for (i = 0; i < KEY_FRAME_CONTEXT; i++)
     {
         cpi->prior_key_frame_distance[i] = (int)cpi->output_frame_rate;
@@ -2861,9 +2897,6 @@ static void encode_frame_to_data_rate
 
         // Reset the loop filter deltas and segmentation map
         setup_features(cpi);
-#if CONFIG_HIGH_PRECISION_MV
-        xd->allow_high_precision_mv = 1;   // Default mv precision adaptation
-#endif
 
         // If segmentation is enabled force a map update for key frames
         if (xd->segmentation_enabled)
@@ -3024,6 +3057,14 @@ static void encode_frame_to_data_rate
 
     loop_count = 0;
 
+#if CONFIG_HIGH_PRECISION_MV
+    /* Decide this based on various factors */
+    if (cm->frame_type != KEY_FRAME)
+    {
+        xd->allow_high_precision_mv = (Q < HIGH_PRECISION_MV_QTHRESH);
+    }
+#endif
+
 #if CONFIG_POSTPROC
 
     if (cpi->oxcf.noise_sensitivity > 0)
@@ -3460,6 +3501,7 @@ static void encode_frame_to_data_rate
     // build the bitstream
     vp8_pack_bitstream(cpi, dest, size);
 
+
     /* Move storing frame_type out of the above loop since it is also
      * needed in motion search besides loopfilter */
     cm->last_frame_type = cm->frame_type;
@@ -3755,7 +3797,7 @@ static void encode_frame_to_data_rate
         fclose(recon_file);
     }
 #endif
-#if OUTPUT_YUV_REC
+#ifdef OUTPUT_YUV_REC
     vp8_write_yuv_rec_frame(cm);
 #endif
 
@@ -3932,6 +3974,9 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
 
     cpi->source = NULL;
 
+#if CONFIG_HIGH_PRECISION_MV
+    cpi->mb.e_mbd.allow_high_precision_mv = ALTREF_HIGH_PRECISION_MV;
+#endif
     // Should we code an alternate reference frame
     if (cpi->oxcf.play_alternate &&
         cpi->source_alt_ref_pending)
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 8aa4f1ff9345aa5fc5ca16a2e1b4adc37db90868..47de2c80411b95720414bd125a9e0ff7238ecc4d 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -64,6 +64,10 @@ typedef struct
 
     MV_CONTEXT mvc[2];
     int mvcosts[2][MVvals+1];
+#if CONFIG_HIGH_PRECISION_MV
+    MV_CONTEXT_HP mvc_hp[2];
+    int mvcosts_hp[2][MVvals_hp+1];
+#endif
 
 #ifdef MODE_STATS
     // Stats
@@ -440,6 +444,9 @@ typedef struct VP8_COMP
     int uv_mode_count[VP8_UV_MODES];       /* intra MB type cts this frame */
 
     unsigned int MVcount [2] [MVvals];  /* (row,col) MV cts this frame */
+#if CONFIG_HIGH_PRECISION_MV
+    unsigned int MVcount_hp [2] [MVvals_hp];  /* (row,col) MV cts this frame */
+#endif
 
     unsigned int coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];  /* for this frame */
     //DECLARE_ALIGNED(16, int, coef_counts_backup [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]);   //not used any more
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c
index 7ea712f7f72f741e0007214f03951ebb7538d82f..b14f8c4cc657870144caeec5e691790def6243c4 100644
--- a/vp8/encoder/quantize.c
+++ b/vp8/encoder/quantize.c
@@ -75,7 +75,7 @@ void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
 
 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
 {
-    int i, rc, eob;
+    int i, rc, eob, nonzeros;
     int x, y, z, sz;
     short *coeff_ptr   = b->coeff;
     short *round_ptr   = b->round;
@@ -1295,4 +1295,3 @@ void vp8_set_quantizer(struct VP8_COMP *cpi, int Q)
     //if(update)
     //    vp8cx_init_quantizer(cpi);
 }
-
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index a501c3e5f526a0852aa5f79657a9a7ef913e6900..ad4a7e07ae86652cbadf62e3187b74b1b57f30b4 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -148,6 +148,10 @@ void vp8_save_coding_context(VP8_COMP *cpi)
 
     vp8_copy(cc->mvc,      cpi->common.fc.mvc);
     vp8_copy(cc->mvcosts,  cpi->mb.mvcosts);
+#if CONFIG_HIGH_PRECISION_MV
+    vp8_copy(cc->mvc_hp,      cpi->common.fc.mvc_hp);
+    vp8_copy(cc->mvcosts_hp,  cpi->mb.mvcosts_hp);
+#endif
 
     vp8_copy(cc->kf_ymode_prob,   cpi->common.kf_ymode_prob);
     vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
@@ -187,6 +191,11 @@ void vp8_restore_coding_context(VP8_COMP *cpi)
     vp8_copy(cpi->common.fc.mvc, cc->mvc);
 
     vp8_copy(cpi->mb.mvcosts, cc->mvcosts);
+#if CONFIG_HIGH_PRECISION_MV
+    vp8_copy(cpi->common.fc.mvc_hp, cc->mvc_hp);
+
+    vp8_copy(cpi->mb.mvcosts_hp, cc->mvcosts_hp);
+#endif
     vp8_copy(cpi->common.kf_ymode_prob,   cc->kf_ymode_prob);
     vp8_copy(cpi->common.fc.ymode_prob,   cc->ymode_prob);
     vp8_copy(cpi->common.kf_uv_mode_prob,  cc->kf_uv_mode_prob);
@@ -222,8 +231,16 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
         int flag[2] = {1, 1};
         vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag);
     }
-
     vpx_memset(cpi->common.fc.pre_mvc, 0, sizeof(cpi->common.fc.pre_mvc));  //initialize pre_mvc to all zero.
+#if CONFIG_HIGH_PRECISION_MV
+    vpx_memcpy(cpi->common.fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp));
+    {
+        int flag[2] = {1, 1};
+        vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flag);
+    }
+    vpx_memset(cpi->common.fc.pre_mvc_hp, 0, sizeof(cpi->common.fc.pre_mvc_hp));  //initialize pre_mvc to all zero.
+#endif
+
 
 #if CONFIG_T8X8
     cpi->common.txfm_mode = ONLY_4X4;
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index c8b79615be15ae7a91e2c89b54977f9b4910f7a3..87e1d93da004b75e474d8553bb040d05f63b0e08 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1601,7 +1601,12 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
                         bestsme = cpi->diamond_search_sad(x, c, e, &mvp_full,
                                                 &mode_mv[NEW4X4], step_param,
                                                 sadpb, &num00, v_fn_ptr,
-                                                x->mvcost, bsi->ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                                                x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                                x->mvcost,
+#endif
+                                                bsi->ref_mv);
 
                         n = num00;
                         num00 = 0;
@@ -1618,7 +1623,12 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
                                                     &mvp_full, &temp_mv,
                                                     step_param + n, sadpb,
                                                     &num00, v_fn_ptr,
-                                                    x->mvcost, bsi->ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                                                    x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                                    x->mvcost,
+#endif
+                                                    bsi->ref_mv);
 
                                 if (thissme < bestsme)
                                 {
@@ -1639,7 +1649,12 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
 
                         thissme = cpi->full_search_sad(x, c, e, &mvp_full,
                                                        sadpb, 16, v_fn_ptr,
-                                                       x->mvcost, bsi->ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                                                       x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                                       x->mvcost,
+#endif
+                                                       bsi->ref_mv);
 
                         if (thissme < bestsme)
                         {
@@ -1659,7 +1674,12 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
                     int distortion;
                     unsigned int sse;
                     cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4],
-                        bsi->ref_mv, x->errorperbit, v_fn_ptr, x->mvcost,
+                        bsi->ref_mv, x->errorperbit, v_fn_ptr,
+#if CONFIG_HIGH_PRECISION_MV
+                        x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                        x->mvcost,
+#endif
                         &distortion, &sse);
                 }
             } /* NEW4X4 */
@@ -2154,19 +2174,43 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv)
         {
             if (x->partition_info->bmi[i].mode == NEW4X4)
             {
-                cpi->MVcount[0][mv_max+((x->partition_info->bmi[i].mv.as_mv.row
-                                          - best_ref_mv->as_mv.row) >> MV_SHIFT)]++;
-                cpi->MVcount[1][mv_max+((x->partition_info->bmi[i].mv.as_mv.col
-                                          - best_ref_mv->as_mv.col) >> MV_SHIFT)]++;
+#if CONFIG_HIGH_PRECISION_MV
+                if (x->e_mbd.allow_high_precision_mv)
+                {
+                    cpi->MVcount_hp[0][mv_max_hp+(x->partition_info->bmi[i].mv.as_mv.row
+                                              - best_ref_mv->as_mv.row)]++;
+                    cpi->MVcount_hp[1][mv_max_hp+(x->partition_info->bmi[i].mv.as_mv.col
+                                              - best_ref_mv->as_mv.col)]++;
+                }
+                else
+#endif
+                {
+                    cpi->MVcount[0][mv_max+((x->partition_info->bmi[i].mv.as_mv.row
+                                              - best_ref_mv->as_mv.row) >> 1)]++;
+                    cpi->MVcount[1][mv_max+((x->partition_info->bmi[i].mv.as_mv.col
+                                              - best_ref_mv->as_mv.col) >> 1)]++;
+                }
             }
         }
     }
     else if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV)
     {
-        cpi->MVcount[0][mv_max+((x->e_mbd.mode_info_context->mbmi.mv.as_mv.row
-                                          - best_ref_mv->as_mv.row) >> MV_SHIFT)]++;
-        cpi->MVcount[1][mv_max+((x->e_mbd.mode_info_context->mbmi.mv.as_mv.col
-                                          - best_ref_mv->as_mv.col) >> MV_SHIFT)]++;
+#if CONFIG_HIGH_PRECISION_MV
+        if (x->e_mbd.allow_high_precision_mv)
+        {
+            cpi->MVcount_hp[0][mv_max_hp+(x->e_mbd.mode_info_context->mbmi.mv.as_mv.row
+                                              - best_ref_mv->as_mv.row)]++;
+            cpi->MVcount_hp[1][mv_max_hp+(x->e_mbd.mode_info_context->mbmi.mv.as_mv.col
+                                              - best_ref_mv->as_mv.col)]++;
+        }
+        else
+#endif
+        {
+            cpi->MVcount[0][mv_max+((x->e_mbd.mode_info_context->mbmi.mv.as_mv.row
+                                              - best_ref_mv->as_mv.row) >> 1)]++;
+            cpi->MVcount[1][mv_max+((x->e_mbd.mode_info_context->mbmi.mv.as_mv.col
+                                              - best_ref_mv->as_mv.col) >> 1)]++;
+        }
     }
 }
 
@@ -2640,7 +2684,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                 bestsme = cpi->diamond_search_sad(x, b, d, &mvp_full, &d->bmi.mv,
                                         step_param, sadpb, &num00,
                                         &cpi->fn_ptr[BLOCK_16X16],
-                                        x->mvcost, &best_ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                                        x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                        x->mvcost,
+#endif
+                                        &best_ref_mv);
                 mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
 
                 // Further step/diamond searches as necessary
@@ -2664,7 +2713,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                     {
                         thissme = cpi->diamond_search_sad(x, b, d, &mvp_full,
                                     &d->bmi.mv, step_param + n, sadpb, &num00,
-                                    &cpi->fn_ptr[BLOCK_16X16], x->mvcost,
+                                    &cpi->fn_ptr[BLOCK_16X16],
+#if CONFIG_HIGH_PRECISION_MV
+                                    x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                    x->mvcost,
+#endif
                                     &best_ref_mv);
 
                         /* check to see if refining search is needed. */
@@ -2696,7 +2750,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                 //thissme = cpi->full_search_sad(x, b, d, &d->bmi.mv.as_mv, sadpb, search_range, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv);
                 thissme = cpi->refining_search_sad(x, b, d, &d->bmi.mv, sadpb,
                                        search_range, &cpi->fn_ptr[BLOCK_16X16],
-                                       x->mvcost, &best_ref_mv);
+#if CONFIG_HIGH_PRECISION_MV
+                                       x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                       x->mvcost,
+#endif
+                                       &best_ref_mv);
 
                 if (thissme < bestsme)
                 {
@@ -2721,7 +2780,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                 cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv, &best_ref_mv,
                                              x->errorperbit,
                                              &cpi->fn_ptr[BLOCK_16X16],
-                                             x->mvcost, &dis, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+                                             x->e_mbd.allow_high_precision_mv?x->mvcost_hp:x->mvcost,
+#else
+                                             x->mvcost,
+#endif
+                                             &dis, &sse);
             }
             mc_search_result[x->e_mbd.mode_info_context->mbmi.ref_frame].as_int = d->bmi.mv.as_int;
 
diff --git a/vp8/encoder/temporal_filter.c b/vp8/encoder/temporal_filter.c
index ede65d669c2e71fd4bdb22ad4cf53e5f8f3c1e43..6c8b45857e7cb8978ff49473468f8e3f48902249 100644
--- a/vp8/encoder/temporal_filter.c
+++ b/vp8/encoder/temporal_filter.c
@@ -36,6 +36,7 @@
 
 #if VP8_TEMPORAL_ALT_REF
 
+
 static void vp8_temporal_filter_predictors_mb_c
 (
     MACROBLOCKD *x,
@@ -154,6 +155,9 @@ void vp8_temporal_filter_apply_c
 
 #if ALT_REF_MC_ENABLED
 static int dummy_cost[2*mv_max+1];
+#if CONFIG_HIGH_PRECISION_MV
+static int dummy_cost_hp[2*mv_max_hp+1];
+#endif
 
 static int vp8_temporal_filter_find_matching_mb_c
 (
@@ -177,6 +181,10 @@ static int vp8_temporal_filter_find_matching_mb_c
 
     int *mvcost[2]    = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
     int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
+#if CONFIG_HIGH_PRECISION_MV
+    int *mvcost_hp[2]    = { &dummy_cost_hp[mv_max_hp+1], &dummy_cost_hp[mv_max_hp+1] };
+    int *mvsadcost_hp[2] = { &dummy_cost_hp[mv_max_hp+1], &dummy_cost_hp[mv_max_hp+1] };
+#endif
 
     // Save input state
     unsigned char **base_src = b->base_src;
@@ -220,7 +228,13 @@ static int vp8_temporal_filter_find_matching_mb_c
         step_param,
         sadpb,
         &cpi->fn_ptr[BLOCK_16X16],
-        mvsadcost, mvcost, &best_ref_mv1);
+#if CONFIG_HIGH_PRECISION_MV
+        x->e_mbd.allow_high_precision_mv?mvsadcost_hp:mvsadcost,
+        x->e_mbd.allow_high_precision_mv?mvcost_hp:mvcost,
+#else
+        mvsadcost, mvcost,
+#endif
+        &best_ref_mv1);
 
 #if ALT_REF_SUBPEL_ENABLED
     // Try sub-pixel MC?
@@ -231,7 +245,12 @@ static int vp8_temporal_filter_find_matching_mb_c
         bestsme = cpi->find_fractional_mv_step(x, b, d,
                     &d->bmi.mv, &best_ref_mv1,
                     x->errorperbit, &cpi->fn_ptr[BLOCK_16X16],
-                    mvcost, &distortion, &sse);
+#if CONFIG_HIGH_PRECISION_MV
+                    x->e_mbd.allow_high_precision_mv?mvcost_hp:mvcost,
+#else
+                    mvcost,
+#endif
+                    &distortion, &sse);
     }
 #endif
 
@@ -280,17 +299,17 @@ static void vp8_temporal_filter_iterate_c
 #if ALT_REF_MC_ENABLED
         // Source frames are extended to 16 pixels.  This is different than
         //  L/A/G reference frames that have a border of 32 (VP8BORDERINPIXELS)
-        // A 6 tap filter is used for motion search.  This requires 2 pixels
+        // A 6/8 tap filter is used for motion search.  This requires 2 pixels
         //  before and 3 pixels after.  So the largest Y mv on a border would
-        //  then be 16 - 3.  The UV blocks are half the size of the Y and
+        //  then be 16 - INTERP_EXTEND. The UV blocks are half the size of the Y and
         //  therefore only extended by 8.  The largest mv that a UV block
-        //  can support is 8 - 3.  A UV mv is half of a Y mv.
-        //  (16 - 3) >> 1 == 6 which is greater than 8 - 3.
+        //  can support is 8 - INTERP_EXTEND.  A UV mv is half of a Y mv.
+        //  (16 - INTERP_EXTEND) >> 1 which is greater than 8 - INTERP_EXTEND.
         // To keep the mv in play for both Y and UV planes the max that it
-        //  can be on a border is therefore 16 - 5.
-        cpi->mb.mv_row_min = -((mb_row * 16) + (16 - 5));
+        //  can be on a border is therefore 16 - (2*INTERP_EXTEND+1).
+        cpi->mb.mv_row_min = -((mb_row * 16) + (17 - 2*INTERP_EXTEND));
         cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16)
-                                + (16 - 5);
+                                + (17 - 2*INTERP_EXTEND);
 #endif
 
         for (mb_col = 0; mb_col < mb_cols; mb_col++)
@@ -302,9 +321,9 @@ static void vp8_temporal_filter_iterate_c
             vpx_memset(count, 0, 384*sizeof(unsigned short));
 
 #if ALT_REF_MC_ENABLED
-            cpi->mb.mv_col_min = -((mb_col * 16) + (16 - 5));
+            cpi->mb.mv_col_min = -((mb_col * 16) + (17 - 2*INTERP_EXTEND));
             cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16)
-                                    + (16 - 5);
+                                    + (17 - 2*INTERP_EXTEND);
 #endif
 
             for (frame = 0; frame < frame_count; frame++)