Moving quantization and loopfilter data to uncompressed header.
Overall PSNR drop on derf set is -0.024. Change-Id: I1c05d2ace83488205ca16e3b06cd5f0ebceec8d6
This commit is contained in:
parent
317d832d38
commit
b8b91b2f91
@ -40,10 +40,6 @@
|
|||||||
int dec_debug = 0;
|
int dec_debug = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int read_le16(const uint8_t *p) {
|
|
||||||
return (p[1] << 8) | p[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static int read_le32(const uint8_t *p) {
|
static int read_le32(const uint8_t *p) {
|
||||||
return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
|
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];
|
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,
|
static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize,
|
||||||
int ss_txfrm_size, void *arg) {
|
int ss_txfrm_size, void *arg) {
|
||||||
MACROBLOCKD* const xd = 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,
|
static void set_offsets(VP9D_COMP *pbi, BLOCK_SIZE_TYPE bsize,
|
||||||
int mi_row, int mi_col) {
|
int mi_row, int mi_col) {
|
||||||
const int bh = 1 << mi_height_log2(bsize);
|
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) {
|
static void setup_loopfilter(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
|
||||||
pc->filter_level = vp9_read_literal(r, 6);
|
VP9_COMMON *const cm = &pbi->common;
|
||||||
pc->sharpness_level = vp9_read_literal(r, 3);
|
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
|
// Read in loop filter deltas applied at the MB level based on mode or ref
|
||||||
// frame.
|
// frame.
|
||||||
xd->mode_ref_lf_delta_update = 0;
|
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) {
|
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) {
|
if (xd->mode_ref_lf_delta_update) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_REF_LF_DELTAS; i++) {
|
for (i = 0; i < MAX_REF_LF_DELTAS; i++) {
|
||||||
if (vp9_read_bit(r)) {
|
if (vp9_rb_read_bit(rb)) {
|
||||||
const int value = vp9_read_literal(r, 6);
|
const int value = vp9_rb_read_literal(rb, 6);
|
||||||
xd->ref_lf_deltas[i] = vp9_read_and_apply_sign(r, value);
|
xd->ref_lf_deltas[i] = vp9_rb_read_bit(rb) ? -value : value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
|
for (i = 0; i < MAX_MODE_LF_DELTAS; i++) {
|
||||||
if (vp9_read_bit(r)) {
|
if (vp9_rb_read_bit(rb)) {
|
||||||
const int value = vp9_read_literal(r, 6);
|
const int value = vp9_rb_read_literal(rb, 6);
|
||||||
xd->mode_lf_deltas[i] = vp9_read_and_apply_sign(r, value);
|
xd->mode_lf_deltas[i] = vp9_rb_read_bit(rb) ? -value : value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_quantization(VP9D_COMP *pbi, vp9_reader *r) {
|
static int read_delta_q(struct vp9_read_bit_buffer *rb, int *delta_q) {
|
||||||
// Read the default quantizers
|
const int old = *delta_q;
|
||||||
VP9_COMMON *const pc = &pbi->common;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
pc->base_qindex = vp9_read_literal(r, QINDEX_BITS);
|
static void setup_quantization(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) {
|
||||||
if (get_delta_q(r, &pc->y_dc_delta_q) |
|
VP9_COMMON *const cm = &pbi->common;
|
||||||
get_delta_q(r, &pc->uv_dc_delta_q) |
|
int update = 0;
|
||||||
get_delta_q(r, &pc->uv_ac_delta_q))
|
cm->base_qindex = vp9_rb_read_literal(rb, QINDEX_BITS);
|
||||||
vp9_init_dequantizer(pc);
|
update |= read_delta_q(rb, &cm->y_dc_delta_q);
|
||||||
|
update |= read_delta_q(rb, &cm->uv_dc_delta_q);
|
||||||
mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup
|
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) {
|
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;
|
cm->frame_parallel_decoding_mode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_loopfilter(pbi, rb);
|
||||||
|
setup_quantization(pbi, rb);
|
||||||
|
|
||||||
return vp9_rb_read_literal(rb, 16);
|
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,
|
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
||||||
"Failed to allocate bool decoder 0");
|
"Failed to allocate bool decoder 0");
|
||||||
|
|
||||||
setup_loopfilter(pc, xd, &header_bc);
|
mb_init_dequantizer(pc, &pbi->mb); // MB level dequantizer setup
|
||||||
|
|
||||||
setup_quantization(pbi, &header_bc);
|
|
||||||
|
|
||||||
xd->lossless = pc->base_qindex == 0 &&
|
xd->lossless = pc->base_qindex == 0 &&
|
||||||
pc->y_dc_delta_q == 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;
|
int i;
|
||||||
|
|
||||||
// Encode the loop filter level and type
|
// Encode the loop filter level and type
|
||||||
vp9_write_literal(w, pc->filter_level, 6);
|
vp9_wb_write_literal(wb, pc->filter_level, 6);
|
||||||
vp9_write_literal(w, pc->sharpness_level, 3);
|
vp9_wb_write_literal(wb, pc->sharpness_level, 3);
|
||||||
|
|
||||||
// Write out loop filter deltas applied at the MB level based on mode or
|
// Write out loop filter deltas applied at the MB level based on mode or
|
||||||
// ref frame (if they are enabled).
|
// 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) {
|
if (xd->mode_ref_lf_delta_enabled) {
|
||||||
// Do the deltas need to be updated
|
// 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) {
|
if (xd->mode_ref_lf_delta_update) {
|
||||||
// Send update
|
// Send update
|
||||||
for (i = 0; i < MAX_REF_LF_DELTAS; i++) {
|
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
|
// Frame level data
|
||||||
if (delta != xd->last_ref_lf_deltas[i]) {
|
if (delta != xd->last_ref_lf_deltas[i]) {
|
||||||
xd->last_ref_lf_deltas[i] = delta;
|
xd->last_ref_lf_deltas[i] = delta;
|
||||||
vp9_write_bit(w, 1);
|
vp9_wb_write_bit(wb, 1);
|
||||||
|
|
||||||
if (delta > 0) {
|
assert(delta != 0);
|
||||||
vp9_write_literal(w, delta & 0x3F, 6);
|
vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6);
|
||||||
vp9_write_bit(w, 0); // sign
|
vp9_wb_write_bit(wb, delta < 0);
|
||||||
} else {
|
|
||||||
assert(delta < 0);
|
|
||||||
vp9_write_literal(w, (-delta) & 0x3F, 6);
|
|
||||||
vp9_write_bit(w, 1); // sign
|
|
||||||
}
|
|
||||||
} else {
|
} 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];
|
const int delta = xd->mode_lf_deltas[i];
|
||||||
if (delta != xd->last_mode_lf_deltas[i]) {
|
if (delta != xd->last_mode_lf_deltas[i]) {
|
||||||
xd->last_mode_lf_deltas[i] = delta;
|
xd->last_mode_lf_deltas[i] = delta;
|
||||||
vp9_write_bit(w, 1);
|
vp9_wb_write_bit(wb, 1);
|
||||||
|
|
||||||
if (delta > 0) {
|
assert(delta != 0);
|
||||||
vp9_write_literal(w, delta & 0x3F, 6);
|
vp9_wb_write_literal(wb, abs(delta) & 0x3F, 6);
|
||||||
vp9_write_bit(w, 0); // sign
|
vp9_wb_write_bit(wb, delta < 0);
|
||||||
} else {
|
|
||||||
assert(delta < 0);
|
|
||||||
vp9_write_literal(w, (-delta) & 0x3F, 6);
|
|
||||||
vp9_write_bit(w, 1); // sign
|
|
||||||
}
|
|
||||||
} else {
|
} 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) {
|
if (delta_q != 0) {
|
||||||
vp9_write_bit(bc, 1);
|
vp9_wb_write_bit(wb, 1);
|
||||||
vp9_write_literal(bc, abs(delta_q), 4);
|
vp9_wb_write_literal(wb, abs(delta_q), 4);
|
||||||
vp9_write_bit(bc, delta_q < 0);
|
vp9_wb_write_bit(wb, delta_q < 0);
|
||||||
} else {
|
} else {
|
||||||
vp9_write_bit(bc, 0);
|
vp9_wb_write_bit(wb, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encode_quantization(VP9_COMMON *pc, vp9_writer *w) {
|
static void encode_quantization(VP9_COMMON *cm,
|
||||||
vp9_write_literal(w, pc->base_qindex, QINDEX_BITS);
|
struct vp9_write_bit_buffer *wb) {
|
||||||
put_delta_q(w, pc->y_dc_delta_q);
|
vp9_wb_write_literal(wb, cm->base_qindex, QINDEX_BITS);
|
||||||
put_delta_q(w, pc->uv_dc_delta_q);
|
write_delta_q(wb, cm->y_dc_delta_q);
|
||||||
put_delta_q(w, pc->uv_ac_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) {
|
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 ||
|
const int scaling_active = cm->width != cm->display_width ||
|
||||||
cm->height != cm->display_height;
|
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->refresh_frame_context);
|
||||||
vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
|
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) {
|
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 wb = {dest, 0};
|
||||||
struct vp9_write_bit_buffer first_partition_size_wb;
|
struct vp9_write_bit_buffer first_partition_size_wb;
|
||||||
|
|
||||||
write_uncompressed_header(pc, &wb);
|
write_uncompressed_header(cpi, &wb);
|
||||||
first_partition_size_wb = wb;
|
first_partition_size_wb = wb;
|
||||||
vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size
|
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);
|
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
|
// When there is a key frame all reference buffers are updated using the new key frame
|
||||||
if (pc->frame_type != KEY_FRAME) {
|
if (pc->frame_type != KEY_FRAME) {
|
||||||
int refresh_mask;
|
int refresh_mask;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user