Prune warped motion search based on stats
Pruned warped motion search based on stats gathered from previous
frames. This was turned on for >=480p at speed 5.
avg_psnr: ovr_psnr: ssim: avg speedup over whole set:
midres: 0.091 0.102 0.088 0.9%
hdres: 0.033 0.034 0.028 0.8%
STATS_CHANGED
Change-Id: Id0ee6c5122acea35417044d934965d221a6d61c9
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index aa05d8d..b22adb3 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1632,8 +1632,9 @@
update_stats(&cpi->common, td, mi_row, mi_col);
}
- // Gather obmc count to update the probability.
- if (!cpi->sf.disable_obmc && cpi->sf.prune_obmc_prob_thresh > 0) {
+ // Gather obmc and warped motion count to update the probability.
+ if ((!cpi->sf.disable_obmc && cpi->sf.prune_obmc_prob_thresh > 0) ||
+ (cm->allow_warped_motion && cpi->sf.prune_warped_prob_thresh > 0)) {
const int inter_block = is_inter_block(mbmi);
const int seg_ref_active =
segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
@@ -1643,9 +1644,14 @@
? motion_mode_allowed(xd->global_motion, xd, mbmi,
cm->allow_warped_motion)
: SIMPLE_TRANSLATION;
- if (mbmi->ref_frame[1] != INTRA_FRAME &&
- motion_allowed >= OBMC_CAUSAL) {
- td->rd_counts.obmc_used[bsize][mbmi->motion_mode == OBMC_CAUSAL]++;
+
+ if (mbmi->ref_frame[1] != INTRA_FRAME) {
+ if (motion_allowed >= OBMC_CAUSAL) {
+ td->rd_counts.obmc_used[bsize][mbmi->motion_mode == OBMC_CAUSAL]++;
+ }
+ if (motion_allowed == WARPED_CAUSAL) {
+ td->rd_counts.warped_used[mbmi->motion_mode == WARPED_CAUSAL]++;
+ }
}
}
}
@@ -5082,6 +5088,7 @@
av1_zero(rdc->comp_pred_diff);
av1_zero(rdc->tx_type_used);
av1_zero(rdc->obmc_used);
+ av1_zero(rdc->warped_used);
// Reset the flag.
cpi->intrabc_used = 0;
@@ -5092,6 +5099,12 @@
cm->allow_intrabc &= (cpi->oxcf.enable_intrabc);
+ if (cm->allow_warped_motion && cpi->sf.prune_warped_prob_thresh > 0) {
+ const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
+ if (cpi->warped_probs[update_type] < cpi->sf.prune_warped_prob_thresh)
+ cm->allow_warped_motion = 0;
+ }
+
if (!is_stat_generation_stage(cpi) && av1_use_hash_me(cpi) &&
!cpi->sf.use_nonrd_pick_mode) {
// add to hash table
@@ -5398,6 +5411,15 @@
(cpi->obmc_probs[update_type][i] + new_prob) >> 1;
}
}
+
+ if (cm->allow_warped_motion && cpi->sf.prune_warped_prob_thresh > 0) {
+ const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
+ int sum = 0;
+ for (i = 0; i < 2; i++) sum += cpi->td.rd_counts.warped_used[i];
+ const int new_prob = sum ? 128 * cpi->td.rd_counts.warped_used[1] / sum : 0;
+ cpi->warped_probs[update_type] =
+ (cpi->warped_probs[update_type] + new_prob) >> 1;
+ }
}
#define CHECK_PRECOMPUTED_REF_FRAME_MAP 0
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 4486dca..3174a1b 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -247,6 +247,9 @@
35, 32, 19, 16, 16, 0, 0, 49, 55, 29, 19 }
};
+const int default_warped_probs[FRAME_UPDATE_TYPES] = { 64, 64, 64, 64,
+ 64, 64, 64 };
+
static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
switch (mode) {
case NORMAL:
@@ -5045,6 +5048,10 @@
cm->current_frame.frame_type == KEY_FRAME) {
av1_copy(cpi->obmc_probs, default_obmc_probs);
}
+ if (cpi->sf.prune_warped_prob_thresh > 0 &&
+ cm->current_frame.frame_type == KEY_FRAME) {
+ av1_copy(cpi->warped_probs, default_warped_probs);
+ }
// Loop variables
int loop_count = 0;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index b07d918..898133e 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -610,6 +610,7 @@
int skip_mode_used_flag;
int tx_type_used[TX_SIZES_ALL][TX_TYPES];
int obmc_used[BLOCK_SIZES_ALL][2];
+ int warped_used[2];
} RD_COUNTS;
typedef struct ThreadData {
@@ -986,6 +987,7 @@
BLOCK_SIZE vbp_bsize_min;
int obmc_probs[FRAME_UPDATE_TYPES][BLOCK_SIZES_ALL];
+ int warped_probs[FRAME_UPDATE_TYPES];
int tx_type_probs[FRAME_UPDATE_TYPES][TX_SIZES_ALL][TX_TYPES];
int tx_type_probs_thresh[FRAME_UPDATE_TYPES];
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index aeb0dec..f1a541c 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -38,6 +38,10 @@
td->rd_counts.obmc_used[i][j] += td_t->rd_counts.obmc_used[i][j];
}
}
+
+ for (int i = 0; i < 2; i++) {
+ td->rd_counts.warped_used[i] += td_t->rd_counts.warped_used[i];
+ }
}
static AOM_INLINE void update_delta_lf_for_row_mt(AV1_COMP *cpi) {
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 90521fd..b5858ec 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -230,6 +230,14 @@
sf->prune_obmc_prob_thresh = 16;
}
+
+ if (speed >= 5) {
+ if (is_720p_or_larger) {
+ sf->prune_warped_prob_thresh = 16;
+ } else if (is_480p_or_larger) {
+ sf->prune_warped_prob_thresh = 8;
+ }
+ }
}
static void set_rt_speed_feature_framesize_dependent(const AV1_COMP *const cpi,
@@ -944,6 +952,7 @@
sf->nonrd_merge_partition = 0;
sf->disable_interinter_wedge = 0;
sf->prune_ref_mv_idx_search = 0;
+ sf->prune_warped_prob_thresh = 0;
if (oxcf->mode == GOOD)
set_good_speed_features_framesize_independent(cpi, sf, speed);
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 622090e..5043382 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -566,6 +566,9 @@
// TRANSLATION and AFFINE(based on number of warp neighbors)
int prune_warp_using_wmtype;
+ // Prune warped motion search using previous frame stats.
+ int prune_warped_prob_thresh;
+
// Enable/disable interintra wedge search.
int disable_wedge_interintra_search;