ref: d01357bbad6fb495f16c763add16dcc351a6f8b3
parent: 3f7182cb0d880109a79b4ea86bb7563254642307
author: Deb Mukherjee <debargha@google.com>
date: Tue Oct 9 09:19:15 EDT 2012
New b-intra mode where direction is contextual Preliminary patch on a new 4x4 intra mode B_CONTEXT_PRED where the dominant direction from the context is used to encode. Various decoder changes are needed to support decoding of B_CONTEXT_PRED in conjunction with hybrid transforms since the scan order and tokenization depends on the actual direction of prediction obtained from the context. Currently the traditional directional modes are used in conjunction with the B_CONTEXT_PRED, which also seems to provide the best results. The gains are small - in the 0.1% range. Change-Id: I5a7ea80b5218f42a9c0dfb42d3f79a68c7f0cdc2
--- a/configure
+++ b/configure
@@ -245,6 +245,7 @@
subpelrefmv
new_mvref
implicit_segmentation
+ newbintramodes
"
CONFIG_LIST="
external_build
--- a/vp9/common/blockd.h
+++ b/vp9/common/blockd.h
@@ -149,8 +149,8 @@
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 @@
B_VL_PRED,
B_HD_PRED,
B_HU_PRED,
+#if CONFIG_NEWBINTRAMODES
+ B_CONTEXT_PRED,
+#endif
LEFT4X4,
ABOVE4X4,
@@ -168,9 +171,19 @@
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,10 +200,12 @@
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 {
int_mv first;
@@ -443,6 +458,12 @@
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 @@
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;
}
--- a/vp9/common/entropymode.c
+++ b/vp9/common/entropymode.c
@@ -68,9 +68,22 @@
{ 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,19 +154,57 @@
/* 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
explicitly-programmed predecessors. */
const vp9_tree_index vp9_ymode_tree[VP9_YMODES * 2 - 2] = {
@@ -235,21 +286,22 @@
-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 @@
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 @@
#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 @@
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 @@
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 @@
}
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 @@
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;
--- 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_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_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 @@
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 *);
--- a/vp9/common/findnearmv.c
+++ b/vp9/common/findnearmv.c
@@ -159,12 +159,12 @@
}
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;
}
--- 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 */
--- a/vp9/common/onyxc_int.h
+++ b/vp9/common/onyxc_int.h
@@ -44,12 +44,12 @@
#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 @@
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 @@
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 @@
/* 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];
--- a/vp9/common/reconintra.c
+++ b/vp9/common/reconintra.c
@@ -196,9 +196,50 @@
}
}
+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);
--- 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
--- 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 @@
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 @@
}
break;
-
+#if CONFIG_NEWBINTRAMODES
+ case B_CONTEXT_PRED:
+ break;
+ /*
+ case B_CORNER_PRED:
+ corner_predictor(predictor, 16, 4, Above, Left);
+ break;
+ */
+#endif
}
}
--- a/vp9/decoder/decodemv.c
+++ b/vp9/decoder/decodemv.c
@@ -29,9 +29,19 @@
#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) {
return treed_read(bc, vp9_ymode_tree, p);
}
@@ -142,7 +152,7 @@
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);
@@ -149,12 +159,12 @@
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 @@
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);
--- a/vp9/decoder/decodframe.c
+++ b/vp9/decoder/decodframe.c
@@ -376,7 +376,7 @@
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,8 +404,10 @@
/* 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 @@
}
} else if (mode == B_PRED) {
for (i = 0; i < 16; i++) {
+ int b_mode;
+#if CONFIG_COMP_INTRA_PRED
+ int b_mode2;
+#endif
BLOCKD *b = &xd->block[i];
- int b_mode = xd->mode_info_context->bmi[i].as_mode.first;
+ 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
- int b_mode2 = xd->mode_info_context->bmi[i].as_mode.second;
+ 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 @@
*(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 @@
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 @@
(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 @@
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 @@
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. */
--- a/vp9/decoder/detokenize.c
+++ b/vp9/decoder/detokenize.c
@@ -572,36 +572,58 @@
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 @@
}
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;
}
--- a/vp9/decoder/detokenize.h
+++ b/vp9/decoder/detokenize.h
@@ -21,5 +21,7 @@
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 */
--- a/vp9/encoder/bitstream.c
+++ b/vp9/encoder/bitstream.c
@@ -36,7 +36,9 @@
#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_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 @@
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 @@
#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 @@
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 @@
++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);
--- a/vp9/encoder/block.h
+++ b/vp9/encoder/block.h
@@ -129,7 +129,7 @@
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]
--- a/vp9/encoder/encodeframe.c
+++ b/vp9/encoder/encodeframe.c
@@ -1778,7 +1778,11 @@
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);
}
}
--- a/vp9/encoder/encodeintra.c
+++ b/vp9/encoder/encodeintra.c
@@ -57,6 +57,10 @@
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
--- 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);
}
}
--- a/vp9/encoder/onyx_if.c
+++ b/vp9/encoder/onyx_if.c
@@ -122,7 +122,9 @@
#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 @@
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 @@
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
--- a/vp9/encoder/onyx_int.h
+++ b/vp9/encoder/onyx_int.h
@@ -102,12 +102,12 @@
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 @@
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;
--- a/vp9/encoder/ratectrl.c
+++ b/vp9/encoder/ratectrl.c
@@ -271,16 +271,16 @@
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));
}
}
--- a/vp9/encoder/rdopt.c
+++ b/vp9/encoder/rdopt.c
@@ -1005,7 +1005,10 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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;
--
⑨