ERP: add syntax-level options for disabling ternary ERP parts
diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h
index 44ff95c..366c890 100644
--- a/aom/aom_encoder.h
+++ b/aom/aom_encoder.h
@@ -258,6 +258,18 @@
    *
    */
   unsigned int use_ml_erp_pruning;
+  /*!\brief disable 3-way partitions for 64xN and Nx64 (N <= 64) blocks
+   *
+   */
+  unsigned int disable_3way_part_64xn;
+  /*!\brief disable 3-way partitions for 32xN and Nx32 (N <= 32) blocks
+   *
+   */
+  unsigned int disable_3way_part_32xn;
+  /*!\brief disable 3-way partitions for 16xN and Nx16 (N <= 16) blocks
+   *
+   */
+  unsigned int disable_3way_part_16xn;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   /*!\brief disable ml-based speed-up for transform search
    *
diff --git a/apps/aomenc.c b/apps/aomenc.c
index 638ffd0..94c83f6 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -425,6 +425,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   &g_av1_codec_arg_defs.erp_pruning_level,
   &g_av1_codec_arg_defs.use_ml_erp_pruning,
+  &g_av1_codec_arg_defs.disable_3way_part_64xn,
+  &g_av1_codec_arg_defs.disable_3way_part_32xn,
+  &g_av1_codec_arg_defs.disable_3way_part_16xn,
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   &g_av1_codec_arg_defs.enable_sdp,
   &g_av1_codec_arg_defs.enable_mrls,
@@ -605,6 +608,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   config->erp_pruning_level = 5;
   config->use_ml_erp_pruning = 0;
+  config->disable_3way_part_64xn = 0;
+  config->disable_3way_part_32xn = 0;
+  config->disable_3way_part_16xn = 0;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   config->enable_sdp = 1;
   config->enable_mrls = 1;
diff --git a/av1/arg_defs.c b/av1/arg_defs.c
index 5b20964..75df663 100644
--- a/av1/arg_defs.c
+++ b/av1/arg_defs.c
@@ -345,6 +345,18 @@
   .use_ml_erp_pruning = ARG_DEF(NULL, "use-ml-erp-pruning", 1,
                                 "Use ML model to perform ERP Pruning."
                                 "(0: off (default), 1: on)."),
+  .disable_3way_part_64xn =
+      ARG_DEF(NULL, "disable-3way-part-64xn", 1,
+              "Disable ternary partitions in 64xN/Nx64 (N<=64) blocks."
+              "(0: off (default), 1: on)."),
+  .disable_3way_part_32xn =
+      ARG_DEF(NULL, "disable-3way-part-32xn", 1,
+              "Disable ternary partitions in 32xN/Nx32 (N<=32) blocks."
+              "(0: off (default), 1: on)."),
+  .disable_3way_part_16xn =
+      ARG_DEF(NULL, "disable-3way-part-16xn", 1,
+              "Disable ternary partitions in 16xN/Nx16 (N<=16) blocks."
+              "(0: off (default), 1: on)."),
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   .enable_rect_partitions = ARG_DEF(NULL, "enable-rect-partitions", 1,
                                     "Enable rectangular partitions "
diff --git a/av1/arg_defs.h b/av1/arg_defs.h
index 8c66828..6523ac9 100644
--- a/av1/arg_defs.h
+++ b/av1/arg_defs.h
@@ -138,6 +138,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   arg_def_t erp_pruning_level;
   arg_def_t use_ml_erp_pruning;
+  arg_def_t disable_3way_part_64xn;
+  arg_def_t disable_3way_part_32xn;
+  arg_def_t disable_3way_part_16xn;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   arg_def_t enable_rect_partitions;
   arg_def_t enable_ab_partitions;
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 57bac05..a0f55c1 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -112,6 +112,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   unsigned int erp_pruning_level;
   int use_ml_erp_pruning;
+  unsigned int disable_3way_part_64xn;
+  unsigned int disable_3way_part_32xn;
+  unsigned int disable_3way_part_16xn;
 #endif                         // CONFIG_EXT_RECUR_PARTITIONS
   int enable_rect_partitions;  // enable rectangular partitions for sequence
   int enable_ab_partitions;    // enable AB partitions for sequence
@@ -413,6 +416,9 @@
   1,  // disable ML based partition speed up features
   5,  // aggressiveness for erp pruning
   0,  // use ml model for erp pruning
+  0,  // disable ternary partitions in 64xN/Nx64(N<=64) blocks
+  0,  // disable ternary partitions in 32xN/Nx32(N<=32) blocks
+  0,  // disable ternary partitions in 16xN/Nx16(N<=16) blocks
 #else
   0,  // disable ML based partition speed up features
 #endif
@@ -887,6 +893,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   cfg->erp_pruning_level = extra_cfg->erp_pruning_level;
   cfg->use_ml_erp_pruning = extra_cfg->use_ml_erp_pruning;
+  cfg->disable_3way_part_64xn = extra_cfg->disable_3way_part_64xn;
+  cfg->disable_3way_part_32xn = extra_cfg->disable_3way_part_32xn;
+  cfg->disable_3way_part_16xn = extra_cfg->disable_3way_part_16xn;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   cfg->enable_rect_partitions = extra_cfg->enable_rect_partitions;
   cfg->enable_ab_partitions = extra_cfg->enable_ab_partitions;
@@ -983,6 +992,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   extra_cfg->erp_pruning_level = cfg->erp_pruning_level;
   extra_cfg->use_ml_erp_pruning = cfg->use_ml_erp_pruning;
+  extra_cfg->disable_3way_part_64xn = cfg->disable_3way_part_64xn;
+  extra_cfg->disable_3way_part_32xn = cfg->disable_3way_part_32xn;
+  extra_cfg->disable_3way_part_16xn = cfg->disable_3way_part_16xn;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   extra_cfg->enable_sdp = cfg->enable_sdp;
   extra_cfg->enable_mrls = cfg->enable_mrls;
@@ -1460,6 +1472,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   part_cfg->erp_pruning_level = extra_cfg->erp_pruning_level;
   part_cfg->use_ml_erp_pruning = extra_cfg->use_ml_erp_pruning;
+  part_cfg->disable_3way_part_64xn = extra_cfg->disable_3way_part_64xn;
+  part_cfg->disable_3way_part_32xn = extra_cfg->disable_3way_part_32xn;
+  part_cfg->disable_3way_part_16xn = extra_cfg->disable_3way_part_16xn;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   part_cfg->min_partition_size = extra_cfg->min_partition_size;
   part_cfg->max_partition_size = extra_cfg->max_partition_size;
@@ -3602,6 +3617,18 @@
   } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.use_ml_erp_pruning,
                               argv, err_string)) {
     extra_cfg.use_ml_erp_pruning = arg_parse_int_helper(&arg, err_string);
+  } else if (arg_match_helper(&arg,
+                              &g_av1_codec_arg_defs.disable_3way_part_64xn,
+                              argv, err_string)) {
+    extra_cfg.disable_3way_part_64xn = arg_parse_int_helper(&arg, err_string);
+  } else if (arg_match_helper(&arg,
+                              &g_av1_codec_arg_defs.disable_3way_part_32xn,
+                              argv, err_string)) {
+    extra_cfg.disable_3way_part_32xn = arg_parse_int_helper(&arg, err_string);
+  } else if (arg_match_helper(&arg,
+                              &g_av1_codec_arg_defs.disable_3way_part_16xn,
+                              argv, err_string)) {
+    extra_cfg.disable_3way_part_16xn = arg_parse_int_helper(&arg, err_string);
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   } else if (arg_match_helper(
                  &arg,
@@ -4070,6 +4097,9 @@
         1,
         5,  // aggressiveness for erp pruning
         0,  // use ml model for erp pruning
+        0,  // disable ternary partition in 64xN/Nx64(N<=64) blocks
+        0,  // disable ternary partition in 32xN/Nx32(N<=32) blocks
+        0,  // disable ternary partition in 16xN/Nx16(N<=16) blocks
 #else       // CONFIG_EXT_RECUR_PARTITIONS
         0,
 #endif      // CONFIG_EXT_RECUR_PARTITIONS
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index 78b6d1a..9a299f2 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -466,6 +466,11 @@
 #if CONFIG_REF_MV_BANK
   uint8_t enable_refmvbank;  // To turn on/off Ref MV Bank
 #endif                       // CONFIG_REF_MV_BANK
+#if CONFIG_EXT_RECUR_PARTITIONS
+  uint8_t disable_3way_part_64xn;  // disable 3way part in 64xn/nx64(n <= 64)
+  uint8_t disable_3way_part_32xn;  // disable 3way part in 32xn/nx32(n <= 32)
+  uint8_t disable_3way_part_16xn;  // disable 3way part in 16xn/nx16(n <= 16)
+#endif                             // CONFIG_EXT_RECUR_PARTITIONS
   BITSTREAM_PROFILE profile;
 
   // Color config.
@@ -2208,6 +2213,7 @@
     return EXT_PARTITION_TYPES;
 }
 
+#if CONFIG_EXT_RECUR_PARTITIONS
 static INLINE int limited_partition_cdf_length(BLOCK_SIZE bsize) {
   assert(block_size_wide[bsize] == block_size_high[bsize]);
   assert(is_bsize_geq(bsize, BLOCK_8X8));
@@ -2215,7 +2221,6 @@
   return partition_cdf_length(bsize) - 1;
 }
 
-#if CONFIG_EXT_RECUR_PARTITIONS
 static INLINE int partition_rec_cdf_length(BLOCK_SIZE bsize) {
   assert(block_size_wide[bsize] != block_size_high[bsize]);
 
@@ -2240,6 +2245,26 @@
   }
 }
 
+static INLINE int partition_noext_rec_cdf_length(BLOCK_SIZE bsize) {
+  assert(block_size_wide[bsize] != block_size_high[bsize]);
+
+  switch (bsize) {
+    case BLOCK_4X8:
+    case BLOCK_8X4:
+    case BLOCK_64X128:
+    case BLOCK_128X64: return 2;
+    case BLOCK_8X16:
+    case BLOCK_16X8:
+    case BLOCK_16X32:
+    case BLOCK_32X16:
+    case BLOCK_32X64:
+    case BLOCK_64X32: return PARTITION_TYPES;
+    default:
+      assert(0 && "Invalid splittable rectangular bsize");
+      return PARTITION_INVALID_REC;
+  }
+}
+
 static INLINE int is_1_to_2_block(BLOCK_SIZE bsize) {
   return 2 * block_size_high[bsize] == block_size_wide[bsize] ||
          block_size_high[bsize] == 2 * block_size_wide[bsize];
@@ -2253,6 +2278,15 @@
   assert(is_1_to_2_block(bsize));
   return partition_rec_cdf_length(bsize) - 1;
 }
+
+static INLINE int partition_middle_noext_rec_cdf_length(BLOCK_SIZE bsize) {
+  // For some bock sizes, HORZ|VERT is already unavailable, so we shouldn't call
+  // this function.
+  assert(is_bsize_geq(bsize, BLOCK_8X8));
+  assert(is_bsize_geq(BLOCK_64X64, bsize));
+  assert(is_1_to_2_block(bsize));
+  return partition_noext_rec_cdf_length(bsize) - 1;
+}
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
 
 static INLINE int max_block_wide(const MACROBLOCKD *xd, BLOCK_SIZE bsize,
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 14df418..a48491c 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -579,7 +579,19 @@
          is_inter_ref_frame(mbmi->ref_frame[0]);
 }
 
+static INLINE int is_square_block(BLOCK_SIZE bsize) {
+  return block_size_high[bsize] == block_size_wide[bsize];
+}
+
 #if CONFIG_EXT_RECUR_PARTITIONS
+static INLINE bool is_tall_block(BLOCK_SIZE bsize) {
+  return block_size_high[bsize] > block_size_wide[bsize];
+}
+
+static INLINE bool is_wide_block(BLOCK_SIZE bsize) {
+  return block_size_high[bsize] < block_size_wide[bsize];
+}
+
 static INLINE PARTITION_TYPE get_partition_from_symbol_rec_block(
     BLOCK_SIZE bsize, PARTITION_TYPE_REC partition_rec) {
   if (block_size_wide[bsize] > block_size_high[bsize])
@@ -590,6 +602,26 @@
     return PARTITION_INVALID;
 }
 
+static INLINE PARTITION_TYPE
+get_partition_noext_from_symbol_rec_block(BLOCK_SIZE bsize, int symbol) {
+  if (symbol == 0) {
+    return PARTITION_NONE;
+  } else {
+    const int is_wide = is_wide_block(bsize);
+    const PARTITION_TYPE partition_longside_2way =
+        is_wide ? PARTITION_VERT : PARTITION_HORZ;
+    const PARTITION_TYPE partition_shortside_2way =
+        is_wide ? PARTITION_HORZ : PARTITION_VERT;
+
+    if (symbol == 1)
+      return partition_longside_2way;
+    else if (symbol == 2)
+      return partition_shortside_2way;
+    else
+      return PARTITION_INVALID;
+  }
+}
+
 static INLINE PARTITION_TYPE_REC get_symbol_from_partition_rec_block(
     BLOCK_SIZE bsize, PARTITION_TYPE partition) {
   assert(bsize < BLOCK_SIZES_ALL);
@@ -602,6 +634,23 @@
     return PARTITION_INVALID_REC;
 }
 
+static INLINE PARTITION_TYPE_REC get_symbol_from_partition_noext_rec_block(
+    BLOCK_SIZE bsize, PARTITION_TYPE partition) {
+  assert(bsize < BLOCK_SIZES_ALL);
+  assert(partition < EXT_PARTITION_TYPES);
+
+  if (partition >= PARTITION_TYPES) return PARTITION_INVALID_REC;
+  if (partition == PARTITION_NONE) return 0;
+
+  PARTITION_TYPE partition_longside_2way =
+      is_wide_block(bsize) ? PARTITION_VERT : PARTITION_HORZ;
+  if (is_bsize_geq(BLOCK_8X8, bsize) || is_bsize_geq(bsize, BLOCK_64X64)) {
+    return partition == partition_longside_2way ? 1 : PARTITION_INVALID_REC;
+  } else {
+    return partition == partition_longside_2way ? 1 : 2;
+  }
+}
+
 static INLINE PARTITION_TYPE get_symbol_from_limited_partition(
     PARTITION_TYPE part, PARTITION_TYPE parent_part) {
   assert(part != PARTITION_INVALID);
@@ -620,6 +669,26 @@
   return symbol;
 }
 
+static INLINE PARTITION_TYPE get_symbol_from_limited_partition_noext(
+    PARTITION_TYPE part, PARTITION_TYPE parent_part) {
+  assert(part != PARTITION_INVALID);
+  assert(parent_part == PARTITION_HORZ_3 || parent_part == PARTITION_VERT_3);
+  static const int partition_to_symbol_map[NUM_LIMITED_PARTITION_PARENTS]
+                                          [EXT_PARTITION_TYPES] = {
+                                            // PARTITION_HORZ_3
+                                            { 0, PARTITION_INVALID_REC, 1,
+                                              PARTITION_INVALID_REC,
+                                              PARTITION_INVALID_REC },
+                                            // PARTITION_VERT_3
+                                            { 0, 1, PARTITION_INVALID_REC,
+                                              PARTITION_INVALID_REC,
+                                              PARTITION_INVALID_REC },
+                                          };
+  const int dir = (parent_part == PARTITION_HORZ_3) ? 0 : 1;
+  const int symbol = partition_to_symbol_map[dir][part];
+  return symbol;
+}
+
 static INLINE PARTITION_TYPE
 get_limited_partition_from_symbol(int symbol, PARTITION_TYPE parent_part) {
   assert(parent_part == PARTITION_HORZ_3 || parent_part == PARTITION_VERT_3);
@@ -641,6 +710,25 @@
   }
 }
 
+static INLINE PARTITION_TYPE get_limited_partition_noext_from_symbol(
+    int symbol, PARTITION_TYPE parent_part) {
+  assert(parent_part == PARTITION_HORZ_3 || parent_part == PARTITION_VERT_3);
+  static const PARTITION_TYPE horz3_parts[LIMITED_PARTITION_TYPES] = {
+    PARTITION_NONE, PARTITION_VERT
+  };
+  static const PARTITION_TYPE vert3_parts[LIMITED_PARTITION_TYPES] = {
+    PARTITION_NONE, PARTITION_HORZ
+  };
+  switch (parent_part) {
+    case PARTITION_HORZ_3: return horz3_parts[symbol];
+    case PARTITION_VERT_3: return vert3_parts[symbol];
+    default:
+      assert(0 &&
+             "Invalid parent partition in get_limited_partition from symbol");
+      return PARTITION_INVALID;
+  }
+}
+
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
 
 static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) {
@@ -704,20 +792,6 @@
          block_size_allowed;
 }
 
-static INLINE int is_square_block(BLOCK_SIZE bsize) {
-  return block_size_high[bsize] == block_size_wide[bsize];
-}
-
-#if CONFIG_EXT_RECUR_PARTITIONS
-static INLINE bool is_tall_block(BLOCK_SIZE bsize) {
-  return block_size_high[bsize] > block_size_wide[bsize];
-}
-
-static INLINE bool is_wide_block(BLOCK_SIZE bsize) {
-  return block_size_high[bsize] < block_size_wide[bsize];
-}
-#endif  // CONFIG_EXT_RECUR_PARTITIONS
-
 static INLINE int is_partition_point(BLOCK_SIZE bsize) {
 #if CONFIG_EXT_RECUR_PARTITIONS
   return bsize != BLOCK_4X4 && bsize < BLOCK_SIZES;
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 3e6e0b4..a22fbc2 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -285,6 +285,64 @@
                                       { AOM_CDF3(2715, 30175) },
                                       { AOM_CDF3(2286, 20850) },
                                   } };
+static const aom_cdf_prob
+    default_partition_noext_cdf[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS]
+                               [CDF_SIZE(PARTITION_TYPES)] = {
+                                 {
+                                     // 8x8
+                                     { AOM_CDF3(25405, 29765) },
+                                     { AOM_CDF3(20718, 26547) },
+                                     { AOM_CDF3(18495, 29033) },
+                                     { AOM_CDF3(14030, 27418) },
+                                     // 16x16
+                                     { AOM_CDF3(17068, 26841) },
+                                     { AOM_CDF3(11534, 19955) },
+                                     { AOM_CDF3(9216, 26696) },
+                                     { AOM_CDF3(7987, 20777) },
+                                     // 32x32
+                                     { AOM_CDF3(13065, 27593) },
+                                     { AOM_CDF3(8608, 20630) },
+                                     { AOM_CDF3(5281, 27411) },
+                                     { AOM_CDF3(6459, 20044) },
+                                     // 64x64
+                                     { AOM_CDF3(9265, 26250) },
+                                     { AOM_CDF3(7509, 17214) },
+                                     { AOM_CDF3(2577, 28098) },
+                                     { AOM_CDF3(2577, 28098) },
+                                     // 128x128
+                                     { AOM_CDF3(22143, 27468) },
+                                     { AOM_CDF3(6754, 12691) },
+                                     { AOM_CDF3(2715, 30175) },
+                                     { AOM_CDF3(2286, 20850) },
+                                 },
+                                 {
+                                     // 8x8
+                                     { AOM_CDF3(25405, 29765) },
+                                     { AOM_CDF3(20718, 26547) },
+                                     { AOM_CDF3(18495, 29033) },
+                                     { AOM_CDF3(14030, 27418) },
+                                     // 16x16
+                                     { AOM_CDF3(17068, 26841) },
+                                     { AOM_CDF3(11534, 19955) },
+                                     { AOM_CDF3(9216, 26696) },
+                                     { AOM_CDF3(7987, 20777) },
+                                     // 32x32
+                                     { AOM_CDF3(13065, 27593) },
+                                     { AOM_CDF3(8608, 20630) },
+                                     { AOM_CDF3(5281, 27411) },
+                                     { AOM_CDF3(6459, 20044) },
+                                     // 64x64
+                                     { AOM_CDF3(9265, 26250) },
+                                     { AOM_CDF3(7509, 17214) },
+                                     { AOM_CDF3(2577, 28098) },
+                                     { AOM_CDF3(2577, 28098) },
+                                     // 128x128
+                                     { AOM_CDF3(22143, 27468) },
+                                     { AOM_CDF3(6754, 12691) },
+                                     { AOM_CDF3(2715, 30175) },
+                                     { AOM_CDF3(2286, 20850) },
+                                 }
+                               };
 #else   // !ERP_LIMIT_PARTITION3_128
 static const aom_cdf_prob
     default_partition_cdf[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS][CDF_SIZE(
@@ -378,7 +436,6 @@
         },
         // VERT_3
         {
-
             // 8x8
             { AOM_CDF2(24114) },
             { AOM_CDF2(20966) },
@@ -404,7 +461,6 @@
             { AOM_CDF2(16584) },
             { AOM_CDF2(15476) },
             { AOM_CDF2(11625) },
-
         } },
       // Chroma
       { // HORZ_3
@@ -437,7 +493,6 @@
         },
         // VERT_3
         {
-
             // 8x8
             { AOM_CDF2(24114) },
             { AOM_CDF2(20966) },
@@ -463,7 +518,124 @@
             { AOM_CDF2(16584) },
             { AOM_CDF2(15476) },
             { AOM_CDF2(11625) },
-
+        } }
+    };
+static const aom_cdf_prob default_limited_partition_noext_cdf
+    [PARTITION_STRUCTURE_NUM][NUM_LIMITED_PARTITION_PARENTS][PARTITION_CONTEXTS]
+    [CDF_SIZE(LIMITED_PARTITION_TYPES)] = {
+      // Luma/Shared
+      { // HORZ_3
+        {
+            // 8x8
+            { AOM_CDF2(25550) },
+            { AOM_CDF2(21449) },
+            { AOM_CDF2(22555) },
+            { AOM_CDF2(21203) },
+            // 16x16
+            { AOM_CDF2(16588) },
+            { AOM_CDF2(9278) },
+            { AOM_CDF2(11426) },
+            { AOM_CDF2(7824) },
+            // 32x32
+            { AOM_CDF2(13817) },
+            { AOM_CDF2(7015) },
+            { AOM_CDF2(9045) },
+            { AOM_CDF2(5801) },
+            // 64x64
+            { AOM_CDF2(22701) },
+            { AOM_CDF2(7745) },
+            { AOM_CDF2(9203) },
+            { AOM_CDF2(5150) },
+            // 128x128
+            { AOM_CDF2(27175) },  // Unused
+            { AOM_CDF2(11141) },  // Unused
+            { AOM_CDF2(15312) },  // Unused
+            { AOM_CDF2(7362) },   // Unused
+        },
+        // VERT_3
+        {
+            // 8x8
+            { AOM_CDF2(24114) },
+            { AOM_CDF2(20966) },
+            { AOM_CDF2(18259) },
+            { AOM_CDF2(17964) },
+            // 16x16
+            { AOM_CDF2(16315) },
+            { AOM_CDF2(11233) },
+            { AOM_CDF2(8724) },
+            { AOM_CDF2(7346) },
+            // 32x32
+            { AOM_CDF2(13603) },
+            { AOM_CDF2(8550) },
+            { AOM_CDF2(7448) },
+            { AOM_CDF2(6276) },
+            // 64x64
+            { AOM_CDF2(22750) },
+            { AOM_CDF2(8951) },
+            { AOM_CDF2(8126) },
+            { AOM_CDF2(49802) },
+            // 128x128
+            { AOM_CDF2(27774) },
+            { AOM_CDF2(16584) },
+            { AOM_CDF2(15476) },
+            { AOM_CDF2(11625) },
+        } },
+      // Chroma
+      { // HORZ_3
+        {
+            // 8x8
+            { AOM_CDF2(25550) },
+            { AOM_CDF2(21449) },
+            { AOM_CDF2(22555) },
+            { AOM_CDF2(21203) },
+            // 16x16
+            { AOM_CDF2(16588) },
+            { AOM_CDF2(9278) },
+            { AOM_CDF2(11426) },
+            { AOM_CDF2(7824) },
+            // 32x32
+            { AOM_CDF2(13817) },
+            { AOM_CDF2(7015) },
+            { AOM_CDF2(9045) },
+            { AOM_CDF2(5801) },
+            // 64x64
+            { AOM_CDF2(22701) },
+            { AOM_CDF2(7745) },
+            { AOM_CDF2(9203) },
+            { AOM_CDF2(5150) },
+            // 128x128
+            { AOM_CDF2(27175) },  // Unused
+            { AOM_CDF2(11141) },  // Unused
+            { AOM_CDF2(15312) },  // Unused
+            { AOM_CDF2(7362) },   // Unused
+        },
+        // VERT_3
+        {
+            // 8x8
+            { AOM_CDF2(24114) },
+            { AOM_CDF2(20966) },
+            { AOM_CDF2(18259) },
+            { AOM_CDF2(17964) },
+            // 16x16
+            { AOM_CDF2(16315) },
+            { AOM_CDF2(11233) },
+            { AOM_CDF2(8724) },
+            { AOM_CDF2(7346) },
+            // 32x32
+            { AOM_CDF2(13603) },
+            { AOM_CDF2(8550) },
+            { AOM_CDF2(7448) },
+            { AOM_CDF2(6276) },
+            // 64x64
+            { AOM_CDF2(22750) },
+            { AOM_CDF2(8951) },
+            { AOM_CDF2(8126) },
+            { AOM_CDF2(4980) },
+            // 128x128
+            { AOM_CDF2(27774) },
+            { AOM_CDF2(16584) },
+            { AOM_CDF2(15476) },
+            { AOM_CDF2(11625) },
         } }
     };
 #else
@@ -572,6 +744,35 @@
                                { AOM_CDF2(8532) },
                                { AOM_CDF2(8532) },
                              };
+static const aom_cdf_prob
+    default_partition_noext_rec_cdf[PARTITION_CONTEXTS_REC]
+                                   [CDF_SIZE(PARTITION_TYPES)] = {
+                                     // 8x4, 4x8
+                                     { AOM_CDF2(30612) },
+                                     { AOM_CDF2(26074) },
+                                     { AOM_CDF2(28683) },
+                                     { AOM_CDF2(21191) },
+                                     // 16x8, 8x16
+                                     { AOM_CDF3(21708, 29163) },
+                                     { AOM_CDF3(13852, 27221) },
+                                     { AOM_CDF3(19187, 27661) },
+                                     { AOM_CDF3(9933, 21239) },
+                                     // 32x16, 16x32
+                                     { AOM_CDF3(14474, 25684) },
+                                     { AOM_CDF3(5925, 22613) },
+                                     { AOM_CDF3(12840, 23573) },
+                                     { AOM_CDF3(6088, 16570) },
+                                     // 64x32, 32x64
+                                     { AOM_CDF3(11157, 25388) },
+                                     { AOM_CDF3(3692, 24449) },
+                                     { AOM_CDF3(13455, 23113) },
+                                     { AOM_CDF3(13455, 23113) },
+                                     // 128x64, 64x128
+                                     { AOM_CDF2(9487) },
+                                     { AOM_CDF2(2668) },
+                                     { AOM_CDF2(8532) },
+                                     { AOM_CDF2(8532) },
+                                   };
 #else   // !ERP_LIMIT_PARTITION3_128
 static const aom_cdf_prob
     default_partition_rec_cdf[PARTITION_CONTEXTS_REC]
@@ -633,6 +834,34 @@
                                       { AOM_CDF3(9068, 21038) },   // Not used
                                       { AOM_CDF3(10923, 21845) },  // Not used
                                     };
+static const aom_cdf_prob
+    default_partition_middle_noext_rec_cdf[PARTITION_CONTEXTS_REC][CDF_SIZE(
+        LIMITED_PARTITION_TYPES)] = {
+      // 8x4, 4x8
+      { AOM_CDF2(30462) },  // Not used
+      { AOM_CDF2(25506) },  // Not used
+      { AOM_CDF2(27632) },  // Not used
+      { AOM_CDF2(19443) },  // Not used
+      // 16x8, 8x16
+      { AOM_CDF2(20645) }, { AOM_CDF2(13282) }, { AOM_CDF2(17766) },
+      {
+          AOM_CDF2(13067),
+          // 32x16, 16x32
+          { AOM_CDF2(14234) },
+          { AOM_CDF2(7421) },
+          { AOM_CDF2(8692) },
+          { AOM_CDF2(5458) },
+          // 64x32, 32x64
+          { AOM_CDF2(14706) },
+          { AOM_CDF2(6131) },
+          { AOM_CDF2(6588) },
+          { AOM_CDF2(8175) },
+          // 128x64, 64x128
+          { AOM_CDF2(15208) },  // Not used
+          { AOM_CDF2(6597) },   // Not used
+          { AOM_CDF2(9068) },   // Not used
+          { AOM_CDF2(10923) },  // Not used
+      };
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
 
 static const aom_cdf_prob default_intra_ext_tx_cdf
@@ -2211,8 +2440,14 @@
   av1_copy(fc->partition_cdf, default_partition_cdf);
 #if CONFIG_EXT_RECUR_PARTITIONS
   av1_copy(fc->limited_partition_cdf, default_limited_partition_cdf);
+  av1_copy(fc->partition_noext_cdf, default_partition_noext_cdf);
+  av1_copy(fc->limited_partition_noext_cdf,
+           default_limited_partition_noext_cdf);
   av1_copy(fc->partition_rec_cdf, default_partition_rec_cdf);
   av1_copy(fc->partition_middle_rec_cdf, default_partition_middle_rec_cdf);
+  av1_copy(fc->partition_noext_rec_cdf, default_partition_noext_rec_cdf);
+  av1_copy(fc->partition_middle_noext_rec_cdf,
+           default_partition_middle_noext_rec_cdf);
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   av1_copy(fc->intra_ext_tx_cdf, default_intra_ext_tx_cdf);
   av1_copy(fc->inter_ext_tx_cdf, default_inter_ext_tx_cdf);
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index bfa842b..c13bb85 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -234,12 +234,20 @@
                                     [NUM_LIMITED_PARTITION_PARENTS]
                                     [PARTITION_CONTEXTS]
                                     [CDF_SIZE(LIMITED_EXT_PARTITION_TYPES)];
-#endif  // CONFIG_EXT_RECUR_PARTITIONS
-#if CONFIG_EXT_RECUR_PARTITIONS
+  aom_cdf_prob partition_noext_cdf[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS]
+                                  [CDF_SIZE(PARTITION_TYPES)];
+  aom_cdf_prob limited_partition_noext_cdf[PARTITION_STRUCTURE_NUM]
+                                          [NUM_LIMITED_PARTITION_PARENTS]
+                                          [PARTITION_CONTEXTS]
+                                          [CDF_SIZE(LIMITED_PARTITION_TYPES)];
   aom_cdf_prob partition_rec_cdf[PARTITION_CONTEXTS_REC]
                                 [CDF_SIZE(PARTITION_TYPES_REC)];
   aom_cdf_prob partition_middle_rec_cdf[PARTITION_CONTEXTS_REC]
                                        [CDF_SIZE(PARTITION_TYPES_MIDDLE_REC)];
+  aom_cdf_prob partition_noext_rec_cdf[PARTITION_CONTEXTS_REC]
+                                      [CDF_SIZE(PARTITION_TYPES)];
+  aom_cdf_prob partition_middle_noext_rec_cdf[PARTITION_CONTEXTS_REC][CDF_SIZE(
+      LIMITED_PARTITION_TYPES)];
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   aom_cdf_prob switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS]
                                     [CDF_SIZE(SWITCHABLE_FILTERS)];
diff --git a/av1/common/enums.h b/av1/common/enums.h
index 91a97c0..26d6433 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -270,6 +270,7 @@
   LIMITED_EXT_PARTITION_TYPES = EXT_PARTITION_TYPES - 1,
   PARTITION_SPLIT = EXT_PARTITION_TYPES,
   PARTITION_TYPES = PARTITION_VERT + 1,
+  LIMITED_PARTITION_TYPES = PARTITION_TYPES - 1,
   PARTITION_INVALID = 255
 } UENUM1BYTE(PARTITION_TYPE);
 #else   // CONFIG_EXT_RECUR_PARTITIONS
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 7ed7f64..9a3737a 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1854,49 +1854,91 @@
   const bool limit_rect_split = is_middle_block &&
                                 is_bsize_geq(bsize, BLOCK_8X8) &&
                                 is_bsize_geq(BLOCK_64X64, bsize);
+  const int max_1dsize = AOMMAX(block_size_wide[bsize], block_size_high[bsize]);
+  const bool disable_ext_part =
+      (max_1dsize == 64 && cm->seq_params.disable_3way_part_64xn) ||
+      (max_1dsize == 32 && cm->seq_params.disable_3way_part_32xn) ||
+      (max_1dsize == 16 && cm->seq_params.disable_3way_part_16xn);
 
   if (is_square_block(bsize)) {
     assert(ctx >= 0);
-    aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[plane][ctx];
+    if (disable_ext_part) {
+      aom_cdf_prob *partition_cdf = ec_ctx->partition_noext_cdf[plane][ctx];
 
-    if (limit_rect_split) {
-      const int dir_index = parent_partition == PARTITION_HORZ_3 ? 0 : 1;
-      partition_cdf = ec_ctx->limited_partition_cdf[plane][dir_index][ctx];
-      const int symbol = aom_read_symbol(
-          r, partition_cdf, limited_partition_cdf_length(bsize), ACCT_STR);
-      return get_limited_partition_from_symbol(symbol, parent_partition);
+      if (limit_rect_split) {
+        const int dir_index = parent_partition == PARTITION_HORZ_3 ? 0 : 1;
+        partition_cdf =
+            ec_ctx->limited_partition_noext_cdf[plane][dir_index][ctx];
+        const int symbol = aom_read_symbol(r, partition_cdf,
+                                           LIMITED_PARTITION_TYPES, ACCT_STR);
+        return get_limited_partition_noext_from_symbol(symbol,
+                                                       parent_partition);
+      } else {
+        return (PARTITION_TYPE)aom_read_symbol(r, partition_cdf,
+                                               PARTITION_TYPES, ACCT_STR);
+      }
     } else {
-      return (PARTITION_TYPE)aom_read_symbol(
-          r, partition_cdf, partition_cdf_length(bsize), ACCT_STR);
+      aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[plane][ctx];
+
+      if (limit_rect_split) {
+        const int dir_index = parent_partition == PARTITION_HORZ_3 ? 0 : 1;
+        partition_cdf = ec_ctx->limited_partition_cdf[plane][dir_index][ctx];
+        const int symbol = aom_read_symbol(
+            r, partition_cdf, limited_partition_cdf_length(bsize), ACCT_STR);
+        return get_limited_partition_from_symbol(symbol, parent_partition);
+      } else {
+        return (PARTITION_TYPE)aom_read_symbol(
+            r, partition_cdf, partition_cdf_length(bsize), ACCT_STR);
+      }
     }
-  } else {  // Rectangular block.
-    if (limit_rect_split) {
-      // If we are the middle block of a 3-way partitioning, disable HORZ/VERT
-      // of the middle partition because it is redundant.
-      assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
-                     block_size_wide[bsize] == 2 * block_size_high[bsize]));
-      assert(IMPLIES(parent_partition == PARTITION_VERT_3,
-                     2 * block_size_wide[bsize] == block_size_high[bsize]));
-      aom_cdf_prob *partition_middle_rec_cdf =
-          ec_ctx->partition_middle_rec_cdf[ctx];
+  } else {
+    if (disable_ext_part) {
+      if (limit_rect_split) {
+        aom_cdf_prob *partition_cdf =
+            ec_ctx->partition_middle_noext_rec_cdf[ctx];
+        const int cdf_length = partition_middle_noext_rec_cdf_length(bsize);
+        const int symbol =
+            aom_read_symbol(r, partition_cdf, cdf_length, ACCT_STR);
+
+        return get_limited_partition_noext_from_symbol(symbol,
+                                                       parent_partition);
+      } else {
+        aom_cdf_prob *partition_cdf = ec_ctx->partition_noext_rec_cdf[ctx];
+        const int cdf_length = partition_noext_rec_cdf_length(bsize);
+        const int symbol =
+            aom_read_symbol(r, partition_cdf, cdf_length, ACCT_STR);
+
+        return get_partition_noext_from_symbol_rec_block(bsize, symbol);
+      }
+    } else {
+      if (limit_rect_split) {
+        // If we are the middle block of a 3-way partitioning, disable HORZ/VERT
+        // of the middle partition because it is redundant.
+        assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
+                       block_size_wide[bsize] == 2 * block_size_high[bsize]));
+        assert(IMPLIES(parent_partition == PARTITION_VERT_3,
+                       2 * block_size_wide[bsize] == block_size_high[bsize]));
+        aom_cdf_prob *partition_middle_rec_cdf =
+            ec_ctx->partition_middle_rec_cdf[ctx];
+        const PARTITION_TYPE_REC symbol = (PARTITION_TYPE_REC)aom_read_symbol(
+            r, partition_middle_rec_cdf, partition_middle_rec_cdf_length(bsize),
+            ACCT_STR);
+
+        const PARTITION_TYPE partition =
+            get_partition_from_symbol_rec_block(bsize, symbol);
+        assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
+                       partition != PARTITION_HORZ));
+        assert(IMPLIES(parent_partition == PARTITION_VERT_3,
+                       partition != PARTITION_VERT));
+
+        return partition;
+      }
+      aom_cdf_prob *partition_rec_cdf = ec_ctx->partition_rec_cdf[ctx];
       const PARTITION_TYPE_REC symbol = (PARTITION_TYPE_REC)aom_read_symbol(
-          r, partition_middle_rec_cdf, partition_middle_rec_cdf_length(bsize),
-          ACCT_STR);
+          r, partition_rec_cdf, partition_rec_cdf_length(bsize), ACCT_STR);
 
-      const PARTITION_TYPE partition =
-          get_partition_from_symbol_rec_block(bsize, symbol);
-      assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
-                     partition != PARTITION_HORZ));
-      assert(IMPLIES(parent_partition == PARTITION_VERT_3,
-                     partition != PARTITION_VERT));
-
-      return partition;
+      return get_partition_from_symbol_rec_block(bsize, symbol);
     }
-    aom_cdf_prob *partition_rec_cdf = ec_ctx->partition_rec_cdf[ctx];
-    const PARTITION_TYPE_REC symbol = (PARTITION_TYPE_REC)aom_read_symbol(
-        r, partition_rec_cdf, partition_rec_cdf_length(bsize), ACCT_STR);
-
-    return get_partition_from_symbol_rec_block(bsize, symbol);
   }
 #else   // !CONFIG_EXT_RECUR_PARTITIONS
   if (!has_rows && !has_cols) return PARTITION_SPLIT;
@@ -5374,6 +5416,11 @@
 #if CONFIG_NEW_TX_PARTITION
   seq_params->enable_tx_split_4way = aom_rb_read_bit(rb);
 #endif  // CONFIG_NEW_TX_PARTITION
+#if CONFIG_EXT_RECUR_PARTITIONS
+  seq_params->disable_3way_part_64xn = aom_rb_read_bit(rb);
+  seq_params->disable_3way_part_32xn = aom_rb_read_bit(rb);
+  seq_params->disable_3way_part_16xn = aom_rb_read_bit(rb);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
 }
 
 static int read_global_motion_params(WarpedMotionParams *params,
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 7720d84..f117953 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2321,36 +2321,84 @@
   const bool limit_rect_split = is_middle_block &&
                                 is_bsize_geq(bsize, BLOCK_8X8) &&
                                 is_bsize_geq(BLOCK_64X64, bsize);
+  const int max_1dsize = AOMMAX(block_size_wide[bsize], block_size_high[bsize]);
+  const bool disable_ext_part =
+      (max_1dsize == 64 && cm->seq_params.disable_3way_part_64xn) ||
+      (max_1dsize == 32 && cm->seq_params.disable_3way_part_32xn) ||
+      (max_1dsize == 16 && cm->seq_params.disable_3way_part_16xn);
   if (is_square_block(bsize)) {
-    aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[plane][ctx];
-    if (limit_rect_split) {
-      const int dir_index = parent_partition == PARTITION_HORZ_3 ? 0 : 1;
-      partition_cdf = ec_ctx->limited_partition_cdf[plane][dir_index][ctx];
-      const int symbol = get_symbol_from_limited_partition(p, parent_partition);
-      aom_write_symbol(w, symbol, partition_cdf,
-                       limited_partition_cdf_length(bsize));
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
+
+#if CONFIG_EXT_RECUR_PARTITIONS
+    if (disable_ext_part) {
+      aom_cdf_prob *partition_cdf;
+      int symbol, cdf_length;
+      if (limit_rect_split) {
+        const int dir_index = parent_partition == PARTITION_HORZ_3 ? 0 : 1;
+        partition_cdf =
+            ec_ctx->limited_partition_noext_cdf[plane][dir_index][ctx];
+        symbol = get_symbol_from_limited_partition_noext(p, parent_partition);
+        cdf_length = LIMITED_PARTITION_TYPES;
+      } else {
+        partition_cdf = ec_ctx->partition_noext_cdf[plane][ctx];
+        symbol = p;
+        cdf_length = PARTITION_TYPES;
+      }
+      aom_write_symbol(w, symbol, partition_cdf, cdf_length);
     } else {
-      aom_write_symbol(w, p, partition_cdf, partition_cdf_length(bsize));
+      aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[plane][ctx];
+      if (limit_rect_split) {
+        const int dir_index = parent_partition == PARTITION_HORZ_3 ? 0 : 1;
+        partition_cdf = ec_ctx->limited_partition_cdf[plane][dir_index][ctx];
+        const int symbol =
+            get_symbol_from_limited_partition(p, parent_partition);
+        aom_write_symbol(w, symbol, partition_cdf,
+                         limited_partition_cdf_length(bsize));
+      } else {
+        aom_write_symbol(w, p, partition_cdf, partition_cdf_length(bsize));
+      }
     }
   } else {  // 1:2 or 2:1 rectangular blocks
-    if (limit_rect_split) {
-      assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
-                     block_size_wide[bsize] == 2 * block_size_high[bsize]));
-      assert(IMPLIES(parent_partition == PARTITION_VERT_3,
-                     2 * block_size_wide[bsize] == block_size_high[bsize]));
-      assert(
-          IMPLIES(parent_partition == PARTITION_HORZ_3, p != PARTITION_HORZ));
-      assert(
-          IMPLIES(parent_partition == PARTITION_VERT_3, p != PARTITION_VERT));
-      const PARTITION_TYPE_REC symbol =
-          get_symbol_from_partition_rec_block(bsize, p);
-      aom_write_symbol(w, symbol, ec_ctx->partition_middle_rec_cdf[ctx],
-                       partition_middle_rec_cdf_length(bsize));
+    if (disable_ext_part) {
+      if (limit_rect_split) {
+        assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
+                       block_size_wide[bsize] == 2 * block_size_high[bsize]));
+        assert(IMPLIES(parent_partition == PARTITION_VERT_3,
+                       2 * block_size_wide[bsize] == block_size_high[bsize]));
+        assert(
+            IMPLIES(parent_partition == PARTITION_HORZ_3, p != PARTITION_HORZ));
+        assert(
+            IMPLIES(parent_partition == PARTITION_VERT_3, p != PARTITION_VERT));
+        const PARTITION_TYPE_REC symbol =
+            get_symbol_from_limited_partition_noext(bsize, p);
+        aom_write_symbol(w, symbol, ec_ctx->partition_middle_noext_rec_cdf[ctx],
+                         partition_middle_noext_rec_cdf_length(bsize));
+      } else {
+        const PARTITION_TYPE_REC symbol =
+            get_symbol_from_partition_noext_rec_block(bsize, p);
+        aom_write_symbol(w, symbol, ec_ctx->partition_noext_rec_cdf[ctx],
+                         partition_noext_rec_cdf_length(bsize));
+      }
     } else {
-      const PARTITION_TYPE_REC symbol =
-          get_symbol_from_partition_rec_block(bsize, p);
-      aom_write_symbol(w, symbol, ec_ctx->partition_rec_cdf[ctx],
-                       partition_rec_cdf_length(bsize));
+      if (limit_rect_split) {
+        assert(IMPLIES(parent_partition == PARTITION_HORZ_3,
+                       block_size_wide[bsize] == 2 * block_size_high[bsize]));
+        assert(IMPLIES(parent_partition == PARTITION_VERT_3,
+                       2 * block_size_wide[bsize] == block_size_high[bsize]));
+        assert(
+            IMPLIES(parent_partition == PARTITION_HORZ_3, p != PARTITION_HORZ));
+        assert(
+            IMPLIES(parent_partition == PARTITION_VERT_3, p != PARTITION_VERT));
+        const PARTITION_TYPE_REC symbol =
+            get_symbol_from_partition_rec_block(bsize, p);
+        aom_write_symbol(w, symbol, ec_ctx->partition_middle_rec_cdf[ctx],
+                         partition_middle_rec_cdf_length(bsize));
+      } else {
+        const PARTITION_TYPE_REC symbol =
+            get_symbol_from_partition_rec_block(bsize, p);
+        aom_write_symbol(w, symbol, ec_ctx->partition_rec_cdf[ctx],
+                         partition_rec_cdf_length(bsize));
+      }
     }
   }
 #else   // CONFIG_EXT_RECUR_PARTITIONS
@@ -3785,6 +3833,11 @@
 #if CONFIG_NEW_TX_PARTITION
   aom_wb_write_bit(wb, seq_params->enable_tx_split_4way);
 #endif  // CONFIG_NEW_TX_PARTITION
+#if CONFIG_EXT_RECUR_PARTITIONS
+  aom_wb_write_bit(wb, seq_params->disable_3way_part_64xn);
+  aom_wb_write_bit(wb, seq_params->disable_3way_part_32xn);
+  aom_wb_write_bit(wb, seq_params->disable_3way_part_16xn);
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
 }
 
 static AOM_INLINE void write_global_motion_params(
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 335aa95..01c3a7b 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -707,17 +707,29 @@
   int partition_cost[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS]
                     [EXT_PARTITION_TYPES];
 #if CONFIG_EXT_RECUR_PARTITIONS
+  //! Cost for coding the partition when ext partitions are disabled
+  int partition_noext_cost[PARTITION_STRUCTURE_NUM][PARTITION_CONTEXTS]
+                          [PARTITION_TYPES];
   //! Cost for coding the limited partition.
   int limited_partition_cost[PARTITION_STRUCTURE_NUM]
                             [NUM_LIMITED_PARTITION_PARENTS][PARTITION_CONTEXTS]
                             [EXT_PARTITION_TYPES];
-#endif  // CONFIG_EXT_RECUR_PARTITIONS
-#if CONFIG_EXT_RECUR_PARTITIONS
+  //! Cost for coding the limited partition when ext partitions are disabled
+  int limited_partition_noext_cost[PARTITION_STRUCTURE_NUM]
+                                  [NUM_LIMITED_PARTITION_PARENTS]
+                                  [PARTITION_CONTEXTS][LIMITED_PARTITION_TYPES];
   /*! Cost for coding the partition for rectangular blocks. */
   int partition_rec_cost[PARTITION_CONTEXTS_REC][PARTITION_TYPES_REC];
   /*! Cost for coding the partition for rectangular blocks in the middle of
    * 3-way partitions. */
   int partition_middle_rec_cost[PARTITION_CONTEXTS_REC][PARTITION_TYPES_REC];
