Use balanced model for intra prediction mode coding

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
This commit is contained in:
Jingning Han 2015-06-19 17:31:34 -07:00
parent 81c389e790
commit ac50b75e50
9 changed files with 212 additions and 156 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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]);

View File

@ -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]);

View File

@ -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)) {

View File

@ -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])];
}

View File

@ -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);

View File

@ -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],

View File

@ -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;