summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJingning Han <jingning@google.com>2015-06-19 17:31:34 -0700
committerJingning Han <jingning@google.com>2015-06-23 16:42:56 -0700
commitac50b75e507d9c8e24389a9ef7aa6164958f45c4 (patch)
tree6092b720d5e8733e20baf06cabf8cab49cc7e5bb
parent81c389e79035988436fa29121cee54e4a2d7186d (diff)
downloadlibvpx-sandbox/jingning@google.com/experimental.tar.gz
Use balanced model for intra prediction mode codingsandbox/jingning@google.com/experimental
This commit replaces the previous table based intra mode model coding with a more balanced entropy coding system. It reduces the decoder lookup table size by 1K bytes. The key frame compression performance is about even on average. There are a few points where the compression performance is improved by over 5%. Most test points are fairly close to the lookup table approach. Change-Id: I47154276c0a6a22ae87de8845bc2d494681b95f6
-rw-r--r--vp9/common/vp9_entropymode.c119
-rw-r--r--vp9/common/vp9_entropymode.h14
-rw-r--r--vp9/decoder/vp9_decodeframe.c3
-rw-r--r--vp9/decoder/vp9_decodemv.c59
-rw-r--r--vp9/encoder/vp9_bitstream.c62
-rw-r--r--vp9/encoder/vp9_encodeframe.c39
-rw-r--r--vp9/encoder/vp9_pickmode.c11
-rw-r--r--vp9/encoder/vp9_rd.c7
-rw-r--r--vp9/encoder/vp9_rdopt.c54
9 files changed, 212 insertions, 156 deletions
diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c
index 15185e8a2..167a16543 100644
--- a/vp9/common/vp9_entropymode.c
+++ b/vp9/common/vp9_entropymode.c
@@ -13,118 +13,12 @@
#include "vp9/common/vp9_onyxc_int.h"
#include "vp9/common/vp9_seg_common.h"
-const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = {
- { // above = dc
- { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc
- { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v
- { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h
- { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45
- { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135
- { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117
- { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153
- { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207
- { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63
- { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm
- }, { // above = v
- { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc
- { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v
- { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h
- { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45
- { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135
- { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117
- { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153
- { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207
- { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63
- { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm
- }, { // above = h
- { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc
- { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v
- { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h
- { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45
- { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135
- { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117
- { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153
- { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207
- { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63
- { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm
- }, { // above = d45
- { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc
- { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v
- { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h
- { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45
- { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135
- { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117
- { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153
- { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207
- { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63
- { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm
- }, { // above = d135
- { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc
- { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v
- { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h
- { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45
- { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135
- { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117
- { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153
- { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207
- { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63
- { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm
- }, { // above = d117
- { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc
- { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v
- { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h
- { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45
- { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135
- { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117
- { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153
- { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207
- { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63
- { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm
- }, { // above = d153
- { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc
- { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v
- { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h
- { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45
- { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135
- { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117
- { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153
- { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207
- { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63
- { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm
- }, { // above = d207
- { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc
- { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v
- { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h
- { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45
- { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135
- { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117
- { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153
- { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207
- { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63
- { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm
- }, { // above = d63
- { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc
- { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v
- { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h
- { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45
- { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135
- { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117
- { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153
- { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207
- { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63
- { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm
- }, { // above = tm
- { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc
- { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v
- { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h
- { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45
- { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135
- { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117
- { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153
- { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207
- { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63
- { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm
- }
+const vp9_prob vp9_intra_mode_prob[INTRA_MODES] = {
+ 227, 223, 219, 213, 204, 191, 170, 127
+};
+
+const vp9_prob vp9_intra_predictor_prob[3] = {
+ 170, 192, 170
};
const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = {
@@ -329,6 +223,7 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
vp9_copy(fc->single_ref_prob, default_single_ref_p);
fc->tx_probs = default_tx_probs;
vp9_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
+ vp9_copy(fc->intra_predictor_prob, vp9_intra_predictor_prob);
vp9_copy(fc->skip_probs, default_skip_probs);
vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
}
diff --git a/vp9/common/vp9_entropymode.h b/vp9/common/vp9_entropymode.h
index 8db3de9f2..68c89ebd2 100644
--- a/vp9/common/vp9_entropymode.h
+++ b/vp9/common/vp9_entropymode.h
@@ -50,6 +50,7 @@ typedef struct frame_contexts {
vp9_prob comp_ref_prob[REF_CONTEXTS];
struct tx_probs tx_probs;
vp9_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
+ vp9_prob intra_predictor_prob[3];
vp9_prob skip_probs[SKIP_CONTEXTS];
nmv_context nmvc;
int initialized;
@@ -72,12 +73,12 @@ typedef struct FRAME_COUNTS {
struct tx_counts tx;
unsigned int skip[SKIP_CONTEXTS][2];
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
+ unsigned int intra_predictor[2][2];
nmv_context_counts mv;
} FRAME_COUNTS;
+extern const vp9_prob vp9_intra_mode_prob[INTRA_MODES];
extern const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1];
-extern const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES]
- [INTRA_MODES - 1];
extern const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS]
[PARTITION_TYPES - 1];
extern const vp9_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
@@ -99,15 +100,6 @@ void tx_counts_to_branch_counts_16x16(const unsigned int *tx_count_16x16p,
void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
unsigned int (*ct_8x8p)[2]);
-static INLINE const vp9_prob *get_y_mode_probs(const MODE_INFO *mi,
- const MODE_INFO *above_mi,
- const MODE_INFO *left_mi,
- int block) {
- const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
- const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
- return vp9_kf_y_mode_prob[above][left];
-}
-
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 16e30d99f..d6546e6f2 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -1598,6 +1598,9 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
vp9_diff_update_prob(&r, &fc->txfm_partition_prob[k]);
+ for (k = 0; k < 3; ++k)
+ vp9_diff_update_prob(&r, &fc->intra_predictor_prob[k]);
+
for (k = 0; k < SKIP_CONTEXTS; ++k)
vp9_diff_update_prob(&r, &fc->skip_probs[k]);
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index 0ea7337e3..a6fdd7948 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -23,6 +23,51 @@
#include "vp9/decoder/vp9_decodeframe.h"
#include "vp9/decoder/vp9_reader.h"
+static PREDICTION_MODE read_intra_mode_exp(const VP9_COMMON *cm,
+ vp9_reader *r, const MODE_INFO *mi,
+ const MODE_INFO *above_mi,
+ const MODE_INFO *left_mi,
+ int block) {
+ const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
+ const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
+ PREDICTION_MODE i;
+ int count = 0;
+
+ if (above == left) {
+ if (vp9_read(r, cm->fc->intra_predictor_prob[0]))
+ return above;
+ for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+ if (i == above)
+ continue;
+ if (vp9_read(r, vp9_intra_mode_prob[count]))
+ return i;
+ ++count;
+ if (count == INTRA_MODES - 2)
+ return (i + 1) == above ? (i + 2) : (i + 1);
+ }
+ return (INTRA_MODES - 1);
+ } else {
+ if (vp9_read(r, cm->fc->intra_predictor_prob[1]))
+ return above;
+ if (vp9_read(r, cm->fc->intra_predictor_prob[2]))
+ return left;
+
+ for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+ if (i == above || i == left)
+ continue;
+ if (vp9_read(r, vp9_intra_mode_prob[count + 1]))
+ return i;
+ ++count;
+ if (count == INTRA_MODES - 3)
+ break;
+ }
+ for (++i; i <= INTRA_MODES - 1; ++i)
+ if (i != above && i != left)
+ return i;
+ return (INTRA_MODES - 1);
+ }
+}
+
static PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
return (PREDICTION_MODE)vp9_read_tree(r, vp9_intra_mode_tree, p);
}
@@ -264,24 +309,24 @@ static void read_intra_frame_mode_info(VP9_COMMON *const cm,
case BLOCK_4X4:
for (i = 0; i < 4; ++i)
mi->bmi[i].as_mode =
- read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, i));
+ read_intra_mode_exp(cm, r, mi, above_mi, left_mi, i);
mbmi->mode = mi->bmi[3].as_mode;
break;
case BLOCK_4X8:
mi->bmi[0].as_mode = mi->bmi[2].as_mode =
- read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
+ read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
- read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 1));
+ read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 1);
break;
case BLOCK_8X4:
mi->bmi[0].as_mode = mi->bmi[1].as_mode =
- read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 0));
+ read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
- read_intra_mode(r, get_y_mode_probs(mi, above_mi, left_mi, 2));
+ read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 2);
break;
default:
- mbmi->mode = read_intra_mode(r,
- get_y_mode_probs(mi, above_mi, left_mi, 0));
+ mbmi->mode =
+ read_intra_mode_exp(cm, r, mi, above_mi, left_mi, 0);
}
mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index e74774768..1a91a41f7 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -44,6 +44,53 @@ static const struct vp9_token partition_encodings[PARTITION_TYPES] =
static const struct vp9_token inter_mode_encodings[INTER_MODES] =
{{2, 2}, {6, 3}, {0, 1}, {7, 3}};
+static void write_intra_mode_exp(const VP9_COMMON *cm,
+ vp9_writer *w, const MODE_INFO *mi,
+ const MODE_INFO *above_mi,
+ const MODE_INFO *left_mi, int block,
+ PREDICTION_MODE mode) {
+ const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, block);
+ const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, block);
+ PREDICTION_MODE i;
+ int count = 0;
+
+ if (above == left) {
+ vp9_write(w, mode == above, cm->fc->intra_predictor_prob[0]);
+ if (mode == above)
+ return;
+
+ for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+ if (i == above)
+ continue;
+ vp9_write(w, i == mode, vp9_intra_mode_prob[count]);
+ ++count;
+ if (i == mode)
+ return;
+ if (count == INTRA_MODES - 2)
+ return;
+ }
+ } else {
+ // above and left reference modes differ
+ vp9_write(w, mode == above, cm->fc->intra_predictor_prob[1]);
+ if (mode == above)
+ return;
+ vp9_write(w, mode == left, cm->fc->intra_predictor_prob[2]);
+ if (mode == left)
+ return;
+
+ for (i = DC_PRED; i < INTRA_MODES - 1; ++i) {
+ if (i == above || i == left)
+ continue;
+ vp9_write(w, i == mode, vp9_intra_mode_prob[count + 1]);
+ ++count;
+ if (i == mode)
+ return;
+ if (count == INTRA_MODES - 3)
+ return;
+ }
+ }
+}
+
static void write_intra_mode(vp9_writer *w, PREDICTION_MODE mode,
const vp9_prob *probs) {
vp9_write_token(w, vp9_intra_mode_tree, probs, &intra_mode_encodings[mode]);
@@ -145,6 +192,14 @@ static void update_txfm_partition_probs(VP9_COMMON *cm, vp9_writer *w,
counts->txfm_partition[k]);
}
+static void update_intra_predictor_probs(VP9_COMMON *cm, vp9_writer *w,
+ FRAME_COUNTS *counts) {
+ int k;
+ for (k = 0; k < 3; ++k)
+ vp9_cond_prob_diff_update(w, &cm->fc->intra_predictor_prob[k],
+ counts->intra_predictor[k]);
+}
+
static int write_skip(const VP9_COMMON *cm, const MACROBLOCKD *xd,
int segment_id, const MODE_INFO *mi, vp9_writer *w) {
if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
@@ -449,7 +504,7 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
write_selected_tx_size(cm, xd, w);
if (bsize >= BLOCK_8X8) {
- write_intra_mode(w, mbmi->mode, get_y_mode_probs(mi, above_mi, left_mi, 0));
+ write_intra_mode_exp(cm, w, mi, above_mi, left_mi, 0, mbmi->mode);
} else {
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -458,8 +513,8 @@ static void write_mb_modes_kf(const VP9_COMMON *cm, const MACROBLOCKD *xd,
for (idy = 0; idy < 2; idy += num_4x4_h) {
for (idx = 0; idx < 2; idx += num_4x4_w) {
const int block = idy * 2 + idx;
- write_intra_mode(w, mi->bmi[block].as_mode,
- get_y_mode_probs(mi, above_mi, left_mi, block));
+ write_intra_mode_exp(cm, w, mi, above_mi, left_mi, block,
+ mi->bmi[block].as_mode);
}
}
}
@@ -1258,6 +1313,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
update_coef_probs(cpi, &header_bc);
update_txfm_partition_probs(cm, &header_bc, counts);
+ update_intra_predictor_probs(cm, &header_bc, counts);
update_skip_probs(cm, &header_bc, counts);
if (!frame_is_intra_only(cm)) {
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 4b13aa374..b469a8e6d 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -4211,6 +4211,45 @@ static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows)
mi_8x8[mis * y + x].src_mi->mbmi.tx_size = tx_size;
}
+
+ if (!is_inter_block(mbmi)) {
+ // TODO(jingning): refactor this code for speed improvement.
+ const MODE_INFO *above_mi = xd->mi[-cm->mi_stride].src_mi;
+ const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL;
+ if (bsize >= BLOCK_8X8) {
+ int idx, idy;
+ const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
+ const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
+ for (idy = 0; idy < 2; idy += num_4x4_h) {
+ for (idx = 0; idx < 2; idx += num_4x4_w) {
+ const int block = idy * 2 + idx;
+ const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi,
+ block);
+ const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi,
+ block);
+ if (above == left) {
+ ++td->counts->intra_predictor[0][mi->bmi[block].as_mode == above];
+ } else {
+ ++td->counts->intra_predictor[1][mi->bmi[block].as_mode == above];
+ if (mbmi->mode != above)
+ ++td->counts->intra_predictor[1]
+ [mi->bmi[block].as_mode == left];
+ }
+ }
+ }
+ } else {
+ const PREDICTION_MODE above = vp9_above_block_mode(mi, above_mi, 0);
+ const PREDICTION_MODE left = vp9_left_block_mode(mi, left_mi, 0);
+ if (above == left) {
+ ++td->counts->intra_predictor[0][mbmi->mode == above];
+ } else {
+ ++td->counts->intra_predictor[1][mbmi->mode == above];
+ if (mbmi->mode != above)
+ ++td->counts->intra_predictor[1][mbmi->mode == left];
+ }
+ }
+ }
+
++td->counts->tx.tx_totals[mbmi->tx_size];
++td->counts->tx.tx_totals[get_uv_tx_size(mbmi, &xd->plane[1])];
}
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index b69fcfc26..ccdac6617 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -940,12 +940,11 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
MIN(max_txsize_lookup[bsize],
tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
MODE_INFO *const mic = xd->mi[0].src_mi;
- int *bmode_costs;
+ int bmode_costs;
const MODE_INFO *above_mi = xd->mi[-xd->mi_stride].src_mi;
const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL;
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
- bmode_costs = cpi->y_mode_costs[A][L];
(void) ctx;
vp9_rd_cost_reset(&best_rdc);
@@ -963,11 +962,17 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
args.rate = 0;
args.dist = 0;
mbmi->tx_size = intra_tx_size;
+
+ if (A == L)
+ bmode_costs = (this_mode == A) ? 406 : 961;
+ else // (A != L)
+ bmode_costs = (this_mode == A) || (this_mode == L) ? 512 : 1024;
+
vp9_foreach_transformed_block_in_plane(xd, bsize, 0,
estimate_block_intra, &args);
this_rdc.rate = args.rate;
this_rdc.dist = args.dist;
- this_rdc.rate += bmode_costs[this_mode];
+ this_rdc.rate += bmode_costs;
this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
this_rdc.rate, this_rdc.dist);
diff --git a/vp9/encoder/vp9_rd.c b/vp9/encoder/vp9_rd.c
index bbf70ead5..217626c2e 100644
--- a/vp9/encoder/vp9_rd.c
+++ b/vp9/encoder/vp9_rd.c
@@ -66,12 +66,7 @@ static const uint8_t rd_thresh_block_size_factor[BLOCK_SIZES] = {
static void fill_mode_costs(VP9_COMP *cpi) {
const FRAME_CONTEXT *const fc = cpi->common.fc;
- int i, j;
-
- for (i = 0; i < INTRA_MODES; ++i)
- for (j = 0; j < INTRA_MODES; ++j)
- vp9_cost_tokens(cpi->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
- vp9_intra_mode_tree);
+ int i;
vp9_cost_tokens(cpi->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
vp9_cost_tokens(cpi->intra_uv_mode_cost[KEY_FRAME],
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 912a92a6b..8869d8407 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -777,8 +777,8 @@ static int conditional_skipintra(PREDICTION_MODE mode,
static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
PREDICTION_MODE *best_mode,
- const int *bmode_costs,
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
+ PREDICTION_MODE A, PREDICTION_MODE L,
int *bestrate, int *bestratey,
int64_t *bestdistortion,
BLOCK_SIZE bsize, int64_t rd_thresh) {
@@ -817,7 +817,12 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
int64_t this_rd;
int ratey = 0;
int64_t distortion = 0;
- int rate = bmode_costs[mode];
+ int rate;
+
+ if (A == L)
+ rate = (mode == A) ? 256 : 1064;
+ else // (A != L)
+ rate = (mode == A) || (mode == L) ? 404 : 1169;
if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
continue;
@@ -918,7 +923,12 @@ static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
int64_t this_rd;
int ratey = 0;
int64_t distortion = 0;
- int rate = bmode_costs[mode];
+ int rate;
+
+ if (A == L)
+ rate = (mode == A) ? 406 : 961;
+ else // (A != L)
+ rate = (mode == A) || (mode == L) ? 512 : 1024;
if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
continue;
@@ -1026,7 +1036,8 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
int tot_rate_y = 0;
int64_t total_rd = 0;
ENTROPY_CONTEXT t_above[4], t_left[4];
- const int *bmode_costs = cpi->mbmode_cost;
+ PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
+ PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
@@ -1039,14 +1050,13 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
int64_t d = INT64_MAX, this_rd = INT64_MAX;
i = idy * 2 + idx;
if (cpi->common.frame_type == KEY_FRAME) {
- const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, i);
- const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, i);
-
- bmode_costs = cpi->y_mode_costs[A][L];
+ A = vp9_above_block_mode(mic, above_mi, i);
+ L = vp9_left_block_mode(mic, left_mi, i);
}
- this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs,
- t_above + idx, t_left + idy, &r, &ry, &d,
+ this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode,
+ t_above + idx, t_left + idy,
+ A, L, &r, &ry, &d,
bsize, best_rd - total_rd);
if (this_rd >= best_rd - total_rd)
return INT64_MAX;
@@ -1090,12 +1100,11 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
int64_t this_distortion, this_rd;
TX_SIZE best_tx = TX_4X4;
int i;
- int *bmode_costs;
+ int bmode_costs;
const MODE_INFO *above_mi = xd->above_mi;
const MODE_INFO *left_mi = xd->left_mi;
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
- bmode_costs = cpi->y_mode_costs[A][L];
if (cpi->sf.tx_size_search_method == USE_FULL_RD)
for (i = 0; i < TX_MODES; i++)
@@ -1106,6 +1115,11 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
int64_t local_tx_cache[TX_MODES];
+ if (A == L)
+ bmode_costs = (mode == A) ? 406 : 961;
+ else // (A != L)
+ bmode_costs = (mode == A) || (mode == L) ? 512 : 1024;
+
if (cpi->sf.use_nonrd_pick_mode) {
// These speed features are turned on in hybrid non-RD and RD mode
// for key frame coding in the context of real-time setting.
@@ -1123,7 +1137,7 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (this_rate_tokenonly == INT_MAX)
continue;
- this_rate = this_rate_tokenonly + bmode_costs[mode];
+ this_rate = this_rate_tokenonly + bmode_costs;
this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
if (this_rd < best_rd) {
@@ -3782,6 +3796,13 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
struct macroblockd_plane *const pd = &xd->plane[1];
+ MODE_INFO *const mic = xd->mi[0].src_mi;
+ const MODE_INFO *above_mi = xd->above_mi;
+ const MODE_INFO *left_mi = xd->left_mi;
+
+ const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
+ const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
+ int intra_mode_cost;
vpx_memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
NULL, bsize, tx_cache, best_rd);
@@ -3796,12 +3817,17 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
&dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
}
+ if (A == L)
+ intra_mode_cost = (this_mode == A) ? 256 : 1064;
+ else // (A != L)
+ intra_mode_cost = (this_mode == A) || (this_mode == L) ? 404 : 1169;
+
rate_uv = rate_uv_tokenonly[uv_tx];
distortion_uv = dist_uv[uv_tx];
skippable = skippable && skip_uv[uv_tx];
mbmi->uv_mode = mode_uv[uv_tx];
- rate2 = rate_y + cpi->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
+ rate2 = rate_y + intra_mode_cost + rate_uv_intra[uv_tx];
if (this_mode != DC_PRED && this_mode != TM_PRED)
rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;