Step size and arithmetic coding for delta quantization.

Example performance: 1.8% bit rate savings using
the AQ test mode aq-mode=4 :
./aomenc --codec=av1 --ivf --tile-columns=1 --tile-rows=1 \
                 --kf-max-dist=1000 --kf-min-dist=1000 --cpu-used=0 \
                 --passes=1 --threads=1 --lag-in-frames=0 \
                 --end-usage=q --limit=600 --cq-level=42 \
                 --aq-mode=4 --error-resilient=1 out.bits FourPeople_1280x720_60.y4m

Change-Id: Iba01cf2732a57f3c27481ac2a3c8fc37bb9e5533
This commit is contained in:
Thomas Davies
2016-09-05 16:51:31 +01:00
committed by Yaowu Xu
parent 07441165fe
commit f693610a1a
10 changed files with 177 additions and 75 deletions

View File

@@ -33,6 +33,7 @@
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
#include "av1/common/mvref_common.h"
#include "av1/common/odintrin.h"
#include "av1/common/pred_common.h"
#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
@@ -489,19 +490,38 @@ static int write_skip(const AV1_COMMON *cm, const MACROBLOCKD *xd,
}
#if CONFIG_DELTA_Q
static void write_delta_qindex(int delta_qindex, aom_writer *w) {
static void write_delta_qindex(const AV1_COMMON *cm, int delta_qindex,
aom_writer *w) {
int sign = delta_qindex < 0;
int abs = sign ? -delta_qindex : delta_qindex;
if (abs < 3) {
aom_write_literal(w, 1, abs + 1);
} else {
aom_write_literal(w, 0, 3);
aom_write_literal(w, abs, 6);
int rem_bits, thr, i = 0;
int smallval = abs < DELTA_Q_SMALL ? 1 : 0;
while (i < DELTA_Q_SMALL && i <= abs) {
int bit = (i < abs);
aom_write(w, bit, cm->fc->delta_q_prob[i]);
i++;
}
if (!smallval) {
rem_bits = OD_ILOG_NZ(abs - 1) - 1;
thr = (1 << rem_bits) + 1;
aom_write_literal(w, rem_bits, 3);
aom_write_literal(w, abs - thr, rem_bits);
}
if (abs > 0) {
aom_write_bit(w, sign);
}
}
static void update_delta_q_probs(AV1_COMMON *cm, aom_writer *w,
FRAME_COUNTS *counts) {
int k;
for (k = 0; k < DELTA_Q_CONTEXTS; ++k) {
av1_cond_prob_diff_update(w, &cm->fc->delta_q_prob[k], counts->delta_q[k]);
}
}
#endif
static void update_skip_probs(AV1_COMMON *cm, aom_writer *w,
@@ -1126,12 +1146,14 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
#endif // CONFIG_SUPERTX
#if CONFIG_DELTA_Q
if (cm->delta_q_present_flag) {
int mi_row = (-xd->mb_to_top_edge) >> 6;
int mi_col = (-xd->mb_to_left_edge) >> 6;
int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
int mi_row = (-xd->mb_to_top_edge) >> (MI_SIZE_LOG2 + 3);
int mi_col = (-xd->mb_to_left_edge) >> (MI_SIZE_LOG2 + 3);
int super_block_upper_left =
((mi_row & MAX_MIB_MASK) == 0) && ((mi_col & MAX_MIB_MASK) == 0);
if ((bsize != BLOCK_64X64 || skip == 0) && super_block_upper_left) {
int delta_qindex = mbmi->current_q_index - xd->prev_qindex;
write_delta_qindex(delta_qindex, w);
int reduced_delta_qindex =
(mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
write_delta_qindex(cm, reduced_delta_qindex, w);
xd->prev_qindex = mbmi->current_q_index;
}
}
@@ -1562,8 +1584,9 @@ static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int mi_col = (-xd->mb_to_left_edge) >> 6;
int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
if ((bsize != BLOCK_64X64 || skip == 0) && super_block_upper_left) {
int delta_qindex = mbmi->current_q_index - xd->prev_qindex;
write_delta_qindex(delta_qindex, w);
int reduced_delta_qindex =
(mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
write_delta_qindex(cm, reduced_delta_qindex, w);
xd->prev_qindex = mbmi->current_q_index;
}
}
@@ -3409,6 +3432,7 @@ static void write_uncompressed_header(AV1_COMP *cpi,
cm->delta_q_present_flag = cpi->oxcf.aq_mode == DELTA_AQ;
aom_wb_write_bit(wb, cm->delta_q_present_flag);
if (cm->delta_q_present_flag) {
aom_wb_write_literal(wb, OD_ILOG_NZ(cm->delta_q_res) - 1, 2);
xd->prev_qindex = cm->base_qindex;
}
}
@@ -3530,6 +3554,9 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
#endif
update_skip_probs(cm, header_bc, counts);
#if CONFIG_DELTA_Q
update_delta_q_probs(cm, header_bc, counts);
#endif
update_seg_probs(cpi, header_bc);
for (i = 0; i < INTRA_MODES; ++i)