Commit 1d44e7ce authored by Yaowu Xu's avatar Yaowu Xu
Browse files

enable selecting&transmitting to for intra mode entropy

This commit added a 3 bit index to the bitstream, the index is used to
look into the intra mode coding entropy context table. The commit uses
the mode stats to calculate the cost of transmitting modes using 8
possible entropy distributions, and selects the distribution that
provides the lowest cost to do the actual mode coding.

Initial test show this provides additional .2%~.3% gain over quantizer
adaptive intra mode coding. So the adaptive intra mode coding provides
a total of .5%(psnr) to .6% gain(ssim) combined for all-key-encoding

To build and test, configure with
--enable-experimental --enable-qimode

Change-Id: I7c41cd8bfb352bc1fe7c5da1848a58faea5ed74a
parent aac2c126
...@@ -207,6 +207,9 @@ void vp8_create_common(VP8_COMMON *oci) ...@@ -207,6 +207,9 @@ void vp8_create_common(VP8_COMMON *oci)
/* Default disable buffer to buffer copying */ /* Default disable buffer to buffer copying */
oci->copy_buffer_to_gf = 0; oci->copy_buffer_to_gf = 0;
oci->copy_buffer_to_arf = 0; oci->copy_buffer_to_arf = 0;
#if CONFIG_QIMODE
oci->kf_ymode_probs_update = 0;
#endif
} }
void vp8_remove_common(VP8_COMMON *oci) void vp8_remove_common(VP8_COMMON *oci)
......
...@@ -25,7 +25,7 @@ void vpx_log(const char *format, ...); ...@@ -25,7 +25,7 @@ void vpx_log(const char *format, ...);
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
#define MODE_STATS //#define MODE_STATS
/*#define DCPRED 1*/ /*#define DCPRED 1*/
#define DCPREDSIMTHRESH 0 #define DCPREDSIMTHRESH 0
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#if CONFIG_I8X8 #if CONFIG_I8X8
#if CONFIG_QIMODE #if CONFIG_QIMODE
static const unsigned int kf_y_mode_cts[8][VP8_YMODES] = const unsigned int kf_y_mode_cts[8][VP8_YMODES] =
{ {
{17, 6, 5, 2, 22, 203}, {17, 6, 5, 2, 22, 203},
{27, 13, 13, 6, 27, 170}, {27, 13, 13, 6, 27, 170},
......
...@@ -185,6 +185,8 @@ typedef struct VP8Common ...@@ -185,6 +185,8 @@ typedef struct VP8Common
vp8_prob kf_bmode_prob [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1]; vp8_prob kf_bmode_prob [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1];
#if CONFIG_QIMODE #if CONFIG_QIMODE
vp8_prob kf_ymode_prob[8][VP8_YMODES-1]; /* keyframe "" */ vp8_prob kf_ymode_prob[8][VP8_YMODES-1]; /* keyframe "" */
int kf_ymode_probs_index;
int kf_ymode_probs_update;
#else #else
vp8_prob kf_ymode_prob [VP8_YMODES-1]; /* keyframe "" */ vp8_prob kf_ymode_prob [VP8_YMODES-1]; /* keyframe "" */
#endif #endif
......
...@@ -92,7 +92,7 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_co ...@@ -92,7 +92,7 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_co
m->mbmi.mb_skip_coeff = 0; m->mbmi.mb_skip_coeff = 0;
#if CONFIG_QIMODE #if CONFIG_QIMODE
y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc, y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc,
pbi->common.kf_ymode_prob[pbi->common.base_qindex>>4]); pbi->common.kf_ymode_prob[pbi->common.kf_ymode_probs_index]);
#else #else
y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc, pbi->common.kf_ymode_prob); y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc, pbi->common.kf_ymode_prob);
#endif #endif
...@@ -127,7 +127,6 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_co ...@@ -127,7 +127,6 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_co
} }
//printf("%2d%2d%2d%2d\n", m->bmi[0].as_mode,m->bmi[2].as_mode, //printf("%2d%2d%2d%2d\n", m->bmi[0].as_mode,m->bmi[2].as_mode,
// m->bmi[8].as_mode,m->bmi[10].as_mode); // m->bmi[8].as_mode,m->bmi[10].as_mode);
*/
} }
else else
#endif #endif
...@@ -557,6 +556,13 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi) ...@@ -557,6 +556,13 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
mb_mode_mv_init(pbi); mb_mode_mv_init(pbi);
#if CONFIG_QIMODE
if(pbi->common.frame_type==KEY_FRAME && !pbi->common.kf_ymode_probs_update)
{
pbi->common.kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3);
}
#endif
while (++mb_row < pbi->common.mb_rows) while (++mb_row < pbi->common.mb_rows)
{ {
int mb_col = -1; int mb_col = -1;
......
...@@ -1160,6 +1160,13 @@ static void write_kfmodes(VP8_COMP *cpi) ...@@ -1160,6 +1160,13 @@ static void write_kfmodes(VP8_COMP *cpi)
vp8_write_literal(bc, prob_skip_false, 8); vp8_write_literal(bc, prob_skip_false, 8);
} }
#if CONFIG_QIMODE
if(!c->kf_ymode_probs_update)
{
vp8_write_literal(bc, c->kf_ymode_probs_index, 3);
}
#endif
while (++mb_row < c->mb_rows) while (++mb_row < c->mb_rows)
{ {
int mb_col = -1; int mb_col = -1;
...@@ -1193,7 +1200,7 @@ static void write_kfmodes(VP8_COMP *cpi) ...@@ -1193,7 +1200,7 @@ static void write_kfmodes(VP8_COMP *cpi)
if (c->mb_no_coeff_skip) if (c->mb_no_coeff_skip)
vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false); vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
#if CONFIG_QIMODE #if CONFIG_QIMODE
kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->base_qindex>>4]); kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->kf_ymode_probs_index]);
#else #else
kfwrite_ymode(bc, ym, c->kf_ymode_prob); kfwrite_ymode(bc, ym, c->kf_ymode_prob);
#endif #endif
...@@ -1785,6 +1792,35 @@ static void put_delta_q(vp8_writer *bc, int delta_q) ...@@ -1785,6 +1792,35 @@ static void put_delta_q(vp8_writer *bc, int delta_q)
else else
vp8_write_bit(bc, 0); vp8_write_bit(bc, 0);
} }
#if CONFIG_QIMODE
extern const unsigned int kf_y_mode_cts[8][VP8_YMODES];
static void decide_kf_ymode_entropy(VP8_COMP *cpi)
{
int mode_cost[MB_MODE_COUNT];
int cost;
int bestcost = INT_MAX;
int bestindex = 0;
int i, j;
for(i=0; i<8; i++)
{
vp8_cost_tokens(mode_cost, cpi->common.kf_ymode_prob[i], vp8_kf_ymode_tree);
cost = 0;
for(j=0;j<VP8_YMODES;j++)
{
cost += mode_cost[j] * cpi->ymode_count[j];
}
if(cost < bestcost)
{
bestindex = i;
bestcost = cost;
}
}
cpi->common.kf_ymode_probs_index = bestindex;
}
#endif
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
{ {
...@@ -2083,6 +2119,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) ...@@ -2083,6 +2119,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
if (pc->frame_type == KEY_FRAME) if (pc->frame_type == KEY_FRAME)
{ {
#if CONFIG_QIMODE
decide_kf_ymode_entropy(cpi);
#endif
write_kfmodes(cpi); write_kfmodes(cpi);
#ifdef ENTROPY_STATS #ifdef ENTROPY_STATS
......
...@@ -41,7 +41,8 @@ void vp8_init_mode_costs(VP8_COMP *c) ...@@ -41,7 +41,8 @@ void vp8_init_mode_costs(VP8_COMP *c)
vp8_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree); vp8_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree);
#if CONFIG_QIMODE #if CONFIG_QIMODE
vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob[c->common.base_qindex>>4], vp8_kf_ymode_tree); vp8_cost_tokens(c->mb.mbmode_cost[0],
x->kf_ymode_prob[c->common.kf_ymode_probs_index], vp8_kf_ymode_tree);
#else #else
vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree); vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree);
#endif #endif
......
...@@ -349,6 +349,10 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex) ...@@ -349,6 +349,10 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
(const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs
); );
#if CONFIG_QIMODE
//rough estimate for costing
cpi->common.kf_ymode_probs_index = cpi->common.base_qindex>>4;
#endif
vp8_init_mode_costs(cpi); vp8_init_mode_costs(cpi);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment