Commit 25ca3229 authored by Jingning Han's avatar Jingning Han

Trellis based adaptive quantization

This commit combines uniform quantizer with trellis based coefficient
level optimization. It improves the codebase compression performance:

lowres 0.8%
midres 1.0%
hdres  1.6%

Note that the current trellis optimization unit is using C code. This
will make the cost of the overall quantization process slower. A number
of optimizations will come up next.

Change-Id: Id441dd238e4844409d0f08f82604be777f3f5282
parent e14f61b9
......@@ -52,10 +52,6 @@ void vp10_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
pd->dst.buf, pd->dst.stride);
}
#define RDTRUNC(RM, DM, R, D) \
(((1 << (VP9_PROB_COST_SHIFT - 1)) + (R) * (RM)) & \
((1 << VP9_PROB_COST_SHIFT) - 1))
typedef struct vp10_token_state {
int rate;
int error;
......@@ -65,16 +61,12 @@ typedef struct vp10_token_state {
} vp10_token_state;
// TODO(jimbankoski): experiment to find optimal RD numbers.
static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] ={ {9, 7}, {7, 5}, };
static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] ={ {9, 7}, {8, 5}, };
#define UPDATE_RD_COST()\
{\
rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);\
rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);\
if (rd_cost0 == rd_cost1) {\
rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);\
rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);\
}\
}
// This function is a place holder for now but may ultimately need
......@@ -90,8 +82,8 @@ static int trellis_get_coeff_context(const int16_t *scan,
return pt;
}
static int optimize_b(MACROBLOCK *mb, int plane, int block,
TX_SIZE tx_size, int ctx) {
int vp10_optimize_b(MACROBLOCK *mb, int plane, int block,
TX_SIZE tx_size, int ctx) {
MACROBLOCKD *const xd = &mb->e_mbd;
struct macroblock_plane *const p = &mb->plane[plane];
struct macroblockd_plane *const pd = &xd->plane[plane];
......@@ -961,7 +953,7 @@ static void encode_block(int plane, int block, int blk_row, int blk_col,
tx_size);
#else
vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize,
tx_size, VP10_XFORM_QUANT_B);
tx_size, VP10_XFORM_QUANT_FP);
#endif // CONFIG_NEW_QUANT
} else if (x->skip_txfm[plane][blk_index] == SKIP_TXFM_AC_ONLY) {
// fast path forward transform and quantization
......@@ -986,7 +978,7 @@ static void encode_block(int plane, int block, int blk_row, int blk_col,
tx_size);
#else
vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize,
tx_size, VP10_XFORM_QUANT_B);
tx_size, VP10_XFORM_QUANT_FP);
#endif // CONFIG_NEW_QUANT
}
}
......@@ -1021,7 +1013,7 @@ static void encode_block(int plane, int block, int blk_row, int blk_col,
}
#endif
ctx = combine_entropy_contexts(*a, *l);
*a = *l = optimize_b(x, plane, block, tx_size, ctx) > 0;
*a = *l = vp10_optimize_b(x, plane, block, tx_size, ctx) > 0;
} else {
*a = *l = p->eobs[block] > 0;
}
......@@ -1293,7 +1285,7 @@ void vp10_encode_block_intra(int plane, int block, int blk_row, int blk_col,
if (x->optimize) {
int ctx;
ctx = combine_entropy_contexts(*a, *l);
*a = *l = optimize_b(x, plane, block, tx_size, ctx) > 0;
*a = *l = vp10_optimize_b(x, plane, block, tx_size, ctx) > 0;
} else {
*a = *l = p->eobs[block] > 0;
}
......
......@@ -56,6 +56,9 @@ void vp10_xform_quant_dc_fp_nuq(MACROBLOCK *x, int plane, int block,
BLOCK_SIZE plane_bsize, TX_SIZE tx_size);
#endif
int vp10_optimize_b(MACROBLOCK *mb, int plane, int block,
TX_SIZE tx_size, int ctx);
void vp10_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane);
void vp10_encode_block_intra(int plane, int block, int blk_row, int blk_col,
......
......@@ -1223,10 +1223,7 @@ void vp10_init_quantizer(VP10_COMP *cpi) {
const int qrounding_factor = q == 0 ? 64 : 48;
for (i = 0; i < 2; ++i) {
int qrounding_factor_fp = i == 0 ? 48 : 42;
if (q == 0)
qrounding_factor_fp = 64;
int qrounding_factor_fp = 64;
// y
quant = i == 0 ? vp10_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth)
: vp10_ac_quant(q, 0, cm->bit_depth);
......
......@@ -1213,6 +1213,10 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
int rate;
int64_t dist;
int64_t sse;
#if !CONFIG_NEW_QUANT
ENTROPY_CONTEXT coeff_ctx = combine_entropy_contexts(
*(args->t_above + blk_col), *(args->t_left + blk_row));
#endif
if (args->exit_early)
return;
......@@ -1264,9 +1268,10 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
plane_bsize, tx_size);
#else
vp10_xform_quant(x, plane, block, blk_row, blk_col,
plane_bsize, tx_size, VP10_XFORM_QUANT_B);
plane_bsize, tx_size, VP10_XFORM_QUANT_FP);
vp10_optimize_b(x, plane, block, tx_size, coeff_ctx);
#endif // CONFIG_NEW_QUANT
dist_block(args->cpi, x, plane, block, blk_row, blk_col,
dist_block(args->cpi, x, plane, block, blk_row, blk_col,
tx_size, &dist, &sse);
} else if (x->skip_txfm[plane][block >> (tx_size << 1)] ==
SKIP_TXFM_AC_ONLY) {
......@@ -1318,7 +1323,8 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
tx_size);
#else
vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
VP10_XFORM_QUANT_B);
VP10_XFORM_QUANT_FP);
vp10_optimize_b(x, plane, block, tx_size, coeff_ctx);
#endif // CONFIG_NEW_QUANT
dist_block(args->cpi, x, plane, block, blk_row, blk_col,
tx_size, &dist, &sse);
......@@ -3076,6 +3082,8 @@ void vp10_tx_block_rd_b(const VP10_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
vp10_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
VP10_XFORM_QUANT_B);
vp10_optimize_b(x, plane, block, tx_size, coeff_ctx);
// TODO(any): Use dist_block to compute distortion
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
......
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