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
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h
index 8c75c97..8011456a 100644
--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -49,15 +49,26 @@
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
diff --git a/vp10/common/entropymode.c b/vp10/common/entropymode.c
index 5797451..44c1099 100644
--- a/vp10/common/entropymode.c
+++ b/vp10/common/entropymode.c
@@ -211,6 +211,19 @@
#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 @@
#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 @@
#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 @@
}
#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]);
diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h
index ffaa3df..01dcd52 100644
--- a/vp10/common/entropymode.h
+++ b/vp10/common/entropymode.h
@@ -26,6 +26,9 @@
#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 @@
#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 @@
#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_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)];
diff --git a/vp10/common/enums.h b/vp10/common/enums.h
index 5b4d1c5..fdcde99 100644
--- a/vp10/common/enums.h
+++ b/vp10/common/enums.h
@@ -179,7 +179,16 @@
#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 @@
#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
diff --git a/vp10/common/loopfilter.c b/vp10/common/loopfilter.c
index 380312e..a484533 100644
--- a/vp10/common/loopfilter.c
+++ b/vp10/common/loopfilter.c
@@ -210,7 +210,8 @@
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
};
diff --git a/vp10/common/mvref_common.c b/vp10/common/mvref_common.c
index 89cd8bb..53394e9 100644
--- a/vp10/common/mvref_common.c
+++ b/vp10/common/mvref_common.c
@@ -41,7 +41,11 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
#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
diff --git a/vp10/common/mvref_common.h b/vp10/common/mvref_common.h
index c1ddc95..4187247 100644
--- a/vp10/common/mvref_common.h
+++ b/vp10/common/mvref_common.h
@@ -57,6 +57,15 @@
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 @@
#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,
diff --git a/vp10/common/thread_common.c b/vp10/common/thread_common.c
index c9cc343..be8b9d1 100644
--- a/vp10/common/thread_common.c
+++ b/vp10/common/thread_common.c
@@ -389,6 +389,13 @@
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];
diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c
index 33e8332..0ed16f1 100644
--- a/vp10/decoder/decodeframe.c
+++ b/vp10/decoder/decodeframe.c
@@ -143,6 +143,19 @@
#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 @@
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 @@
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,
diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c
index d7c3faf..8f6d510 100644
--- a/vp10/decoder/decodemv.c
+++ b/vp10/decoder/decodemv.c
@@ -147,6 +147,22 @@
#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 @@
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 @@
#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 @@
#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 @@
}
} 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 @@
}
#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 @@
lower_mv_precision(&nearmv[i].as_mv, allow_hp);
}
}
+#endif // CONFIG_EXT_INTER
}
#endif
@@ -975,9 +1127,17 @@
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 @@
#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 @@
#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]);
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index 098c86a..48c2564 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -55,6 +55,13 @@
{{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 @@
#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 @@
}
#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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
#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) {
+ vp10_encode_mv(cpi, w, &mi->bmi[j].as_mv[0].as_mv,
+ &mi->bmi[j].ref_mv[0].as_mv, nmvc, allow_hp);
+ }
+#endif // CONFIG_EXT_INTER
}
}
} else {
#if CONFIG_EXT_INTER
- if (mode == NEWMV || mode == NEWFROMNEARMV) {
+ if (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV) {
#else
if (mode == NEWMV) {
#endif // CONFIG_EXT_INTER
@@ -992,6 +1064,14 @@
allow_hp);
#if CONFIG_EXT_INTER
}
+ } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
+ vp10_encode_mv(cpi, w, &mbmi->mv[1].as_mv,
+ &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv, nmvc,
+ allow_hp);
+ } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
+ vp10_encode_mv(cpi, w, &mbmi->mv[0].as_mv,
+ &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv, nmvc,
+ allow_hp);
#endif // CONFIG_EXT_INTER
}
}
@@ -2212,6 +2292,10 @@
counts->inter_mode[i], INTER_MODES, &header_bc);
#endif
+#if CONFIG_EXT_INTER
+ update_inter_compound_mode_probs(cm, &header_bc);
+#endif // CONFIG_EXT_INTER
+
if (cm->interp_filter == SWITCHABLE)
update_switchable_interp_probs(cm, &header_bc, counts);
diff --git a/vp10/encoder/block.h b/vp10/encoder/block.h
index 597f0d7..3e322de 100644
--- a/vp10/encoder/block.h
+++ b/vp10/encoder/block.h
@@ -56,6 +56,9 @@
#if CONFIG_REF_MV
uint8_t ref_mv_count[MODE_CTX_REF_FRAMES];
CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
+#if CONFIG_EXT_INTER
+ int16_t compound_mode_context[MODE_CTX_REF_FRAMES];
+#endif // CONFIG_EXT_INTER
#endif
} MB_MODE_INFO_EXT;
diff --git a/vp10/encoder/denoiser.c b/vp10/encoder/denoiser.c
index 43647b0..e876676 100644
--- a/vp10/encoder/denoiser.c
+++ b/vp10/encoder/denoiser.c
@@ -230,9 +230,19 @@
frame = ctx->best_zeromv_reference_frame;
mbmi->ref_frame[0] = ctx->best_zeromv_reference_frame;
+#if CONFIG_EXT_INTER
+ if (has_second_ref(mbmi))
+ mbmi->mode = ZERO_ZEROMV;
+ else
+#endif // CONFIG_EXT_INTER
mbmi->mode = ZEROMV;
mbmi->mv[0].as_int = 0;
+#if CONFIG_EXT_INTER
+ if (has_second_ref(mbmi))
+ ctx->best_sse_inter_mode = ZERO_ZEROMV;
+ else
+#endif // CONFIG_EXT_INTER
ctx->best_sse_inter_mode = ZEROMV;
ctx->best_sse_mv.as_int = 0;
ctx->newmv_sse = ctx->zeromv_sse;
diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c
index 52926e3..8c75287 100644
--- a/vp10/encoder/encodeframe.c
+++ b/vp10/encoder/encodeframe.c
@@ -1796,6 +1796,12 @@
if (bsize >= BLOCK_8X8) {
const PREDICTION_MODE mode = mbmi->mode;
#if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+ if (has_second_ref(mbmi)) {
+ mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
+ ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
+ } else {
+#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
update_inter_mode_stats(counts, mode,
@@ -1803,8 +1809,15 @@
has_second_ref(mbmi),
#endif // CONFIG_EXT_INTER
mode_ctx);
-
+#if CONFIG_EXT_INTER
+ }
+#endif // CONFIG_EXT_INTER
#else
+#if CONFIG_EXT_INTER
+ if (is_inter_compound_mode(mode))
+ ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
+ else
+#endif // CONFIG_EXT_INTER
++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
#endif
} else {
@@ -1816,6 +1829,13 @@
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 (has_second_ref(mbmi)) {
+ mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
+ ++counts->inter_compound_mode[mode_ctx]
+ [INTER_COMPOUND_OFFSET(b_mode)];
+ } else {
+#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, j);
update_inter_mode_stats(counts, b_mode,
@@ -1823,7 +1843,16 @@
has_second_ref(mbmi),
#endif // CONFIG_EXT_INTER
mode_ctx);
+#if CONFIG_EXT_INTER
+ }
+#endif // CONFIG_EXT_INTER
#else
+#if CONFIG_EXT_INTER
+ if (is_inter_compound_mode(b_mode))
+ ++counts->inter_compound_mode[mode_ctx]
+ [INTER_COMPOUND_OFFSET(b_mode)];
+ else
+#endif // CONFIG_EXT_INTER
++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
#endif
}
diff --git a/vp10/encoder/encodemv.c b/vp10/encoder/encodemv.c
index 0184bae..4124c4a 100644
--- a/vp10/encoder/encodemv.c
+++ b/vp10/encoder/encodemv.c
@@ -232,13 +232,23 @@
PREDICTION_MODE mode = mbmi->mode;
int mv_idx = (mode == NEWFROMNEARMV);
- if (mode == NEWMV || mode == NEWFROMNEARMV) {
+ if (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV) {
for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[i]][mv_idx].as_mv;
const MV diff = {mvs[i].as_mv.row - ref->row,
mvs[i].as_mv.col - ref->col};
vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
}
+ } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
+ const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv;
+ const MV diff = {mvs[1].as_mv.row - ref->row,
+ mvs[1].as_mv.col - ref->col};
+ vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
+ } 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,
+ mvs[0].as_mv.col - ref->col};
+ vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
}
}
@@ -249,13 +259,23 @@
int i;
PREDICTION_MODE mode = mi->bmi[block].as_mode;
- if (mode == NEWMV || mode == NEWFROMNEARMV) {
+ if (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV) {
for (i = 0; i < 1 + has_second_ref(&mi->mbmi); ++i) {
const MV *ref = &mi->bmi[block].ref_mv[i].as_mv;
const MV diff = {mvs[i].as_mv.row - ref->row,
mvs[i].as_mv.col - ref->col};
vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
}
+ } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
+ const MV *ref = &mi->bmi[block].ref_mv[1].as_mv;
+ const MV diff = {mvs[1].as_mv.row - ref->row,
+ mvs[1].as_mv.col - ref->col};
+ vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
+ } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
+ const MV *ref = &mi->bmi[block].ref_mv[0].as_mv;
+ const MV diff = {mvs[0].as_mv.row - ref->row,
+ mvs[0].as_mv.col - ref->col};
+ vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
}
}
#else
diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h
index 797abac..d5c432f 100644
--- a/vp10/encoder/encoder.h
+++ b/vp10/encoder/encoder.h
@@ -482,6 +482,10 @@
#endif
unsigned int inter_mode_cost[INTER_MODE_CONTEXTS][INTER_MODES];
+#if CONFIG_EXT_INTER
+ unsigned int inter_compound_mode_cost[INTER_MODE_CONTEXTS]
+ [INTER_COMPOUND_MODES];
+#endif // CONFIG_EXT_INTER
int intra_uv_mode_cost[INTRA_MODES][INTRA_MODES];
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
diff --git a/vp10/encoder/mbgraph.c b/vp10/encoder/mbgraph.c
index ed0f539..ab1e60f 100644
--- a/vp10/encoder/mbgraph.c
+++ b/vp10/encoder/mbgraph.c
@@ -67,6 +67,11 @@
&distortion, &sse, NULL, 0, 0);
}
+#if CONFIG_EXT_INTER
+ if (has_second_ref(&xd->mi[0]->mbmi))
+ xd->mi[0]->mbmi.mode = NEW_NEWMV;
+ else
+#endif // CONFIG_EXT_INTER
xd->mi[0]->mbmi.mode = NEWMV;
xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv;
diff --git a/vp10/encoder/rd.c b/vp10/encoder/rd.c
index d67f7c3..9dede8e 100644
--- a/vp10/encoder/rd.c
+++ b/vp10/encoder/rd.c
@@ -386,6 +386,12 @@
vp10_cost_tokens((int *)cpi->inter_mode_cost[i],
cm->fc->inter_mode_probs[i], vp10_inter_mode_tree);
#endif
+#if CONFIG_EXT_INTER
+ for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
+ vp10_cost_tokens((int *)cpi->inter_compound_mode_cost[i],
+ cm->fc->inter_compound_mode_probs[i],
+ vp10_inter_compound_mode_tree);
+#endif // CONFIG_EXT_INTER
}
}
@@ -692,11 +698,11 @@
#if CONFIG_EXT_INTER
rd->thresh_mult[THR_NEWFROMNEARMV] += 1000;
-#if CONFIG_EXT_REF
+#if CONFIG_EXT_REFS
rd->thresh_mult[THR_NEWFROMNEARL2] += 1000;
rd->thresh_mult[THR_NEWFROMNEARL3] += 1000;
rd->thresh_mult[THR_NEWFROMNEARL4] += 1000;
-#endif // CONFIG_EXT_REF
+#endif // CONFIG_EXT_REFS
rd->thresh_mult[THR_NEWFROMNEARG] += 1000;
rd->thresh_mult[THR_NEWFROMNEARA] += 1000;
#endif // CONFIG_EXT_INTER
@@ -712,6 +718,59 @@
rd->thresh_mult[THR_TM] += 1000;
+#if CONFIG_EXT_INTER
+ rd->thresh_mult[THR_COMP_NEAREST_NEARESTLA] += 1000;
+ rd->thresh_mult[THR_COMP_NEAREST_NEARESTGA] += 1000;
+ rd->thresh_mult[THR_COMP_NEAREST_NEARLA] += 1200;
+ rd->thresh_mult[THR_COMP_NEAREST_NEARGA] += 1200;
+ rd->thresh_mult[THR_COMP_NEAR_NEARESTLA] += 1200;
+ rd->thresh_mult[THR_COMP_NEAR_NEARESTGA] += 1200;
+ rd->thresh_mult[THR_COMP_NEAREST_NEWLA] += 1500;
+ rd->thresh_mult[THR_COMP_NEAREST_NEWGA] += 1500;
+ rd->thresh_mult[THR_COMP_NEW_NEARESTLA] += 1500;
+ rd->thresh_mult[THR_COMP_NEW_NEARESTGA] += 1500;
+ rd->thresh_mult[THR_COMP_NEAR_NEWLA] += 1700;
+ rd->thresh_mult[THR_COMP_NEAR_NEWGA] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEARLA] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEARGA] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEWLA] += 2000;
+ rd->thresh_mult[THR_COMP_NEW_NEWGA] += 2000;
+ rd->thresh_mult[THR_COMP_ZERO_ZEROLA] += 2500;
+ rd->thresh_mult[THR_COMP_ZERO_ZEROGA] += 2500;
+
+#if CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_NEAREST_NEARESTL2A] += 1000;
+ rd->thresh_mult[THR_COMP_NEAREST_NEARL2A] += 1200;
+ rd->thresh_mult[THR_COMP_NEAR_NEARESTL2A] += 1200;
+ rd->thresh_mult[THR_COMP_NEAREST_NEWL2A] += 1500;
+ rd->thresh_mult[THR_COMP_NEW_NEARESTL2A] += 1500;
+ rd->thresh_mult[THR_COMP_NEAR_NEWL2A] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEARL2A] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEWL2A] += 2000;
+ rd->thresh_mult[THR_COMP_ZERO_ZEROL2A] += 2500;
+
+ rd->thresh_mult[THR_COMP_NEAREST_NEARESTL3A] += 1000;
+ rd->thresh_mult[THR_COMP_NEAREST_NEARL3A] += 1200;
+ rd->thresh_mult[THR_COMP_NEAR_NEARESTL3A] += 1200;
+ rd->thresh_mult[THR_COMP_NEAREST_NEWL3A] += 1500;
+ rd->thresh_mult[THR_COMP_NEW_NEARESTL3A] += 1500;
+ rd->thresh_mult[THR_COMP_NEAR_NEWL3A] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEARL3A] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEWL3A] += 2000;
+ rd->thresh_mult[THR_COMP_ZERO_ZEROL3A] += 2500;
+
+ rd->thresh_mult[THR_COMP_NEAREST_NEARESTL4A] += 1000;
+ rd->thresh_mult[THR_COMP_NEAREST_NEARL4A] += 1200;
+ rd->thresh_mult[THR_COMP_NEAR_NEARESTL4A] += 1200;
+ rd->thresh_mult[THR_COMP_NEAREST_NEWL4A] += 1500;
+ rd->thresh_mult[THR_COMP_NEW_NEARESTL4A] += 1500;
+ rd->thresh_mult[THR_COMP_NEAR_NEWL4A] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEARL4A] += 1700;
+ rd->thresh_mult[THR_COMP_NEW_NEWL4A] += 2000;
+ rd->thresh_mult[THR_COMP_ZERO_ZEROL4A] += 2500;
+
+#endif // CONFIG_EXT_REFS
+#else
rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
#if CONFIG_EXT_REFS
rd->thresh_mult[THR_COMP_NEARESTL2A] += 1000;
@@ -740,6 +799,7 @@
rd->thresh_mult[THR_COMP_ZEROL4A] += 2500;
#endif // CONFIG_EXT_REFS
rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
+#endif // CONFIG_EXT_INTER
rd->thresh_mult[THR_H_PRED] += 2000;
rd->thresh_mult[THR_V_PRED] += 2000;
diff --git a/vp10/encoder/rd.h b/vp10/encoder/rd.h
index 2b6106d..2303c20 100644
--- a/vp10/encoder/rd.h
+++ b/vp10/encoder/rd.h
@@ -39,13 +39,13 @@
#if CONFIG_EXT_REFS
#if CONFIG_EXT_INTER
-#define MAX_MODES 60
+#define MAX_MODES 85
#else
#define MAX_MODES 54
#endif // CONFIG_EXT_INTER
#else
#if CONFIG_EXT_INTER
-#define MAX_MODES 33
+#define MAX_MODES 43
#else
#define MAX_MODES 30
#endif // CONFIG_EXT_INTER
@@ -94,11 +94,11 @@
#if CONFIG_EXT_INTER
THR_NEWFROMNEARMV,
-#if CONFIG_EXT_REF
+#if CONFIG_EXT_REFS
THR_NEWFROMNEARL2,
THR_NEWFROMNEARL3,
THR_NEWFROMNEARL4,
-#endif // CONFIG_EXT_REF
+#endif // CONFIG_EXT_REFS
THR_NEWFROMNEARA,
THR_NEWFROMNEARG,
#endif // CONFIG_EXT_INTER
@@ -112,6 +112,15 @@
THR_ZEROG,
THR_ZEROA,
+#if CONFIG_EXT_INTER
+ THR_COMP_NEAREST_NEARESTLA,
+#if CONFIG_EXT_REFS
+ THR_COMP_NEAREST_NEARESTL2A,
+ THR_COMP_NEAREST_NEARESTL3A,
+ THR_COMP_NEAREST_NEARESTL4A,
+#endif // CONFIG_EXT_REFS
+ THR_COMP_NEAREST_NEARESTGA,
+#else // CONFIG_EXT_INTER
THR_COMP_NEARESTLA,
#if CONFIG_EXT_REFS
THR_COMP_NEARESTL2A,
@@ -119,9 +128,57 @@
THR_COMP_NEARESTL4A,
#endif // CONFIG_EXT_REFS
THR_COMP_NEARESTGA,
+#endif // CONFIG_EXT_INTER
THR_TM,
+#if CONFIG_EXT_INTER
+ THR_COMP_NEAR_NEARESTLA,
+ THR_COMP_NEAR_NEARESTGA,
+ THR_COMP_NEAREST_NEARLA,
+ THR_COMP_NEAREST_NEARGA,
+ THR_COMP_NEW_NEARESTLA,
+ THR_COMP_NEW_NEARESTGA,
+ THR_COMP_NEAREST_NEWLA,
+ THR_COMP_NEAREST_NEWGA,
+ THR_COMP_NEW_NEARLA,
+ THR_COMP_NEW_NEARGA,
+ THR_COMP_NEAR_NEWLA,
+ THR_COMP_NEAR_NEWGA,
+ THR_COMP_NEW_NEWLA,
+ THR_COMP_NEW_NEWGA,
+ THR_COMP_ZERO_ZEROLA,
+ THR_COMP_ZERO_ZEROGA,
+
+#if CONFIG_EXT_REFS
+ THR_COMP_NEAR_NEARESTL2A,
+ THR_COMP_NEAREST_NEARL2A,
+ THR_COMP_NEW_NEARESTL2A,
+ THR_COMP_NEAREST_NEWL2A,
+ THR_COMP_NEW_NEARL2A,
+ THR_COMP_NEAR_NEWL2A,
+ THR_COMP_NEW_NEWL2A,
+ THR_COMP_ZERO_ZEROL2A,
+
+ THR_COMP_NEAR_NEARESTL3A,
+ THR_COMP_NEAREST_NEARL3A,
+ THR_COMP_NEW_NEARESTL3A,
+ THR_COMP_NEAREST_NEWL3A,
+ THR_COMP_NEW_NEARL3A,
+ THR_COMP_NEAR_NEWL3A,
+ THR_COMP_NEW_NEWL3A,
+ THR_COMP_ZERO_ZEROL3A,
+
+ THR_COMP_NEAR_NEARESTL4A,
+ THR_COMP_NEAREST_NEARL4A,
+ THR_COMP_NEW_NEARESTL4A,
+ THR_COMP_NEAREST_NEWL4A,
+ THR_COMP_NEW_NEARL4A,
+ THR_COMP_NEAR_NEWL4A,
+ THR_COMP_NEW_NEWL4A,
+ THR_COMP_ZERO_ZEROL4A,
+#endif // CONFIG_EXT_REFS
+#else
THR_COMP_NEARLA,
THR_COMP_NEWLA,
#if CONFIG_EXT_REFS
@@ -142,6 +199,7 @@
THR_COMP_ZEROL4A,
#endif // CONFIG_EXT_REFS
THR_COMP_ZEROGA,
+#endif // CONFIG_EXT_INTER
THR_H_PRED,
THR_V_PRED,
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c
index ec67dca..0ec4af1 100644
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -148,11 +148,11 @@
#if CONFIG_EXT_INTER
{NEWFROMNEARMV, {LAST_FRAME, NONE}},
-#if CONFIG_EXT_REF
+#if CONFIG_EXT_REFS
{NEWFROMNEARMV, {LAST2_FRAME, NONE}},
{NEWFROMNEARMV, {LAST3_FRAME, NONE}},
{NEWFROMNEARMV, {LAST4_FRAME, NONE}},
-#endif // CONFIG_EXT_REF
+#endif // CONFIG_EXT_REFS
{NEWFROMNEARMV, {ALTREF_FRAME, NONE}},
{NEWFROMNEARMV, {GOLDEN_FRAME, NONE}},
#endif // CONFIG_EXT_INTER
@@ -166,6 +166,15 @@
{ZEROMV, {GOLDEN_FRAME, NONE}},
{ZEROMV, {ALTREF_FRAME, NONE}},
+#if CONFIG_EXT_INTER
+ {NEAREST_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
+#if CONFIG_EXT_REFS
+ {NEAREST_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
+#endif // CONFIG_EXT_REFS
+ {NEAREST_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#else // CONFIG_EXT_INTER
{NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
#if CONFIG_EXT_REFS
{NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
@@ -173,9 +182,56 @@
{NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
#endif // CONFIG_EXT_REFS
{NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#endif // CONFIG_EXT_INTER
{TM_PRED, {INTRA_FRAME, NONE}},
+#if CONFIG_EXT_INTER
+ {NEAR_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEAR_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {NEW_NEARESTMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEW_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {NEW_NEARMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEW_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {NEAR_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEAR_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {NEW_NEWMV, {LAST_FRAME, ALTREF_FRAME}},
+ {NEW_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+ {ZERO_ZEROMV, {LAST_FRAME, ALTREF_FRAME}},
+ {ZERO_ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#if CONFIG_EXT_REFS
+ {NEAR_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEW_NEARESTMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEW_NEARMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEAR_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {NEW_NEWMV, {LAST2_FRAME, ALTREF_FRAME}},
+ {ZERO_ZEROMV, {LAST2_FRAME, ALTREF_FRAME}},
+
+ {NEAR_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEW_NEARESTMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEW_NEARMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEAR_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {NEW_NEWMV, {LAST3_FRAME, ALTREF_FRAME}},
+ {ZERO_ZEROMV, {LAST3_FRAME, ALTREF_FRAME}},
+
+ {NEAR_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {NEW_NEARESTMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {NEAREST_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {NEW_NEARMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {NEAR_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {NEW_NEWMV, {LAST4_FRAME, ALTREF_FRAME}},
+ {ZERO_ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
+#endif // CONFIG_EXT_REFS
+#else
{NEARMV, {LAST_FRAME, ALTREF_FRAME}},
{NEWMV, {LAST_FRAME, ALTREF_FRAME}},
#if CONFIG_EXT_REFS
@@ -196,6 +252,7 @@
{ZEROMV, {LAST4_FRAME, ALTREF_FRAME}},
#endif // CONFIG_EXT_REFS
{ZEROMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#endif // CONFIG_EXT_INTER
{H_PRED, {INTRA_FRAME, NONE}},
{V_PRED, {INTRA_FRAME, NONE}},
@@ -3150,13 +3207,22 @@
int16_t mode_context) {
#if CONFIG_REF_MV
int mode_cost = 0;
+#if CONFIG_EXT_INTER
+ int16_t mode_ctx = is_compound ? mode_context :
+ (mode_context & NEWMV_CTX_MASK);
+#else
int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
+#endif // CONFIG_EXT_INTER
int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
assert(is_inter_mode(mode));
#if CONFIG_EXT_INTER
- if (mode == NEWMV || mode == NEWFROMNEARMV) {
+ if (is_compound) {
+ return cpi->inter_compound_mode_cost[mode_context]
+ [INTER_COMPOUND_OFFSET(mode)];
+ } else {
+ if (mode == NEWMV || mode == NEWFROMNEARMV) {
#else
if (mode == NEWMV) {
#endif // CONFIG_EXT_INTER
@@ -3191,9 +3257,21 @@
return mode_cost;
}
}
+#if CONFIG_EXT_INTER
+ }
+#endif // CONFIG_EXT_INTER
#else
assert(is_inter_mode(mode));
+#if CONFIG_EXT_INTER
+ if (is_inter_compound_mode(mode)) {
+ return cpi->inter_compound_mode_cost[mode_context]
+ [INTER_COMPOUND_OFFSET(mode)];
+ } else {
+#endif // CONFIG_EXT_INTER
return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
+#if CONFIG_EXT_INTER
+ }
+#endif // CONFIG_EXT_INTER
#endif
}
@@ -3221,7 +3299,6 @@
case NEWMV:
#if CONFIG_EXT_INTER
case NEWFROMNEARMV:
- if (!is_compound) {
#endif // CONFIG_EXT_INTER
this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
#if CONFIG_EXT_INTER
@@ -3231,36 +3308,13 @@
#endif // CONFIG_EXT_INTER
thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
mvjcost, mvcost, MV_COST_WEIGHT_SUB);
-#if CONFIG_EXT_INTER
- } else {
- if (compound_seg_newmvs[0].as_int == INVALID_MV ||
- compound_seg_newmvs[1].as_int == INVALID_MV) {
- this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
- this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
- } else {
- this_mv[0].as_int = compound_seg_newmvs[0].as_int;
- this_mv[1].as_int = compound_seg_newmvs[1].as_int;
- }
- if (!cpi->common.allow_high_precision_mv ||
- !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
- lower_mv_precision(&this_mv[0].as_mv, 0);
- if (!cpi->common.allow_high_precision_mv ||
- !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
- lower_mv_precision(&this_mv[1].as_mv, 0);
- thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
- &best_ref_mv[0]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
- &best_ref_mv[1]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- }
-#else
+#if !CONFIG_EXT_INTER
if (is_compound) {
this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
mvjcost, mvcost, MV_COST_WEIGHT_SUB);
}
-#endif // CONFIG_EXT_INTER
+#endif // !CONFIG_EXT_INTER
break;
case NEARMV:
case NEARESTMV:
@@ -3273,6 +3327,60 @@
if (is_compound)
this_mv[1].as_int = 0;
break;
+#if CONFIG_EXT_INTER
+ case NEW_NEWMV:
+ if (compound_seg_newmvs[0].as_int == INVALID_MV ||
+ compound_seg_newmvs[1].as_int == INVALID_MV) {
+ this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
+ this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
+ } else {
+ this_mv[0].as_int = compound_seg_newmvs[0].as_int;
+ this_mv[1].as_int = compound_seg_newmvs[1].as_int;
+ }
+ if (!cpi->common.allow_high_precision_mv ||
+ !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
+ lower_mv_precision(&this_mv[0].as_mv, 0);
+ if (!cpi->common.allow_high_precision_mv ||
+ !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
+ lower_mv_precision(&this_mv[1].as_mv, 0);
+ thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
+ &best_ref_mv[0]->as_mv,
+ mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+ thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
+ &best_ref_mv[1]->as_mv,
+ mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+ break;
+ case NEW_NEARMV:
+ case NEW_NEARESTMV:
+ this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
+ if (!cpi->common.allow_high_precision_mv ||
+ !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
+ lower_mv_precision(&this_mv[0].as_mv, 0);
+ thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
+ mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+ this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
+ break;
+ case NEAR_NEWMV:
+ case NEAREST_NEWMV:
+ this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
+ this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
+ if (!cpi->common.allow_high_precision_mv ||
+ !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
+ lower_mv_precision(&this_mv[1].as_mv, 0);
+ thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
+ mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+ break;
+ case NEAREST_NEARMV:
+ case NEAR_NEARESTMV:
+ case NEAREST_NEARESTMV:
+ this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
+ this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
+ break;
+ case ZERO_ZEROMV:
+ this_mv[0].as_int = 0;
+ this_mv[1].as_int = 0;
+ break;
+#endif // CONFIG_EXT_INTER
default:
break;
}
@@ -3288,6 +3396,11 @@
memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
#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, mbmi->sb_type, i);
#endif
@@ -3441,7 +3554,11 @@
int64_t sse;
int segment_yrate;
PREDICTION_MODE modes[4];
+#if CONFIG_EXT_INTER
+ SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
+#else
SEG_RDSTAT rdstat[4][INTER_MODES];
+#endif // CONFIG_EXT_INTER
int mvthresh;
} BEST_SEG_INFO;
@@ -3480,6 +3597,9 @@
// TODO(aconverse): Find out if this is still productive then clean up or remove
static int check_best_zero_mv(
const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+ const int16_t compound_mode_context[MAX_REF_FRAMES],
+#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
const MV_REFERENCE_FRAME ref_frames[2],
const BLOCK_SIZE bsize, int block) {
@@ -3527,6 +3647,56 @@
}
}
}
+#if CONFIG_EXT_INTER
+ else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
+ this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
+ frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
+ frame_mv[this_mode][ref_frames[1]].as_int == 0) {
+#if CONFIG_REF_MV
+ int16_t rfc = compound_mode_context[ref_frames[0]];
+ int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
+ int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
+ int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
+ int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
+#else
+ int16_t rfc = mode_context[ref_frames[0]];
+ int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
+ int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
+ int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
+ int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
+#endif
+
+ if (this_mode == NEAREST_NEARMV) {
+ if (c1 > c3) return 0;
+ } else if (this_mode == NEAREST_NEARESTMV) {
+ if (c2 > c3) return 0;
+ } else if (this_mode == NEAR_NEARESTMV) {
+ if (c4 > c3) return 0;
+ } else {
+ assert(this_mode == ZERO_ZEROMV);
+ if (ref_frames[1] == NONE) {
+ if ((c3 >= c2 &&
+ frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0) ||
+ (c3 >= c1 &&
+ frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0) ||
+ (c3 >= c4 &&
+ frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0))
+ return 0;
+ } else {
+ if ((c3 >= c2 &&
+ frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
+ frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
+ (c3 >= c1 &&
+ frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
+ frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
+ (c3 >= c4 &&
+ frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
+ frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
+ return 0;
+ }
+ }
+ }
+#endif // CONFIG_EXT_INTER
return 1;
}
@@ -3827,13 +3997,40 @@
mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
&ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
+
+ if (has_second_rf) {
+ frame_mv[ZERO_ZEROMV][frame].as_int = 0;
+ frame_mv[NEAREST_NEARESTMV][frame].as_int =
+ frame_mv[NEARESTMV][frame].as_int;
+
+ if (ref == 0) {
+ frame_mv[NEAREST_NEARMV][frame].as_int =
+ frame_mv[NEARESTMV][frame].as_int;
+ frame_mv[NEAR_NEARESTMV][frame].as_int =
+ frame_mv[NEARMV][frame].as_int;
+ frame_mv[NEAREST_NEWMV][frame].as_int =
+ frame_mv[NEARESTMV][frame].as_int;
+ frame_mv[NEAR_NEWMV][frame].as_int =
+ frame_mv[NEARMV][frame].as_int;
+ } else if (ref == 1) {
+ frame_mv[NEAREST_NEARMV][frame].as_int =
+ frame_mv[NEARMV][frame].as_int;
+ frame_mv[NEAR_NEARESTMV][frame].as_int =
+ frame_mv[NEARESTMV][frame].as_int;
+ frame_mv[NEW_NEARESTMV][frame].as_int =
+ frame_mv[NEARESTMV][frame].as_int;
+ frame_mv[NEW_NEARMV][frame].as_int =
+ frame_mv[NEARMV][frame].as_int;
+ }
+ }
#endif // CONFIG_EXT_INTER
}
// search for the best motion vector on this segment
#if CONFIG_EXT_INTER
- for (this_mode = NEARESTMV;
- this_mode <= (has_second_rf ? NEWMV : NEWFROMNEARMV); ++this_mode) {
+ for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
+ this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
+ ++this_mode) {
#else
for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
#endif // CONFIG_EXT_INTER
@@ -3843,6 +4040,7 @@
mode_idx = INTER_OFFSET(this_mode);
#if CONFIG_EXT_INTER
mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
+
for (ref = 0; ref < 1 + has_second_rf; ++ref)
bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
#endif // CONFIG_EXT_INTER
@@ -3850,7 +4048,11 @@
if (!(inter_mode_mask & (1 << this_mode)))
continue;
- if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
+ if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+ mbmi_ext->compound_mode_context,
+#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
+ frame_mv,
this_mode, mbmi->ref_frame, bsize, i))
continue;
@@ -3977,7 +4179,12 @@
continue;
}
- if (has_second_rf && this_mode == NEWMV &&
+ if (has_second_rf &&
+#if CONFIG_EXT_INTER
+ this_mode == NEW_NEWMV &&
+#else
+ this_mode == NEWMV &&
+#endif // CONFIG_EXT_INTER
mbmi->interp_filter == EIGHTTAP) {
// adjust src pointers
mi_buf_shift(x, i);
@@ -4133,7 +4340,11 @@
if (best_rd == INT64_MAX) {
int iy, midx;
for (iy = i + 1; iy < 4; ++iy)
+#if CONFIG_EXT_INTER
+ for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
+#else
for (midx = 0; midx < INTER_MODES; ++midx)
+#endif // CONFIG_EXT_INTER
bsi->rdstat[iy][midx].brdcost = INT64_MAX;
bsi->segment_rd = INT64_MAX;
return INT64_MAX;
@@ -4168,7 +4379,11 @@
if (this_segment_rd > bsi->segment_rd) {
int iy, midx;
for (iy = i + 1; iy < 4; ++iy)
+#if CONFIG_EXT_INTER
+ for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
+#else
for (midx = 0; midx < INTER_MODES; ++midx)
+#endif // CONFIG_EXT_INTER
bsi->rdstat[iy][midx].brdcost = INT64_MAX;
bsi->segment_rd = INT64_MAX;
return INT64_MAX;
@@ -4400,6 +4615,9 @@
#if CONFIG_REF_MV
&mbmi_ext->ref_mv_count[ref_frame],
mbmi_ext->ref_mv_stack[ref_frame],
+#if CONFIG_EXT_INTER
+ mbmi_ext->compound_mode_context,
+#endif // CONFIG_EXT_INTER
#endif
candidates, mi_row, mi_col,
NULL, NULL, mbmi_ext->mode_context);
@@ -4630,6 +4848,9 @@
#if CONFIG_EXT_INTER
int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
int_mv single_newmv[MAX_REF_FRAMES];
+#if CONFIG_REF_MV
+ uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
+#endif
#endif // CONFIG_EXT_INTER
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * 64 * 64]);
@@ -4659,6 +4880,11 @@
int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
#if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+ if (is_comp_pred)
+ mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
+ else
+#endif // CONFIG_EXT_INTER
mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
#endif
@@ -4679,7 +4905,8 @@
lf = xd->mi[-1]->mbmi.interp_filter;
#if CONFIG_EXT_INTER
- if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV) || (af == lf))
+ if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
+ this_mode != NEW_NEWMV) || (af == lf))
#else
if ((this_mode != NEWMV) || (af == lf))
#endif // CONFIG_EXT_INTER
@@ -4692,9 +4919,64 @@
return INT64_MAX;
if (cpi->sf.adaptive_mode_search) {
+#if CONFIG_EXT_INTER
+ switch (this_mode) {
+ case NEAREST_NEARESTMV:
+ if (single_filter[NEARESTMV][refs[0]] ==
+ single_filter[NEARESTMV][refs[1]])
+ best_filter = single_filter[NEARESTMV][refs[0]];
+ break;
+ case NEAREST_NEARMV:
+ if (single_filter[NEARESTMV][refs[0]] ==
+ single_filter[NEARMV][refs[1]])
+ best_filter = single_filter[NEARESTMV][refs[0]];
+ break;
+ case NEAR_NEARESTMV:
+ if (single_filter[NEARMV][refs[0]] ==
+ single_filter[NEARESTMV][refs[1]])
+ best_filter = single_filter[NEARMV][refs[0]];
+ break;
+ case ZERO_ZEROMV:
+ if (single_filter[ZEROMV][refs[0]] ==
+ single_filter[ZEROMV][refs[1]])
+ best_filter = single_filter[ZEROMV][refs[0]];
+ break;
+ case NEW_NEWMV:
+ if (single_filter[NEWMV][refs[0]] ==
+ single_filter[NEWMV][refs[1]])
+ best_filter = single_filter[NEWMV][refs[0]];
+ break;
+ case NEAREST_NEWMV:
+ if (single_filter[NEARESTMV][refs[0]] ==
+ single_filter[NEWMV][refs[1]])
+ best_filter = single_filter[NEARESTMV][refs[0]];
+ break;
+ case NEAR_NEWMV:
+ if (single_filter[NEARMV][refs[0]] ==
+ single_filter[NEWMV][refs[1]])
+ best_filter = single_filter[NEARMV][refs[0]];
+ break;
+ case NEW_NEARESTMV:
+ if (single_filter[NEWMV][refs[0]] ==
+ single_filter[NEARESTMV][refs[1]])
+ best_filter = single_filter[NEWMV][refs[0]];
+ break;
+ case NEW_NEARMV:
+ if (single_filter[NEWMV][refs[0]] ==
+ single_filter[NEARMV][refs[1]])
+ best_filter = single_filter[NEWMV][refs[0]];
+ break;
+ default:
+ if (single_filter[this_mode][refs[0]] ==
+ single_filter[this_mode][refs[1]])
+ best_filter = single_filter[this_mode][refs[0]];
+ break;
+ }
+#else
if (single_filter[this_mode][refs[0]] ==
single_filter[this_mode][refs[1]])
best_filter = single_filter[this_mode][refs[0]];
+#endif // CONFIG_EXT_INTER
}
}
@@ -4708,9 +4990,38 @@
#if CONFIG_EXT_INTER
for (i = 0; i < 2; ++i) {
single_newmv[refs[i]].as_int =
- single_newmvs[mv_idx][refs[i]].as_int;
+ single_newmvs[mv_idx][refs[i]].as_int;
}
-#endif // CONFIG_EXT_INTER
+
+ if (this_mode == NEW_NEWMV) {
+ frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
+ frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
+
+ if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
+ joint_motion_search(cpi, x, bsize, frame_mv,
+ mi_row, mi_col, NULL, single_newmv, &rate_mv);
+ } else {
+ rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
+ &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
+ x->nmvjointcost, x->mvcost,
+ MV_COST_WEIGHT);
+ rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
+ &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
+ x->nmvjointcost, x->mvcost,
+ MV_COST_WEIGHT);
+ }
+ } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
+ frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
+ rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
+ &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
+ x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+ } else {
+ frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
+ rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
+ &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
+ x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+ }
+#else
// Initialize mv using single prediction mode result.
frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
@@ -4718,9 +5029,6 @@
if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
joint_motion_search(cpi, x, bsize, frame_mv,
mi_row, mi_col,
-#if CONFIG_EXT_INTER
- NULL,
-#endif // CONFIG_EXT_INTER
single_newmv, &rate_mv);
} else {
rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
@@ -4730,6 +5038,7 @@
&x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
}
+#endif // CONFIG_EXT_INTER
*rate2 += rate_mv;
} else {
int_mv tmp_mv;
@@ -4777,8 +5086,12 @@
}
#if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+ if (this_mode == NEAREST_NEARESTMV) {
+#else
if (this_mode == NEARESTMV && is_comp_pred) {
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
+#endif // CONFIG_EXT_INTER
if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
@@ -4793,6 +5106,51 @@
}
}
+#if CONFIG_EXT_INTER
+ if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
+ if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
+ cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
+
+ lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
+ clamp_mv2(&cur_mv[0].as_mv, xd);
+ if (mv_check_bounds(x, &cur_mv[0].as_mv))
+ return INT64_MAX;
+ mbmi->mv[0].as_int = cur_mv[0].as_int;
+ }
+
+ if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
+ cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
+
+ lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
+ clamp_mv2(&cur_mv[1].as_mv, xd);
+ if (mv_check_bounds(x, &cur_mv[1].as_mv))
+ return INT64_MAX;
+ mbmi->mv[1].as_int = cur_mv[1].as_int;
+ }
+ }
+
+ if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
+ if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
+ cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
+
+ lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
+ clamp_mv2(&cur_mv[0].as_mv, xd);
+ if (mv_check_bounds(x, &cur_mv[0].as_mv))
+ return INT64_MAX;
+ mbmi->mv[0].as_int = cur_mv[0].as_int;
+ }
+
+ if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
+ cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
+
+ lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
+ clamp_mv2(&cur_mv[1].as_mv, xd);
+ if (mv_check_bounds(x, &cur_mv[1].as_mv))
+ return INT64_MAX;
+ mbmi->mv[1].as_int = cur_mv[1].as_int;
+ }
+ }
+#else
if (this_mode == NEARMV && is_comp_pred) {
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
@@ -4808,6 +5166,7 @@
}
}
}
+#endif // CONFIG_EXT_INTER
#endif
// do first prediction into the destination buffer. Do the next
@@ -4845,7 +5204,11 @@
}
if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
+#if CONFIG_EXT_INTER
+ mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV)
+#else
mbmi->mode != NEARESTMV)
+#endif // CONFIG_EXT_INTER
return INT64_MAX;
pred_exists = 0;
@@ -4994,9 +5357,64 @@
if (cpi->sf.adaptive_mode_search)
if (is_comp_pred)
+#if CONFIG_EXT_INTER
+ switch (this_mode) {
+ case NEAREST_NEARESTMV:
+ if (single_skippable[NEARESTMV][refs[0]] &&
+ single_skippable[NEARESTMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case ZERO_ZEROMV:
+ if (single_skippable[ZEROMV][refs[0]] &&
+ single_skippable[ZEROMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEW_NEWMV:
+ if (single_skippable[NEWMV][refs[0]] &&
+ single_skippable[NEWMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEAREST_NEWMV:
+ if (single_skippable[NEARESTMV][refs[0]] &&
+ single_skippable[NEWMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEAR_NEWMV:
+ if (single_skippable[NEARMV][refs[0]] &&
+ single_skippable[NEWMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEW_NEARESTMV:
+ if (single_skippable[NEWMV][refs[0]] &&
+ single_skippable[NEARESTMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEW_NEARMV:
+ if (single_skippable[NEWMV][refs[0]] &&
+ single_skippable[NEARMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEAREST_NEARMV:
+ if (single_skippable[NEARESTMV][refs[0]] &&
+ single_skippable[NEARMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ case NEAR_NEARESTMV:
+ if (single_skippable[NEARMV][refs[0]] &&
+ single_skippable[NEARESTMV][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ default:
+ if (single_skippable[this_mode][refs[0]] &&
+ single_skippable[this_mode][refs[1]])
+ memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+ break;
+ }
+#else
if (single_skippable[this_mode][refs[0]] &&
single_skippable[this_mode][refs[1]])
memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+#endif // CONFIG_EXT_INTER
if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
// if current pred_error modeled rd is substantially more than the best
@@ -5387,6 +5805,9 @@
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
x->mbmi_ext->mode_context[ref_frame] = 0;
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+ x->mbmi_ext->compound_mode_context[ref_frame] = 0;
+#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
@@ -5396,6 +5817,8 @@
frame_mv[ZEROMV][ref_frame].as_int = 0;
#if CONFIG_EXT_INTER
frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
+ frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
+ frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
#endif // CONFIG_EXT_INTER
}
@@ -5408,6 +5831,9 @@
#if CONFIG_REF_MV
&mbmi_ext->ref_mv_count[ref_frame],
mbmi_ext->ref_mv_stack[ref_frame],
+#if CONFIG_EXT_INTER
+ mbmi_ext->compound_mode_context,
+#endif // CONFIG_EXT_INTER
#endif
candidates, mi_row, mi_col,
NULL, NULL, mbmi_ext->mode_context);
@@ -5462,6 +5888,14 @@
mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
+#if CONFIG_EXT_INTER
+ if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
+ mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
+ if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
+ mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
+ if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
+ mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
+#endif // CONFIG_EXT_INTER
}
}
@@ -5531,6 +5965,50 @@
ref_frame = vp10_mode_order[mode_index].ref_frame[0];
second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
+#if CONFIG_EXT_INTER
+ if (this_mode == NEAREST_NEARESTMV) {
+ frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
+ frame_mv[NEARESTMV][ref_frame].as_int;
+ frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
+ frame_mv[NEARESTMV][second_ref_frame].as_int;
+ } else if (this_mode == NEAREST_NEARMV) {
+ frame_mv[NEAREST_NEARMV][ref_frame].as_int =
+ frame_mv[NEARESTMV][ref_frame].as_int;
+ frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
+ frame_mv[NEARMV][second_ref_frame].as_int;
+ } else if (this_mode == NEAR_NEARESTMV) {
+ frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
+ frame_mv[NEARMV][ref_frame].as_int;
+ frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
+ frame_mv[NEARESTMV][second_ref_frame].as_int;
+ } else if (this_mode == NEAREST_NEWMV) {
+ frame_mv[NEAREST_NEWMV][ref_frame].as_int =
+ frame_mv[NEARESTMV][ref_frame].as_int;
+ frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
+ frame_mv[NEWMV][second_ref_frame].as_int;
+ } else if (this_mode == NEW_NEARESTMV) {
+ frame_mv[NEW_NEARESTMV][ref_frame].as_int =
+ frame_mv[NEWMV][ref_frame].as_int;
+ frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
+ frame_mv[NEARESTMV][second_ref_frame].as_int;
+ } else if (this_mode == NEAR_NEWMV) {
+ frame_mv[NEAR_NEWMV][ref_frame].as_int =
+ frame_mv[NEARMV][ref_frame].as_int;
+ frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
+ frame_mv[NEWMV][second_ref_frame].as_int;
+ } else if (this_mode == NEW_NEARMV) {
+ frame_mv[NEW_NEARMV][ref_frame].as_int =
+ frame_mv[NEWMV][ref_frame].as_int;
+ frame_mv[NEW_NEARMV][second_ref_frame].as_int =
+ frame_mv[NEARMV][second_ref_frame].as_int;
+ } else if (this_mode == NEW_NEWMV) {
+ frame_mv[NEW_NEWMV][ref_frame].as_int =
+ frame_mv[NEWMV][ref_frame].as_int;
+ frame_mv[NEW_NEWMV][second_ref_frame].as_int =
+ frame_mv[NEWMV][second_ref_frame].as_int;
+ }
+#endif // CONFIG_EXT_INTER
+
// Look at the reference frame of the best mode so far and set the
// skip mask to look at a subset of the remaining modes.
if (midx == mode_skip_start && best_mode_index >= 0) {
@@ -5635,7 +6113,11 @@
}
} else {
const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
- if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
+ if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+ mbmi_ext->compound_mode_context,
+#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
+ frame_mv,
this_mode, ref_frames, bsize, -1))
continue;
}
@@ -6008,6 +6490,7 @@
if (best_mbmode.mode == NEWMV
#if CONFIG_EXT_INTER
|| best_mbmode.mode == NEWFROMNEARMV
+ || best_mbmode.mode == NEW_NEWMV
#endif // CONFIG_EXT_INTER
) {
const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
@@ -6048,14 +6531,29 @@
if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
nearestmv[1].as_int == best_mbmode.mv[1].as_int)
+#if CONFIG_EXT_INTER
+ best_mbmode.mode = NEAREST_NEARESTMV;
+ else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
+ nearmv[1].as_int == best_mbmode.mv[1].as_int)
+ best_mbmode.mode = NEAREST_NEARMV;
+ else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
+ nearestmv[1].as_int == best_mbmode.mv[1].as_int)
+ best_mbmode.mode = NEAR_NEARESTMV;
+ else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
+ best_mbmode.mode = ZERO_ZEROMV;
+#else
best_mbmode.mode = NEARESTMV;
else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
nearmv[1].as_int == best_mbmode.mv[1].as_int)
best_mbmode.mode = NEARMV;
else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
best_mbmode.mode = ZEROMV;
+#endif // CONFIG_EXT_INTER
}
#else
+#if CONFIG_EXT_INTER
+ if (!comp_pred_mode) {
+#endif // CONFIG_EXT_INTER
if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
best_mbmode.mv[1].as_int) || !comp_pred_mode))
@@ -6067,16 +6565,46 @@
else if (best_mbmode.mv[0].as_int == 0 &&
((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
best_mbmode.mode = ZEROMV;
+#if CONFIG_EXT_INTER
+ } else {
+ const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
+ best_mbmode.ref_frame[1]};
+
+ if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
+ best_mbmode.mv[0].as_int &&
+ frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
+ best_mbmode.mv[1].as_int)
+ best_mbmode.mode = NEAREST_NEARESTMV;
+ else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
+ best_mbmode.mv[0].as_int &&
+ frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
+ best_mbmode.mv[1].as_int)
+ best_mbmode.mode = NEAREST_NEARMV;
+ else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
+ best_mbmode.mv[0].as_int &&
+ frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
+ best_mbmode.mv[1].as_int)
+ best_mbmode.mode = NEAR_NEARESTMV;
+ else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
+ best_mbmode.mode = ZERO_ZEROMV;
+ }
+#endif // CONFIG_EXT_INTER
#endif
}
#if CONFIG_REF_MV
if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
best_mbmode.mv[0].as_int == 0 &&
+#if CONFIG_EXT_INTER
+ best_mbmode.ref_frame[1] == NONE) {
+#else
(best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)) {
+#endif // CONFIG_EXT_INTER
int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
+#if !CONFIG_EXT_INTER
if (best_mbmode.ref_frame[1] > NONE)
mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
+#endif // !CONFIG_EXT_INTER
if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
best_mbmode.mode = ZEROMV;
@@ -6381,6 +6909,9 @@
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
x->mbmi_ext->mode_context[ref_frame] = 0;
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+ x->mbmi_ext->compound_mode_context[ref_frame] = 0;
+#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV],
diff --git a/vp10/encoder/speed_features.h b/vp10/encoder/speed_features.h
index a48a76c..170e537 100644
--- a/vp10/encoder/speed_features.h
+++ b/vp10/encoder/speed_features.h
@@ -35,16 +35,40 @@
enum {
INTER_ALL =
(1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) |
- (1 << NEWMV) | (1 << NEWFROMNEARMV),
- INTER_NEAREST = (1 << NEARESTMV),
- INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV),
- INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV),
+ (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+ (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) | (1 << NEAREST_NEARMV) |
+ (1 << NEAR_NEARESTMV) | (1 << NEW_NEWMV) | (1 << NEAREST_NEWMV) |
+ (1 << NEAR_NEWMV) | (1 << NEW_NEARMV) | (1 << NEW_NEARESTMV),
+ INTER_NEAREST = (1 << NEARESTMV) | (1 << NEAREST_NEARESTMV) |
+ (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+ (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV),
+ INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+ (1 << NEAREST_NEARESTMV) | (1 << NEW_NEWMV) |
+ (1 << NEAR_NEARESTMV) | (1 << NEAREST_NEARMV) |
+ (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
+ (1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
+ INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV) |
+ (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
+ (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+ (1 << NEAREST_NEWMV) | (1 << NEW_NEARESTMV),
INTER_NEAREST_NEW_ZERO =
- (1 << NEARESTMV) | (1 << ZEROMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV),
+ (1 << NEARESTMV) | (1 << ZEROMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+ (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) | (1 << NEW_NEWMV) |
+ (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+ (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
+ (1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
INTER_NEAREST_NEAR_NEW =
- (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV),
+ (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+ (1 << NEAREST_NEARESTMV) | (1 << NEW_NEWMV) |
+ (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+ (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
+ (1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
INTER_NEAREST_NEAR_ZERO =
- (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV)
+ (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) |
+ (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
+ (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+ (1 << NEAREST_NEWMV) | (1 << NEW_NEARESTMV) |
+ (1 << NEW_NEARMV) | (1 << NEAR_NEWMV)
};
#else
enum {