From ef56088c2a65d72a937776f028d18954ae43eb55 Mon Sep 17 00:00:00 2001 From: "Nathan E. Egge" Date: Wed, 7 Sep 2016 18:20:41 -0400 Subject: [PATCH] Update kf_y_mode_cdf tables once per frame. Move computing the kf_y_mode_cdf tables per coded intra mode symbol to computing them only when the probabilities are updated. Change-Id: I5999447050c2f7d5dbccde80bee05ecd1c5440ab --- av1/common/entropymode.c | 8 ++++++++ av1/common/entropymode.h | 7 +++++++ av1/common/onyxc_int.h | 15 +++++++++++++++ av1/decoder/decodeframe.c | 10 +++++++++- av1/decoder/decodemv.c | 32 ++++++++++++++++++++++++++++++++ av1/decoder/decoder.c | 2 ++ av1/encoder/bitstream.c | 23 ++++++++++++++++++++++- 7 files changed, 95 insertions(+), 2 deletions(-) diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c index e7a47d0c1..b21dbc73d 100644 --- a/av1/common/entropymode.c +++ b/av1/common/entropymode.c @@ -146,6 +146,9 @@ const aom_prob av1_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = { { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm } }; +#if CONFIG_DAALA_EC +aom_cdf_prob av1_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][INTRA_MODES]; +#endif static const aom_prob default_if_y_probs[BLOCK_SIZE_GROUPS][INTRA_MODES - 1] = { { 65, 32, 18, 144, 162, 194, 41, 51, 98 }, // block_size < 8x8 @@ -219,6 +222,9 @@ static const aom_prob { 25, 29, 30 }, // 6 = two intra neighbours }; +int av1_intra_mode_ind[INTRA_MODES]; +int av1_intra_mode_inv[INTRA_MODES]; + /* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */ const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = { -DC_PRED, 2, /* 0 = DC_NODE */ @@ -868,6 +874,8 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { fc->inter_ext_tx_cdf, EXT_TX_SIZES); av1_tree_to_cdf_1D(av1_partition_tree, fc->partition_prob, fc->partition_cdf, PARTITION_CONTEXTS); + av1_tree_to_cdf_2D(av1_intra_mode_tree, av1_kf_y_mode_prob, av1_kf_y_mode_cdf, + INTRA_MODES, INTRA_MODES); #if CONFIG_MISC_FIXES av1_tree_to_cdf(av1_segment_tree, fc->seg.tree_probs, fc->seg.tree_cdf); #endif diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h index 871c2a42f..3cb0bb54f 100644 --- a/av1/common/entropymode.h +++ b/av1/common/entropymode.h @@ -158,6 +158,9 @@ typedef struct FRAME_COUNTS { extern const aom_prob av1_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1]; +#if CONFIG_DAALA_EC +extern aom_cdf_prob av1_kf_y_mode_cdf[INTRA_MODES][INTRA_MODES][INTRA_MODES]; +#endif #if CONFIG_PALETTE extern const aom_prob av1_default_palette_y_mode_prob[PALETTE_BLOCK_SIZES] @@ -175,6 +178,10 @@ extern const aom_prob av1_default_palette_uv_color_prob extern const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)]; extern const aom_tree_index av1_inter_mode_tree[TREE_SIZE(INTER_MODES)]; +#if CONFIG_DAALA_EC +extern int av1_intra_mode_ind[INTRA_MODES]; +extern int av1_intra_mode_inv[INTRA_MODES]; +#endif #if CONFIG_MOTION_VAR extern const aom_tree_index av1_motion_mode_tree[TREE_SIZE(MOTION_MODES)]; #endif // CONFIG_MOTION_VAR diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h index 7d388a1fa..2d0482049 100644 --- a/av1/common/onyxc_int.h +++ b/av1/common/onyxc_int.h @@ -337,6 +337,9 @@ typedef struct AV1Common { // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon // each keyframe and not used afterwards aom_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1]; +#if CONFIG_DAALA_EC + aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES][INTRA_MODES]; +#endif #if CONFIG_DERING int dering_level; #endif @@ -519,6 +522,18 @@ static INLINE const aom_prob *get_y_mode_probs(const AV1_COMMON *cm, return cm->kf_y_prob[above][left]; } +#if CONFIG_DAALA_EC +static INLINE const aom_cdf_prob *get_y_mode_cdf(const AV1_COMMON *cm, + const MODE_INFO *mi, + const MODE_INFO *above_mi, + const MODE_INFO *left_mi, + int block) { + const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, block); + const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, block); + return cm->kf_y_cdf[above][left]; +} +#endif + static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row, int mi_col, BLOCK_SIZE subsize, BLOCK_SIZE bsize) { diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 289575ff0..9bc8449ff 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -2052,11 +2052,19 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data, if (frame_is_intra_only(cm)) { av1_copy(cm->kf_y_prob, av1_kf_y_mode_prob); +#if CONFIG_DAALA_EC + av1_copy(cm->kf_y_cdf, av1_kf_y_mode_cdf); +#endif #if CONFIG_MISC_FIXES for (k = 0; k < INTRA_MODES; k++) - for (j = 0; j < INTRA_MODES; j++) + for (j = 0; j < INTRA_MODES; j++) { for (i = 0; i < INTRA_MODES - 1; ++i) av1_diff_update_prob(&r, &cm->kf_y_prob[k][j][i], ACCT_STR); +#if CONFIG_DAALA_EC + av1_tree_to_cdf(av1_intra_mode_tree, cm->kf_y_prob[k][j], + cm->kf_y_cdf[k][j]); +#endif + } #endif } else { #if !CONFIG_REF_MV diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c index e173acf66..d7acd9118 100644 --- a/av1/decoder/decodemv.c +++ b/av1/decoder/decodemv.c @@ -27,6 +27,13 @@ #define ACCT_STR __func__ +#if CONFIG_DAALA_EC +static PREDICTION_MODE read_intra_mode_cdf(aom_reader *r, + const aom_cdf_prob *cdf) { + return (PREDICTION_MODE) + av1_intra_mode_inv[aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR)]; +} +#endif static PREDICTION_MODE read_intra_mode(aom_reader *r, const aom_prob *p) { return (PREDICTION_MODE)aom_read_tree(r, av1_intra_mode_tree, p, ACCT_STR); } @@ -447,24 +454,49 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm, case BLOCK_4X4: for (i = 0; i < 4; ++i) mi->bmi[i].as_mode = +#if CONFIG_DAALA_EC + read_intra_mode_cdf(r, + get_y_mode_cdf(cm, mi, above_mi, left_mi, i)); +#else read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i)); +#endif mbmi->mode = mi->bmi[3].as_mode; break; case BLOCK_4X8: mi->bmi[0].as_mode = mi->bmi[2].as_mode = +#if CONFIG_DAALA_EC + read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0)); +#else read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); +#endif mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode = +#if CONFIG_DAALA_EC + read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 1)); +#else read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1)); +#endif break; case BLOCK_8X4: mi->bmi[0].as_mode = mi->bmi[1].as_mode = +#if CONFIG_DAALA_EC + read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0)); +#else read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); +#endif mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode = +#if CONFIG_DAALA_EC + read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 2)); +#else read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2)); +#endif break; default: mbmi->mode = +#if CONFIG_DAALA_EC + read_intra_mode_cdf(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0)); +#else read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); +#endif } mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode); diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c index a259641a1..ee3f7a5af 100644 --- a/av1/decoder/decoder.c +++ b/av1/decoder/decoder.c @@ -48,6 +48,8 @@ static void initialize_dec(void) { SWITCHABLE_FILTERS, av1_switchable_interp_tree); av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES, av1_ext_tx_tree); + av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, INTRA_MODES, + av1_intra_mode_tree); #endif } } diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index ee1116193..1d9283c20 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -111,6 +111,8 @@ void av1_encode_token_init() { structure. */ av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES, av1_ext_tx_tree); + av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv, INTRA_MODES, + av1_intra_mode_tree); #endif } @@ -873,8 +875,13 @@ static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd, write_selected_tx_size(cm, xd, w); if (bsize >= BLOCK_8X8) { +#if CONFIG_DAALA_EC + aom_write_symbol(w, av1_intra_mode_ind[mbmi->mode], + get_y_mode_cdf(cm, mi, above_mi, left_mi, 0), INTRA_MODES); +#else write_intra_mode(w, mbmi->mode, get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); +#endif } else { const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; @@ -883,8 +890,14 @@ static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd, for (idy = 0; idy < 2; idy += num_4x4_h) { for (idx = 0; idx < 2; idx += num_4x4_w) { const int block = idy * 2 + idx; +#if CONFIG_DAALA_EC + aom_write_symbol(w, av1_intra_mode_ind[mi->bmi[block].as_mode], + get_y_mode_cdf(cm, mi, above_mi, left_mi, block), + INTRA_MODES); +#else write_intra_mode(w, mi->bmi[block].as_mode, get_y_mode_probs(cm, mi, above_mi, left_mi, block)); +#endif } } } @@ -1968,11 +1981,19 @@ static size_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) { if (frame_is_intra_only(cm)) { av1_copy(cm->kf_y_prob, av1_kf_y_mode_prob); +#if CONFIG_DAALA_EC + av1_copy(cm->kf_y_cdf, av1_kf_y_mode_cdf); +#endif #if CONFIG_MISC_FIXES for (i = 0; i < INTRA_MODES; ++i) - for (j = 0; j < INTRA_MODES; ++j) + for (j = 0; j < INTRA_MODES; ++j) { prob_diff_update(av1_intra_mode_tree, cm->kf_y_prob[i][j], counts->kf_y_mode[i][j], INTRA_MODES, header_bc); +#if CONFIG_DAALA_EC + av1_tree_to_cdf(av1_intra_mode_tree, cm->kf_y_prob[i][j], + cm->kf_y_cdf[i][j]); +#endif + } #endif } else { #if CONFIG_REF_MV -- GitLab