+  /*! Cost for coding the partition for rectangular blocks when ext partitions
+   * are disabled. */
+  int partition_noext_rec_cost[PARTITION_CONTEXTS_REC][PARTITION_TYPES];
+  /*! Cost for coding the partition for rectangular blocks in the middle of
+   * 3-way partitions when ext partitions are disabled. */
+  int partition_middle_noext_rec_cost[PARTITION_CONTEXTS_REC]
+                                     [LIMITED_PARTITION_TYPES];
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   /**@}*/
 
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index feb3ae2..5bb528d 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -457,6 +457,11 @@
   }
   seq->enable_tip_hole_fill = seq->enable_tip;
 #endif  // CONFIG_TIP
+#if CONFIG_EXT_RECUR_PARTITIONS
+  seq->disable_3way_part_64xn = oxcf->part_cfg.disable_3way_part_64xn;
+  seq->disable_3way_part_32xn = oxcf->part_cfg.disable_3way_part_32xn;
+  seq->disable_3way_part_16xn = oxcf->part_cfg.disable_3way_part_16xn;
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
   seq->enable_warped_motion = oxcf->motion_mode_cfg.enable_warped_motion;
   seq->enable_interintra_compound = tool_cfg->enable_interintra_comp;
   seq->enable_masked_compound = oxcf->comp_type_cfg.enable_masked_comp;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index c530d8c..a977371 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -215,6 +215,18 @@
    * Flag to indicate the use of ml model for erp pruning.
    * */
   int use_ml_erp_pruning;
