blob: 2292ec6639d154e8b9c418512594cc19b2c1b813 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <math.h>
Yaowu Xuf883b422016-08-30 14:01:10 -070013#include "./aom_dsp_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070014#include "aom_dsp/quantize.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070016#include "aom_ports/mem.h"
17
Yi Luo554bd722016-11-14 10:02:26 -080018#include "av1/common/idct.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "av1/common/quant_common.h"
20#include "av1/common/scan.h"
21#include "av1/common/seg_common.h"
22
Tom Finegan17ce8b12017-02-08 12:46:31 -080023#include "av1/encoder/av1_quantize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070024#include "av1/encoder/encoder.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070025#include "av1/encoder/rd.h"
26
Yaowu Xuf883b422016-08-30 14:01:10 -070027void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr,
28 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070029 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
30 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
31 *eob_ptr = 0;
32}
33
Cheng Chen4c2e4342017-04-20 18:10:08 -070034static void quantize_fp_helper_c(
35 const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
36 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
37 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
38 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010039 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
40 const qm_val_t *iqm_ptr, int log_scale) {
Cheng Chen4c2e4342017-04-20 18:10:08 -070041 int i, eob = -1;
42 // TODO(jingning) Decide the need of these arguments after the
43 // quantization process is completed.
44 (void)zbin_ptr;
45 (void)quant_shift_ptr;
46 (void)iscan;
Cheng Chen4c2e4342017-04-20 18:10:08 -070047
48 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
49 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
50
51 if (!skip_block) {
52 // Quantization pass: All coefficients with index >= zero_flag are
53 // skippable. Note: zero_flag can be zero.
54 for (i = 0; i < n_coeffs; i++) {
55 const int rc = scan[i];
56 const int coeff = coeff_ptr[rc];
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010057 const qm_val_t wt = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS);
58 const qm_val_t iwt = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
Cheng Chen4c2e4342017-04-20 18:10:08 -070059 const int dequant =
60 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
61 AOM_QM_BITS;
Cheng Chen4c2e4342017-04-20 18:10:08 -070062 const int coeff_sign = (coeff >> 31);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010063 int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
Cheng Chen4c2e4342017-04-20 18:10:08 -070064 int tmp32 = 0;
Cheng Chen4c2e4342017-04-20 18:10:08 -070065 if (abs_coeff * wt >=
66 (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
Cheng Chen4c2e4342017-04-20 18:10:08 -070067 abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010068 abs_coeff = clamp64(abs_coeff, INT16_MIN, INT16_MAX);
Cheng Chen4c2e4342017-04-20 18:10:08 -070069 tmp32 = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >>
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010070 (16 - log_scale + AOM_QM_BITS));
Cheng Chen4c2e4342017-04-20 18:10:08 -070071 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
72 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / (1 << log_scale);
Cheng Chen4c2e4342017-04-20 18:10:08 -070073 }
74
75 if (tmp32) eob = i;
76 }
77 }
78 *eob_ptr = eob + 1;
79}
80
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010081static void highbd_quantize_fp_helper_c(
82 const tran_low_t *coeff_ptr, intptr_t count, int skip_block,
83 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
84 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
85 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
86 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
87 const qm_val_t *iqm_ptr, int log_scale) {
88 int i;
89 int eob = -1;
90 const int scale = 1 << log_scale;
91 const int shift = 16 - log_scale;
92 // TODO(jingning) Decide the need of these arguments after the
93 // quantization process is completed.
94 (void)zbin_ptr;
95 (void)quant_shift_ptr;
96 (void)iscan;
97
98 memset(qcoeff_ptr, 0, count * sizeof(*qcoeff_ptr));
99 memset(dqcoeff_ptr, 0, count * sizeof(*dqcoeff_ptr));
100
101 if (!skip_block) {
102 // Quantization pass: All coefficients with index >= zero_flag are
103 // skippable. Note: zero_flag can be zero.
104 for (i = 0; i < count; i++) {
105 const int rc = scan[i];
106 const int coeff = coeff_ptr[rc];
107 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
108 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
109 const int dequant =
110 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
111 AOM_QM_BITS;
112 const int coeff_sign = (coeff >> 31);
113 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
114 const int64_t tmp = abs_coeff + (round_ptr[rc != 0] >> log_scale);
115 const int abs_qcoeff =
116 (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
117 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
118 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / scale;
119 if (abs_qcoeff) eob = i;
120 }
121 }
122 *eob_ptr = eob + 1;
123}
124
Cheng Chen4c2e4342017-04-20 18:10:08 -0700125void av1_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
126 int skip_block, const int16_t *zbin_ptr,
127 const int16_t *round_ptr, const int16_t *quant_ptr,
128 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
129 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
130 uint16_t *eob_ptr, const int16_t *scan,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100131 const int16_t *iscan) {
Cheng Chen4c2e4342017-04-20 18:10:08 -0700132 quantize_fp_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
133 quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100134 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 0);
Cheng Chen4c2e4342017-04-20 18:10:08 -0700135}
136
137void av1_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
138 int skip_block, const int16_t *zbin_ptr,
139 const int16_t *round_ptr, const int16_t *quant_ptr,
140 const int16_t *quant_shift_ptr,
141 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
142 const int16_t *dequant_ptr, uint16_t *eob_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100143 const int16_t *scan, const int16_t *iscan) {
Cheng Chen4c2e4342017-04-20 18:10:08 -0700144 quantize_fp_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
145 quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100146 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 1);
Cheng Chen4c2e4342017-04-20 18:10:08 -0700147}
148
Cheng Chen4c2e4342017-04-20 18:10:08 -0700149void av1_quantize_fp_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
150 int skip_block, const int16_t *zbin_ptr,
151 const int16_t *round_ptr, const int16_t *quant_ptr,
152 const int16_t *quant_shift_ptr,
153 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
154 const int16_t *dequant_ptr, uint16_t *eob_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100155 const int16_t *scan, const int16_t *iscan) {
Cheng Chen4c2e4342017-04-20 18:10:08 -0700156 quantize_fp_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
157 quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100158 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 2);
Cheng Chen4c2e4342017-04-20 18:10:08 -0700159}
Cheng Chen4c2e4342017-04-20 18:10:08 -0700160
Yaowu Xuf883b422016-08-30 14:01:10 -0700161void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700162 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700163 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800164 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700165 // obsolete skip_block
166 const int skip_block = 0;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800167 const qm_val_t *qm_ptr = qparam->qmatrix;
168 const qm_val_t *iqm_ptr = qparam->iqmatrix;
Thomas Davies18703822017-07-21 14:39:33 +0100169 if (qm_ptr != NULL && iqm_ptr != NULL) {
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400170 quantize_fp_helper_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
171 p->round_fp_QTX, p->quant_fp_QTX, p->quant_shift_QTX,
172 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
173 sc->scan, sc->iscan, qm_ptr, iqm_ptr,
174 qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100175 } else {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100176 switch (qparam->log_scale) {
177 case 0:
178 if (n_coeffs < 16) {
179 // TODO(jingning): Need SIMD implementation for smaller block size
180 // quantization.
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400181 quantize_fp_helper_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
182 p->round_fp_QTX, p->quant_fp_QTX,
183 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
184 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan,
185 NULL, NULL, qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100186 } else {
Debargha Mukherjee24e31042017-11-29 20:21:15 -0800187 if (qparam->tx_size == TX_4X16 || qparam->tx_size == TX_16X4 ||
188 qparam->tx_size == TX_8X32 || qparam->tx_size == TX_32X8)
189 av1_quantize_fp_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
190 p->round_fp_QTX, p->quant_fp_QTX,
191 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
192 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
193 else
Debargha Mukherjee24e31042017-11-29 20:21:15 -0800194 av1_quantize_fp(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
195 p->round_fp_QTX, p->quant_fp_QTX,
196 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
197 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100198 }
199 break;
200 case 1:
Debargha Mukherjee3f921082017-12-01 21:45:57 -0800201 if (qparam->tx_size == TX_16X64 || qparam->tx_size == TX_64X16)
202 av1_quantize_fp_32x32_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
203 p->round_fp_QTX, p->quant_fp_QTX,
204 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
205 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
206 else
Debargha Mukherjee3f921082017-12-01 21:45:57 -0800207 av1_quantize_fp_32x32(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
208 p->round_fp_QTX, p->quant_fp_QTX,
209 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
210 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100211 break;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100212 case 2:
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400213 av1_quantize_fp_64x64(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
214 p->round_fp_QTX, p->quant_fp_QTX,
215 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
216 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100217 break;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100218 default: assert(0);
219 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700220 }
221}
222
223void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
224 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400225 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
226 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700227 // obsolete skip_block
228 const int skip_block = 0;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800229 const qm_val_t *qm_ptr = qparam->qmatrix;
230 const qm_val_t *iqm_ptr = qparam->iqmatrix;
Thomas Davies18703822017-07-21 14:39:33 +0100231 if (qm_ptr != NULL && iqm_ptr != NULL) {
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400232 quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
233 p->round_QTX, p->quant_QTX, p->quant_shift_QTX,
234 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
235 sc->scan, sc->iscan, qm_ptr, iqm_ptr,
236 qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100237 } else {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100238 switch (qparam->log_scale) {
239 case 0:
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400240 aom_quantize_b(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
241 p->round_QTX, p->quant_QTX, p->quant_shift_QTX,
242 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
243 sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100244 break;
245 case 1:
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400246 aom_quantize_b_32x32(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
247 p->round_QTX, p->quant_QTX, p->quant_shift_QTX,
248 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
249 sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100250 break;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100251 case 2:
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400252 aom_quantize_b_64x64(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
253 p->round_QTX, p->quant_QTX, p->quant_shift_QTX,
254 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
255 sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100256 break;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100257 default: assert(0);
258 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700259 }
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100260}
261
262static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
263 int skip_block, const int16_t *round_ptr,
264 const int16_t quant, tran_low_t *qcoeff_ptr,
265 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
266 uint16_t *eob_ptr, const qm_val_t *qm_ptr,
267 const qm_val_t *iqm_ptr, const int log_scale) {
268 const int rc = 0;
269 const int coeff = coeff_ptr[rc];
270 const int coeff_sign = (coeff >> 31);
271 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
Sarah Parkeraf210e42017-09-08 14:19:04 -0700272 int64_t tmp;
273 int eob = -1;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100274 int32_t tmp32;
275 int dequant;
276
277 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
278 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
279
280 if (!skip_block) {
281 const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
282 const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
283 tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
284 INT16_MIN, INT16_MAX);
285 tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS));
286 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
287 dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
288 dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / (1 << log_scale);
289 if (tmp32) eob = 0;
290 }
291 *eob_ptr = eob + 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700292}
293
Yaowu Xuf883b422016-08-30 14:01:10 -0700294void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
295 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
Yaowu Xuf883b422016-08-30 14:01:10 -0700296 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800297 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700298 // obsolete skip_block
299 const int skip_block = 0;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100300 (void)sc;
Yaowu Xud3d41592018-02-14 13:26:52 -0800301 assert(qparam->log_scale >= 0 && qparam->log_scale < (3));
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800302 const qm_val_t *qm_ptr = qparam->qmatrix;
303 const qm_val_t *iqm_ptr = qparam->iqmatrix;
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400304 quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
305 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0],
306 eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700307}
308
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800309void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
310 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
311 tran_low_t *qcoeff_ptr,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800312 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
313 const SCAN_ORDER *sc,
314 const QUANT_PARAM *qparam) {
315 // obsolete skip_block
316 const int skip_block = 0;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800317 const qm_val_t *qm_ptr = qparam->qmatrix;
318 const qm_val_t *iqm_ptr = qparam->iqmatrix;
Thomas Davies18703822017-07-21 14:39:33 +0100319 if (qm_ptr != NULL && iqm_ptr != NULL) {
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400320 highbd_quantize_fp_helper_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
321 p->round_fp_QTX, p->quant_fp_QTX,
322 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
323 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan,
324 qm_ptr, iqm_ptr, qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100325 } else {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100326 if (n_coeffs < 16) {
327 // TODO(jingning): Need SIMD implementation for smaller block size
328 // quantization.
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400329 av1_highbd_quantize_fp_c(
330 coeff_ptr, n_coeffs, skip_block, p->zbin_QTX, p->round_fp_QTX,
331 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
332 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan, qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100333 return;
334 }
Jingning Handaf03ee2017-03-08 08:52:30 -0800335
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400336 av1_highbd_quantize_fp(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
337 p->round_fp_QTX, p->quant_fp_QTX, p->quant_shift_QTX,
338 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
339 sc->scan, sc->iscan, qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100340 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700341}
342
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800343void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
344 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
345 tran_low_t *qcoeff_ptr,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800346 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
347 const SCAN_ORDER *sc,
348 const QUANT_PARAM *qparam) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700349 // obsolete skip_block
350 const int skip_block = 0;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800351 const qm_val_t *qm_ptr = qparam->qmatrix;
352 const qm_val_t *iqm_ptr = qparam->iqmatrix;
Thomas Davies18703822017-07-21 14:39:33 +0100353 if (qm_ptr != NULL && iqm_ptr != NULL) {
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400354 highbd_quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
355 p->round_QTX, p->quant_QTX, p->quant_shift_QTX,
356 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
357 sc->scan, sc->iscan, qm_ptr, iqm_ptr,
358 qparam->log_scale);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100359 } else {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100360 switch (qparam->log_scale) {
361 case 0:
362 if (LIKELY(n_coeffs >= 8)) {
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400363 aom_highbd_quantize_b(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
364 p->round_QTX, p->quant_QTX, p->quant_shift_QTX,
365 qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
366 eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100367 } else {
368 // TODO(luoyi): Need SIMD (e.g. sse2) for smaller block size
369 // quantization
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400370 aom_highbd_quantize_b_c(coeff_ptr, n_coeffs, skip_block, p->zbin_QTX,
371 p->round_QTX, p->quant_QTX,
372 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
373 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100374 }
375 break;
376 case 1:
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400377 aom_highbd_quantize_b_32x32(
378 coeff_ptr, n_coeffs, skip_block, p->zbin_QTX, p->round_QTX,
379 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
380 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100381 break;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100382 case 2:
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400383 aom_highbd_quantize_b_64x64(
384 coeff_ptr, n_coeffs, skip_block, p->zbin_QTX, p->round_QTX,
385 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
386 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100387 break;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100388 default: assert(0);
389 }
Cheng Chen9b180372017-04-24 16:21:25 -0700390 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700391}
392
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800393static INLINE void highbd_quantize_dc(
394 const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
395 const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr,
396 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100397 const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) {
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800398 int eob = -1;
399
400 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
401 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100402
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800403 if (!skip_block) {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100404 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS);
405 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS);
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800406 const int coeff = coeff_ptr[0];
407 const int coeff_sign = (coeff >> 31);
408 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100409 const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale);
410 const int64_t tmpw = tmp * wt;
411 const int abs_qcoeff =
412 (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS));
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800413 qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100414 const int dequant =
415 (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
416
417 dqcoeff_ptr[0] = (qcoeff_ptr[0] * dequant) / (1 << log_scale);
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800418 if (abs_qcoeff) eob = 0;
419 }
420 *eob_ptr = eob + 1;
421}
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800422
423void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
424 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
425 tran_low_t *qcoeff_ptr,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800426 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
427 const SCAN_ORDER *sc,
428 const QUANT_PARAM *qparam) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700429 // obsolete skip_block
430 const int skip_block = 0;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800431 const qm_val_t *qm_ptr = qparam->qmatrix;
432 const qm_val_t *iqm_ptr = qparam->iqmatrix;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700433 (void)sc;
434
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400435 highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
436 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr,
437 p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr,
438 qparam->log_scale);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700439}
440
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100441void av1_highbd_quantize_fp_c(
442 const tran_low_t *coeff_ptr, intptr_t count, int skip_block,
443 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
444 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
445 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
446 const int16_t *scan, const int16_t *iscan, int log_scale) {
447 highbd_quantize_fp_helper_c(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
448 quant_ptr, quant_shift_ptr, qcoeff_ptr,
449 dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan,
450 NULL, NULL, log_scale);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700451}
452
Yaowu Xuc27fc142016-08-22 16:08:15 -0700453static void invert_quant(int16_t *quant, int16_t *shift, int d) {
Yaowu Xuaf048632016-05-18 17:35:34 -0700454 uint32_t t;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700455 int l, m;
456 t = d;
457 for (l = 0; t > 1; l++) t >>= 1;
458 m = 1 + (1 << (16 + l)) / d;
459 *quant = (int16_t)(m - (1 << 16));
460 *shift = 1 << (16 - l);
461}
462
Yaowu Xuf883b422016-08-30 14:01:10 -0700463static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) {
Monty Montgomery60f2a222017-11-01 19:48:38 -0400464 const int quant = av1_dc_quant_Q3(q, 0, bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700465 switch (bit_depth) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700466 case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
467 case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
468 case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700469 default:
Yaowu Xuf883b422016-08-30 14:01:10 -0700470 assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700471 return -1;
472 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700473}
474
Yi Luoc6210232017-05-25 15:09:25 -0700475void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
Yaowu Xube42dc72017-11-08 17:38:24 -0800476 int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
477 int v_ac_delta_q, QUANTS *const quants,
478 Dequants *const deq) {
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400479 int i, q, quant_Q3, quant_QTX;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700480
481 for (q = 0; q < QINDEX_RANGE; q++) {
Yi Luoc6210232017-05-25 15:09:25 -0700482 const int qzbin_factor = get_qzbin_factor(q, bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483 const int qrounding_factor = q == 0 ? 64 : 48;
484
485 for (i = 0; i < 2; ++i) {
486 int qrounding_factor_fp = 64;
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400487 // y quantizer setup with original coeff shift of Q3
Monty Montgomery60f2a222017-11-01 19:48:38 -0400488 quant_Q3 = i == 0 ? av1_dc_quant_Q3(q, y_dc_delta_q, bit_depth)
489 : av1_ac_quant_Q3(q, 0, bit_depth);
490 // y quantizer with TX scale
491 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth)
492 : av1_ac_quant_QTX(q, 0, bit_depth);
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400493 invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i],
494 quant_QTX);
495 quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX;
496 quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
497 quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
498 quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
499 deq->y_dequant_QTX[q][i] = quant_QTX;
500 deq->y_dequant_Q3[q][i] = quant_Q3;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700501
Yaowu Xube42dc72017-11-08 17:38:24 -0800502 // u quantizer setup with original coeff shift of Q3
Monty Montgomery60f2a222017-11-01 19:48:38 -0400503 quant_Q3 = i == 0 ? av1_dc_quant_Q3(q, u_dc_delta_q, bit_depth)
504 : av1_ac_quant_Q3(q, u_ac_delta_q, bit_depth);
505 // u quantizer with TX scale
506 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth)
507 : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth);
Yaowu Xube42dc72017-11-08 17:38:24 -0800508 invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i],
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400509 quant_QTX);
Yaowu Xube42dc72017-11-08 17:38:24 -0800510 quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX;
511 quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
512 quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
513 quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
514 deq->u_dequant_QTX[q][i] = quant_QTX;
515 deq->u_dequant_Q3[q][i] = quant_Q3;
516
517 // v quantizer setup with original coeff shift of Q3
Monty Montgomery60f2a222017-11-01 19:48:38 -0400518 quant_Q3 = i == 0 ? av1_dc_quant_Q3(q, v_dc_delta_q, bit_depth)
519 : av1_ac_quant_Q3(q, v_ac_delta_q, bit_depth);
520 // v quantizer with TX scale
521 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth)
522 : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth);
Yaowu Xube42dc72017-11-08 17:38:24 -0800523 invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i],
524 quant_QTX);
525 quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX;
526 quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
527 quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
528 quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
529 deq->v_dequant_QTX[q][i] = quant_QTX;
530 deq->v_dequant_Q3[q][i] = quant_Q3;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700531 }
532
Yaowu Xuc27fc142016-08-22 16:08:15 -0700533 for (i = 2; i < 8; i++) { // 8: SIMD width
534 quants->y_quant[q][i] = quants->y_quant[q][1];
535 quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
536 quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
537 quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
538 quants->y_zbin[q][i] = quants->y_zbin[q][1];
539 quants->y_round[q][i] = quants->y_round[q][1];
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400540 deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1];
541 deq->y_dequant_Q3[q][i] = deq->y_dequant_Q3[q][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700542
Yaowu Xube42dc72017-11-08 17:38:24 -0800543 quants->u_quant[q][i] = quants->u_quant[q][1];
544 quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1];
545 quants->u_round_fp[q][i] = quants->u_round_fp[q][1];
546 quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1];
547 quants->u_zbin[q][i] = quants->u_zbin[q][1];
548 quants->u_round[q][i] = quants->u_round[q][1];
549 deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1];
550 deq->u_dequant_Q3[q][i] = deq->u_dequant_Q3[q][1];
551 quants->v_quant[q][i] = quants->u_quant[q][1];
552 quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1];
553 quants->v_round_fp[q][i] = quants->v_round_fp[q][1];
554 quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1];
555 quants->v_zbin[q][i] = quants->v_zbin[q][1];
556 quants->v_round[q][i] = quants->v_round[q][1];
557 deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1];
558 deq->v_dequant_Q3[q][i] = deq->v_dequant_Q3[q][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559 }
560 }
561}
562
Yi Luoc6210232017-05-25 15:09:25 -0700563void av1_init_quantizer(AV1_COMP *cpi) {
564 AV1_COMMON *const cm = &cpi->common;
565 QUANTS *const quants = &cpi->quants;
566 Dequants *const dequants = &cpi->dequants;
Yaowu Xube42dc72017-11-08 17:38:24 -0800567 av1_build_quantizer(cm->bit_depth, cm->y_dc_delta_q, cm->u_dc_delta_q,
568 cm->u_ac_delta_q, cm->v_dc_delta_q, cm->v_ac_delta_q,
569 quants, dequants);
Yi Luoc6210232017-05-25 15:09:25 -0700570}
571
Yaowu Xuf883b422016-08-30 14:01:10 -0700572void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
573 int segment_id) {
574 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700575 MACROBLOCKD *const xd = &x->e_mbd;
576 const QUANTS *const quants = &cpi->quants;
Arild Fuldseth07441162016-08-15 15:07:52 +0200577
Fangwen Fu6160df22017-04-24 09:45:51 -0700578#if CONFIG_EXT_DELTA_Q
Johannb0ef6ff2018-02-08 14:32:21 -0800579 int current_q_index = AOMMAX(
580 0, AOMMIN(QINDEX_RANGE - 1, cpi->oxcf.deltaq_mode != NO_DELTA_Q
581 ? cm->base_qindex + xd->delta_qindex
582 : cm->base_qindex));
Fangwen Fu6160df22017-04-24 09:45:51 -0700583#else
Yaowu Xubfed7382018-02-25 20:18:14 -0800584 int current_q_index = AOMMAX(
585 0, AOMMIN(QINDEX_RANGE - 1, cm->delta_q_present_flag
586 ? cm->base_qindex + xd->delta_qindex
587 : cm->base_qindex));
Fangwen Fu6160df22017-04-24 09:45:51 -0700588#endif
Arild Fuldseth07441162016-08-15 15:07:52 +0200589 const int qindex = av1_get_qindex(&cm->seg, segment_id, current_q_index);
Yaowu Xuf883b422016-08-30 14:01:10 -0700590 const int rdmult = av1_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
Yaowu Xuf7a12422018-01-31 15:29:20 -0800591#if CONFIG_AOM_QM_EXT
592 int qmlevel = (xd->lossless[segment_id] || cm->using_qmatrix == 0)
593 ? NUM_QM_LEVELS - 1
594 : cm->qm_y;
595#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700596 int minqm = cm->min_qmlevel;
597 int maxqm = cm->max_qmlevel;
598 // Quant matrix only depends on the base QP so there is only one set per frame
Yaowu Xu0dd04632016-10-19 09:31:50 -0700599 int qmlevel = (xd->lossless[segment_id] || cm->using_qmatrix == 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700600 ? NUM_QM_LEVELS - 1
601 : aom_get_qmlevel(cm->base_qindex, minqm, maxqm);
Yaowu Xuf7a12422018-01-31 15:29:20 -0800602#endif // CONFIG_AOM_QM_EXT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700603
604 // Y
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400605 x->plane[0].quant_QTX = quants->y_quant[qindex];
606 x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex];
607 x->plane[0].round_fp_QTX = quants->y_round_fp[qindex];
608 x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex];
609 x->plane[0].zbin_QTX = quants->y_zbin[qindex];
610 x->plane[0].round_QTX = quants->y_round[qindex];
611 x->plane[0].dequant_QTX = cpi->dequants.y_dequant_QTX[qindex];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700612 memcpy(&xd->plane[0].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel][0],
613 sizeof(cm->gqmatrix[qmlevel][0]));
614 memcpy(&xd->plane[0].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel][0],
615 sizeof(cm->giqmatrix[qmlevel][0]));
Monty Montgomery125c0fc2017-10-26 00:44:35 -0400616 xd->plane[0].dequant_Q3 = cpi->dequants.y_dequant_Q3[qindex];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700617
Yaowu Xuf7a12422018-01-31 15:29:20 -0800618// U
Yaowu Xuf7a12422018-01-31 15:29:20 -0800619#if CONFIG_AOM_QM_EXT
620 qmlevel = (xd->lossless[segment_id] || cm->using_qmatrix == 0)
621 ? NUM_QM_LEVELS - 1
622 : cm->qm_u;
623#endif
Yaowu Xube42dc72017-11-08 17:38:24 -0800624 {
625 x->plane[1].quant_QTX = quants->u_quant[qindex];
626 x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex];
627 x->plane[1].round_fp_QTX = quants->u_round_fp[qindex];
628 x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex];
629 x->plane[1].zbin_QTX = quants->u_zbin[qindex];
630 x->plane[1].round_QTX = quants->u_round[qindex];
631 x->plane[1].dequant_QTX = cpi->dequants.u_dequant_QTX[qindex];
Yaowu Xube42dc72017-11-08 17:38:24 -0800632 memcpy(&xd->plane[1].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel][1],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633 sizeof(cm->gqmatrix[qmlevel][1]));
Yaowu Xube42dc72017-11-08 17:38:24 -0800634 memcpy(&xd->plane[1].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel][1],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635 sizeof(cm->giqmatrix[qmlevel][1]));
Yaowu Xube42dc72017-11-08 17:38:24 -0800636 x->plane[1].dequant_QTX = cpi->dequants.u_dequant_QTX[qindex];
637 xd->plane[1].dequant_Q3 = cpi->dequants.u_dequant_Q3[qindex];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638 }
Yaowu Xuf7a12422018-01-31 15:29:20 -0800639// V
Yaowu Xuf7a12422018-01-31 15:29:20 -0800640#if CONFIG_AOM_QM_EXT
641 qmlevel = (xd->lossless[segment_id] || cm->using_qmatrix == 0)
642 ? NUM_QM_LEVELS - 1
643 : cm->qm_v;
644#endif
Yaowu Xube42dc72017-11-08 17:38:24 -0800645 {
646 x->plane[2].quant_QTX = quants->v_quant[qindex];
647 x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex];
648 x->plane[2].round_fp_QTX = quants->v_round_fp[qindex];
649 x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex];
650 x->plane[2].zbin_QTX = quants->v_zbin[qindex];
651 x->plane[2].round_QTX = quants->v_round[qindex];
652 x->plane[2].dequant_QTX = cpi->dequants.v_dequant_QTX[qindex];
Yaowu Xud467bba2017-11-09 13:39:11 -0800653 memcpy(&xd->plane[2].seg_qmatrix[segment_id], cm->gqmatrix[qmlevel][2],
654 sizeof(cm->gqmatrix[qmlevel][2]));
655 memcpy(&xd->plane[2].seg_iqmatrix[segment_id], cm->giqmatrix[qmlevel][2],
656 sizeof(cm->giqmatrix[qmlevel][2]));
Yaowu Xube42dc72017-11-08 17:38:24 -0800657 x->plane[2].dequant_QTX = cpi->dequants.v_dequant_QTX[qindex];
658 xd->plane[2].dequant_Q3 = cpi->dequants.v_dequant_Q3[qindex];
Yaowu Xube42dc72017-11-08 17:38:24 -0800659 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700660 x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
David Barkerd7d78c82016-10-24 10:55:35 +0100661 x->qindex = qindex;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700662
663 set_error_per_bit(x, rdmult);
664
David Barkerd7d78c82016-10-24 10:55:35 +0100665 av1_initialize_me_consts(cpi, x, qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666}
667
Yaowu Xuf883b422016-08-30 14:01:10 -0700668void av1_frame_init_quantizer(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700669 MACROBLOCK *const x = &cpi->td.mb;
670 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700671 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672}
673
Yaowu Xuf883b422016-08-30 14:01:10 -0700674void av1_set_quantizer(AV1_COMMON *cm, int q) {
675 // quantizer has to be reinitialized with av1_init_quantizer() if any
Yaowu Xuc27fc142016-08-22 16:08:15 -0700676 // delta_q changes.
677 cm->base_qindex = q;
678 cm->y_dc_delta_q = 0;
Yaowu Xube42dc72017-11-08 17:38:24 -0800679 cm->u_dc_delta_q = 0;
680 cm->u_ac_delta_q = 0;
681 cm->v_dc_delta_q = 0;
682 cm->v_ac_delta_q = 0;
Yaowu Xuf7a12422018-01-31 15:29:20 -0800683#if CONFIG_AOM_QM_EXT
684 cm->qm_y = aom_get_qmlevel(cm->base_qindex, cm->min_qmlevel, cm->max_qmlevel);
685 cm->qm_u = aom_get_qmlevel(cm->base_qindex + cm->u_ac_delta_q,
686 cm->min_qmlevel, cm->max_qmlevel);
687
Yaowu Xuf7a12422018-01-31 15:29:20 -0800688 if (!cm->separate_uv_delta_q)
689 cm->qm_v = cm->qm_u;
690 else
Yaowu Xuf7a12422018-01-31 15:29:20 -0800691 cm->qm_v = aom_get_qmlevel(cm->base_qindex + cm->v_ac_delta_q,
692 cm->min_qmlevel, cm->max_qmlevel);
693#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700694}
695
696// Table that converts 0-63 Q-range values passed in outside to the Qindex
697// range used internally.
698static const int quantizer_to_qindex[] = {
699 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
700 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100,
701 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
702 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
703 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
704};
705
Yaowu Xuf883b422016-08-30 14:01:10 -0700706int av1_quantizer_to_qindex(int quantizer) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700707 return quantizer_to_qindex[quantizer];
708}
709
Yaowu Xuf883b422016-08-30 14:01:10 -0700710int av1_qindex_to_quantizer(int qindex) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711 int quantizer;
712
713 for (quantizer = 0; quantizer < 64; ++quantizer)
714 if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
715
716 return 63;
717}