Commit 3b635245 authored by RogerZhou's avatar RogerZhou Committed by Roger Zhou

Adaptive Motion Vector Resolution

Change-Id: Ic3c93a5d2e427ce1ed578389196a265245063821
parent f6a45cdb
......@@ -825,7 +825,10 @@ typedef struct macroblockd {
int qindex[MAX_SEGMENTS];
int lossless[MAX_SEGMENTS];
int corrupted;
#if CONFIG_AMVR
int cur_frame_mv_precision_level;
// same with that in AV1_COMMON
#endif
struct aom_internal_error_info *error_info;
#if CONFIG_GLOBAL_MOTION
WarpedMotionParams *global_motion;
......@@ -1621,10 +1624,16 @@ static INLINE MOTION_MODE motion_mode_allowed(
#endif
const MODE_INFO *mi) {
const MB_MODE_INFO *mbmi = &mi->mbmi;
#if CONFIG_AMVR
if (xd->cur_frame_mv_precision_level == 0) {
#endif
#if CONFIG_GLOBAL_MOTION
const TransformationType gm_type = gm_params[mbmi->ref_frame[0]].wmtype;
if (is_global_mv_block(mi, block, gm_type)) return SIMPLE_TRANSLATION;
const TransformationType gm_type = gm_params[mbmi->ref_frame[0]].wmtype;
if (is_global_mv_block(mi, block, gm_type)) return SIMPLE_TRANSLATION;
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_AMVR
}
#endif
#if CONFIG_EXT_INTER
if (is_motion_variation_allowed_bsize(mbmi->sb_type) &&
is_inter_mode(mbmi->mode) && mbmi->ref_frame[1] != INTRA_FRAME &&
......@@ -1639,8 +1648,14 @@ static INLINE MOTION_MODE motion_mode_allowed(
#if CONFIG_WARPED_MOTION
if (!has_second_ref(mbmi) && mbmi->num_proj_ref[0] >= 1 &&
!av1_is_scaled(&(xd->block_refs[0]->sf))) {
#if CONFIG_AMVR
if (xd->cur_frame_mv_precision_level) {
return OBMC_CAUSAL;
}
#endif
return WARPED_CAUSAL;
}
#endif // CONFIG_WARPED_MOTION
#if CONFIG_MOTION_VAR
#if CONFIG_NCOBMC_ADAPT_WEIGHT
......@@ -1689,7 +1704,8 @@ static INLINE int is_neighbor_overlappable(const MB_MODE_INFO *mbmi) {
// Returns sub-sampled dimensions of the given block.
// The output values for 'rows_within_bounds' and 'cols_within_bounds' will
// differ from 'height' and 'width' when part of the block is outside the right
// differ from 'height' and 'width' when part of the block is outside the
// right
// and/or bottom image boundary.
static INLINE void av1_get_block_dimensions(BLOCK_SIZE bsize, int plane,
const MACROBLOCKD *xd, int *width,
......
......@@ -169,7 +169,7 @@ static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
if (c == MV_CLASS_0) {
comp_counts->class0[d] += incr;
#if CONFIG_INTRABC
#if CONFIG_INTRABC || CONFIG_AMVR
if (precision > MV_SUBPEL_NONE)
#endif
comp_counts->class0_fp[d][f] += incr;
......@@ -178,7 +178,7 @@ static void inc_mv_component(int v, nmv_component_counts *comp_counts, int incr,
int i;
int b = c + CLASS0_BITS - 1; // number of bits
for (i = 0; i < b; ++i) comp_counts->bits[i][((d >> i) & 1)] += incr;
#if CONFIG_INTRABC
#if CONFIG_INTRABC || CONFIG_AMVR
if (precision > MV_SUBPEL_NONE)
#endif
comp_counts->fp[f] += incr;
......@@ -222,18 +222,23 @@ void av1_adapt_mv_probs(AV1_COMMON *cm, int allow_hp) {
for (j = 0; j < MV_OFFSET_BITS; ++j)
comp->bits[j] = av1_mode_mv_merge_probs(pre_comp->bits[j], c->bits[j]);
for (j = 0; j < CLASS0_SIZE; ++j)
aom_tree_merge_probs(av1_mv_fp_tree, pre_comp->class0_fp[j],
c->class0_fp[j], comp->class0_fp[j]);
aom_tree_merge_probs(av1_mv_fp_tree, pre_comp->fp, c->fp, comp->fp);
if (allow_hp) {
comp->class0_hp =
av1_mode_mv_merge_probs(pre_comp->class0_hp, c->class0_hp);
comp->hp = av1_mode_mv_merge_probs(pre_comp->hp, c->hp);
#if CONFIG_AMVR
if (cm->cur_frame_mv_precision_level == 0) {
#endif
for (j = 0; j < CLASS0_SIZE; ++j)
aom_tree_merge_probs(av1_mv_fp_tree, pre_comp->class0_fp[j],
c->class0_fp[j], comp->class0_fp[j]);
aom_tree_merge_probs(av1_mv_fp_tree, pre_comp->fp, c->fp, comp->fp);
if (allow_hp) {
comp->class0_hp =
av1_mode_mv_merge_probs(pre_comp->class0_hp, c->class0_hp);
comp->hp = av1_mode_mv_merge_probs(pre_comp->hp, c->hp);
}
#if CONFIG_AMVR
}
#endif
}
}
}
......
......@@ -133,7 +133,7 @@ typedef struct {
} nmv_context_counts;
typedef enum {
#if CONFIG_INTRABC
#if CONFIG_INTRABC || CONFIG_AMVR
MV_SUBPEL_NONE = -1,
#endif
MV_SUBPEL_LOW_PRECISION = 0,
......
......@@ -206,13 +206,43 @@ static INLINE int convert_to_trans_prec(int allow_hp, int coor) {
else
return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 2) * 2;
}
#if CONFIG_AMVR
static INLINE void integer_mv_precision(MV *mv) {
int mod = (mv->row % 8);
if (mod != 0) {
mv->row -= mod;
if (abs(mod) > 4) {
if (mod > 0) {
mv->row += 8;
} else {
mv->row -= 8;
}
}
}
mod = (mv->col % 8);
if (mod != 0) {
mv->col -= mod;
if (abs(mod) > 4) {
if (mod > 0) {
mv->col += 8;
} else {
mv->col -= 8;
}
}
}
}
#endif
// Convert a global motion translation vector (which may have more bits than a
// regular motion vector) into a motion vector
static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
int allow_hp, BLOCK_SIZE bsize,
int mi_col, int mi_row,
int block_idx) {
int mi_col, int mi_row, int block_idx
#if CONFIG_AMVR
,
int is_integer
#endif
) {
const int unify_bsize = CONFIG_CB4X4;
int_mv res;
const int32_t *mat = gm->wmmat;
......@@ -260,6 +290,11 @@ static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
res.as_mv.row = ty;
res.as_mv.col = tx;
#if CONFIG_AMVR
if (is_integer) {
integer_mv_precision(&res.as_mv);
}
#endif
return res;
}
......
......@@ -20,7 +20,12 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
uint8_t *refmv_count,
CANDIDATE_MV *ref_mv_stack,
const int use_hp, int len, int block,
int col, int weight) {
int col, int weight
#if CONFIG_AMVR
,
int is_integer
#endif
) {
int index = 0, ref;
int newmv_count = 0;
#if CONFIG_CB4X4
......@@ -35,7 +40,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
for (ref = 0; ref < 2; ++ref) {
if (candidate->ref_frame[ref] == rf[0]) {
int_mv this_refmv = get_sub_block_mv(candidate_mi, ref, col, block);
#if CONFIG_AMVR
lower_mv_precision(&this_refmv.as_mv, use_hp, is_integer);
#else
lower_mv_precision(&this_refmv.as_mv, use_hp);
#endif
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
......@@ -57,8 +66,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
!unify_bsize) {
int alt_block = 3 - block;
this_refmv = get_sub_block_mv(candidate_mi, ref, col, alt_block);
#if CONFIG_AMVR
lower_mv_precision(&this_refmv.as_mv, use_hp, is_integer);
#else
lower_mv_precision(&this_refmv.as_mv, use_hp);
#endif
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
......@@ -85,7 +97,12 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
for (ref = 0; ref < 2; ++ref) {
this_refmv[ref] = get_sub_block_mv(candidate_mi, ref, col, block);
#if CONFIG_AMVR
lower_mv_precision(&this_refmv[ref].as_mv, use_hp, is_integer);
#else
lower_mv_precision(&this_refmv[ref].as_mv, use_hp);
#endif
}
for (index = 0; index < *refmv_count; ++index)
......@@ -120,9 +137,13 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
this_refmv[0] = get_sub_block_mv(candidate_mi, 0, col, alt_block);
this_refmv[1] = get_sub_block_mv(candidate_mi, 1, col, alt_block);
for (ref = 0; ref < 2; ++ref)
for (ref = 0; ref < 2; ++ref) {
#if CONFIG_AMVR
lower_mv_precision(&this_refmv[ref].as_mv, use_hp, is_integer);
#else
lower_mv_precision(&this_refmv[ref].as_mv, use_hp);
#endif
}
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int &&
ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int)
......@@ -202,9 +223,16 @@ static uint8_t scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
*processed_rows = inc - row_offset - 1;
}
#if CONFIG_AMVR
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, col_offset + i, weight,
cm->cur_frame_mv_precision_level);
#else
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, col_offset + i, weight);
#endif
i += len;
}
......@@ -256,9 +284,16 @@ static uint8_t scan_col_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
*processed_cols = inc - col_offset - 1;
}
#if CONFIG_AMVR
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, col_offset, weight,
cm->cur_frame_mv_precision_level);
#else
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, col_offset, weight);
#endif
i += len;
}
......@@ -284,9 +319,16 @@ static uint8_t scan_blk_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
const int len = mi_size_wide[BLOCK_8X8];
#if CONFIG_AMVR
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, mi_pos.col, 2,
cm->cur_frame_mv_precision_level);
#else
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, mi_pos.col, 2);
#endif
} // Analyze a single 8x8 block motion information.
return newmv_count;
......@@ -473,8 +515,12 @@ static int add_col_ref_mv(const AV1_COMMON *cm,
for (ref = 0; ref < 2; ++ref) {
if (prev_frame_mvs->ref_frame[ref] == ref_frame) {
int_mv this_refmv = prev_frame_mvs->mv[ref];
#if CONFIG_AMVR
lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv,
cm->cur_frame_mv_precision_level);
#else
lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv);
#endif
if (abs(this_refmv.as_mv.row) >= 16 || abs(this_refmv.as_mv.col) >= 16)
mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
......@@ -1057,14 +1103,25 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
av1_set_ref_frame(rf, ref_frame);
zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
cm->allow_high_precision_mv, bsize,
mi_col, mi_row, 0)
mi_col, mi_row, 0
#if CONFIG_AMVR
,
cm->cur_frame_mv_precision_level
#endif
)
.as_int;
zeromv[1].as_int = (rf[1] != NONE_FRAME)
? gm_get_motion_vector(&cm->global_motion[rf[1]],
cm->allow_high_precision_mv,
bsize, mi_col, mi_row, 0)
.as_int
: 0;
zeromv[1].as_int =
(rf[1] != NONE_FRAME)
? gm_get_motion_vector(&cm->global_motion[rf[1]],
cm->allow_high_precision_mv, bsize, mi_col,
mi_row, 0
#if CONFIG_AMVR
,
cm->cur_frame_mv_precision_level
#endif
)
.as_int
: 0;
} else {
zeromv[0].as_int = zeromv[1].as_int = 0;
}
......@@ -1107,11 +1164,20 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
}
void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
int_mv *near_mv) {
int_mv *near_mv
#if CONFIG_AMVR
,
int is_integer
#endif
) {
int i;
// Make sure all the candidates are properly clamped etc
for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
#if CONFIG_AMVR
lower_mv_precision(&mvlist[i].as_mv, allow_hp, is_integer);
#else
lower_mv_precision(&mvlist[i].as_mv, allow_hp);
#endif
}
*nearest_mv = mvlist[0];
*near_mv = mvlist[1];
......@@ -1143,7 +1209,12 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
#if CONFIG_GLOBAL_MOTION
zeromv.as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
cm->allow_high_precision_mv,
mi->mbmi.sb_type, mi_col, mi_row, block)
mi->mbmi.sb_type, mi_col, mi_row, block
#if CONFIG_AMVR
,
cm->cur_frame_mv_precision_level
#endif
)
.as_int;
#else
zeromv.as_int = 0;
......
......@@ -231,11 +231,24 @@ static INLINE int find_valid_col_offset(const TileInfo *const tile, int mi_col,
tile->mi_col_end - mi_col - 1);
}
static INLINE void lower_mv_precision(MV *mv, int allow_hp) {
if (!allow_hp) {
if (mv->row & 1) mv->row += (mv->row > 0 ? -1 : 1);
if (mv->col & 1) mv->col += (mv->col > 0 ? -1 : 1);
static INLINE void lower_mv_precision(MV *mv, int allow_hp
#if CONFIG_AMVR
,
int is_integer
#endif
) {
#if CONFIG_AMVR
if (is_integer) {
integer_mv_precision(mv);
} else {
#endif
if (!allow_hp) {
if (mv->row & 1) mv->row += (mv->row > 0 ? -1 : 1);
if (mv->col & 1) mv->col += (mv->col > 0 ? -1 : 1);
}
#if CONFIG_AMVR
}
#endif
}
static INLINE uint8_t av1_get_pred_diff_ctx(const int_mv pred_mv,
......@@ -396,8 +409,13 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
// check a list of motion vectors by sad score using a number rows of pixels
// above and a number cols of pixels in the left to select the one with best
// score to use as ref motion vector
#if CONFIG_AMVR
void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
int_mv *near_mv, int is_integer);
#else
void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
int_mv *near_mv);
#endif
void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
int block, int ref, int mi_row, int mi_col,
......
......@@ -260,6 +260,11 @@ typedef struct AV1Common {
uint8_t last_intra_only;
int allow_high_precision_mv;
#if CONFIG_AMVR
int seq_mv_precision_level; // 0 the default in AOM, 1 only integer, 2
// adaptive
int cur_frame_mv_precision_level; // 0 the default in AOM, 1 only integer
#endif
int allow_screen_content_tools;
#if CONFIG_EXT_INTER
......
......@@ -182,7 +182,11 @@ static INLINE void av1_make_inter_predictor(
build_for_obmc,
#endif // CONFIG_MOTION_VAR
&final_warp_params);
if (do_warp) {
if (do_warp
#if CONFIG_AMVR
&& xd->cur_frame_mv_precision_level == 0
#endif
) {
const struct macroblockd_plane *const pd = &xd->plane[plane];
const struct buf_2d *const pre_buf = &pd->pre[ref];
av1_warp_plane(&final_warp_params,
......
......@@ -4562,6 +4562,17 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
cm->ans_window_size_log2 = aom_rb_read_literal(rb, 4) + 8;
#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
cm->allow_screen_content_tools = aom_rb_read_bit(rb);
#if CONFIG_AMVR
if (cm->allow_screen_content_tools) {
if (aom_rb_read_bit(rb)) {
cm->seq_mv_precision_level = 2;
} else {
cm->seq_mv_precision_level = aom_rb_read_bit(rb) ? 0 : 1;
}
} else {
cm->seq_mv_precision_level = 0;
}
#endif
#if CONFIG_TEMPMV_SIGNALING
cm->use_prev_frame_mvs = 0;
#endif
......@@ -4661,6 +4672,13 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
setup_frame_size_with_refs(cm, rb);
#endif
#if CONFIG_AMVR
if (cm->seq_mv_precision_level == 2) {
cm->cur_frame_mv_precision_level = aom_rb_read_bit(rb) ? 0 : 1;
} else {
cm->cur_frame_mv_precision_level = cm->seq_mv_precision_level;
}
#endif
cm->allow_high_precision_mv = aom_rb_read_bit(rb);
cm->interp_filter = read_frame_interp_filter(rb);
#if CONFIG_TEMPMV_SIGNALING
......@@ -4831,7 +4849,9 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
}
}
#endif
#if CONFIG_AMVR
xd->cur_frame_mv_precision_level = cm->cur_frame_mv_precision_level;
#endif
for (i = 0; i < MAX_SEGMENTS; ++i) {
const int qindex = cm->seg.enabled
? av1_get_qindex(&cm->seg, i, cm->base_qindex)
......@@ -4974,8 +4994,14 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#if !CONFIG_NEW_MULTISYMBOL
for (i = 0; i < NMV_CONTEXTS; ++i)
read_mv_probs(&fc->nmvc[i], cm->allow_high_precision_mv, &r);
#if CONFIG_AMVR
if (cm->cur_frame_mv_precision_level == 0) {
#endif
for (i = 0; i < NMV_CONTEXTS; ++i)
read_mv_probs(&fc->nmvc[i], cm->allow_high_precision_mv, &r);
#if CONFIG_AMVR
}
#endif
#endif
#if CONFIG_SUPERTX
if (!xd->lossless[0]) read_supertx_probs(fc, &r);
......
This diff is collapsed.
......@@ -4447,6 +4447,16 @@ static void write_uncompressed_header(AV1_COMP *cpi,
aom_wb_write_literal(wb, cpi->common.ans_window_size_log2 - 8, 4);
#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
aom_wb_write_bit(wb, cm->allow_screen_content_tools);
#if CONFIG_AMVR
if (cm->allow_screen_content_tools) {
if (cm->seq_mv_precision_level == 2) {
aom_wb_write_bit(wb, 1);
} else {
aom_wb_write_bit(wb, 0);
aom_wb_write_bit(wb, cm->seq_mv_precision_level == 0);
}
}
#endif
} else {
if (!cm->show_frame) aom_wb_write_bit(wb, cm->intra_only);
if (cm->intra_only) aom_wb_write_bit(wb, cm->allow_screen_content_tools);
......@@ -4534,6 +4544,11 @@ static void write_uncompressed_header(AV1_COMP *cpi,
write_frame_size_with_refs(cpi, wb);
#endif
#if CONFIG_AMVR
if (cm->seq_mv_precision_level == 2) {
aom_wb_write_bit(wb, cm->cur_frame_mv_precision_level == 0);
}
#endif
aom_wb_write_bit(wb, cm->allow_high_precision_mv);
fix_interp_filter(cm, cpi->td.counts);
......
......@@ -4637,7 +4637,9 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
}
#if CONFIG_AMVR
xd->cur_frame_mv_precision_level = cm->cur_frame_mv_precision_level;
#endif
#if CONFIG_DELTA_Q
if (cm->delta_q_present_flag) {
// Test mode for delta quantization
......
......@@ -66,9 +66,9 @@ static void encode_mv_component(aom_writer *w, int comp, nmv_component *mvcomp,
}
// Fractional bits
#if CONFIG_INTRABC
#if CONFIG_INTRABC || CONFIG_AMVR
if (precision > MV_SUBPEL_NONE)
#endif // CONFIG_INTRABC
#endif // CONFIG_INTRABC || CONFIG_AMVR
{
aom_write_symbol(
w, fr,
......@@ -130,9 +130,9 @@ static void build_nmv_component_cost_table(int *mvcost,
const int b = c + CLASS0_BITS - 1; /* number of bits */
for (i = 0; i < b; ++i) cost += bits_cost[i][((d >> i) & 1)];
}
#if CONFIG_INTRABC
#if CONFIG_INTRABC || CONFIG_AMVR
if (precision > MV_SUBPEL_NONE)
#endif // CONFIG_INTRABC
#endif // CONFIG_INTRABC || CONFIG_AMVR
{
if (c == MV_CLASS_0) {
cost += class0_fp_cost[d][f];
......@@ -166,6 +166,11 @@ void av1_write_nmv_probs(AV1_COMMON *cm, int usehp, aom_writer *w,
nmv_context_counts *const nmv_counts) {
int i;
int nmv_ctx = 0;
#if CONFIG_AMVR
if (cm->cur_frame_mv_precision_level) {
return;
}
#endif
for (nmv_ctx = 0; nmv_ctx < NMV_CONTEXTS; ++nmv_ctx) {
nmv_context *const mvc = &cm->fc->nmvc[nmv_ctx];
nmv_context_counts *const counts = &nmv_counts[nmv_ctx];
......@@ -185,6 +190,11 @@ void av1_encode_mv(AV1_COMP *cpi, aom_writer *w, const MV *mv, const MV *ref,
nmv_context *mvctx, int usehp) {
const MV diff = { mv->row - ref->row, mv->col - ref->col };
const MV_JOINT_TYPE j = av1_get_mv_joint(&diff);
#if CONFIG_AMVR
if (cpi->common.cur_frame_mv_precision_level) {
usehp = MV_SUBPEL_NONE;
}
#endif
aom_write_symbol(w, j, mvctx->joint_cdf, MV_JOINTS);
if (mv_joint_vertical(j))
encode_mv_component(w, diff.row, &mvctx->comps[0], usehp);
......@@ -226,7 +236,12 @@ void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
#if CONFIG_EXT_INTER
static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext,
const int_mv mvs[2], const int_mv pred_mvs[2],
nmv_context_counts *nmv_counts) {
nmv_context_counts *nmv_counts
#if CONFIG_AMVR
,
MvSubpelPrecision precision
#endif
) {
int i;
PREDICTION_MODE mode = mbmi->mode;
......@@ -241,7 +256,11 @@ static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext,
mbmi_ext->ref_mv_stack[rf_type], i, mbmi->ref_mv_idx);
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
(void)pred_mvs;
#if CONFIG_AMVR
av1_inc_mv(&diff, counts, precision);
#else
av1_inc_mv(&diff, counts, 1);
#endif
}
} else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv;
......@@ -252,7 +271,11 @@ static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext,
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
mbmi_ext->ref_mv_stack[rf_type], 1, mbmi->ref_mv_idx);
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
#if CONFIG_AMVR
av1_inc_mv(&diff, counts, precision);
#else
av1_inc_mv(&diff, counts, 1);
#endif
} else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv;
const MV diff = { mvs[0].as_mv.row - ref->row,
......@@ -262,7 +285,11 @@ static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext,
av1_nmv_ctx(mbmi_ext->ref_mv_count[rf_type],
mbmi_ext->ref_mv_stack[rf_type], 0, mbmi->ref_mv_idx);
nmv_context_counts *counts = &nmv_counts[nmv_ctx];
#if CONFIG_AMVR
av1_inc_mv(&diff, counts, precision);
#else
av1_inc_mv(&diff, counts, 1);
#endif