From 7169441aa280d29e0393911d0f085c394fbbca16 Mon Sep 17 00:00:00 2001 From: Boyuan Xiao Date: Fri, 26 Oct 2018 11:27:31 +0100 Subject: [PATCH] Use transform DCT_DCT if block quantizer is zero To figure out the block quantizer, add the frame-level quantizer to any delta from the current segment. If this is zero, we should use DCT_DCT rather than reading the transform type from the bitstream. See section 5.11.47 of the spec. --- src/recon_tmpl.c | 52 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/recon_tmpl.c b/src/recon_tmpl.c index 31b687a..8942d08 100644 --- a/src/recon_tmpl.c +++ b/src/recon_tmpl.c @@ -46,6 +46,26 @@ #include "src/tables.h" #include "src/wedge.h" +// This matches the get_qindex function in section 7.12.2 of the spec +// (with ignoreDeltaQ = 1). It returns the quantizer index of the +// current block, ignoring how ts->last_qidx differs from the +// frame-level Q. +static uint8_t get_qindex(const Dav1dFrameContext *const f, + int seg_id) +{ + // When for finding the quantizer for a block with ignoreDeltaQ + // set, you look up frame's base quantizer level (quant.yac) and + // then add any delta for the current segment. + // + // The segment delta is stored in seg_data.d[seg_id].delta_q. In + // general, this segment might not have a delta_q but in this + // case, the code in parse_frame_hdr sets it to zero (so adding it + // on has no effect). + + return iclip_u8 (f->frame_hdr.quant.yac + + f->frame_hdr.segmentation.seg_data.d[seg_id].delta_q); +} + static unsigned read_golomb(MsacContext *const msac) { int len = 0; unsigned val = 1; @@ -100,20 +120,28 @@ static int decode_coefs(Dav1dTileContext *const t, unsigned idx; if (set_cnt == 1) { idx = 0; + *txtp = dav1d_tx_types_per_set[set][idx]; } else { - const int set_idx = dav1d_tx_type_set_index[!intra][set]; - const enum IntraPredMode y_mode_nofilt = intra ? b->y_mode == FILTER_PRED ? - dav1d_filter_mode_to_y_mode[b->y_angle] : b->y_mode : 0; - uint16_t *const txtp_cdf = intra ? - ts->cdf.m.txtp_intra[set_idx][t_dim->min][y_mode_nofilt] : - ts->cdf.m.txtp_inter[set_idx][t_dim->min]; - idx = msac_decode_symbol_adapt(&ts->msac, txtp_cdf, set_cnt); - if (dbg) - printf("Post-txtp[%d->%d][%d->%d][%d][%d->%d]: r=%d\n", - set, set_idx, tx, t_dim->min, intra ? (int)y_mode_nofilt : -1, - idx, dav1d_tx_types_per_set[set][idx], ts->msac.rng); + const int quant = (f->frame_hdr.segmentation.enabled ? + get_qindex(f, b->seg_id) : + f->frame_hdr.quant.yac); + if (quant == 0) { + *txtp = DCT_DCT; + } else { + const int set_idx = dav1d_tx_type_set_index[!intra][set]; + const enum IntraPredMode y_mode_nofilt = intra ? b->y_mode == FILTER_PRED ? + dav1d_filter_mode_to_y_mode[b->y_angle] : b->y_mode : 0; + uint16_t *const txtp_cdf = intra ? + ts->cdf.m.txtp_intra[set_idx][t_dim->min][y_mode_nofilt] : + ts->cdf.m.txtp_inter[set_idx][t_dim->min]; + idx = msac_decode_symbol_adapt(&ts->msac, txtp_cdf, set_cnt); + if (dbg) + printf("Post-txtp[%d->%d][%d->%d][%d][%d->%d]: r=%d\n", + set, set_idx, tx, t_dim->min, intra ? (int)y_mode_nofilt : -1, + idx, dav1d_tx_types_per_set[set][idx], ts->msac.rng); + *txtp = dav1d_tx_types_per_set[set][idx]; + } } - *txtp = dav1d_tx_types_per_set[set][idx]; } // find end-of-block (eob) -- 2.19.1