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 { ...@@ -49,15 +49,26 @@ typedef enum {
static INLINE int is_inter_mode(PREDICTION_MODE mode) { static INLINE int is_inter_mode(PREDICTION_MODE mode) {
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
return mode >= NEARESTMV && mode <= NEWFROMNEARMV; return mode >= NEARESTMV && mode <= NEW_NEWMV;
#else #else
return mode >= NEARESTMV && mode <= NEWMV; return mode >= NEARESTMV && mode <= NEWMV;
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
} }
#if 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) { 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 #endif // CONFIG_EXT_INTER
......
...@@ -211,6 +211,19 @@ static const vpx_prob default_inter_mode_probs[INTER_MODE_CONTEXTS] ...@@ -211,6 +211,19 @@ static const vpx_prob default_inter_mode_probs[INTER_MODE_CONTEXTS]
#endif // CONFIG_EXT_INTER #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. */ /* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = { const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
-DC_PRED, 2, /* 0 = DC_NODE */ -DC_PRED, 2, /* 0 = DC_NODE */
...@@ -235,6 +248,21 @@ const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_MODES)] = { ...@@ -235,6 +248,21 @@ const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_MODES)] = {
#endif // CONFIG_EXT_INTER #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)] = { const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)] = {
-PARTITION_NONE, 2, -PARTITION_NONE, 2,
-PARTITION_HORZ, 4, -PARTITION_HORZ, 4,
...@@ -1257,6 +1285,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { ...@@ -1257,6 +1285,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
#endif // CONFIG_REF_MV #endif // CONFIG_REF_MV
vp10_copy(fc->inter_mode_probs, default_inter_mode_probs); 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 #if CONFIG_SUPERTX
vp10_copy(fc->supertx_prob, default_supertx_prob); vp10_copy(fc->supertx_prob, default_supertx_prob);
#endif // CONFIG_SUPERTX #endif // CONFIG_SUPERTX
...@@ -1336,6 +1367,14 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { ...@@ -1336,6 +1367,14 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
} }
#endif // CONFIG_SUPERTX #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++) for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i], vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i],
counts->y_mode[i], fc->y_mode_prob[i]); counts->y_mode[i], fc->y_mode_prob[i]);
......
...@@ -26,6 +26,9 @@ extern "C" { ...@@ -26,6 +26,9 @@ extern "C" {
#define TX_SIZE_CONTEXTS 2 #define TX_SIZE_CONTEXTS 2
#define INTER_OFFSET(mode) ((mode) - NEARESTMV) #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_COLOR_CONTEXTS 16
#define PALETTE_MAX_SIZE 8 #define PALETTE_MAX_SIZE 8
...@@ -71,6 +74,10 @@ typedef struct frame_contexts { ...@@ -71,6 +74,10 @@ typedef struct frame_contexts {
#endif #endif
vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1]; 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 intra_inter_prob[INTRA_INTER_CONTEXTS];
vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS]; vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1]; vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1];
...@@ -119,6 +126,9 @@ typedef struct FRAME_COUNTS { ...@@ -119,6 +126,9 @@ typedef struct FRAME_COUNTS {
#endif #endif
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES]; 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 intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2]; unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][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 ...@@ -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_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
extern const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_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_partition_tree[TREE_SIZE(PARTITION_TYPES)];
extern const vpx_tree_index vp10_switchable_interp_tree extern const vpx_tree_index vp10_switchable_interp_tree
[TREE_SIZE(SWITCHABLE_FILTERS)]; [TREE_SIZE(SWITCHABLE_FILTERS)];
......
...@@ -179,7 +179,16 @@ typedef enum { ...@@ -179,7 +179,16 @@ typedef enum {
#define NEWMV 13 #define NEWMV 13
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
#define NEWFROMNEARMV 14 #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 #else
#define MB_MODE_COUNT 14 #define MB_MODE_COUNT 14
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
...@@ -212,6 +221,10 @@ typedef enum { ...@@ -212,6 +221,10 @@ typedef enum {
#define INTER_MODES (1 + NEWMV - NEARESTMV) #define INTER_MODES (1 + NEWMV - NEARESTMV)
#endif // CONFIG_EXT_INTER #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 #define SKIP_CONTEXTS 3
#if CONFIG_REF_MV #if CONFIG_REF_MV
......
...@@ -210,7 +210,8 @@ static const int mode_lf_lut[MB_MODE_COUNT] = { ...@@ -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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES
1, 1, 0, 1 // INTER_MODES (ZEROMV == 0) 1, 1, 0, 1 // INTER_MODES (ZEROMV == 0)
#if CONFIG_EXT_INTER #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 #endif // CONFIG_EXT_INTER
}; };
......
...@@ -41,7 +41,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi, ...@@ -41,7 +41,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = 2 * weight; ref_mv_stack[index].weight = 2 * weight;
++(*refmv_count); ++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEWMV || candidate->mode == NEWFROMNEARMV)
#else
if (candidate->mode == NEWMV) if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count; ++newmv_count;
} }
...@@ -62,7 +66,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi, ...@@ -62,7 +66,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = weight; ref_mv_stack[index].weight = weight;
++(*refmv_count); ++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEWMV || candidate->mode == NEWFROMNEARMV)
#else
if (candidate->mode == NEWMV) if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count; ++newmv_count;
} }
} }
...@@ -92,7 +100,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi, ...@@ -92,7 +100,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = 2 * weight; ref_mv_stack[index].weight = 2 * weight;
++(*refmv_count); ++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEW_NEWMV)
#else
if (candidate->mode == NEWMV) if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count; ++newmv_count;
} }
...@@ -116,7 +128,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi, ...@@ -116,7 +128,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
ref_mv_stack[index].weight = weight; ref_mv_stack[index].weight = weight;
++(*refmv_count); ++(*refmv_count);
#if CONFIG_EXT_INTER
if (candidate->mode == NEW_NEWMV)
#else
if (candidate->mode == NEWMV) if (candidate->mode == NEWMV)
#endif // CONFIG_EXT_INTER
++newmv_count; ++newmv_count;
} }
} }
...@@ -664,6 +680,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -664,6 +680,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
#if CONFIG_REF_MV #if CONFIG_REF_MV
uint8_t *ref_mv_count, uint8_t *ref_mv_count,
CANDIDATE_MV *ref_mv_stack, CANDIDATE_MV *ref_mv_stack,
#if CONFIG_EXT_INTER
int16_t *compound_mode_context,
#endif // CONFIG_EXT_INTER
#endif #endif
int_mv *mv_ref_list, int_mv *mv_ref_list,
int mi_row, int mi_col, int mi_row, int mi_col,
...@@ -674,7 +693,12 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -674,7 +693,12 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
#endif #endif
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
vp10_update_mv_context(cm, xd, mi, ref_frame, mv_ref_list, -1, 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, find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1,
mi_row, mi_col, sync, data, NULL); mi_row, mi_col, sync, data, NULL);
#else #else
......
...@@ -57,6 +57,15 @@ static const int mode_2_counter[MB_MODE_COUNT] = { ...@@ -57,6 +57,15 @@ static const int mode_2_counter[MB_MODE_COUNT] = {
1, // NEWMV 1, // NEWMV
#if CONFIG_EXT_INTER #if CONFIG_EXT_INTER
1, // NEWFROMNEARMV 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 #endif // CONFIG_EXT_INTER
}; };
...@@ -255,6 +264,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -255,6 +264,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
#if CONFIG_REF_MV #if CONFIG_REF_MV
uint8_t *ref_mv_count, uint8_t *ref_mv_count,
CANDIDATE_MV *ref_mv_stack, CANDIDATE_MV *ref_mv_stack,
#if CONFIG_EXT_INTER
int16_t *compound_mode_context,
#endif // CONFIG_EXT_INTER
#endif #endif
int_mv *mv_ref_list, int mi_row, int mi_col, int_mv *mv_ref_list, int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data, find_mv_refs_sync sync, void *const data,
......
...@@ -389,6 +389,13 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts, ...@@ -389,6 +389,13 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
for (j = 0; j < INTER_MODES; j++) for (j = 0; j < INTER_MODES; j++)
cm->counts.inter_mode[i][j] += counts->inter_mode[i][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 (i = 0; i < INTRA_INTER_CONTEXTS; i++)
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
cm->counts.intra_inter[i][j] += counts->intra_inter[i][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) { ...@@ -143,6 +143,19 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
#endif #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, static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
struct vpx_read_bit_buffer *rb) { struct vpx_read_bit_buffer *rb) {
if (is_compound_reference_allowed(cm)) { if (is_compound_reference_allowed(cm)) {
...@@ -3259,6 +3272,10 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data, ...@@ -3259,6 +3272,10 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
read_inter_mode_probs(fc, &r); 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) if (cm->interp_filter == SWITCHABLE)
read_switchable_interp_probs(fc, &r); read_switchable_interp_probs(fc, &r);
...@@ -3308,6 +3325,11 @@ static void debug_check_frame_counts(const VP10_COMMON *const cm) { ...@@ -3308,6 +3325,11 @@ static void debug_check_frame_counts(const VP10_COMMON *const cm) {
sizeof(cm->counts.switchable_interp))); sizeof(cm->counts.switchable_interp)));
assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode, assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
sizeof(cm->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, assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,
sizeof(cm->counts.intra_inter))); sizeof(cm->counts.intra_inter)));
assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_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, ...@@ -147,6 +147,22 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
#endif #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, static int read_segment_id(vpx_reader *r,
const struct segmentation_probs *segp) { const struct segmentation_probs *segp) {
return vpx_read_tree(r, vp10_segment_tree, segp->tree_probs); 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, ...@@ -826,6 +842,83 @@ static INLINE int assign_mv(VP10_COMMON *cm, MACROBLOCKD *xd,
mv[1].as_int = 0; mv[1].as_int = 0;
break; 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: { default: {
return 0; return 0;
} }
...@@ -868,6 +961,9 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, ...@@ -868,6 +961,9 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
#endif // CONFIG_EXT_INTER #endif // CONFIG_EXT_INTER
int ref, is_compound; int ref, is_compound;
int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES]; 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; int16_t mode_ctx = 0;
MV_REFERENCE_FRAME ref_frame; MV_REFERENCE_FRAME ref_frame;
...@@ -891,12 +987,20 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, ...@@ -891,12 +987,20 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
#if CONFIG_REF_MV #if CONFIG_REF_MV
&xd->ref_mv_count[ref_frame], &xd->ref_mv_count[ref_frame],
xd->ref_mv_stack[ref_frame], xd->ref_mv_stack[ref_frame],
#if CONFIG_EXT_INTER
compound_inter_mode_ctx,
#endif // CONFIG_EXT_INTER
#endif #endif
ref_mvs[ref_frame], ref_mvs[ref_frame],
mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx); mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
} }
#if CONFIG_REF_MV #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, mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,
mbmi->ref_frame, bsize, -1); mbmi->ref_frame, bsize, -1);
#else #else
...@@ -912,14 +1016,28 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, ...@@ -912,14 +1016,28 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
} }
} else { } else {
if (bsize >= BLOCK_8X8) 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, mbmi->mode = read_inter_mode(cm, xd,
#if CONFIG_REF_MV && CONFIG_EXT_INTER #if CONFIG_REF_MV && CONFIG_EXT_INTER
mbmi, mbmi,
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER #endif // CONFIG_REF_MV && CONFIG_EXT_INTER
r, mode_ctx); 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) { if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
#endif // CONFIG_EXT_INTER
for (ref = 0; ref < 1 + is_compound; ++ref) { for (ref = 0; ref < 1 + is_compound; ++ref) {
vp10_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[ref]], vp10_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[ref]],
&nearestmv[ref], &nearmv[ref]); &nearestmv[ref], &nearmv[ref]);
...@@ -927,19 +1045,52 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, ...@@ -927,19 +1045,52 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
} }
#if CONFIG_REF_MV #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 && if (is_compound && bsize >= BLOCK_8X8 && mbmi->mode != NEWMV &&
mbmi->mode != ZEROMV) { mbmi->mode != ZEROMV) {
#endif // CONFIG_EXT_INTER
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame); 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) { if (xd->ref_mv_count[ref_frame_type