Modularize frame level probabilities in AV1_COMP
This CL groups probability arrays for various tools
from AV1_COMP into new struct FrameProbInfo, removes
redundant variables and adds relevant documentation.
BUG=aomedia:2610
Change-Id: Ie09bcf674e78c865b0709f77844dbc7be04c7d6d
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index d2f9d95..533b851 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -5617,6 +5617,7 @@
MACROBLOCKD *const xd = &x->e_mbd;
RD_COUNTS *const rdc = &cpi->td.rd_counts;
GlobalMotionInfo *const gm_info = &cpi->gm_info;
+ FrameProbInfo *const frame_probs = &cpi->frame_probs;
int i;
if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
@@ -5649,7 +5650,7 @@
if (features->allow_warped_motion &&
cpi->sf.inter_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] <
+ if (frame_probs->warped_probs[update_type] <
cpi->sf.inter_sf.prune_warped_prob_thresh)
features->allow_warped_motion = 0;
}
@@ -5943,10 +5944,11 @@
const int new_prob =
sum ? 1024 * cpi->td.rd_counts.tx_type_used[i][j] / sum
: (j ? 0 : 1024);
- int prob = (cpi->tx_type_probs[update_type][i][j] + new_prob) >> 1;
+ int prob =
+ (frame_probs->tx_type_probs[update_type][i][j] + new_prob) >> 1;
left -= prob;
if (j == 0) prob += left;
- cpi->tx_type_probs[update_type][i][j] = prob;
+ frame_probs->tx_type_probs[update_type][i][j] = prob;
}
}
}
@@ -5961,8 +5963,8 @@
const int new_prob =
sum ? 128 * cpi->td.rd_counts.obmc_used[i][1] / sum : 0;
- cpi->obmc_probs[update_type][i] =
- (cpi->obmc_probs[update_type][i] + new_prob) >> 1;
+ frame_probs->obmc_probs[update_type][i] =
+ (frame_probs->obmc_probs[update_type][i] + new_prob) >> 1;
}
}
@@ -5972,8 +5974,8 @@
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;
+ frame_probs->warped_probs[update_type] =
+ (frame_probs->warped_probs[update_type] + new_prob) >> 1;
}
if (cm->current_frame.frame_type != KEY_FRAME &&
@@ -5994,11 +5996,12 @@
const int new_prob =
sum ? 1536 * cpi->td.counts->switchable_interp[i][j] / sum
: (j ? 0 : 1536);
- int prob =
- (cpi->switchable_interp_probs[update_type][i][j] + new_prob) >> 1;
+ int prob = (frame_probs->switchable_interp_probs[update_type][i][j] +
+ new_prob) >>
+ 1;
left -= prob;
if (j == 0) prob += left;
- cpi->switchable_interp_probs[update_type][i][j] = prob;
+ frame_probs->switchable_interp_probs[update_type][i][j] = prob;
}
}
}
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 471742e..178baf5 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -5436,39 +5436,27 @@
}
}
- if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats) {
- const int thr[2][2] = { { 15, 10 }, { 17, 10 } };
- for (int f = 0; f < FRAME_UPDATE_TYPES; f++) {
- int kf_arf_update = (f == KF_UPDATE || f == ARF_UPDATE);
- cpi->tx_type_probs_thresh[f] =
- thr[cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats - 1]
- [kf_arf_update];
+ if (cm->current_frame.frame_type == KEY_FRAME) {
+ FrameProbInfo *const frame_probs = &cpi->frame_probs;
+
+ if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats) {
+ av1_copy(frame_probs->tx_type_probs, default_tx_type_probs);
}
- if (cm->current_frame.frame_type == KEY_FRAME) {
- av1_copy(cpi->tx_type_probs, default_tx_type_probs);
+
+ if (!cpi->sf.inter_sf.disable_obmc &&
+ cpi->sf.inter_sf.prune_obmc_prob_thresh > 0) {
+ av1_copy(frame_probs->obmc_probs, default_obmc_probs);
+ }
+
+ if (cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
+ av1_copy(frame_probs->warped_probs, default_warped_probs);
+ }
+
+ if (cpi->sf.interp_sf.adaptive_interp_filter_search == 2) {
+ av1_copy(frame_probs->switchable_interp_probs,
+ default_switchable_interp_probs);
}
}
-
- if (!cpi->sf.inter_sf.disable_obmc &&
- cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
- cm->current_frame.frame_type == KEY_FRAME) {
- av1_copy(cpi->obmc_probs, default_obmc_probs);
- }
- if (cpi->sf.inter_sf.prune_warped_prob_thresh > 0 &&
- cm->current_frame.frame_type == KEY_FRAME) {
- av1_copy(cpi->warped_probs, default_warped_probs);
- }
-
- if (cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
- cm->current_frame.frame_type == KEY_FRAME) {
- av1_copy(cpi->switchable_interp_probs, default_switchable_interp_probs);
-
- const int thr[7] = { 0, 8, 8, 8, 8, 0, 8 };
- for (int f = 0; f < FRAME_UPDATE_TYPES; f++) {
- cpi->switchable_interp_thresh[f] = thr[f];
- }
- }
-
#if !CONFIG_REALTIME_ONLY
// Determine whether to use screen content tools using two fast encoding.
determine_sc_tools_with_encoding(cpi, q);
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index f1d51f7..80096a2 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -454,6 +454,31 @@
return cfg->best_allowed_q == 0 && cfg->worst_allowed_q == 0;
}
+typedef struct {
+ // obmc_probs[i][j] is the probability of OBMC being the best motion mode for
+ // jth block size and ith frame update type, averaged over past frames. If
+ // obmc_probs[i][j] < thresh, then OBMC search is pruned.
+ int obmc_probs[FRAME_UPDATE_TYPES][BLOCK_SIZES_ALL];
+
+ // warped_probs[i] is the probability of warped motion being the best motion
+ // mode for ith frame update type, averaged over past frames. If
+ // warped_probs[i] < thresh, then warped motion search is pruned.
+ int warped_probs[FRAME_UPDATE_TYPES];
+
+ // tx_type_probs[i][j][k] is the probability of kth tx_type being the best
+ // for jth transform size and ith frame update type, averaged over past
+ // frames. If tx_type_probs[i][j][k] < thresh, then transform search for that
+ // type is pruned.
+ int tx_type_probs[FRAME_UPDATE_TYPES][TX_SIZES_ALL][TX_TYPES];
+
+ // switchable_interp_probs[i][j][k] is the probability of kth interpolation
+ // filter being the best for jth filter context and ith frame update type,
+ // averaged over past frames. If switchable_interp_probs[i][j][k] < thresh,
+ // then interpolation filter search is pruned for that case.
+ int switchable_interp_probs[FRAME_UPDATE_TYPES][SWITCHABLE_FILTER_CONTEXTS]
+ [SWITCHABLE_FILTERS];
+} FrameProbInfo;
+
typedef struct FRAME_COUNTS {
// Note: This structure should only contain 'unsigned int' fields, or
// aggregates built solely from 'unsigned int' fields/elements
@@ -1180,13 +1205,8 @@
int64_t vbp_thresholds[5];
int64_t vbp_threshold_minmax;
- 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];
- int switchable_interp_probs[FRAME_UPDATE_TYPES][SWITCHABLE_FILTER_CONTEXTS]
- [SWITCHABLE_FILTERS];
- int switchable_interp_thresh[FRAME_UPDATE_TYPES];
+ // Probabilities for pruning of various AV1 tools.
+ FrameProbInfo frame_probs;
// Multi-threading
int num_workers;
diff --git a/av1/encoder/interp_search.c b/av1/encoder/interp_search.c
index 377eb66..6b7317b 100644
--- a/av1/encoder/interp_search.c
+++ b/av1/encoder/interp_search.c
@@ -450,11 +450,12 @@
const int ctx0 = av1_get_pred_context_switchable_interp(xd, 0);
const int ctx1 = av1_get_pred_context_switchable_interp(xd, 1);
const int *switchable_interp_p0 =
- cpi->switchable_interp_probs[update_type][ctx0];
+ cpi->frame_probs.switchable_interp_probs[update_type][ctx0];
const int *switchable_interp_p1 =
- cpi->switchable_interp_probs[update_type][ctx1];
+ cpi->frame_probs.switchable_interp_probs[update_type][ctx1];
- const int thresh = cpi->switchable_interp_thresh[update_type];
+ static const int thr[7] = { 0, 8, 8, 8, 8, 0, 8 };
+ const int thresh = thr[update_type];
for (i = 0; i < SWITCHABLE_FILTERS; i++) {
// For non-dual case, the 2 dir's prob should be identical.
assert(switchable_interp_p0[i] == switchable_interp_p1[i]);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index da9e068..2b86b8e 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -1300,7 +1300,7 @@
}
const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
- const int prune_obmc = cpi->obmc_probs[update_type][bsize] <
+ const int prune_obmc = cpi->frame_probs.obmc_probs[update_type][bsize] <
cpi->sf.inter_sf.prune_obmc_prob_thresh;
if ((cpi->oxcf.enable_obmc == 0 || cpi->sf.inter_sf.disable_obmc ||
cpi->sf.rt_sf.use_nonrd_pick_mode || prune_obmc) &&
@@ -3505,7 +3505,7 @@
av1_count_overlappable_neighbors(cm, xd);
const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
- const int prune_obmc = cpi->obmc_probs[update_type][bsize] <
+ const int prune_obmc = cpi->frame_probs.obmc_probs[update_type][bsize] <
cpi->sf.inter_sf.prune_obmc_prob_thresh;
if (cpi->oxcf.enable_obmc && !cpi->sf.inter_sf.disable_obmc && !prune_obmc) {
if (check_num_overlappable_neighbors(mbmi) &&
diff --git a/av1/encoder/tx_search.c b/av1/encoder/tx_search.c
index e6f97be..d3a9f1a 100644
--- a/av1/encoder/tx_search.c
+++ b/av1/encoder/tx_search.c
@@ -1968,11 +1968,16 @@
allowed_tx_mask = ext_tx_used_flag;
int num_allowed = 0;
const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
- const int *tx_type_probs = cpi->tx_type_probs[update_type][tx_size];
+ const int *tx_type_probs =
+ cpi->frame_probs.tx_type_probs[update_type][tx_size];
int i;
if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats) {
- const int thresh = cpi->tx_type_probs_thresh[update_type];
+ static const int thresh_arr[2][7] = { { 10, 15, 15, 10, 15, 15, 15 },
+ { 10, 17, 17, 10, 17, 17, 17 } };
+ const int thresh =
+ thresh_arr[cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats - 1]
+ [update_type];
uint16_t prune = 0;
int max_prob = -1;
int max_idx = 0;