Commit 87ab7b0f authored by Dmitry Kovalev's avatar Dmitry Kovalev Committed by Gerrit Code Review
Browse files

Merge "Moving quantization and loopfilter data to uncompressed header." into experimental

parents 9068bce4 b8b91b2f
......@@ -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 &&
......
......@@ -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;
......
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