RTC: Disable compound modes based on variance
This commit introduces speed feature skip_compound_based_on_var that
skips all compound modes if the best single mode prediction has low
residual variance.
Furthermore, this commit also disables the sad_based_comp_prune speed
feature on speed 9, 10 as variance of best mode outperforms the SAD
of zeromv on last frame. Note that the speed feature is disabled by
inserting a 0 into the conditional. This is because there are other
speed features that relies on the stats collected by
sad_based_comp_prune. This will be corrected in a later commit.
Performance:
| SPD_SET | TESTSET | AVG_PSNR | OVR_PSNR | SSIM | ENC_T |
|---------|----------|----------|----------|---------|-------|
| 7 | rtc | +0.035% | +0.219% | +0.252% | -0.3% |
|---------|----------|----------|----------|---------|-------|
| 8 | rtc | +0.026% | +0.027% | +0.137% | -0.3% |
|---------|----------|----------|----------|---------|-------|
| 9 | rtc | -0.169% | -0.060% | +0.253% | -0.3% |
|---------|----------|----------|----------|---------|-------|
| 10 | rtc | -0.007% | -0.018% | +0.140% | -0.2% |
The larger PSNR loss on speed 7 is caused by thaloundeskmtgvga.y4m.
STATS_CHANGED
Change-Id: I7f663ddbf316fe75f5827ee0a8367ca50d691b0c
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 5c3f1c4..b11b30a 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -2636,6 +2636,27 @@
return 0;
}
+// Prune compound mode if the single mode variance is lower than a fixed
+// percentage of the median value.
+static bool skip_comp_based_on_var(
+ const unsigned int (*single_vars)[REF_FRAMES], BLOCK_SIZE bsize) {
+ unsigned int best_var = UINT_MAX;
+ for (int cur_mode_idx = 0; cur_mode_idx < RTC_INTER_MODES; cur_mode_idx++) {
+ for (int ref_idx = 0; ref_idx < REF_FRAMES; ref_idx++) {
+ best_var = AOMMIN(best_var, single_vars[cur_mode_idx][ref_idx]);
+ }
+ }
+ const unsigned int thresh_64 = (unsigned int)(0.57356805f * 8659);
+ const unsigned int thresh_32 = (unsigned int)(0.23964763f * 4281);
+
+ if (bsize == BLOCK_64X64) {
+ return best_var < thresh_64;
+ } else if (bsize == BLOCK_32X32) {
+ return best_var < thresh_32;
+ }
+ return false;
+}
+
static AOM_FORCE_INLINE void fill_single_inter_mode_costs(
int (*single_inter_mode_costs)[REF_FRAMES], const int num_inter_modes,
const REF_MODE *ref_mode_set, const ModeCosts *mode_costs,
@@ -2941,7 +2962,10 @@
}
// Skip compound mode based on sad
- if (tot_num_comp_modes && cpi->sf.rt_sf.sad_based_comp_prune &&
+ // Temporarily disable this with a 0 flag. Currently we cannot simply turn off
+ // cpi->sf.rt_sf.sad_based_comp_prune as it causes unexpected stats changed.
+ // TODO(chiyotsai@google.com): Figure remove the 0 from the conditional.
+ if (0 && tot_num_comp_modes && cpi->sf.rt_sf.sad_based_comp_prune &&
bsize >= BLOCK_64X64 && cpi->src_sad_blk_64x64 &&
skip_comp_based_on_sad(cpi, x, mi_row, mi_col, bsize)) {
tot_num_comp_modes = 0;
@@ -3003,6 +3027,13 @@
MV_REFERENCE_FRAME last_comp_ref_frame = NONE_FRAME;
for (int idx = 0; idx < num_inter_modes + tot_num_comp_modes; ++idx) {
+ // If we are at the first compound mode, and the single modes already
+ // perform well, then end the search.
+ if (cpi->sf.rt_sf.skip_compound_based_on_var && idx == num_inter_modes &&
+ skip_comp_based_on_var(vars, bsize)) {
+ break;
+ }
+
const struct segmentation *const seg = &cm->seg;
int rate_mv = 0;
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 5f3a949..b9411ab 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1672,6 +1672,7 @@
sf->rt_sf.var_part_based_on_qidx = 3;
sf->rt_sf.prune_compoundmode_with_singlecompound_var = true;
sf->rt_sf.prune_compoundmode_with_singlemode_var = true;
+ sf->rt_sf.skip_compound_based_on_var = true;
}
if (speed >= 8) {
@@ -2053,6 +2054,7 @@
rt_sf->check_only_zero_zeromv_on_large_blocks = false;
rt_sf->disable_cdf_update_non_reference_frame = false;
rt_sf->prune_compoundmode_with_singlemode_var = false;
+ rt_sf->skip_compound_based_on_var = false;
rt_sf->top_right_sync_wait_in_mis = false;
}
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 3d50d1c..fad0774 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1602,6 +1602,10 @@
// Prune compound modes if the single modes variances do not perform well.
bool prune_compoundmode_with_singlemode_var;
+ // Skip searching all compound mode if the variance of single_mode residue is
+ // sufficiently low.
+ bool skip_compound_based_on_var;
+
// In multi-threaded encoding, enable top right dependency wait of threads at
// mi level.
bool top_right_sync_wait_in_mis;