[Normative] Add a header flag to control advanced motion_modes
A 1-bit frame level flag (switchable_motion_mode) is added to the
header. If it is 1, per-block motion_mode signalling is enabled,
motion_mode can be any of SIMPLE_TRANSLATION/OBMC_CAUSAL/
WARPED_CAUSAL. Otherwise, motion_mode is always SIMPLE_TRANSLATION
without sending motion_mode syntax in the bitstream.
BUG=aomedia:1185
Change-Id: Iff35cb8425d5a72eaba310e3e63910b8970a27c9
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 77e1c8b..271d66d 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -440,6 +440,8 @@
InterpFilter interp_filter;
+ int switchable_motion_mode;
+
loop_filter_info_n lf_info;
#if CONFIG_HORZONLY_FRAME_SUPERRES
// The denominator of the superres scale; the numerator is fixed.
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 139f1f2..5bbb65a 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3016,6 +3016,7 @@
cm->allow_high_precision_mv = aom_rb_read_bit(rb);
#endif
cm->interp_filter = read_frame_interp_filter(rb);
+ cm->switchable_motion_mode = aom_rb_read_bit(rb);
if (frame_might_use_prev_frame_mvs(cm))
cm->use_ref_frame_mvs = aom_rb_read_bit(rb);
else
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index a37f274..7c561b0 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -247,10 +247,11 @@
}
}
-static MOTION_MODE read_motion_mode(MACROBLOCKD *xd, MODE_INFO *mi,
- aom_reader *r) {
+static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
+ MODE_INFO *mi, aom_reader *r) {
MB_MODE_INFO *mbmi = &mi->mbmi;
+ if (cm->switchable_motion_mode == 0) return SIMPLE_TRANSLATION;
#if CONFIG_EXT_SKIP
if (mbmi->skip_mode) return SIMPLE_TRANSLATION;
#endif // CONFIG_EXT_SKIP
@@ -1924,7 +1925,7 @@
av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
if (mbmi->ref_frame[1] != INTRA_FRAME)
- mbmi->motion_mode = read_motion_mode(xd, mi, r);
+ mbmi->motion_mode = read_motion_mode(cm, xd, mi, r);
#if CONFIG_JNT_COMP
// init
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 7b84174..9963f46 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -289,7 +289,10 @@
const MB_MODE_INFO *mbmi = &mi->mbmi;
MOTION_MODE last_motion_mode_allowed =
- motion_mode_allowed(cm->global_motion, xd, mi);
+ cm->switchable_motion_mode
+ ? motion_mode_allowed(cm->global_motion, xd, mi)
+ : SIMPLE_TRANSLATION;
+ assert(mbmi->motion_mode <= last_motion_mode_allowed);
switch (last_motion_mode_allowed) {
case SIMPLE_TRANSLATION: break;
case OBMC_CAUSAL:
@@ -3493,6 +3496,7 @@
#endif
fix_interp_filter(cm, cpi->td.counts);
write_frame_interp_filter(cm->interp_filter, wb);
+ aom_wb_write_bit(wb, cm->switchable_motion_mode);
if (frame_might_use_prev_frame_mvs(cm)) {
aom_wb_write_bit(wb, cm->use_ref_frame_mvs);
}
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 25a83ca..884dd85 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1225,7 +1225,9 @@
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
const MOTION_MODE motion_allowed =
- motion_mode_allowed(xd->global_motion, xd, mi);
+ cm->switchable_motion_mode
+ ? motion_mode_allowed(xd->global_motion, xd, mi)
+ : SIMPLE_TRANSLATION;
if (mbmi->ref_frame[1] != INTRA_FRAME) {
if (motion_allowed == WARPED_CAUSAL) {
counts->motion_mode[bsize][mbmi->motion_mode]++;
@@ -4612,6 +4614,8 @@
if (cm->large_scale_tile) cm->interp_filter = EIGHTTAP_REGULAR;
#endif // CONFIG_EXT_TILE
+ cm->switchable_motion_mode = 1;
+
make_consistent_compound_tools(cm);
rdc->compound_ref_used_flag = 0;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 1f9c2b9..c177d94 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3225,6 +3225,8 @@
cm->interp_filter = EIGHTTAP_REGULAR;
#endif // CONFIG_EXT_TILE
+ cm->switchable_motion_mode = 1;
+
if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) {
cm->render_width = cpi->oxcf.render_width;
cm->render_height = cpi->oxcf.render_height;
@@ -4761,6 +4763,7 @@
av1_set_rd_speed_thresholds(cpi);
av1_set_rd_speed_thresholds_sub8x8(cpi);
cpi->common.interp_filter = cpi->sf.default_interp_filter;
+ cpi->common.switchable_motion_mode = 1;
if (!frame_is_intra_only(&cpi->common)) set_compound_tools(&cpi->common);
}
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 1911742..00ae7d1 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -7553,7 +7553,9 @@
rate2_nocoeff = rd_stats->rate;
base_mbmi = *mbmi;
MOTION_MODE last_motion_mode_allowed =
- motion_mode_allowed(xd->global_motion, xd, mi);
+ cm->switchable_motion_mode
+ ? motion_mode_allowed(xd->global_motion, xd, mi)
+ : SIMPLE_TRANSLATION;
assert(mbmi->ref_frame[1] != INTRA_FRAME);
int64_t best_rd = INT64_MAX;
@@ -10743,10 +10745,7 @@
// Note: this section is needed since the mode may have been forced to
// GLOBALMV by the all-zero mode handling of ref-mv.
if (mbmi->mode == GLOBALMV || mbmi->mode == GLOBAL_GLOBALMV) {
- // Correct the motion mode for GLOBALMV
- const MOTION_MODE last_motion_mode_allowed =
- motion_mode_allowed(xd->global_motion, xd, xd->mi[0]);
- if (mbmi->motion_mode > last_motion_mode_allowed) assert(0);
+ // Correct the interp filters for GLOBALMV
if (is_nontrans_global_motion(xd)) {
assert(mbmi->interp_filters ==
av1_broadcast_interp_filter(