Add unpoison_partition_ctx experiment
At the edges of the picture only a subset of partitions are legal. Add
new contexts for these borders so they don't distort the probabilities of
the interior of the image where all partitions are legal.
Only include one context for each block size of each border direction
because so few blocks fall into these contexts to begin with.
objective-1-fast:
PSNR | PSNR Cb | PSNR Cr | PSNR HVS | SSIM | MS SSIM | CIEDE 2000
-0.0294 | -0.0911 | -0.2382 | -0.0481 | -0.0441 | -0.0450 | -0.0454
derf144: -0.135
lowres: -0.124
midres: -0.076
hdres: -0.078
Change-Id: I909b98eebb7e49273cde90154c8408febe334158
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 34e9ad6..868ecc6 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -387,6 +387,22 @@
{ 58, 32, 12, 128, 128, 128, 128 }, // l split, a not split
{ 10, 7, 6, 128, 128, 128, 128 }, // a/l both split
#endif // CONFIG_EXT_PARTITION
+#if CONFIG_UNPOISON_PARTITION_CTX
+ { 0, 0, 141, 0, 0, 0, 0 }, // 8x8 -> 4x4
+ { 0, 0, 87, 0, 0, 0, 0 }, // 16x16 -> 8x8
+ { 0, 0, 59, 0, 0, 0, 0 }, // 32x32 -> 16x16
+ { 0, 0, 30, 0, 0, 0, 0 }, // 64x64 -> 32x32
+#if CONFIG_EXT_PARTITION
+ { 0, 0, 30, 0, 0, 0, 0 }, // 128x128 -> 64x64
+#endif // CONFIG_EXT_PARTITION
+ { 0, 122, 0, 0, 0, 0, 0 }, // 8x8 -> 4x4
+ { 0, 73, 0, 0, 0, 0, 0 }, // 16x16 -> 8x8
+ { 0, 58, 0, 0, 0, 0, 0 }, // 32x32 -> 16x16
+ { 0, 34, 0, 0, 0, 0, 0 }, // 64x64 -> 32x32
+#if CONFIG_EXT_PARTITION
+ { 0, 34, 0, 0, 0, 0, 0 }, // 128x128 -> 64x64
+#endif // CONFIG_EXT_PARTITION
+#endif // CONFIG_UNPOISON_PARTITION_CTX
};
#else
static const aom_prob
@@ -418,6 +434,22 @@
{ 58, 32, 12 }, // l split, a not split
{ 10, 7, 6 }, // a/l both split
#endif // CONFIG_EXT_PARTITION
+#if CONFIG_UNPOISON_PARTITION_CTX
+ { 0, 0, 141 }, // 8x8 -> 4x4
+ { 0, 0, 87 }, // 16x16 -> 8x8
+ { 0, 0, 59 }, // 32x32 -> 16x16
+ { 0, 0, 30 }, // 64x64 -> 32x32
+#if CONFIG_EXT_PARTITION
+ { 0, 0, 30 }, // 128x128 -> 64x64
+#endif // CONFIG_EXT_PARTITION
+ { 0, 122, 0 }, // 8x8 -> 4x4
+ { 0, 73, 0 }, // 16x16 -> 8x8
+ { 0, 58, 0 }, // 32x32 -> 16x16
+ { 0, 34, 0 }, // 64x64 -> 32x32
+#if CONFIG_EXT_PARTITION
+ { 0, 34, 0 }, // 128x128 -> 64x64
+#endif // CONFIG_EXT_PARTITION
+#endif // CONFIG_UNPOISON_PARTITION_CTX
};
#endif // CONFIG_EXT_PARTITION_TYPES
@@ -2039,15 +2071,39 @@
#if CONFIG_EXT_PARTITION_TYPES
aom_tree_merge_probs(av1_partition_tree, pre_fc->partition_prob[0],
counts->partition[0], fc->partition_prob[0]);
- for (i = 1; i < PARTITION_CONTEXTS; i++)
+ for (i = 1; i < PARTITION_CONTEXTS_PRIMARY; i++)
aom_tree_merge_probs(av1_ext_partition_tree, pre_fc->partition_prob[i],
counts->partition[i], fc->partition_prob[i]);
#else
- for (i = 0; i < PARTITION_CONTEXTS; i++) {
+ for (i = 0; i < PARTITION_CONTEXTS_PRIMARY; i++) {
aom_tree_merge_probs(av1_partition_tree, pre_fc->partition_prob[i],
counts->partition[i], fc->partition_prob[i]);
}
#endif // CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_UNPOISON_PARTITION_CTX
+ for (i = PARTITION_CONTEXTS_PRIMARY;
+ i < PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES; ++i) {
+ unsigned int ct[2] = { counts->partition[i][PARTITION_VERT],
+ counts->partition[i][PARTITION_SPLIT] };
+ assert(counts->partition[i][PARTITION_NONE] == 0);
+ assert(counts->partition[i][PARTITION_HORZ] == 0);
+ assert(fc->partition_prob[i][PARTITION_NONE] == 0);
+ assert(fc->partition_prob[i][PARTITION_HORZ] == 0);
+ fc->partition_prob[i][PARTITION_VERT] =
+ av1_mode_mv_merge_probs(pre_fc->partition_prob[i][PARTITION_VERT], ct);
+ }
+ for (i = PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES;
+ i < PARTITION_CONTEXTS_PRIMARY + 2 * PARTITION_BLOCK_SIZES; ++i) {
+ unsigned int ct[2] = { counts->partition[i][PARTITION_HORZ],
+ counts->partition[i][PARTITION_SPLIT] };
+ assert(counts->partition[i][PARTITION_NONE] == 0);
+ assert(counts->partition[i][PARTITION_VERT] == 0);
+ assert(fc->partition_prob[i][PARTITION_NONE] == 0);
+ assert(fc->partition_prob[i][PARTITION_VERT] == 0);
+ fc->partition_prob[i][PARTITION_HORZ] =
+ av1_mode_mv_merge_probs(pre_fc->partition_prob[i][PARTITION_HORZ], ct);
+ }
+#endif
#if CONFIG_DELTA_Q
for (i = 0; i < DELTA_Q_CONTEXTS; ++i)
fc->delta_q_prob[i] =
diff --git a/av1/common/enums.h b/av1/common/enums.h
index cf1ca8a..530e304 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -131,11 +131,14 @@
typedef char PARTITION_CONTEXT;
#define PARTITION_PLOFFSET 4 // number of probability models per block size
-#if CONFIG_EXT_PARTITION
-#define PARTITION_CONTEXTS (5 * PARTITION_PLOFFSET)
+#define PARTITION_BLOCK_SIZES (4 + CONFIG_EXT_PARTITION)
+#define PARTITION_CONTEXTS_PRIMARY (PARTITION_BLOCK_SIZES * PARTITION_PLOFFSET)
+#if CONFIG_UNPOISON_PARTITION_CTX
+#define PARTITION_CONTEXTS \
+ (PARTITION_CONTEXTS_PRIMARY + 2 * PARTITION_BLOCK_SIZES)
#else
-#define PARTITION_CONTEXTS (4 * PARTITION_PLOFFSET)
-#endif // CONFIG_EXT_PARTITION
+#define PARTITION_CONTEXTS PARTITION_CONTEXTS_PRIMARY
+#endif
// block transform size
typedef enum ATTRIBUTE_PACKED {
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index bb17c09..4315431 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -700,7 +700,31 @@
#endif // CONFIG_EXT_PARTITION_TYPES
static INLINE int partition_plane_context(const MACROBLOCKD *xd, int mi_row,
- int mi_col, BLOCK_SIZE bsize) {
+ int mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ int has_rows, int has_cols,
+#endif
+ BLOCK_SIZE bsize) {
+#if CONFIG_UNPOISON_PARTITION_CTX
+ const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col;
+ const PARTITION_CONTEXT *left_ctx =
+ xd->left_seg_context + (mi_row & MAX_MIB_MASK);
+ // Minimum partition point is 8x8. Offset the bsl accordingly.
+ const int bsl = mi_width_log2_lookup[bsize] - mi_width_log2_lookup[BLOCK_8X8];
+ int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1;
+
+ assert(b_width_log2_lookup[bsize] == b_height_log2_lookup[bsize]);
+ assert(bsl >= 0);
+
+ if (has_rows && has_cols)
+ return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
+ else if (has_rows && !has_cols)
+ return PARTITION_CONTEXTS_PRIMARY + bsl;
+ else if (!has_rows && has_cols)
+ return PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES + bsl;
+ else
+ return -1; // Bogus context, forced SPLIT
+#else
const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col;
const PARTITION_CONTEXT *left_ctx =
xd->left_seg_context + (mi_row & MAX_MIB_MASK);
@@ -712,6 +736,7 @@
assert(bsl >= 0);
return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
+#endif
}
static INLINE int max_block_wide(const MACROBLOCKD *xd, const BLOCK_SIZE bsize,
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 60b678e..48c0f5f 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1822,9 +1822,16 @@
int mi_row, int mi_col, aom_reader *r,
int has_rows, int has_cols,
BLOCK_SIZE bsize) {
+#if CONFIG_UNPOISON_PARTITION_CTX
+ const int ctx =
+ partition_plane_context(xd, mi_row, mi_col, has_rows, has_cols, bsize);
+ const aom_prob *const probs = ctx >= 0 ? cm->fc->partition_prob[ctx] : NULL;
+ FRAME_COUNTS *const counts = ctx >= 0 ? xd->counts : NULL;
+#else
const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
const aom_prob *const probs = cm->fc->partition_prob[ctx];
- FRAME_COUNTS *counts = xd->counts;
+ FRAME_COUNTS *const counts = xd->counts;
+#endif
PARTITION_TYPE p;
if (has_rows && has_cols)
@@ -4394,15 +4401,21 @@
#if CONFIG_EXT_PARTITION_TYPES
for (i = 0; i < PARTITION_TYPES - 1; ++i)
av1_diff_update_prob(&r, &fc->partition_prob[0][i], ACCT_STR);
- for (j = 1; j < PARTITION_CONTEXTS; ++j)
+ for (j = 1; j < PARTITION_CONTEXTS_PRIMARY; ++j)
for (i = 0; i < EXT_PARTITION_TYPES - 1; ++i)
av1_diff_update_prob(&r, &fc->partition_prob[j][i], ACCT_STR);
#else
- for (j = 0; j < PARTITION_CONTEXTS; ++j)
+ for (j = 0; j < PARTITION_CONTEXTS_PRIMARY; ++j)
for (i = 0; i < PARTITION_TYPES - 1; ++i)
av1_diff_update_prob(&r, &fc->partition_prob[j][i], ACCT_STR);
#endif // CONFIG_EXT_PARTITION_TYPES
-#endif // EC_ADAPT, DAALA_EC
+#if CONFIG_UNPOISON_PARTITION_CTX
+ for (; j < PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES; ++j)
+ av1_diff_update_prob(&r, &fc->partition_prob[j][PARTITION_VERT], ACCT_STR);
+ for (; j < PARTITION_CONTEXTS_PRIMARY + 2 * PARTITION_BLOCK_SIZES; ++j)
+ av1_diff_update_prob(&r, &fc->partition_prob[j][PARTITION_HORZ], ACCT_STR);
+#endif // CONFIG_UNPOISON_PARTITION_CTX
+#endif // CONFIG_EC_ADAPT
#if CONFIG_EXT_INTRA
#if CONFIG_INTRA_INTERP
for (i = 0; i < INTRA_FILTERS + 1; ++i)
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index ba8b1e8..d18c8ca 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2254,13 +2254,21 @@
const MACROBLOCKD *const xd, int hbs, int mi_row,
int mi_col, PARTITION_TYPE p, BLOCK_SIZE bsize,
aom_writer *w) {
- const int is_partition_point = bsize >= BLOCK_8X8;
- const int ctx = is_partition_point
- ? partition_plane_context(xd, mi_row, mi_col, bsize)
- : 0;
- const aom_prob *const probs = cm->fc->partition_prob[ctx];
const int has_rows = (mi_row + hbs) < cm->mi_rows;
const int has_cols = (mi_col + hbs) < cm->mi_cols;
+ const int is_partition_point = bsize >= BLOCK_8X8;
+ const int ctx = is_partition_point
+ ? partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ has_rows, has_cols,
+#endif
+ bsize)
+ : 0;
+#if CONFIG_UNPOISON_PARTITION_CTX
+ const aom_prob *const probs = ctx >= 0 ? cm->fc->partition_prob[ctx] : NULL;
+#else
+ const aom_prob *const probs = cm->fc->partition_prob[ctx];
+#endif
if (!is_partition_point) return;
@@ -4336,16 +4344,38 @@
#if CONFIG_EXT_PARTITION_TYPES
prob_diff_update(av1_partition_tree, fc->partition_prob[0],
counts->partition[0], PARTITION_TYPES, probwt, header_bc);
- for (i = 1; i < PARTITION_CONTEXTS; ++i)
+ for (i = 1; i < PARTITION_CONTEXTS_PRIMARY; ++i)
prob_diff_update(av1_ext_partition_tree, fc->partition_prob[i],
counts->partition[i], EXT_PARTITION_TYPES, probwt,
header_bc);
#else
- for (i = 0; i < PARTITION_CONTEXTS; ++i) {
+ for (i = 0; i < PARTITION_CONTEXTS_PRIMARY; ++i) {
prob_diff_update(av1_partition_tree, fc->partition_prob[i],
counts->partition[i], PARTITION_TYPES, probwt, header_bc);
}
-#endif // CONFIG_EC_ADAPT, CONFIG_DAALA_EC
+#endif // CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_UNPOISON_PARTITION_CTX
+ for (; i < PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES; ++i) {
+ unsigned int ct[2] = { counts->partition[i][PARTITION_VERT],
+ counts->partition[i][PARTITION_SPLIT] };
+ assert(counts->partition[i][PARTITION_NONE] == 0);
+ assert(counts->partition[i][PARTITION_HORZ] == 0);
+ assert(fc->partition_prob[i][PARTITION_NONE] == 0);
+ assert(fc->partition_prob[i][PARTITION_HORZ] == 0);
+ av1_cond_prob_diff_update(header_bc, &fc->partition_prob[i][PARTITION_VERT],
+ ct, probwt);
+ }
+ for (; i < PARTITION_CONTEXTS_PRIMARY + 2 * PARTITION_BLOCK_SIZES; ++i) {
+ unsigned int ct[2] = { counts->partition[i][PARTITION_HORZ],
+ counts->partition[i][PARTITION_SPLIT] };
+ assert(counts->partition[i][PARTITION_NONE] == 0);
+ assert(counts->partition[i][PARTITION_VERT] == 0);
+ assert(fc->partition_prob[i][PARTITION_NONE] == 0);
+ assert(fc->partition_prob[i][PARTITION_VERT] == 0);
+ av1_cond_prob_diff_update(header_bc, &fc->partition_prob[i][PARTITION_HORZ],
+ ct, probwt);
+ }
+#endif
#if CONFIG_EXT_INTRA
#if CONFIG_INTRA_INTERP
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 196bcaf..69b1a02 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -2265,11 +2265,16 @@
const AV1_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
+ const int hbs = mi_size_wide[bsize] / 2;
const int is_partition_root = bsize >= BLOCK_8X8;
const int ctx = is_partition_root
- ? partition_plane_context(xd, mi_row, mi_col, bsize)
- : 0;
- const int hbs = mi_size_wide[bsize] / 2;
+ ? partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ mi_row + hbs < cm->mi_rows,
+ mi_col + hbs < cm->mi_cols,
+#endif
+ bsize)
+ : -1;
const PARTITION_TYPE partition = pc_tree->partitioning;
const BLOCK_SIZE subsize = get_subsize(bsize, partition);
#if CONFIG_EXT_PARTITION_TYPES
@@ -2285,7 +2290,7 @@
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
- if (!dry_run && is_partition_root) td->counts->partition[ctx][partition]++;
+ if (!dry_run && ctx >= 0) td->counts->partition[ctx][partition]++;
#if CONFIG_SUPERTX
if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
@@ -2562,7 +2567,12 @@
const int bs = mi_size_wide[bsize];
const int hbs = bs / 2;
int i;
- const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
+ const int pl = partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ mi_row + hbs < cm->mi_rows,
+ mi_col + hbs < cm->mi_cols,
+#endif
+ bsize);
const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
const BLOCK_SIZE subsize = get_subsize(bsize, partition);
RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
@@ -2638,11 +2648,14 @@
bsize, ctx_none, INT64_MAX);
if (none_rdc.rate < INT_MAX) {
- none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ none_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_NONE];
none_rdc.rdcost =
RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
#if CONFIG_SUPERTX
- none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
+ none_rate_nocoef +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_NONE];
#endif
}
@@ -2816,11 +2829,13 @@
}
if (last_part_rdc.rate < INT_MAX) {
- last_part_rdc.rate += cpi->partition_cost[pl][partition];
+ last_part_rdc.rate +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
last_part_rdc.rdcost =
RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
#if CONFIG_SUPERTX
- last_part_rate_nocoef += cpi->partition_cost[pl][partition];
+ last_part_rate_nocoef +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
#endif
}
@@ -2895,17 +2910,23 @@
encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
- chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ chosen_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_NONE];
#if CONFIG_SUPERTX
- chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
+ chosen_rate_nocoef +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_SPLIT];
#endif
}
if (chosen_rdc.rate < INT_MAX) {
- chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
+ chosen_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_SPLIT];
chosen_rdc.rdcost =
RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
#if CONFIG_SUPERTX
- chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
+ chosen_rate_nocoef +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_NONE];
#endif
}
}
@@ -3422,12 +3443,18 @@
#endif // CONFIG_SUPERTX
if (sum_rdc.rdcost < best_rdc->rdcost) {
- int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- sum_rdc.rate += cpi->partition_cost[pl][partition];
+ int pl = partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ has_rows, has_cols,
+#endif
+ bsize);
+ sum_rdc.rate +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
sum_rdc.rdcost =
RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
#if CONFIG_SUPERTX
- sum_rate_nocoef += cpi->partition_cost[pl][partition];
+ sum_rate_nocoef +=
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
#endif
if (sum_rdc.rdcost < best_rdc->rdcost) {
#if CONFIG_SUPERTX
@@ -3462,23 +3489,36 @@
RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
const TOKENEXTRA *const tp_orig = *tp;
PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
-
+#if CONFIG_UNPOISON_PARTITION_CTX
+ const int hbs = mi_size_wide[bsize] / 2;
+ const int has_rows = mi_row + hbs < cm->mi_rows;
+ const int has_cols = mi_col + hbs < cm->mi_cols;
+#else
int tmp_partition_cost[PARTITION_TYPES];
+#endif
BLOCK_SIZE subsize;
RD_COST this_rdc, sum_rdc, best_rdc;
const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
int do_square_split = bsize_at_least_8x8;
-
#if CONFIG_CB4X4
const int unify_bsize = 1;
const int pl = bsize_at_least_8x8
- ? partition_plane_context(xd, mi_row, mi_col, bsize)
- : 0;
+ ? partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ has_rows, has_cols,
+#endif
+ bsize)
+ : -1;
#else
const int unify_bsize = 0;
- const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
+ const int pl = partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ has_rows, has_cols,
+#endif
+ bsize);
#endif // CONFIG_CB4X4
- const int *partition_cost = cpi->partition_cost[pl];
+ const int *partition_cost =
+ cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX];
#if CONFIG_SUPERTX
int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
int abort_flag;
@@ -3518,6 +3558,7 @@
(void)*tp_orig;
+#if !CONFIG_UNPOISON_PARTITION_CTX
if (force_horz_split || force_vert_split) {
tmp_partition_cost[PARTITION_NONE] = INT_MAX;
@@ -3541,6 +3582,7 @@
partition_cost = tmp_partition_cost;
}
+#endif
#if CONFIG_VAR_TX
#ifndef NDEBUG
@@ -5975,11 +6017,16 @@
const AV1_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
+ const int hbs = mi_size_wide[bsize] / 2;
const int is_partition_root = bsize >= BLOCK_8X8;
const int ctx = is_partition_root
- ? partition_plane_context(xd, mi_row, mi_col, bsize)
- : 0;
- const int hbs = mi_size_wide[bsize] / 2;
+ ? partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ mi_row + hbs < cm->mi_rows,
+ mi_col + hbs < cm->mi_cols,
+#endif
+ bsize)
+ : -1;
const PARTITION_TYPE partition = pc_tree->partitioning;
const BLOCK_SIZE subsize = get_subsize(bsize, partition);
#if CONFIG_EXT_PARTITION_TYPES
@@ -6030,7 +6077,7 @@
}
#endif // CONFIG_AOM_HIGHBITDEPTH
- if (!dry_run && is_partition_root && bsize < top_bsize) {
+ if (!dry_run && ctx >= 0 && bsize < top_bsize) {
// Explicitly cast away const.
FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
frame_counts->partition[ctx][partition]++;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index f1d06b9..dce432b 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -549,9 +549,11 @@
int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
#if CONFIG_EXT_PARTITION_TYPES
- int partition_cost[PARTITION_CONTEXTS][EXT_PARTITION_TYPES];
+ int partition_cost[PARTITION_CONTEXTS + CONFIG_UNPOISON_PARTITION_CTX]
+ [EXT_PARTITION_TYPES];
#else
- int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES];
+ int partition_cost[PARTITION_CONTEXTS + CONFIG_UNPOISON_PARTITION_CTX]
+ [PARTITION_TYPES];
#endif
#if CONFIG_PALETTE
int palette_y_size_cost[PALETTE_BLOCK_SIZES][PALETTE_SIZES];
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index 5771946..e40c422 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -398,17 +398,41 @@
if (cpi->sf.partition_search_type != VAR_BASED_PARTITION ||
cm->frame_type == KEY_FRAME) {
+#if CONFIG_UNPOISON_PARTITION_CTX
+ cpi->partition_cost[0][PARTITION_NONE] = INT_MAX;
+ cpi->partition_cost[0][PARTITION_HORZ] = INT_MAX;
+ cpi->partition_cost[0][PARTITION_VERT] = INT_MAX;
+ cpi->partition_cost[0][PARTITION_SPLIT] = 0;
+#endif
#if CONFIG_EXT_PARTITION_TYPES
- av1_cost_tokens(cpi->partition_cost[0], cm->fc->partition_prob[0],
- av1_partition_tree);
- for (i = 1; i < PARTITION_CONTEXTS; ++i)
- av1_cost_tokens(cpi->partition_cost[i], cm->fc->partition_prob[i],
- av1_ext_partition_tree);
+ av1_cost_tokens(cpi->partition_cost[CONFIG_UNPOISON_PARTITION_CTX],
+ cm->fc->partition_prob[0], av1_partition_tree);
+ for (i = 1; i < PARTITION_CONTEXTS_PRIMARY; ++i)
+ av1_cost_tokens(cpi->partition_cost[CONFIG_UNPOISON_PARTITION_CTX + i],
+ cm->fc->partition_prob[i], av1_ext_partition_tree);
#else
- for (i = 0; i < PARTITION_CONTEXTS; ++i)
- av1_cost_tokens(cpi->partition_cost[i], cm->fc->partition_prob[i],
- av1_partition_tree);
+ for (i = 0; i < PARTITION_CONTEXTS_PRIMARY; ++i)
+ av1_cost_tokens(cpi->partition_cost[CONFIG_UNPOISON_PARTITION_CTX + i],
+ cm->fc->partition_prob[i], av1_partition_tree);
#endif // CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_UNPOISON_PARTITION_CTX
+ for (; i < PARTITION_CONTEXTS_PRIMARY + PARTITION_BLOCK_SIZES; ++i) {
+ aom_prob p = cm->fc->partition_prob[i][PARTITION_VERT];
+ assert(p > 0);
+ cpi->partition_cost[1 + i][PARTITION_NONE] = INT_MAX;
+ cpi->partition_cost[1 + i][PARTITION_HORZ] = INT_MAX;
+ cpi->partition_cost[1 + i][PARTITION_VERT] = av1_cost_bit(p, 0);
+ cpi->partition_cost[1 + i][PARTITION_SPLIT] = av1_cost_bit(p, 1);
+ }
+ for (; i < PARTITION_CONTEXTS_PRIMARY + 2 * PARTITION_BLOCK_SIZES; ++i) {
+ aom_prob p = cm->fc->partition_prob[i][PARTITION_HORZ];
+ assert(p > 0);
+ cpi->partition_cost[1 + i][PARTITION_NONE] = INT_MAX;
+ cpi->partition_cost[1 + i][PARTITION_HORZ] = av1_cost_bit(p, 0);
+ cpi->partition_cost[1 + i][PARTITION_VERT] = INT_MAX;
+ cpi->partition_cost[1 + i][PARTITION_SPLIT] = av1_cost_bit(p, 1);
+ }
+#endif
}
fill_mode_costs(cpi);
diff --git a/configure b/configure
index bf62a8c..41a984a 100755
--- a/configure
+++ b/configure
@@ -271,6 +271,7 @@
loop_restoration
ext_partition
ext_partition_types
+ unpoison_partition_ctx
ext_tile
motion_var
ncobmc