From: Ronald S. Bultje Date: Tue, 13 Oct 2015 18:07:47 +0000 (-0400) Subject: vp10: merge keyframe/interframe uvintramode/partition probabilities. X-Git-Tag: v1.5.0~27^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d8f3bb1837f7ef966b1a380359e84d15bb92e18b;p=libvpx vp10: merge keyframe/interframe uvintramode/partition probabilities. This has various benefits: - simplify implementations because we don't have to switch between multiple probability tables depending on frametype - allows fw subexp and bw adaptivity for partitions/uvmode in keyframes See issue 1040 point 5. Change-Id: Ia566aa2863252d130cee9deedcf123bb2a0d3765 --- diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h index 6d921b532..ea73bfe26 100644 --- a/vp10/common/blockd.h +++ b/vp10/common/blockd.h @@ -186,8 +186,6 @@ typedef struct macroblockd { int up_available; int left_available; - const vpx_prob (*partition_probs)[PARTITION_TYPES - 1]; - /* Distance of MB away from frame edges */ int mb_to_left_edge; int mb_to_right_edge; diff --git a/vp10/common/entropymode.c b/vp10/common/entropymode.c index 5a729f0b2..64a7c9263 100644 --- a/vp10/common/entropymode.c +++ b/vp10/common/entropymode.c @@ -127,6 +127,7 @@ const vpx_prob vp10_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = } }; +#if !CONFIG_MISC_FIXES const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = { { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v @@ -139,6 +140,7 @@ const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = { { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63 { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm }; +#endif static const vpx_prob default_if_y_probs[BLOCK_SIZE_GROUPS][INTRA_MODES - 1] = { { 65, 32, 18, 144, 162, 194, 41, 51, 98 }, // block_size < 8x8 @@ -147,7 +149,7 @@ static const vpx_prob default_if_y_probs[BLOCK_SIZE_GROUPS][INTRA_MODES - 1] = { { 221, 135, 38, 194, 248, 121, 96, 85, 29 } // block_size >= 32x32 }; -static const vpx_prob default_if_uv_probs[INTRA_MODES][INTRA_MODES - 1] = { +static const vpx_prob default_uv_probs[INTRA_MODES][INTRA_MODES - 1] = { { 120, 7, 76, 176, 208, 126, 28, 54, 103 }, // y = dc { 48, 12, 154, 155, 139, 90, 34, 117, 119 }, // y = v { 67, 6, 25, 204, 243, 158, 13, 21, 96 }, // y = h @@ -160,6 +162,7 @@ static const vpx_prob default_if_uv_probs[INTRA_MODES][INTRA_MODES - 1] = { { 101, 21, 107, 181, 192, 103, 19, 67, 125 } // y = tm }; +#if !CONFIG_MISC_FIXES const vpx_prob vp10_kf_partition_probs[PARTITION_CONTEXTS] [PARTITION_TYPES - 1] = { // 8x8 -> 4x4 @@ -183,6 +186,7 @@ const vpx_prob vp10_kf_partition_probs[PARTITION_CONTEXTS] { 57, 15, 9 }, // l split, a not split { 12, 3, 3 }, // a/l both split }; +#endif static const vpx_prob default_partition_probs[PARTITION_CONTEXTS] [PARTITION_TYPES - 1] = { @@ -755,7 +759,7 @@ static const struct segmentation_probs default_seg_probs = { #endif static void init_mode_probs(FRAME_CONTEXT *fc) { - vp10_copy(fc->uv_mode_prob, default_if_uv_probs); + vp10_copy(fc->uv_mode_prob, default_uv_probs); vp10_copy(fc->y_mode_prob, default_if_y_probs); vp10_copy(fc->switchable_interp_prob, default_switchable_interp_prob); vp10_copy(fc->partition_prob, default_partition_probs); @@ -806,6 +810,7 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i], counts->y_mode[i], fc->y_mode_prob[i]); +#if !CONFIG_MISC_FIXES for (i = 0; i < INTRA_MODES; ++i) vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->uv_mode_prob[i], counts->uv_mode[i], fc->uv_mode_prob[i]); @@ -813,6 +818,7 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { 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 if (cm->interp_filter == SWITCHABLE) { for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) @@ -869,6 +875,14 @@ void vp10_adapt_intra_frame_probs(VP10_COMMON *cm) { vpx_tree_merge_probs(vp10_segment_tree, pre_fc->seg.tree_probs, counts->seg.tree_total, fc->seg.tree_probs); } + + for (i = 0; i < INTRA_MODES; ++i) + vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->uv_mode_prob[i], + counts->uv_mode[i], fc->uv_mode_prob[i]); + + 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 } diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h index c5e3bc771..0e6a01808 100644 --- a/vp10/common/entropymode.h +++ b/vp10/common/entropymode.h @@ -97,11 +97,13 @@ typedef struct FRAME_COUNTS { #endif } FRAME_COUNTS; -extern const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; extern const vpx_prob vp10_kf_y_mode_prob[INTRA_MODES][INTRA_MODES] [INTRA_MODES - 1]; +#if !CONFIG_MISC_FIXES +extern const vpx_prob vp10_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; extern const vpx_prob vp10_kf_partition_probs[PARTITION_CONTEXTS] [PARTITION_TYPES - 1]; +#endif extern const vpx_prob vp10_default_palette_y_mode_prob[PALETTE_BLOCK_SIZES][PALETTE_Y_MODE_CONTEXTS]; extern const vpx_prob diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h index 4a20bb589..eac75a670 100644 --- a/vp10/common/onyxc_int.h +++ b/vp10/common/onyxc_int.h @@ -374,14 +374,6 @@ static INLINE int frame_is_intra_only(const VP10_COMMON *const cm) { return cm->frame_type == KEY_FRAME || cm->intra_only; } -static INLINE void set_partition_probs(const VP10_COMMON *const cm, - MACROBLOCKD *const xd) { - xd->partition_probs = - frame_is_intra_only(cm) ? - &vp10_kf_partition_probs[0] : - (const vpx_prob (*)[PARTITION_TYPES - 1])cm->fc->partition_prob; -} - static INLINE void vp10_init_macroblockd(VP10_COMMON *cm, MACROBLOCKD *xd, tran_low_t *dqcoeff) { int i; @@ -402,13 +394,6 @@ static INLINE void vp10_init_macroblockd(VP10_COMMON *cm, MACROBLOCKD *xd, xd->above_seg_context = cm->above_seg_context; xd->mi_stride = cm->mi_stride; xd->error_info = &cm->error; - - set_partition_probs(cm, xd); -} - -static INLINE const vpx_prob* get_partition_probs(const MACROBLOCKD *xd, - int ctx) { - return xd->partition_probs[ctx]; } static INLINE void set_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col) { diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index 1e1bba875..e23ed91a1 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -922,11 +922,11 @@ static INLINE void dec_update_partition_context(MACROBLOCKD *xd, memset(left_ctx, partition_context_lookup[subsize].left, bw); } -static PARTITION_TYPE read_partition(MACROBLOCKD *xd, int mi_row, int mi_col, - vpx_reader *r, +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) { const int ctx = dec_partition_plane_context(xd, mi_row, mi_col, bsl); - const vpx_prob *const probs = get_partition_probs(xd, ctx); + const vpx_prob *const probs = cm->fc->partition_prob[ctx]; FRAME_COUNTS *counts = xd->counts; PARTITION_TYPE p; @@ -961,7 +961,7 @@ static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd, if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; - partition = read_partition(xd, mi_row, mi_col, r, has_rows, has_cols, + partition = read_partition(cm, xd, mi_row, mi_col, r, has_rows, has_cols, n8x8_l2); subsize = subsize_lookup[partition][bsize]; // get_subsize(bsize, partition); if (!hbs) { @@ -2120,7 +2120,7 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data, #endif FRAME_CONTEXT *const fc = cm->fc; vpx_reader r; - int k; + int k, i, j; if (vpx_reader_init(&r, data, partition_size, pbi->decrypt_cb, pbi->decrypt_state)) @@ -2146,11 +2146,18 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data, for (k = 0; k < MAX_SEGMENTS - 1; k++) vp10_diff_update_prob(&r, &cm->fc->seg.tree_probs[k]); } + + for (j = 0; j < INTRA_MODES; j++) + for (i = 0; i < INTRA_MODES - 1; ++i) + vp10_diff_update_prob(&r, &fc->uv_mode_prob[j][i]); + + 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 if (!frame_is_intra_only(cm)) { nmv_context *const nmvc = &fc->nmvc; - int i, j; read_inter_mode_probs(fc, &r); @@ -2171,15 +2178,11 @@ 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->y_mode_prob[j][i]); -#if CONFIG_MISC_FIXES - for (j = 0; j < INTRA_MODES; j++) - for (i = 0; i < INTRA_MODES - 1; ++i) - vp10_diff_update_prob(&r, &fc->uv_mode_prob[j][i]); -#endif - +#if !CONFIG_MISC_FIXES 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 read_mv_probs(nmvc, cm->allow_high_precision_mv, &r); } diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c index 90a98b40f..6c21e3c86 100644 --- a/vp10/decoder/decodemv.c +++ b/vp10/decoder/decodemv.c @@ -325,7 +325,7 @@ static void read_intra_frame_mode_info(VP10_COMMON *const cm, get_y_mode_probs(mi, above_mi, left_mi, 0)); } - mbmi->uv_mode = read_intra_mode(r, vp10_kf_uv_mode_prob[mbmi->mode]); + mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode); mbmi->palette_mode_info.palette_size[0] = 0; mbmi->palette_mode_info.palette_size[1] = 0; diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 7dd8e4a34..bf66e017d 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -470,7 +470,7 @@ static void write_mb_modes_kf(const VP10_COMMON *cm, const MACROBLOCKD *xd, } } - write_intra_mode(w, mbmi->uv_mode, vp10_kf_uv_mode_prob[mbmi->mode]); + write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mbmi->mode]); if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools && mbmi->mode == DC_PRED) @@ -525,7 +525,7 @@ static void write_partition(const VP10_COMMON *const cm, int hbs, int mi_row, int mi_col, PARTITION_TYPE p, BLOCK_SIZE bsize, vpx_writer *w) { const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize); - const vpx_prob *const probs = xd->partition_probs[ctx]; + const vpx_prob *const probs = cm->fc->partition_prob[ctx]; const int has_rows = (mi_row + hbs) < cm->mi_rows; const int has_cols = (mi_col + hbs) < cm->mi_cols; @@ -603,12 +603,9 @@ static void write_modes_sb(VP10_COMP *cpi, static void write_modes(VP10_COMP *cpi, const TileInfo *const tile, vpx_writer *w, TOKENEXTRA **tok, const TOKENEXTRA *const tok_end) { - const VP10_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; int mi_row, mi_col; - set_partition_probs(cm, xd); - for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; mi_row += MI_BLOCK_SIZE) { vp10_zero(xd->left_seg_context); @@ -1350,6 +1347,7 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { FRAME_CONTEXT *const fc = cm->fc; FRAME_COUNTS *counts = cpi->td.counts; vpx_writer header_bc; + int i; vpx_start_encode(&header_bc, data); @@ -1365,11 +1363,17 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { update_skip_probs(cm, &header_bc, counts); #if CONFIG_MISC_FIXES update_seg_probs(cpi, &header_bc); + + for (i = 0; i < INTRA_MODES; ++i) + prob_diff_update(vp10_intra_mode_tree, fc->uv_mode_prob[i], + counts->uv_mode[i], INTRA_MODES, &header_bc); + + 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 if (!frame_is_intra_only(cm)) { - int i; - for (i = 0; i < INTER_MODE_CONTEXTS; ++i) prob_diff_update(vp10_inter_mode_tree, cm->fc->inter_mode_probs[i], counts->inter_mode[i], INTER_MODES, &header_bc); @@ -1420,15 +1424,11 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { prob_diff_update(vp10_intra_mode_tree, cm->fc->y_mode_prob[i], counts->y_mode[i], INTRA_MODES, &header_bc); -#if CONFIG_MISC_FIXES - for (i = 0; i < INTRA_MODES; ++i) - prob_diff_update(vp10_intra_mode_tree, cm->fc->uv_mode_prob[i], - counts->uv_mode[i], INTRA_MODES, &header_bc); -#endif - +#if !CONFIG_MISC_FIXES 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 vp10_write_nmv_probs(cm, cm->allow_high_precision_mv, &header_bc, &counts->mv); diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h index 98ded30d1..630032fa3 100644 --- a/vp10/encoder/encoder.h +++ b/vp10/encoder/encoder.h @@ -456,7 +456,7 @@ typedef struct VP10_COMP { int mbmode_cost[INTRA_MODES]; unsigned int inter_mode_cost[INTER_MODE_CONTEXTS][INTER_MODES]; - int intra_uv_mode_cost[FRAME_TYPES][INTRA_MODES]; + int intra_uv_mode_cost[INTRA_MODES]; int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES]; int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS]; int partition_cost[PARTITION_CONTEXTS][PARTITION_TYPES]; diff --git a/vp10/encoder/rd.c b/vp10/encoder/rd.c index 806b8542b..22d8f6de7 100644 --- a/vp10/encoder/rd.c +++ b/vp10/encoder/rd.c @@ -76,9 +76,7 @@ static void fill_mode_costs(VP10_COMP *cpi) { vp10_intra_mode_tree); vp10_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp10_intra_mode_tree); - vp10_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME], - vp10_kf_uv_mode_prob[TM_PRED], vp10_intra_mode_tree); - vp10_cost_tokens(cpi->intra_uv_mode_cost[INTER_FRAME], + vp10_cost_tokens(cpi->intra_uv_mode_cost, fc->uv_mode_prob[TM_PRED], vp10_intra_mode_tree); for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) @@ -287,7 +285,6 @@ static void set_block_thresholds(const VP10_COMMON *cm, RD_OPT *rd) { void vp10_initialize_rd_consts(VP10_COMP *cpi) { VP10_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->td.mb; - MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; RD_OPT *const rd = &cpi->rd; int i; @@ -303,14 +300,13 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) { cm->frame_type != KEY_FRAME) ? 0 : 1; set_block_thresholds(cm, rd); - set_partition_probs(cm, xd); fill_token_costs(x->token_costs, cm->fc->coef_probs); if (cpi->sf.partition_search_type != VAR_BASED_PARTITION || cm->frame_type == KEY_FRAME) { for (i = 0; i < PARTITION_CONTEXTS; ++i) - vp10_cost_tokens(cpi->partition_cost[i], get_partition_probs(xd, i), + vp10_cost_tokens(cpi->partition_cost[i], cm->fc->partition_prob[i], vp10_partition_tree); } diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index c9ad94557..4c9b4ba29 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c @@ -1347,8 +1347,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x, if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, &this_sse, bsize, best_rd)) continue; - this_rate = this_rate_tokenonly + - cpi->intra_uv_mode_cost[cpi->common.frame_type][mode]; + this_rate = this_rate_tokenonly + cpi->intra_uv_mode_cost[mode]; this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); if (this_rd < best_rd) { @@ -1371,14 +1370,13 @@ static int64_t rd_sbuv_dcpred(const VP10_COMP *cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly, int64_t *distortion, int *skippable, BLOCK_SIZE bsize) { - const VP10_COMMON *cm = &cpi->common; int64_t unused; x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED; memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm)); super_block_uvrd(cpi, x, rate_tokenonly, distortion, skippable, &unused, bsize, INT64_MAX); - *rate = *rate_tokenonly + cpi->intra_uv_mode_cost[cm->frame_type][DC_PRED]; + *rate = *rate_tokenonly + cpi->intra_uv_mode_cost[DC_PRED]; return RDCOST(x->rdmult, x->rddiv, *rate, *distortion); }