From 5cce322a09a27e994f0d76d981e427388a23c181 Mon Sep 17 00:00:00 2001 From: Julia Robson Date: Thu, 17 Mar 2016 16:50:28 +0000 Subject: [PATCH] Porting ext_partition experiment from nextgen This has been ported under ext_partition_types because it is due to be combined with the coding_unit_size experiment which is already being ported under ext_partition Change-Id: I47af869ae123ddf0aa99160dac644059d14266ee --- vp10/common/blockd.h | 34 ++ vp10/common/common_data.h | 61 +++ vp10/common/entropymode.c | 46 +++ vp10/common/entropymode.h | 12 + vp10/common/enums.h | 18 +- vp10/common/loopfilter.c | 8 +- vp10/common/mvref_common.c | 20 + vp10/common/onyxc_int.h | 48 +++ vp10/common/reconintra.c | 47 ++- vp10/common/thread_common.c | 15 +- vp10/decoder/decodeframe.c | 418 +++++++++++++++++++- vp10/encoder/bitstream.c | 99 +++++ vp10/encoder/context_tree.c | 71 +++- vp10/encoder/context_tree.h | 15 + vp10/encoder/encodeframe.c | 754 +++++++++++++++++++++++++++++++++++- vp10/encoder/encodemv.c | 12 +- vp10/encoder/encoder.h | 4 + vp10/encoder/rd.c | 8 + vp10/encoder/segmentation.c | 98 ++++- 19 files changed, 1759 insertions(+), 29 deletions(-) diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h index 50b69811a..de91431ca 100644 --- a/vp10/common/blockd.h +++ b/vp10/common/blockd.h @@ -212,6 +212,9 @@ typedef struct { #if CONFIG_REF_MV uint8_t ref_mv_idx; #endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition; +#endif } MB_MODE_INFO; typedef struct MODE_INFO { @@ -356,6 +359,37 @@ static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, return subsize_lookup[partition][bsize]; } +#if CONFIG_EXT_PARTITION_TYPES +static INLINE PARTITION_TYPE get_partition(const MODE_INFO *const mi, + int mi_stride, int mi_rows, + int mi_cols, int mi_row, + int mi_col, BLOCK_SIZE bsize) { + const int bsl = b_width_log2_lookup[bsize]; + const int bs = (1 << bsl) / 4; + MODE_INFO m = mi[mi_row * mi_stride + mi_col]; + PARTITION_TYPE partition = partition_lookup[bsl][m.mbmi.sb_type]; + if (partition != PARTITION_NONE && bsize > BLOCK_8X8 && + mi_row + bs < mi_rows && mi_col + bs < mi_cols) { + BLOCK_SIZE h = get_subsize(bsize, PARTITION_HORZ_A); + BLOCK_SIZE v = get_subsize(bsize, PARTITION_VERT_A); + MODE_INFO m_right = mi[mi_row * mi_stride + mi_col + bs]; + MODE_INFO m_below = mi[(mi_row + bs) * mi_stride + mi_col]; + if (m.mbmi.sb_type == h) { + return m_below.mbmi.sb_type == h ? PARTITION_HORZ : PARTITION_HORZ_B; + } else if (m.mbmi.sb_type == v) { + return m_right.mbmi.sb_type == v ? PARTITION_VERT : PARTITION_VERT_B; + } else if (m_below.mbmi.sb_type == h) { + return PARTITION_HORZ_A; + } else if (m_right.mbmi.sb_type == v) { + return PARTITION_VERT_A; + } else { + return PARTITION_SPLIT; + } + } + return partition; +} +#endif // CONFIG_EXT_PARTITION_TYPES + static const TX_TYPE intra_mode_to_tx_type_context[INTRA_MODES] = { DCT_DCT, // DC ADST_DCT, // V diff --git a/vp10/common/common_data.h b/vp10/common/common_data.h index 84476fa0a..67d6e3a81 100644 --- a/vp10/common/common_data.h +++ b/vp10/common/common_data.h @@ -80,6 +80,59 @@ static const PARTITION_TYPE partition_lookup[][BLOCK_SIZES] = { } }; +#if CONFIG_EXT_PARTITION_TYPES +static const BLOCK_SIZE subsize_lookup[EXT_PARTITION_TYPES][BLOCK_SIZES] = { + { // PARTITION_NONE + BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, + BLOCK_8X8, BLOCK_8X16, BLOCK_16X8, + BLOCK_16X16, BLOCK_16X32, BLOCK_32X16, + BLOCK_32X32, BLOCK_32X64, BLOCK_64X32, + BLOCK_64X64, + }, { // PARTITION_HORZ + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X4, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_64X32, + }, { // PARTITION_VERT + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_4X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X32, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X64, + }, { // PARTITION_SPLIT + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_4X4, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X32, + }, { // PARTITION_HORZ_A + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X4, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_64X32, + }, { // PARTITION_HORZ_B + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X4, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_64X32, + }, { // PARTITION_VERT_A + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_4X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X32, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X64, + }, { // PARTITION_VERT_B + BLOCK_INVALID, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_4X8, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_8X16, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_16X32, BLOCK_INVALID, BLOCK_INVALID, + BLOCK_32X64, + } +}; +#else static const BLOCK_SIZE subsize_lookup[PARTITION_TYPES][BLOCK_SIZES] = { { // PARTITION_NONE BLOCK_4X4, BLOCK_4X8, BLOCK_8X4, @@ -107,6 +160,7 @@ static const BLOCK_SIZE subsize_lookup[PARTITION_TYPES][BLOCK_SIZES] = { BLOCK_32X32, } }; +#endif // CONFIG_EXT_PARTITION_TYPES static const TX_SIZE max_txsize_lookup[BLOCK_SIZES] = { TX_4X4, TX_4X4, TX_4X4, @@ -180,9 +234,16 @@ static const TX_SIZE uvsupertx_size_lookup[TX_SIZES][2][2] = { {{TX_32X32, TX_16X16}, {TX_16X16, TX_16X16}}, }; +#if CONFIG_EXT_PARTITION_TYPES +static const int partition_supertx_context_lookup[EXT_PARTITION_TYPES] = { + -1, 0, 0, 1, 0, 0, 0, 0 +}; + +#else static const int partition_supertx_context_lookup[PARTITION_TYPES] = { -1, 0, 0, 1 }; +#endif // CONFIG_EXT_PARTITION_TYPES #endif // CONFIG_SUPERTX #ifdef __cplusplus diff --git a/vp10/common/entropymode.c b/vp10/common/entropymode.c index 8afcbb8cb..7dc91b697 100644 --- a/vp10/common/entropymode.c +++ b/vp10/common/entropymode.c @@ -148,6 +148,31 @@ static const vpx_prob default_uv_probs[INTRA_MODES][INTRA_MODES - 1] = { { 101, 21, 107, 181, 192, 103, 19, 67, 125 } // y = tm }; +#if CONFIG_EXT_PARTITION_TYPES +static const vpx_prob default_partition_probs[PARTITION_CONTEXTS] + [EXT_PARTITION_TYPES - 1] = { + // 8x8 -> 4x4 + { 199, 122, 141, 128, 128, 128, 128 }, // a/l both not split + { 147, 63, 159, 128, 128, 128, 128 }, // a split, l not split + { 148, 133, 118, 128, 128, 128, 128 }, // l split, a not split + { 121, 104, 114, 128, 128, 128, 128 }, // a/l both split + // 16x16 -> 8x8 + { 174, 73, 87, 128, 128, 128, 128 }, // a/l both not split + { 92, 41, 83, 128, 128, 128, 128 }, // a split, l not split + { 82, 99, 50, 128, 128, 128, 128 }, // l split, a not split + { 53, 39, 39, 128, 128, 128, 128 }, // a/l both split + // 32x32 -> 16x16 + { 177, 58, 59, 128, 128, 128, 128 }, // a/l both not split + { 68, 26, 63, 128, 128, 128, 128 }, // a split, l not split + { 52, 79, 25, 128, 128, 128, 128 }, // l split, a not split + { 17, 14, 12, 128, 128, 128, 128 }, // a/l both split + // 64x64 -> 32x32 + { 222, 34, 30, 128, 128, 128, 128 }, // a/l both not split + { 72, 16, 44, 128, 128, 128, 128 }, // a split, l not split + { 58, 32, 12, 128, 128, 128, 128 }, // l split, a not split + { 10, 7, 6, 128, 128, 128, 128 }, // a/l both split +}; +#else static const vpx_prob default_partition_probs[PARTITION_CONTEXTS] [PARTITION_TYPES - 1] = { // 8x8 -> 4x4 @@ -171,6 +196,7 @@ static const vpx_prob default_partition_probs[PARTITION_CONTEXTS] { 58, 32, 12 }, // l split, a not split { 10, 7, 6 }, // a/l both split }; +#endif // CONFIG_EXT_PARTITION_TYPES #if CONFIG_REF_MV static const vpx_prob default_newmv_prob[NEWMV_MODE_CONTEXTS] = { @@ -292,6 +318,18 @@ const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)] = { -PARTITION_VERT, -PARTITION_SPLIT }; +#if CONFIG_EXT_PARTITION_TYPES +const vpx_tree_index vp10_ext_partition_tree[TREE_SIZE(EXT_PARTITION_TYPES)] = { + -PARTITION_NONE, 2, + 6, 4, + 8, -PARTITION_SPLIT, + -PARTITION_HORZ, 10, + -PARTITION_VERT, 12, + -PARTITION_HORZ_A, -PARTITION_HORZ_B, + -PARTITION_VERT_A, -PARTITION_VERT_B +}; +#endif // CONFIG_EXT_PARTITION_TYPES + static const vpx_prob default_intra_inter_p[INTRA_INTER_CONTEXTS] = { 9, 102, 187, 225 }; @@ -1354,9 +1392,17 @@ void vp10_adapt_intra_frame_probs(VP10_COMMON *cm) { vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->uv_mode_prob[i], counts->uv_mode[i], fc->uv_mode_prob[i]); +#if CONFIG_EXT_PARTITION_TYPES + vpx_tree_merge_probs(vp10_partition_tree, pre_fc->partition_prob[0], + counts->partition[0], fc->partition_prob[0]); + for (i = 1; i < PARTITION_CONTEXTS; i++) + vpx_tree_merge_probs(vp10_ext_partition_tree, pre_fc->partition_prob[i], + counts->partition[i], fc->partition_prob[i]); +#else for (i = 0; i < PARTITION_CONTEXTS; i++) vpx_tree_merge_probs(vp10_partition_tree, pre_fc->partition_prob[i], counts->partition[i], fc->partition_prob[i]); +#endif // CONFIG_EXT_PARTITION_TYPES #if CONFIG_EXT_INTRA for (i = 0; i < PLANE_TYPES; ++i) { diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h index 2443d60f8..3fc0bb080 100644 --- a/vp10/common/entropymode.h +++ b/vp10/common/entropymode.h @@ -46,7 +46,11 @@ struct seg_counts { typedef struct frame_contexts { vpx_prob y_mode_prob[BLOCK_SIZE_GROUPS][INTRA_MODES - 1]; vpx_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; +#if CONFIG_EXT_PARTITION_TYPES + vpx_prob partition_prob[PARTITION_CONTEXTS][EXT_PARTITION_TYPES - 1]; +#else vpx_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1]; +#endif vp10_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES]; vpx_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS] [SWITCHABLE_FILTERS - 1]; @@ -111,7 +115,11 @@ typedef struct FRAME_COUNTS { unsigned int kf_y_mode[INTRA_MODES][INTRA_MODES][INTRA_MODES]; unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES]; unsigned int uv_mode[INTRA_MODES][INTRA_MODES]; +#if CONFIG_EXT_PARTITION_TYPES + unsigned int partition[PARTITION_CONTEXTS][EXT_PARTITION_TYPES]; +#else unsigned int partition[PARTITION_CONTEXTS][PARTITION_TYPES]; +#endif vp10_coeff_count_model coef[TX_SIZES][PLANE_TYPES]; unsigned int eob_branch[TX_SIZES][PLANE_TYPES][REF_TYPES] [COEF_BANDS][COEFF_CONTEXTS]; @@ -193,6 +201,10 @@ extern const vpx_tree_index vp10_inter_compound_mode_tree [TREE_SIZE(INTER_COMPOUND_MODES)]; #endif // CONFIG_EXT_INTER extern const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)]; +#if CONFIG_EXT_PARTITION_TYPES +extern const vpx_tree_index vp10_ext_partition_tree + [TREE_SIZE(EXT_PARTITION_TYPES)]; +#endif extern const vpx_tree_index vp10_switchable_interp_tree [TREE_SIZE(SWITCHABLE_FILTERS)]; extern const vpx_tree_index vp10_palette_size_tree[TREE_SIZE(PALETTE_SIZES)]; diff --git a/vp10/common/enums.h b/vp10/common/enums.h index 4a0e243ac..ee61020f5 100644 --- a/vp10/common/enums.h +++ b/vp10/common/enums.h @@ -69,6 +69,21 @@ typedef enum BITSTREAM_PROFILE { typedef uint8_t BLOCK_SIZE; +#if CONFIG_EXT_PARTITION_TYPES +typedef enum PARTITION_TYPE { + PARTITION_NONE, + PARTITION_HORZ, + PARTITION_VERT, + PARTITION_SPLIT, + PARTITION_HORZ_A, // HORZ split and the left partition is split again + PARTITION_HORZ_B, // HORZ split and the right partition is split again + PARTITION_VERT_A, // VERT split and the top partition is split again + PARTITION_VERT_B, // VERT split and the bottom partition is split again + EXT_PARTITION_TYPES, + PARTITION_TYPES = PARTITION_SPLIT + 1, + PARTITION_INVALID = EXT_PARTITION_TYPES +} PARTITION_TYPE; +#else typedef enum PARTITION_TYPE { PARTITION_NONE, PARTITION_HORZ, @@ -77,10 +92,11 @@ typedef enum PARTITION_TYPE { PARTITION_TYPES, PARTITION_INVALID = PARTITION_TYPES } PARTITION_TYPE; +#endif // CONFIG_EXT_PARTITION_TYPES typedef char PARTITION_CONTEXT; #define PARTITION_PLOFFSET 4 // number of probability models per block size -#define PARTITION_CONTEXTS (4 * PARTITION_PLOFFSET) +#define PARTITION_CONTEXTS (4 * PARTITION_PLOFFSET) // block transform size typedef uint8_t TX_SIZE; diff --git a/vp10/common/loopfilter.c b/vp10/common/loopfilter.c index c4fdd2aad..25941d02b 100644 --- a/vp10/common/loopfilter.c +++ b/vp10/common/loopfilter.c @@ -1634,7 +1634,7 @@ void vp10_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, int start, int stop, int y_only) { const int num_planes = y_only ? 1 : MAX_MB_PLANE; int mi_row, mi_col; -#if !CONFIG_VAR_TX +#if !CONFIG_VAR_TX && !CONFIG_EXT_PARTITION_TYPES enum lf_path path; LOOP_FILTER_MASK lfm; @@ -1646,7 +1646,7 @@ void vp10_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, path = LF_PATH_444; else path = LF_PATH_SLOW; -#endif +#endif // !CONFIG_VAR_TX && !CONFIG_EXT_PARTITION_TYPES #if CONFIG_VAR_TX memset(cm->above_txfm_context, TX_SIZES, cm->mi_cols); @@ -1661,7 +1661,7 @@ void vp10_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, vp10_setup_dst_planes(planes, frame_buffer, mi_row, mi_col); -#if CONFIG_VAR_TX +#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION_TYPES for (plane = 0; plane < num_planes; ++plane) vp10_filter_block_plane_non420(cm, &planes[plane], mi + mi_col, mi_row, mi_col); @@ -1684,7 +1684,7 @@ void vp10_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, break; } } -#endif +#endif // CONFIG_VAR_TX || CONFIG_EXT_PARTITION_TYPES } } } diff --git a/vp10/common/mvref_common.c b/vp10/common/mvref_common.c index c67beed62..19a188119 100644 --- a/vp10/common/mvref_common.c +++ b/vp10/common/mvref_common.c @@ -246,31 +246,51 @@ static uint8_t scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, return newmv_count; } +// This function assumes MI blocks are 8x8 and coding units are 64x64 static int has_top_right(const MACROBLOCKD *xd, int mi_row, int mi_col, int bs) { + // In a split partition all apart from the bottom right has a top right int has_tr = !((mi_row & bs) & (bs * 2 - 1)) || !((mi_col & bs) & (bs * 2 - 1)); // Filter out partial right-most boundaries + // For each 4x4 group of blocks, when the bottom right is decoded the blocks + // to the right have not been decoded therefore the second from bottom in the + // right-most column does not have a top right if ((mi_col & bs) & (bs * 2 - 1)) { if (((mi_col & (2 * bs)) & (bs * 4 - 1)) && ((mi_row & (2 * bs)) & (bs * 4 - 1))) has_tr = 0; } + // If the right had side of the block lines up with the right had edge end of + // a group of 8x8 MI blocks (i.e. edge of a coding unit) and is not on the top + // row of that coding unit, it does not have a top right if (has_tr) if (((mi_col + xd->n8_w) & 0x07) == 0) if ((mi_row & 0x07) > 0) has_tr = 0; + // The left had of two vertical rectangles always has a top right (as the + // block above will have been decoded) if (xd->n8_w < xd->n8_h) if (!xd->is_sec_rect) has_tr = 1; + // The bottom of two horizontal rectangles never has a top right (as the block + // to the right won't have been decoded) 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 (xd->mi[0]->mbmi.partition == PARTITION_VERT_A) + if ((mi_row & bs) && !(mi_col & bs)) + has_tr = 0; +#endif // CONFIG_EXT_PARTITION_TYPES + return has_tr; } diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h index 26ae569f0..2dd09b574 100644 --- a/vp10/common/onyxc_int.h +++ b/vp10/common/onyxc_int.h @@ -499,6 +499,12 @@ static INLINE void update_partition_context(MACROBLOCKD *xd, PARTITION_CONTEXT *const above_ctx = xd->above_seg_context + mi_col; PARTITION_CONTEXT *const left_ctx = xd->left_seg_context + (mi_row & MI_MASK); +#if CONFIG_EXT_PARTITION_TYPES + const int bw = num_8x8_blocks_wide_lookup[bsize]; + const int bh = num_8x8_blocks_high_lookup[bsize]; + memset(above_ctx, partition_context_lookup[subsize].above, bw); + memset(left_ctx, partition_context_lookup[subsize].left, bh); +#else // num_4x4_blocks_wide_lookup[bsize] / 2 const int bs = num_8x8_blocks_wide_lookup[bsize]; @@ -507,7 +513,49 @@ static INLINE void update_partition_context(MACROBLOCKD *xd, // bits of smaller block sizes to be zero. memset(above_ctx, partition_context_lookup[subsize].above, bs); memset(left_ctx, partition_context_lookup[subsize].left, bs); +#endif // CONFIG_EXT_PARTITION_TYPES +} + +#if CONFIG_EXT_PARTITION_TYPES +static INLINE void update_ext_partition_context(MACROBLOCKD *xd, + int mi_row, int mi_col, + BLOCK_SIZE subsize, + BLOCK_SIZE bsize, + PARTITION_TYPE partition) { + if (bsize >= BLOCK_8X8) { + const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); + switch (partition) { + case PARTITION_SPLIT: + if (bsize != BLOCK_8X8) + break; + case PARTITION_NONE: + case PARTITION_HORZ: + case PARTITION_VERT: + update_partition_context(xd, mi_row, mi_col, subsize, bsize); + break; + 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); + break; + case PARTITION_HORZ_B: + update_partition_context(xd, mi_row, mi_col, subsize, subsize); + update_partition_context(xd, mi_row + hbs, mi_col, bsize2, subsize); + break; + case PARTITION_VERT_A: + update_partition_context(xd, mi_row, mi_col, bsize2, subsize); + update_partition_context(xd, mi_row, mi_col + hbs, 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 + hbs, bsize2, subsize); + break; + default: + assert(0 && "Invalid partition type"); + } + } } +#endif // CONFIG_EXT_PARTITION_TYPES static INLINE int partition_plane_context(const MACROBLOCKD *xd, int mi_row, int mi_col, diff --git a/vp10/common/reconintra.c b/vp10/common/reconintra.c index e28f01cb7..10a66f830 100644 --- a/vp10/common/reconintra.c +++ b/vp10/common/reconintra.c @@ -99,9 +99,40 @@ static const uint8_t *const orders[BLOCK_SIZES] = { orders_16x32, orders_32x16, orders_32x32, orders_32x64, orders_64x32, orders_64x64, }; +#if CONFIG_EXT_PARTITION_TYPES +static const uint8_t orders_verta_32x32[4] = { + 0, 2, + 1, 2, +}; +static const uint8_t orders_verta_16x16[16] = { + 0, 2, 4, 6, + 1, 2, 5, 6, + 8, 10, 12, 14, + 9, 10, 13, 14, +}; +static const uint8_t orders_verta_8x8[64] = { + 0, 2, 4, 6, 16, 18, 20, 22, + 1, 2, 5, 6, 17, 18, 21, 22, + 8, 10, 12, 14, 24, 26, 28, 30, + 9, 10, 13, 14, 25, 26, 29, 30, + 32, 34, 36, 38, 48, 50, 52, 54, + 33, 34, 37, 38, 49, 50, 53, 54, + 40, 42, 44, 46, 56, 58, 60, 62, + 41, 42, 45, 46, 57, 58, 61, 62, +}; +static const uint8_t *const orders_verta[BLOCK_SIZES] = { + orders_verta_8x8, orders_verta_8x8, orders_verta_8x8, orders_verta_8x8, + orders_8x16, orders_16x8, orders_verta_16x16, + orders_16x32, orders_32x16, orders_verta_32x32, + orders_32x64, orders_64x32, orders_64x64, +}; +#endif // CONFIG_EXT_PARTITION_TYPES static int vp10_has_right(BLOCK_SIZE bsize, int mi_row, int mi_col, int right_available, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition, +#endif TX_SIZE txsz, int y, int x, int ss_x) { const int wl = mi_width_log2_lookup[bsize]; const int w = VPXMAX(num_4x4_blocks_wide_lookup[bsize] >> ss_x, 1); @@ -113,8 +144,14 @@ static int vp10_has_right(BLOCK_SIZE bsize, int mi_row, int mi_col, if (y == 0) { const int hl = mi_height_log2_lookup[bsize]; - const uint8_t *order = orders[bsize]; + const uint8_t *order; int my_order, tr_order; +#if CONFIG_EXT_PARTITION_TYPES + if (partition == PARTITION_VERT_A) + order = orders_verta[bsize]; + else +#endif // CONFIG_EXT_PARTITION_TYPES + order = orders[bsize]; if (x + step < w) return 1; @@ -122,9 +159,11 @@ static int vp10_has_right(BLOCK_SIZE bsize, int mi_row, int mi_col, mi_row = (mi_row & 7) >> hl; mi_col = (mi_col & 7) >> wl; + // If top row of coding unit if (mi_row == 0) return right_available; + // If rightmost column of coding unit if (((mi_col + 1) << wl) >= 8) return 0; @@ -1346,8 +1385,14 @@ void vp10_predict_intra_block(const MACROBLOCKD *xd, int bwl_in, int bhl_in, const struct macroblockd_plane *const pd = &xd->plane[plane]; const int right_available = mi_col + (1 << mi_width_log2_lookup[bsize]) < xd->tile.mi_col_end; +#if CONFIG_EXT_PARTITION_TYPES + const PARTITION_TYPE partition = xd->mi[0]->mbmi.partition; +#endif const int have_right = vp10_has_right(bsize, mi_row, mi_col, right_available, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif tx_size, row_off, col_off, pd->subsampling_x); const int have_bottom = vp10_has_bottom(bsize, mi_row, mi_col, diff --git a/vp10/common/thread_common.c b/vp10/common/thread_common.c index f8bfc899f..23e8045db 100644 --- a/vp10/common/thread_common.c +++ b/vp10/common/thread_common.c @@ -96,7 +96,9 @@ void thread_loop_filter_rows(const YV12_BUFFER_CONFIG *const frame_buffer, const int num_planes = y_only ? 1 : MAX_MB_PLANE; const int sb_cols = mi_cols_aligned_to_sb(cm->mi_cols) >> MI_BLOCK_SIZE_LOG2; int mi_row, mi_col; +#if !CONFIG_EXT_PARTITION_TYPES enum lf_path path; + LOOP_FILTER_MASK lfm; if (y_only) path = LF_PATH_444; else if (planes[1].subsampling_y == 1 && planes[1].subsampling_x == 1) @@ -105,6 +107,7 @@ void thread_loop_filter_rows(const YV12_BUFFER_CONFIG *const frame_buffer, path = LF_PATH_444; else path = LF_PATH_SLOW; +#endif // !CONFIG_EXT_PARTITION_TYPES for (mi_row = start; mi_row < stop; mi_row += lf_sync->num_workers * MI_BLOCK_SIZE) { @@ -113,13 +116,17 @@ void thread_loop_filter_rows(const YV12_BUFFER_CONFIG *const frame_buffer, for (mi_col = 0; mi_col < cm->mi_cols; mi_col += MI_BLOCK_SIZE) { const int r = mi_row >> MI_BLOCK_SIZE_LOG2; const int c = mi_col >> MI_BLOCK_SIZE_LOG2; - LOOP_FILTER_MASK lfm; int plane; sync_read(lf_sync, r, c); vp10_setup_dst_planes(planes, frame_buffer, mi_row, mi_col); +#if CONFIG_EXT_PARTITION_TYPES + for (plane = 0; plane < num_planes; ++plane) + vp10_filter_block_plane_non420(cm, &planes[plane], mi + mi_col, + mi_row, mi_col); +#else // TODO(JBB): Make setup_mask work for non 420. vp10_setup_mask(cm, mi_row, mi_col, mi + mi_col, cm->mi_stride, &lfm); @@ -139,7 +146,7 @@ void thread_loop_filter_rows(const YV12_BUFFER_CONFIG *const frame_buffer, break; } } - +#endif // CONFIG_EXT_PARTITION_TYPES sync_write(lf_sync, r, c, sb_cols); } } @@ -331,7 +338,11 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts, cm->counts.uv_mode[i][j] += counts->uv_mode[i][j]; for (i = 0; i < PARTITION_CONTEXTS; i++) +#if CONFIG_EXT_PARTITION_TYPES + for (j = 0; j < (i ? EXT_PARTITION_TYPES : PARTITION_TYPES); j++) +#else for (j = 0; j < PARTITION_TYPES; j++) +#endif cm->counts.partition[i][j] += counts->partition[i][j]; if (is_dec) { diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index 6aa52544f..3426c4a23 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -1529,8 +1529,13 @@ static void dec_predict_sb_complex(VP10Decoder *const pbi, const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; PARTITION_TYPE partition; BLOCK_SIZE subsize; +#if !CONFIG_EXT_PARTITION_TYPES MB_MODE_INFO *mbmi; +#endif int i, offset = mi_row * cm->mi_stride + mi_col; +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); +#endif uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3]; DECLARE_ALIGNED(16, uint8_t, @@ -1575,8 +1580,13 @@ static void dec_predict_sb_complex(VP10Decoder *const pbi, xd->mi = cm->mi_grid_visible + offset; xd->mi[0] = cm->mi + offset; +#if CONFIG_EXT_PARTITION_TYPES + partition = get_partition(cm->mi, cm->mi_stride, cm->mi_rows, cm->mi_cols, + mi_row, mi_col, bsize); +#else mbmi = &xd->mi[0]->mbmi; partition = partition_lookup[bsl][mbmi->sb_type]; +#endif subsize = get_subsize(bsize, partition); for (i = 0; i < MAX_MB_PLANE; i++) { @@ -1822,6 +1832,204 @@ static void dec_predict_sb_complex(VP10Decoder *const pbi, } } break; +#if CONFIG_EXT_PARTITION_TYPES + 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, + top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row, + mi_col + hbs, mi_row_top, mi_col_top, + dst_buf1, dst_stride1, top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs, + mi_row_top, mi_col_top, dst_buf1, dst_stride1); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, + mi_row + hbs, mi_col, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, top_bsize, subsize, 0, 0); + if (bsize < top_bsize) + dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, + mi_row + hbs, mi_col, mi_row_top, mi_col_top, + dst_buf2, dst_stride2); + else + dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, + mi_row + hbs, mi_col, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, 1); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + break; + case PARTITION_VERT_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, + top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, + mi_row + hbs, mi_col, mi_row_top, mi_col_top, + dst_buf1, dst_stride1, top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col, + mi_row_top, mi_col_top, dst_buf1, dst_stride1); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, + mi_row, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, + top_bsize, subsize, 0, 0); + if (bsize < top_bsize) + dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, + mi_row, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2); + else + dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, + mi_row, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, 2); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + break; + case PARTITION_HORZ_B: + 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, + top_bsize, subsize, 0, 0); + if (bsize < top_bsize) + dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride); + else + dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride, 0); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, mi_row + hbs, + mi_col, mi_row_top, mi_col_top, + dst_buf1, dst_stride1, top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col, + mi_row_top, mi_col_top, dst_buf1, dst_stride1); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col + hbs, + mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, + mi_row + hbs, mi_col + hbs, + mi_row_top, mi_col_top, dst_buf2, dst_stride2); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf1[i]; + xd->plane[i].dst.stride = dst_stride1[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf1[i], dst_stride1[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + break; + case PARTITION_VERT_B: + 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, + top_bsize, subsize, 0, 0); + if (bsize < top_bsize) + dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride); + else + dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride, 3); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, + mi_row, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf1, dst_stride1, top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs, + mi_row_top, mi_col_top, dst_buf1, dst_stride1); + + dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col + hbs, + mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, top_bsize, bsize2, 0, 0); + dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, + mi_row + hbs, mi_col + hbs, + mi_row_top, mi_col_top, dst_buf2, dst_stride2); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf1[i]; + xd->plane[i].dst.stride = dst_stride1[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf1[i], dst_stride1[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } @@ -1837,6 +2045,9 @@ static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS struct AnsDecoder *const tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition, +#endif // CONFIG_EXT_PARTITION_TYPES BLOCK_SIZE bsize, int bwl, int bhl) { VP10_COMMON *const cm = &pbi->common; @@ -1855,11 +2066,17 @@ static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd, mbmi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis, bwl, bhl); } +#if CONFIG_EXT_PARTITION_TYPES + xd->mi[0]->mbmi.partition = partition; +#endif vp10_read_mode_info(pbi, xd, supertx_enabled, mi_row, mi_col, r, x_mis, y_mis); #else MB_MODE_INFO *mbmi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis, bwl, bhl); +#if CONFIG_EXT_PARTITION_TYPES + xd->mi[0]->mbmi.partition = partition; +#endif vp10_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis); #endif // CONFIG_SUPERTX @@ -1899,6 +2116,9 @@ static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd, (xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); + if (plane <= 1 && mbmi->palette_mode_info.palette_size[plane]) + vp10_decode_palette_tokens(xd, plane, r); + for (row = 0; row < max_blocks_high; row += step) for (col = 0; col < max_blocks_wide; col += step) predict_and_reconstruct_intra_block(xd, @@ -2041,6 +2261,7 @@ static INLINE int dec_partition_plane_context(const MACROBLOCKD *xd, return (left * 2 + above) + bsl * PARTITION_PLOFFSET; } +#if !CONFIG_EXT_PARTITION_TYPES static INLINE void dec_update_partition_context(MACROBLOCKD *xd, int mi_row, int mi_col, BLOCK_SIZE subsize, @@ -2054,17 +2275,29 @@ static INLINE void dec_update_partition_context(MACROBLOCKD *xd, memset(above_ctx, partition_context_lookup[subsize].above, bw); memset(left_ctx, partition_context_lookup[subsize].left, bw); } +#endif // !CONFIG_EXT_PARTITION_TYPES static PARTITION_TYPE read_partition(VP10_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col, vpx_reader *r, - int has_rows, int has_cols, int bsl) { + int has_rows, int has_cols, +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize, +#endif + int bsl) { const int ctx = dec_partition_plane_context(xd, mi_row, mi_col, bsl); const vpx_prob *const probs = cm->fc->partition_prob[ctx]; FRAME_COUNTS *counts = xd->counts; PARTITION_TYPE p; if (has_rows && has_cols) +#if CONFIG_EXT_PARTITION_TYPES + if (bsize <= BLOCK_8X8) + p = (PARTITION_TYPE)vpx_read_tree(r, vp10_partition_tree, probs); + else + p = (PARTITION_TYPE)vpx_read_tree(r, vp10_ext_partition_tree, probs); +#else p = (PARTITION_TYPE)vpx_read_tree(r, vp10_partition_tree, probs); +#endif // CONFIG_EXT_PARTITION_TYPES else if (!has_rows && has_cols) p = vpx_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ; else if (has_rows && !has_cols) @@ -2107,6 +2340,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, const int hbs = num_8x8_wh >> 1; PARTITION_TYPE partition; BLOCK_SIZE subsize; +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); +#endif const int has_rows = (mi_row + hbs) < cm->mi_rows; const int has_cols = (mi_col + hbs) < cm->mi_cols; #if CONFIG_SUPERTX @@ -2121,6 +2357,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, return; partition = read_partition(cm, xd, mi_row, mi_col, r, has_rows, has_cols, +#if CONFIG_EXT_PARTITION_TYPES + bsize, +#endif n8x8_l2); subsize = subsize_lookup[partition][bsize]; // get_subsize(bsize, partition); #if CONFIG_SUPERTX @@ -2185,6 +2424,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif // CONFIG_EXT_PARTITION_TYPES subsize, 1, 1); } else { switch (partition) { @@ -2197,6 +2439,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif // CONFIG_EXT_PARTITION_TYPES subsize, n4x4_l2, n4x4_l2); break; case PARTITION_HORZ: @@ -2208,6 +2453,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif // CONFIG_EXT_PARTITION_TYPES subsize, n4x4_l2, n8x8_l2); if (has_rows) decode_block(pbi, xd, @@ -2218,6 +2466,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif // CONFIG_EXT_PARTITION_TYPES subsize, n4x4_l2, n8x8_l2); break; case PARTITION_VERT: @@ -2229,6 +2480,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif // CONFIG_EXT_PARTITION_TYPES subsize, n8x8_l2, n4x4_l2); if (has_cols) decode_block(pbi, xd, @@ -2239,6 +2493,9 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #if CONFIG_ANS tok, #endif // CONFIG_ANS +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif // CONFIG_EXT_PARTITION_TYPES subsize, n8x8_l2, n4x4_l2); break; case PARTITION_SPLIT: @@ -2279,6 +2536,124 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, #endif // CONFIG_ANS subsize, n8x8_l2); break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col + hbs, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + hbs, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, subsize, n4x4_l2, n8x8_l2); + break; + case PARTITION_HORZ_B: + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, subsize, n4x4_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + hbs, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + hbs, mi_col + hbs, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + break; + case PARTITION_VERT_A: + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + hbs, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col + hbs, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, subsize, n8x8_l2, n4x4_l2); + break; + case PARTITION_VERT_B: + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, subsize, n8x8_l2, n4x4_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col + hbs, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + decode_block(pbi, xd, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + hbs, mi_col + hbs, r, +#if CONFIG_ANS + tok, +#endif // CONFIG_ANS + partition, bsize2, n8x8_l2, n8x8_l2); + break; +#endif default: assert(0 && "Invalid partition type"); } @@ -2336,10 +2711,43 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, } #endif // CONFIG_SUPERTX +#if CONFIG_EXT_PARTITION_TYPES + if (bsize >= BLOCK_8X8) { + switch (partition) { + case PARTITION_SPLIT: + if (bsize > BLOCK_8X8) + break; + case PARTITION_NONE: + case PARTITION_HORZ: + case PARTITION_VERT: + update_partition_context(xd, mi_row, mi_col, subsize, bsize); + break; + 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); + break; + case PARTITION_HORZ_B: + update_partition_context(xd, mi_row, mi_col, subsize, subsize); + update_partition_context(xd, mi_row + hbs, mi_col, bsize2, subsize); + break; + case PARTITION_VERT_A: + update_partition_context(xd, mi_row, mi_col, bsize2, subsize); + update_partition_context(xd, mi_row, mi_col + hbs, 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 + hbs, bsize2, subsize); + break; + default: + assert(0 && "Invalid partition type"); + } + } +#else // update partition context if (bsize >= BLOCK_8X8 && (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT)) dec_update_partition_context(xd, mi_row, mi_col, subsize, num_8x8_wh); +#endif // CONFIG_EXT_PARTITION_TYPES } static void setup_bool_decoder(const uint8_t *data, @@ -3594,9 +4002,17 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data, for (i = 0; i < INTRA_MODES - 1; ++i) vp10_diff_update_prob(&r, &fc->uv_mode_prob[j][i]); +#if CONFIG_EXT_PARTITION_TYPES + for (i = 0; i < PARTITION_TYPES - 1; ++i) + vp10_diff_update_prob(&r, &fc->partition_prob[0][i]); + for (j = 1; j < PARTITION_CONTEXTS; ++j) + for (i = 0; i < EXT_PARTITION_TYPES - 1; ++i) + vp10_diff_update_prob(&r, &fc->partition_prob[j][i]); +#else for (j = 0; j < PARTITION_CONTEXTS; ++j) for (i = 0; i < PARTITION_TYPES - 1; ++i) vp10_diff_update_prob(&r, &fc->partition_prob[j][i]); +#endif // CONFIG_EXT_PARTITION_TYPES #if CONFIG_EXT_INTRA for (i = 0; i < INTRA_FILTERS + 1; ++i) diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 5ae69cf79..fad893085 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -50,6 +50,10 @@ static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] = static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] = {{0, 1}, {2, 2}, {3, 2}}; #endif // CONFIG_EXT_INTERP && SWITCHABLE_FILTERS == 4 +#if CONFIG_EXT_PARTITION_TYPES +static const struct vp10_token ext_partition_encodings[EXT_PARTITION_TYPES] = + {{0, 1}, {4, 3}, {12, 4}, {7, 3}, {10, 4}, {11, 4}, {26, 5}, {27, 5}}; +#endif static const struct vp10_token partition_encodings[PARTITION_TYPES] = {{0, 1}, {2, 2}, {6, 3}, {7, 3}}; #if !CONFIG_REF_MV @@ -1583,7 +1587,15 @@ static void write_partition(const VP10_COMMON *const cm, const int has_cols = (mi_col + hbs) < cm->mi_cols; if (has_rows && has_cols) { +#if CONFIG_EXT_PARTITION_TYPES + if (bsize <= BLOCK_8X8) + vp10_write_token(w, vp10_partition_tree, probs, &partition_encodings[p]); + else + vp10_write_token(w, vp10_ext_partition_tree, probs, + &ext_partition_encodings[p]); +#else vp10_write_token(w, vp10_partition_tree, probs, &partition_encodings[p]); +#endif // CONFIG_EXT_PARTITION_TYPES } else if (!has_rows && has_cols) { assert(p == PARTITION_SPLIT || p == PARTITION_HORZ); vpx_write(w, p == PARTITION_SPLIT, probs[1]); @@ -1625,6 +1637,10 @@ static void write_modes_sb(VP10_COMP *cpi, const TileInfo *const tile, m = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]; partition = partition_lookup[bsl][m->mbmi.sb_type]; +#if CONFIG_EXT_PARTITION_TYPES + partition = get_partition(cm->mi, cm->mi_stride, cm->mi_rows, cm->mi_cols, + mi_row, mi_col, bsize); +#endif write_partition(cm, xd, bs, mi_row, mi_col, partition, bsize, w); subsize = get_subsize(bsize, partition); #if CONFIG_SUPERTX @@ -1770,6 +1786,76 @@ static void write_modes_sb(VP10_COMP *cpi, const TileInfo *const tile, #endif // CONFIG_SUPERTX mi_row + bs, mi_col + bs, subsize); break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col + bs); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + bs, mi_col); + break; + case PARTITION_HORZ_B: + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + bs, mi_col); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + bs, mi_col + bs); + break; + case PARTITION_VERT_A: + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + bs, mi_col); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col + bs); + break; + case PARTITION_VERT_B: + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row, mi_col + bs); + write_modes_b(cpi, tile, w, tok, tok_end, +#if CONFIG_SUPERTX + supertx_enabled, +#endif + mi_row + bs, mi_col + bs); + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } @@ -1803,9 +1889,13 @@ static void write_modes_sb(VP10_COMP *cpi, const TileInfo *const tile, #endif // CONFIG_SUPERTX // update partition context +#if CONFIG_EXT_PARTITION_TYPES + update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition); +#else if (bsize >= BLOCK_8X8 && (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT)) update_partition_context(xd, mi_row, mi_col, subsize, bsize); +#endif // CONFIG_EXT_PARTITION_TYPES } static void write_modes(VP10_COMP *cpi, const TileInfo *const tile, @@ -2581,9 +2671,18 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { prob_diff_update(vp10_intra_mode_tree, fc->uv_mode_prob[i], counts->uv_mode[i], INTRA_MODES, &header_bc); +#if CONFIG_EXT_PARTITION_TYPES + prob_diff_update(vp10_partition_tree, fc->partition_prob[0], + counts->partition[0], PARTITION_TYPES, &header_bc); + for (i = 1; i < PARTITION_CONTEXTS; ++i) + prob_diff_update(vp10_ext_partition_tree, fc->partition_prob[i], + counts->partition[i], EXT_PARTITION_TYPES, + &header_bc); +#else for (i = 0; i < PARTITION_CONTEXTS; ++i) prob_diff_update(vp10_partition_tree, fc->partition_prob[i], counts->partition[i], PARTITION_TYPES, &header_bc); +#endif // CONFIG_EXT_PARTITION_TYPES #if CONFIG_EXT_INTRA for (i = 0; i < INTRA_FILTERS + 1; ++i) diff --git a/vp10/encoder/context_tree.c b/vp10/encoder/context_tree.c index 3cd23ecf6..0a7619530 100644 --- a/vp10/encoder/context_tree.c +++ b/vp10/encoder/context_tree.c @@ -19,11 +19,17 @@ static const BLOCK_SIZE square[] = { }; static void alloc_mode_context(VP10_COMMON *cm, int num_4x4_blk, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition, +#endif PICK_MODE_CONTEXT *ctx) { const int num_blk = (num_4x4_blk < 4 ? 4 : num_4x4_blk); const int num_pix = num_blk << 4; int i, k; ctx->num_4x4_blk = num_blk; +#if CONFIG_EXT_PARTITION_TYPES + ctx->partition = partition; +#endif CHECK_MEM_ERROR(cm, ctx->zcoeff_blk, vpx_calloc(num_blk, sizeof(uint8_t))); @@ -78,6 +84,46 @@ static void free_mode_context(PICK_MODE_CONTEXT *ctx) { static void alloc_tree_contexts(VP10_COMMON *cm, PC_TREE *tree, int num_4x4_blk) { +#if CONFIG_EXT_PARTITION_TYPES + alloc_mode_context(cm, num_4x4_blk, PARTITION_NONE, &tree->none); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_HORZ, &tree->horizontal[0]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_VERT, &tree->vertical[0]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_VERT, &tree->horizontal[1]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_VERT, &tree->vertical[1]); + + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_HORZ_A, + &tree->horizontala[0]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_HORZ_A, + &tree->horizontala[1]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_HORZ_A, + &tree->horizontala[2]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_HORZ_B, + &tree->horizontalb[0]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_HORZ_B, + &tree->horizontalb[1]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_HORZ_B, + &tree->horizontalb[2]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_VERT_A, &tree->verticala[0]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_VERT_A, &tree->verticala[1]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_VERT_A, &tree->verticala[2]); + alloc_mode_context(cm, num_4x4_blk/2, PARTITION_VERT_B, &tree->verticalb[0]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_VERT_B, &tree->verticalb[1]); + alloc_mode_context(cm, num_4x4_blk/4, PARTITION_VERT_B, &tree->verticalb[2]); +#ifdef CONFIG_SUPERTX + alloc_mode_context(cm, num_4x4_blk, PARTITION_HORZ, + &tree->horizontal_supertx); + alloc_mode_context(cm, num_4x4_blk, PARTITION_VERT, &tree->vertical_supertx); + alloc_mode_context(cm, num_4x4_blk, PARTITION_SPLIT, &tree->split_supertx); + alloc_mode_context(cm, num_4x4_blk, PARTITION_HORZ_A, + &tree->horizontala_supertx); + alloc_mode_context(cm, num_4x4_blk, PARTITION_HORZ_B, + &tree->horizontalb_supertx); + alloc_mode_context(cm, num_4x4_blk, PARTITION_VERT_A, + &tree->verticala_supertx); + alloc_mode_context(cm, num_4x4_blk, PARTITION_VERT_B, + &tree->verticalb_supertx); +#endif // CONFIG_SUPERTX +#else alloc_mode_context(cm, num_4x4_blk, &tree->none); alloc_mode_context(cm, num_4x4_blk/2, &tree->horizontal[0]); alloc_mode_context(cm, num_4x4_blk/2, &tree->vertical[0]); @@ -94,9 +140,19 @@ static void alloc_tree_contexts(VP10_COMMON *cm, PC_TREE *tree, memset(&tree->horizontal[1], 0, sizeof(tree->horizontal[1])); memset(&tree->vertical[1], 0, sizeof(tree->vertical[1])); } +#endif // CONFIG_EXT_PARTITION_TYPES } static void free_tree_contexts(PC_TREE *tree) { +#if CONFIG_EXT_PARTITION_TYPES + int i; + for (i = 0; i < 3; i++) { + free_mode_context(&tree->horizontala[i]); + free_mode_context(&tree->horizontalb[i]); + free_mode_context(&tree->verticala[i]); + free_mode_context(&tree->verticalb[i]); + } +#endif // CONFIG_EXT_PARTITION_TYPES free_mode_context(&tree->none); free_mode_context(&tree->horizontal[0]); free_mode_context(&tree->horizontal[1]); @@ -106,7 +162,13 @@ static void free_tree_contexts(PC_TREE *tree) { free_mode_context(&tree->horizontal_supertx); free_mode_context(&tree->vertical_supertx); free_mode_context(&tree->split_supertx); -#endif +#if CONFIG_EXT_PARTITION_TYPES + free_mode_context(&tree->horizontala_supertx); + free_mode_context(&tree->horizontalb_supertx); + free_mode_context(&tree->verticala_supertx); + free_mode_context(&tree->verticalb_supertx); +#endif // CONFIG_EXT_PARTITION_TYPES +#endif // CONFIG_SUPERTX } // This function sets up a tree of contexts such that at each square @@ -135,8 +197,13 @@ void vp10_setup_pc_tree(VP10_COMMON *cm, ThreadData *td) { // 4x4 blocks smaller than 8x8 but in the same 8x8 block share the same // context so we only need to allocate 1 for each 8x8 block. - for (i = 0; i < leaf_nodes; ++i) + for (i = 0; i < leaf_nodes; ++i) { +#if CONFIG_EXT_PARTITION_TYPES + alloc_mode_context(cm, 1, PARTITION_NONE, &td->leaf_tree[i]); +#else alloc_mode_context(cm, 1, &td->leaf_tree[i]); +#endif + } // Sets up all the leaf nodes in the tree. for (pc_tree_index = 0; pc_tree_index < leaf_nodes; ++pc_tree_index) { diff --git a/vp10/encoder/context_tree.h b/vp10/encoder/context_tree.h index 53c7142d5..de17e3ea2 100644 --- a/vp10/encoder/context_tree.h +++ b/vp10/encoder/context_tree.h @@ -73,6 +73,9 @@ typedef struct { // search loop MV pred_mv[MAX_REF_FRAMES]; INTERP_FILTER pred_interp_filter; +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition; +#endif } PICK_MODE_CONTEXT; typedef struct PC_TREE { @@ -82,6 +85,12 @@ typedef struct PC_TREE { PICK_MODE_CONTEXT none; PICK_MODE_CONTEXT horizontal[2]; PICK_MODE_CONTEXT vertical[2]; +#if CONFIG_EXT_PARTITION_TYPES + PICK_MODE_CONTEXT horizontala[3]; + PICK_MODE_CONTEXT horizontalb[3]; + PICK_MODE_CONTEXT verticala[3]; + PICK_MODE_CONTEXT verticalb[3]; +#endif union { struct PC_TREE *split[4]; PICK_MODE_CONTEXT *leaf_split[4]; @@ -90,6 +99,12 @@ typedef struct PC_TREE { PICK_MODE_CONTEXT horizontal_supertx; PICK_MODE_CONTEXT vertical_supertx; PICK_MODE_CONTEXT split_supertx; +#if CONFIG_EXT_PARTITION_TYPES + PICK_MODE_CONTEXT horizontala_supertx; + PICK_MODE_CONTEXT horizontalb_supertx; + PICK_MODE_CONTEXT verticala_supertx; + PICK_MODE_CONTEXT verticalb_supertx; +#endif #endif } PC_TREE; diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c index 03ac189dc..fe79e089b 100644 --- a/vp10/encoder/encodeframe.c +++ b/vp10/encoder/encodeframe.c @@ -792,6 +792,10 @@ static int choose_partitioning(VP10_COMP *cpi, } } +#if CONFIG_EXT_PARTITION_TYPES + assert(0); +#endif + set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64); if (xd->mb_to_right_edge < 0) @@ -1386,6 +1390,9 @@ static void update_state_sb_supertx(VP10_COMP *cpi, ThreadData *td, PARTITION_TYPE partition = pc_tree->partitioning; BLOCK_SIZE subsize = get_subsize(bsize, partition); int i; +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); +#endif PICK_MODE_CONTEXT *pmc = NULL; if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) @@ -1440,6 +1447,56 @@ static void update_state_sb_supertx(VP10_COMP *cpi, ThreadData *td, } pmc = &pc_tree->split_supertx; break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2); + update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col, + bsize2, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2); + update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row, + mi_col + hbs, bsize2, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize); + update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs, + mi_col, subsize, output_enabled); + pmc = &pc_tree->horizontala_supertx; + break; + case PARTITION_HORZ_B: + set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize); + update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col, + subsize, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2); + update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs, + mi_col, bsize2, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2); + update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs, + mi_col + hbs, bsize2, output_enabled); + pmc = &pc_tree->horizontalb_supertx; + break; + case PARTITION_VERT_A: + set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2); + update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col, + bsize2, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2); + update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs, + mi_col, bsize2, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize); + update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row, + mi_col + hbs, subsize, output_enabled); + pmc = &pc_tree->verticala_supertx; + break; + case PARTITION_VERT_B: + set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize); + update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col, + subsize, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2); + update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row, + mi_col + hbs, bsize2, output_enabled); + set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2); + update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs, + mi_col + hbs, bsize2, output_enabled); + pmc = &pc_tree->verticalb_supertx; + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } @@ -1488,6 +1545,9 @@ static void update_supertx_param_sb(VP10_COMP *cpi, ThreadData *td, int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; PARTITION_TYPE partition = pc_tree->partitioning; BLOCK_SIZE subsize = get_subsize(bsize, partition); +#if CONFIG_EXT_PARTITION_TYPES + int i; +#endif if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; @@ -1536,6 +1596,28 @@ static void update_supertx_param_sb(VP10_COMP *cpi, ThreadData *td, supertx_size, pc_tree->split[3]); } break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + for ( i = 0; i < 3; i++) + update_supertx_param(td, &pc_tree->horizontala[i], best_tx, + supertx_size); + break; + case PARTITION_HORZ_B: + for ( i = 0; i < 3; i++) + update_supertx_param(td, &pc_tree->horizontalb[i], best_tx, + supertx_size); + break; + case PARTITION_VERT_A: + for ( i = 0; i < 3; i++) + update_supertx_param(td, &pc_tree->verticala[i], best_tx, + supertx_size); + break; + case PARTITION_VERT_B: + for ( i = 0; i < 3; i++) + update_supertx_param(td, &pc_tree->verticalb[i], best_tx, + supertx_size); + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } @@ -1575,6 +1657,9 @@ static void rd_pick_sb_modes(VP10_COMP *cpi, int mi_row, int mi_col, RD_COST *rd_cost, #if CONFIG_SUPERTX int *totalrate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition, #endif BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd) { @@ -1603,6 +1688,9 @@ static void rd_pick_sb_modes(VP10_COMP *cpi, // block as a supertx block, even if rdopt did not pick it as such. mbmi->tx_size = max_txsize_lookup[bsize]; #endif +#if CONFIG_EXT_PARTITION_TYPES + mbmi->partition = partition; +#endif for (i = 0; i < MAX_MB_PLANE; ++i) { p[i].coeff = ctx->coeff_pbuf[i][0]; @@ -2078,9 +2166,15 @@ static void encode_b(VP10_COMP *cpi, const TileInfo *const tile, ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col, int output_enabled, BLOCK_SIZE bsize, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition, +#endif PICK_MODE_CONTEXT *ctx) { MACROBLOCK *const x = &td->mb; set_offsets(cpi, tile, x, mi_row, mi_col, bsize); +#if CONFIG_EXT_PARTITION_TYPES + x->e_mbd.mi[0]->mbmi.partition = partition; +#endif update_state(cpi, td, ctx, mi_row, mi_col, bsize, output_enabled); encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx); @@ -2106,6 +2200,9 @@ static void encode_sb(VP10_COMP *cpi, ThreadData *td, int ctx; PARTITION_TYPE partition; BLOCK_SIZE subsize = bsize; +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); +#endif if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; @@ -2119,6 +2216,10 @@ static void encode_sb(VP10_COMP *cpi, ThreadData *td, } partition = partition_lookup[bsl][subsize]; +#if CONFIG_EXT_PARTITION_TYPES + if (bsize > BLOCK_8X8) + partition = pc_tree->partitioning; +#endif if (output_enabled && bsize != BLOCK_4X4) td->counts->partition[ctx][partition]++; @@ -2197,8 +2298,13 @@ static void encode_sb(VP10_COMP *cpi, ThreadData *td, } #endif // CONFIG_EXT_TX } +#if CONFIG_EXT_PARTITION_TYPES + update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, + partition); +#else if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) update_partition_context(xd, mi_row, mi_col, subsize, bsize); +#endif #if CONFIG_VAR_TX set_txfm_ctx(xd->left_txfm_context, supertx_size, xd->n8_h); set_txfm_ctx(xd->above_txfm_context, supertx_size, mi_height); @@ -2216,27 +2322,47 @@ static void encode_sb(VP10_COMP *cpi, ThreadData *td, switch (partition) { case PARTITION_NONE: encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif &pc_tree->none); break; case PARTITION_VERT: encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif &pc_tree->vertical[0]); if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) { encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, - subsize, &pc_tree->vertical[1]); + subsize, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + &pc_tree->vertical[1]); } break; case PARTITION_HORZ: encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif &pc_tree->horizontal[0]); if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) { encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, - subsize, &pc_tree->horizontal[1]); + subsize, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + &pc_tree->horizontal[1]); } break; case PARTITION_SPLIT: if (bsize == BLOCK_8X8) { encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif pc_tree->leaf_split[0]); } else { encode_sb(cpi, td, tile, tp, mi_row, mi_col, output_enabled, subsize, @@ -2249,13 +2375,52 @@ static void encode_sb(VP10_COMP *cpi, ThreadData *td, subsize, pc_tree->split[3]); } break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, bsize2, + partition, &pc_tree->horizontala[0]); + encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, bsize2, + partition, &pc_tree->horizontala[1]); + encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, subsize, + partition, &pc_tree->horizontala[2]); + break; + case PARTITION_HORZ_B: + encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, + partition, &pc_tree->horizontalb[0]); + encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, bsize2, + partition, &pc_tree->horizontalb[1]); + encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, output_enabled, + bsize2, partition, &pc_tree->horizontalb[2]); + break; + case PARTITION_VERT_A: + encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, bsize2, + partition, &pc_tree->verticala[0]); + encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, output_enabled, bsize2, + partition, &pc_tree->verticala[1]); + encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, subsize, + partition, &pc_tree->verticala[2]); + + break; + case PARTITION_VERT_B: + encode_b(cpi, tile, td, tp, mi_row, mi_col, output_enabled, subsize, + partition, &pc_tree->verticalb[0]); + encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, output_enabled, bsize2, + partition, &pc_tree->verticalb[1]); + encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, output_enabled, + bsize2, partition, &pc_tree->verticalb[2]); + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0 && "Invalid partition type."); break; } +#if CONFIG_EXT_PARTITION_TYPES + update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition); +#else if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) update_partition_context(xd, mi_row, mi_col, subsize, bsize); +#endif // CONFIG_EXT_PARTITION_TYPES } // Check to see if the given partition size is allowed for a specified number @@ -2365,6 +2530,10 @@ static void rd_use_partition(VP10_COMP *cpi, int chosen_rate_nocoef = INT_MAX; #endif +#if CONFIG_EXT_PARTITION_TYPES + assert(0); +#endif + if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; @@ -2417,6 +2586,9 @@ static void rd_use_partition(VP10_COMP *cpi, rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc, #if CONFIG_SUPERTX &none_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_NONE, #endif bsize, ctx, INT64_MAX); @@ -2443,6 +2615,9 @@ static void rd_use_partition(VP10_COMP *cpi, rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, #if CONFIG_SUPERTX &last_part_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_NONE, #endif bsize, ctx, INT64_MAX); break; @@ -2450,6 +2625,9 @@ static void rd_use_partition(VP10_COMP *cpi, rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, #if CONFIG_SUPERTX &last_part_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_HORZ, #endif subsize, &pc_tree->horizontal[0], INT64_MAX); @@ -2467,6 +2645,9 @@ static void rd_use_partition(VP10_COMP *cpi, mi_row + (mi_step >> 1), mi_col, &tmp_rdc, #if CONFIG_SUPERTX &rt_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_HORZ, #endif subsize, &pc_tree->horizontal[1], INT64_MAX); if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { @@ -2488,6 +2669,9 @@ static void rd_use_partition(VP10_COMP *cpi, rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, #if CONFIG_SUPERTX &last_part_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_VERT, #endif subsize, &pc_tree->vertical[0], INT64_MAX); if (last_part_rdc.rate != INT_MAX && @@ -2504,6 +2688,9 @@ static void rd_use_partition(VP10_COMP *cpi, mi_row, mi_col + (mi_step >> 1), &tmp_rdc, #if CONFIG_SUPERTX &rt_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_VERT, #endif subsize, &pc_tree->vertical[bsize > BLOCK_8X8], INT64_MAX); @@ -2527,6 +2714,9 @@ static void rd_use_partition(VP10_COMP *cpi, rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, #if CONFIG_SUPERTX &last_part_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_SPLIT, #endif subsize, pc_tree->leaf_split[0], INT64_MAX); break; @@ -2624,6 +2814,9 @@ static void rd_use_partition(VP10_COMP *cpi, mi_row + y_idx, mi_col + x_idx, &tmp_rdc, #if CONFIG_SUPERTX &rt_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_SPLIT, #endif split_subsize, &pc_tree->split[i]->none, INT64_MAX); @@ -2945,6 +3138,192 @@ static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv, } #endif +#if CONFIG_EXT_PARTITION_TYPES +static void rd_test_partition3(VP10_COMP *cpi, ThreadData *td, + TileDataEnc *tile_data, + TOKENEXTRA **tp, PC_TREE *pc_tree, + RD_COST *best_rdc, PICK_MODE_CONTEXT ctxs[3], + PICK_MODE_CONTEXT *ctx, + int mi_row, int mi_col, BLOCK_SIZE bsize, + PARTITION_TYPE partition, +#if CONFIG_SUPERTX + int64_t best_rd, int *best_rate_nocoef, + RD_SEARCH_MACROBLOCK_CONTEXT* x_ctx, +#endif + int mi_row0, int mi_col0, BLOCK_SIZE subsize0, + int mi_row1, int mi_col1, BLOCK_SIZE subsize1, + int mi_row2, int mi_col2, BLOCK_SIZE subsize2) { + MACROBLOCK *const x = &td->mb; + MACROBLOCKD *const xd = &x->e_mbd; + RD_COST this_rdc, sum_rdc; +#if CONFIG_SUPERTX + VP10_COMMON *const cm = &cpi->common; + TileInfo *const tile_info = &tile_data->tile_info; + int this_rate_nocoef, sum_rate_nocoef; + int abort_flag; + PARTITION_TYPE best_partition; + int tmp_rate; + int64_t tmp_dist, tmp_rd; +#endif + if (cpi->sf.adaptive_motion_search) + load_pred_mv(x, ctx); + + rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc, +#if CONFIG_SUPERTX + &sum_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + subsize0, &ctxs[0], best_rdc->rdcost); +#if CONFIG_SUPERTX + abort_flag = sum_rdc.rdcost >= best_rd; +#endif + +#if CONFIG_SUPERTX + if (sum_rdc.rdcost < INT64_MAX) { +#else + if (sum_rdc.rdcost < best_rdc->rdcost) { +#endif + PICK_MODE_CONTEXT *ctx = &ctxs[0]; + update_state(cpi, td, ctx, mi_row0, mi_col0, subsize0, 0); + encode_superblock(cpi, td, tp, 0, mi_row0, mi_col0, subsize0, ctx); + + if (cpi->sf.adaptive_motion_search) + load_pred_mv(x, ctx); + +#if CONFIG_SUPERTX + rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc, + &this_rate_nocoef, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost); +#else + rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost); +#endif // CONFIG_SUPERTX + + if (this_rdc.rate == INT_MAX) { + sum_rdc.rdcost = INT64_MAX; +#if CONFIG_SUPERTX + sum_rate_nocoef = INT_MAX; +#endif + } else { + sum_rdc.rate += this_rdc.rate; + sum_rdc.dist += this_rdc.dist; + sum_rdc.rdcost += this_rdc.rdcost; +#if CONFIG_SUPERTX + sum_rate_nocoef += this_rate_nocoef; +#endif + } + +#if CONFIG_SUPERTX + if (sum_rdc.rdcost < INT64_MAX) { +#else + if (sum_rdc.rdcost < best_rdc->rdcost) { +#endif + PICK_MODE_CONTEXT *ctx = &ctxs[1]; + update_state(cpi, td, ctx, mi_row1, mi_col1, subsize1, 0); + encode_superblock(cpi, td, tp, 0, mi_row1, mi_col1, subsize1, ctx); + + if (cpi->sf.adaptive_motion_search) + load_pred_mv(x, ctx); + +#if CONFIG_SUPERTX + rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc, + &this_rate_nocoef, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost); +#else + rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc, +#if CONFIG_EXT_PARTITION_TYPES + partition, +#endif + subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost); +#endif // CONFIG_SUPERTX + + if (this_rdc.rate == INT_MAX) { + sum_rdc.rdcost = INT64_MAX; +#if CONFIG_SUPERTX + sum_rate_nocoef = INT_MAX; +#endif + } else { + sum_rdc.rate += this_rdc.rate; + sum_rdc.dist += this_rdc.dist; + sum_rdc.rdcost += this_rdc.rdcost; +#if CONFIG_SUPERTX + sum_rate_nocoef += this_rate_nocoef; +#endif + } + +#if CONFIG_SUPERTX + if (cm->frame_type != KEY_FRAME && !abort_flag && + sum_rdc.rdcost < INT64_MAX && bsize <= MAX_SUPERTX_BLOCK_SIZE && + !xd->lossless[0]) { + TX_SIZE supertx_size = max_txsize_lookup[bsize]; + best_partition = pc_tree->partitioning; + pc_tree->partitioning = partition; + sum_rdc.rate += vp10_cost_bit( + cm->fc->supertx_prob + [partition_supertx_context_lookup[partition]][supertx_size], + 0); + sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, + sum_rdc.dist); + + if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) { + TX_TYPE best_tx = DCT_DCT; + + tmp_rate = sum_rate_nocoef; + tmp_dist = 0; + restore_context(x, x_ctx, mi_row, mi_col, bsize); + rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rate, + &tmp_dist, &best_tx, pc_tree); + + tmp_rate += vp10_cost_bit( + cm->fc->supertx_prob + [partition_supertx_context_lookup[partition]][supertx_size], + 1); + tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rate, tmp_dist); + if (tmp_rd < sum_rdc.rdcost) { + sum_rdc.rdcost = tmp_rd; + sum_rdc.rate = tmp_rate; + sum_rdc.dist = tmp_dist; + update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx, + supertx_size, pc_tree); + } + } + pc_tree->partitioning = best_partition; + } +#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]; + 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]; +#endif + if (sum_rdc.rdcost < best_rdc->rdcost) { +#if CONFIG_SUPERTX + *best_rate_nocoef = sum_rate_nocoef; + assert(*best_rate_nocoef >= 0); +#endif + *best_rdc = sum_rdc; + pc_tree->partitioning = partition; + } + } + } + } +} +#endif // CONFIG_EXT_PARTITION_TYPES + // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are // unlikely to be selected depending on previous rate-distortion optimization // results, for encoding speed-up. @@ -2977,6 +3356,9 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, #endif // CONFIG_SUPERTX int do_split = bsize >= BLOCK_8X8; int do_rect = 1; +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); +#endif // Override skipping rectangular partition operations for edge blocks const int force_horz_split = (mi_row + mi_step >= cm->mi_rows); @@ -3106,6 +3488,9 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, #if CONFIG_SUPERTX &this_rate_nocoef, +#endif +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_NONE, #endif bsize, ctx, best_rdc.rdcost); if (this_rdc.rate != INT_MAX) { @@ -3215,11 +3600,17 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, ctx->mic.mbmi.interp_filter; #if CONFIG_SUPERTX rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, - &sum_rate_nocoef, subsize, pc_tree->leaf_split[0], - INT64_MAX); + &sum_rate_nocoef, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_SPLIT, +#endif + subsize, pc_tree->leaf_split[0], INT64_MAX); #else - rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize, - pc_tree->leaf_split[0], best_rdc.rdcost); + rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_SPLIT, +#endif + subsize, pc_tree->leaf_split[0], best_rdc.rdcost); #endif // CONFIG_SUPERTX if (sum_rdc.rate == INT_MAX) { sum_rdc.rdcost = INT64_MAX; @@ -3400,6 +3791,9 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, #if CONFIG_SUPERTX &sum_rate_nocoef, #endif // CONFIG_SUPERTX +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_HORZ, +#endif subsize, &pc_tree->horizontal[0], best_rdc.rdcost); #if CONFIG_SUPERTX @@ -3424,11 +3818,18 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, #if CONFIG_SUPERTX rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc, &this_rate_nocoef, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_HORZ, +#endif subsize, &pc_tree->horizontal[1], INT64_MAX); #else rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, - &this_rdc, subsize, &pc_tree->horizontal[1], + &this_rdc, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_HORZ, +#endif + subsize, &pc_tree->horizontal[1], best_rdc.rdcost - sum_rdc.rdcost); #endif // CONFIG_SUPERTX if (this_rdc.rate == INT_MAX) { @@ -3522,6 +3923,9 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, #if CONFIG_SUPERTX &sum_rate_nocoef, #endif // CONFIG_SUPERTX +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_VERT, +#endif subsize, &pc_tree->vertical[0], best_rdc.rdcost); #if CONFIG_SUPERTX abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) || @@ -3544,11 +3948,19 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, ctx->mic.mbmi.interp_filter; #if CONFIG_SUPERTX rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc, - &this_rate_nocoef, subsize, &pc_tree->vertical[1], + &this_rate_nocoef, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_VERT, +#endif + subsize, &pc_tree->vertical[1], INT64_MAX - sum_rdc.rdcost); #else rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, - &this_rdc, subsize, + &this_rdc, +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_VERT, +#endif + subsize, &pc_tree->vertical[1], best_rdc.rdcost - sum_rdc.rdcost); #endif // CONFIG_SUPERTX if (this_rdc.rate == INT_MAX) { @@ -3624,9 +4036,71 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td, pc_tree->partitioning = PARTITION_VERT; } } + restore_context(x, &x_ctx, mi_row, mi_col, bsize); + } +#if CONFIG_EXT_PARTITION_TYPES + // PARTITION_HORZ_A + if (partition_horz_allowed && do_rect && bsize > BLOCK_8X8 && + partition_none_allowed) { + subsize = get_subsize(bsize, PARTITION_HORZ_A); + rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc, + pc_tree->horizontala, + ctx, mi_row, mi_col, bsize, PARTITION_HORZ_A, +#if CONFIG_SUPERTX + best_rd, &best_rate_nocoef, &x_ctx, +#endif + mi_row, mi_col, bsize2, + mi_row, mi_col + mi_step, bsize2, + mi_row + mi_step, mi_col, subsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize); + } + // PARTITION_HORZ_B + if (partition_horz_allowed && do_rect && bsize > BLOCK_8X8 && + partition_none_allowed) { + subsize = get_subsize(bsize, PARTITION_HORZ_B); + rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc, + pc_tree->horizontalb, + ctx, mi_row, mi_col, bsize, PARTITION_HORZ_B, +#if CONFIG_SUPERTX + best_rd, &best_rate_nocoef, &x_ctx, +#endif + mi_row, mi_col, subsize, + mi_row + mi_step, mi_col, bsize2, + mi_row + mi_step, mi_col + mi_step, bsize2); + restore_context(x, &x_ctx, mi_row, mi_col, bsize); + } + // PARTITION_VERT_A + if (partition_vert_allowed && do_rect && bsize > BLOCK_8X8 && + partition_none_allowed) { + subsize = get_subsize(bsize, PARTITION_VERT_A); + rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc, + pc_tree->verticala, + ctx, mi_row, mi_col, bsize, PARTITION_VERT_A, +#if CONFIG_SUPERTX + best_rd, &best_rate_nocoef, &x_ctx, +#endif + mi_row, mi_col, bsize2, + mi_row + mi_step, mi_col, bsize2, + mi_row, mi_col + mi_step, subsize); + restore_context(x, &x_ctx, mi_row, mi_col, bsize); + } + // PARTITION_VERT_B + if (partition_vert_allowed && do_rect && bsize > BLOCK_8X8 && + partition_none_allowed) { + subsize = get_subsize(bsize, PARTITION_VERT_B); + rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc, + pc_tree->verticalb, + ctx, mi_row, mi_col, bsize, PARTITION_VERT_B, +#if CONFIG_SUPERTX + best_rd, &best_rate_nocoef, &x_ctx, +#endif + mi_row, mi_col, subsize, + mi_row, mi_col + mi_step, bsize2, + mi_row + mi_step, mi_col + mi_step, bsize2); restore_context(x, &x_ctx, mi_row, mi_col, bsize); } +#endif // CONFIG_EXT_PARTITION_TYPES // TODO(jbb): This code added so that we avoid static analysis // warning related to the fact that best_rd isn't used after this @@ -4576,6 +5050,9 @@ static int check_intra_sb(VP10_COMP *cpi, const TileInfo *const tile, const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; PARTITION_TYPE partition; BLOCK_SIZE subsize = bsize; +#if CONFIG_EXT_PARTITION_TYPES + int i; +#endif if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1; @@ -4586,6 +5063,10 @@ static int check_intra_sb(VP10_COMP *cpi, const TileInfo *const tile, subsize = BLOCK_4X4; partition = partition_lookup[bsl][subsize]; +#if CONFIG_EXT_PARTITION_TYPES + if (bsize > BLOCK_8X8) + partition = pc_tree->partitioning; +#endif switch (partition) { case PARTITION_NONE: @@ -4626,6 +5107,32 @@ static int check_intra_sb(VP10_COMP *cpi, const TileInfo *const tile, return 1; } break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + for (i = 0; i < 3; i++) { + if (check_intra_b(&pc_tree->horizontala[i])) + return 1; + } + break; + case PARTITION_HORZ_B: + for (i = 0; i < 3; i++) { + if (check_intra_b(&pc_tree->horizontalb[i])) + return 1; + } + break; + case PARTITION_VERT_A: + for (i = 0; i < 3; i++) { + if (check_intra_b(&pc_tree->verticala[i])) + return 1; + } + break; + case PARTITION_VERT_B: + for (i = 0; i < 3; i++) { + if (check_intra_b(&pc_tree->verticalb[i])) + return 1; + } + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } @@ -4655,6 +5162,16 @@ static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size, return check_supertx_b(supertx_size, pc_tree->leaf_split[0]); else return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]); +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + return check_supertx_b(supertx_size, &pc_tree->horizontala[0]); + case PARTITION_HORZ_B: + return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]); + case PARTITION_VERT_A: + return check_supertx_b(supertx_size, &pc_tree->verticala[0]); + case PARTITION_VERT_B: + return check_supertx_b(supertx_size, &pc_tree->verticalb[0]); +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); return 0; @@ -4889,6 +5406,9 @@ static void predict_sb_complex(VP10_COMP *cpi, ThreadData *td, const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4; PARTITION_TYPE partition; BLOCK_SIZE subsize; +#if CONFIG_EXT_PARTITION_TYPES + BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT); +#endif int i, ctx; uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3]; @@ -4939,6 +5459,10 @@ static void predict_sb_complex(VP10_COMP *cpi, ThreadData *td, subsize = BLOCK_4X4; } partition = partition_lookup[bsl][subsize]; +#if CONFIG_EXT_PARTITION_TYPES + if (bsize > BLOCK_8X8) + partition = pc_tree->partitioning; +#endif if (output_enabled && bsize != BLOCK_4X4 && bsize < top_bsize) cm->counts.partition[ctx][partition]++; @@ -5199,13 +5723,225 @@ static void predict_sb_complex(VP10_COMP *cpi, ThreadData *td, } } break; +#if CONFIG_EXT_PARTITION_TYPES + case PARTITION_HORZ_A: + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride, + bsize2, top_bsize, bsize2, output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride); + + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, + mi_row, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf1, dst_stride1, bsize2, top_bsize, bsize2, + output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs, + mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1); + + predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs, + mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2, + subsize, top_bsize, subsize, output_enabled, 0, 0); + if (bsize < top_bsize) + extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col, + mi_row_top, mi_col_top, output_enabled, + dst_buf2, dst_stride2); + else + extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col, + mi_row_top, mi_col_top, output_enabled, + dst_buf2, dst_stride2, 1); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + + break; + case PARTITION_VERT_A: + + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride, + bsize2, top_bsize, bsize2, output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride); + + predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs, + mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1, + bsize2, top_bsize, bsize2, output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col, + mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1); + + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row, + mi_col + hbs, mi_row_top, mi_col_top, dst_buf2, + dst_stride2, subsize, top_bsize, subsize, output_enabled, + 0, 0); + if (bsize < top_bsize) + extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs, + mi_row_top, mi_col_top, output_enabled, + dst_buf2, dst_stride2); + else + extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs, + mi_row_top, mi_col_top, output_enabled, + dst_buf2, dst_stride2, 2); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + break; + case PARTITION_HORZ_B: + + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride, + subsize, top_bsize, subsize, output_enabled, 0, 0); + if (bsize < top_bsize) + extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride); + else + extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, output_enabled, + dst_buf, dst_stride, 0); + + predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs, + mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1, + bsize2, top_bsize, bsize2, output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col, + mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1); + + predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs, + mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, bsize2, top_bsize, bsize2, + output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, + mi_col + hbs, mi_row_top, mi_col_top, output_enabled, dst_buf2, + dst_stride2); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf1[i]; + xd->plane[i].dst.stride = dst_stride1[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf1[i], dst_stride1[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + break; + case PARTITION_VERT_B: + + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col, + mi_row_top, mi_col_top, dst_buf, dst_stride, + subsize, top_bsize, subsize, output_enabled, 0, 0); + if (bsize < top_bsize) + extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, output_enabled, dst_buf, dst_stride); + else + extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col, + mi_row_top, mi_col_top, output_enabled, + dst_buf, dst_stride, 3); + + predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row, + mi_col + hbs, mi_row_top, mi_col_top, dst_buf1, + dst_stride1, bsize2, top_bsize, bsize2, output_enabled, + 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs, + mi_row_top, mi_col_top, output_enabled, dst_buf1, dst_stride1); + + predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs, + mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top, + dst_buf2, dst_stride2, bsize2, top_bsize, bsize2, + output_enabled, 0, 0); + extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, + mi_col + hbs, mi_row_top, mi_col_top, output_enabled, dst_buf2, + dst_stride2); + + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf1[i]; + xd->plane[i].dst.stride = dst_stride1[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf1[i], dst_stride1[i], + dst_buf2[i], dst_stride2[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_HORZ, i); + } + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = dst_buf[i]; + xd->plane[i].dst.stride = dst_stride[i]; + vp10_build_masked_inter_predictor_complex(xd, + dst_buf[i], dst_stride[i], + dst_buf1[i], dst_stride1[i], + &xd->plane[i], + mi_row, mi_col, + mi_row_top, mi_col_top, + bsize, top_bsize, + PARTITION_VERT, i); + } + break; +#endif // CONFIG_EXT_PARTITION_TYPES default: assert(0); } +#if CONFIG_EXT_PARTITION_TYPES + if (bsize < top_bsize) + update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition); +#else if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)) update_partition_context(xd, mi_row, mi_col, subsize, bsize); +#endif // CONFIG_EXT_PARTITION_TYPES } static void rd_supertx_sb(VP10_COMP *cpi, ThreadData *td, diff --git a/vp10/encoder/encodemv.c b/vp10/encoder/encodemv.c index 61429aaa2..79413632e 100644 --- a/vp10/encoder/encodemv.c +++ b/vp10/encoder/encodemv.c @@ -282,9 +282,9 @@ static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext, const MV diff = {mvs[i].as_mv.row - ref->row, mvs[i].as_mv.col - ref->col}; #if CONFIG_REF_MV - int nmv_ctx = vp10_nmv_ctx(mbmi_ext->ref_mv_count[mbmi->ref_frame[i]], - mbmi_ext->ref_mv_stack[mbmi->ref_frame[i]]); - nmv_context_counts *counts = &nmv_counts[nmv_ctx]; + int nmv_ctx = vp10_nmv_ctx(mbmi_ext->ref_mv_count[mbmi->ref_frame[i]], + mbmi_ext->ref_mv_stack[mbmi->ref_frame[i]]); + nmv_context_counts *counts = &nmv_counts[nmv_ctx]; #endif vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref)); } @@ -332,9 +332,9 @@ static void inc_mvs_sub8x8(const MODE_INFO *mi, const MV diff = {mvs[i].as_mv.row - ref->row, mvs[i].as_mv.col - ref->col}; #if CONFIG_REF_MV - int nmv_ctx = vp10_nmv_ctx(mbmi_ext->ref_mv_count[mbmi->ref_frame[i]], - mbmi_ext->ref_mv_stack[mbmi->ref_frame[i]]); - nmv_context_counts *counts = &nmv_counts[nmv_ctx]; + int nmv_ctx = vp10_nmv_ctx(mbmi_ext->ref_mv_count[mbmi->ref_frame[i]], + mbmi_ext->ref_mv_stack[mbmi->ref_frame[i]]); + nmv_context_counts *counts = &nmv_counts[nmv_ctx]; #endif vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref)); } diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h index a319901e2..4024d68e0 100644 --- a/vp10/encoder/encoder.h +++ b/vp10/encoder/encoder.h @@ -504,7 +504,11 @@ typedef struct VP10_COMP { int intra_uv_mode_cost[INTRA_MODES][INTRA_MODES]; 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]; +#else int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES]; +#endif int palette_y_size_cost[PALETTE_BLOCK_SIZES][PALETTE_SIZES]; int palette_uv_size_cost[PALETTE_BLOCK_SIZES][PALETTE_SIZES]; int palette_y_color_cost[PALETTE_MAX_SIZE - 1][PALETTE_COLOR_CONTEXTS] diff --git a/vp10/encoder/rd.c b/vp10/encoder/rd.c index 78e8e9a36..7af70d5ef 100644 --- a/vp10/encoder/rd.c +++ b/vp10/encoder/rd.c @@ -393,9 +393,17 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) { if (cpi->sf.partition_search_type != VAR_BASED_PARTITION || cm->frame_type == KEY_FRAME) { +#if CONFIG_EXT_PARTITION_TYPES + vp10_cost_tokens(cpi->partition_cost[0], cm->fc->partition_prob[0], + vp10_partition_tree); + for (i = 1; i < PARTITION_CONTEXTS; ++i) + vp10_cost_tokens(cpi->partition_cost[i], cm->fc->partition_prob[i], + vp10_ext_partition_tree); +#else for (i = 0; i < PARTITION_CONTEXTS; ++i) vp10_cost_tokens(cpi->partition_cost[i], cm->fc->partition_prob[i], vp10_partition_tree); +#endif // CONFIG_EXT_PARTITION_TYPES } fill_mode_costs(cpi); diff --git a/vp10/encoder/segmentation.c b/vp10/encoder/segmentation.c index 969b87fa9..477e32df9 100644 --- a/vp10/encoder/segmentation.c +++ b/vp10/encoder/segmentation.c @@ -164,15 +164,106 @@ static void count_segs_sb(const VP10_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col, BLOCK_SIZE bsize) { const int mis = cm->mi_stride; - int bw, bh; const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; +#if CONFIG_EXT_PARTITION_TYPES + PARTITION_TYPE partition; +#else + const int bw = num_8x8_blocks_wide_lookup[mi[0]->mbmi.sb_type]; + const int bh = num_8x8_blocks_high_lookup[mi[0]->mbmi.sb_type]; +#endif // CONFIG_EXT_PARTITION_TYPES if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - bw = num_8x8_blocks_wide_lookup[mi[0]->mbmi.sb_type]; - bh = num_8x8_blocks_high_lookup[mi[0]->mbmi.sb_type]; +#if CONFIG_EXT_PARTITION_TYPES + if (bsize == BLOCK_8X8) + partition = PARTITION_NONE; + else + partition = get_partition(cm->mi, cm->mi_stride, cm->mi_rows, cm->mi_cols, + mi_row, mi_col, bsize); + switch (partition) { + case PARTITION_NONE: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, bs, bs, mi_row, mi_col); + break; + case PARTITION_HORZ: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, bs, hbs, mi_row, mi_col); + count_segs(cm, xd, tile, mi + hbs * mis, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, bs, hbs, + mi_row + hbs, mi_col); + break; + case PARTITION_VERT: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, bs, mi_row, mi_col); + count_segs(cm, xd, tile, mi + hbs, + no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, bs, mi_row, mi_col + hbs); + break; + case PARTITION_HORZ_A: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, hbs, mi_row, mi_col); + count_segs(cm, xd, tile, mi + hbs, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, hbs, hbs, + mi_row, mi_col + hbs); + count_segs(cm, xd, tile, mi + hbs * mis, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, bs, hbs, + mi_row + hbs, mi_col); + break; + case PARTITION_HORZ_B: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, bs, hbs, mi_row, mi_col); + count_segs(cm, xd, tile, mi + hbs * mis, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, hbs, hbs, + mi_row + hbs, mi_col); + count_segs(cm, xd, tile, mi + hbs + hbs * mis, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, hbs, hbs, + mi_row + hbs, mi_col + hbs); + break; + case PARTITION_VERT_A: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, hbs, mi_row, mi_col); + count_segs(cm, xd, tile, mi + hbs * mis, no_pred_segcounts, + temporal_predictor_count, t_unpred_seg_counts, hbs, hbs, + mi_row + hbs, mi_col); + count_segs(cm, xd, tile, mi + hbs, + no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, bs, mi_row, mi_col + hbs); + break; + case PARTITION_VERT_B: + count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, bs, mi_row, mi_col); + count_segs(cm, xd, tile, mi + hbs, + no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, hbs, mi_row, mi_col + hbs); + count_segs(cm, xd, tile, mi + hbs + hbs * mis, + no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, hbs, hbs, mi_row + hbs, mi_col + hbs); + break; + case PARTITION_SPLIT: + { + const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; + int n; + + assert(num_8x8_blocks_wide_lookup[mi[0]->mbmi.sb_type] < bs && + num_8x8_blocks_high_lookup[mi[0]->mbmi.sb_type] < bs); + + for (n = 0; n < 4; n++) { + const int mi_dc = hbs * (n & 1); + const int mi_dr = hbs * (n >> 1); + + count_segs_sb(cm, xd, tile, &mi[mi_dr * mis + mi_dc], + no_pred_segcounts, temporal_predictor_count, + t_unpred_seg_counts, + mi_row + mi_dr, mi_col + mi_dc, subsize); + } + } + break; + default: + assert(0); + } +#else if (bw == bs && bh == bs) { count_segs(cm, xd, tile, mi, no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, bs, bs, mi_row, mi_col); @@ -204,6 +295,7 @@ static void count_segs_sb(const VP10_COMMON *cm, MACROBLOCKD *xd, mi_row + mi_dr, mi_col + mi_dc, subsize); } } +#endif // CONFIG_EXT_PARTITION_TYPES } void vp10_choose_segmap_coding_method(VP10_COMMON *cm, MACROBLOCKD *xd) { -- 2.50.0