Merge "Optimize the dequantization process on decoder side."

This commit is contained in:
Hangyu Kuang 2015-02-20 08:23:54 -08:00 committed by Gerrit Code Review
commit a28a8cb726
4 changed files with 33 additions and 51 deletions

View File

@ -181,14 +181,6 @@ static void read_mv_probs(nmv_context *ctx, int allow_hp, vp9_reader *r) {
}
}
static void setup_plane_dequants(VP9_COMMON *cm, MACROBLOCKD *xd, int q_index) {
int i;
xd->plane[0].dequant = cm->y_dequant[q_index];
for (i = 1; i < MAX_MB_PLANE; i++)
xd->plane[i].dequant = cm->uv_dequant[q_index];
}
static void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
TX_SIZE tx_size, uint8_t *dst, int stride,
int eob) {
@ -301,6 +293,8 @@ struct intra_args {
MACROBLOCKD *xd;
FRAME_COUNTS *counts;
vp9_reader *r;
const int16_t *const y_dequant;
const int16_t *const uv_dequant;
};
static void predict_and_reconstruct_intra_block(int plane, int block,
@ -313,6 +307,8 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
MODE_INFO *const mi = xd->mi[0].src_mi;
const PREDICTION_MODE mode = (plane == 0) ? get_y_mode(mi, block)
: mi->mbmi.uv_mode;
const int16_t *const dequant = (plane == 0) ? args->y_dequant
: args->uv_dequant;
int x, y;
uint8_t *dst;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
@ -326,7 +322,7 @@ static void predict_and_reconstruct_intra_block(int plane, int block,
if (!mi->mbmi.skip) {
const int eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block,
plane_bsize, x, y, tx_size,
args->r);
args->r, dequant);
inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride,
eob);
}
@ -338,6 +334,8 @@ struct inter_args {
vp9_reader *r;
FRAME_COUNTS *counts;
int *eobtotal;
const int16_t *const y_dequant;
const int16_t *const uv_dequant;
};
static void reconstruct_inter_block(int plane, int block,
@ -347,10 +345,12 @@ static void reconstruct_inter_block(int plane, int block,
VP9_COMMON *const cm = args->cm;
MACROBLOCKD *const xd = args->xd;
struct macroblockd_plane *const pd = &xd->plane[plane];
const int16_t *const dequant = (plane == 0) ? args->y_dequant
: args->uv_dequant;
int x, y, eob;
txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
eob = vp9_decode_block_tokens(cm, xd, args->counts, plane, block, plane_bsize,
x, y, tx_size, args->r);
x, y, tx_size, args->r, dequant);
inverse_transform_block(xd, plane, block, tx_size,
&pd->dst.buf[4 * y * pd->dst.stride + 4 * x],
pd->dst.stride, eob);
@ -393,6 +393,8 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
vp9_reader *r, BLOCK_SIZE bsize) {
VP9_COMMON *const cm = &pbi->common;
const int less8x8 = bsize < BLOCK_8X8;
int16_t y_dequant[2], uv_dequant[2];
int qindex = cm->base_qindex;
MB_MODE_INFO *mbmi = set_offsets(cm, xd, tile, bsize, mi_row, mi_col);
vp9_read_mode_info(pbi, xd, counts, tile, mi_row, mi_col, r);
@ -401,14 +403,17 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
if (mbmi->skip) {
reset_skip_context(xd, bsize);
} else {
if (cm->seg.enabled)
setup_plane_dequants(cm, xd, vp9_get_qindex(&cm->seg, mbmi->segment_id,
cm->base_qindex));
} else if (cm->seg.enabled) {
qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex);
}
y_dequant[0] = vp9_dc_quant(qindex, cm->y_dc_delta_q, cm->bit_depth);
y_dequant[1] = vp9_ac_quant(qindex, 0, cm->bit_depth);
uv_dequant[0] = vp9_dc_quant(qindex, cm->uv_dc_delta_q, cm->bit_depth);
uv_dequant[1] = vp9_ac_quant(qindex, cm->uv_ac_delta_q, cm->bit_depth);
if (!is_inter_block(mbmi)) {
struct intra_args arg = { cm, xd, counts, r };
struct intra_args arg = {cm, xd, counts, r , y_dequant, uv_dequant};
vp9_foreach_transformed_block(xd, bsize,
predict_and_reconstruct_intra_block, &arg);
} else {
@ -418,7 +423,8 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
// Reconstruction
if (!mbmi->skip) {
int eobtotal = 0;
struct inter_args arg = { cm, xd, r, counts, &eobtotal };
struct inter_args arg = {cm, xd, r, counts, &eobtotal, y_dequant,
uv_dequant};
vp9_foreach_transformed_block(xd, bsize, reconstruct_inter_block, &arg);
if (!less8x8 && eobtotal == 0)
mbmi->skip = 1; // skip loopfilter
@ -627,25 +633,17 @@ static void setup_loopfilter(struct loopfilter *lf,
}
}
static int read_delta_q(struct vp9_read_bit_buffer *rb, int *delta_q) {
const int old = *delta_q;
*delta_q = vp9_rb_read_bit(rb) ? vp9_rb_read_signed_literal(rb, 4) : 0;
return old != *delta_q;
static INLINE int read_delta_q(struct vp9_read_bit_buffer *rb) {
return vp9_rb_read_bit(rb) ? vp9_rb_read_signed_literal(rb, 4) : 0;
}
static void setup_quantization(VP9_COMMON *const cm, MACROBLOCKD *const xd,
struct vp9_read_bit_buffer *rb) {
int update = 0;
cm->base_qindex = vp9_rb_read_literal(rb, QINDEX_BITS);
update |= read_delta_q(rb, &cm->y_dc_delta_q);
update |= read_delta_q(rb, &cm->uv_dc_delta_q);
update |= read_delta_q(rb, &cm->uv_ac_delta_q);
if (update || cm->bit_depth != cm->dequant_bit_depth) {
vp9_init_dequantizer(cm);
cm->dequant_bit_depth = cm->bit_depth;
}
cm->y_dc_delta_q = read_delta_q(rb);
cm->uv_dc_delta_q = read_delta_q(rb);
cm->uv_ac_delta_q = read_delta_q(rb);
cm->dequant_bit_depth = cm->bit_depth;
xd->lossless = cm->base_qindex == 0 &&
cm->y_dc_delta_q == 0 &&
cm->uv_dc_delta_q == 0 &&
@ -1550,18 +1548,6 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
return vp9_reader_has_error(&r);
}
void vp9_init_dequantizer(VP9_COMMON *cm) {
int q;
for (q = 0; q < QINDEX_RANGE; q++) {
cm->y_dequant[q][0] = vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth);
cm->y_dequant[q][1] = vp9_ac_quant(q, 0, cm->bit_depth);
cm->uv_dequant[q][0] = vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth);
cm->uv_dequant[q][1] = vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth);
}
}
#ifdef NDEBUG
#define debug_check_frame_counts(cm) (void)0
#else // !NDEBUG
@ -1652,7 +1638,6 @@ void vp9_decode_frame(VP9Decoder *pbi,
!cm->intra_only &&
cm->last_show_frame;
setup_plane_dequants(cm, xd, cm->base_qindex);
vp9_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
*cm->fc = cm->frame_contexts[cm->frame_context_idx];

View File

@ -103,11 +103,6 @@ VP9Decoder *vp9_decoder_create(BufferPool *const pool) {
cm->free_mi = vp9_dec_free_mi;
cm->setup_mi = vp9_dec_setup_mi;
// vp9_init_dequantizer() is first called here. Add check in
// frame_init_dequantizer() to avoid unnecessary calling of
// vp9_init_dequantizer() for every frame.
vp9_init_dequantizer(cm);
vp9_loop_filter_init(cm);
cm->error.setjmp = 0;

View File

@ -215,14 +215,15 @@ static int decode_coefs(VP9_COMMON *cm, const MACROBLOCKD *xd,
int vp9_decode_block_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
FRAME_COUNTS *counts, int plane, int block,
BLOCK_SIZE plane_bsize, int x, int y,
TX_SIZE tx_size, vp9_reader *r) {
TX_SIZE tx_size, vp9_reader *r,
const int16_t *const dequant) {
struct macroblockd_plane *const pd = &xd->plane[plane];
const int ctx = get_entropy_context(tx_size, pd->above_context + x,
pd->left_context + y);
const scan_order *so = get_scan(xd, tx_size, pd->plane_type, block);
const int eob = decode_coefs(cm, xd, counts, pd->plane_type,
BLOCK_OFFSET(pd->dqcoeff, block), tx_size,
pd->dequant, ctx, so->scan, so->neighbors, r);
dequant, ctx, so->scan, so->neighbors, r);
vp9_set_contexts(xd, pd, plane_bsize, tx_size, eob > 0, x, y);
return eob;
}

View File

@ -22,7 +22,8 @@ extern "C" {
int vp9_decode_block_tokens(VP9_COMMON *cm, MACROBLOCKD *xd,
FRAME_COUNTS *counts, int plane, int block,
BLOCK_SIZE plane_bsize, int x, int y,
TX_SIZE tx_size, vp9_reader *r);
TX_SIZE tx_size, vp9_reader *r,
const int16_t *const dequant);
#ifdef __cplusplus
} // extern "C"