From 1eb51a2010c95845d340ac7dafe311e4c1716d66 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 13 Oct 2015 14:08:24 -0400 Subject: [PATCH] vp10: allow forward updates for keyframe y intra mode probabilities. See issue 1040 point 5. Change-Id: I51a70b9eade39efba392a1457bd70a3c515525cb --- vp10/common/blockd.h | 9 --------- vp10/common/entropymode.h | 1 + vp10/common/onyxc_int.h | 15 +++++++++++++++ vp10/decoder/decodeframe.c | 10 +++++++++- vp10/decoder/decodemv.c | 12 ++++++------ vp10/encoder/bitstream.c | 18 +++++++++++++++--- vp10/encoder/encodeframe.c | 28 +++++++++++++++++++++++----- 7 files changed, 69 insertions(+), 24 deletions(-) diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h index ea73bfe26..4ba353fde 100644 --- a/vp10/common/blockd.h +++ b/vp10/common/blockd.h @@ -282,15 +282,6 @@ static INLINE void reset_skip_context(MACROBLOCKD *xd, BLOCK_SIZE bsize) { } } -static INLINE const vpx_prob *get_y_mode_probs(const MODE_INFO *mi, - const MODE_INFO *above_mi, - const MODE_INFO *left_mi, - int block) { - const PREDICTION_MODE above = vp10_above_block_mode(mi, above_mi, block); - const PREDICTION_MODE left = vp10_left_block_mode(mi, left_mi, block); - return vp10_kf_y_mode_prob[above][left]; -} - typedef void (*foreach_transformed_block_visitor)(int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h index 0e6a01808..c9b667ba4 100644 --- a/vp10/common/entropymode.h +++ b/vp10/common/entropymode.h @@ -76,6 +76,7 @@ typedef struct frame_contexts { } FRAME_CONTEXT; 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]; unsigned int partition[PARTITION_CONTEXTS][PARTITION_TYPES]; diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h index eac75a670..681413377 100644 --- a/vp10/common/onyxc_int.h +++ b/vp10/common/onyxc_int.h @@ -302,6 +302,11 @@ typedef struct VP10Common { PARTITION_CONTEXT *above_seg_context; ENTROPY_CONTEXT *above_context; int above_context_alloc_cols; + + // scratch memory for intraonly/keyframe forward updates from default tables + // - this is intentionally not placed in FRAME_CONTEXT since it's reset upon + // each keyframe and not used afterwards + vpx_prob kf_y_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1]; } VP10_COMMON; // TODO(hkuang): Don't need to lock the whole pool after implementing atomic @@ -443,6 +448,16 @@ static INLINE void set_mi_row_col(MACROBLOCKD *xd, const TileInfo *const tile, } } +static INLINE const vpx_prob *get_y_mode_probs(const VP10_COMMON *cm, + const MODE_INFO *mi, + const MODE_INFO *above_mi, + const MODE_INFO *left_mi, + int block) { + const PREDICTION_MODE above = vp10_above_block_mode(mi, above_mi, block); + const PREDICTION_MODE left = vp10_left_block_mode(mi, left_mi, block); + return cm->kf_y_prob[above][left]; +} + static INLINE void update_partition_context(MACROBLOCKD *xd, int mi_row, int mi_col, BLOCK_SIZE subsize, diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index e23ed91a1..53a76f4c1 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -2156,7 +2156,15 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data, vp10_diff_update_prob(&r, &fc->partition_prob[j][i]); #endif - if (!frame_is_intra_only(cm)) { + if (frame_is_intra_only(cm)) { + vp10_copy(cm->kf_y_prob, vp10_kf_y_mode_prob); +#if CONFIG_MISC_FIXES + for (k = 0; k < INTRA_MODES; k++) + for (j = 0; j < INTRA_MODES; j++) + for (i = 0; i < INTRA_MODES - 1; ++i) + vp10_diff_update_prob(&r, &cm->kf_y_prob[k][j][i]); +#endif + } else { nmv_context *const nmvc = &fc->nmvc; read_inter_mode_probs(fc, &r); diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c index 6c21e3c86..38ea0736a 100644 --- a/vp10/decoder/decodemv.c +++ b/vp10/decoder/decodemv.c @@ -305,24 +305,24 @@ static void read_intra_frame_mode_info(VP10_COMMON *const cm, case BLOCK_4X4: for (i = 0; i < 4; ++i) mi->bmi[i].as_mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i)); + read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i)); mbmi->mode = mi->bmi[3].as_mode; break; case BLOCK_4X8: mi->bmi[0].as_mode = mi->bmi[2].as_mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); + read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1)); + read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1)); break; case BLOCK_8X4: mi->bmi[0].as_mode = mi->bmi[1].as_mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0)); + read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode = - read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2)); + read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2)); break; default: mbmi->mode = read_intra_mode(r, - get_y_mode_probs(mi, above_mi, left_mi, 0)); + get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); } mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode); diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index bf66e017d..5ce33c461 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -455,7 +455,8 @@ static void write_mb_modes_kf(const VP10_COMMON *cm, const MACROBLOCKD *xd, write_selected_tx_size(cm, xd, w); if (bsize >= BLOCK_8X8) { - write_intra_mode(w, mbmi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0)); + write_intra_mode(w, mbmi->mode, + get_y_mode_probs(cm, mi, above_mi, left_mi, 0)); } else { const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; @@ -465,7 +466,7 @@ static void write_mb_modes_kf(const VP10_COMMON *cm, const MACROBLOCKD *xd, for (idx = 0; idx < 2; idx += num_4x4_w) { const int block = idy * 2 + idx; write_intra_mode(w, mi->bmi[block].as_mode, - get_y_mode_probs(mi, above_mi, left_mi, block)); + get_y_mode_probs(cm, mi, above_mi, left_mi, block)); } } } @@ -1348,6 +1349,9 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { FRAME_COUNTS *counts = cpi->td.counts; vpx_writer header_bc; int i; +#if CONFIG_MISC_FIXES + int j; +#endif vpx_start_encode(&header_bc, data); @@ -1373,7 +1377,15 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) { counts->partition[i], PARTITION_TYPES, &header_bc); #endif - if (!frame_is_intra_only(cm)) { + if (frame_is_intra_only(cm)) { + vp10_copy(cm->kf_y_prob, vp10_kf_y_mode_prob); +#if CONFIG_MISC_FIXES + for (i = 0; i < INTRA_MODES; ++i) + for (j = 0; j < INTRA_MODES; ++j) + prob_diff_update(vp10_intra_mode_tree, cm->kf_y_prob[i][j], + counts->kf_y_mode[i][j], INTRA_MODES, &header_bc); +#endif + } else { 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); diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c index bb16c10ba..c9e4cfbd5 100644 --- a/vp10/encoder/encodeframe.c +++ b/vp10/encoder/encodeframe.c @@ -2900,7 +2900,9 @@ void vp10_encode_frame(VP10_COMP *cpi) { } } -static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) { +static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi, + const MODE_INFO *above_mi, const MODE_INFO *left_mi, + const int intraonly) { const PREDICTION_MODE y_mode = mi->mbmi.mode; const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode; const BLOCK_SIZE bsize = mi->mbmi.sb_type; @@ -2910,10 +2912,25 @@ static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) { const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; for (idy = 0; idy < 2; idy += num_4x4_h) - for (idx = 0; idx < 2; idx += num_4x4_w) - ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode]; + for (idx = 0; idx < 2; idx += num_4x4_w) { + const int bidx = idy * 2 + idx; + const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode; + if (intraonly) { + const PREDICTION_MODE a = vp10_above_block_mode(mi, above_mi, bidx); + const PREDICTION_MODE l = vp10_left_block_mode(mi, left_mi, bidx); + ++counts->kf_y_mode[a][l][bmode]; + } else { + ++counts->y_mode[0][bmode]; + } + } } else { - ++counts->y_mode[size_group_lookup[bsize]][y_mode]; + if (intraonly) { + const PREDICTION_MODE above = vp10_above_block_mode(mi, above_mi, 0); + const PREDICTION_MODE left = vp10_left_block_mode(mi, left_mi, 0); + ++counts->kf_y_mode[above][left][y_mode]; + } else { + ++counts->y_mode[size_group_lookup[bsize]][y_mode]; + } } ++counts->uv_mode[y_mode][uv_mode]; @@ -2953,7 +2970,8 @@ static void encode_superblock(VP10_COMP *cpi, ThreadData *td, for (plane = 0; plane < MAX_MB_PLANE; ++plane) vp10_encode_intra_block_plane(x, VPXMAX(bsize, BLOCK_8X8), plane); if (output_enabled) - sum_intra_stats(td->counts, mi); + sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi, + frame_is_intra_only(cm)); if (bsize >= BLOCK_8X8 && output_enabled) { if (mbmi->palette_mode_info.palette_size[0] > 0) { -- 2.40.0