Commit 3e1cad9c authored by Deb Mukherjee's avatar Deb Mukherjee
Browse files

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
parent 3d93ae52
...@@ -226,7 +226,7 @@ struct vp8_token_struct vp8_mv_ref_encoding_array [VP8_MVREFS]; ...@@ -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]; struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
#if CONFIG_HIGH_PRECISION_MV #if CONFIG_HIGH_PRECISION_MV
const vp8_tree_index vp8_small_mvtree [30] = const vp8_tree_index vp8_small_mvtree_hp [30] =
{ {
2, 16, 2, 16,
4, 10, 4, 10,
...@@ -244,9 +244,8 @@ const vp8_tree_index vp8_small_mvtree [30] = ...@@ -244,9 +244,8 @@ const vp8_tree_index vp8_small_mvtree [30] =
-12, -13, -12, -13,
-14, -15 -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] = const vp8_tree_index vp8_small_mvtree [14] =
{ {
...@@ -260,7 +259,6 @@ 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]; struct vp8_token_struct vp8_small_mvencodings [8];
#endif /* CONFIG_HIGH_PRECISION_MV */
void vp8_init_mbmode_probs(VP8_COMMON *x) void vp8_init_mbmode_probs(VP8_COMMON *x)
...@@ -381,6 +379,9 @@ void vp8_entropy_mode_init() ...@@ -381,6 +379,9 @@ void vp8_entropy_mode_init()
vp8_sub_mv_ref_tree, LEFT4X4); vp8_sub_mv_ref_tree, LEFT4X4);
vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree); 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) void vp8_init_mode_contexts(VP8_COMMON *pc)
......
...@@ -56,11 +56,10 @@ extern struct vp8_token_struct vp8_mv_ref_encoding_array [VP8_MVREFS]; ...@@ -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 struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
extern const vp8_tree_index vp8_small_mvtree[]; 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]; 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 #endif
void vp8_entropy_mode_init(void); void vp8_entropy_mode_init(void);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include "entropymv.h" #include "entropymv.h"
#if CONFIG_HIGH_PRECISION_MV #if CONFIG_HIGH_PRECISION_MV
const MV_CONTEXT vp8_mv_update_probs[2] = const MV_CONTEXT_HP vp8_mv_update_probs_hp[2] =
{ {
{{ {{
237, 237,
...@@ -27,7 +27,7 @@ const MV_CONTEXT vp8_mv_update_probs[2] = ...@@ -27,7 +27,7 @@ const MV_CONTEXT vp8_mv_update_probs[2] =
254, 254, 254, 254, 254, 251, 251, 254, 254, 254, 254 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 */ /* row */
...@@ -44,7 +44,8 @@ const MV_CONTEXT vp8_default_mv_context[2] = ...@@ -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 */ 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] = const MV_CONTEXT vp8_mv_update_probs[2] =
{ {
{{ {{
...@@ -77,4 +78,3 @@ const MV_CONTEXT vp8_default_mv_context[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 */ 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 /* long bits */
}} }}
}; };
#endif /* CONFIG_HIGH_PRECISION_MV */
...@@ -15,27 +15,13 @@ ...@@ -15,27 +15,13 @@
#include "treecoder.h" #include "treecoder.h"
#include "vpx_config.h" #include "vpx_config.h"
#if CONFIG_HIGH_PRECISION_MV
#define MV_SHIFT 0
#else
#define MV_SHIFT 1
#endif
enum 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 */ mv_max = 1023, /* max absolute value of a MV component */
MVvals = (2 * mv_max) + 1, /* # possible values "" */ MVvals = (2 * mv_max) + 1, /* # possible values "" */
mvlong_width = 10, /* Large MVs have 9 bit magnitudes */ mvlong_width = 10, /* Large MVs have 9 bit magnitudes */
mvnum_short = 8, /* magnitudes 0 through 7 */ mvnum_short = 8, /* magnitudes 0 through 7 */
mvnum_short_bits = 3, /* number of bits for short mvs */ mvnum_short_bits = 3, /* number of bits for short mvs */
#endif
mvfp_max = 255, /* max absolute value of a full pixel MV component */ mvfp_max = 255, /* max absolute value of a full pixel MV component */
MVfpvals = (2 * mvfp_max) + 1, /* # possible full pixel MV values */ MVfpvals = (2 * mvfp_max) + 1, /* # possible full pixel MV values */
...@@ -57,4 +43,34 @@ typedef struct mv_context ...@@ -57,4 +43,34 @@ typedef struct mv_context
extern const MV_CONTEXT vp8_mv_update_probs[2], vp8_default_mv_context[2]; 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 #endif
...@@ -45,7 +45,7 @@ DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[SUBPEL_SHIFTS][2]) = ...@@ -45,7 +45,7 @@ DECLARE_ALIGNED(16, const short, vp8_bilinear_filters[SUBPEL_SHIFTS][2]) =
}; };
#if CONFIG_ENHANCED_INTERP #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]) = DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters[SUBPEL_SHIFTS][2*INTERP_EXTEND]) =
{ {
/* Generated using MATLAB: /* Generated using MATLAB:
......
...@@ -21,6 +21,7 @@ const unsigned char vp8_mbsplit_offset[4][16] = { ...@@ -21,6 +21,7 @@ const unsigned char vp8_mbsplit_offset[4][16] = {
/* Predict motion vectors using those from already-decoded nearby blocks. /* Predict motion vectors using those from already-decoded nearby blocks.
Note that we only consider one 4x4 subblock from each candidate 16x16 Note that we only consider one 4x4 subblock from each candidate 16x16
macroblock. */ macroblock. */
void vp8_find_near_mvs void vp8_find_near_mvs
( (
MACROBLOCKD *xd, MACROBLOCKD *xd,
...@@ -145,6 +146,27 @@ void vp8_find_near_mvs ...@@ -145,6 +146,27 @@ void vp8_find_near_mvs
nearest->as_int = near_mvs[CNT_NEAREST].as_int; nearest->as_int = near_mvs[CNT_NEAREST].as_int;
nearby->as_int = near_mvs[CNT_NEAR].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 //TODO: move clamp outside findnearmv
vp8_clamp_mv2(nearest, xd); vp8_clamp_mv2(nearest, xd);
vp8_clamp_mv2(nearby, xd); vp8_clamp_mv2(nearby, xd);
...@@ -161,4 +183,3 @@ vp8_prob *vp8_mv_ref_probs(VP8_COMMON *pc, ...@@ -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]; p[3] = pc->vp8_mode_contexts [near_mv_ref_ct[3]] [3];
return p; return p;
} }
...@@ -58,6 +58,10 @@ typedef struct frame_contexts ...@@ -58,6 +58,10 @@ typedef struct frame_contexts
#endif #endif
MV_CONTEXT mvc[2]; MV_CONTEXT mvc[2];
MV_CONTEXT pre_mvc[2]; /* not to caculate the mvcost for the frame if mvc doesn't change. */ 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; } FRAME_CONTEXT;
typedef enum typedef enum
......
/* /*
* 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 * 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 * 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) ...@@ -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) static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc)
{ {
mv->row = (short)(read_mvcomponent(r, mvc) << MV_SHIFT); mv->row = (short)(read_mvcomponent(r, mvc) << 1);
mv->col = (short)(read_mvcomponent(r, ++mvc) << MV_SHIFT); mv->col = (short)(read_mvcomponent(r, ++mvc) << 1);
#ifdef DEBUG_DEC_MV #ifdef DEBUG_DEC_MV
int i; int i;
printf("%d: %d %d\n", dec_mvcount++, mv->row, mv->col); 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[-1])->prob[i]); printf("\n");
for (i=0; i<MVPcount;++i) printf(" %d", (&mvc[0])->prob[i]); printf("\n"); //for (i=0; i<MVPcount;++i) printf(" %d", (&mvc[0])->prob[i]); printf("\n");
#endif #endif
} }
...@@ -238,6 +238,79 @@ static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc) ...@@ -238,6 +238,79 @@ static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc)
while (++i < 2); 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 // Read the referncence frame
static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi, static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
vp8_reader *const bc, vp8_reader *const bc,
...@@ -406,6 +479,10 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) ...@@ -406,6 +479,10 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
VP8_COMMON *const cm = & pbi->common; VP8_COMMON *const cm = & pbi->common;
vp8_reader *const bc = & pbi->bc; vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc; 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; pbi->prob_skip_false = 0;
if (pbi->common.mb_no_coeff_skip) if (pbi->common.mb_no_coeff_skip)
...@@ -456,6 +533,11 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) ...@@ -456,6 +533,11 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
while (++i < VP8_UV_MODES-1); while (++i < VP8_UV_MODES-1);
} }
#endif /* CONFIG_UVINTRA */ #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); read_mvcontexts(bc, mvc);
} }
} }
...@@ -529,6 +611,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, ...@@ -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_COMMON *const cm = & pbi->common;
vp8_reader *const bc = & pbi->bc; vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc; 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; const int mis = pbi->common.mode_info_stride;
MACROBLOCKD *const xd = & pbi->mb; 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, ...@@ -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))*/ switch (sub_mv_ref(bc, vp8_sub_mv_ref_prob2 [mv_contz])) /*pc->fc.sub_mv_ref_prob))*/
{ {
case NEW4X4: 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); read_mv(bc, &blockmv.as_mv, (const MV_CONTEXT *) mvc);
blockmv.as_mv.row += best_mv.as_mv.row; blockmv.as_mv.row += best_mv.as_mv.row;
blockmv.as_mv.col += best_mv.as_mv.col; 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, ...@@ -717,6 +807,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
goto propagate_mv; goto propagate_mv;
case NEWMV: 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); read_mv(bc, &mv->as_mv, (const MV_CONTEXT *) mvc);
mv->as_mv.row += best_mv.as_mv.row; mv->as_mv.row += best_mv.as_mv.row;
mv->as_mv.col += best_mv.as_mv.col; 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, ...@@ -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); mb_to_top_edge, mb_to_bottom_edge);
break; break;
case NEWMV: 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); 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.row += best_mv.as_mv.row;
mbmi->second_mv.as_mv.col += best_mv.as_mv.col; mbmi->second_mv.as_mv.col += best_mv.as_mv.col;
......
...@@ -738,6 +738,10 @@ static void init_frame(VP8D_COMP *pbi) ...@@ -738,6 +738,10 @@ static void init_frame(VP8D_COMP *pbi)
{ {
/* Various keyframe initializations */ /* Various keyframe initializations */
vpx_memcpy(pc->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); 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); vp8_init_mbmode_probs(pc);
......
...@@ -46,7 +46,6 @@ extern unsigned int active_section; ...@@ -46,7 +46,6 @@ extern unsigned int active_section;
int count_mb_seg[4] = { 0, 0, 0, 0 }; int count_mb_seg[4] = { 0, 0, 0, 0 };
#endif #endif
static void update_mode( static void update_mode(
vp8_writer *const w, vp8_writer *const w,
int n, int n,
...@@ -389,6 +388,20 @@ static void write_mv ...@@ -389,6 +388,20 @@ static void write_mv
vp8_encode_motion_vector(w, &e, mvc); 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 // 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. // It should only be called if a segment map update is indicated.
static void write_mb_segid(vp8_writer *w, static void write_mb_segid(vp8_writer *w,
...@@ -556,6 +569,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ...@@ -556,6 +569,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
VP8_COMMON *const pc = & cpi->common; VP8_COMMON *const pc = & cpi->common;
vp8_writer *const w = & cpi->bc; vp8_writer *const w = & cpi->bc;
const MV_CONTEXT *mvc = pc->fc.mvc; 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; MACROBLOCKD *xd = &cpi->mb.e_mbd;
int i; int i;
...@@ -643,6 +659,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ...@@ -643,6 +659,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
update_mbintra_mode_probs(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); vp8_write_mvprobs(cpi);
mb_row = 0; mb_row = 0;
...@@ -806,6 +827,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ...@@ -806,6 +827,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
active_section = 5; 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); write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) if (cpi->common.dual_pred_mode == HYBRID_PREDICTION)
...@@ -824,7 +850,14 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ...@@ -824,7 +850,14 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
&n1, &n2, &best_mv, &n1, &n2, &best_mv,
ct, second_rf, ct, second_rf,
cpi->common.ref_frame_sign_bias); cpi->common.ref_frame_sign_bias);