Speed up one-sided compound mode (ext-comp-refs)
One-sided compound ref prediction is used only when all reference
frames are one-sided.
This patch has demonstrated an encoder speedup of ~28%.
Using the following configure setups, the coding performance has been
dropped on Google test sets (50 frames) in BDRate by ~0.2% for lowres
and by ~0.1% for midres (Corresponding performance impact should be
smaller on AWCY):
--enable-experimental --disable-convolve-round --disable-ext-partition
--disable-ext-partition-types --disable-txk-sel --disable-txm
Change-Id: I585bbffb2f8d154e8f52a1e79a84eff8bb4a471d
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 58f1165..4f0b6bf 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -3755,6 +3755,21 @@
return counts * blk_h * blk_w * 10 > width * height;
}
+#if CONFIG_FRAME_MARKER
+static int refs_are_one_sided(const AV1_COMMON *cm) {
+ int one_sided_refs = 1;
+ if (cm->cur_frame->lst_frame_offset > cm->frame_offset ||
+ cm->cur_frame->lst2_frame_offset > cm->frame_offset ||
+ cm->cur_frame->lst3_frame_offset > cm->frame_offset ||
+ cm->cur_frame->gld_frame_offset > cm->frame_offset ||
+ cm->cur_frame->bwd_frame_offset > cm->frame_offset ||
+ cm->cur_frame->alt2_frame_offset > cm->frame_offset ||
+ cm->cur_frame->alt_frame_offset > cm->frame_offset)
+ one_sided_refs = 0;
+ return one_sided_refs;
+}
+#endif // CONFIG_FRAME_MARKER
+
static void encode_frame_internal(AV1_COMP *cpi) {
ThreadData *const td = &cpi->td;
MACROBLOCK *const x = &td->mb;
@@ -4068,6 +4083,10 @@
av1_setup_motion_field(cm);
#endif // CONFIG_MFMV
+#if CONFIG_FRAME_MARKER
+ cpi->all_one_sided_refs = refs_are_one_sided(cm);
+#endif // CONFIG_FRAME_MARKER
+
{
struct aom_usec_timer emr_timer;
aom_usec_timer_start(&emr_timer);
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 075b07d..6868ce3 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -475,6 +475,9 @@
int mv_step_param;
int allow_comp_inter_inter;
+#if CONFIG_FRAME_MARKER
+ int all_one_sided_refs;
+#endif // CONFIG_FARME_MARKER
uint8_t *segmentation_map;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 17b3f6f..e3520ad 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -9985,7 +9985,22 @@
if (cm->cur_frame->lst2_frame_offset <= cm->cur_frame->gld_frame_offset)
continue;
}
-#endif
+
+ // One-sided compound is used only when all reference frames are one-sided.
+ if (sf->selective_ref_frame && comp_pred && !cpi->all_one_sided_refs) {
+ unsigned int ref_offsets[2];
+ for (i = 0; i < 2; ++i) {
+ const int buf_idx = cm->frame_refs[mbmi->ref_frame[i] - LAST_FRAME].idx;
+ assert(buf_idx >= 0);
+ ref_offsets[i] = cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset;
+ }
+ if ((ref_offsets[0] <= cm->frame_offset &&
+ ref_offsets[1] <= cm->frame_offset) ||
+ (ref_offsets[0] > cm->frame_offset &&
+ ref_offsets[1] > cm->frame_offset))
+ continue;
+ }
+#endif // CONFIG_FRAME_MARKER
if (ref_frame == INTRA_FRAME) {
RD_STATS rd_stats_y;