Commit 968bbc7b authored by Yue Chen's avatar Yue Chen

Adding new compound modes to EXT_INTER experiment

Combinations of different mv modes for two reference frames
are allowed in compound inter modes. 9 options are enabled,
including NEAREST_NEARESTMV, NEAREST_NEARMV, NEAR_NEARESTMV,
NEAREST_NEWMV, NEW_NEARESTMV, NEAR_NEWMV, NEW_NEARMV, ZERO_ZEROMV,
and NEW_NEWMV.
This experiment is mostly deported from the nextgen branch.
It is made compatible with other experiments

Coding gain of EXT_INTER(derflr/hevcmr/hevchd): 0.533%/0.728%/0.639%

Change-Id: Id47e97284e6481b186870afbad33204b7a33dbb0
parent 53c9ffd0
......@@ -49,15 +49,26 @@ typedef enum {
static INLINE int is_inter_mode(PREDICTION_MODE mode) {
#if CONFIG_EXT_INTER
return mode >= NEARESTMV && mode <= NEWFROMNEARMV;
return mode >= NEARESTMV && mode <= NEW_NEWMV;
#else
return mode >= NEARESTMV && mode <= NEWMV;
#endif // CONFIG_EXT_INTER
}
#if CONFIG_EXT_INTER
static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) {
return mode >= NEARESTMV && mode <= NEWFROMNEARMV;
}
static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV;
}
static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
return (mode == NEWMV || mode == NEWFROMNEARMV);
return (mode == NEWMV || mode == NEWFROMNEARMV ||
mode == NEW_NEWMV ||
mode == NEAREST_NEWMV || mode == NEW_NEARESTMV ||
mode == NEAR_NEWMV || mode == NEW_NEARMV);
}
#endif // CONFIG_EXT_INTER
......
......@@ -211,6 +211,19 @@ static const vpx_prob default_inter_mode_probs[INTER_MODE_CONTEXTS]
#endif // CONFIG_EXT_INTER
};
#if CONFIG_EXT_INTER
static const vpx_prob default_inter_compound_mode_probs
[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES - 1] = {
{ 2, 173, 68, 192, 192, 128, 180, 180}, // 0 = both zero mv
{ 7, 145, 160, 192, 192, 128, 180, 180}, // 1 = 1 zero + 1 predicted
{ 7, 166, 126, 192, 192, 128, 180, 180}, // 2 = two predicted mvs
{ 7, 94, 132, 192, 192, 128, 180, 180}, // 3 = 1 pred/zero, 1 new
{ 8, 64, 64, 192, 192, 128, 180, 180}, // 4 = two new mvs
{17, 81, 52, 192, 192, 128, 180, 180}, // 5 = one intra neighbour
{25, 29, 50, 192, 192, 128, 180, 180}, // 6 = two intra neighbours
};
#endif // CONFIG_EXT_INTER
/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
-DC_PRED, 2, /* 0 = DC_NODE */
......@@ -235,6 +248,21 @@ const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_MODES)] = {
#endif // CONFIG_EXT_INTER
};
#if CONFIG_EXT_INTER
const vpx_tree_index vp10_inter_compound_mode_tree
[TREE_SIZE(INTER_COMPOUND_MODES)] = {
-INTER_COMPOUND_OFFSET(ZERO_ZEROMV), 2,
-INTER_COMPOUND_OFFSET(NEAREST_NEARESTMV), 4,
6, -INTER_COMPOUND_OFFSET(NEW_NEWMV),
8, 10,
-INTER_COMPOUND_OFFSET(NEAREST_NEARMV),
-INTER_COMPOUND_OFFSET(NEAR_NEARESTMV),
12, 14,
-INTER_COMPOUND_OFFSET(NEAREST_NEWMV), -INTER_COMPOUND_OFFSET(NEW_NEARESTMV),
-INTER_COMPOUND_OFFSET(NEAR_NEWMV), -INTER_COMPOUND_OFFSET(NEW_NEARMV)
};
#endif // CONFIG_EXT_INTER
const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)] = {
-PARTITION_NONE, 2,
-PARTITION_HORZ, 4,
......@@ -1257,6 +1285,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#endif // CONFIG_EXT_INTER
#endif // CONFIG_REF_MV
vp10_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_EXT_INTER
vp10_copy(fc->inter_compound_mode_probs, default_inter_compound_mode_probs);
#endif // CONFIG_EXT_INTER
#if CONFIG_SUPERTX
vp10_copy(fc->supertx_prob, default_supertx_prob);
#endif // CONFIG_SUPERTX
......@@ -1336,6 +1367,14 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
}
#endif // CONFIG_SUPERTX
#if CONFIG_EXT_INTER
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
vpx_tree_merge_probs(vp10_inter_compound_mode_tree,
pre_fc->inter_compound_mode_probs[i],
counts->inter_compound_mode[i],
fc->inter_compound_mode_probs[i]);
#endif // CONFIG_EXT_INTER
for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i],
counts->y_mode[i], fc->y_mode_prob[i]);
......
......@@ -26,6 +26,9 @@ extern "C" {
#define TX_SIZE_CONTEXTS 2
#define INTER_OFFSET(mode) ((mode) - NEARESTMV)
#if CONFIG_EXT_INTER
#define INTER_COMPOUND_OFFSET(mode) ((mode) - NEAREST_NEARESTMV)
#endif // CONFIG_EXT_INTER
#define PALETTE_COLOR_CONTEXTS 16
#define PALETTE_MAX_SIZE 8
......@@ -71,6 +74,10 @@ typedef struct frame_contexts {
#endif
vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
#if CONFIG_EXT_INTER
vpx_prob inter_compound_mode_probs[INTER_MODE_CONTEXTS]
[INTER_COMPOUND_MODES - 1];
#endif // CONFIG_EXT_INTER
vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1];
......@@ -119,6 +126,9 @@ typedef struct FRAME_COUNTS {
#endif
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
#if CONFIG_EXT_INTER
unsigned int inter_compound_mode[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
#endif // CONFIG_EXT_INTER
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
......@@ -162,6 +172,10 @@ extern const vpx_prob vp10_default_palette_uv_color_prob
extern const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
extern const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_MODES)];
#if CONFIG_EXT_INTER
extern const vpx_tree_index vp10_inter_compound_mode_tree
[TREE_SIZE(INTER_COMPOUND_MODES)];
#endif // CONFIG_EXT_INTER
extern const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)];
extern const vpx_tree_index vp10_switchable_interp_tree
[TREE_SIZE(SWITCHABLE_FILTERS)];
......
......@@ -179,7 +179,16 @@ typedef enum {
#define NEWMV 13
#if CONFIG_EXT_INTER
#define NEWFROMNEARMV 14
#define MB_MODE_COUNT 15
#define NEAREST_NEARESTMV 15
#define NEAREST_NEARMV 16
#define NEAR_NEARESTMV 17
#define NEAREST_NEWMV 18
#define NEW_NEARESTMV 19
#define NEAR_NEWMV 20
#define NEW_NEARMV 21
#define ZERO_ZEROMV 22
#define NEW_NEWMV 23
#define MB_MODE_COUNT 24
#else
#define MB_MODE_COUNT 14
#endif // CONFIG_EXT_INTER
......@@ -212,6 +221,10 @@ typedef enum {
#define INTER_MODES (1 + NEWMV - NEARESTMV)
#endif // CONFIG_EXT_INTER
#if CONFIG_EXT_INTER
#define INTER_COMPOUND_MODES (1 + NEW_NEWMV - NEAREST_NEARESTMV)
#endif // CONFIG_EXT_INTER
#define SKIP_CONTEXTS 3
#if CONFIG_REF_MV
......
......@@ -210,7 +210,8 @@ static const int mode_lf_lut[MB_MODE_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES
1, 1, 0, 1 // INTER_MODES (ZEROMV == 0)
#if CONFIG_EXT_INTER
, 1 // NEWFROMNEARMV mode
, 1, // NEWFROMNEARMV mode
1, 1, 1, 1, 1, 1, 1, 0, 1 // INTER_COMPOUND_MODES (ZERO_ZEROMV == 0)
#endif // CONFIG_EXT_INTER
};
......
......@@ -41,7 +41,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = 2 * weight;
++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEWMV || candidate->mode == NEWFROMNEARMV)
#else
if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count;
}
......@@ -62,7 +66,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = weight;
++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEWMV || candidate->mode == NEWFROMNEARMV)
#else
if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count;
}
}
......@@ -92,7 +100,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = 2 * weight;
++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEW_NEWMV)
#else
if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count;
}
......@@ -116,7 +128,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = weight;
++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEW_NEWMV)
#else
if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count;
}
}
......@@ -664,6 +680,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
#if CONFIG_REF_MV
uint8_t *ref_mv_count,
CANDIDATE_MV *ref_mv_stack,
#if CONFIG_EXT_INTER
int16_t *compound_mode_context,
#endif // CONFIG_EXT_INTER
#endif
int_mv *mv_ref_list,
int mi_row, int mi_col,
......@@ -674,7 +693,12 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
#endif
#if CONFIG_EXT_INTER
vp10_update_mv_context(cm, xd, mi, ref_frame, mv_ref_list, -1,
mi_row, mi_col, mode_context);
mi_row, mi_col,
#if CONFIG_REF_MV
compound_mode_context);
#else
mode_context);
#endif // CONFIG_REF_MV
find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1,
mi_row, mi_col, sync, data, NULL);
#else
......
......@@ -57,6 +57,15 @@ static const int mode_2_counter[MB_MODE_COUNT] = {
1, // NEWMV
#if CONFIG_EXT_INTER
1, // NEWFROMNEARMV
0, // NEAREST_NEARESTMV
0, // NEAREST_NEARMV
0, // NEAR_NEARESTMV
1, // NEAREST_NEWMV
1, // NEW_NEARESTMV
1, // NEAR_NEWMV
1, // NEW_NEARMV
3, // ZERO_ZEROMV
1, // NEW_NEWMV
#endif // CONFIG_EXT_INTER
};
......@@ -255,6 +264,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
#if CONFIG_REF_MV
uint8_t *ref_mv_count,
CANDIDATE_MV *ref_mv_stack,
#if CONFIG_EXT_INTER
int16_t *compound_mode_context,
#endif // CONFIG_EXT_INTER
#endif
int_mv *mv_ref_list, int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data,
......
......@@ -389,6 +389,13 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
for (j = 0; j < INTER_MODES; j++)
cm->counts.inter_mode[i][j] += counts->inter_mode[i][j];
#if CONFIG_EXT_INTER
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
for (j = 0; j < INTER_COMPOUND_MODES; j++)
cm->counts.inter_compound_mode[i][j] +=
counts->inter_compound_mode[i][j];
#endif // CONFIG_EXT_INTER
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
for (j = 0; j < 2; j++)
cm->counts.intra_inter[i][j] += counts->intra_inter[i][j];
......
......@@ -143,6 +143,19 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
#endif
}
#if CONFIG_EXT_INTER
static void read_inter_compound_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
int i, j;
if (vpx_read(r, GROUP_DIFF_UPDATE_PROB)) {
for (j = 0; j < INTER_MODE_CONTEXTS; ++j) {
for (i = 0; i < INTER_COMPOUND_MODES - 1; ++i) {
vp10_diff_update_prob(r, &fc->inter_compound_mode_probs[j][i]);
}
}
}
}
#endif // CONFIG_EXT_INTER
static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
struct vpx_read_bit_buffer *rb) {
if (is_compound_reference_allowed(cm)) {
......@@ -3259,6 +3272,10 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
read_inter_mode_probs(fc, &r);
#if CONFIG_EXT_INTER
read_inter_compound_mode_probs(fc, &r);
#endif // CONFIG_EXT_INTER
if (cm->interp_filter == SWITCHABLE)
read_switchable_interp_probs(fc, &r);
......@@ -3308,6 +3325,11 @@ static void debug_check_frame_counts(const VP10_COMMON *const cm) {
sizeof(cm->counts.switchable_interp)));
assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
sizeof(cm->counts.inter_mode)));
#if CONFIG_EXT_INTER
assert(!memcmp(cm->counts.inter_compound_mode,
zero_counts.inter_compound_mode,
sizeof(cm->counts.inter_compound_mode)));
#endif // CONFIG_EXT_INTER
assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,
sizeof(cm->counts.intra_inter)));
assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_inter,
......
......@@ -147,6 +147,22 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
#endif
}
#if CONFIG_EXT_INTER
static PREDICTION_MODE read_inter_compound_mode(VP10_COMMON *cm,
MACROBLOCKD *xd,
vpx_reader *r, int16_t ctx) {
const int mode = vpx_read_tree(r, vp10_inter_compound_mode_tree,
cm->fc->inter_compound_mode_probs[ctx]);
FRAME_COUNTS *counts = xd->counts;
if (counts)
++counts->inter_compound_mode[ctx][mode];
assert(is_inter_compound_mode(NEAREST_NEARESTMV + mode));
return NEAREST_NEARESTMV + mode;
}
#endif // CONFIG_EXT_INTER
static int read_segment_id(vpx_reader *r,
const struct segmentation_probs *segp) {
return vpx_read_tree(r, vp10_segment_tree, segp->tree_probs);
......@@ -826,6 +842,83 @@ static INLINE int assign_mv(VP10_COMMON *cm, MACROBLOCKD *xd,
mv[1].as_int = 0;
break;
}
#if CONFIG_EXT_INTER
case NEW_NEWMV: {
FRAME_COUNTS *counts = xd->counts;
nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
assert(is_compound);
for (i = 0; i < 2; ++i) {
read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
allow_hp);
ret = ret && is_mv_valid(&mv[i].as_mv);
}
break;
}
case NEAREST_NEARESTMV: {
assert(is_compound);
mv[0].as_int = nearest_mv[0].as_int;
mv[1].as_int = nearest_mv[1].as_int;
break;
}
case NEAREST_NEARMV: {
assert(is_compound);
mv[0].as_int = nearest_mv[0].as_int;
mv[1].as_int = near_mv[1].as_int;
break;
}
case NEAR_NEARESTMV: {
assert(is_compound);
mv[0].as_int = near_mv[0].as_int;
mv[1].as_int = nearest_mv[1].as_int;
break;
}
case NEW_NEARESTMV: {
FRAME_COUNTS *counts = xd->counts;
nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
assert(is_compound);
read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
allow_hp);
ret = ret && is_mv_valid(&mv[0].as_mv);
mv[1].as_int = nearest_mv[1].as_int;
break;
}
case NEAREST_NEWMV: {
FRAME_COUNTS *counts = xd->counts;
nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
assert(is_compound);
mv[0].as_int = nearest_mv[0].as_int;
read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv, &cm->fc->nmvc, mv_counts,
allow_hp);
ret = ret && is_mv_valid(&mv[1].as_mv);
break;
}
case NEAR_NEWMV: {
FRAME_COUNTS *counts = xd->counts;
nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
assert(is_compound);
mv[0].as_int = near_mv[0].as_int;
read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv, &cm->fc->nmvc, mv_counts,
allow_hp);
ret = ret && is_mv_valid(&mv[1].as_mv);
break;
}
case NEW_NEARMV: {
FRAME_COUNTS *counts = xd->counts;
nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
assert(is_compound);
read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
allow_hp);
ret = ret && is_mv_valid(&mv[0].as_mv);
mv[1].as_int = near_mv[1].as_int;
break;
}
case ZERO_ZEROMV: {
assert(is_compound);
mv[0].as_int = 0;
mv[1].as_int = 0;
break;
}
#endif // CONFIG_EXT_INTER
default: {
return 0;
}
......@@ -868,6 +961,9 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
#endif // CONFIG_EXT_INTER
int ref, is_compound;
int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
#if CONFIG_REF_MV && CONFIG_EXT_INTER
int16_t compound_inter_mode_ctx[MODE_CTX_REF_FRAMES];
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
int16_t mode_ctx = 0;
MV_REFERENCE_FRAME ref_frame;
......@@ -891,12 +987,20 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
#if CONFIG_REF_MV
&xd->ref_mv_count[ref_frame],
xd->ref_mv_stack[ref_frame],
#if CONFIG_EXT_INTER
compound_inter_mode_ctx,
#endif // CONFIG_EXT_INTER
#endif
ref_mvs[ref_frame],
mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
}
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (is_compound)
mode_ctx = compound_inter_mode_ctx[mbmi->ref_frame[0]];
else
#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,
mbmi->ref_frame, bsize, -1);
#else
......@@ -912,14 +1016,28 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
}
} else {
if (bsize >= BLOCK_8X8)
#if CONFIG_EXT_INTER
{
if (is_compound)
mbmi->mode = read_inter_compound_mode(cm, xd, r, mode_ctx);
else
#endif // CONFIG_EXT_INTER
mbmi->mode = read_inter_mode(cm, xd,
#if CONFIG_REF_MV && CONFIG_EXT_INTER
mbmi,
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
r, mode_ctx);
#if CONFIG_EXT_INTER
}
#endif // CONFIG_EXT_INTER
}
#if CONFIG_EXT_INTER
if (bsize < BLOCK_8X8 ||
(mbmi->mode != ZEROMV && mbmi->mode != ZERO_ZEROMV)) {
#else
if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
#endif // CONFIG_EXT_INTER
for (ref = 0; ref < 1 + is_compound; ++ref) {
vp10_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[ref]],
&nearestmv[ref], &nearmv[ref]);
......@@ -927,19 +1045,52 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
}
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (is_compound && bsize >= BLOCK_8X8 && mbmi->mode != ZERO_ZEROMV) {
#else
if (is_compound && bsize >= BLOCK_8X8 && mbmi->mode != NEWMV &&
mbmi->mode != ZEROMV) {
#endif // CONFIG_EXT_INTER
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
#if CONFIG_EXT_INTER
if (xd->ref_mv_count[ref_frame_type] > 0) {
#else
if (xd->ref_mv_count[ref_frame_type] == 1 && mbmi->mode == NEARESTMV) {
#endif // CONFIG_EXT_INTER
int i;
#if CONFIG_EXT_INTER
if (mbmi->mode == NEAREST_NEARESTMV) {
#endif // CONFIG_EXT_INTER
nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
nearestmv[1] = xd->ref_mv_stack[ref_frame_type][0].comp_mv;
for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i)
lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
#if CONFIG_EXT_INTER
} else if (mbmi->mode == NEAREST_NEWMV || mbmi->mode == NEAREST_NEARMV) {
nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
lower_mv_precision(&nearestmv[0].as_mv, allow_hp);
} else if (mbmi->mode == NEW_NEARESTMV || mbmi->mode == NEAR_NEARESTMV) {
nearestmv[1] = xd->ref_mv_stack[ref_frame_type][0].comp_mv;
lower_mv_precision(&nearestmv[1].as_mv, allow_hp);
}
#endif // CONFIG_EXT_INTER
}
#if CONFIG_EXT_INTER
if (xd->ref_mv_count[ref_frame_type] > 1) {
if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEAR_NEARESTMV) {
nearmv[0] = xd->ref_mv_stack[ref_frame_type][1].this_mv;
lower_mv_precision(&nearmv[0].as_mv, allow_hp);
}
if (mbmi->mode == NEW_NEARMV || mbmi->mode == NEAREST_NEARMV) {
nearmv[1] = xd->ref_mv_stack[ref_frame_type][1].comp_mv;
lower_mv_precision(&nearmv[1].as_mv, allow_hp);
}
}
#else
if (xd->ref_mv_count[ref_frame_type] > 1) {
int i;
nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
......@@ -952,6 +1103,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
lower_mv_precision(&nearmv[i].as_mv, allow_hp);
}
}
#endif // CONFIG_EXT_INTER
}
#endif
......@@ -975,9 +1127,17 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
int_mv block[2];
const int j = idy * 2 + idx;
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (!is_compound)
#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx, mbmi->ref_frame,
bsize, j);
#endif
#if CONFIG_EXT_INTER
if (is_compound)
b_mode = read_inter_compound_mode(cm, xd, r, mode_ctx);
else
#endif // CONFIG_EXT_INTER
b_mode = read_inter_mode(cm, xd,
#if CONFIG_REF_MV && CONFIG_EXT_INTER
mbmi,
......@@ -987,7 +1147,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
#if CONFIG_EXT_INTER
mv_idx = (b_mode == NEWFROMNEARMV) ? 1 : 0;
if (b_mode != ZEROMV) {
if (b_mode != ZEROMV && b_mode != ZERO_ZEROMV) {
#else
if (b_mode == NEARESTMV || b_mode == NEARMV) {
#endif // CONFIG_EXT_INTER
......@@ -1000,7 +1160,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
#endif // CONFIG_EXT_INTER
vp10_append_sub8x8_mvs_for_idx(cm, xd, j, ref, mi_row, mi_col,
#if CONFIG_EXT_INTER
mv_ref_list,
mv_ref_list,
#endif // CONFIG_EXT_INTER
&nearest_sub8x8[ref],
&near_sub8x8[ref]);
......
......@@ -55,6 +55,13 @@ static const struct vp10_token inter_mode_encodings[INTER_MODES] =
{{2, 2}, {6, 3}, {0, 1}, {7, 3}};
#endif // CONFIG_EXT_INTER
#endif
#if CONFIG_EXT_INTER
static const struct vp10_token inter_compound_mode_encodings
[INTER_COMPOUND_MODES] = {
{2, 2}, {24, 5}, {25, 5}, {52, 6}, {53, 6},
{54, 6}, {55, 6}, {0, 1}, {7, 3}
};
#endif // CONFIG_EXT_INTER
static const struct vp10_token palette_size_encodings[] = {
{0, 1}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {63, 6},
};
......@@ -173,6 +180,19 @@ static void write_inter_mode(VP10_COMMON *cm,
#endif
}
#if CONFIG_EXT_INTER
static void write_inter_compound_mode(VP10_COMMON *cm, vpx_writer *w,
PREDICTION_MODE mode,
const int16_t mode_ctx) {
const vpx_prob *const inter_compound_probs =
cm->fc->inter_compound_mode_probs[mode_ctx];
assert(is_inter_compound_mode(mode));
vp10_write_token(w, vp10_inter_compound_mode_tree, inter_compound_probs,
&inter_compound_mode_encodings[INTER_COMPOUND_OFFSET(mode)]);
}
#endif // CONFIG_EXT_INTER
static void encode_unsigned_max(struct vpx_write_bit_buffer *wb,
int data, int max) {
vpx_wb_write_literal(wb, data, get_unsigned_bits(max));
......@@ -302,6 +322,32 @@ static void update_inter_mode_probs(VP10_COMMON *cm, vpx_writer *w,
}
#endif
#if CONFIG_EXT_INTER
static void update_inter_compound_mode_probs(VP10_COMMON *cm, vpx_writer *w) {
const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
int i;
int savings = 0;
int do_update = 0;
for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
savings += prob_diff_update_savings(vp10_inter_compound_mode_tree,
cm->fc->inter_compound_mode_probs[i],
cm->counts.inter_compound_mode[i],
INTER_COMPOUND_MODES);
}
do_update = savings > savings_thresh;
vpx_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
if (do_update) {
for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
prob_diff_update(vp10_inter_compound_mode_tree,
cm->fc->inter_compound_mode_probs[i],
cm->counts.inter_compound_mode[i],
INTER_COMPOUND_MODES, w);
}
}
}
#endif // CONFIG_EXT_INTER
static int write_skip(const VP10_COMMON *cm, const MACROBLOCKD *xd,
int segment_id, const MODE_INFO *mi, vpx_writer *w) {
if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
......@@ -793,8 +839,6 @@ static void write_switchable_interp_filter(VP10_COMP *cpi,
const int ctx = vp10_get_pred_context_switchable_interp(xd);
#if CONFIG_EXT_INTERP
if (!vp10_is_interp_needed(xd)) {
// if (mbmi->interp_filter != EIGHTTAP)
// printf("Error [%d]\n", mbmi->sb_type);
assert(mbmi->interp_filter == EIGHTTAP);
return;
}
......@@ -919,6 +963,11 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
write_ref_frames(cm, xd, w);
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (is_compound)
mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
else
#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
#endif
......@@ -926,6 +975,11 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
// If segment skip is not enabled code the mode.
if (!segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
if (bsize >= BLOCK_8X8) {
#if CONFIG_EXT_INTER
if (is_inter_compound_mode(mode))
write_inter_compound_mode(cm, w, mode, mode_ctx);
else if (is_inter_singleref_mode(mode))
#endif // CONFIG_EXT_INTER
write_inter_mode(cm, w, mode,
#if CONFIG_REF_MV && CONFIG_EXT_INTER
has_second_ref(mbmi),
......@@ -947,9 +1001,17 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
const int j = idy * 2 + idx;
const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (!is_compound)
#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, j);
#endif
#if CONFIG_EXT_INTER
if (is_inter_compound_mode(b_mode))
write_inter_compound_mode(cm, w, b_mode, mode_ctx);
else if (is_inter_singleref_mode(b_mode))
#endif // CONFIG_EXT_INTER
write_inter_mode(cm, w, b_mode,
#if CONFIG_REF_MV && CONFIG_EXT_INTER
has_second_ref(mbmi),
......@@ -957,7 +1019,8 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
mode_ctx);
#if CONFIG_EXT_INTER
if (b_mode == NEWMV || b_mode == NEWFROMNEARMV) {
if (b_mode == NEWMV || b_mode == NEWFROMNEARMV ||
b_mode == NEW_NEWMV) {
#else
if (b_mode == NEWMV) {
#endif // CONFIG_EXT_INTER
......@@ -970,11 +1033,20 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
#endif // CONFIG_EXT_INTER
nmvc, allow_hp);
}
#if CONFIG_EXT_INTER
else if (b_mode == NEAREST_NEWMV || b_mode == NEAR_NEWMV) {
vp10_encode_mv(cpi, w, &mi->bmi[j].as_mv[1].as_mv,
&mi->bmi[j].ref_mv[1].as_mv, nmvc, allow_hp);
} else if (b_mode == NEW_NEARESTMV || b_mode == NEW_NEARMV) {