Support for delta-q at superblock level
Change-Id: I4128af44776d1f361bddc1fdffb75ed2224dbfa5
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index b7cbc00..fe6ffe7 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -488,6 +488,22 @@
}
}
+#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 @@
#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 @@
#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 @@
}
}
+#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 @@
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 @@
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 @@
#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