Support ext-skip for both low delay and high delay
For both low delay and high delay scenarios, the reference pair in
skip mode are specified as the closest fwd ref, together with the
closest bwd ref if there is any bwd ref, otherwise with the two
closest fwd refs.
Skip mode by default uses COMPOUND_AVERAGE. When all the reference
frames are on the same side, temporal-distance weighted compound is
considered, and a compound index is signaled to indicate whether
distance-weighted compound or compound-average is usd.
Whether to use distance-weighted compound for skip mode is still
under experimenting, hence a flag is temporarily added:
SKIP_MODE_WITH_JNT_COMP.
Following experimental results are obtained over 30 frames, using the
setup of --disable-ext-partition --disable-ext-partition-types
--disable-txmg --enable-jnt-comp --enable-mfmv --enable-ext-skip:
(1) High Latency:
For Google test sets (lowres/midres), the BDRate coding gain is ~0.2%;
For AWCY, the coding gain is ~0.1%.
(2) Low Latency:
No gain has been observed over Google sets and ~0.1% gain is obtained
only when temporal-distance weighted prediction is used.
Change-Id: I8c433357adebed0126ebfdd5c4d51aa71e64be57
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 361eaf5..50281d3 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -47,6 +47,11 @@
// chroma.
#define DISABLE_VARTX_FOR_CHROMA 1
+#if CONFIG_EXT_SKIP && CONFIG_JNT_COMP
+// NOTE: To explore whether weighted-compound prediction to be considered.
+#define SKIP_MODE_WITH_JNT_COMP 0
+#endif // CONFIG_EXT_SKIP && CONFIG_JNT_COMP
+
// SEG_MASK_TYPES should not surpass 1 << MAX_SEG_MASK_BITS
typedef enum {
#if COMPOUND_SEGMENT_TYPE == 0
@@ -706,6 +711,10 @@
#if CONFIG_JNT_COMP
JNT_COMP_PARAMS jcp_param;
#endif
+
+#if CONFIG_EXT_SKIP
+ int all_one_sided_refs;
+#endif // CONFIG_EXT_SKIP
} MACROBLOCKD;
static INLINE int get_bitdepth_data_path_index(const MACROBLOCKD *xd) {
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index dfd43762b..ab2d141 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -2054,9 +2054,9 @@
}
// Flag is set when and only when both forward and backward references
- // are available and their distance is no greater than 3, i.e. as
- // opposed to the current frame position, the reference distance pair are
- // either: (1, 1), (1, 2), or (2, 1).
+ // are available and the difference between their temporal distance to
+ // the current frame is no greater than 1, i.e. they may have the same
+ // temporal distance to the current frame, or the distances are off by 1.
if (ref_idx[0] != INVALID_IDX && ref_idx[1] != INVALID_IDX) {
const int cur_to_fwd = cm->frame_offset - ref_frame_offset[0];
const int cur_to_bwd = ref_frame_offset[1] - cm->frame_offset;
@@ -2070,6 +2070,38 @@
}
}
+ // NOTE: Low delay scenario
+ if (av1_refs_are_one_sided(cm)) {
+ assert(ref_idx[1] == INVALID_IDX);
+ assert(ref_idx[0] != INVALID_IDX);
+ // Identify the second closest forward reference frame.
+ ref_frame_offset[1] = -1;
+ cm->is_skip_mode_allowed = 0;
+ for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
+ const int buf_idx = cm->frame_refs[i].idx;
+ if (buf_idx == INVALID_IDX) continue;
+
+ const int ref_offset = frame_bufs[buf_idx].cur_frame_offset;
+ if (ref_offset < ref_frame_offset[0] &&
+ ref_offset > ref_frame_offset[1]) {
+ // Second closest forward reference
+ ref_frame_offset[1] = ref_offset;
+ ref_idx[1] = i;
+ ref_buf_idx[1] = buf_idx;
+ }
+ }
+ if (ref_frame_offset[1] >= 0) {
+ const int cur_to_fwd0 = cur_frame_offset - ref_frame_offset[0];
+ const int cur_to_fwd1 = cur_frame_offset - ref_frame_offset[1];
+ assert(cur_to_fwd1 > cur_to_fwd0);
+ if ((cur_to_fwd1 - cur_to_fwd0) <= 1) {
+ cm->is_skip_mode_allowed = 1;
+ cm->ref_frame_idx_0 = AOMMIN(ref_idx[0], ref_idx[1]);
+ cm->ref_frame_idx_1 = AOMMAX(ref_idx[0], ref_idx[1]);
+ }
+ }
+ }
+
// Set up the temporal mv candidates for skip mode.
cm->tpl_frame_ref0_idx = INVALID_IDX;
if (cm->is_skip_mode_allowed && cm->use_ref_frame_mvs) {
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index 67bfca6..e28eaea 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -402,6 +402,24 @@
}
#if CONFIG_FRAME_MARKER
+static INLINE int av1_refs_are_one_sided(const AV1_COMMON *cm) {
+ assert(!frame_is_intra_only(cm));
+
+ int one_sided_refs = 1;
+ for (int ref = 0; ref < INTER_REFS_PER_FRAME; ++ref) {
+ const int buf_idx = cm->frame_refs[ref].idx;
+ if (buf_idx == INVALID_IDX) continue;
+
+ const int ref_offset =
+ cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset;
+ if (ref_offset > (int)cm->frame_offset) {
+ one_sided_refs = 0; // bwd reference
+ break;
+ }
+ }
+ return one_sided_refs;
+}
+
void av1_setup_frame_buf_refs(AV1_COMMON *cm);
#if CONFIG_FRAME_SIGN_BIAS
void av1_setup_frame_sign_bias(AV1_COMMON *cm);