diff --git a/configure b/configure index d52052504..c1ee96dda 100755 --- a/configure +++ b/configure @@ -245,6 +245,7 @@ EXPERIMENT_LIST=" subpelrefmv new_mvref implicit_segmentation + newbintramodes " CONFIG_LIST=" external_build diff --git a/vp9/common/blockd.h b/vp9/common/blockd.h index 9d5eedc58..862335483 100644 --- a/vp9/common/blockd.h +++ b/vp9/common/blockd.h @@ -149,8 +149,8 @@ typedef enum { B_DC_PRED, /* average of above and left pixels */ B_TM_PRED, - B_VE_PRED, /* vertical prediction */ - B_HE_PRED, /* horizontal prediction */ + B_VE_PRED, /* vertical prediction */ + B_HE_PRED, /* horizontal prediction */ B_LD_PRED, B_RD_PRED, @@ -159,6 +159,9 @@ typedef enum { B_VL_PRED, B_HD_PRED, B_HU_PRED, +#if CONFIG_NEWBINTRAMODES + B_CONTEXT_PRED, +#endif LEFT4X4, ABOVE4X4, @@ -168,9 +171,19 @@ typedef enum { B_MODE_COUNT } B_PREDICTION_MODE; -#define VP9_BINTRAMODES (B_HU_PRED + 1) /* 10 */ +#define VP9_BINTRAMODES (LEFT4X4) #define VP9_SUBMVREFS (1 + NEW4X4 - LEFT4X4) +#if CONFIG_NEWBINTRAMODES +/* The number of B_PRED intra modes that are replaced by B_CONTEXT_PRED */ +#define CONTEXT_PRED_REPLACEMENTS 0 +#define VP9_KF_BINTRAMODES (VP9_BINTRAMODES - 1) +#define VP9_NKF_BINTRAMODES (VP9_BINTRAMODES - CONTEXT_PRED_REPLACEMENTS) +#else +#define VP9_KF_BINTRAMODES (VP9_BINTRAMODES) /* 10 */ +#define VP9_NKF_BINTRAMODES (VP9_BINTRAMODES) /* 10 */ +#endif + typedef enum { PARTITIONING_16X8 = 0, PARTITIONING_8X16, @@ -187,9 +200,11 @@ union b_mode_info { struct { B_PREDICTION_MODE first; TX_TYPE tx_type; - #if CONFIG_COMP_INTRA_PRED B_PREDICTION_MODE second; +#endif +#if CONFIG_NEWBINTRAMODES + B_PREDICTION_MODE context; #endif } as_mode; struct { @@ -443,6 +458,12 @@ static TX_TYPE txfm_map(B_PREDICTION_MODE bmode) { tx_type = DCT_ADST; break; +#if CONFIG_NEWBINTRAMODES + case B_CONTEXT_PRED: + assert(0); + break; +#endif + default : tx_type = DCT_DCT; break; @@ -454,7 +475,11 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, const BLOCKD *b) { TX_TYPE tx_type = DCT_DCT; if (xd->mode_info_context->mbmi.mode == B_PRED && xd->q_index < ACTIVE_HT) { - tx_type = txfm_map(b->bmi.as_mode.first); + tx_type = txfm_map( +#if CONFIG_NEWBINTRAMODES + b->bmi.as_mode.first == B_CONTEXT_PRED ? b->bmi.as_mode.context : +#endif + b->bmi.as_mode.first); } return tx_type; } diff --git a/vp9/common/entropymode.c b/vp9/common/entropymode.c index 5b265787c..37d09db9e 100644 --- a/vp9/common/entropymode.c +++ b/vp9/common/entropymode.c @@ -68,9 +68,22 @@ static const unsigned int kf_uv_mode_cts [VP9_YMODES] [VP9_UV_MODES] = { { 122, 41, 35, 20, 20, 20, 20, 20, 20, 18}, /* BPRED */ }; -static const unsigned int bmode_cts[VP9_BINTRAMODES] = { +static const unsigned int bmode_cts[VP9_NKF_BINTRAMODES] = { +#if CONFIG_NEWBINTRAMODES +#if CONTEXT_PRED_REPLACEMENTS == 6 + /* DC TM VE HE CONTEXT */ + 43891, 17694, 10036, 3920, 20000 +#elif CONTEXT_PRED_REPLACEMENTS == 4 + /* DC TM VE HE LD RD CONTEXT */ + 43891, 17694, 10036, 3920, 3363, 2546, 14000 +#elif CONTEXT_PRED_REPLACEMENTS == 0 + /* DC TM VE HE LD RD VR VL HD HU CONTEXT */ + 43891, 17694, 10036, 3920, 3363, 2546, 5119, 3221, 2471, 1723, 50000 +#endif +#else /* DC TM VE HE LD RD VR VL HD HU */ 43891, 17694, 10036, 3920, 3363, 2546, 5119, 3221, 2471, 1723 +#endif }; typedef enum { @@ -141,17 +154,55 @@ const vp9_prob vp9_mbsplit_probs [VP9_NUMMBSPLITS - 1] = { 110, 111, 150}; /* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */ -const vp9_tree_index vp9_bmode_tree[VP9_BINTRAMODES * 2 - 2] = /* INTRAMODECONTEXTNODE value */ -{ - -B_DC_PRED, 2, /* 0 = DC_NODE */ - -B_TM_PRED, 4, /* 1 = TM_NODE */ - -B_VE_PRED, 6, /* 2 = VE_NODE */ - 8, 12, /* 3 = COM_NODE */ - -B_HE_PRED, 10, /* 4 = HE_NODE */ - -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ - -B_LD_PRED, 14, /* 6 = LD_NODE */ - -B_VL_PRED, 16, /* 7 = VL_NODE */ - -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ +const vp9_tree_index vp9_kf_bmode_tree[VP9_KF_BINTRAMODES * 2 - 2] = { + -B_DC_PRED, 2, /* 0 = DC_NODE */ + -B_TM_PRED, 4, /* 1 = TM_NODE */ + -B_VE_PRED, 6, /* 2 = VE_NODE */ + 8, 12, /* 3 = COM_NODE */ + -B_HE_PRED, 10, /* 4 = HE_NODE */ + -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ + -B_LD_PRED, 14, /* 6 = LD_NODE */ + -B_VL_PRED, 16, /* 7 = VL_NODE */ + -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ +}; + +const vp9_tree_index vp9_bmode_tree[VP9_NKF_BINTRAMODES * 2 - 2] = { +#if CONFIG_NEWBINTRAMODES +#if CONTEXT_PRED_REPLACEMENTS == 6 + -B_DC_PRED, 2, + -B_TM_PRED, 4, + 6, -(B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS), + -B_VE_PRED, -B_HE_PRED +#elif CONTEXT_PRED_REPLACEMENTS == 4 + -B_DC_PRED, 2, + -B_TM_PRED, 4, + 6, 8, + -B_VE_PRED, -B_HE_PRED, + 10, -(B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS), + -B_RD_PRED, -B_LD_PRED, +#elif CONTEXT_PRED_REPLACEMENTS == 0 + -B_DC_PRED, 2, /* 0 = DC_NODE */ + -B_TM_PRED, 4, /* 1 = TM_NODE */ + -B_VE_PRED, 6, /* 2 = VE_NODE */ + 8, 12, /* 3 = COM_NODE */ + -B_HE_PRED, 10, /* 4 = HE_NODE */ + -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ + -B_LD_PRED, 14, /* 6 = LD_NODE */ + -B_VL_PRED, 16, /* 7 = VL_NODE */ + -B_HD_PRED, 18, + -B_HU_PRED, -B_CONTEXT_PRED +#endif +#else + -B_DC_PRED, 2, /* 0 = DC_NODE */ + -B_TM_PRED, 4, /* 1 = TM_NODE */ + -B_VE_PRED, 6, /* 2 = VE_NODE */ + 8, 12, /* 3 = COM_NODE */ + -B_HE_PRED, 10, /* 4 = HE_NODE */ + -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ + -B_LD_PRED, 14, /* 6 = LD_NODE */ + -B_VL_PRED, 16, /* 7 = VL_NODE */ + -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ +#endif }; /* Again, these trees use the same probability indices as their @@ -235,21 +286,22 @@ const vp9_tree_index vp9_sub_mv_ref_tree[6] = { -ZERO4X4, -NEW4X4 }; -struct vp9_token_struct vp9_bmode_encodings [VP9_BINTRAMODES]; -struct vp9_token_struct vp9_ymode_encodings [VP9_YMODES]; +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]; #endif -struct vp9_token_struct vp9_kf_ymode_encodings [VP9_YMODES]; -struct vp9_token_struct vp9_uv_mode_encodings [VP9_UV_MODES]; -struct vp9_token_struct vp9_i8x8_mode_encodings [VP9_I8X8_MODES]; -struct vp9_token_struct vp9_mbsplit_encodings [VP9_NUMMBSPLITS]; +struct vp9_token_struct vp9_kf_ymode_encodings[VP9_YMODES]; +struct vp9_token_struct vp9_uv_mode_encodings[VP9_UV_MODES]; +struct vp9_token_struct vp9_i8x8_mode_encodings[VP9_I8X8_MODES]; +struct vp9_token_struct vp9_mbsplit_encodings[VP9_NUMMBSPLITS]; -struct vp9_token_struct vp9_mv_ref_encoding_array [VP9_MVREFS]; +struct vp9_token_struct vp9_mv_ref_encoding_array[VP9_MVREFS]; #if CONFIG_SUPERBLOCKS -struct vp9_token_struct vp9_sb_mv_ref_encoding_array [VP9_MVREFS]; +struct vp9_token_struct vp9_sb_mv_ref_encoding_array[VP9_MVREFS]; #endif -struct vp9_token_struct vp9_sub_mv_ref_encoding_array [VP9_SUBMVREFS]; +struct vp9_token_struct vp9_sub_mv_ref_encoding_array[VP9_SUBMVREFS]; void vp9_init_mbmode_probs(VP9_COMMON *x) { unsigned int bct [VP9_YMODES] [2]; /* num Ymodes > num UV modes */ @@ -297,28 +349,36 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) { static void intra_bmode_probs_from_distribution( - vp9_prob p [VP9_BINTRAMODES - 1], - unsigned int branch_ct [VP9_BINTRAMODES - 1] [2], - const unsigned int events [VP9_BINTRAMODES]) { - vp9_tree_probs_from_distribution(VP9_BINTRAMODES, vp9_bmode_encodings, - vp9_bmode_tree, p, branch_ct, - events, 256, 1); + vp9_prob p[VP9_NKF_BINTRAMODES - 1], + unsigned int branch_ct[VP9_NKF_BINTRAMODES - 1][2], + const unsigned int events[VP9_NKF_BINTRAMODES]) { + vp9_tree_probs_from_distribution(VP9_NKF_BINTRAMODES, vp9_bmode_encodings, + vp9_bmode_tree, p, branch_ct, events, 256, 1); } -void vp9_default_bmode_probs(vp9_prob p [VP9_BINTRAMODES - 1]) { - unsigned int branch_ct [VP9_BINTRAMODES - 1] [2]; +void vp9_default_bmode_probs(vp9_prob p[VP9_NKF_BINTRAMODES - 1]) { + unsigned int branch_ct[VP9_NKF_BINTRAMODES - 1][2]; intra_bmode_probs_from_distribution(p, branch_ct, bmode_cts); } -void vp9_kf_default_bmode_probs(vp9_prob p[VP9_BINTRAMODES][VP9_BINTRAMODES] - [VP9_BINTRAMODES - 1]) { - unsigned int branch_ct[VP9_BINTRAMODES - 1][2]; +static void intra_kf_bmode_probs_from_distribution( + vp9_prob p[VP9_KF_BINTRAMODES - 1], + unsigned int branch_ct[VP9_KF_BINTRAMODES - 1][2], + const unsigned int events[VP9_KF_BINTRAMODES]) { + vp9_tree_probs_from_distribution(VP9_KF_BINTRAMODES, vp9_kf_bmode_encodings, + vp9_kf_bmode_tree, p, branch_ct, events, 256, 1); +} + +void vp9_kf_default_bmode_probs(vp9_prob p[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES - 1]) { + unsigned int branch_ct[VP9_KF_BINTRAMODES - 1][2]; int i, j; - for (i = 0; i < VP9_BINTRAMODES; i++) { - for (j = 0; j < VP9_BINTRAMODES; j++) { - intra_bmode_probs_from_distribution( - p[i][j], branch_ct, vp9_kf_default_bmode_counts[i][j]); + for (i = 0; i < VP9_KF_BINTRAMODES; ++i) { + for (j = 0; j < VP9_KF_BINTRAMODES; ++j) { + intra_kf_bmode_probs_from_distribution( + p[i][j], branch_ct, vp9_kf_default_bmode_counts[i][j]); } } } @@ -353,6 +413,7 @@ const int vp9_switchable_interp_map[SWITCHABLE+1] = {-1, -1, 0, 1, -1}; //8, 8s #endif void vp9_entropy_mode_init() { + vp9_tokens_from_tree(vp9_kf_bmode_encodings, vp9_kf_bmode_tree); vp9_tokens_from_tree(vp9_bmode_encodings, vp9_bmode_tree); vp9_tokens_from_tree(vp9_ymode_encodings, vp9_ymode_tree); vp9_tokens_from_tree(vp9_kf_ymode_encodings, vp9_kf_ymode_tree); @@ -444,7 +505,7 @@ void vp9_update_mode_context(VP9_COMMON *pc) { this_prob = count > 0 ? 256 * mv_ref_ct[j][i][0] / count : 128; count = count > MVREF_COUNT_SAT ? MVREF_COUNT_SAT : count; factor = (MVREF_MAX_UPDATE_FACTOR * count / MVREF_COUNT_SAT); - this_prob = (pc->fc.vp8_mode_contexts[j][i] * (256 - factor) + + 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; @@ -482,7 +543,7 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { unsigned int branch_ct[32][2]; vp9_prob ymode_probs[VP9_YMODES - 1]; vp9_prob uvmode_probs[VP9_UV_MODES - 1]; - vp9_prob bmode_probs[VP9_BINTRAMODES - 1]; + vp9_prob bmode_probs[VP9_NKF_BINTRAMODES - 1]; vp9_prob i8x8_mode_probs[VP9_I8X8_MODES - 1]; vp9_prob sub_mv_ref_probs[VP9_SUBMVREFS - 1]; vp9_prob mbsplit_probs[VP9_NUMMBSPLITS - 1]; @@ -500,8 +561,9 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { } printf("};\n"); printf("static const unsigned int\nbmode_counts" - "[VP9_BINTRAMODES] = {\n"); - for (t = 0; t < VP9_BINTRAMODES; ++t) printf("%d, ", cm->fc.bmode_counts[t]); + "[VP9_NKF_BINTRAMODES] = {\n"); + for (t = 0; t < VP9_NKF_BINTRAMODES; ++t) + printf("%d, ", cm->fc.bmode_counts[t]); printf("};\n"); printf("static const unsigned int\ni8x8_mode_counts" "[VP9_I8X8_MODES] = {\n"); @@ -551,10 +613,10 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { else cm->fc.uv_mode_prob[i][t] = prob; } } - vp9_tree_probs_from_distribution(VP9_BINTRAMODES, vp9_bmode_encodings, + vp9_tree_probs_from_distribution(VP9_NKF_BINTRAMODES, vp9_bmode_encodings, vp9_bmode_tree, bmode_probs, branch_ct, cm->fc.bmode_counts, 256, 1); - for (t = 0; t < VP9_BINTRAMODES - 1; ++t) { + for (t = 0; t < VP9_NKF_BINTRAMODES - 1; ++t) { int prob; count = branch_ct[t][0] + branch_ct[t][1]; count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count; diff --git a/vp9/common/entropymode.h b/vp9/common/entropymode.h index b55e3b0a6..02975918e 100644 --- a/vp9/common/entropymode.h +++ b/vp9/common/entropymode.h @@ -17,6 +17,9 @@ #define SUBMVREF_COUNT 5 #define VP9_NUMMBSPLITS 4 +#if CONFIG_COMP_INTRA_PRED +#define DEFAULT_COMP_INTRA_PROB 32 +#endif typedef const int vp9_mbsplit[16]; @@ -32,11 +35,12 @@ extern const vp9_prob vp9_sub_mv_ref_prob[VP9_SUBMVREFS - 1]; extern const vp9_prob vp9_sub_mv_ref_prob2[SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; -extern const unsigned int vp9_kf_default_bmode_counts[VP9_BINTRAMODES] - [VP9_BINTRAMODES] - [VP9_BINTRAMODES]; +extern const unsigned int vp9_kf_default_bmode_counts[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES]; extern const vp9_tree_index vp9_bmode_tree[]; +extern const vp9_tree_index vp9_kf_bmode_tree[]; extern const vp9_tree_index vp9_ymode_tree[]; extern const vp9_tree_index vp9_kf_ymode_tree[]; @@ -48,7 +52,8 @@ extern const vp9_tree_index vp9_mv_ref_tree[]; extern const vp9_tree_index vp9_sb_mv_ref_tree[]; extern const vp9_tree_index vp9_sub_mv_ref_tree[]; -extern struct vp9_token_struct vp9_bmode_encodings[VP9_BINTRAMODES]; +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_kf_ymode_encodings[VP9_I32X32_MODES]; extern struct vp9_token_struct vp9_kf_ymode_encodings[VP9_YMODES]; @@ -76,10 +81,11 @@ extern void vp9_accum_mv_refs(struct VP9Common *pc, MB_PREDICTION_MODE m, const int ct[4]); -void vp9_default_bmode_probs(vp9_prob dest[VP9_BINTRAMODES - 1]); +void vp9_default_bmode_probs(vp9_prob dest[VP9_NKF_BINTRAMODES - 1]); -void vp9_kf_default_bmode_probs(vp9_prob dest[VP9_BINTRAMODES][VP9_BINTRAMODES] - [VP9_BINTRAMODES - 1]); +void vp9_kf_default_bmode_probs(vp9_prob dest[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES - 1]); void vp9_adapt_mode_probs(struct VP9Common *); diff --git a/vp9/common/findnearmv.c b/vp9/common/findnearmv.c index 4f3d15a82..84a377e75 100644 --- a/vp9/common/findnearmv.c +++ b/vp9/common/findnearmv.c @@ -159,12 +159,12 @@ void vp9_find_near_mvs } vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc, - vp9_prob p[VP9_MVREFS - 1], const int near_mv_ref_ct[4] - ) { - p[0] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[0]] [0]; - p[1] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[1]] [1]; - p[2] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[2]] [2]; - p[3] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[3]] [3]; + vp9_prob p[VP9_MVREFS - 1], + const int near_mv_ref_ct[4]) { + p[0] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[0]][0]; + p[1] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[1]][1]; + p[2] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[2]][2]; + p[3] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[3]][3]; return p; } diff --git a/vp9/common/modecontext.c b/vp9/common/modecontext.c index 37796d80f..522498609 100644 --- a/vp9/common/modecontext.c +++ b/vp9/common/modecontext.c @@ -11,7 +11,9 @@ #include "entropymode.h" -const unsigned int vp9_kf_default_bmode_counts[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES] = { +const unsigned int vp9_kf_default_bmode_counts[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] = { { /*Above Mode : 0*/ { 43438, 2195, 470, 316, 615, 171, 217, 412, 124, 160, }, /* left_mode 0 */ diff --git a/vp9/common/onyxc_int.h b/vp9/common/onyxc_int.h index c85c7ef49..de814705b 100644 --- a/vp9/common/onyxc_int.h +++ b/vp9/common/onyxc_int.h @@ -44,12 +44,12 @@ void vp9_initialize_common(void); #define COMP_PRED_CONTEXTS 2 typedef struct frame_contexts { - vp9_prob bmode_prob [VP9_BINTRAMODES - 1]; - vp9_prob ymode_prob [VP9_YMODES - 1]; /* interframe intra mode probs */ - 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]; - vp9_prob mbsplit_prob [VP9_NUMMBSPLITS - 1]; + vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1]; + vp9_prob ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */ + 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]; + vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1]; vp9_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; vp9_prob hybrid_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; vp9_prob coef_probs_8x8 [BLOCK_TYPES_8X8] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; @@ -59,18 +59,18 @@ typedef struct frame_contexts { nmv_context nmvc; nmv_context pre_nmvc; - vp9_prob pre_bmode_prob [VP9_BINTRAMODES - 1]; - vp9_prob pre_ymode_prob [VP9_YMODES - 1]; /* interframe intra mode probs */ - 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_BINTRAMODES]; - unsigned int ymode_counts [VP9_YMODES]; /* interframe intra mode probs */ - unsigned int uv_mode_counts [VP9_YMODES][VP9_UV_MODES]; - unsigned int i8x8_mode_counts [VP9_I8X8_MODES]; /* interframe intra mode probs */ - unsigned int sub_mv_ref_counts [SUBMVREF_COUNT][VP9_SUBMVREFS]; - unsigned int mbsplit_counts [VP9_NUMMBSPLITS]; + vp9_prob pre_bmode_prob[VP9_NKF_BINTRAMODES - 1]; + vp9_prob pre_ymode_prob[VP9_YMODES - 1]; /* interframe intra mode probs */ + 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 */ + 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]; + unsigned int mbsplit_counts[VP9_NUMMBSPLITS]; vp9_prob pre_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]; @@ -108,7 +108,7 @@ typedef struct frame_contexts { int mode_context[6][4]; int mode_context_a[6][4]; - int vp8_mode_contexts[6][4]; + int vp9_mode_contexts[6][4]; int mv_ref_ct[6][4][2]; int mv_ref_ct_a[6][4][2]; } FRAME_CONTEXT; @@ -241,7 +241,9 @@ typedef struct VP9Common { /* keyframe block modes are predicted by their above, left neighbors */ - vp9_prob kf_bmode_prob [VP9_BINTRAMODES] [VP9_BINTRAMODES] [VP9_BINTRAMODES - 1]; + vp9_prob kf_bmode_prob[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES - 1]; vp9_prob kf_ymode_prob[8][VP9_YMODES - 1]; /* keyframe "" */ #if CONFIG_SUPERBLOCKS vp9_prob sb_kf_ymode_prob[8][VP9_I32X32_MODES - 1]; diff --git a/vp9/common/reconintra.c b/vp9/common/reconintra.c index 97f782c52..c9b8bd052 100644 --- a/vp9/common/reconintra.c +++ b/vp9/common/reconintra.c @@ -196,9 +196,50 @@ static void d153_predictor(uint8_t *ypred_ptr, int y_stride, int n, } } +static void corner_predictor(unsigned char *ypred_ptr, int y_stride, int n, + unsigned char *yabove_row, + unsigned char *yleft_col) { + int h[32], v[32], mh, mv, maxgradh, maxgradv, x, y, nx, ny; + int i, j; + int top_left = yabove_row[-1]; + mh = mv = 0; + maxgradh = yabove_row[1] - top_left; + maxgradv = yleft_col[1] - top_left; + for (i = 2; i < n; ++i) { + int gh = yabove_row[i] - yabove_row[i - 2]; + int gv = yleft_col[i] - yleft_col[i - 2]; + if (gh > maxgradh) { + maxgradh = gh; + mh = i - 1; + } + if (gv > maxgradv) { + maxgradv = gv; + mv = i - 1; + } + } + nx = mh + mv + 3; + ny = 2 * n + 1 - nx; + + x = top_left; + for (i = 0; i <= mh; ++i) x += yabove_row[i]; + for (i = 0; i <= mv; ++i) x += yleft_col[i]; + x += (nx >> 1); + x /= nx; + y = 0; + for (i = mh + 1; i < n; ++i) y += yabove_row[i]; + for (i = mv + 1; i < n; ++i) y += yleft_col[i]; + y += (ny >> 1); + y /= ny; + + for (i = 0; i < n; ++i) { + for (j = 0; j < n; ++j) + ypred_ptr[j] = (i <= mh && j <= mv ? x : y); + ypred_ptr += y_stride; + } +} + void vp9_recon_intra_mbuv(MACROBLOCKD *xd) { int i; - for (i = 16; i < 24; i += 2) { BLOCKD *b = &xd->block[i]; vp9_recon2b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride); diff --git a/vp9/common/reconintra.h b/vp9/common/reconintra.h index 7bc66707c..35a839db3 100644 --- a/vp9/common/reconintra.h +++ b/vp9/common/reconintra.h @@ -14,5 +14,8 @@ #include "blockd.h" extern void vp9_recon_intra_mbuv(MACROBLOCKD *xd); +extern B_PREDICTION_MODE vp9_find_dominant_direction(unsigned char *ptr, + int stride, int n); +extern B_PREDICTION_MODE vp9_find_bpred_context(BLOCKD *x); #endif // __INC_RECONINTRA_H diff --git a/vp9/common/reconintra4x4.c b/vp9/common/reconintra4x4.c index d2b457c58..7af613d33 100644 --- a/vp9/common/reconintra4x4.c +++ b/vp9/common/reconintra4x4.c @@ -14,8 +14,146 @@ #include "reconintra.h" #include "vpx_rtcd.h" -void vp9_intra4x4_predict_c(BLOCKD *x, int b_mode, - unsigned char *predictor) { +#if CONFIG_NEWBINTRAMODES +static int find_grad_measure(unsigned char *x, int stride, int n, int t, + int dx, int dy) { + int i, j; + int count = 0, gsum = 0, gdiv; + /* TODO: Make this code more efficient by breaking up into two loops */ + for (i = -t; i < n; ++i) + for (j = -t; j < n; ++j) { + int g; + if (i >= 0 && j >= 0) continue; + if (i + dy >= 0 && j + dx >= 0) continue; + if (i + dy < -t || i + dy >= n || j + dx < -t || j + dx >= n) continue; + g = abs(x[(i + dy) * stride + j + dx] - x[i * stride + j]); + gsum += g * g; + count++; + } + gdiv = (dx * dx + dy * dy) * count; + return ((gsum << 8) + (gdiv >> 1)) / gdiv; +} + +#if CONTEXT_PRED_REPLACEMENTS == 6 +B_PREDICTION_MODE vp9_find_dominant_direction( + unsigned char *ptr, int stride, int n) { + int g[8], i, imin, imax; + g[1] = find_grad_measure(ptr, stride, n, 4, 2, 1); + g[2] = find_grad_measure(ptr, stride, n, 4, 1, 1); + g[3] = find_grad_measure(ptr, stride, n, 4, 1, 2); + g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2); + g[6] = find_grad_measure(ptr, stride, n, 4, -1, 1); + g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1); + imin = 1; + for (i = 2; i < 8; i += 1 + (i == 3)) + imin = (g[i] < g[imin] ? i : imin); + imax = 1; + for (i = 2; i < 8; i += 1 + (i == 3)) + imax = (g[i] > g[imax] ? i : imax); + /* + printf("%d %d %d %d %d %d = %d %d\n", + g[1], g[2], g[3], g[5], g[6], g[7], imin, imax); + */ + switch (imin) { + case 1: + return B_HD_PRED; + case 2: + return B_RD_PRED; + case 3: + return B_VR_PRED; + case 5: + return B_VL_PRED; + case 6: + return B_LD_PRED; + case 7: + return B_HU_PRED; + default: + assert(0); + } +} +#elif CONTEXT_PRED_REPLACEMENTS == 4 +B_PREDICTION_MODE vp9_find_dominant_direction( + unsigned char *ptr, int stride, int n) { + int g[8], i, imin, imax; + g[1] = find_grad_measure(ptr, stride, n, 4, 2, 1); + g[3] = find_grad_measure(ptr, stride, n, 4, 1, 2); + g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2); + g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1); + imin = 1; + for (i = 3; i < 8; i+=2) + imin = (g[i] < g[imin] ? i : imin); + imax = 1; + for (i = 3; i < 8; i+=2) + imax = (g[i] > g[imax] ? i : imax); + /* + printf("%d %d %d %d = %d %d\n", + g[1], g[3], g[5], g[7], imin, imax); + */ + switch (imin) { + case 1: + return B_HD_PRED; + case 3: + return B_VR_PRED; + case 5: + return B_VL_PRED; + case 7: + return B_HU_PRED; + default: + assert(0); + } +} +#elif CONTEXT_PRED_REPLACEMENTS == 0 +B_PREDICTION_MODE vp9_find_dominant_direction( + unsigned char *ptr, int stride, int n) { + int g[8], i, imin, imin2, imax; + g[0] = find_grad_measure(ptr, stride, n, 4, 1, 0); + g[1] = find_grad_measure(ptr, stride, n, 4, 2, 1); + g[2] = find_grad_measure(ptr, stride, n, 4, 1, 1); + g[3] = find_grad_measure(ptr, stride, n, 4, 1, 2); + g[4] = find_grad_measure(ptr, stride, n, 4, 0, 1); + g[5] = find_grad_measure(ptr, stride, n, 4, -1, 2); + g[6] = find_grad_measure(ptr, stride, n, 4, -1, 1); + g[7] = find_grad_measure(ptr, stride, n, 4, -2, 1); + imax = 0; + for (i = 1; i < 8; i++) + imax = (g[i] > g[imax] ? i : imax); + imin = 0; + for (i = 1; i < 8; i++) + imin = (g[i] < g[imin] ? i : imin); + + switch (imin) { + case 0: + return B_HE_PRED; + case 1: + return B_HD_PRED; + case 2: + return B_RD_PRED; + case 3: + return B_VR_PRED; + case 4: + return B_VE_PRED; + case 5: + return B_VL_PRED; + case 6: + return B_LD_PRED; + case 7: + return B_HU_PRED; + default: + assert(0); + } +} +#endif + +B_PREDICTION_MODE vp9_find_bpred_context(BLOCKD *x) { + unsigned char *ptr = *(x->base_dst) + x->dst; + int stride = x->dst_stride; + return vp9_find_dominant_direction(ptr, stride, 4); +} +#endif + +void vp9_intra4x4_predict(BLOCKD *x, + int b_mode, + unsigned char *predictor) { int i, r, c; unsigned char *Above = *(x->base_dst) + x->dst - x->dst_stride; @@ -27,6 +165,11 @@ void vp9_intra4x4_predict_c(BLOCKD *x, int b_mode, Left[2] = (*(x->base_dst))[x->dst - 1 + 2 * x->dst_stride]; Left[3] = (*(x->base_dst))[x->dst - 1 + 3 * x->dst_stride]; +#if CONFIG_NEWBINTRAMODES + if (b_mode == B_CONTEXT_PRED) + b_mode = x->bmi.as_mode.context; +#endif + switch (b_mode) { case B_DC_PRED: { int expected_dc = 0; @@ -270,7 +413,15 @@ void vp9_intra4x4_predict_c(BLOCKD *x, int b_mode, } break; - +#if CONFIG_NEWBINTRAMODES + case B_CONTEXT_PRED: + break; + /* + case B_CORNER_PRED: + corner_predictor(predictor, 16, 4, Above, Left); + break; + */ +#endif } } diff --git a/vp9/decoder/decodemv.c b/vp9/decoder/decodemv.c index a22df8f3c..7d4d6a7c2 100644 --- a/vp9/decoder/decodemv.c +++ b/vp9/decoder/decodemv.c @@ -29,7 +29,17 @@ int dec_mvcount = 0; #endif static int read_bmode(vp9_reader *bc, const vp9_prob *p) { - return treed_read(bc, vp9_bmode_tree, p); + B_PREDICTION_MODE m = treed_read(bc, vp9_bmode_tree, p); +#if CONFIG_NEWBINTRAMODES + if (m == B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS) + m = B_CONTEXT_PRED; + assert(m < B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS || m == B_CONTEXT_PRED); +#endif + return m; +} + +static int read_kf_bmode(vp9_reader *bc, const vp9_prob *p) { + return treed_read(bc, vp9_kf_bmode_tree, p); } static int read_ymode(vp9_reader *bc, const vp9_prob *p) { @@ -142,19 +152,19 @@ static void kfread_modes(VP9D_COMP *pbi, if ((m->mbmi.mode = y_mode) == B_PRED) { int i = 0; #if CONFIG_COMP_INTRA_PRED - int use_comp_pred = vp9_read(bc, 128); + int use_comp_pred = vp9_read(bc, DEFAULT_COMP_INTRA_PROB); #endif do { const B_PREDICTION_MODE A = above_block_mode(m, i, mis); const B_PREDICTION_MODE L = left_block_mode(m, i); m->bmi[i].as_mode.first = - (B_PREDICTION_MODE) read_bmode( + (B_PREDICTION_MODE) read_kf_bmode( bc, pbi->common.kf_bmode_prob [A] [L]); #if CONFIG_COMP_INTRA_PRED if (use_comp_pred) { m->bmi[i].as_mode.second = - (B_PREDICTION_MODE) read_bmode( + (B_PREDICTION_MODE) read_kf_bmode( bc, pbi->common.kf_bmode_prob [A] [L]); } else { m->bmi[i].as_mode.second = (B_PREDICTION_MODE)(B_DC_PRED - 1); @@ -1075,19 +1085,16 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, if (mbmi->mode == B_PRED) { int j = 0; #if CONFIG_COMP_INTRA_PRED - int use_comp_pred = vp9_read(bc, 128); + int use_comp_pred = vp9_read(bc, DEFAULT_COMP_INTRA_PROB); #endif do { - mi->bmi[j].as_mode.first = (B_PREDICTION_MODE)read_bmode(bc, pbi->common.fc.bmode_prob); - /* - { - int p; - for (p = 0; p < VP9_BINTRAMODES - 1; ++p) - printf(" %d", pbi->common.fc.bmode_prob[p]); - printf("\nbmode[%d][%d]: %d\n", pbi->common.current_video_frame, j, mi->bmi[j].as_mode.first); - } - */ - pbi->common.fc.bmode_counts[mi->bmi[j].as_mode.first]++; + int m; + m = mi->bmi[j].as_mode.first = (B_PREDICTION_MODE) + read_bmode(bc, pbi->common.fc.bmode_prob); +#if CONFIG_NEWBINTRAMODES + if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS; +#endif + pbi->common.fc.bmode_counts[m]++; #if CONFIG_COMP_INTRA_PRED if (use_comp_pred) { mi->bmi[j].as_mode.second = (B_PREDICTION_MODE)read_bmode(bc, pbi->common.fc.bmode_prob); diff --git a/vp9/decoder/decodframe.c b/vp9/decoder/decodframe.c index 72dcb5a81..ebbf1669a 100644 --- a/vp9/decoder/decodframe.c +++ b/vp9/decoder/decodframe.c @@ -376,7 +376,7 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd, eobtotal = vp9_decode_mb_tokens_16x16(pbi, xd, bc); } else if (tx_size == TX_8X8) { eobtotal = vp9_decode_mb_tokens_8x8(pbi, xd, bc); - } else { + } else if (mode != B_PRED) { eobtotal = vp9_decode_mb_tokens(pbi, xd, bc); } } @@ -404,7 +404,9 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd, /* do prediction */ if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { if (mode != I8X8_PRED) { - vp9_build_intra_predictors_mbuv(xd); + if (mode != B_PRED) { + vp9_build_intra_predictors_mbuv(xd); + } if (mode != B_PRED) { vp9_build_intra_predictors_mby(xd); } @@ -461,10 +463,20 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd, } } else if (mode == B_PRED) { for (i = 0; i < 16; i++) { - BLOCKD *b = &xd->block[i]; - int b_mode = xd->mode_info_context->bmi[i].as_mode.first; + int b_mode; #if CONFIG_COMP_INTRA_PRED - int b_mode2 = xd->mode_info_context->bmi[i].as_mode.second; + int b_mode2; +#endif + BLOCKD *b = &xd->block[i]; + b_mode = xd->mode_info_context->bmi[i].as_mode.first; +#if CONFIG_NEWBINTRAMODES + xd->mode_info_context->bmi[i].as_mode.context = b->bmi.as_mode.context = + vp9_find_bpred_context(b); +#endif + if (!xd->mode_info_context->mbmi.mb_skip_coeff) + eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_Y_WITH_DC, i); +#if CONFIG_COMP_INTRA_PRED + b_mode2 = xd->mode_info_context->bmi[i].as_mode.second; if (b_mode2 == (B_PREDICTION_MODE)(B_DC_PRED - 1)) { #endif @@ -485,6 +497,14 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd, *(b->base_dst) + b->dst, 16, b->dst_stride); } } + if (!xd->mode_info_context->mbmi.mb_skip_coeff) { + for (i = 16; i < 24; ++i) + eobtotal += vp9_decode_coefs_4x4(pbi, xd, bc, PLANE_TYPE_UV, i); + } + vp9_build_intra_predictors_mbuv(xd); + pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant, + xd->predictor + 16 * 16, xd->dst.u_buffer, + xd->dst.v_buffer, xd->dst.uv_stride, xd->eobs + 16); } else if (mode == SPLITMV) { if (tx_size == TX_8X8) { vp9_dequant_idct_add_y_block_8x8(xd->qcoeff, xd->block[0].dequant, @@ -492,8 +512,8 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd, xd->dst.y_stride, xd->eobs, xd); } else { pbi->idct_add_y_block(xd->qcoeff, xd->block[0].dequant, - xd->predictor, xd->dst.y_buffer, - xd->dst.y_stride, xd->eobs); + xd->predictor, xd->dst.y_buffer, + xd->dst.y_stride, xd->eobs); } } else { BLOCKD *b = &xd->block[24]; @@ -556,7 +576,8 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd, (xd->qcoeff + 16 * 16, xd->block[16].dequant, xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer, xd->dst.uv_stride, xd->eobs + 16, xd); - else if (xd->mode_info_context->mbmi.mode != I8X8_PRED) + else if (xd->mode_info_context->mbmi.mode != I8X8_PRED && + xd->mode_info_context->mbmi.mode != B_PRED) pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant, xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer, xd->dst.uv_stride, xd->eobs + 16); @@ -833,7 +854,7 @@ static void init_frame(VP9D_COMP *pbi) { vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc)); vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc)); - vpx_memcpy(pbi->common.fc.vp8_mode_contexts, + vpx_memcpy(pbi->common.fc.vp9_mode_contexts, pbi->common.fc.mode_context, sizeof(pbi->common.fc.mode_context)); vpx_memset(pc->prev_mip, 0, @@ -1220,14 +1241,14 @@ int vp9_decode_frame(VP9D_COMP *pbi) { if (pc->refresh_alt_ref_frame) { vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc)); - vpx_memcpy(pc->fc.vp8_mode_contexts, + vpx_memcpy(pc->fc.vp9_mode_contexts, pc->fc.mode_context_a, - sizeof(pc->fc.vp8_mode_contexts)); + sizeof(pc->fc.vp9_mode_contexts)); } else { vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc)); - vpx_memcpy(pc->fc.vp8_mode_contexts, + vpx_memcpy(pc->fc.vp9_mode_contexts, pc->fc.mode_context, - sizeof(pc->fc.vp8_mode_contexts)); + sizeof(pc->fc.vp9_mode_contexts)); } /* Buffer to buffer copy flags. */ diff --git a/vp9/decoder/detokenize.c b/vp9/decoder/detokenize.c index 68f2c283a..54baa0c95 100644 --- a/vp9/decoder/detokenize.c +++ b/vp9/decoder/detokenize.c @@ -572,36 +572,58 @@ int vp9_decode_mb_tokens_8x8(VP9D_COMP* const pbi, return eobtotal; } - -int vp9_decode_mb_tokens(VP9D_COMP* const dx, - MACROBLOCKD* const xd, - BOOL_DECODER* const bc) { +int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd, + BOOL_DECODER* const bc, int type, int i) { ENTROPY_CONTEXT *const A = (ENTROPY_CONTEXT *)xd->above_context; ENTROPY_CONTEXT *const L = (ENTROPY_CONTEXT *)xd->left_context; - - unsigned short *const eobs = xd->eobs; - const int *scan = vp9_default_zig_zag1d; - PLANE_TYPE type; - int c, i, eobtotal = 0, seg_eob = 16; + ENTROPY_CONTEXT *const a = A + vp9_block2above[i]; + ENTROPY_CONTEXT *const l = L + vp9_block2left[i]; INT16 *qcoeff_ptr = &xd->qcoeff[0]; - + const int *scan = vp9_default_zig_zag1d; + unsigned short *const eobs = xd->eobs; + int c, seg_eob = 16; + TX_TYPE tx_type = DCT_DCT; int segment_id = xd->mode_info_context->mbmi.segment_id; if (vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB)) seg_eob = vp9_get_segdata(xd, segment_id, SEG_LVL_EOB); + if (i == 24) + type = PLANE_TYPE_Y2; + else if (i >= 16) + type = PLANE_TYPE_UV; + + if (type == PLANE_TYPE_Y_WITH_DC) + tx_type = get_tx_type(xd, &xd->block[i]); + switch (tx_type) { + case ADST_DCT : + scan = vp9_row_scan; + break; + + case DCT_ADST : + scan = vp9_col_scan; + break; + + default : + scan = vp9_default_zig_zag1d; + break; + } + c = decode_coefs(dx, xd, bc, a, l, type, + tx_type, + seg_eob, qcoeff_ptr + i * 16, + i, scan, TX_4X4, coef_bands_x); + a[0] = l[0] = ((eobs[i] = c) != !type); + return c; +} + +int vp9_decode_mb_tokens(VP9D_COMP *dx, MACROBLOCKD *xd, + BOOL_DECODER* const bc) { + int i, type, eobtotal = 0; + if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != I8X8_PRED && xd->mode_info_context->mbmi.mode != SPLITMV) { - ENTROPY_CONTEXT *const a = A + vp9_block2above[24]; - ENTROPY_CONTEXT *const l = L + vp9_block2left[24]; - type = PLANE_TYPE_Y2; - c = decode_coefs(dx, xd, bc, a, l, type, - DCT_DCT, - seg_eob, qcoeff_ptr + 24 * 16, 24, - scan, TX_4X4, coef_bands_x); - a[0] = l[0] = ((eobs[24] = c) != !type); - eobtotal += c - 16; + eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, PLANE_TYPE_Y2, 24) - 16; type = PLANE_TYPE_Y_NO_DC; } else { @@ -609,35 +631,7 @@ int vp9_decode_mb_tokens(VP9D_COMP* const dx, } for (i = 0; i < 24; ++i) { - ENTROPY_CONTEXT *const a = A + vp9_block2above[i]; - ENTROPY_CONTEXT *const l = L + vp9_block2left[i]; - TX_TYPE tx_type = DCT_DCT; - if (i == 16) - type = PLANE_TYPE_UV; - - tx_type = get_tx_type(xd, &xd->block[i]); - switch(tx_type) { - case ADST_DCT : - scan = vp9_row_scan; - break; - - case DCT_ADST : - scan = vp9_col_scan; - break; - - default : - scan = vp9_default_zig_zag1d; - break; - } - - c = decode_coefs(dx, xd, bc, a, l, type, tx_type, - seg_eob, qcoeff_ptr, - i, scan, TX_4X4, coef_bands_x); - a[0] = l[0] = ((eobs[i] = c) != !type); - - eobtotal += c; - qcoeff_ptr += 16; + eobtotal += vp9_decode_coefs_4x4(dx, xd, bc, type, i); } - return eobtotal; } diff --git a/vp9/decoder/detokenize.h b/vp9/decoder/detokenize.h index aa36402c1..674850382 100644 --- a/vp9/decoder/detokenize.h +++ b/vp9/decoder/detokenize.h @@ -21,5 +21,7 @@ int vp9_decode_mb_tokens_8x8(VP9D_COMP* const, MACROBLOCKD* const, BOOL_DECODER* const); int vp9_decode_mb_tokens_16x16(VP9D_COMP* const, MACROBLOCKD* const, BOOL_DECODER* const); +int vp9_decode_coefs_4x4(VP9D_COMP *dx, MACROBLOCKD *xd, BOOL_DECODER* const bc, + int type, int i); #endif /* DETOKENIZE_H */ diff --git a/vp9/encoder/bitstream.c b/vp9/encoder/bitstream.c index 47958bf09..a80532e48 100644 --- a/vp9/encoder/bitstream.c +++ b/vp9/encoder/bitstream.c @@ -36,7 +36,9 @@ unsigned __int64 Sectionbits[500]; #endif #ifdef ENTROPY_STATS -int intra_mode_stats [VP9_BINTRAMODES] [VP9_BINTRAMODES] [VP9_BINTRAMODES]; +int intra_mode_stats[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES]; unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] @@ -341,11 +343,20 @@ static void write_uv_mode(vp9_writer *bc, int m, const vp9_prob *p) { static void write_bmode(vp9_writer *bc, int m, const vp9_prob *p) { +#if CONFIG_NEWBINTRAMODES + assert(m < B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS || m == B_CONTEXT_PRED); + if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS; +#endif write_token(bc, vp9_bmode_tree, p, vp9_bmode_encodings + m); } +static void write_kf_bmode(vp9_writer *bc, int m, const vp9_prob *p) { + write_token(bc, vp9_kf_bmode_tree, p, vp9_kf_bmode_encodings + m); +} + static void write_split(vp9_writer *bc, int x, const vp9_prob *p) { - write_token(bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x); + write_token( + bc, vp9_mbsplit_tree, p, vp9_mbsplit_encodings + x); } static int prob_update_savings(const unsigned int *ct, @@ -1005,7 +1016,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) { int uses_second = m->bmi[0].as_mode.second != (B_PREDICTION_MODE)(B_DC_PRED - 1); - vp9_write(bc, uses_second, 128); + vp9_write(bc, uses_second, DEFAULT_COMP_INTRA_PROB); #endif do { #if CONFIG_COMP_INTRA_PRED @@ -1013,14 +1024,6 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) { #endif write_bmode(bc, m->bmi[j].as_mode.first, pc->fc.bmode_prob); - /* - if (!cpi->dummy_packing) { - int p; - for (p = 0; p < VP9_BINTRAMODES - 1; ++p) - printf(" %d", pc->fc.bmode_prob[p]); - printf("\nbmode[%d][%d]: %d\n", pc->current_video_frame, j, m->bmi[j].as_mode.first); - } - */ #if CONFIG_COMP_INTRA_PRED if (uses_second) { write_bmode(bc, mode2, pc->fc.bmode_prob); @@ -1344,7 +1347,7 @@ static void write_mb_modes_kf(const VP9_COMMON *c, int uses_second = m->bmi[0].as_mode.second != (B_PREDICTION_MODE)(B_DC_PRED - 1); - vp9_write(bc, uses_second, 128); + vp9_write(bc, uses_second, DEFAULT_COMP_INTRA_PROB); #endif do { const B_PREDICTION_MODE A = above_block_mode(m, i, mis); @@ -1358,11 +1361,14 @@ static void write_mb_modes_kf(const VP9_COMMON *c, ++intra_mode_stats [A] [L] [bm]; #endif - write_bmode(bc, bm, c->kf_bmode_prob [A] [L]); - // printf(" mode: %d\n", bm); + write_kf_bmode(bc, bm, c->kf_bmode_prob[A][L]); +#if 0 // CONFIG_NEWBINTRAMODES + if (!cpi->dummy_packing) + printf("%d: %d %d\n", i, bm, m->bmi[i].as_mode.context); +#endif #if CONFIG_COMP_INTRA_PRED if (uses_second) { - write_bmode(bc, bm2, c->kf_bmode_prob [A] [L]); + write_kf_bmode(bc, bm2, c->kf_bmode_prob[A][L]); } #endif } while (++i < 16); diff --git a/vp9/encoder/block.h b/vp9/encoder/block.h index 3f2910dbb..7c0099368 100644 --- a/vp9/encoder/block.h +++ b/vp9/encoder/block.h @@ -129,7 +129,7 @@ typedef struct macroblock { int mbmode_cost[2][MB_MODE_COUNT]; int intra_uv_mode_cost[2][MB_MODE_COUNT]; - int bmode_costs[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES]; + int bmode_costs[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES]; int i8x8_mode_costs[MB_MODE_COUNT]; int inter_bmode_costs[B_MODE_COUNT]; int switchable_interp_costs[VP9_SWITCHABLE_FILTERS + 1] diff --git a/vp9/encoder/encodeframe.c b/vp9/encoder/encodeframe.c index 21def264f..12e517a36 100644 --- a/vp9/encoder/encodeframe.c +++ b/vp9/encoder/encodeframe.c @@ -1778,7 +1778,11 @@ static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) { if (m == B_PRED) { int b = 0; do { - ++ cpi->bmode_count[xd->block[b].bmi.as_mode.first]; + int m = xd->block[b].bmi.as_mode.first; +#if CONFIG_NEWBINTRAMODES + if (m == B_CONTEXT_PRED) m -= CONTEXT_PRED_REPLACEMENTS; +#endif + ++cpi->bmode_count[m]; } while (++b < 16); } } diff --git a/vp9/encoder/encodeintra.c b/vp9/encoder/encodeintra.c index 32aa5bde4..365784c4f 100644 --- a/vp9/encoder/encodeintra.c +++ b/vp9/encoder/encodeintra.c @@ -57,6 +57,10 @@ void vp9_encode_intra4x4block(const VP9_ENCODER_RTCD *rtcd, BLOCK *be = &x->block[ib]; TX_TYPE tx_type; +#if CONFIG_NEWBINTRAMODES + b->bmi.as_mode.context = vp9_find_bpred_context(b); +#endif + #if CONFIG_COMP_INTRA_PRED if (b->bmi.as_mode.second == (B_PREDICTION_MODE)(B_DC_PRED - 1)) { #endif diff --git a/vp9/encoder/modecosts.c b/vp9/encoder/modecosts.c index 2224f5430..f7c38eacd 100644 --- a/vp9/encoder/modecosts.c +++ b/vp9/encoder/modecosts.c @@ -18,12 +18,13 @@ void vp9_init_mode_costs(VP9_COMP *c) { VP9_COMMON *x = &c->common; const vp9_tree_p T = vp9_bmode_tree; + const vp9_tree_p KT = vp9_kf_bmode_tree; int i, j; - for (i = 0; i < VP9_BINTRAMODES; i++) { - for (j = 0; j < VP9_BINTRAMODES; j++) { + for (i = 0; i < VP9_KF_BINTRAMODES; i++) { + for (j = 0; j < VP9_KF_BINTRAMODES; j++) { vp9_cost_tokens((int *)c->mb.bmode_costs[i][j], - x->kf_bmode_prob[i][j], T); + x->kf_bmode_prob[i][j], KT); } } diff --git a/vp9/encoder/onyx_if.c b/vp9/encoder/onyx_if.c index 88ec5ecf2..50ead37b0 100644 --- a/vp9/encoder/onyx_if.c +++ b/vp9/encoder/onyx_if.c @@ -122,7 +122,9 @@ extern int skip_false_count; #ifdef ENTROPY_STATS -extern int intra_mode_stats[VP9_BINTRAMODES][VP9_BINTRAMODES][VP9_BINTRAMODES]; +extern int intra_mode_stats[VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES] + [VP9_KF_BINTRAMODES]; #endif #ifdef NMV_STATS @@ -2126,7 +2128,7 @@ void vp9_remove_compressor(VP9_PTR *ptr) { int i; fprintf(f, "B: "); - for (i = 0; i < VP9_BINTRAMODES; i++) + for (i = 0; i < VP9_NKF_BINTRAMODES; i++) fprintf(f, "%8d, ", b_modes[i]); fprintf(f, "\n"); @@ -2165,17 +2167,18 @@ void vp9_remove_compressor(VP9_PTR *ptr) { fprintf(fmode, "\n#include \"entropymode.h\"\n\n"); fprintf(fmode, "const unsigned int vp9_kf_default_bmode_counts "); - fprintf(fmode, "[VP9_BINTRAMODES] [VP9_BINTRAMODES] [VP9_BINTRAMODES] =\n{\n"); + fprintf(fmode, "[VP9_KF_BINTRAMODES][VP9_KF_BINTRAMODES]" + "[VP9_KF_BINTRAMODES] =\n{\n"); - for (i = 0; i < 10; i++) { + for (i = 0; i < VP8_KF_BINTRAMODES; i++) { fprintf(fmode, " { // Above Mode : %d\n", i); - for (j = 0; j < 10; j++) { + for (j = 0; j < VP8_KF_BINTRAMODES; j++) { fprintf(fmode, " {"); - for (k = 0; k < VP9_BINTRAMODES; k++) { + for (k = 0; k < VP9_KF_BINTRAMODES; k++) { if (!intra_mode_stats[i][j][k]) fprintf(fmode, " %5d, ", 1); else diff --git a/vp9/encoder/onyx_int.h b/vp9/encoder/onyx_int.h index 5406e9029..2a9fd68b1 100644 --- a/vp9/encoder/onyx_int.h +++ b/vp9/encoder/onyx_int.h @@ -102,12 +102,12 @@ typedef struct { vp9_prob hybrid_coef_probs_16x16[BLOCK_TYPES_16X16] [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]; - 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_BINTRAMODES - 1]; - vp9_prob i8x8_mode_prob [VP9_I8X8_MODES - 1]; - vp9_prob sub_mv_ref_prob [SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; - vp9_prob mbsplit_prob [VP9_NUMMBSPLITS - 1]; + 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]; + vp9_prob i8x8_mode_prob[VP9_I8X8_MODES - 1]; + vp9_prob sub_mv_ref_prob[SUBMVREF_COUNT][VP9_SUBMVREFS - 1]; + vp9_prob mbsplit_prob[VP9_NUMMBSPLITS - 1]; vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1] [VP9_SWITCHABLE_FILTERS - 1]; @@ -533,12 +533,11 @@ typedef struct VP9_COMP { int sb_count; int sb_ymode_count [VP9_I32X32_MODES]; #endif - int ymode_count [VP9_YMODES]; /* intra MB type cts this frame */ - int bmode_count [VP9_BINTRAMODES]; - int i8x8_mode_count [VP9_I8X8_MODES]; - int sub_mv_ref_count [SUBMVREF_COUNT][VP9_SUBMVREFS]; - int mbsplit_count [VP9_NUMMBSPLITS]; - // int uv_mode_count[VP9_UV_MODES]; /* intra MB type cts this frame */ + int ymode_count[VP9_YMODES]; /* intra MB type cts this frame */ + int bmode_count[VP9_NKF_BINTRAMODES]; + int i8x8_mode_count[VP9_I8X8_MODES]; + int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS]; + int mbsplit_count[VP9_NUMMBSPLITS]; int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES]; nmv_context_counts NMVcount; diff --git a/vp9/encoder/ratectrl.c b/vp9/encoder/ratectrl.c index 2838e26f0..b499f1df0 100644 --- a/vp9/encoder/ratectrl.c +++ b/vp9/encoder/ratectrl.c @@ -271,16 +271,16 @@ void vp9_setup_inter_frame(VP9_COMP *cpi) { vpx_memcpy(&cpi->common.fc, &cpi->common.lfc_a, sizeof(cpi->common.fc)); - vpx_memcpy(cpi->common.fc.vp8_mode_contexts, + vpx_memcpy(cpi->common.fc.vp9_mode_contexts, cpi->common.fc.mode_context_a, - sizeof(cpi->common.fc.vp8_mode_contexts)); + sizeof(cpi->common.fc.vp9_mode_contexts)); } else { vpx_memcpy(&cpi->common.fc, &cpi->common.lfc, sizeof(cpi->common.fc)); - vpx_memcpy(cpi->common.fc.vp8_mode_contexts, + vpx_memcpy(cpi->common.fc.vp9_mode_contexts, cpi->common.fc.mode_context, - sizeof(cpi->common.fc.vp8_mode_contexts)); + sizeof(cpi->common.fc.vp9_mode_contexts)); } } diff --git a/vp9/encoder/rdopt.c b/vp9/encoder/rdopt.c index 65467f7c8..4637db033 100644 --- a/vp9/encoder/rdopt.c +++ b/vp9/encoder/rdopt.c @@ -1005,7 +1005,10 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, BLOCK *be, DECLARE_ALIGNED_ARRAY(16, unsigned char, best_predictor, 16 * 4); DECLARE_ALIGNED_ARRAY(16, short, best_dqcoeff, 16); - for (mode = B_DC_PRED; mode <= B_HU_PRED; mode++) { +#if CONFIG_NEWBINTRAMODES + b->bmi.as_mode.context = vp9_find_bpred_context(b); +#endif + for (mode = B_DC_PRED; mode < LEFT4X4; mode++) { #if CONFIG_COMP_INTRA_PRED for (mode2 = (allow_comp ? 0 : (B_DC_PRED - 1)); mode2 != (allow_comp ? (mode + 1) : 0); mode2++) { @@ -1013,8 +1016,31 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, BLOCK *be, int64_t this_rd; int ratey; +#if CONFIG_NEWBINTRAMODES + if (xd->frame_type == KEY_FRAME) { + if (mode == B_CONTEXT_PRED) continue; +#if CONFIG_COMP_INTRA_PRED + if (mode2 == B_CONTEXT_PRED) continue; +#endif + } else { + if (mode >= B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS && + mode < B_CONTEXT_PRED) + continue; +#if CONFIG_COMP_INTRA_PRED + if (mode2 >= B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS && + mode2 < B_CONTEXT_PRED) + continue; +#endif + } +#endif + b->bmi.as_mode.first = mode; +#if CONFIG_NEWBINTRAMODES + rate = bmode_costs[ + mode == B_CONTEXT_PRED ? mode - CONTEXT_PRED_REPLACEMENTS : mode]; +#else rate = bmode_costs[mode]; +#endif #if CONFIG_COMP_INTRA_PRED if (mode2 == (B_PREDICTION_MODE)(B_DC_PRED - 1)) { @@ -1023,7 +1049,13 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, BLOCK *be, #if CONFIG_COMP_INTRA_PRED } else { vp9_comp_intra4x4_predict(b, mode, mode2, b->predictor); +#if CONFIG_NEWBINTRAMODES + rate += bmode_costs[ + mode2 == B_CONTEXT_PRED ? + mode2 - CONTEXT_PRED_REPLACEMENTS : mode2]; +#else rate += bmode_costs[mode2]; +#endif } #endif vp9_subtract_b(be, b, 16); @@ -1131,6 +1163,9 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb, int *Rat bmode_costs = mb->bmode_costs[A][L]; } +#if CONFIG_NEWBINTRAMODES + mic->bmi[i].as_mode.context = vp9_find_bpred_context(xd->block + i); +#endif total_rd += rd_pick_intra4x4block( cpi, mb, mb->block + i, xd->block + i, &best_mode, @@ -1149,6 +1184,10 @@ static int64_t rd_pick_intra4x4mby_modes(VP9_COMP *cpi, MACROBLOCK *mb, int *Rat mic->bmi[i].as_mode.second = best_second_mode; #endif +#if 0 // CONFIG_NEWBINTRAMODES + printf("%d %d\n", mic->bmi[i].as_mode.first, mic->bmi[i].as_mode.context); +#endif + if (total_rd >= best_rd) break; } @@ -1970,7 +2009,12 @@ static int labels2mode( m = LEFT4X4; } - cost = x->inter_bmode_costs[ m]; +#if CONFIG_NEWBINTRAMODES + cost = x->inter_bmode_costs[ + m == B_CONTEXT_PRED ? m - CONTEXT_PRED_REPLACEMENTS : m]; +#else + cost = x->inter_bmode_costs[m]; +#endif } d->bmi.as_mv.first.as_int = this_mv->as_int;