+  /*!
+   * Flag to indicate if ternary partitions are disabled in 64xN/Nx64(N<=64).
+   * */
+  unsigned int disable_3way_part_64xn;
+  /*!
+   * Flag to indicate if ternary partitions are disabled in 32xN/Nx32(N<=32).
+   * */
+  unsigned int disable_3way_part_32xn;
+  /*!
+   * Flag to indicate if ternary partitions are disabled in 16xN/Nx16(N<=16).
+   * */
+  unsigned int disable_3way_part_16xn;
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   /*!
    * Flag to indicate if rectanguar partitions should be enabled.
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index 99b01ca..9dd0bac 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -1626,6 +1626,7 @@
                                    int allow_update_cdf,
                                    const CommonModeInfoParams *const mi_params,
 #if CONFIG_EXT_RECUR_PARTITIONS
+                                   int disable_ext_part,
                                    PARTITION_TREE const *ptree,
                                    PARTITION_TREE const *ptree_luma,
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
@@ -1668,47 +1669,84 @@
                                 is_bsize_geq(bsize, BLOCK_8X8) &&
                                 is_bsize_geq(BLOCK_64X64, bsize);
   if (is_square_block(bsize)) {
-    if (limit_rect_split) {
-      const int dir_idx = (parent_partition == PARTITION_HORZ_3) ? 0 : 1;
-      const int symbol =
-          get_symbol_from_limited_partition(partition, parent_partition);
+    if (disable_ext_part) {
+      if (limit_rect_split) {
+        const int dir_idx = (parent_partition == PARTITION_HORZ_3) ? 0 : 1;
+        const int symbol = get_symbol_from_limited_partition_noext(
+            partition, parent_partition);
 
-#if CONFIG_ENTROPY_STATS
-      counts->limited_partition[plane_index][dir_idx][ctx][symbol]++;
-#endif  // CONFIG_ENTROPY_STATS
-      if (allow_update_cdf) {
-        update_cdf(fc->limited_partition_cdf[plane_index][dir_idx][ctx], symbol,
-                   limited_partition_cdf_length(bsize));
+        if (allow_update_cdf) {
+          update_cdf(fc->limited_partition_noext_cdf[plane_index][dir_idx][ctx],
+                     symbol, LIMITED_PARTITION_TYPES);
+        }
+      } else {
+        if (allow_update_cdf) {
+          update_cdf(fc->partition_noext_cdf[plane_index][ctx], partition,
+                     PARTITION_TYPES);
+        }
       }
     } else {
+      if (limit_rect_split) {
+        const int dir_idx = (parent_partition == PARTITION_HORZ_3) ? 0 : 1;
+        const int symbol =
+            get_symbol_from_limited_partition(partition, parent_partition);
+
 #if CONFIG_ENTROPY_STATS
-      counts->partition[plane_index][ctx][partition]++;
+        counts->limited_partition[plane_index][dir_idx][ctx][symbol]++;
 #endif  // CONFIG_ENTROPY_STATS
-      if (allow_update_cdf) {
-        update_cdf(fc->partition_cdf[plane_index][ctx], partition,
-                   partition_cdf_length(bsize));
+        if (allow_update_cdf) {
+          update_cdf(fc->limited_partition_cdf[plane_index][dir_idx][ctx],
+                     symbol, limited_partition_cdf_length(bsize));
+        }
+      } else {
+#if CONFIG_ENTROPY_STATS
+        counts->partition[plane_index][ctx][partition]++;
+#endif  // CONFIG_ENTROPY_STATS
+        if (allow_update_cdf) {
+          update_cdf(fc->partition_cdf[plane_index][ctx], partition,
+                     partition_cdf_length(bsize));
+        }
       }
     }
   } else {  // Rectangular blocks
-    const PARTITION_TYPE_REC p_rec =
-        get_symbol_from_partition_rec_block(bsize, partition);
-    if (limit_rect_split) {
-#if CONFIG_ENTROPY_STATS
-      counts->partition_middle_rec[ctx][p_rec]++;
-#endif  // CONFIG_ENTROPY_STATS
-
-      if (allow_update_cdf) {
-        update_cdf(fc->partition_middle_rec_cdf[ctx], p_rec,
-                   partition_middle_rec_cdf_length(bsize));
+    if (disable_ext_part) {
+      if (limit_rect_split) {
+        const PARTITION_TYPE_REC p_rec =
+            get_symbol_from_limited_partition_noext(partition,
+                                                    parent_partition);
+        if (allow_update_cdf) {
+          update_cdf(fc->partition_middle_noext_rec_cdf[ctx], p_rec,
+                     partition_middle_noext_rec_cdf_length(bsize));
+        }
+      } else {
+        const PARTITION_TYPE_REC p_rec =
+            get_symbol_from_partition_noext_rec_block(bsize, partition);
+        if (allow_update_cdf) {
+          update_cdf(fc->partition_noext_rec_cdf[ctx], p_rec,
+                     partition_noext_rec_cdf_length(bsize));
+        }
       }
     } else {
+      const PARTITION_TYPE_REC p_rec =
+          get_symbol_from_partition_rec_block(bsize, partition);
+      if (limit_rect_split) {
 #if CONFIG_ENTROPY_STATS
-      counts->partition_rec[ctx][p_rec]++;
+        counts->partition_middle_rec[ctx][p_rec]++;
 #endif  // CONFIG_ENTROPY_STATS
 
-      if (allow_update_cdf) {
-        update_cdf(fc->partition_rec_cdf[ctx], p_rec,
-                   partition_rec_cdf_length(bsize));
+        if (allow_update_cdf) {
+          update_cdf(fc->partition_middle_rec_cdf[ctx], p_rec,
+                     partition_middle_rec_cdf_length(bsize));
+        }
+      } else {
+#if CONFIG_ENTROPY_STATS
+        counts->partition_rec[ctx][p_rec]++;
+#endif  // CONFIG_ENTROPY_STATS
+
+        if (allow_update_cdf) {
+          update_cdf(fc->partition_rec_cdf[ctx], p_rec,
+                     partition_rec_cdf_length(bsize));
+        }
       }
     }
   }
@@ -1830,9 +1868,15 @@
                       : -1;
   const PARTITION_TYPE partition = pc_tree->partitioning;
   const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition);
-#if !CONFIG_EXT_RECUR_PARTITIONS
+#if CONFIG_EXT_RECUR_PARTITIONS
+  const int max_1dsize = AOMMAX(block_size_wide[bsize], block_size_high[bsize]);
+  const bool disable_ext_part =
+      (max_1dsize == 64 && cm->seq_params.disable_3way_part_64xn) ||
+      (max_1dsize == 32 && cm->seq_params.disable_3way_part_32xn) ||
+      (max_1dsize == 16 && cm->seq_params.disable_3way_part_16xn);
+#else
   const BLOCK_SIZE bsize2 = get_partition_subsize(bsize, PARTITION_SPLIT);
-#endif  // !CONFIG_EXT_RECUR_PARTITIONS
+#endif  // CONFIG_EXT_RECUR_PARTITIONS
 
   if (subsize == BLOCK_INVALID) return;
 #if CONFIG_EXT_RECUR_PARTITIONS
@@ -1846,7 +1890,7 @@
 #endif  // CONFIG_ENTROPY_STATS
                            tile_data->allow_update_cdf, mi_params,
 #if CONFIG_EXT_RECUR_PARTITIONS
-                           ptree, ptree_luma,
+                           disable_ext_part, ptree, ptree_luma,
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
                            partition, mi_row, mi_col, bsize, ctx);
 
@@ -2735,47 +2779,101 @@
   const bool limit_rect_split = is_middle_block &&
                                 is_bsize_geq(bsize, BLOCK_8X8) &&
                                 is_bsize_geq(BLOCK_64X64, bsize);
+  const int max_1dsize = AOMMAX(block_size_wide[bsize], block_size_high[bsize]);
+  const bool disable_ext_part =
+      (max_1dsize == 64 && cm->seq_params.disable_3way_part_64xn) ||
+      (max_1dsize == 32 && cm->seq_params.disable_3way_part_32xn) ||
+      (max_1dsize == 16 && cm->seq_params.disable_3way_part_16xn);
   const int pl = part_search_state->pl_ctx_idx;
   const int plane_index = xd->tree_type == CHROMA_PART;
   if (is_square_block(bsize)) {
-    if (limit_rect_split) {
-      const PARTITION_TYPE parent_part =
-          (pc_tree->parent->horizontal3[1] == pc_tree) ? PARTITION_HORZ_3
-                                                       : PARTITION_VERT_3;
-      const int dir = (parent_part == PARTITION_HORZ_3) ? 0 : 1;
-      for (PARTITION_TYPE p = PARTITION_NONE; p < EXT_PARTITION_TYPES; ++p) {
-        const int symbol = get_symbol_from_limited_partition(p, parent_part);
-        if (symbol == PARTITION_INVALID_REC) {
-          part_search_state->partition_cost_table[p] = INT_MAX;
-        } else {
-          part_search_state->partition_cost_table[p] =
-              mode_costs->limited_partition_cost[plane_index][dir][pl][symbol];
+    if (disable_ext_part) {
+      if (limit_rect_split) {
+        const PARTITION_TYPE parent_part =
+            (pc_tree->parent->horizontal3[1] == pc_tree) ? PARTITION_HORZ_3
+                                                         : PARTITION_VERT_3;
+        const int dir = (parent_part == PARTITION_HORZ_3) ? 0 : 1;
+        for (PARTITION_TYPE p = PARTITION_NONE; p < EXT_PARTITION_TYPES; ++p) {
+          const int symbol =
+              get_symbol_from_limited_partition_noext(p, parent_part);
+          if (symbol == PARTITION_INVALID_REC) {
+            part_search_state->partition_cost_table[p] = INT_MAX;
+          } else {
+            part_search_state->partition_cost_table[p] =
+                mode_costs->limited_partition_noext_cost[plane_index][dir][pl]
+                                                        [symbol];
+          }
+          part_search_state->partition_cost =
+              part_search_state->partition_cost_table;
         }
+      } else {
         part_search_state->partition_cost =
-            part_search_state->partition_cost_table;
+            mode_costs->partition_noext_cost[plane_index][pl];
       }
     } else {
-      part_search_state->partition_cost =
-          mode_costs->partition_cost[plane_index][pl];
+      if (limit_rect_split) {
+        const PARTITION_TYPE parent_part =
+            (pc_tree->parent->horizontal3[1] == pc_tree) ? PARTITION_HORZ_3
+                                                         : PARTITION_VERT_3;
+        const int dir = (parent_part == PARTITION_HORZ_3) ? 0 : 1;
+        for (PARTITION_TYPE p = PARTITION_NONE; p < EXT_PARTITION_TYPES; ++p) {
+          const int symbol = get_symbol_from_limited_partition(p, parent_part);
+          if (symbol == PARTITION_INVALID_REC) {
+            part_search_state->partition_cost_table[p] = INT_MAX;
+          } else {
+            part_search_state->partition_cost_table[p] =
+                mode_costs
+                    ->limited_partition_cost[plane_index][dir][pl][symbol];
+          }
+          part_search_state->partition_cost =
+              part_search_state->partition_cost_table;
+        }
+      } else {
+        part_search_state->partition_cost =
+            mode_costs->partition_cost[plane_index][pl];
+      }
     }
   } else {
     for (PARTITION_TYPE p = PARTITION_NONE; p < EXT_PARTITION_TYPES; ++p) {
-      PARTITION_TYPE_REC p_rec = get_symbol_from_partition_rec_block(bsize, p);
-      if (limit_rect_split) {
-        if ((pc_tree->parent->horizontal3[1] == pc_tree &&
-             p == PARTITION_HORZ) ||
-            (pc_tree->parent->vertical3[1] == pc_tree && p == PARTITION_VERT)) {
-          p_rec = PARTITION_INVALID_REC;
+      PARTITION_TYPE_REC p_rec = PARTITION_INVALID_REC;
+      if (disable_ext_part) {
+        if (limit_rect_split) {
+          const PARTITION_TYPE parent_part =
+              (pc_tree->parent->horizontal3[1] == pc_tree) ? PARTITION_HORZ_3
+                                                           : PARTITION_VERT_3;
+          p_rec = get_symbol_from_limited_partition_noext(p, parent_part);
+        } else {
+          p_rec = get_symbol_from_partition_noext_rec_block(bsize, p);
+        }
+      } else {
+        p_rec = get_symbol_from_partition_rec_block(bsize, p);
+        if (limit_rect_split) {
+          if ((pc_tree->parent->horizontal3[1] == pc_tree &&
+               p == PARTITION_HORZ) ||
+              (pc_tree->parent->vertical3[1] == pc_tree &&
+               p == PARTITION_VERT)) {
+            p_rec = PARTITION_INVALID_REC;
+          }
         }
       }
 
       if (p_rec != PARTITION_INVALID_REC) {
-        if (limit_rect_split) {
-          part_search_state->partition_cost_table[p] =
-              mode_costs->partition_middle_rec_cost[pl][p_rec];
+        if (disable_ext_part) {
+          if (limit_rect_split) {
+            part_search_state->partition_cost_table[p] =
+                mode_costs->partition_middle_noext_rec_cost[pl][p_rec];
+          } else {
+            part_search_state->partition_cost_table[p] =
+                mode_costs->partition_noext_rec_cost[pl][p_rec];
+          }
         } else {
-          part_search_state->partition_cost_table[p] =
-              mode_costs->partition_rec_cost[pl][p_rec];
+          if (limit_rect_split) {
+            part_search_state->partition_cost_table[p] =
+                mode_costs->partition_middle_rec_cost[pl][p_rec];
+          } else {
+            part_search_state->partition_cost_table[p] =
+                mode_costs->partition_rec_cost[pl][p_rec];
+          }
         }
       } else {
         part_search_state->partition_cost_table[p] = INT_MAX;
@@ -5074,9 +5172,13 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
   const int ext_partition_allowed = !is_partition_implied_at_boundary(
       &cm->mi_params, mi_row, mi_col, bsize, NULL);
-  const int partition_3_allowed = ext_partition_allowed &&
-                                  bsize != BLOCK_128X128 &&
-                                  max_recursion_depth > 0;
+  const int max_1dsize = AOMMAX(block_size_wide[bsize], block_size_high[bsize]);
+  const int partition_3_allowed =
+      ext_partition_allowed && bsize != BLOCK_128X128 &&
+      max_recursion_depth > 0 &&
+      IMPLIES(max_1dsize == 64, !cpi->oxcf.part_cfg.disable_3way_part_64xn) &&
+      IMPLIES(max_1dsize == 32, !cpi->oxcf.part_cfg.disable_3way_part_32xn) &&
+      IMPLIES(max_1dsize == 16, !cpi->oxcf.part_cfg.disable_3way_part_16xn);
   const int is_wide_block = block_size_wide[bsize] > block_size_high[bsize];
   const int is_tall_block = block_size_wide[bsize] < block_size_high[bsize];
   const PARTITION_SPEED_FEATURES *part_sf = &cpi->sf.part_sf;
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index 0e58a9f..e4407a8 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -100,12 +100,23 @@
     }
 #if CONFIG_EXT_RECUR_PARTITIONS
     for (i = 0; i < PARTITION_CONTEXTS; ++i) {
+      av1_cost_tokens_from_cdf(mode_costs->partition_noext_cost[plane_index][i],
+                               fc->partition_noext_cdf[plane_index][i], NULL);
+    }
+    for (i = 0; i < PARTITION_CONTEXTS; ++i) {
       for (int dir = 0; dir < NUM_LIMITED_PARTITION_PARENTS; dir++) {
         av1_cost_tokens_from_cdf(
             mode_costs->limited_partition_cost[plane_index][dir][i],
             fc->limited_partition_cdf[plane_index][dir][i], NULL);
       }
     }
+    for (i = 0; i < PARTITION_CONTEXTS; ++i) {
+      for (int dir = 0; dir < NUM_LIMITED_PARTITION_PARENTS; dir++) {
+        av1_cost_tokens_from_cdf(
+            mode_costs->limited_partition_noext_cost[plane_index][dir][i],
+            fc->limited_partition_noext_cdf[plane_index][dir][i], NULL);
+      }
+    }
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
   }
 
@@ -115,6 +126,10 @@
                              fc->partition_rec_cdf[i], NULL);
     av1_cost_tokens_from_cdf(mode_costs->partition_middle_rec_cost[i],
                              fc->partition_middle_rec_cdf[i], NULL);
+    av1_cost_tokens_from_cdf(mode_costs->partition_noext_rec_cost[i],
+                             fc->partition_noext_rec_cdf[i], NULL);
+    av1_cost_tokens_from_cdf(mode_costs->partition_middle_noext_rec_cost[i],
+                             fc->partition_middle_noext_rec_cdf[i], NULL);
   }
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
 
diff --git a/common/args.c b/common/args.c
index 65d13c7..abe43db 100644
--- a/common/args.c
+++ b/common/args.c
@@ -86,6 +86,9 @@
 #if CONFIG_EXT_RECUR_PARTITIONS
     GET_PARAMS(erp_pruning_level);
     GET_PARAMS(use_ml_erp_pruning);
+    GET_PARAMS(disable_3way_part_64xn);
+    GET_PARAMS(disable_3way_part_32xn);
+    GET_PARAMS(disable_3way_part_16xn);
 #endif  // CONFIG_EXT_RECUR_PARTITIONS
     GET_PARAMS(enable_sdp);
     GET_PARAMS(enable_mrls);