lc-dec: Bias against RD cost of split partition
This patch introduces a speed feature to increase the RD cost of
PARTITION_SPLIT type so that encoder decisions are biased towards
larger partition size.
Decode Time BD-Rate Loss(%)
cpu Reduction(%) avg.psnr ssim vmaf vmaf_neg
1 2.033 0.1219 0.0546 -0.0185 0.0210
2 1.453 -0.0148 -0.0399 -0.0569 -0.0373
3 1.768 0.1098 0.0864 0.0498 0.0475
STATS_CHANGED for low complexity decode.
Change-Id: I8bddab0f5527ff85ef463a40dd15ad23489432fc
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index 956c669..9d70eab 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -4403,6 +4403,22 @@
av1_restore_context(x, x_ctx, mi_row, mi_col, bsize, av1_num_planes(cm));
}
+static inline double get_split_partition_penalty(
+ BLOCK_SIZE bsize, int split_partition_penalty_level) {
+ if (!split_partition_penalty_level) return 1.00;
+
+ // Higher penalty for smaller block sizes.
+ static const double penalty_factors[2][SQR_BLOCK_SIZES - 1] = {
+ { 1.080, 1.040, 1.020, 1.010, 1.000 },
+ { 1.100, 1.075, 1.050, 1.025, 1.000 },
+ };
+ const int sqr_bsize_idx = get_sqr_bsize_idx(bsize);
+ assert(sqr_bsize_idx > 0 && sqr_bsize_idx < SQR_BLOCK_SIZES);
+ const double this_penalty_factor =
+ penalty_factors[split_partition_penalty_level - 1][sqr_bsize_idx - 1];
+ return this_penalty_factor;
+}
+
// PARTITION_SPLIT search.
static void split_partition_search(
AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
@@ -4514,7 +4530,10 @@
*part_split_rd = sum_rdc.rdcost;
if (reached_last_index && sum_rdc.rdcost < best_rdc->rdcost) {
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
- if (sum_rdc.rdcost < best_rdc->rdcost) {
+ const double penalty_factor = get_split_partition_penalty(
+ bsize, cpi->sf.part_sf.split_partition_penalty_level);
+ const int64_t this_rdcost = (int64_t)(sum_rdc.rdcost * penalty_factor);
+ if (this_rdcost < best_rdc->rdcost) {
*best_rdc = sum_rdc;
part_search_state->found_best_partition = true;
pc_tree->partitioning = PARTITION_SPLIT;
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index d9b9931..6c06685 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -642,6 +642,13 @@
: 0;
sf->inter_sf.bias_warp_mode_rd_scale_pct = 4;
+
+ const int is_key_frame = frame_is_intra_only(&cpi->common);
+ sf->part_sf.split_partition_penalty_level = is_key_frame ? 0 : 2;
+
+ if (speed >= 2) {
+ sf->part_sf.split_partition_penalty_level = is_key_frame ? 0 : 1;
+ }
}
static void set_good_speed_feature_framesize_dependent(
@@ -2126,6 +2133,7 @@
part_sf->use_best_rd_for_pruning = 0;
part_sf->skip_non_sq_part_based_on_none = 0;
part_sf->disable_8x8_part_based_on_qidx = 0;
+ part_sf->split_partition_penalty_level = 0;
}
static inline void init_mv_sf(MV_SPEED_FEATURES *mv_sf) {
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 4c96c67..a7a46c8 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -834,6 +834,11 @@
// Disables 8x8 and below partitions for low quantizers.
int disable_8x8_part_based_on_qidx;
+
+ // Decoder side speed feature to add penalty for use of smaller partitions.
+ // Takes values 0 - 2, 0 indicating no penalty and higher level indicating
+ // increased penalty.
+ int split_partition_penalty_level;
} PARTITION_SPEED_FEATURES;
typedef struct MV_SPEED_FEATURES {