]> granicus.if.org Git - libvpx/commitdiff
Initial refactoring of high_precision mv code.
authorDeb Mukherjee <debargha@google.com>
Mon, 27 Feb 2012 18:22:38 +0000 (10:22 -0800)
committerDeb Mukherjee <debargha@google.com>
Tue, 28 Feb 2012 23:09:20 +0000 (15:09 -0800)
This is the first patch for refactoring of the code related to
high-precision mv, so that 1/4 and 1/8 pel motion vectors can
co-exist in the same bit-stream by use of a frame level flag.
The current patch works fine for only use of 1/4th and
only use of 1/8th pel mv, but there are some issues with the
mode switching in between. Subsequent patches on this change Id
will fix the remaining issues.

Patch 2: Adds fixes to make sure that multiple mv precisions can
co-exist in the bit-stream. Frame level switching has been tested
to work correctly.

Patch 3: Fixes lines exceeding 80 char

Patch 4:
http://www.corp.google.com/~debargha/vp8_results/enhinterp.html

Results on derf after ssse3 bugfix, compared to everything
enabled but the 8-tap, 1/8-subpel and 1/16-subpel uv. Overall the
gains are about 3% now. Hopefully there are no more bugs lingering.
Apparently the sse3 bug affected the quartel subpel results more than
the eighth pel ones (which is understandabale because one bad predictor
due to the bug, matters less if there are a lot more subpel options
available as in the 1/8 subpel case).
The results in the 4th column correspond to the current settings.
The first two columns correspond to two settings of adaptive switching
of the 1/4 or 1/8 subpel mode based on initial Q estimate. These
do not work as good as just using 1/8 all the time yet.

Change-Id: I3ef392ad338329f4d68a85257a49f2b14f3af472

23 files changed:
vp8/common/entropymode.c
vp8/common/entropymode.h
vp8/common/entropymv.c
vp8/common/entropymv.h
vp8/common/filter.c
vp8/common/findnearmv.c
vp8/common/onyxc_int.h
vp8/decoder/decodemv.c
vp8/decoder/decodframe.c
vp8/encoder/bitstream.c
vp8/encoder/block.h
vp8/encoder/encodeframe.c
vp8/encoder/encodemv.c
vp8/encoder/encodemv.h
vp8/encoder/firstpass.c
vp8/encoder/mbgraph.c
vp8/encoder/mcomp.c
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h
vp8/encoder/quantize.c
vp8/encoder/ratectrl.c
vp8/encoder/rdopt.c
vp8/encoder/temporal_filter.c

index 540da33ed147ef6c54e3ed93516c4b80f2166b4d..f220a6ba0afdec6aa59f5184e46039a999d2f9ad 100644 (file)
@@ -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)
index 31170677c281d3b8287a34708b25a3df8c91a907..5c14ccaded9ba659d58e5464214cf8f79e915b81 100644 (file)
@@ -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);
index 4959fe92e94838e8271f89f856a9301a9e96edfd..90195f7bccdeb2c2de6413f5c10aa587ccca23f6 100644 (file)
@@ -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 */
index 390c4f4a28b52935e659272ed2b103d3cfd0ff5a..d97c12eab61caf883f746080ee83cab3b8ec9e77 100644 (file)
 #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
index 2e3acc29ceb492c8ebf9c5ba055af9cfbe9e79d7..d1ef79666df9c4ae5ed726df8c2184e94f4b28b6 100644 (file)
@@ -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:
index 2023a1910e7fe5a68322e2693353a2740ecd4dd7..a741471064dc630e92cfe2a07929fa7e31179d06 100644 (file)
@@ -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;
 }
-
index ba500cf160732fb4d758404151f398a1d6adf0ac..b7ce29e9a2abd45aa3ee1fa5a586e70e1f5b040a 100644 (file)
@@ -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
index d77340b0bcd533a16ee346fe5cf3ee065a82f535..fc1098a44dc92dccbcfd258b283cd3ddc7dd6cdd 100644 (file)
@@ -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;
index 0cb1d0e4881ee990a9d08b70967dcaa4d5a402d4..06673b4c2d3a599d26f1563fe62fa1a2209efc0a 100644 (file)
@@ -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);
 
index 2531e02735725293fa82732f13c663b6ed2e48d5..1a62e44ae6e1b84c82d6b93aedd657174aa48e99 100644 (file)
@@ -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);
                             }
                         }
index e197490529029dfbd55275744189fa439386512a..54f38590c6cd046157d78c2b84c629b9f9d10f8d 100644 (file)
@@ -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];
index e33e6ce6219b5182fcddfc28f3e6757700c55d6f..6c9c4f0420c7dd267438ad40040e0fdcd2702fcc 100644 (file)
@@ -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);
index 4d5d8cb813202ecdf412693516cd4c744b6fbba2..e3ddc2d54c00c2090452da8364c976f9efb8fdd9 100644 (file)
@@ -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 */
index a6116c133d01a6dc36b4eb3046d48f2f4d8eb9bf..09b0935cbf493f272c0c876bcf19fb4dbed1e34b 100644 (file)
 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
index 7d9c386655d68a01a42da9958a5bf9deca9a61b7..9cf875c4c7a6628b2a61e34c351518e9337f6af9 100644 (file)
@@ -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
index e0fed4a4741ff52f65d270c36839ae358d860bcc..3779f0622de0c7b29428f4ce7611dece470d2375 100644 (file)
@@ -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);
index 093ac3354c6d7d29756263ca235c8c31ef5d93e6..9f522279fcbad0ead67a6e630e021170012f3561 100644 (file)
@@ -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;
 }
index 285a8a2a5ca4048522a88b76be0a822e5fb12509..dcae1196faee9a3d693f7a865f91f1f00e872508 100644 (file)
@@ -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)
index 8aa4f1ff9345aa5fc5ca16a2e1b4adc37db90868..47de2c80411b95720414bd125a9e0ff7238ecc4d 100644 (file)
@@ -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
index 7ea712f7f72f741e0007214f03951ebb7538d82f..b14f8c4cc657870144caeec5e691790def6243c4 100644 (file)
@@ -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);
 }
-
index a501c3e5f526a0852aa5f79657a9a7ef913e6900..ad4a7e07ae86652cbadf62e3187b74b1b57f30b4 100644 (file)
@@ -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;
index c8b79615be15ae7a91e2c89b54977f9b4910f7a3..87e1d93da004b75e474d8553bb040d05f63b0e08 100644 (file)
@@ -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;
 
index ede65d669c2e71fd4bdb22ad4cf53e5f8f3c1e43..6c8b45857e7cb8978ff49473468f8e3f48902249 100644 (file)
@@ -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++)