diff options
author | Dmitry Kovalev <dkovalev@google.com> | 2013-06-03 10:50:57 -0700 |
---|---|---|
committer | Dmitry Kovalev <dkovalev@google.com> | 2013-06-03 10:50:57 -0700 |
commit | b8b91b2f91af1d95dd640d9750ccc01193a5c2d5 (patch) | |
tree | 93027bff949265957bf08049ba43ee071c15c11f /vp9 | |
parent | 317d832d3827f74404b07225061d7e417d751dc8 (diff) | |
download | libvpx-b8b91b2f91af1d95dd640d9750ccc01193a5c2d5.tar libvpx-b8b91b2f91af1d95dd640d9750ccc01193a5c2d5.tar.gz libvpx-b8b91b2f91af1d95dd640d9750ccc01193a5c2d5.tar.bz2 libvpx-b8b91b2f91af1d95dd640d9750ccc01193a5c2d5.zip |
Moving quantization and loopfilter data to uncompressed header.
Overall PSNR drop on derf set is -0.024.
Change-Id: I1c05d2ace83488205ca16e3b06cd5f0ebceec8d6
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/decoder/vp9_decodframe.c | 90 | ||||
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 76 |
2 files changed, 70 insertions, 96 deletions
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index d4b789899..5c03061b5 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -40,10 +40,6 @@ int dec_debug = 0; #endif -static int read_le16(const uint8_t *p) { - return (p[1] << 8) | p[0]; -} - static int read_le32(const uint8_t *p) { return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]; } @@ -186,21 +182,6 @@ static void mb_init_dequantizer(VP9_COMMON *pc, MACROBLOCKD *xd) { xd->plane[i].dequant = pc->uv_dequant[xd->q_index]; } -static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx, - BLOCK_SIZE_TYPE bsize) { - struct macroblockd_plane *const y = &xd->plane[0]; - uint8_t* const dst = raster_block_offset_uint8(xd, bsize, 0, idx, - xd->plane[0].dst.buf, - xd->plane[0].dst.stride); - if (tx_type != DCT_DCT) { - vp9_iht_add_c(tx_type, BLOCK_OFFSET(y->qcoeff, idx, 16), - dst, xd->plane[0].dst.stride, y->eobs[idx]); - } else { - xd->itxm_add(BLOCK_OFFSET(y->qcoeff, idx, 16), - dst, xd->plane[0].dst.stride, y->eobs[idx]); - } -} - static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, int ss_txfrm_size, void *arg) { MACROBLOCKD* const xd = arg; @@ -383,18 +364,6 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, } } -static int get_delta_q(vp9_reader *r, int *dq) { - const int old_value = *dq; - - if (vp9_read_bit(r)) { // Update bit - const int value = vp9_read_literal(r, 4); - *dq = vp9_read_and_apply_sign(r, value); - } - - // Trigger a quantizer update if the delta-q value has changed - return old_value != *dq; -} - static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize, int mi_row, int mi_col) { const int bh = 1 << mi_height_log2(bsize); @@ -693,48 +662,58 @@ static void setup_pred_probs(VP9_COMMON *pc, vp9_reader *r) { } } -static void setup_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_reader *r) { - pc->filter_level = vp9_read_literal(r, 6); - pc->sharpness_level = vp9_read_literal(r, 3); +static void setup_loopfilter(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { + VP9_COMMON *const cm = &pbi->common; + MACROBLOCKD *const xd = &pbi->mb; + + cm->filter_level = vp9_rb_read_literal(rb, 6); + cm->sharpness_level = vp9_rb_read_literal(rb, 3); // Read in loop filter deltas applied at the MB level based on mode or ref // frame. xd->mode_ref_lf_delta_update = 0; - xd->mode_ref_lf_delta_enabled = vp9_read_bit(r); + xd->mode_ref_lf_delta_enabled = vp9_rb_read_bit(rb); if (xd->mode_ref_lf_delta_enabled) { - xd->mode_ref_lf_delta_update = vp9_read_bit(r); + xd->mode_ref_lf_delta_update = vp9_rb_read_bit(rb); if (xd->mode_ref_lf_delta_update) { int i; for (i = 0; i < MAX_REF_LF_DELTAS; i++) { - if (vp9_read_bit(r)) { - const int value = vp9_read_literal(r, 6); - xd->ref_lf_deltas[i] = vp9_read_and_apply_sign(r, value); + if (vp9_rb_read_bit(rb)) { + const int value = vp9_rb_read_literal(rb, 6); + xd->ref_lf_deltas[i] = vp9_rb_read_bit(rb) ? -value : value; } } for (i = 0; i < MAX_MODE_LF_DELTAS; i++) { - if (vp9_read_bit(r)) { - const int value = vp9_read_literal(r, 6); - xd->mode_lf_deltas[i] = vp9_read_and_apply_sign(r, value); + if (vp9_rb_read_bit(rb)) { + const int value = vp9_rb_read_literal(rb, 6); + xd->mode_lf_deltas[i] = vp9_rb_read_bit(rb) ? -value : value; } } } } } -static void setup_quantization(VP9D_COMP *pbi, vp9_reader *r) { - // Read the default quantizers - VP9_COMMON *const pc = &pbi->common; - - pc->base_qindex = vp9_read_literal(r, QINDEX_BITS); - if (get_delta_q(r, &pc->y_dc_delta_q) | - get_delta_q(r, &pc->uv_dc_delta_q) | - get_delta_q(r, &pc->uv_ac_delta_q)) - vp9_init_dequantizer(pc); +static int read_delta_q(struct vp9_read_bit_buffer *rb, int *delta_q) { + const int old = *delta_q; + if (vp9_rb_read_bit(rb)) { + const int value = vp9_rb_read_literal(rb, 4); + *delta_q = vp9_rb_read_bit(rb) ? -value : value; + } + return old != *delta_q; +} - mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup +static void setup_quantization(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { + VP9_COMMON *const cm = &pbi->common; + 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) + vp9_init_dequantizer(cm); } static INTERPOLATIONFILTERTYPE read_mcomp_filter_type(vp9_reader *r) { @@ -966,6 +945,9 @@ size_t read_uncompressed_header(VP9D_COMP *pbi, cm->frame_parallel_decoding_mode = 1; } + setup_loopfilter(pbi, rb); + setup_quantization(pbi, rb); + return vp9_rb_read_literal(rb, 16); } @@ -1008,9 +990,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder 0"); - setup_loopfilter(pc, xd, &header_bc); - - setup_quantization(pbi, &header_bc); + mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup xd->lossless = pc->base_qindex == 0 && pc->y_dc_delta_q == 0 && diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 95e9a7df0..043ac6ad2 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1205,20 +1205,21 @@ static void segment_reference_frames(VP9_COMP *cpi) { } } -static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_writer *w) { +static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, + struct vp9_write_bit_buffer *wb) { int i; // Encode the loop filter level and type - vp9_write_literal(w, pc->filter_level, 6); - vp9_write_literal(w, pc->sharpness_level, 3); + vp9_wb_write_literal(wb, pc->filter_level, 6); + vp9_wb_write_literal(wb, pc->sharpness_level, 3); // Write out loop filter deltas applied at the MB level based on mode or // ref frame (if they are enabled). - vp9_write_bit(w, xd->mode_ref_lf_delta_enabled); + vp9_wb_write_bit(wb, xd->mode_ref_lf_delta_enabled); if (xd->mode_ref_lf_delta_enabled) { // Do the deltas need to be updated - vp9_write_bit(w, xd->mode_ref_lf_delta_update); + vp9_wb_write_bit(wb, xd->mode_ref_lf_delta_update); if (xd->mode_ref_lf_delta_update) { // Send update for (i = 0; i < MAX_REF_LF_DELTAS; i++) { @@ -1227,18 +1228,13 @@ static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_writer *w) { // Frame level data if (delta != xd->last_ref_lf_deltas[i]) { xd->last_ref_lf_deltas[i] = delta; - vp9_write_bit(w, 1); + vp9_wb_write_bit(wb, 1); - if (delta > 0) { - vp9_write_literal(w, delta & 0x3F, 6); - vp9_write_bit(w, 0); // sign - } else { - assert(delta < 0); - vp9_write_literal(w, (-delta) & 0x3F, 6); - vp9_write_bit(w, 1); // sign - } + assert(delta != 0); + vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6); + vp9_wb_write_bit(wb, delta < 0); } else { - vp9_write_bit(w, 0); + vp9_wb_write_bit(wb, 0); } } @@ -1247,39 +1243,35 @@ static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, vp9_writer *w) { const int delta = xd->mode_lf_deltas[i]; if (delta != xd->last_mode_lf_deltas[i]) { xd->last_mode_lf_deltas[i] = delta; - vp9_write_bit(w, 1); + vp9_wb_write_bit(wb, 1); - if (delta > 0) { - vp9_write_literal(w, delta & 0x3F, 6); - vp9_write_bit(w, 0); // sign - } else { - assert(delta < 0); - vp9_write_literal(w, (-delta) & 0x3F, 6); - vp9_write_bit(w, 1); // sign - } + assert(delta != 0); + vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6); + vp9_wb_write_bit(wb, delta < 0); } else { - vp9_write_bit(w, 0); + vp9_wb_write_bit(wb, 0); } } } } } -static void put_delta_q(vp9_writer *bc, int delta_q) { +static void write_delta_q(struct vp9_write_bit_buffer *wb, int delta_q) { if (delta_q != 0) { - vp9_write_bit(bc, 1); - vp9_write_literal(bc, abs(delta_q), 4); - vp9_write_bit(bc, delta_q < 0); + vp9_wb_write_bit(wb, 1); + vp9_wb_write_literal(wb, abs(delta_q), 4); + vp9_wb_write_bit(wb, delta_q < 0); } else { - vp9_write_bit(bc, 0); + vp9_wb_write_bit(wb, 0); } } -static void encode_quantization(VP9_COMMON *pc, vp9_writer *w) { - vp9_write_literal(w, pc->base_qindex, QINDEX_BITS); - put_delta_q(w, pc->y_dc_delta_q); - put_delta_q(w, pc->uv_dc_delta_q); - put_delta_q(w, pc->uv_ac_delta_q); +static void encode_quantization(VP9_COMMON *cm, + struct vp9_write_bit_buffer *wb) { + vp9_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS); + write_delta_q(wb, cm->y_dc_delta_q); + write_delta_q(wb, cm->uv_dc_delta_q); + write_delta_q(wb, cm->uv_ac_delta_q); } @@ -1399,8 +1391,11 @@ static void encode_txfm(VP9_COMP *cpi, vp9_writer *w) { } } -void write_uncompressed_header(VP9_COMMON *cm, +void write_uncompressed_header(VP9_COMP *cpi, struct vp9_write_bit_buffer *wb) { + VP9_COMMON *const cm = &cpi->common; + MACROBLOCKD *const xd = &cpi->mb.e_mbd; + const int scaling_active = cm->width != cm->display_width || cm->height != cm->display_height; @@ -1438,6 +1433,9 @@ void write_uncompressed_header(VP9_COMMON *cm, vp9_wb_write_bit(wb, cm->refresh_frame_context); vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode); } + + encode_loopfilter(cm, xd, wb); + encode_quantization(cm, wb); } void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { @@ -1450,7 +1448,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { struct vp9_write_bit_buffer wb = {dest, 0}; struct vp9_write_bit_buffer first_partition_size_wb; - write_uncompressed_header(pc, &wb); + write_uncompressed_header(cpi, &wb); first_partition_size_wb = wb; vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size @@ -1461,10 +1459,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { vp9_start_encode(&header_bc, cx_data); - encode_loopfilter(pc, xd, &header_bc); - - encode_quantization(pc, &header_bc); - // When there is a key frame all reference buffers are updated using the new key frame if (pc->frame_type != KEY_FRAME) { int refresh_mask; |