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);