Splitting partition_probs array into two arrays. We only update partition_probs for inter frames but they are constant for key frames. It is not necessary to have constants inside frame context and copy them every time. This change reduces FRAME_CONTEXT size by at least 48 bytes. Change-Id: If70a53be51043f37fe7d113853217937710932a7
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index 5f388ae..c4d7c38 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c
@@ -161,51 +161,52 @@ { 101, 21, 107, 181, 192, 103, 19, 67, 125 } // y = tm }; -static const vp9_prob default_partition_probs[FRAME_TYPES][PARTITION_CONTEXTS] +const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS] + [PARTITION_TYPES - 1] = { + // 8x8 -> 4x4 + { 158, 97, 94 }, // a/l both not split + { 93, 24, 99 }, // a split, l not split + { 85, 119, 44 }, // l split, a not split + { 62, 59, 67 }, // a/l both split + // 16x16 -> 8x8 + { 149, 53, 53 }, // a/l both not split + { 94, 20, 48 }, // a split, l not split + { 83, 53, 24 }, // l split, a not split + { 52, 18, 18 }, // a/l both split + // 32x32 -> 16x16 + { 150, 40, 39 }, // a/l both not split + { 78, 12, 26 }, // a split, l not split + { 67, 33, 11 }, // l split, a not split + { 24, 7, 5 }, // a/l both split + // 64x64 -> 32x32 + { 174, 35, 49 }, // a/l both not split + { 68, 11, 27 }, // a split, l not split + { 57, 15, 9 }, // l split, a not split + { 12, 3, 3 }, // a/l both split +}; + +static const vp9_prob default_partition_probs[PARTITION_CONTEXTS] [PARTITION_TYPES - 1] = { - { // frame_type = keyframe - // 8x8 -> 4x4 - { 158, 97, 94 }, // a/l both not split - { 93, 24, 99 }, // a split, l not split - { 85, 119, 44 }, // l split, a not split - { 62, 59, 67 }, // a/l both split - // 16x16 -> 8x8 - { 149, 53, 53 }, // a/l both not split - { 94, 20, 48 }, // a split, l not split - { 83, 53, 24 }, // l split, a not split - { 52, 18, 18 }, // a/l both split - // 32x32 -> 16x16 - { 150, 40, 39 }, // a/l both not split - { 78, 12, 26 }, // a split, l not split - { 67, 33, 11 }, // l split, a not split - { 24, 7, 5 }, // a/l both split - // 64x64 -> 32x32 - { 174, 35, 49 }, // a/l both not split - { 68, 11, 27 }, // a split, l not split - { 57, 15, 9 }, // l split, a not split - { 12, 3, 3 }, // a/l both split - }, { // frame_type = interframe - // 8x8 -> 4x4 - { 199, 122, 141 }, // a/l both not split - { 147, 63, 159 }, // a split, l not split - { 148, 133, 118 }, // l split, a not split - { 121, 104, 114 }, // a/l both split - // 16x16 -> 8x8 - { 174, 73, 87 }, // a/l both not split - { 92, 41, 83 }, // a split, l not split - { 82, 99, 50 }, // l split, a not split - { 53, 39, 39 }, // a/l both split - // 32x32 -> 16x16 - { 177, 58, 59 }, // a/l both not split - { 68, 26, 63 }, // a split, l not split - { 52, 79, 25 }, // l split, a not split - { 17, 14, 12 }, // a/l both split - // 64x64 -> 32x32 - { 222, 34, 30 }, // a/l both not split - { 72, 16, 44 }, // a split, l not split - { 58, 32, 12 }, // l split, a not split - { 10, 7, 6 }, // a/l both split - } + // 8x8 -> 4x4 + { 199, 122, 141 }, // a/l both not split + { 147, 63, 159 }, // a split, l not split + { 148, 133, 118 }, // l split, a not split + { 121, 104, 114 }, // a/l both split + // 16x16 -> 8x8 + { 174, 73, 87 }, // a/l both not split + { 92, 41, 83 }, // a split, l not split + { 82, 99, 50 }, // l split, a not split + { 53, 39, 39 }, // a/l both split + // 32x32 -> 16x16 + { 177, 58, 59 }, // a/l both not split + { 68, 26, 63 }, // a split, l not split + { 52, 79, 25 }, // l split, a not split + { 17, 14, 12 }, // a/l both split + // 64x64 -> 32x32 + { 222, 34, 30 }, // a/l both not split + { 72, 16, 44 }, // a split, l not split + { 58, 32, 12 }, // l split, a not split + { 10, 7, 6 }, // a/l both split }; static const vp9_prob default_inter_mode_probs[INTER_MODE_CONTEXTS] @@ -404,10 +405,8 @@ fc->uv_mode_prob[i], 0); for (i = 0; i < PARTITION_CONTEXTS; i++) - update_mode_probs(PARTITION_TYPES, vp9_partition_tree, - counts->partition[i], - pre_fc->partition_prob[INTER_FRAME][i], - fc->partition_prob[INTER_FRAME][i], 0); + update_mode_probs(PARTITION_TYPES, vp9_partition_tree, counts->partition[i], + pre_fc->partition_prob[i], fc->partition_prob[i], 0); if (cm->mcomp_filter_type == SWITCHABLE) { for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h index ea96555..38b4199 100644 --- a/vp9/common/vp9_entropymode.h +++ b/vp9/common/vp9_entropymode.h
@@ -38,6 +38,9 @@ extern const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES] [INTRA_MODES - 1]; +extern const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS] + [PARTITION_TYPES - 1]; + extern const vp9_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)]; extern struct vp9_token vp9_intra_mode_encodings[INTRA_MODES];
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index ba2e9d8..a2af57a 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h
@@ -41,7 +41,7 @@ typedef struct frame_contexts { vp9_prob y_mode_prob[BLOCK_SIZE_GROUPS][INTRA_MODES - 1]; vp9_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; - vp9_prob partition_prob[FRAME_TYPES][PARTITION_CONTEXTS][PARTITION_TYPES - 1]; + vp9_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1]; vp9_coeff_probs_model coef_probs[TX_SIZES][BLOCK_TYPES]; vp9_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS] [SWITCHABLE_FILTERS - 1]; @@ -245,6 +245,11 @@ return ALIGN_POWER_OF_TWO(n_mis, MI_BLOCK_SIZE_LOG2); } +static INLINE const vp9_prob* get_partition_probs(VP9_COMMON *cm, int ctx) { + return cm->frame_type == KEY_FRAME ? vp9_kf_partition_probs[ctx] + : cm->fc.partition_prob[ctx]; +} + static INLINE void set_skip_context( MACROBLOCKD *xd, ENTROPY_CONTEXT *above_context[MAX_MB_PLANE],
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 41d1400..63b889d 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c
@@ -448,21 +448,30 @@ xd->corrupted |= vp9_reader_has_error(r); } -static PARTITION_TYPE read_partition(int hbs, int mi_rows, int mi_cols, - int mi_row, int mi_col, - vp9_prob probs[PARTITION_TYPES - 1], +static PARTITION_TYPE read_partition(VP9_COMMON *cm, MACROBLOCKD *xd, int hbs, + int mi_row, int mi_col, BLOCK_SIZE bsize, vp9_reader *r) { - const int has_rows = (mi_row + hbs) < mi_rows; - const int has_cols = (mi_col + hbs) < mi_cols; + const int ctx = partition_plane_context(xd->above_seg_context, + xd->left_seg_context, + mi_row, mi_col, bsize); + const vp9_prob *const probs = get_partition_probs(cm, ctx); + const int has_rows = (mi_row + hbs) < cm->mi_rows; + const int has_cols = (mi_col + hbs) < cm->mi_cols; + PARTITION_TYPE p; if (has_rows && has_cols) - return treed_read(r, vp9_partition_tree, probs); + p = treed_read(r, vp9_partition_tree, probs); else if (!has_rows && has_cols) - return vp9_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ; + p = vp9_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ; else if (has_rows && !has_cols) - return vp9_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT; + p = vp9_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT; else - return PARTITION_SPLIT; + p = PARTITION_SPLIT; + + if (!cm->frame_parallel_decoding_mode) + ++cm->counts.partition[ctx][p]; + + return p; } static void decode_modes_sb(VP9_COMMON *const cm, MACROBLOCKD *const xd, @@ -472,19 +481,11 @@ const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2; PARTITION_TYPE partition; BLOCK_SIZE subsize; - int ctx; if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - ctx = partition_plane_context(xd->above_seg_context, xd->left_seg_context, - mi_row, mi_col, bsize); - partition = read_partition(hbs, cm->mi_rows, cm->mi_cols, mi_row, mi_col, - cm->fc.partition_prob[cm->frame_type][ctx], r); - - if (!cm->frame_parallel_decoding_mode) - ++cm->counts.partition[ctx][partition]; - + partition = read_partition(cm, xd, hbs, mi_row, mi_col, bsize, r); subsize = get_subsize(bsize, partition); if (subsize < BLOCK_8X8) { decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize); @@ -1209,7 +1210,7 @@ for (j = 0; j < PARTITION_CONTEXTS; ++j) for (i = 0; i < PARTITION_TYPES - 1; ++i) - vp9_diff_update_prob(&r, &fc->partition_prob[INTER_FRAME][j][i]); + vp9_diff_update_prob(&r, &fc->partition_prob[j][i]); read_mv_probs(&r, nmvc, cm->allow_high_precision_mv); }
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 98bae90..87bd36c 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c
@@ -578,25 +578,26 @@ pack_mb_tokens(bc, tok, tok_end); } -static void write_partition(PARTITION_TYPE partition, - int hbs, int mi_rows, int mi_cols, - int mi_row, int mi_col, - vp9_prob probs[PARTITION_TYPES - 1], - vp9_writer *w) { - const int has_rows = (mi_row + hbs) < mi_rows; - const int has_cols = (mi_col + hbs) < mi_cols; +static void write_partition(VP9_COMP *cpi, int hbs, int mi_row, int mi_col, + PARTITION_TYPE p, BLOCK_SIZE bsize, vp9_writer *w) { + VP9_COMMON *const cm = &cpi->common; + const int ctx = partition_plane_context(cpi->above_seg_context, + cpi->left_seg_context, + mi_row, mi_col, bsize); + const vp9_prob *const probs = get_partition_probs(cm, ctx); + const int has_rows = (mi_row + hbs) < cm->mi_rows; + const int has_cols = (mi_col + hbs) < cm->mi_cols; if (has_rows && has_cols) { - write_token(w, vp9_partition_tree, probs, - &vp9_partition_encodings[partition]); + write_token(w, vp9_partition_tree, probs, &vp9_partition_encodings[p]); } else if (!has_rows && has_cols) { - assert(partition == PARTITION_SPLIT || partition == PARTITION_HORZ); - vp9_write(w, partition == PARTITION_SPLIT, probs[1]); + assert(p == PARTITION_SPLIT || p == PARTITION_HORZ); + vp9_write(w, p == PARTITION_SPLIT, probs[1]); } else if (has_rows && !has_cols) { - assert(partition == PARTITION_SPLIT || partition == PARTITION_VERT); - vp9_write(w, partition == PARTITION_SPLIT, probs[2]); + assert(p == PARTITION_SPLIT || p == PARTITION_VERT); + vp9_write(w, p == PARTITION_SPLIT, probs[2]); } else { - assert(partition == PARTITION_SPLIT); + assert(p == PARTITION_SPLIT); } } @@ -623,11 +624,7 @@ if (index > 0) return; } else { - const int ctx = partition_plane_context(cpi->above_seg_context, - cpi->left_seg_context, - mi_row, mi_col, bsize); - write_partition(partition, bs, cm->mi_rows, cm->mi_cols, mi_row, mi_col, - cm->fc.partition_prob[cm->frame_type][ctx], bc); + write_partition(cpi, bs, mi_row, mi_col, partition, bsize, bc); } subsize = get_subsize(bsize, partition); @@ -1452,7 +1449,7 @@ for (i = 0; i < PARTITION_CONTEXTS; ++i) { unsigned int bct[PARTITION_TYPES - 1][2]; update_mode(&header_bc, PARTITION_TYPES, vp9_partition_tree, - fc->partition_prob[cm->frame_type][i], bct, + fc->partition_prob[i], bct, (unsigned int *)cpi->partition_count[i]); }
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 682a2a6..05928e0 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c
@@ -251,8 +251,7 @@ fill_token_costs(cpi->mb.token_costs, cm->fc.coef_probs); for (i = 0; i < PARTITION_CONTEXTS; i++) - vp9_cost_tokens(cpi->mb.partition_cost[i], - cm->fc.partition_prob[cm->frame_type][i], + vp9_cost_tokens(cpi->mb.partition_cost[i], get_partition_probs(cm, i), vp9_partition_tree); /*rough estimate for costing*/