Prune rectangular split based on q index for smaller blocks

Rectangular, AB and 4-way partitions are pruned based on q index
for smaller blocks. Prune aggressiveness is high for lower
q-index and low for higher q-index. This speed feature is enabled
for speed 6.

          Instruction Count        BD-Rate Loss(%)
cpu-used    Reduction(%)     avg.psnr  ovr.psnr   ssim
   6          1.529           0.1584    0.1582    0.1098

STATS_CHANGED

Change-Id: I47ad8b886da177fd17233614d283d89230708eea
diff --git a/av1/encoder/partition_strategy.c b/av1/encoder/partition_strategy.c
index cb95ab4..46810ec 100644
--- a/av1/encoder/partition_strategy.c
+++ b/av1/encoder/partition_strategy.c
@@ -1303,6 +1303,27 @@
   const AV1_COMMON *const cm = &cpi->common;
   const CommonModeInfoParams *const mi_params = &cm->mi_params;
 
+  // Prune rectangular, AB and 4-way partition based on q index and block size
+  if (cpi->sf.part_sf.prune_rectangular_split_based_on_qidx) {
+    // Enumeration difference between two square partitions
+    const int sqr_bsize_step = BLOCK_32X32 - BLOCK_16X16;
+    int max_bsize =
+        BLOCK_32X32 - (x->qindex * 3 / QINDEX_RANGE) * sqr_bsize_step;
+    max_bsize = AOMMAX(max_bsize, BLOCK_4X4);
+    const BLOCK_SIZE max_prune_bsize =
+        (BLOCK_SIZE)AOMMIN(max_bsize, BLOCK_32X32);
+
+    // Prune partition
+    // qidx 0 to 85: prune bsize below BLOCK_32X32
+    // qidx 86 to 170: prune bsize below BLOCK_16X16
+    // qidx 171 to 255: prune bsize below BLOCK_8X8
+    if (bsize < max_prune_bsize) {
+      *do_rectangular_split = 0;
+      *partition_horz_allowed = 0;
+      *partition_vert_allowed = 0;
+    }
+  }
+
   // A CNN-based speed feature pruning out either split or all non-split
   // partition in INTRA frame coding.
   const int try_intra_cnn_split =
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 4ef32b4..428a3c7 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -657,6 +657,8 @@
 
   if (speed >= 6) {
     sf->inter_sf.prune_inter_modes_based_on_tpl = boosted ? 0 : 3;
+    sf->part_sf.prune_rectangular_split_based_on_qidx =
+        boosted || allow_screen_content_tools ? 0 : 1;
 
     sf->mv_sf.simple_motion_subpel_force_stop = FULL_PEL;
     sf->mv_sf.use_bsize_dependent_search_method = 1;
@@ -1049,6 +1051,7 @@
   part_sf->ext_partition_eval_thresh = BLOCK_8X8;
   part_sf->prune_4_partition_using_split_info = 0;
   part_sf->prune_ab_partition_using_split_info = 0;
+  part_sf->prune_rectangular_split_based_on_qidx = 0;
   part_sf->early_term_after_none_split = 0;
   part_sf->ml_predict_breakout_level = 0;
 }
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index ae252ab..48475ac 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -470,6 +470,9 @@
   // Prune AB partition search using split and HORZ/VERT info
   int prune_ab_partition_using_split_info;
 
+  // Prunt rectangular, AB and 4-way partition based on q index and block size
+  int prune_rectangular_split_based_on_qidx;
+
   // Terminate partition search for child partition,
   // when NONE and SPLIT partition rd_costs are INT64_MAX.
   int early_term_after_none_split;