diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/common/vp9_alloccommon.c | 16 | ||||
-rw-r--r-- | vp9/common/vp9_blockd.h | 74 | ||||
-rw-r--r-- | vp9/common/vp9_entropymode.c | 21 | ||||
-rw-r--r-- | vp9/common/vp9_enums.h | 3 | ||||
-rw-r--r-- | vp9/common/vp9_onyxc_int.h | 14 | ||||
-rw-r--r-- | vp9/decoder/vp9_decodemv.c | 7 | ||||
-rw-r--r-- | vp9/decoder/vp9_decodframe.c | 23 | ||||
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 35 | ||||
-rw-r--r-- | vp9/encoder/vp9_block.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 103 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 4 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 2 |
12 files changed, 238 insertions, 66 deletions
diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c index 8d75c4db0..56fac12b4 100644 --- a/vp9/common/vp9_alloccommon.c +++ b/vp9/common/vp9_alloccommon.c @@ -57,11 +57,12 @@ void vp9_free_frame_buffers(VP9_COMMON *oci) { vpx_free(oci->above_context); vpx_free(oci->mip); vpx_free(oci->prev_mip); + vpx_free(oci->above_seg_context); oci->above_context = 0; oci->mip = 0; oci->prev_mip = 0; - + oci->above_seg_context = 0; } int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { @@ -130,13 +131,24 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { oci->prev_mi = oci->prev_mip + oci->mode_info_stride + 1; oci->above_context = - vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * (3 + oci->mb_cols), 1); + vpx_calloc(sizeof(ENTROPY_CONTEXT_PLANES) * mb_cols_aligned_to_sb(oci), 1); if (!oci->above_context) { vp9_free_frame_buffers(oci); return 1; } + oci->above_seg_context = + vpx_calloc(sizeof(PARTITION_CONTEXT) * mb_cols_aligned_to_sb(oci), 1); + + if (!oci->above_seg_context) { + vp9_free_frame_buffers(oci); + return 1; + } + + vp9_update_mode_info_border(oci, oci->mip); + vp9_update_mode_info_in_image(oci, oci->mi); + return 0; } diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 6b4f607b1..1e55bed9b 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -54,6 +54,8 @@ typedef struct { ENTROPY_CONTEXT v[2]; } ENTROPY_CONTEXT_PLANES; +typedef char PARTITION_CONTEXT; + static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a, ENTROPY_CONTEXT b) { return (a != 0) + (b != 0); @@ -245,11 +247,6 @@ static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) { return mb_height_log2(sb_type) + 2; } -static INLINE int partition_plane(BLOCK_SIZE_TYPE sb_type) { - assert(mb_width_log2(sb_type) == mb_height_log2(sb_type)); - return (mb_width_log2(sb_type) - 1); -} - typedef struct { MB_PREDICTION_MODE mode, uv_mode; #if CONFIG_COMP_INTERINTRA_PRED @@ -377,6 +374,10 @@ typedef struct macroblockd { ENTROPY_CONTEXT_PLANES *above_context; ENTROPY_CONTEXT_PLANES *left_context; + // partition contexts + PARTITION_CONTEXT *above_seg_context; + PARTITION_CONTEXT *left_seg_context; + /* 0 indicates segmentation at MB level is not enabled. Otherwise the individual bits indicate which features are active. */ unsigned char segmentation_enabled; @@ -449,6 +450,69 @@ typedef struct macroblockd { } MACROBLOCKD; +static INLINE void update_partition_context(MACROBLOCKD *xd, + BLOCK_SIZE_TYPE sb_type, + BLOCK_SIZE_TYPE sb_size) { + int bsl = mb_width_log2(sb_size), bs = 1 << bsl; + int bwl = mb_width_log2(sb_type); + int bhl = mb_height_log2(sb_type); + int boffset = mb_width_log2(BLOCK_SIZE_SB64X64) - bsl; + int i; + // skip macroblock partition + if (bsl == 0) + return; + + // update the partition context at the end notes. set partition bits + // of block sizes larger than the current one to be one, and partition + // bits of smaller block sizes to be zero. + if ((bwl == bsl) && (bhl == bsl)) { + for (i = 0; i < bs; i++) + xd->left_seg_context[i] = ~(0xf << boffset); + for (i = 0; i < bs; i++) + xd->above_seg_context[i] = ~(0xf << boffset); +#if CONFIG_SBSEGMENT + } else if ((bwl == bsl) && (bhl < bsl)) { + for (i = 0; i < bs; i++) + xd->left_seg_context[i] = ~(0xe << boffset); + for (i = 0; i < bs; i++) + xd->above_seg_context[i] = ~(0xf << boffset); + } else if ((bwl < bsl) && (bhl == bsl)) { + for (i = 0; i < bs; i++) + xd->left_seg_context[i] = ~(0xf << boffset); + for (i = 0; i < bs; i++) + xd->above_seg_context[i] = ~(0xe << boffset); +#endif + } else if ((bwl < bsl) && (bhl < bsl)) { + for (i = 0; i < bs; i++) + xd->left_seg_context[i] = ~(0xe << boffset); + for (i = 0; i < bs; i++) + xd->above_seg_context[i] = ~(0xe << boffset); + } else { + assert(0); + } +} + +static INLINE int partition_plane_context(MACROBLOCKD *xd, + BLOCK_SIZE_TYPE sb_type) { + int bsl = mb_width_log2(sb_type), bs = 1 << bsl; + int above = 0, left = 0, i; + int boffset = mb_width_log2(BLOCK_SIZE_SB64X64) - bsl; + + assert(mb_width_log2(sb_type) == mb_height_log2(sb_type)); + assert(bsl >= 0); + assert(boffset >= 0); + + for (i = 0; i < bs; i++) + above |= (xd->above_seg_context[i] & (1 << boffset)); + for (i = 0; i < bs; i++) + left |= (xd->left_seg_context[i] & (1 << boffset)); + + above = (above > 0); + left = (left > 0); + + return (left * 2 + above) + (bsl - 1) * PARTITION_PLOFFSET; +} + #define ACTIVE_HT 110 // quantization stepsize threshold #define ACTIVE_HT8 300 diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index ff5abcc26..fc93c9961 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c @@ -152,13 +152,22 @@ const int vp9_mbsplit_count [VP9_NUMMBSPLITS] = { 2, 2, 4, 16}; const vp9_prob vp9_mbsplit_probs [VP9_NUMMBSPLITS - 1] = { 110, 111, 150}; #if CONFIG_SBSEGMENT -const vp9_prob vp9_partition_probs[PARTITION_PLANES][PARTITION_TYPES - 1] = { - {110, 111, 150}, - {110, 111, 150}, +const vp9_prob vp9_partition_probs[NUM_PARTITION_CONTEXTS] + [PARTITION_TYPES - 1] = { + {202, 162, 107}, + {16, 2, 169}, + {3, 246, 19}, + {104, 90, 134}, + {183, 70, 109}, + {30, 14, 162}, + {67, 208, 22}, + {4, 17, 5}, }; #else -const vp9_prob vp9_partition_probs[PARTITION_PLANES][PARTITION_TYPES - 1] = { - {200}, {200}, +const vp9_prob vp9_partition_probs[NUM_PARTITION_CONTEXTS] + [PARTITION_TYPES - 1] = { + {200}, {200}, {200}, {200}, + {200}, {200}, {200}, {200}, }; #endif @@ -660,7 +669,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { interintra_prob, factor); } #endif - for (i = 0; i < PARTITION_PLANES; i++) + for (i = 0; i < NUM_PARTITION_CONTEXTS; i++) update_mode_probs(PARTITION_TYPES, vp9_partition_tree, fc->partition_counts[i], fc->pre_partition_prob[i], fc->partition_prob[i], 0); diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h index 51a2a5fdc..d9a6721a7 100644 --- a/vp9/common/vp9_enums.h +++ b/vp9/common/vp9_enums.h @@ -44,6 +44,7 @@ typedef enum PARTITION_TYPE { PARTITION_TYPES } PARTITION_TYPE; -#define PARTITION_PLANES 2 // number of probability models +#define PARTITION_PLOFFSET 4 // number of probability models per block size +#define NUM_PARTITION_CONTEXTS (2 * PARTITION_PLOFFSET) #endif // VP9_COMMON_VP9_ENUMS_H_ diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index dc734b87f..3e09c864c 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -68,7 +68,7 @@ typedef struct frame_contexts { vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1]; vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1]; - vp9_prob partition_prob[PARTITION_PLANES][PARTITION_TYPES - 1]; + vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1]; vp9_coeff_probs coef_probs_4x4[BLOCK_TYPES]; vp9_coeff_probs coef_probs_8x8[BLOCK_TYPES]; @@ -90,7 +90,7 @@ typedef struct frame_contexts { vp9_prob pre_i8x8_mode_prob[VP9_I8X8_MODES - 1]; vp9_prob pre_sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; vp9_prob pre_mbsplit_prob[VP9_NUMMBSPLITS - 1]; - vp9_prob pre_partition_prob[PARTITION_PLANES][PARTITION_TYPES - 1]; + vp9_prob pre_partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1]; unsigned int bmode_counts[VP9_NKF_BINTRAMODES]; unsigned int ymode_counts[VP9_YMODES]; /* interframe intra mode probs */ unsigned int sb_ymode_counts[VP9_I32X32_MODES]; @@ -98,7 +98,7 @@ typedef struct frame_contexts { unsigned int i8x8_mode_counts[VP9_I8X8_MODES]; /* interframe intra probs */ unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS]; unsigned int mbsplit_counts[VP9_NUMMBSPLITS]; - unsigned int partition_counts[PARTITION_PLANES][PARTITION_TYPES]; + unsigned int partition_counts[NUM_PARTITION_CONTEXTS][PARTITION_TYPES]; vp9_coeff_probs pre_coef_probs_4x4[BLOCK_TYPES]; vp9_coeff_probs pre_coef_probs_8x8[BLOCK_TYPES]; @@ -251,6 +251,10 @@ typedef struct VP9Common { ENTROPY_CONTEXT_PLANES *above_context; /* row of context for each plane */ ENTROPY_CONTEXT_PLANES left_context[4]; /* (up to) 4 contexts "" */ + // partition contexts + PARTITION_CONTEXT *above_seg_context; + PARTITION_CONTEXT left_seg_context[4]; + /* keyframe block modes are predicted by their above, left neighbors */ vp9_prob kf_bmode_prob[VP9_KF_BINTRAMODES] @@ -333,6 +337,10 @@ static void ref_cnt_fb(int *buf, int *idx, int new_idx) { buf[new_idx]++; } +static int mb_cols_aligned_to_sb(VP9_COMMON *cm) { + return (cm->mb_cols + 3) & ~3; +} + // TODO(debargha): merge the two functions static void set_mb_row(VP9_COMMON *cm, MACROBLOCKD *xd, int mb_row, int block_size) { diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 5352a0839..a0733524d 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -479,7 +479,7 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) { } else { nmv_context *const nmvc = &pbi->common.fc.nmvc; MACROBLOCKD *const xd = &pbi->mb; - int i, j; + int i; if (cm->mcomp_filter_type == SWITCHABLE) read_switchable_interp_probs(pbi, r); @@ -513,11 +513,6 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) { for (i = 0; i < VP9_I32X32_MODES - 1; ++i) cm->fc.sb_ymode_prob[i] = vp9_read_prob(r); - for (j = 0; j < PARTITION_PLANES; j++) - if (vp9_read_bit(r)) - for (i = 0; i < PARTITION_TYPES - 1; i++) - cm->fc.partition_prob[j][i] = vp9_read_prob(r); - read_nmvprobs(r, nmvc, xd->allow_high_precision_mv); } } diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 864eb82fd..a3445c03a 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -796,6 +796,8 @@ static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, xd->prev_mode_info_context = cm->prev_mi + mb_idx; xd->above_context = cm->above_context + mb_col; xd->left_context = cm->left_context + mb_row % 4; + xd->above_seg_context = cm->above_seg_context + mb_col; + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); // Distance of Mb to the various image edges. These are specified to 8th pel // as they are always compared to values that are in 1/8th pel units @@ -865,10 +867,14 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mb_row, int mb_col, return; if (bsize > BLOCK_SIZE_MB16X16) { + int pl; // read the partition information + xd->left_seg_context = pc->left_seg_context + (mb_row & 3); + xd->above_seg_context = pc->above_seg_context + mb_col; + pl = partition_plane_context(xd, bsize); partition = treed_read(r, vp9_partition_tree, - pc->fc.partition_prob[bsl - 1]); - pc->fc.partition_counts[bsl - 1][partition]++; + pc->fc.partition_prob[pl]); + pc->fc.partition_counts[pl][partition]++; } switch (partition) { @@ -907,6 +913,13 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mb_row, int mb_col, default: assert(0); } + // update partition context + if ((partition == PARTITION_SPLIT) && (bsize > BLOCK_SIZE_SB32X32)) + return; + + xd->left_seg_context = pc->left_seg_context + (mb_row & 3); + xd->above_seg_context = pc->above_seg_context + mb_col; + update_partition_context(xd, subsize, bsize); } /* Decode a row of Superblocks (4x4 region of MBs) */ @@ -918,6 +931,7 @@ static void decode_tile(VP9D_COMP *pbi, vp9_reader* r) { mb_row < pc->cur_tile_mb_row_end; mb_row += 4) { // For a SB there are 2 left contexts, each pertaining to a MB row within vpx_memset(pc->left_context, 0, sizeof(pc->left_context)); + vpx_memset(pc->left_seg_context, 0, sizeof(pc->left_seg_context)); for (mb_col = pc->cur_tile_mb_col_start; mb_col < pc->cur_tile_mb_col_end; mb_col += 4) { decode_modes_sb(pbi, mb_row, mb_col, r, BLOCK_SIZE_SB64X64); @@ -1359,7 +1373,10 @@ static void decode_tiles(VP9D_COMP *pbi, pc->tile_rows = 1 << pc->log2_tile_rows; vpx_memset(pc->above_context, 0, - sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols); + sizeof(ENTROPY_CONTEXT_PLANES) * mb_cols_aligned_to_sb(pc)); + + vpx_memset(pc->above_seg_context, 0, sizeof(PARTITION_CONTEXT) * + mb_cols_aligned_to_sb(pc)); if (pbi->oxcf.inv_tile_order) { const int n_cols = pc->tile_columns; diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index e80c9ccb7..978fdcdfe 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1176,6 +1176,7 @@ static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc, int mb_row, int mb_col, BLOCK_SIZE_TYPE bsize) { VP9_COMMON *const cm = &cpi->common; + MACROBLOCKD *xd = &cpi->mb.e_mbd; const int mis = cm->mode_info_stride; int bwl, bhl; #if CONFIG_SBSEGMENT @@ -1210,22 +1211,32 @@ static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc, else assert(0); - if (bsize > BLOCK_SIZE_MB16X16) + if (bsize > BLOCK_SIZE_MB16X16) { + int pl; + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, bsize); // encode the partition information - write_token(bc, vp9_partition_tree, cm->fc.partition_prob[bsl - 1], + write_token(bc, vp9_partition_tree, cm->fc.partition_prob[pl], vp9_partition_encodings + partition); + } switch (partition) { case PARTITION_NONE: + subsize = bsize; write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col); break; #if CONFIG_SBSEGMENT case PARTITION_HORZ: + subsize = (bsize == BLOCK_SIZE_SB64X64) ? BLOCK_SIZE_SB64X32 : + BLOCK_SIZE_SB32X16; write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col); if ((mb_row + bh) < cm->mb_rows) write_modes_b(cpi, m + bh * mis, bc, tok, tok_end, mb_row + bh, mb_col); break; case PARTITION_VERT: + subsize = (bsize == BLOCK_SIZE_SB64X64) ? BLOCK_SIZE_SB32X64 : + BLOCK_SIZE_SB16X32; write_modes_b(cpi, m, bc, tok, tok_end, mb_row, mb_col); if ((mb_col + bw) < cm->mb_cols) write_modes_b(cpi, m + bw, bc, tok, tok_end, mb_row, mb_col + bw); @@ -1249,6 +1260,14 @@ static void write_modes_sb(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc, default: assert(0); } + + // update partition context + if ((partition == PARTITION_SPLIT) && (bsize > BLOCK_SIZE_SB32X32)) + return; + + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); + xd->above_seg_context = cm->above_seg_context + mb_col; + update_partition_context(xd, subsize, bsize); } static void write_modes(VP9_COMP *cpi, vp9_writer* const bc, @@ -1259,9 +1278,13 @@ static void write_modes(VP9_COMP *cpi, vp9_writer* const bc, int mb_row, mb_col; m_ptr += c->cur_tile_mb_col_start + c->cur_tile_mb_row_start * mis; + vpx_memset(c->above_seg_context, 0, sizeof(PARTITION_CONTEXT) * + mb_cols_aligned_to_sb(c)); + for (mb_row = c->cur_tile_mb_row_start; mb_row < c->cur_tile_mb_row_end; mb_row += 4, m_ptr += 4 * mis) { m = m_ptr; + vpx_memset(c->left_seg_context, 0, sizeof(c->left_seg_context)); for (mb_col = c->cur_tile_mb_col_start; mb_col < c->cur_tile_mb_col_end; mb_col += 4, m += 4) write_modes_sb(cpi, m, bc, tok, tok_end, mb_row, mb_col, @@ -2253,14 +2276,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, } update_mbintra_mode_probs(cpi, &header_bc); - for (i = 0; i < PARTITION_PLANES; i++) { - vp9_prob Pnew[PARTITION_TYPES - 1]; - unsigned int bct[PARTITION_TYPES - 1][2]; - update_mode(&header_bc, PARTITION_TYPES, vp9_partition_encodings, - vp9_partition_tree, Pnew, pc->fc.partition_prob[i], bct, - (unsigned int *)cpi->partition_count[i]); - } - vp9_write_nmv_probs(cpi, xd->allow_high_precision_mv, &header_bc); } diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index 9d8abab33..eede4cb64 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -163,7 +163,7 @@ struct macroblock { PICK_MODE_CONTEXT sb64x32_context[2]; #endif PICK_MODE_CONTEXT sb64_context; - int partition_cost[PARTITION_PLANES][PARTITION_TYPES]; + int partition_cost[NUM_PARTITION_CONTEXTS][PARTITION_TYPES]; void (*fwd_txm4x4)(int16_t *input, int16_t *output, int pitch); void (*fwd_txm8x4)(int16_t *input, int16_t *output, int pitch); diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index b1b28c785..5bc164400 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -551,6 +551,10 @@ static void set_offsets(VP9_COMP *cpi, xd->above_context = cm->above_context + mb_col; xd->left_context = cm->left_context + (mb_row & 3); + // partition contexts + xd->above_seg_context = cm->above_seg_context + mb_col; + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); + // Activity map pointer x->mb_activity_ptr = &cpi->mb_activity_map[idx_map]; x->active_ptr = cpi->active_map + idx_map; @@ -749,6 +753,11 @@ static void encode_sb(VP9_COMP *cpi, MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; BLOCK_SIZE_TYPE bsize = BLOCK_SIZE_SB32X32; + int pl; + + xd->left_seg_context = cm->left_seg_context + (mb_row & 0x03); + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, bsize); if (is_sb == BLOCK_SIZE_SB32X32) { set_offsets(cpi, mb_row, mb_col, bsize); @@ -759,7 +768,7 @@ static void encode_sb(VP9_COMP *cpi, output_enabled, mb_row, mb_col, bsize); if (output_enabled) { update_stats(cpi, mb_row, mb_col); - cpi->partition_count[partition_plane(bsize)][PARTITION_NONE]++; + cpi->partition_count[pl][PARTITION_NONE]++; (*tp)->token = EOSB_TOKEN; (*tp)++; @@ -769,7 +778,7 @@ static void encode_sb(VP9_COMP *cpi, int i; if (output_enabled) - cpi->partition_count[partition_plane(bsize)][PARTITION_VERT]++; + cpi->partition_count[pl][PARTITION_VERT]++; for (i = 0; i < 2 && mb_col + i != cm->mb_cols; i++) { set_offsets(cpi, mb_row, mb_col + i, BLOCK_SIZE_SB16X32); update_state(cpi, &x->sb16x32_context[xd->sb_index][i], @@ -787,7 +796,7 @@ static void encode_sb(VP9_COMP *cpi, int i; if (output_enabled) - cpi->partition_count[partition_plane(bsize)][PARTITION_HORZ]++; + cpi->partition_count[pl][PARTITION_HORZ]++; for (i = 0; i < 2 && mb_row + i != cm->mb_rows; i++) { set_offsets(cpi, mb_row + i, mb_col, BLOCK_SIZE_SB32X16); update_state(cpi, &x->sb32x16_context[xd->sb_index][i], @@ -805,7 +814,7 @@ static void encode_sb(VP9_COMP *cpi, } else { int i; if (output_enabled) - cpi->partition_count[partition_plane(bsize)][PARTITION_SPLIT]++; + cpi->partition_count[pl][PARTITION_SPLIT]++; for (i = 0; i < 4; i++) { const int x_idx = i & 1, y_idx = i >> 1; @@ -834,6 +843,10 @@ static void encode_sb(VP9_COMP *cpi, } } + xd->above_seg_context = cm->above_seg_context + mb_col; + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); + update_partition_context(xd, is_sb, BLOCK_SIZE_SB32X32); + // debug output #if DBG_PRNT_SEGMAP { @@ -853,6 +866,11 @@ static void encode_sb64(VP9_COMP *cpi, MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; BLOCK_SIZE_TYPE bsize = BLOCK_SIZE_SB64X64; + int pl; + + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, bsize); if (is_sb[0] == BLOCK_SIZE_SB64X64) { set_offsets(cpi, mb_row, mb_col, bsize); @@ -863,12 +881,13 @@ static void encode_sb64(VP9_COMP *cpi, (*tp)->token = EOSB_TOKEN; (*tp)++; - cpi->partition_count[partition_plane(bsize)][PARTITION_NONE]++; + + cpi->partition_count[pl][PARTITION_NONE]++; #if CONFIG_SBSEGMENT } else if (is_sb[0] == BLOCK_SIZE_SB32X64) { int i; - cpi->partition_count[partition_plane(bsize)][PARTITION_VERT]++; + cpi->partition_count[pl][PARTITION_VERT]++; for (i = 0; i < 2 && mb_col + i * 2 != cm->mb_cols; i++) { set_offsets(cpi, mb_row, mb_col + i * 2, BLOCK_SIZE_SB32X64); update_state(cpi, &x->sb32x64_context[i], BLOCK_SIZE_SB32X64, 1); @@ -882,7 +901,7 @@ static void encode_sb64(VP9_COMP *cpi, } else if (is_sb[0] == BLOCK_SIZE_SB64X32) { int i; - cpi->partition_count[partition_plane(bsize)][PARTITION_HORZ]++; + cpi->partition_count[pl][PARTITION_HORZ]++; for (i = 0; i < 2 && mb_row + i * 2 != cm->mb_rows; i++) { set_offsets(cpi, mb_row + i * 2, mb_col, BLOCK_SIZE_SB64X32); update_state(cpi, &x->sb64x32_context[i], BLOCK_SIZE_SB64X32, 1); @@ -896,7 +915,7 @@ static void encode_sb64(VP9_COMP *cpi, #endif } else { int i; - cpi->partition_count[partition_plane(bsize)][PARTITION_SPLIT]++; + cpi->partition_count[pl][PARTITION_SPLIT]++; for (i = 0; i < 4; i++) { const int x_idx = i & 1, y_idx = i >> 1; @@ -910,6 +929,12 @@ static void encode_sb64(VP9_COMP *cpi, is_sb[i]); } } + + if (is_sb[0] > BLOCK_SIZE_SB32X32) { + xd->above_seg_context = cm->above_seg_context + mb_col; + xd->left_seg_context = cm->left_seg_context + (mb_row & 3); + update_partition_context(xd, is_sb[0], BLOCK_SIZE_SB64X64); + } } static void encode_sb_row(VP9_COMP *cpi, @@ -919,10 +944,11 @@ static void encode_sb_row(VP9_COMP *cpi, VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; - int mb_col; + int mb_col, pl; // Initialize the left context for the new SB row vpx_memset(cm->left_context, 0, sizeof(cm->left_context)); + vpx_memset(cm->left_seg_context, 0, sizeof(cm->left_seg_context)); // Code each SB in the row for (mb_col = cm->cur_tile_mb_col_start; @@ -932,10 +958,13 @@ static void encode_sb_row(VP9_COMP *cpi, int sb64_rate = 0, sb64_dist = 0; int sb64_skip = 0; ENTROPY_CONTEXT_PLANES l[4], a[4]; + PARTITION_CONTEXT seg_l[4], seg_a[4]; TOKENEXTRA *tp_orig = *tp; memcpy(&a, cm->above_context + mb_col, sizeof(a)); memcpy(&l, cm->left_context, sizeof(l)); + memcpy(&seg_a, cm->above_seg_context + mb_col, sizeof(seg_a)); + memcpy(&seg_l, cm->left_seg_context, sizeof(seg_l)); for (i = 0; i < 4; i++) { const int x_idx = (i & 1) << 1, y_idx = i & 2; int sb32_rate = 0, sb32_dist = 0; @@ -982,8 +1011,10 @@ static void encode_sb_row(VP9_COMP *cpi, vpx_memcpy(cm->left_context + y_idx, l2, sizeof(l2)); vpx_memcpy(cm->above_context + mb_col + x_idx, a2, sizeof(a2)); - sb32_rate += x->partition_cost[partition_plane(BLOCK_SIZE_SB32X32)] - [PARTITION_SPLIT]; + xd->left_seg_context = cm->left_seg_context + (y_idx & 3); + xd->above_seg_context = cm->above_seg_context + mb_col + x_idx; + pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32); + sb32_rate += x->partition_cost[pl][PARTITION_SPLIT]; if (cpi->sf.splitmode_breakout) { sb32_skip = splitmodes_used; @@ -1015,8 +1046,10 @@ static void encode_sb_row(VP9_COMP *cpi, d += d2; } - r += x->partition_cost[partition_plane(BLOCK_SIZE_SB32X32)] - [PARTITION_HORZ]; + xd->left_seg_context = cm->left_seg_context + (y_idx & 3); + xd->above_seg_context = cm->above_seg_context + mb_col + x_idx; + pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32); + r += x->partition_cost[pl][PARTITION_HORZ]; /* is this better than MB coding? */ if (RDCOST(x->rdmult, x->rddiv, r, d) < @@ -1054,8 +1087,10 @@ static void encode_sb_row(VP9_COMP *cpi, d += d2; } - r += x->partition_cost[partition_plane(BLOCK_SIZE_SB32X32)] - [PARTITION_VERT]; + xd->left_seg_context = cm->left_seg_context + (y_idx & 3); + xd->above_seg_context = cm->above_seg_context + mb_col + x_idx; + pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32); + r += x->partition_cost[pl][PARTITION_VERT]; /* is this better than MB coding? */ if (RDCOST(x->rdmult, x->rddiv, r, d) < @@ -1078,8 +1113,11 @@ static void encode_sb_row(VP9_COMP *cpi, pick_sb_modes(cpi, mb_row + y_idx, mb_col + x_idx, tp, &r, &d, BLOCK_SIZE_SB32X32, &x->sb32_context[xd->sb_index]); - r += x->partition_cost[partition_plane(BLOCK_SIZE_SB32X32)] - [PARTITION_NONE]; + + xd->left_seg_context = cm->left_seg_context + (y_idx & 3); + xd->above_seg_context = cm->above_seg_context + mb_col + x_idx; + pl = partition_plane_context(xd, BLOCK_SIZE_SB32X32); + r += x->partition_cost[pl][PARTITION_NONE]; if (RDCOST(x->rdmult, x->rddiv, r, d) < RDCOST(x->rdmult, x->rddiv, sb32_rate, sb32_dist)) { @@ -1109,9 +1147,13 @@ static void encode_sb_row(VP9_COMP *cpi, memcpy(cm->above_context + mb_col, &a, sizeof(a)); memcpy(cm->left_context, &l, sizeof(l)); + memcpy(cm->above_seg_context + mb_col, &seg_a, sizeof(seg_a)); + memcpy(cm->left_seg_context, &seg_l, sizeof(seg_l)); - sb64_rate += x->partition_cost[partition_plane(BLOCK_SIZE_SB64X64)] - [PARTITION_SPLIT]; + xd->left_seg_context = cm->left_seg_context; + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64); + sb64_rate += x->partition_cost[pl][PARTITION_SPLIT]; #if CONFIG_SBSEGMENT // check 64x32 @@ -1137,8 +1179,10 @@ static void encode_sb_row(VP9_COMP *cpi, d += d2; } - r += x->partition_cost[partition_plane(BLOCK_SIZE_SB64X64)] - [PARTITION_HORZ]; + xd->left_seg_context = cm->left_seg_context; + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64); + r += x->partition_cost[pl][PARTITION_HORZ]; /* is this better than MB coding? */ if (RDCOST(x->rdmult, x->rddiv, r, d) < @@ -1175,8 +1219,10 @@ static void encode_sb_row(VP9_COMP *cpi, d += d2; } - r += x->partition_cost[partition_plane(BLOCK_SIZE_SB64X64)] - [PARTITION_VERT]; + xd->left_seg_context = cm->left_seg_context; + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64); + r += x->partition_cost[pl][PARTITION_VERT]; /* is this better than MB coding? */ if (RDCOST(x->rdmult, x->rddiv, r, d) < @@ -1197,8 +1243,11 @@ static void encode_sb_row(VP9_COMP *cpi, pick_sb_modes(cpi, mb_row, mb_col, tp, &r, &d, BLOCK_SIZE_SB64X64, &x->sb64_context); - r += x->partition_cost[partition_plane(BLOCK_SIZE_SB64X64)] - [PARTITION_NONE]; + + xd->left_seg_context = cm->left_seg_context; + xd->above_seg_context = cm->above_seg_context + mb_col; + pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64); + r += x->partition_cost[pl][PARTITION_NONE]; if (RDCOST(x->rdmult, x->rddiv, r, d) < RDCOST(x->rdmult, x->rddiv, sb64_rate, sb64_dist)) { @@ -1268,7 +1317,9 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { #endif vpx_memset(cm->above_context, 0, - sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols); + sizeof(ENTROPY_CONTEXT_PLANES) * mb_cols_aligned_to_sb(cm)); + vpx_memset(cm->above_seg_context, 0, sizeof(PARTITION_CONTEXT) * + mb_cols_aligned_to_sb(cm)); } static void switch_lossless_mode(VP9_COMP *cpi, int lossless) { diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index e6a2a3183..4fff2334f 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -103,7 +103,7 @@ typedef struct { vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1]; vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1]; - vp9_prob partition_prob[PARTITION_PLANES][PARTITION_TYPES - 1]; + vp9_prob partition_prob[NUM_PARTITION_CONTEXTS][PARTITION_TYPES - 1]; vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1] [VP9_SWITCHABLE_FILTERS - 1]; @@ -457,7 +457,7 @@ typedef struct VP9_COMP { int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS]; int mbsplit_count[VP9_NUMMBSPLITS]; int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES]; - unsigned int partition_count[PARTITION_PLANES][PARTITION_TYPES]; + unsigned int partition_count[NUM_PARTITION_CONTEXTS][PARTITION_TYPES]; #if CONFIG_COMP_INTERINTRA_PRED unsigned int interintra_count[2]; unsigned int interintra_select_count[2]; diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 626769718..f846cf311 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -260,7 +260,7 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi, int qindex) { fill_token_costs(cpi->mb.token_costs[TX_32X32], cpi->common.fc.coef_probs_32x32, TX_32X32); - for (i = 0; i < 2; i++) + for (i = 0; i < NUM_PARTITION_CONTEXTS; i++) vp9_cost_tokens(cpi->mb.partition_cost[i], cpi->common.fc.partition_prob[i], vp9_partition_tree); |