Support for delta-q at superblock level
Change-Id: I4128af44776d1f361bddc1fdffb75ed2224dbfa5
This commit is contained in:
7
aomenc.c
7
aomenc.c
@@ -392,10 +392,17 @@ static const arg_def_t frame_parallel_decoding =
|
||||
ARG_DEF(NULL, "frame-parallel", 1,
|
||||
"Enable frame parallel decodability features "
|
||||
"(0: false (default), 1: true)");
|
||||
#if CONFIG_DELTA_Q
|
||||
static const arg_def_t aq_mode = ARG_DEF(
|
||||
NULL, "aq-mode", 1,
|
||||
"Adaptive quantization mode (0: off (default), 1: variance 2: complexity, "
|
||||
"3: cyclic refresh)");
|
||||
#else
|
||||
static const arg_def_t aq_mode = ARG_DEF(
|
||||
NULL, "aq-mode", 1,
|
||||
"Adaptive quantization mode (0: off (default), 1: variance 2: complexity, "
|
||||
"3: cyclic refresh, 4: equator360)");
|
||||
#endif
|
||||
static const arg_def_t frame_periodic_boost =
|
||||
ARG_DEF(NULL, "frame-boost", 1,
|
||||
"Enable frame periodic boost (0: off (default), 1: on)");
|
||||
|
||||
@@ -246,6 +246,9 @@ typedef struct {
|
||||
#endif // CONFIG_NEW_QUANT
|
||||
/* deringing gain *per-superblock* */
|
||||
int8_t dering_gain;
|
||||
#if CONFIG_DELTA_Q
|
||||
int current_q_index;
|
||||
#endif
|
||||
} MB_MODE_INFO;
|
||||
|
||||
typedef struct MODE_INFO {
|
||||
@@ -401,6 +404,11 @@ typedef struct macroblockd {
|
||||
#if CONFIG_GLOBAL_MOTION
|
||||
Global_Motion_Params *global_motion;
|
||||
#endif // CONFIG_GLOBAL_MOTION
|
||||
#if CONFIG_DELTA_Q
|
||||
int prev_qindex;
|
||||
int delta_qindex;
|
||||
int current_qindex;
|
||||
#endif
|
||||
} MACROBLOCKD;
|
||||
|
||||
static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
|
||||
|
||||
@@ -395,6 +395,9 @@ typedef struct AV1Common {
|
||||
#if CONFIG_DERING
|
||||
int dering_level;
|
||||
#endif
|
||||
#if CONFIG_DELTA_Q
|
||||
int delta_q_present_flag;
|
||||
#endif
|
||||
} AV1_COMMON;
|
||||
|
||||
// TODO(hkuang): Don't need to lock the whole pool after implementing atomic
|
||||
|
||||
@@ -1209,6 +1209,26 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
|
||||
}
|
||||
#endif // CONFIG_SUPERTX
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
if (cm->delta_q_present_flag) {
|
||||
int i;
|
||||
for (i = 0; i < MAX_SEGMENTS; i++) {
|
||||
xd->plane[0].seg_dequant[i][0] =
|
||||
av1_dc_quant(xd->current_qindex, cm->y_dc_delta_q, cm->bit_depth);
|
||||
xd->plane[0].seg_dequant[i][1] =
|
||||
av1_ac_quant(xd->current_qindex, 0, cm->bit_depth);
|
||||
xd->plane[1].seg_dequant[i][0] =
|
||||
av1_dc_quant(xd->current_qindex, cm->uv_dc_delta_q, cm->bit_depth);
|
||||
xd->plane[1].seg_dequant[i][1] =
|
||||
av1_ac_quant(xd->current_qindex, cm->uv_ac_delta_q, cm->bit_depth);
|
||||
xd->plane[2].seg_dequant[i][0] =
|
||||
av1_dc_quant(xd->current_qindex, cm->uv_dc_delta_q, cm->bit_depth);
|
||||
xd->plane[2].seg_dequant[i][1] =
|
||||
av1_ac_quant(xd->current_qindex, cm->uv_ac_delta_q, cm->bit_depth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mbmi->skip) {
|
||||
dec_reset_skip_context(xd);
|
||||
}
|
||||
@@ -3485,6 +3505,27 @@ static size_t read_uncompressed_header(AV1Decoder *pbi,
|
||||
|
||||
setup_segmentation(cm, rb);
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
{
|
||||
struct segmentation *const seg = &cm->seg;
|
||||
int segment_quantizer_active = 0;
|
||||
for (i = 0; i < MAX_SEGMENTS; i++) {
|
||||
if (segfeature_active(seg, i, SEG_LVL_ALT_Q)) {
|
||||
segment_quantizer_active = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (segment_quantizer_active == 0) {
|
||||
cm->delta_q_present_flag = aom_rb_read_bit(rb);
|
||||
} else {
|
||||
cm->delta_q_present_flag = 0;
|
||||
}
|
||||
if (cm->delta_q_present_flag) {
|
||||
xd->prev_qindex = cm->base_qindex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_SEGMENTS; ++i) {
|
||||
const int qindex = cm->seg.enabled
|
||||
? av1_get_qindex(&cm->seg, i, cm->base_qindex)
|
||||
|
||||
@@ -598,6 +598,38 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
|
||||
|
||||
mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
|
||||
mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
if (cm->delta_q_present_flag) {
|
||||
int b_col = mi_col & 7;
|
||||
int b_row = mi_row & 7;
|
||||
int read_delta_q_flag = (b_col == 0 && b_row == 0);
|
||||
if ((bsize != BLOCK_64X64 || mbmi->skip == 0) && read_delta_q_flag) {
|
||||
int sign, abs, tmp, delta_qindex;
|
||||
|
||||
abs = 0;
|
||||
tmp = aom_read_bit(r, ACCT_STR);
|
||||
while (tmp == 0 && abs < 2) {
|
||||
tmp = aom_read_bit(r, ACCT_STR);
|
||||
abs++;
|
||||
}
|
||||
if (tmp == 0) {
|
||||
abs = aom_read_literal(r, 6, ACCT_STR);
|
||||
}
|
||||
|
||||
if (abs) {
|
||||
sign = aom_read_bit(r, ACCT_STR);
|
||||
} else {
|
||||
sign = 1;
|
||||
}
|
||||
|
||||
delta_qindex = sign ? -abs : abs;
|
||||
xd->current_qindex = xd->prev_qindex + delta_qindex;
|
||||
xd->prev_qindex = xd->current_qindex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mbmi->tx_size = read_tx_size_intra(cm, xd, r);
|
||||
mbmi->ref_frame[0] = INTRA_FRAME;
|
||||
mbmi->ref_frame[1] = NONE;
|
||||
@@ -1655,6 +1687,35 @@ static void read_inter_frame_mode_info(AV1Decoder *const pbi,
|
||||
if (!supertx_enabled) {
|
||||
#endif // CONFIG_SUPERTX
|
||||
mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
|
||||
#if CONFIG_DELTA_Q
|
||||
if (cm->delta_q_present_flag) {
|
||||
BLOCK_SIZE bsize = mbmi->sb_type;
|
||||
int b_col = mi_col & 7;
|
||||
int b_row = mi_row & 7;
|
||||
int read_delta_q_flag = (b_col == 0 && b_row == 0);
|
||||
if ((bsize != BLOCK_64X64 || mbmi->skip == 0) && read_delta_q_flag) {
|
||||
int sign, abs, tmp, delta_qindex;
|
||||
|
||||
abs = 0;
|
||||
tmp = aom_read_bit(r, ACCT_STR);
|
||||
while (tmp == 0 && abs < 2) {
|
||||
tmp = aom_read_bit(r, ACCT_STR);
|
||||
abs++;
|
||||
}
|
||||
if (tmp == 0) {
|
||||
abs = aom_read_literal(r, 6, ACCT_STR);
|
||||
}
|
||||
if (abs) {
|
||||
sign = aom_read_bit(r, ACCT_STR);
|
||||
} else {
|
||||
sign = 1;
|
||||
}
|
||||
delta_qindex = sign ? -abs : abs;
|
||||
xd->current_qindex = xd->prev_qindex + delta_qindex;
|
||||
xd->prev_qindex = xd->current_qindex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
|
||||
|
||||
#if CONFIG_VAR_TX
|
||||
|
||||
@@ -488,6 +488,22 @@ 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) {
|
||||
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);
|
||||
}
|
||||
if (abs > 0) {
|
||||
aom_write_bit(w, sign);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void update_skip_probs(AV1_COMMON *cm, aom_writer *w,
|
||||
FRAME_COUNTS *counts) {
|
||||
int k;
|
||||
@@ -1069,8 +1085,14 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
|
||||
#if !CONFIG_REF_MV
|
||||
const nmv_context *nmvc = &cm->fc->nmvc;
|
||||
#endif
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
MACROBLOCK *const x = &cpi->td.mb;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
#else
|
||||
const MACROBLOCK *x = &cpi->td.mb;
|
||||
const MACROBLOCKD *xd = &x->e_mbd;
|
||||
#endif
|
||||
const struct segmentation *const seg = &cm->seg;
|
||||
const struct segmentation_probs *const segp = &cm->fc->seg;
|
||||
const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||
@@ -1102,6 +1124,18 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
|
||||
#else
|
||||
skip = write_skip(cm, xd, segment_id, mi, w);
|
||||
#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);
|
||||
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);
|
||||
xd->prev_qindex = mbmi->current_q_index;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_SUPERTX
|
||||
if (!supertx_enabled)
|
||||
@@ -1503,8 +1537,14 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
static void write_mb_modes_kf(const AV1_COMMON *cm, MACROBLOCKD *xd,
|
||||
MODE_INFO **mi_8x8, aom_writer *w) {
|
||||
int skip;
|
||||
#else
|
||||
static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd,
|
||||
MODE_INFO **mi_8x8, aom_writer *w) {
|
||||
#endif
|
||||
const struct segmentation *const seg = &cm->seg;
|
||||
const struct segmentation_probs *const segp = &cm->fc->seg;
|
||||
const MODE_INFO *const mi = mi_8x8[0];
|
||||
@@ -1515,7 +1555,21 @@ static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd,
|
||||
|
||||
if (seg->update_map) write_segment_id(w, seg, segp, mbmi->segment_id);
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
skip = write_skip(cm, xd, mbmi->segment_id, mi, w);
|
||||
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);
|
||||
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);
|
||||
xd->prev_qindex = mbmi->current_q_index;
|
||||
}
|
||||
}
|
||||
#else
|
||||
write_skip(cm, xd, mbmi->segment_id, mi, w);
|
||||
#endif
|
||||
|
||||
if (bsize >= BLOCK_8X8 && cm->tx_mode == TX_MODE_SELECT &&
|
||||
!xd->lossless[mbmi->segment_id])
|
||||
@@ -2000,8 +2054,12 @@ static void write_modes(AV1_COMP *const cpi, const TileInfo *const tile,
|
||||
const int mi_col_start = tile->mi_col_start;
|
||||
const int mi_col_end = tile->mi_col_end;
|
||||
int mi_row, mi_col;
|
||||
|
||||
av1_zero_above_context(cm, mi_col_start, mi_col_end);
|
||||
#if CONFIG_DELTA_Q
|
||||
if (cpi->common.delta_q_present_flag) {
|
||||
xd->prev_qindex = cpi->common.base_qindex;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (mi_row = mi_row_start; mi_row < mi_row_end; mi_row += cm->mib_size) {
|
||||
av1_zero_left_context(xd);
|
||||
@@ -3337,6 +3395,26 @@ static void write_uncompressed_header(AV1_COMP *cpi,
|
||||
#endif // CONFIG_LOOP_RESTORATION
|
||||
encode_quantization(cm, wb);
|
||||
encode_segmentation(cm, xd, wb);
|
||||
#if CONFIG_DELTA_Q
|
||||
{
|
||||
int i;
|
||||
struct segmentation *const seg = &cm->seg;
|
||||
int segment_quantizer_active = 0;
|
||||
for (i = 0; i < MAX_SEGMENTS; i++) {
|
||||
if (segfeature_active(seg, i, SEG_LVL_ALT_Q)) {
|
||||
segment_quantizer_active = 1;
|
||||
}
|
||||
}
|
||||
if (segment_quantizer_active == 0) {
|
||||
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) {
|
||||
xd->prev_qindex = cm->base_qindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!cm->seg.enabled && xd->lossless[0])
|
||||
cm->tx_mode = ONLY_4X4;
|
||||
else
|
||||
|
||||
@@ -1114,8 +1114,13 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
|
||||
xd->mi[x_idx + y * mis] = mi_addr;
|
||||
}
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
|
||||
av1_init_plane_quantizers(cpi, x);
|
||||
#else
|
||||
if (cpi->oxcf.aq_mode)
|
||||
av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
|
||||
#endif
|
||||
|
||||
if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
|
||||
mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
|
||||
@@ -4188,6 +4193,22 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
|
||||
seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
|
||||
}
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
if (cpi->oxcf.aq_mode == DELTA_AQ) {
|
||||
int sb_row = mi_row >> 3;
|
||||
int sb_col = mi_col >> 3;
|
||||
int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
|
||||
int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
|
||||
int offset_qindex = index < 0 ? -index - 8 : index - 8;
|
||||
int current_qindex = clamp(cm->base_qindex + offset_qindex, 1, 255);
|
||||
xd->delta_qindex = current_qindex - cm->base_qindex;
|
||||
set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
|
||||
xd->mi[0]->mbmi.current_q_index = current_qindex;
|
||||
xd->mi[0]->mbmi.segment_id = 0;
|
||||
av1_init_plane_quantizers(cpi, x);
|
||||
}
|
||||
#endif
|
||||
|
||||
x->source_variance = UINT_MAX;
|
||||
if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
|
||||
BLOCK_SIZE bsize;
|
||||
|
||||
@@ -133,6 +133,9 @@ typedef enum {
|
||||
VARIANCE_AQ = 1,
|
||||
COMPLEXITY_AQ = 2,
|
||||
CYCLIC_REFRESH_AQ = 3,
|
||||
#if CONFIG_DELTA_Q
|
||||
DELTA_AQ = 4,
|
||||
#endif
|
||||
AQ_MODE_COUNT // This should always be the last member of the enum
|
||||
} AQ_MODE;
|
||||
|
||||
|
||||
@@ -1219,7 +1219,15 @@ void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
|
||||
const AV1_COMMON *const cm = &cpi->common;
|
||||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
const QUANTS *const quants = &cpi->quants;
|
||||
|
||||
#if CONFIG_DELTA_Q
|
||||
int current_q_index = cpi->oxcf.aq_mode == DELTA_AQ
|
||||
? cm->base_qindex + xd->delta_qindex
|
||||
: cm->base_qindex;
|
||||
const int qindex = av1_get_qindex(&cm->seg, segment_id, current_q_index);
|
||||
#else
|
||||
const int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
|
||||
#endif
|
||||
const int rdmult = av1_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
|
||||
int i;
|
||||
#if CONFIG_AOM_QM
|
||||
|
||||
Reference in New Issue
Block a user