ref: 3e1cad9c69e9d89ecbed47ba187ccb5d48ae0a77
parent: 3d93ae521c4bd71f3be833ab16d93fb35ab1f8d1
author: Deb Mukherjee <debargha@google.com>
date: Mon Feb 27 05:22:38 EST 2012
Initial refactoring of high_precision mv code. 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
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -226,7 +226,7 @@
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,10 +244,9 @@
-12, -13,
-14, -15
};
-struct vp8_token_struct vp8_small_mvencodings [16];
+struct vp8_token_struct vp8_small_mvencodings_hp [16];
+#endif /* CONFIG_HIGH_PRECISION_MV */
-#else
-
const vp8_tree_index vp8_small_mvtree [14] =
{
2, 8,
@@ -260,7 +259,6 @@
};
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 @@
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)
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -56,11 +56,10 @@
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);
--- a/vp8/common/entropymv.c
+++ b/vp8/common/entropymv.c
@@ -12,7 +12,7 @@
#include "entropymv.h"
#if CONFIG_HIGH_PRECISION_MV
-const MV_CONTEXT vp8_mv_update_probs[2] =
+const MV_CONTEXT_HP vp8_mv_update_probs_hp[2] =
{
{{
237,
@@ -27,7 +27,7 @@
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 @@
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 @@
128, 130, 130, 74, 148, 180, 203, 236, 254, 254 /* long bits */
}}
};
-#endif /* CONFIG_HIGH_PRECISION_MV */
--- a/vp8/common/entropymv.h
+++ b/vp8/common/entropymv.h
@@ -15,27 +15,13 @@
#include "treecoder.h"
#include "vpx_config.h"
-#if CONFIG_HIGH_PRECISION_MV
-#define MV_SHIFT 0
-#else
-#define MV_SHIFT 1
-#endif
-
enum
{
-#if CONFIG_HIGH_PRECISION_MV
- mv_max = 2047, /* max absolute value of a MV component */
- MVvals = (2 * mv_max) + 1, /* # possible values "" */
- mvlong_width = 11, /* Large MVs have 9 bit magnitudes */
- mvnum_short = 16, /* magnitudes 0 through 15 */
- mvnum_short_bits = 4, /* number of bits for short mvs */
-#else
mv_max = 1023, /* max absolute value of a MV component */
MVvals = (2 * mv_max) + 1, /* # possible values "" */
mvlong_width = 10, /* Large MVs have 9 bit magnitudes */
mvnum_short = 8, /* magnitudes 0 through 7 */
mvnum_short_bits = 3, /* number of bits for short mvs */
-#endif
mvfp_max = 255, /* max absolute value of a full pixel MV component */
MVfpvals = (2 * mvfp_max) + 1, /* # possible full pixel MV values */
@@ -56,5 +42,35 @@
} 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
--- a/vp8/common/filter.c
+++ b/vp8/common/filter.c
@@ -45,7 +45,7 @@
};
#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:
--- a/vp8/common/findnearmv.c
+++ b/vp8/common/findnearmv.c
@@ -21,6 +21,7 @@
/* 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 @@
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 @@
p[3] = pc->vp8_mode_contexts [near_mv_ref_ct[3]] [3];
return p;
}
-
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -58,6 +58,10 @@
#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
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@@ -203,13 +203,13 @@
static 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -738,6 +738,10 @@
{
/* 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);
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -46,7 +46,6 @@
int count_mb_seg[4] = { 0, 0, 0, 0 };
#endif
-
static void update_mode(
vp8_writer *const w,
int n,
@@ -389,6 +388,20 @@
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 @@
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 @@
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 @@
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 @@
&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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
&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 @@
{
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 @@
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 @@
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);
}
}
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -97,6 +97,12 @@
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 @@
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];
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -605,7 +605,7 @@
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 @@
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);
--- a/vp8/encoder/encodemv.c
+++ b/vp8/encoder/encodemv.c
@@ -95,14 +95,17 @@
}
}
#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 @@
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 */
--- a/vp8/encoder/encodemv.h
+++ b/vp8/encoder/encodemv.h
@@ -17,5 +17,10 @@
void vp8_write_mvprobs(VP8_COMP *);
void vp8_encode_motion_vector(vp8_writer *, const MV *, const MV_CONTEXT *);
void vp8_build_component_cost_table(int *mvcost[2], const MV_CONTEXT *mvc, int mvc_flag[2]);
+#if CONFIG_HIGH_PRECISION_MV
+void vp8_write_mvprobs_hp(VP8_COMP *);
+void vp8_encode_motion_vector_hp(vp8_writer *, const MV *, const MV_CONTEXT_HP *);
+void vp8_build_component_cost_table_hp(int *mvcost[2], const MV_CONTEXT_HP *mvc, int mvc_flag[2]);
+#endif /* CONFIG_HIGH_PRECISION_MV */
#endif
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -420,7 +420,12 @@
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 @@
{
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 @@
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
--- a/vp8/encoder/mbgraph.c
+++ b/vp8/encoder/mbgraph.c
@@ -35,6 +35,11 @@
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 @@
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 @@
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);
--- a/vp8/encoder/mcomp.c
+++ b/vp8/encoder/mcomp.c
@@ -28,16 +28,36 @@
// 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)
{
/* Calculate sad error cost on full pixel basis. */
@@ -46,6 +66,7 @@
* error_per_bit + 128) >> 8;
}
+
void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride)
{
int Len;
@@ -176,17 +197,6 @@
* 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
@@ -193,14 +203,24 @@
#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 @@
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 @@
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 @@
// 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 @@
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 @@
#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 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -79,6 +79,14 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
fclose(recon_file);
}
#endif
-#if OUTPUT_YUV_REC
+#ifdef OUTPUT_YUV_REC
vp8_write_yuv_rec_frame(cm);
#endif
@@ -3932,6 +3974,9 @@
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)
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -64,6 +64,10 @@
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 @@
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
--- a/vp8/encoder/quantize.c
+++ b/vp8/encoder/quantize.c
@@ -75,7 +75,7 @@
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 @@
//if(update)
// vp8cx_init_quantizer(cpi);
}
-
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -148,6 +148,10 @@
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 @@
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 @@
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;
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1601,7 +1601,12 @@
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 @@
&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 @@
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 @@
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 @@
{
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 @@
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 @@
{
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 @@
//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 @@
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;
--- a/vp8/encoder/temporal_filter.c
+++ b/vp8/encoder/temporal_filter.c
@@ -36,6 +36,7 @@
#if VP8_TEMPORAL_ALT_REF
+
static void vp8_temporal_filter_predictors_mb_c
(
MACROBLOCKD *x,
@@ -154,6 +155,9 @@
#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 @@
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 @@
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 @@
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 @@
#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 @@
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++)