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 {