Commit 3dd33911 authored by Rupert Swarbrick's avatar Rupert Swarbrick Committed by Debargha Mukherjee

Add a new layout for HORZ/VERT_A/B partitions

This hides behind --enable-ext_partition_types_ab. When that flag is
set, the mixed partitions change from

   +-+-+---+          +-+-+---+
   |   |   |          | | |   |
   |---+   |    to    | | |   |
   |   |   |          | | |   |
   +-+-+---+          +-+-+---+

(that's PARTITION_VERT_A; other partitions change similarly).

Since 128x32 and 32x128 block support hasn't yet been merged, this
patch also temporarily disables these partitions for 128x128 blocks.

Change-Id: Ic479c0fc129f590b8ad56d72dc98ba79ae1bd1cf
parent 6905dc79
......@@ -371,9 +371,10 @@ static int has_top_right(const AV1_COMMON *cm, const MACROBLOCKD *xd,
if (xd->n8_w > xd->n8_h)
if (xd->is_sec_rect) has_tr = 0;
#if CONFIG_EXT_PARTITION_TYPES
// The bottom left square of a Vertical A does not have a top right as it is
// decoded before the right hand rectangle of the partition
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
// The bottom left square of a Vertical A (in the old format) does
// not have a top right as it is decoded before the right hand
// rectangle of the partition
if (xd->mi[0]->mbmi.partition == PARTITION_VERT_A)
if ((mask_row & bs) && !(mask_col & bs)) has_tr = 0;
#endif // CONFIG_EXT_PARTITION_TYPES
......
......@@ -974,8 +974,10 @@ static INLINE void update_ext_partition_context(MACROBLOCKD *xd, int mi_row,
BLOCK_SIZE bsize,
PARTITION_TYPE partition) {
if (bsize >= BLOCK_8X8) {
#if !CONFIG_EXT_PARTITION_TYPES_AB
const int hbs = mi_size_wide[bsize] / 2;
BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
switch (partition) {
case PARTITION_SPLIT:
if (bsize != BLOCK_8X8) break;
......@@ -986,6 +988,30 @@ static INLINE void update_ext_partition_context(MACROBLOCKD *xd, int mi_row,
case PARTITION_VERT_4:
update_partition_context(xd, mi_row, mi_col, subsize, bsize);
break;
#if CONFIG_EXT_PARTITION_TYPES_AB
case PARTITION_HORZ_A:
update_partition_context(xd, mi_row, mi_col,
get_subsize(bsize, PARTITION_HORZ_4), subsize);
update_partition_context(xd, mi_row + mi_size_high[bsize] / 2, mi_col,
subsize, subsize);
break;
case PARTITION_HORZ_B:
update_partition_context(xd, mi_row, mi_col, subsize, subsize);
update_partition_context(xd, mi_row + mi_size_high[bsize] / 2, mi_col,
get_subsize(bsize, PARTITION_HORZ_4), subsize);
break;
case PARTITION_VERT_A:
update_partition_context(xd, mi_row, mi_col,
get_subsize(bsize, PARTITION_VERT_4), subsize);
update_partition_context(xd, mi_row, mi_col + mi_size_wide[bsize] / 2,
subsize, subsize);
break;
case PARTITION_VERT_B:
update_partition_context(xd, mi_row, mi_col, subsize, subsize);
update_partition_context(xd, mi_row, mi_col + mi_size_wide[bsize] / 2,
get_subsize(bsize, PARTITION_VERT_4), subsize);
break;
#else
case PARTITION_HORZ_A:
update_partition_context(xd, mi_row, mi_col, bsize2, subsize);
update_partition_context(xd, mi_row + hbs, mi_col, subsize, subsize);
......@@ -1002,6 +1028,7 @@ static INLINE void update_ext_partition_context(MACROBLOCKD *xd, int mi_row,
update_partition_context(xd, mi_row, mi_col, subsize, subsize);
update_partition_context(xd, mi_row, mi_col + hbs, bsize2, subsize);
break;
#endif
default: assert(0 && "Invalid partition type");
}
}
......@@ -1228,6 +1255,16 @@ static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
const MB_MODE_INFO *const mbmi_below = &mi[bhigh / 2 * cm->mi_stride]->mbmi;
if (sswide == bwide) {
#if CONFIG_EXT_PARTITION_TYPES_AB
// Smaller height but same width. Is PARTITION_HORZ, PARTITION_HORZ_4,
// PARTITION_HORZ_A or PARTITION_HORZ_B.
if (sshigh * 2 == bhigh)
return (mbmi_below->sb_type == subsize) ? PARTITION_HORZ
: PARTITION_HORZ_B;
assert(sshigh * 4 == bhigh);
return (mbmi_below->sb_type == subsize) ? PARTITION_HORZ_4
: PARTITION_HORZ_A;
#else
// Smaller height but same width. Is PARTITION_HORZ_4, PARTITION_HORZ or
// PARTITION_HORZ_B. To distinguish the latter two, check if the lower
// half was split.
......@@ -1238,7 +1275,18 @@ static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
return PARTITION_HORZ;
else
return PARTITION_HORZ_B;
#endif
} else if (sshigh == bhigh) {
#if CONFIG_EXT_PARTITION_TYPES_AB
// Smaller width but same height. Is PARTITION_VERT, PARTITION_VERT_4,
// PARTITION_VERT_A or PARTITION_VERT_B.
if (sswide * 2 == bwide)
return (mbmi_right->sb_type == subsize) ? PARTITION_VERT
: PARTITION_VERT_B;
assert(sswide * 4 == bwide);
return (mbmi_right->sb_type == subsize) ? PARTITION_VERT_4
: PARTITION_VERT_A;
#else
// Smaller width but same height. Is PARTITION_VERT_4, PARTITION_VERT or
// PARTITION_VERT_B. To distinguish the latter two, check if the right
// half was split.
......@@ -1249,7 +1297,9 @@ static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
return PARTITION_VERT;
else
return PARTITION_VERT_B;
#endif
} else {
#if !CONFIG_EXT_PARTITION_TYPES_AB
// Smaller width and smaller height. Might be PARTITION_SPLIT or could be
// PARTITION_HORZ_A or PARTITION_VERT_A. If subsize isn't halved in both
// dimensions, we immediately know this is a split (which will recurse to
......@@ -1261,6 +1311,7 @@ static INLINE PARTITION_TYPE get_partition(const AV1_COMMON *const cm,
if (mi_size_wide[mbmi_below->sb_type] == bwide) return PARTITION_HORZ_A;
if (mi_size_high[mbmi_right->sb_type] == bhigh) return PARTITION_VERT_A;
#endif
return PARTITION_SPLIT;
}
......
......@@ -435,7 +435,7 @@ static const uint16_t *const orders[BLOCK_SIZES_ALL] = {
/* clang-format on */
#endif // CONFIG_EXT_PARTITION
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
static const uint16_t orders_verta_64x64[4] = {
0, 2, 1, 2,
};
......@@ -525,9 +525,9 @@ static const uint16_t *const orders_verta[BLOCK_SIZES] = {
static int has_top_right(const AV1_COMMON *cm, BLOCK_SIZE bsize, int mi_row,
int mi_col, int top_available, int right_available,
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
PARTITION_TYPE partition,
#endif
#endif // CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
TX_SIZE txsz, int row_off, int col_off, int ss_x) {
if (!top_available || !right_available) return 0;
......@@ -578,7 +578,7 @@ static int has_top_right(const AV1_COMMON *cm, BLOCK_SIZE bsize, int mi_row,
// General case (neither top row nor rightmost column): check if the
// top-right block is coded before the current block.
const uint16_t *const order =
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
(partition == PARTITION_VERT_A) ? orders_verta[bsize] :
#endif // CONFIG_EXT_PARTITION_TYPES
orders[bsize];
......@@ -2969,7 +2969,7 @@ static void predict_intra_block_helper(const AV1_COMMON *cm,
(MI_SIZE_LOG2 - tx_size_wide_log2[0])) <
xd->tile.mi_col_end;
const int bottom_available = (yd > 0);
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
const PARTITION_TYPE partition = xd->mi[0]->mbmi.partition;
#endif
......@@ -2980,9 +2980,9 @@ static void predict_intra_block_helper(const AV1_COMMON *cm,
const int have_top_right =
has_top_right(cm, bsize, mi_row, mi_col, have_top, right_available,
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
partition,
#endif
#endif // CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
tx_size, row_off, col_off, pd->subsampling_x);
const int have_bottom_left =
has_bottom_left(cm, bsize, mi_row, mi_col, bottom_available, have_left,
......
......@@ -1409,6 +1409,9 @@ static void dec_predict_sb_complex(AV1Decoder *const pbi, MACROBLOCKD *const xd,
}
break;
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES_AB
#error HORZ/VERT_A/B partitions not yet updated in superres code
#endif
case PARTITION_HORZ_A:
dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
mi_row_top, mi_col_top, dst_buf, dst_stride,
......@@ -2173,6 +2176,9 @@ static void detoken_and_recon_sb(AV1Decoder *const pbi, MACROBLOCKD *const xd,
detoken_and_recon_sb(pbi, xd, mi_row + hbs, mi_col + hbs, r, subsize);
break;
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES_AB
#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
#endif
case PARTITION_HORZ_A:
decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize2);
decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, bsize2);
......@@ -2306,6 +2312,9 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
AV1_COMMON *const cm = &pbi->common;
const int num_8x8_wh = mi_size_wide[bsize];
const int hbs = num_8x8_wh >> 1;
#if CONFIG_EXT_PARTITION_TYPES && CONFIG_EXT_PARTITION_TYPES_AB
const int qbs = num_8x8_wh >> 2;
#endif
#if CONFIG_CB4X4
const int unify_bsize = 1;
#else
......@@ -2314,9 +2323,11 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
#if CONFIG_EXT_PARTITION_TYPES
BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
const int quarter_step = num_8x8_wh / 4;
int i;
#if !CONFIG_EXT_PARTITION_TYPES_AB
BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
#endif
const int has_rows = (mi_row + hbs) < cm->mi_rows;
const int has_cols = (mi_col + hbs) < cm->mi_cols;
......@@ -2392,6 +2403,32 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
DEC_PARTITION(mi_row + hbs, mi_col + hbs, subsize);
break;
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES_AB
case PARTITION_HORZ_A:
DEC_BLOCK(mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
DEC_BLOCK(mi_row + qbs, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
DEC_BLOCK(mi_row + hbs, mi_col, subsize);
break;
case PARTITION_HORZ_B:
DEC_BLOCK(mi_row, mi_col, subsize);
DEC_BLOCK(mi_row + hbs, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
if (mi_row + 3 * qbs < cm->mi_rows)
DEC_BLOCK(mi_row + 3 * qbs, mi_col,
get_subsize(bsize, PARTITION_HORZ_4));
break;
case PARTITION_VERT_A:
DEC_BLOCK(mi_row, mi_col, get_subsize(bsize, PARTITION_VERT_4));
DEC_BLOCK(mi_row, mi_col + qbs, get_subsize(bsize, PARTITION_VERT_4));
DEC_BLOCK(mi_row, mi_col + hbs, subsize);
break;
case PARTITION_VERT_B:
DEC_BLOCK(mi_row, mi_col, subsize);
DEC_BLOCK(mi_row, mi_col + hbs, get_subsize(bsize, PARTITION_VERT_4));
if (mi_col + 3 * qbs < cm->mi_cols)
DEC_BLOCK(mi_row, mi_col + 3 * qbs,
get_subsize(bsize, PARTITION_VERT_4));
break;
#else
case PARTITION_HORZ_A:
DEC_BLOCK(mi_row, mi_col, bsize2);
DEC_BLOCK(mi_row, mi_col + hbs, bsize2);
......@@ -2412,6 +2449,7 @@ static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
DEC_BLOCK(mi_row, mi_col + hbs, bsize2);
DEC_BLOCK(mi_row + hbs, mi_col + hbs, bsize2);
break;
#endif
case PARTITION_HORZ_4:
for (i = 0; i < 4; ++i) {
int this_mi_row = mi_row + i * quarter_step;
......
......@@ -2781,6 +2781,9 @@ static void write_tokens_sb(AV1_COMP *cpi, const TileInfo *const tile,
subsize);
break;
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES_AB
#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
#endif
case PARTITION_HORZ_A:
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col);
write_tokens_b(cpi, tile, w, tok, tok_end, mi_row, mi_col + hbs);
......@@ -2902,7 +2905,10 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
#if CONFIG_EXT_PARTITION_TYPES
const int quarter_step = mi_size_wide[bsize] / 4;
int i;
#endif
#if CONFIG_EXT_PARTITION_TYPES_AB
const int qbs = mi_size_wide[bsize] / 4;
#endif // CONFIG_EXT_PARTITION_TYPES_AB
#endif // CONFIG_EXT_PARTITION_TYPES
const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
const BLOCK_SIZE subsize = get_subsize(bsize, partition);
#if CONFIG_CB4X4
......@@ -2976,6 +2982,42 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
mi_row + hbs, mi_col + hbs, subsize);
break;
#if CONFIG_EXT_PARTITION_TYPES
#if CONFIG_EXT_PARTITION_TYPES_AB
case PARTITION_HORZ_A:
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col);
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row + qbs, mi_col);
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row + hbs, mi_col);
break;
case PARTITION_HORZ_B:
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col);
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row + hbs, mi_col);
if (mi_row + 3 * qbs < cm->mi_rows)
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row + 3 * qbs, mi_col);
break;
case PARTITION_VERT_A:
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col);
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col + qbs);
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col + hbs);
break;
case PARTITION_VERT_B:
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col);
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col + hbs);
if (mi_col + 3 * qbs < cm->mi_cols)
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col + 3 * qbs);
break;
#else
case PARTITION_HORZ_A:
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row, mi_col);
......@@ -3008,6 +3050,7 @@ static void write_modes_sb(AV1_COMP *const cpi, const TileInfo *const tile,
write_modes_b_wrapper(cpi, tile, w, tok, tok_end, supertx_enabled,
mi_row + hbs, mi_col + hbs);
break;
#endif
case PARTITION_HORZ_4:
for (i = 0; i < 4; ++i) {
int this_mi_row = mi_row + i * quarter_step;
......
This diff is collapsed.
......@@ -167,6 +167,9 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
const int bs = mi_size_wide[bsize], hbs = bs / 2;
#if CONFIG_EXT_PARTITION_TYPES
PARTITION_TYPE partition;
#if CONFIG_EXT_PARTITION_TYPES_AB
const int qbs = bs / 4;
#endif // CONFIG_EXT_PARTITION_TYPES_AB
#else
int bw, bh;
#endif // CONFIG_EXT_PARTITION_TYPES
......@@ -193,6 +196,28 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
CSEGS(hbs, bs, 0, 0);
CSEGS(hbs, bs, 0, hbs);
break;
#if CONFIG_EXT_PARTITION_TYPES_AB
case PARTITION_HORZ_A:
CSEGS(bs, qbs, 0, 0);
CSEGS(bs, qbs, qbs, 0);
CSEGS(bs, hbs, hbs, 0);
break;
case PARTITION_HORZ_B:
CSEGS(bs, hbs, 0, 0);
CSEGS(bs, qbs, hbs, 0);
if (mi_row + 3 * qbs < cm->mi_rows) CSEGS(bs, qbs, 3 * qbs, 0);
break;
case PARTITION_VERT_A:
CSEGS(qbs, bs, 0, 0);
CSEGS(qbs, bs, 0, qbs);
CSEGS(hbs, bs, 0, hbs);
break;
case PARTITION_VERT_B:
CSEGS(hbs, bs, 0, 0);
CSEGS(qbs, bs, 0, hbs);
if (mi_col + 3 * qbs < cm->mi_cols) CSEGS(qbs, bs, 0, 3 * qbs);
break;
#else
case PARTITION_HORZ_A:
CSEGS(hbs, hbs, 0, 0);
CSEGS(hbs, hbs, 0, hbs);
......@@ -213,6 +238,7 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
CSEGS(hbs, hbs, 0, hbs);
CSEGS(hbs, hbs, hbs, hbs);
break;
#endif
case PARTITION_SPLIT: {
const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize];
int n;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment