From: Debargha Mukherjee Date: Thu, 29 Sep 2016 16:17:36 +0000 (-0700) Subject: Further changes to new-quant tables X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c42c0960809f84f2a9c66bb7c01cd2b95e16a1b;p=libvpx Further changes to new-quant tables Refactor to streamline the number of profiles needed, in preparation for the next steps. NO change in performance. Change-Id: I753b89299897857f3c250c316b4cdc4fedcb90e8 --- diff --git a/av1/common/blockd.h b/av1/common/blockd.h index 266f8fe62..2481de73f 100644 --- a/av1/common/blockd.h +++ b/av1/common/blockd.h @@ -387,6 +387,7 @@ typedef struct macroblockd { int bd; #endif + int qindex[MAX_SEGMENTS]; int lossless[MAX_SEGMENTS]; int corrupted; diff --git a/av1/common/entropy.h b/av1/common/entropy.h index 5418d1246..f0727c00d 100644 --- a/av1/common/entropy.h +++ b/av1/common/entropy.h @@ -131,7 +131,9 @@ extern const av1_extra_bit av1_extra_bits_high12[ENTROPY_TOKENS]; distinct bands). */ #define COEFF_CONTEXTS 6 -#define BAND_COEFF_CONTEXTS(band) ((band) == 0 ? 3 : COEFF_CONTEXTS) +#define COEFF_CONTEXTS0 3 // for band 0 +#define BAND_COEFF_CONTEXTS(band) \ + ((band) == 0 ? COEFF_CONTEXTS0 : COEFF_CONTEXTS) // #define ENTROPY_STATS diff --git a/av1/common/quant_common.c b/av1/common/quant_common.c index 536529ab6..b3228b727 100644 --- a/av1/common/quant_common.c +++ b/av1/common/quant_common.c @@ -36,93 +36,54 @@ typedef struct { uint8_t doff; // dequantization } qprofile_type; -static const qprofile_type nuq_lossless[COEF_BANDS] = { - { { 64, 128, 128 }, 0 }, // dc, band 0 - { { 64, 128, 128 }, 0 }, // band 1 - { { 64, 128, 128 }, 0 }, // band 2 - { { 64, 128, 128 }, 0 }, // band 3 - { { 64, 128, 128 }, 0 }, // band 4 - { { 64, 128, 128 }, 0 }, // band 5 -}; - -static const qprofile_type nuq[QUANT_PROFILES][QUANT_RANGES][COEF_BANDS] = { - { { - { { 64, 128, 128 }, 8 }, // dc, band 0 - { { 64, 128, 128 }, 10 }, // band 1 - { { 64, 128, 128 }, 12 }, // band 2 - { { 72, 128, 128 }, 14 }, // band 3 - { { 76, 128, 128 }, 16 }, // band 4 - { { 80, 128, 128 }, 18 } // band 5 - }, - { - { { 64, 128, 128 }, 4 }, // dc, band 0 - { { 64, 128, 128 }, 6 }, // band 1 - { { 64, 128, 128 }, 8 }, // band 2 - { { 64, 128, 128 }, 10 }, // band 3 - { { 72, 128, 128 }, 12 }, // band 4 - { { 80, 128, 128 }, 14 } // band 5 - } }, -#if QUANT_PROFILES > 1 - { { - { { 64, 128, 128 }, 6 }, // dc, band 0 - { { 64, 128, 128 }, 8 }, // band 1 - { { 64, 128, 128 }, 10 }, // band 2 - { { 64, 128, 128 }, 12 }, // band 3 - { { 72, 128, 128 }, 14 }, // band 4 - { { 80, 128, 128 }, 16 } // band 5 - }, - { - { { 64, 128, 128 }, 4 }, // dc, band 0 - { { 64, 128, 128 }, 6 }, // band 1 - { { 64, 128, 128 }, 8 }, // band 2 - { { 64, 128, 128 }, 10 }, // band 3 - { { 72, 128, 128 }, 12 }, // band 4 - { { 80, 128, 128 }, 14 } // band 5 - } }, -#if QUANT_PROFILES > 2 - { { - { { 64, 128, 128 }, 6 }, // dc, band 0 - { { 64, 128, 128 }, 8 }, // band 1 - { { 64, 128, 128 }, 10 }, // band 2 - { { 64, 128, 128 }, 12 }, // band 3 - { { 72, 128, 128 }, 14 }, // band 4 - { { 80, 128, 128 }, 16 } // band 5 - }, - { - { { 64, 128, 128 }, 4 }, // dc, band 0 - { { 64, 128, 128 }, 6 }, // band 1 - { { 64, 128, 128 }, 8 }, // band 2 - { { 64, 128, 128 }, 10 }, // band 3 - { { 72, 128, 128 }, 12 }, // band 4 - { { 80, 128, 128 }, 14 } // band 5 - } } -#endif // QUANT_PROFILES > 2 -#endif // QUANT_PROFILES > 1 +static const qprofile_type nuq[QUANT_PROFILES][COEF_BANDS] = { + { + // lossless + { { 64, 128, 128 }, 0 }, // dc, band 0 + { { 64, 128, 128 }, 0 }, // band 1 + { { 64, 128, 128 }, 0 }, // band 2 + { { 64, 128, 128 }, 0 }, // band 3 + { { 64, 128, 128 }, 0 }, // band 4 + { { 64, 128, 128 }, 0 }, // band 5 + }, + { + { { 64, 128, 128 }, 4 }, // dc, band 0 + { { 64, 128, 128 }, 6 }, // band 1 + { { 64, 128, 128 }, 8 }, // band 2 + { { 64, 128, 128 }, 10 }, // band 3 + { { 72, 128, 128 }, 12 }, // band 4 + { { 80, 128, 128 }, 14 } // band 5 + }, + { + { { 64, 128, 128 }, 6 }, // dc, band 0 + { { 64, 128, 128 }, 8 }, // band 1 + { { 64, 128, 128 }, 10 }, // band 2 + { { 64, 128, 128 }, 12 }, // band 3 + { { 72, 128, 128 }, 14 }, // band 4 + { { 80, 128, 128 }, 16 } // band 5 + }, + { + { { 64, 128, 128 }, 8 }, // dc, band 0 + { { 64, 128, 128 }, 10 }, // band 1 + { { 64, 128, 128 }, 12 }, // band 2 + { { 72, 128, 128 }, 14 }, // band 3 + { { 76, 128, 128 }, 16 }, // band 4 + { { 80, 128, 128 }, 18 } // band 5 + } }; -static INLINE int qrange_from_qindex(int qindex) { - // return high quality (1) or low quality (0) - return qindex < 140 ? 1 : 0; +static const uint8_t *get_nuq_knots(int band, int q_profile) { + return nuq[q_profile][band].knots; } -static const uint8_t *get_nuq_knots(int qindex, int band, int q_profile) { - if (!qindex) - return nuq_lossless[band].knots; - else - return nuq[q_profile][qrange_from_qindex(qindex)][band].knots; -} - -static INLINE int16_t quant_to_doff_fixed(int qindex, int band, int q_profile) { - if (!qindex) - return nuq_lossless[band].doff; - else - return nuq[q_profile][qrange_from_qindex(qindex)][band].doff; +static INLINE int16_t quant_to_doff_fixed(int band, int q_profile) { + return nuq[q_profile][band].doff; } // get cumulative bins -static INLINE void get_cuml_bins_nuq(int q, int qindex, int band, - tran_low_t *cuml_bins, int q_profile) { - const uint8_t *knots = get_nuq_knots(qindex, band, q_profile); +static INLINE void get_cuml_bins_nuq(int q, int band, tran_low_t *cuml_bins, + int q_profile) { + const uint8_t *knots = get_nuq_knots(band, q_profile); int16_t cuml_knots[NUQ_KNOTS]; int i; cuml_knots[0] = knots[0]; @@ -131,22 +92,22 @@ static INLINE void get_cuml_bins_nuq(int q, int qindex, int band, cuml_bins[i] = ROUND_POWER_OF_TWO(cuml_knots[i] * q, 7); } -void av1_get_dequant_val_nuq(int q, int qindex, int band, tran_low_t *dq, +void av1_get_dequant_val_nuq(int q, int band, tran_low_t *dq, tran_low_t *cuml_bins, int q_profile) { - const uint8_t *knots = get_nuq_knots(qindex, band, q_profile); + const uint8_t *knots = get_nuq_knots(band, q_profile); tran_low_t cuml_bins_[NUQ_KNOTS], *cuml_bins_ptr; tran_low_t doff; int i; cuml_bins_ptr = (cuml_bins ? cuml_bins : cuml_bins_); - get_cuml_bins_nuq(q, qindex, band, cuml_bins_ptr, q_profile); + get_cuml_bins_nuq(q, band, cuml_bins_ptr, q_profile); dq[0] = 0; for (i = 1; i < NUQ_KNOTS; ++i) { - doff = quant_to_doff_fixed(qindex, band, q_profile); + doff = quant_to_doff_fixed(band, q_profile); doff = ROUND_POWER_OF_TWO(doff * knots[i], 7); dq[i] = cuml_bins_ptr[i - 1] + ROUND_POWER_OF_TWO((knots[i] - doff * 2) * q, 8); } - doff = quant_to_doff_fixed(qindex, band, q_profile); + doff = quant_to_doff_fixed(band, q_profile); dq[NUQ_KNOTS] = cuml_bins_ptr[NUQ_KNOTS - 1] + ROUND_POWER_OF_TWO((64 - doff) * q, 7); } diff --git a/av1/common/quant_common.h b/av1/common/quant_common.h index b4d615bf0..43833c664 100644 --- a/av1/common/quant_common.h +++ b/av1/common/quant_common.h @@ -15,6 +15,7 @@ #include "aom/aom_codec.h" #include "av1/common/seg_common.h" #include "av1/common/enums.h" +#include "av1/common/entropy.h" #ifdef __cplusplus extern "C" { @@ -45,7 +46,7 @@ int av1_get_qindex(const struct segmentation *seg, int segment_id, #if CONFIG_AOM_QM // Reduce the large number of quantizers to a smaller number of levels for which // different matrices may be defined -static inline int aom_get_qmlevel(int qindex, int first, int last) { +static INLINE int aom_get_qmlevel(int qindex, int first, int last) { int qmlevel = (qindex * (last + 1 - first) + QINDEX_RANGE / 2) / QINDEX_RANGE; qmlevel = AOMMIN(qmlevel + first, NUM_QM_LEVELS - 1); return qmlevel; @@ -59,22 +60,41 @@ qm_val_t *aom_qmatrix(struct AV1Common *cm, int qindex, int comp, #if CONFIG_NEW_QUANT -#define QUANT_PROFILES 3 +#define QUANT_PROFILES 4 #define QUANT_RANGES 2 #define NUQ_KNOTS 3 typedef tran_low_t dequant_val_type_nuq[NUQ_KNOTS + 1]; typedef tran_low_t cuml_bins_type_nuq[NUQ_KNOTS]; -void av1_get_dequant_val_nuq(int q, int qindex, int band, tran_low_t *dq, +void av1_get_dequant_val_nuq(int q, int band, tran_low_t *dq, tran_low_t *cuml_bins, int dq_off_index); tran_low_t av1_dequant_abscoeff_nuq(int v, int q, const tran_low_t *dq); tran_low_t av1_dequant_coeff_nuq(int v, int q, const tran_low_t *dq); -static INLINE int get_dq_profile_from_ctx(int q_ctx, int is_inter, +static INLINE int qindex_to_qrange(int qindex) { + return (qindex < 140 ? 1 : 0); +} + +static INLINE int get_dq_profile_from_ctx(int qindex, int q_ctx, int is_inter, PLANE_TYPE plane_type) { - if (plane_type == PLANE_TYPE_UV) return 0; - if (!is_inter) return QUANT_PROFILES - 1; - return AOMMIN(q_ctx, QUANT_PROFILES - 1); + // intra/inter, Y/UV, ctx, qrange + static const int + def_dq_profile_lookup[REF_TYPES][PLANE_TYPES][COEFF_CONTEXTS0] + [QUANT_RANGES] = { + { + // intra + { { 2, 1 }, { 2, 1 }, { 2, 1 } }, // Y + { { 3, 1 }, { 3, 1 }, { 3, 1 } }, // UV + }, + { + // inter + { { 3, 1 }, { 2, 1 }, { 2, 1 } }, // Y + { { 3, 1 }, { 3, 1 }, { 3, 1 } }, // UV + }, + }; + if (!qindex) return 0; // lossless + return def_dq_profile_lookup[is_inter][plane_type][q_ctx] + [qindex_to_qrange(qindex)]; } #endif // CONFIG_NEW_QUANT diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index d54035e93..cc5d64063 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -2124,9 +2124,9 @@ static void setup_segmentation_dequant(AV1_COMMON *const cm) { #if CONFIG_NEW_QUANT for (dq = 0; dq < QUANT_PROFILES; dq++) { for (b = 0; b < COEF_BANDS; ++b) { - av1_get_dequant_val_nuq(cm->y_dequant[i][b != 0], qindex, b, + av1_get_dequant_val_nuq(cm->y_dequant[i][b != 0], b, cm->y_dequant_nuq[i][dq][b], NULL, dq); - av1_get_dequant_val_nuq(cm->uv_dequant[i][b != 0], qindex, b, + av1_get_dequant_val_nuq(cm->uv_dequant[i][b != 0], b, cm->uv_dequant_nuq[i][dq][b], NULL, dq); } } @@ -2159,9 +2159,9 @@ static void setup_segmentation_dequant(AV1_COMMON *const cm) { #if CONFIG_NEW_QUANT for (dq = 0; dq < QUANT_PROFILES; dq++) { for (b = 0; b < COEF_BANDS; ++b) { - av1_get_dequant_val_nuq(cm->y_dequant[0][b != 0], qindex, b, + av1_get_dequant_val_nuq(cm->y_dequant[0][b != 0], b, cm->y_dequant_nuq[0][dq][b], NULL, dq); - av1_get_dequant_val_nuq(cm->uv_dequant[0][b != 0], qindex, b, + av1_get_dequant_val_nuq(cm->uv_dequant[0][b != 0], b, cm->uv_dequant_nuq[0][dq][b], NULL, dq); } } @@ -3374,6 +3374,7 @@ static size_t read_uncompressed_header(AV1Decoder *pbi, : cm->base_qindex; xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; + xd->qindex[i] = qindex; } } diff --git a/av1/decoder/detokenize.c b/av1/decoder/detokenize.c index 1a0643311..b83ab3d53 100644 --- a/av1/decoder/detokenize.c +++ b/av1/decoder/detokenize.c @@ -506,7 +506,8 @@ int av1_decode_block_tokens(MACROBLOCKD *const xd, int plane, get_entropy_context(tx_size, pd->above_context + x, pd->left_context + y); #if CONFIG_NEW_QUANT const int ref = is_inter_block(&xd->mi[0]->mbmi); - int dq = get_dq_profile_from_ctx(ctx, ref, pd->plane_type); + int dq = + get_dq_profile_from_ctx(xd->qindex[seg_id], ctx, ref, pd->plane_type); #endif // CONFIG_NEW_QUANT #if !CONFIG_ANS diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 12ef33d3d..6cf25fb5c 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c @@ -844,6 +844,7 @@ static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td, if (cyclic_refresh_segment_id_boosted(segment_id)) { int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex); + assert(q == xd->qindex[segment_id]); set_vbp_thresholds(cpi, thresholds, q); } } @@ -1597,6 +1598,7 @@ static int set_segment_rdmult(AV1_COMP *const cpi, MACROBLOCK *const x, av1_init_plane_quantizers(cpi, x, segment_id); aom_clear_system_state(); segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex); + assert(segment_qindex == x->e_mbd.qindex[segment_id]); return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q); } @@ -4594,6 +4596,7 @@ static void encode_frame_internal(AV1_COMP *cpi) { : cm->base_qindex; xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; + xd->qindex[i] = qindex; } if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0; @@ -5126,7 +5129,7 @@ static void encode_superblock(AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, av1_tokenize_sb(cpi, td, t, !output_enabled, AOMMAX(bsize, BLOCK_8X8)); else #endif - av1_tokenize_sb_inter(cpi, td, t, !output_enabled, mi_row, mi_col, + av1_tokenize_sb_vartx(cpi, td, t, !output_enabled, mi_row, mi_col, AOMMAX(bsize, BLOCK_8X8)); #else av1_tokenize_sb(cpi, td, t, !output_enabled, AOMMAX(bsize, BLOCK_8X8)); diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c index cf371407f..c5dfadd25 100644 --- a/av1/encoder/encodemb.c +++ b/av1/encoder/encodemb.c @@ -80,29 +80,29 @@ int av1_optimize_b(MACROBLOCK *mb, int plane, int block, TX_SIZE tx_size, tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); const int eob = p->eobs[block]; - const PLANE_TYPE type = pd->plane_type; + const PLANE_TYPE plane_type = pd->plane_type; const int default_eob = get_tx2d_size(tx_size); const int16_t *const dequant_ptr = pd->dequant; const uint8_t *const band_translate = get_band_translate(tx_size); - TX_TYPE tx_type = get_tx_type(type, xd, block, tx_size); + TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size); const scan_order *const so = get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi)); const int16_t *const scan = so->scan; const int16_t *const nb = so->neighbors; #if CONFIG_AOM_QM int seg_id = xd->mi[0]->mbmi.segment_id; - int is_intra = !is_inter_block(&xd->mi[0]->mbmi); - const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][is_intra][tx_size]; + const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size]; #endif const int shift = get_tx_scale(xd, tx_type, tx_size); #if CONFIG_NEW_QUANT - int dq = get_dq_profile_from_ctx(ctx, ref, type); + int dq = get_dq_profile_from_ctx(xd->qindex[xd->mi[0]->mbmi.segment_id], ctx, + ref, plane_type); const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq]; #else const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift }; #endif // CONFIG_NEW_QUANT int next = eob, sz = 0; - const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][type]) >> 1; + const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1; const int64_t rddiv = mb->rddiv; int64_t rd_cost0, rd_cost1; int rate0, rate1; @@ -117,15 +117,18 @@ int av1_optimize_b(MACROBLOCK *mb, int plane, int block, TX_SIZE tx_size, const int *cat6_high_cost = av1_get_high_cost_table(8); #endif unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] = - mb->token_costs[txsize_sqr_map[tx_size]][type][ref]; + mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref]; const uint16_t *band_counts = &band_count_table[tx_size][band]; uint16_t band_left = eob - band_cum_count_table[tx_size][band] + 1; int shortcut = 0; int next_shortcut = 0; + assert((xd->qindex[xd->mi[0]->mbmi.segment_id] == 0) ^ + (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)); + token_costs += band; - assert((!type && !plane) || (type && plane)); + assert((!plane_type && !plane) || (plane_type && plane)); assert(eob <= default_eob); /* Now set up a Viterbi trellis to evaluate alternative roundings. */ @@ -443,8 +446,8 @@ void av1_xform_quant(MACROBLOCK *x, int plane, int block, int blk_row, const struct macroblockd_plane *const pd = &xd->plane[plane]; PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV; TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size); - const scan_order *const scan_order = - get_scan(tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi)); + const int is_inter = is_inter_block(&xd->mi[0]->mbmi); + const scan_order *const scan_order = get_scan(tx_size, tx_type, is_inter); tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); @@ -452,9 +455,8 @@ void av1_xform_quant(MACROBLOCK *x, int plane, int block, int blk_row, const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; #if CONFIG_AOM_QM int seg_id = xd->mi[0]->mbmi.segment_id; - int is_intra = !is_inter_block(&xd->mi[0]->mbmi); - const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][is_intra][tx_size]; - const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][is_intra][tx_size]; + const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][!is_inter][tx_size]; + const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!is_inter][tx_size]; #endif const int16_t *src_diff; const int tx2d_size = get_tx2d_size(tx_size); @@ -522,7 +524,8 @@ void av1_xform_quant_nuq(MACROBLOCK *x, int plane, int block, int blk_row, tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); - int dq = get_dq_profile_from_ctx(ctx, is_inter, plane_type); + int dq = get_dq_profile_from_ctx(xd->qindex[xd->mi[0]->mbmi.segment_id], ctx, + is_inter, plane_type); uint16_t *const eob = &p->eobs[block]; const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; const int16_t *src_diff; @@ -530,6 +533,9 @@ void av1_xform_quant_nuq(MACROBLOCK *x, int plane, int block, int blk_row, FWD_TXFM_PARAM fwd_txfm_param; + assert((xd->qindex[xd->mi[0]->mbmi.segment_id] == 0) ^ + (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)); + fwd_txfm_param.tx_type = tx_type; fwd_txfm_param.tx_size = tx_size; fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_FP]; @@ -588,7 +594,8 @@ void av1_xform_quant_fp_nuq(MACROBLOCK *x, int plane, int block, int blk_row, PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV; TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size); const scan_order *const scan_order = get_scan(tx_size, tx_type, is_inter); - int dq = get_dq_profile_from_ctx(ctx, is_inter, plane_type); + int dq = get_dq_profile_from_ctx(xd->qindex[xd->mi[0]->mbmi.segment_id], ctx, + is_inter, plane_type); tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block); tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block); tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block); @@ -599,6 +606,9 @@ void av1_xform_quant_fp_nuq(MACROBLOCK *x, int plane, int block, int blk_row, FWD_TXFM_PARAM fwd_txfm_param; + assert((xd->qindex[xd->mi[0]->mbmi.segment_id] == 0) ^ + (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)); + fwd_txfm_param.tx_type = tx_type; fwd_txfm_param.tx_size = tx_size; fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_FP]; @@ -661,10 +671,14 @@ void av1_xform_quant_dc_nuq(MACROBLOCK *x, int plane, int block, int blk_row, const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; const int16_t *src_diff; const int is_inter = is_inter_block(&xd->mi[0]->mbmi); - int dq = get_dq_profile_from_ctx(ctx, is_inter, plane_type); + int dq = get_dq_profile_from_ctx(xd->qindex[xd->mi[0]->mbmi.segment_id], ctx, + is_inter, plane_type); FWD_TXFM_PARAM fwd_txfm_param; + assert((xd->qindex[xd->mi[0]->mbmi.segment_id] == 0) ^ + (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)); + fwd_txfm_param.tx_type = tx_type; fwd_txfm_param.tx_size = tx_size; fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_DC]; @@ -722,10 +736,14 @@ void av1_xform_quant_dc_fp_nuq(MACROBLOCK *x, int plane, int block, int blk_row, const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; const int16_t *src_diff; const int is_inter = is_inter_block(&xd->mi[0]->mbmi); - int dq = get_dq_profile_from_ctx(ctx, is_inter, plane_type); + int dq = get_dq_profile_from_ctx(xd->qindex[xd->mi[0]->mbmi.segment_id], ctx, + is_inter, plane_type); FWD_TXFM_PARAM fwd_txfm_param; + assert((xd->qindex[xd->mi[0]->mbmi.segment_id] == 0) ^ + (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)); + fwd_txfm_param.tx_type = tx_type; fwd_txfm_param.tx_size = tx_size; fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_DC]; diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c index c474e3f7b..5821d3fb4 100644 --- a/av1/encoder/firstpass.c +++ b/av1/encoder/firstpass.c @@ -492,6 +492,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { double intra_factor; double brightness_factor; BufferPool *const pool = cm->buffer_pool; + const int qindex = find_fp_qindex(cm->bit_depth); // First pass code requires valid last and new frame buffers. assert(new_yv12 != NULL); @@ -510,7 +511,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { neutral_count = 0.0; set_first_pass_params(cpi); - av1_set_quantizer(cm, find_fp_qindex(cm->bit_depth)); + av1_set_quantizer(cm, qindex); av1_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); @@ -584,6 +585,8 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) { #if CONFIG_SUPERTX xd->mi[0]->mbmi.segment_id_supertx = 0; #endif // CONFIG_SUPERTX + xd->qindex[xd->mi[0]->mbmi.segment_id] = qindex; + xd->lossless[xd->mi[0]->mbmi.segment_id] = (qindex == 0); xd->mi[0]->mbmi.mode = DC_PRED; xd->mi[0]->mbmi.tx_size = use_dc_pred ? (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4; diff --git a/av1/encoder/quantize.c b/av1/encoder/quantize.c index 73946c2e9..d3b8c1cb3 100644 --- a/av1/encoder/quantize.c +++ b/av1/encoder/quantize.c @@ -1117,10 +1117,9 @@ void av1_init_quantizer(AV1_COMP *cpi) { for (i = 0; i < COEF_BANDS; i++) { const int quant = cpi->y_dequant[q][i != 0]; const int uvquant = cpi->uv_dequant[q][i != 0]; - av1_get_dequant_val_nuq(quant, q, i, cpi->y_dequant_val_nuq[dq][q][i], + av1_get_dequant_val_nuq(quant, i, cpi->y_dequant_val_nuq[dq][q][i], quants->y_cuml_bins_nuq[dq][q][i], dq); - av1_get_dequant_val_nuq(uvquant, q, i, - cpi->uv_dequant_val_nuq[dq][q][i], + av1_get_dequant_val_nuq(uvquant, i, cpi->uv_dequant_val_nuq[dq][q][i], quants->uv_cuml_bins_nuq[dq][q][i], dq); } } diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c index 86c659bf4..3bf24101a 100644 --- a/av1/encoder/tokenize.c +++ b/av1/encoder/tokenize.c @@ -560,9 +560,9 @@ int av1_has_high_freq_in_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { } #if CONFIG_VAR_TX -void tokenize_tx(ThreadData *td, TOKENEXTRA **t, int dry_run, TX_SIZE tx_size, - BLOCK_SIZE plane_bsize, int blk_row, int blk_col, int block, - int plane, void *arg) { +void tokenize_vartx(ThreadData *td, TOKENEXTRA **t, int dry_run, + TX_SIZE tx_size, BLOCK_SIZE plane_bsize, int blk_row, + int blk_col, int block, int plane, void *arg) { MACROBLOCK *const x = &td->mb; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; @@ -610,13 +610,13 @@ void tokenize_tx(ThreadData *td, TOKENEXTRA **t, int dry_run, TX_SIZE tx_size, if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue; - tokenize_tx(td, t, dry_run, tx_size - 1, plane_bsize, offsetr, offsetc, - block + i * step, plane, arg); + tokenize_vartx(td, t, dry_run, tx_size - 1, plane_bsize, offsetr, offsetc, + block + i * step, plane, arg); } } } -void av1_tokenize_sb_inter(AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, +void av1_tokenize_sb_vartx(AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, int dry_run, int mi_row, int mi_col, BLOCK_SIZE bsize) { AV1_COMMON *const cm = &cpi->common; @@ -656,8 +656,8 @@ void av1_tokenize_sb_inter(AV1_COMP *cpi, ThreadData *td, TOKENEXTRA **t, int step = num_4x4_blocks_txsize_lookup[max_tx_size]; for (idy = 0; idy < mi_height; idy += bh) { for (idx = 0; idx < mi_width; idx += bh) { - tokenize_tx(td, t, dry_run, max_tx_size, plane_bsize, idy, idx, block, - plane, &arg); + tokenize_vartx(td, t, dry_run, max_tx_size, plane_bsize, idy, idx, + block, plane, &arg); block += step; } } diff --git a/av1/encoder/tokenize.h b/av1/encoder/tokenize.h index 37f2309a9..a7e30d545 100644 --- a/av1/encoder/tokenize.h +++ b/av1/encoder/tokenize.h @@ -57,7 +57,7 @@ struct AV1_COMP; struct ThreadData; #if CONFIG_VAR_TX -void av1_tokenize_sb_inter(struct AV1_COMP *cpi, struct ThreadData *td, +void av1_tokenize_sb_vartx(struct AV1_COMP *cpi, struct ThreadData *td, TOKENEXTRA **t, int dry_run, int mi_row, int mi_col, BLOCK_SIZE bsize); #endif