diff --git a/vp9/common/entropymode.c b/vp9/common/entropymode.c index 665528d487c7c38e0db73c6b59635b86a517bc36..5d33369163b064496c9815280d29c26d878bc0a8 100644 --- a/vp9/common/entropymode.c +++ b/vp9/common/entropymode.c @@ -290,7 +290,8 @@ struct vp9_token_struct vp9_bmode_encodings[VP9_NKF_BINTRAMODES]; struct vp9_token_struct vp9_kf_bmode_encodings[VP9_KF_BINTRAMODES]; struct vp9_token_struct vp9_ymode_encodings[VP9_YMODES]; #if CONFIG_SUPERBLOCKS -struct vp9_token_struct vp9_sb_kf_ymode_encodings [VP9_I32X32_MODES]; +struct vp9_token_struct vp9_sb_ymode_encodings[VP9_I32X32_MODES]; +struct vp9_token_struct vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES]; #endif struct vp9_token_struct vp9_kf_ymode_encodings[VP9_YMODES]; struct vp9_token_struct vp9_uv_mode_encodings[VP9_UV_MODES]; @@ -309,6 +310,11 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) { vp9_tree_probs_from_distribution(VP9_YMODES, vp9_ymode_encodings, vp9_ymode_tree, x->fc.ymode_prob, bct, y_mode_cts, 256, 1); +#if CONFIG_SUPERBLOCKS + vp9_tree_probs_from_distribution(VP9_I32X32_MODES, vp9_sb_ymode_encodings, + vp9_sb_ymode_tree, x->fc.sb_ymode_prob, + bct, y_mode_cts, 256, 1); +#endif { int i; for (i = 0; i < 8; i++) { @@ -318,7 +324,7 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) { #if CONFIG_SUPERBLOCKS vp9_tree_probs_from_distribution(VP9_I32X32_MODES, vp9_sb_kf_ymode_encodings, - vp9_sb_ymode_tree, + vp9_sb_kf_ymode_tree, x->sb_kf_ymode_prob[i], bct, kf_y_mode_cts[i], 256, 1); #endif @@ -421,7 +427,8 @@ void vp9_entropy_mode_init() { vp9_tokens_from_tree(vp9_ymode_encodings, vp9_ymode_tree); vp9_tokens_from_tree(vp9_kf_ymode_encodings, vp9_kf_ymode_tree); #if CONFIG_SUPERBLOCKS - vp9_tokens_from_tree(vp9_sb_kf_ymode_encodings, vp9_sb_ymode_tree); + vp9_tokens_from_tree(vp9_sb_ymode_encodings, vp9_sb_ymode_tree); + vp9_tokens_from_tree(vp9_sb_kf_ymode_encodings, vp9_sb_kf_ymode_tree); #endif vp9_tokens_from_tree(vp9_uv_mode_encodings, vp9_uv_mode_tree); vp9_tokens_from_tree(vp9_i8x8_mode_encodings, vp9_i8x8_mode_tree); @@ -505,8 +512,7 @@ void vp9_update_mode_context(VP9_COMMON *pc) { factor = (MVREF_MAX_UPDATE_FACTOR * count / MVREF_COUNT_SAT); this_prob = (pc->fc.vp9_mode_contexts[j][i] * (256 - factor) + this_prob * factor + 128) >> 8; - this_prob = this_prob ? (this_prob < 255 ? this_prob : 255) : 1; - mode_context[j][i] = this_prob; + mode_context[j][i] = clip_prob(this_prob); } } } @@ -540,6 +546,9 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { int i, t, count, factor; unsigned int branch_ct[32][2]; vp9_prob ymode_probs[VP9_YMODES - 1]; +#if CONFIG_SUPERBLOCKS + vp9_prob sb_ymode_probs[VP9_I32X32_MODES - 1]; +#endif vp9_prob uvmode_probs[VP9_UV_MODES - 1]; vp9_prob bmode_probs[VP9_NKF_BINTRAMODES - 1]; vp9_prob i8x8_mode_probs[VP9_I8X8_MODES - 1]; @@ -600,10 +609,24 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); prob = ((int)cm->fc.pre_ymode_prob[t] * (256 - factor) + (int)ymode_probs[t] * factor + 128) >> 8; - if (prob <= 0) cm->fc.ymode_prob[t] = 1; - else if (prob > 255) cm->fc.ymode_prob[t] = 255; - else cm->fc.ymode_prob[t] = prob; + cm->fc.ymode_prob[t] = clip_prob(prob); + } +#if CONFIG_SUPERBLOCKS + vp9_tree_probs_from_distribution(VP9_I32X32_MODES, + vp9_sb_ymode_encodings, vp9_sb_ymode_tree, + sb_ymode_probs, branch_ct, + cm->fc.sb_ymode_counts, + 256, 1); + for (t = 0; t < VP9_I32X32_MODES - 1; ++t) { + int prob; + count = branch_ct[t][0] + branch_ct[t][1]; + count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count; + factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); + prob = ((int)cm->fc.pre_sb_ymode_prob[t] * (256 - factor) + + (int)sb_ymode_probs[t] * factor + 128) >> 8; + cm->fc.sb_ymode_prob[t] = clip_prob(prob); } +#endif for (i = 0; i < VP9_YMODES; ++i) { vp9_tree_probs_from_distribution(VP9_UV_MODES, vp9_uv_mode_encodings, vp9_uv_mode_tree, uvmode_probs, branch_ct, @@ -615,9 +638,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); prob = ((int)cm->fc.pre_uv_mode_prob[i][t] * (256 - factor) + (int)uvmode_probs[t] * factor + 128) >> 8; - if (prob <= 0) cm->fc.uv_mode_prob[i][t] = 1; - else if (prob > 255) cm->fc.uv_mode_prob[i][t] = 255; - else cm->fc.uv_mode_prob[i][t] = prob; + cm->fc.uv_mode_prob[i][t] = clip_prob(prob); } } vp9_tree_probs_from_distribution(VP9_NKF_BINTRAMODES, vp9_bmode_encodings, @@ -630,9 +651,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); prob = ((int)cm->fc.pre_bmode_prob[t] * (256 - factor) + (int)bmode_probs[t] * factor + 128) >> 8; - if (prob <= 0) cm->fc.bmode_prob[t] = 1; - else if (prob > 255) cm->fc.bmode_prob[t] = 255; - else cm->fc.bmode_prob[t] = prob; + cm->fc.bmode_prob[t] = clip_prob(prob); } vp9_tree_probs_from_distribution(VP9_I8X8_MODES, vp9_i8x8_mode_encodings, vp9_i8x8_mode_tree, i8x8_mode_probs, @@ -644,9 +663,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); prob = ((int)cm->fc.pre_i8x8_mode_prob[t] * (256 - factor) + (int)i8x8_mode_probs[t] * factor + 128) >> 8; - if (prob <= 0) cm->fc.i8x8_mode_prob[t] = 1; - else if (prob > 255) cm->fc.i8x8_mode_prob[t] = 255; - else cm->fc.i8x8_mode_prob[t] = prob; + cm->fc.i8x8_mode_prob[t] = clip_prob(prob); } for (i = 0; i < SUBMVREF_COUNT; ++i) { vp9_tree_probs_from_distribution(VP9_SUBMVREFS, @@ -661,9 +678,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); prob = ((int)cm->fc.pre_sub_mv_ref_prob[i][t] * (256 - factor) + (int)sub_mv_ref_probs[t] * factor + 128) >> 8; - if (prob <= 0) cm->fc.sub_mv_ref_prob[i][t] = 1; - else if (prob > 255) cm->fc.sub_mv_ref_prob[i][t] = 255; - else cm->fc.sub_mv_ref_prob[i][t] = prob; + cm->fc.sub_mv_ref_prob[i][t] = clip_prob(prob); } } vp9_tree_probs_from_distribution(VP9_NUMMBSPLITS, vp9_mbsplit_encodings, @@ -676,9 +691,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT); prob = ((int)cm->fc.pre_mbsplit_prob[t] * (256 - factor) + (int)mbsplit_probs[t] * factor + 128) >> 8; - if (prob <= 0) cm->fc.mbsplit_prob[t] = 1; - else if (prob > 255) cm->fc.mbsplit_prob[t] = 255; - else cm->fc.mbsplit_prob[t] = prob; + cm->fc.mbsplit_prob[t] = clip_prob(prob); } #if CONFIG_COMP_INTERINTRA_PRED if (cm->use_interintra) { diff --git a/vp9/common/entropymode.h b/vp9/common/entropymode.h index 790f5597b96a6e86cabc599fef3c1ec884d9fc53..9f20ae94d8b5fd0c1212389112c3b99675477f79 100644 --- a/vp9/common/entropymode.h +++ b/vp9/common/entropymode.h @@ -53,6 +53,7 @@ extern const vp9_tree_index vp9_ymode_tree[]; extern const vp9_tree_index vp9_kf_ymode_tree[]; extern const vp9_tree_index vp9_uv_mode_tree[]; #define vp9_sb_ymode_tree vp9_uv_mode_tree +#define vp9_sb_kf_ymode_tree vp9_uv_mode_tree extern const vp9_tree_index vp9_i8x8_mode_tree[]; extern const vp9_tree_index vp9_mbsplit_tree[]; extern const vp9_tree_index vp9_mv_ref_tree[]; @@ -62,6 +63,7 @@ extern const vp9_tree_index vp9_sub_mv_ref_tree[]; extern struct vp9_token_struct vp9_bmode_encodings[VP9_NKF_BINTRAMODES]; extern struct vp9_token_struct vp9_kf_bmode_encodings[VP9_KF_BINTRAMODES]; extern struct vp9_token_struct vp9_ymode_encodings[VP9_YMODES]; +extern struct vp9_token_struct vp9_sb_ymode_encodings[VP9_I32X32_MODES]; extern struct vp9_token_struct vp9_sb_kf_ymode_encodings[VP9_I32X32_MODES]; extern struct vp9_token_struct vp9_kf_ymode_encodings[VP9_YMODES]; extern struct vp9_token_struct vp9_i8x8_mode_encodings[VP9_I8X8_MODES]; diff --git a/vp9/common/onyxc_int.h b/vp9/common/onyxc_int.h index f76c8a0088b42db8cfbf310796bd1528581aea0a..beefdbc055c800b4c6c01a5bea9470535df95b22 100644 --- a/vp9/common/onyxc_int.h +++ b/vp9/common/onyxc_int.h @@ -46,6 +46,9 @@ void vp9_initialize_common(void); typedef struct frame_contexts { vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1]; vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */ +#if CONFIG_SUPERBLOCKS + vp9_prob sb_ymode_prob[VP9_I32X32_MODES - 1]; +#endif vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1]; vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1]; vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; @@ -61,12 +64,18 @@ typedef struct frame_contexts { nmv_context pre_nmvc; vp9_prob pre_bmode_prob[VP9_NKF_BINTRAMODES - 1]; vp9_prob pre_ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */ +#if CONFIG_SUPERBLOCKS + vp9_prob pre_sb_ymode_prob[VP9_I32X32_MODES - 1]; +#endif vp9_prob pre_uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1]; 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]; unsigned int bmode_counts[VP9_NKF_BINTRAMODES]; unsigned int ymode_counts[VP9_YMODES]; /* interframe intra mode probs */ +#if CONFIG_SUPERBLOCKS + unsigned int sb_ymode_counts[VP9_I32X32_MODES]; +#endif unsigned int uv_mode_counts[VP9_YMODES][VP9_UV_MODES]; unsigned int i8x8_mode_counts[VP9_I8X8_MODES]; /* interframe intra probs */ unsigned int sub_mv_ref_counts[SUBMVREF_COUNT][VP9_SUBMVREFS]; diff --git a/vp9/common/treecoder.h b/vp9/common/treecoder.h index 1ebc82d3637c97347dc4758b227229ab22f20978..92b92ef5562d0661e21eb1688e732d4b08f6e3cd 100644 --- a/vp9/common/treecoder.h +++ b/vp9/common/treecoder.h @@ -70,6 +70,14 @@ void vp9_tree_probs_from_distribution( int Round ); +static __inline int clip_prob(int p) { + if (p > 255) + return 255; + else if (p < 1) + return 1; + return p; +} + vp9_prob vp9_bin_prob_from_distribution(const unsigned int counts[2]); #endif diff --git a/vp9/decoder/decodemv.c b/vp9/decoder/decodemv.c index a247f03b811620caeaaec8750bbed77793261a28..0e5f66b60ad2ff97ef702d94b7147419dcbbaaf4 100644 --- a/vp9/decoder/decodemv.c +++ b/vp9/decoder/decodemv.c @@ -48,6 +48,10 @@ static int read_ymode(vp9_reader *bc, const vp9_prob *p) { } #if CONFIG_SUPERBLOCKS +static int read_sb_ymode(vp9_reader *bc, const vp9_prob *p) { + return treed_read(bc, vp9_sb_ymode_tree, p); +} + static int read_kf_sb_ymode(vp9_reader *bc, const vp9_prob *p) { return treed_read(bc, vp9_uv_mode_tree, p); } @@ -564,6 +568,16 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *bc) { } while (++i < VP9_YMODES - 1); } +#if CONFIG_SUPERBLOCKS + if (vp9_read_bit(bc)) { + int i = 0; + + do { + cm->fc.sb_ymode_prob[i] = (vp9_prob) vp9_read_literal(bc, 8); + } while (++i < VP9_I32X32_MODES - 1); + } +#endif + #if CONFIG_NEW_MVREF // Temp defaults probabilities for ecnoding the MV ref id signal vpx_memset(xd->mb_mv_ref_id_probs, 192, sizeof(xd->mb_mv_ref_id_probs)); @@ -1106,11 +1120,16 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, /* required for left and above block mv */ mbmi->mv[0].as_int = 0; - if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_MODE)) + if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_MODE)) { mbmi->mode = (MB_PREDICTION_MODE) vp9_get_segdata(xd, mbmi->segment_id, SEG_LVL_MODE); - else { - // FIXME write using SB mode tree +#if CONFIG_SUPERBLOCKS + } else if (mbmi->encoded_as_sb) { + mbmi->mode = (MB_PREDICTION_MODE) + read_sb_ymode(bc, pbi->common.fc.sb_ymode_prob); + pbi->common.fc.sb_ymode_counts[mbmi->mode]++; +#endif + } else { mbmi->mode = (MB_PREDICTION_MODE) read_ymode(bc, pbi->common.fc.ymode_prob); pbi->common.fc.ymode_counts[mbmi->mode]++; diff --git a/vp9/decoder/decodframe.c b/vp9/decoder/decodframe.c index 2642e5a6cd299d488b23f5055effc3d4fe492a87..a32423b178db6edb335e06a68c8994bb8d2dc202 100644 --- a/vp9/decoder/decodframe.c +++ b/vp9/decoder/decodframe.c @@ -1353,6 +1353,9 @@ int vp9_decode_frame(VP9D_COMP *pbi) { vp9_copy(pbi->common.fc.pre_hybrid_coef_probs_16x16, pbi->common.fc.hybrid_coef_probs_16x16); vp9_copy(pbi->common.fc.pre_ymode_prob, pbi->common.fc.ymode_prob); +#if CONFIG_SUPERBLOCKS + vp9_copy(pbi->common.fc.pre_sb_ymode_prob, pbi->common.fc.sb_ymode_prob); +#endif vp9_copy(pbi->common.fc.pre_uv_mode_prob, pbi->common.fc.uv_mode_prob); vp9_copy(pbi->common.fc.pre_bmode_prob, pbi->common.fc.bmode_prob); vp9_copy(pbi->common.fc.pre_i8x8_mode_prob, pbi->common.fc.i8x8_mode_prob); @@ -1369,6 +1372,9 @@ int vp9_decode_frame(VP9D_COMP *pbi) { vp9_zero(pbi->common.fc.coef_counts_16x16); vp9_zero(pbi->common.fc.hybrid_coef_counts_16x16); vp9_zero(pbi->common.fc.ymode_counts); +#if CONFIG_SUPERBLOCKS + vp9_zero(pbi->common.fc.sb_ymode_counts); +#endif vp9_zero(pbi->common.fc.uv_mode_counts); vp9_zero(pbi->common.fc.bmode_counts); vp9_zero(pbi->common.fc.i8x8_mode_counts); diff --git a/vp9/encoder/bitstream.c b/vp9/encoder/bitstream.c index 6f2771adc783bce3bb4138fdb8a2b35c2b17ff01..9be2db0040bcd04b4f5d4076d1ebbbafd8d97e38 100644 --- a/vp9/encoder/bitstream.c +++ b/vp9/encoder/bitstream.c @@ -164,6 +164,11 @@ static void update_mbintra_mode_probs(VP9_COMP* const cpi, bc, VP9_YMODES, vp9_ymode_encodings, vp9_ymode_tree, Pnew, cm->fc.ymode_prob, bct, (unsigned int *)cpi->ymode_count ); +#if CONFIG_SUPERBLOCKS + update_mode(bc, VP9_I32X32_MODES, vp9_sb_ymode_encodings, + vp9_sb_ymode_tree, Pnew, cm->fc.sb_ymode_prob, bct, + (unsigned int *)cpi->sb_ymode_count); +#endif } } @@ -172,11 +177,7 @@ static int get_prob(int num, int den) { if (den <= 0) return 128; p = (num * 255 + (den >> 1)) / den; - if (p > 255) - return 255; - else if (p < 1) - return 1; - return p; + return clip_prob(p); } static int get_binary_prob(int n0, int n1) { @@ -300,6 +301,10 @@ static void kfwrite_ymode(vp9_writer *bc, int m, const vp9_prob *p) { } #if CONFIG_SUPERBLOCKS +static void write_sb_ymode(vp9_writer *bc, int m, const vp9_prob *p) { + write_token(bc, vp9_sb_ymode_tree, p, vp9_sb_ymode_encodings + m); +} + static void sb_kfwrite_ymode(vp9_writer *bc, int m, const vp9_prob *p) { write_token(bc, vp9_uv_mode_tree, p, vp9_sb_kf_ymode_encodings + m); } @@ -926,9 +931,12 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) { active_section = 6; #endif - // TODO(rbultje) write using SB tree structure - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_MODE)) { +#if CONFIG_SUPERBLOCKS + if (m->mbmi.encoded_as_sb) + write_sb_ymode(bc, mode, pc->fc.sb_ymode_prob); + else +#endif write_ymode(bc, mode, pc->fc.ymode_prob); } @@ -2144,6 +2152,9 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, vp9_copy(cpi->common.fc.pre_hybrid_coef_probs_8x8, cpi->common.fc.hybrid_coef_probs_8x8); vp9_copy(cpi->common.fc.pre_coef_probs_16x16, cpi->common.fc.coef_probs_16x16); vp9_copy(cpi->common.fc.pre_hybrid_coef_probs_16x16, cpi->common.fc.hybrid_coef_probs_16x16); +#if CONFIG_SUPERBLOCKS + vp9_copy(cpi->common.fc.pre_sb_ymode_prob, cpi->common.fc.sb_ymode_prob); +#endif vp9_copy(cpi->common.fc.pre_ymode_prob, cpi->common.fc.ymode_prob); vp9_copy(cpi->common.fc.pre_uv_mode_prob, cpi->common.fc.uv_mode_prob); vp9_copy(cpi->common.fc.pre_bmode_prob, cpi->common.fc.bmode_prob); diff --git a/vp9/encoder/encodeframe.c b/vp9/encoder/encodeframe.c index 7ac0bd3310db58f10f10546721af022702397fc0..a3fe052f43719eb416b4107fc21d5b6024b29ec8 100644 --- a/vp9/encoder/encodeframe.c +++ b/vp9/encoder/encodeframe.c @@ -2139,10 +2139,6 @@ static void encode_macroblock(VP9_COMP *cpi, MACROBLOCK *x, } } - if (output_enabled && cm->frame_type == KEY_FRAME) { - sum_intra_stats(cpi, x); - } - if (!x->skip) { #ifdef ENC_DEBUG if (enc_debug) { @@ -2286,6 +2282,7 @@ static void encode_superblock(VP9_COMP *cpi, MACROBLOCK *x, if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { vp9_build_intra_predictors_sby_s(&x->e_mbd); vp9_build_intra_predictors_sbuv_s(&x->e_mbd); + sum_intra_stats(cpi, x); } else { int ref_fb_idx; @@ -2376,10 +2373,6 @@ static void encode_superblock(VP9_COMP *cpi, MACROBLOCK *x, } } - if (cm->frame_type == KEY_FRAME) { - sum_intra_stats(cpi, x); - } - xd->mode_info_context = mi; update_sb_skip_coeff_state(cpi, x, ta, tl, tp, t, skip); if (cm->txfm_mode == TX_MODE_SELECT && diff --git a/vp9/encoder/modecosts.c b/vp9/encoder/modecosts.c index f7c38eacd7bdc90618839ba4c253e3d53fceda2e..d5266c025cc0a2fa96f31ce2e723d5fb6deee898 100644 --- a/vp9/encoder/modecosts.c +++ b/vp9/encoder/modecosts.c @@ -32,6 +32,7 @@ void vp9_init_mode_costs(VP9_COMP *c) { vp9_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.sub_mv_ref_prob[0], vp9_sub_mv_ref_tree); + // TODO(rbultje) separate tables for superblock costing? vp9_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp9_ymode_tree); vp9_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob[c->common.kf_ymode_probs_index], diff --git a/vp9/encoder/onyx_if.c b/vp9/encoder/onyx_if.c index 215436134b8f753e6c8386e40e965ac57c4a4bbf..333a4f30c44b93e78a3229510d1835f2f6859f2e 100644 --- a/vp9/encoder/onyx_if.c +++ b/vp9/encoder/onyx_if.c @@ -3725,6 +3725,9 @@ static void encode_frame_to_data_rate cpi->hybrid_coef_counts_16x16); vp9_adapt_coef_probs(&cpi->common); if (cpi->common.frame_type != KEY_FRAME) { +#if CONFIG_SUPERBLOCKS + vp9_copy(cpi->common.fc.sb_ymode_counts, cpi->sb_ymode_count); +#endif vp9_copy(cpi->common.fc.ymode_counts, cpi->ymode_count); vp9_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count); vp9_copy(cpi->common.fc.bmode_counts, cpi->bmode_count); diff --git a/vp9/encoder/onyx_int.h b/vp9/encoder/onyx_int.h index 1177451e0979b2c4f0be8a1a43a7b8717ba1096d..696c0e36c7b0659b50f12e1cce580e488d9150ec 100644 --- a/vp9/encoder/onyx_int.h +++ b/vp9/encoder/onyx_int.h @@ -110,6 +110,9 @@ typedef struct { vp9_prob hybrid_coef_probs_16x16[BLOCK_TYPES_16X16] [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]; +#if CONFIG_SUPERBLOCKS + vp9_prob sb_ymode_prob[VP9_I32X32_MODES - 1]; +#endif vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */ vp9_prob uv_mode_prob[VP9_YMODES][VP9_UV_MODES - 1]; vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1]; diff --git a/vp9/encoder/ratectrl.c b/vp9/encoder/ratectrl.c index af93d8b42625e405b1f3aff7581a341c6e1e14a4..e4972d2156f664a60bcce2dd7d66675f73693147 100644 --- a/vp9/encoder/ratectrl.c +++ b/vp9/encoder/ratectrl.c @@ -139,6 +139,9 @@ void vp9_save_coding_context(VP9_COMP *cpi) { vp9_copy(cc->mode_context_a, cm->fc.mode_context_a); vp9_copy(cc->ymode_prob, cm->fc.ymode_prob); +#if CONFIG_SUPERBLOCKS + vp9_copy(cc->sb_ymode_prob, cm->fc.sb_ymode_prob); +#endif vp9_copy(cc->bmode_prob, cm->fc.bmode_prob); vp9_copy(cc->uv_mode_prob, cm->fc.uv_mode_prob); vp9_copy(cc->i8x8_mode_prob, cm->fc.i8x8_mode_prob); @@ -195,6 +198,9 @@ void vp9_restore_coding_context(VP9_COMP *cpi) { vp9_copy(cm->fc.mode_context_a, cc->mode_context_a); vp9_copy(cm->fc.ymode_prob, cc->ymode_prob); +#if CONFIG_SUPERBLOCKS + vp9_copy(cm->fc.sb_ymode_prob, cc->sb_ymode_prob); +#endif vp9_copy(cm->fc.bmode_prob, cc->bmode_prob); vp9_copy(cm->fc.i8x8_mode_prob, cc->i8x8_mode_prob); vp9_copy(cm->fc.uv_mode_prob, cc->uv_mode_prob); diff --git a/vp9/encoder/rdopt.c b/vp9/encoder/rdopt.c index 7f1d7b321565b90b304e9e0177635833aa76ff1f..5d0b111ce3f0f6f9d8d331175f93634624e7727a 100644 --- a/vp9/encoder/rdopt.c +++ b/vp9/encoder/rdopt.c @@ -4578,6 +4578,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int64_t best_intra16_rd = INT64_MAX; int best_intra16_mode = DC_PRED, best_intra16_uv_mode = DC_PRED; #endif + int rate_uv_4x4, rate_uv_8x8, rate_uv_tokenonly_4x4, rate_uv_tokenonly_8x8; + int dist_uv_4x4, dist_uv_8x8, uv_skip_4x4, uv_skip_8x8; + MB_PREDICTION_MODE mode_uv_4x4, mode_uv_8x8; x->skip = 0; xd->mode_info_context->mbmi.segment_id = segment_id; @@ -4600,8 +4603,22 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, frame_mv[ZEROMV][ref_frame].as_int = 0; } + mbmi->mode = DC_PRED; + if (cm->txfm_mode == ONLY_4X4 || cm->txfm_mode == TX_MODE_SELECT) { + mbmi->txfm_size = TX_4X4; + rd_pick_intra_sbuv_mode(cpi, x, &rate_uv_4x4, &rate_uv_tokenonly_4x4, + &dist_uv_4x4, &uv_skip_4x4); + mode_uv_4x4 = mbmi->uv_mode; + } + if (cm->txfm_mode != ONLY_4X4) { + mbmi->txfm_size = TX_8X8; + rd_pick_intra_sbuv_mode(cpi, x, &rate_uv_8x8, &rate_uv_tokenonly_8x8, + &dist_uv_8x8, &uv_skip_8x8); + mode_uv_8x8 = mbmi->uv_mode; + } + for (mode_index = 0; mode_index < MAX_MODES; mode_index++) { - int mode_excluded; + int mode_excluded = 0; int64_t this_rd = INT64_MAX; int disable_skip = 0; int other_cost = 0; @@ -4621,6 +4638,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, this_mode = vp9_mode_order[mode_index].mode; ref_frame = vp9_mode_order[mode_index].ref_frame; + assert(ref_frame == INTRA_FRAME || + (cpi->ref_frame_flags & flag_list[ref_frame])); mbmi->ref_frame = ref_frame; comp_pred = vp9_mode_order[mode_index].second_ref_frame > INTRA_FRAME; mbmi->mode = this_mode; @@ -4633,9 +4652,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, if (!(cpi->ref_frame_flags & flag_list[ref_frame])) continue; - // not yet supported or not superblocky - // TODO(rbultje): support intra coding - if (ref_frame == INTRA_FRAME || this_mode == SPLITMV || + // TODO(debargha): intra/inter encoding at SB level + if (this_mode == I8X8_PRED || this_mode == B_PRED || this_mode == SPLITMV || vp9_mode_order[mode_index].second_ref_frame == INTRA_FRAME) continue; @@ -4657,7 +4675,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, mode_excluded = cm->comp_pred_mode == SINGLE_PREDICTION_ONLY; } else { mbmi->second_ref_frame = NONE; - mode_excluded = cm->comp_pred_mode == COMP_PREDICTION_ONLY; + if (ref_frame != INTRA_FRAME) + mode_excluded = cm->comp_pred_mode == COMP_PREDICTION_ONLY; } xd->pre.y_buffer = y_buffer[ref_frame]; @@ -4690,19 +4709,39 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } - this_rd = handle_inter_mode(cpi, x, BLOCK_32X32, - &saddone, near_sadidx, mdcounts, txfm_cache, - &rate2, &distortion2, &skippable, - &compmode_cost, + if (ref_frame == INTRA_FRAME) { + vp9_build_intra_predictors_sby_s(xd); + super_block_yrd(cpi, x, &rate_y, &distortion_y, + IF_RTCD(&cpi->rtcd), &skippable, txfm_cache); + if (mbmi->txfm_size == TX_4X4) { + rate_uv = rate_uv_4x4; + distortion_uv = dist_uv_4x4; + skippable = skippable && uv_skip_4x4; + mbmi->uv_mode = mode_uv_4x4; + } else { + rate_uv = rate_uv_8x8; + distortion_uv = dist_uv_8x8; + skippable = skippable && uv_skip_8x8; + mbmi->uv_mode = mode_uv_8x8; + } + + rate2 = rate_y + x->mbmode_cost[cm->frame_type][mbmi->mode] + rate_uv; + distortion2 = distortion_y + distortion_uv; + } else { + this_rd = handle_inter_mode(cpi, x, BLOCK_32X32, + &saddone, near_sadidx, mdcounts, txfm_cache, + &rate2, &distortion2, &skippable, + &compmode_cost, #if CONFIG_COMP_INTERINTRA_PRED - &compmode_interintra_cost, + &compmode_interintra_cost, #endif - &rate_y, &distortion_y, - &rate_uv, &distortion_uv, - &mode_excluded, &disable_skip, recon_yoffset, - mode_index, frame_mv, frame_best_ref_mv); - if (this_rd == INT64_MAX) - continue; + &rate_y, &distortion_y, + &rate_uv, &distortion_uv, + &mode_excluded, &disable_skip, recon_yoffset, + mode_index, frame_mv, frame_best_ref_mv); + if (this_rd == INT64_MAX) + continue; + } if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) { rate2 += compmode_cost; @@ -4777,13 +4816,10 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // Note index of best mode so far best_mode_index = mode_index; -#if 0 if (this_mode <= B_PRED) { - xd->mode_info_context->mbmi.uv_mode = uv_intra_mode_8x8; /* required for left and above block mv */ - xd->mode_info_context->mbmi.mv.as_int = 0; + mbmi->mv[0].as_int = 0; } -#endif other_cost += ref_costs[xd->mode_info_context->mbmi.ref_frame];