Coverage Report

Created: 2026-11-12 08:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/av1/encoder/av1_quantize.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3
 *
4
 * 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.
10
 */
11
12
#include <math.h>
13
14
#include "config/aom_dsp_rtcd.h"
15
16
#include "aom/aomcx.h"
17
#include "aom_dsp/quantize.h"
18
#include "aom_mem/aom_mem.h"
19
#include "aom_ports/bitops.h"
20
#include "aom_ports/mem.h"
21
22
#include "av1/common/idct.h"
23
#include "av1/common/quant_common.h"
24
#include "av1/common/scan.h"
25
#include "av1/common/seg_common.h"
26
27
#include "av1/encoder/av1_quantize.h"
28
#include "av1/encoder/encoder.h"
29
#include "av1/encoder/rd.h"
30
31
void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr,
32
0
                       tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr) {
33
0
  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
34
0
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
35
0
  *eob_ptr = 0;
36
0
}
37
38
int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2],
39
                               const int16_t dequant_ptr[2],
40
                               const int16_t round_ptr[2], int log_scale,
41
                               const int16_t *scan, int coeff_count,
42
                               const tran_low_t *coeff_ptr,
43
                               tran_low_t *qcoeff_ptr,
44
0
                               tran_low_t *dqcoeff_ptr) {
45
0
  memset(qcoeff_ptr, 0, coeff_count * sizeof(*qcoeff_ptr));
46
0
  memset(dqcoeff_ptr, 0, coeff_count * sizeof(*dqcoeff_ptr));
47
0
  const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
48
0
                            ROUND_POWER_OF_TWO(round_ptr[1], log_scale) };
49
0
  int eob = 0;
50
0
  for (int i = 0; i < coeff_count; i++) {
51
0
    const int rc = scan[i];
52
0
    const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]);
53
0
    const int coeff = coeff_ptr[rc];
54
0
    const int coeff_sign = AOMSIGN(coeff);
55
0
    int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
56
0
    int tmp32 = 0;
57
0
    if ((abs_coeff << (1 + log_scale)) >= thresh) {
58
0
      abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX);
59
0
      tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale));
60
0
      if (tmp32) {
61
0
        qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
62
0
        const tran_low_t abs_dqcoeff =
63
0
            (tmp32 * dequant_ptr[rc != 0]) >> log_scale;
64
0
        dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
65
0
      }
66
0
    }
67
0
    if (tmp32) eob = i + 1;
68
0
  }
69
0
  return eob;
70
0
}
71
72
static void quantize_fp_helper_c(
73
    const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
74
    const int16_t *round_ptr, const int16_t *quant_ptr,
75
    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
76
    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
77
    const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
78
0
    const qm_val_t *iqm_ptr, int log_scale) {
79
0
  int i, eob = -1;
80
0
  const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
81
0
                            ROUND_POWER_OF_TWO(round_ptr[1], log_scale) };
82
  // TODO(jingning) Decide the need of these arguments after the
83
  // quantization process is completed.
84
0
  (void)zbin_ptr;
85
0
  (void)quant_shift_ptr;
86
0
  (void)iscan;
87
88
0
  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
89
0
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
90
91
0
  if (qm_ptr == NULL && iqm_ptr == NULL) {
92
0
    *eob_ptr = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr,
93
0
                                          log_scale, scan, (int)n_coeffs,
94
0
                                          coeff_ptr, qcoeff_ptr, dqcoeff_ptr);
95
0
  } else {
96
    // Quantization pass: All coefficients with index >= zero_flag are
97
    // skippable. Note: zero_flag can be zero.
98
0
    for (i = 0; i < n_coeffs; i++) {
99
0
      const int rc = scan[i];
100
0
      const int coeff = coeff_ptr[rc];
101
0
      const qm_val_t wt = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS);
102
0
      const qm_val_t iwt = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
103
0
      const int dequant =
104
0
          (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
105
0
          AOM_QM_BITS;
106
0
      const int coeff_sign = AOMSIGN(coeff);
107
0
      int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
108
0
      int tmp32 = 0;
109
0
      if (abs_coeff * wt >=
110
0
          (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
111
0
        abs_coeff += rounding[rc != 0];
112
0
        abs_coeff = clamp64(abs_coeff, INT16_MIN, INT16_MAX);
113
0
        tmp32 = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >>
114
0
                      (16 - log_scale + AOM_QM_BITS));
115
0
        qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
116
0
        const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
117
0
        dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
118
0
      }
119
120
0
      if (tmp32) eob = i;
121
0
    }
122
0
    *eob_ptr = eob + 1;
123
0
  }
124
0
}
125
126
#if CONFIG_AV1_HIGHBITDEPTH
127
static void highbd_quantize_fp_helper_c(
128
    const tran_low_t *coeff_ptr, intptr_t count, const int16_t *zbin_ptr,
129
    const int16_t *round_ptr, const int16_t *quant_ptr,
130
    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
131
    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
132
    const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
133
0
    const qm_val_t *iqm_ptr, int log_scale) {
134
0
  int i;
135
0
  int eob = -1;
136
0
  const int shift = 16 - log_scale;
137
  // TODO(jingning) Decide the need of these arguments after the
138
  // quantization process is completed.
139
0
  (void)zbin_ptr;
140
0
  (void)quant_shift_ptr;
141
0
  (void)iscan;
142
143
0
  if (qm_ptr || iqm_ptr) {
144
    // Quantization pass: All coefficients with index >= zero_flag are
145
    // skippable. Note: zero_flag can be zero.
146
0
    for (i = 0; i < count; i++) {
147
0
      const int rc = scan[i];
148
0
      const int coeff = coeff_ptr[rc];
149
0
      const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
150
0
      const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
151
0
      const int dequant =
152
0
          (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
153
0
          AOM_QM_BITS;
154
0
      const int coeff_sign = AOMSIGN(coeff);
155
0
      const int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
156
0
      int abs_qcoeff = 0;
157
0
      if (abs_coeff * wt >=
158
0
          (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
159
0
        const int64_t tmp =
160
0
            abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
161
0
        abs_qcoeff =
162
0
            (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
163
0
        qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
164
0
        const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
165
0
        dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
166
0
        if (abs_qcoeff) eob = i;
167
0
      } else {
168
0
        qcoeff_ptr[rc] = 0;
169
0
        dqcoeff_ptr[rc] = 0;
170
0
      }
171
0
    }
172
0
  } else {
173
0
    const int log_scaled_round_arr[2] = {
174
0
      ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
175
0
      ROUND_POWER_OF_TWO(round_ptr[1], log_scale),
176
0
    };
177
0
    for (i = 0; i < count; i++) {
178
0
      const int rc = scan[i];
179
0
      const int coeff = coeff_ptr[rc];
180
0
      const int rc01 = (rc != 0);
181
0
      const int coeff_sign = AOMSIGN(coeff);
182
0
      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
183
0
      const int log_scaled_round = log_scaled_round_arr[rc01];
184
0
      if ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) {
185
0
        const int quant = quant_ptr[rc01];
186
0
        const int dequant = dequant_ptr[rc01];
187
0
        const int64_t tmp = (int64_t)abs_coeff + log_scaled_round;
188
0
        const int abs_qcoeff = (int)((tmp * quant) >> shift);
189
0
        qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
190
0
        const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
191
0
        if (abs_qcoeff) eob = i;
192
0
        dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
193
0
      } else {
194
0
        qcoeff_ptr[rc] = 0;
195
0
        dqcoeff_ptr[rc] = 0;
196
0
      }
197
0
    }
198
0
  }
199
0
  *eob_ptr = eob + 1;
200
0
}
201
#endif  // CONFIG_AV1_HIGHBITDEPTH
202
203
void av1_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
204
                       const int16_t *zbin_ptr, const int16_t *round_ptr,
205
                       const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
206
                       tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
207
                       const int16_t *dequant_ptr, uint16_t *eob_ptr,
208
0
                       const int16_t *scan, const int16_t *iscan) {
209
0
  quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
210
0
                       quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
211
0
                       eob_ptr, scan, iscan, NULL, NULL, 0);
212
0
}
213
214
void av1_quantize_lp_c(const int16_t *coeff_ptr, intptr_t n_coeffs,
215
                       const int16_t *round_ptr, const int16_t *quant_ptr,
216
                       int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
217
                       const int16_t *dequant_ptr, uint16_t *eob_ptr,
218
0
                       const int16_t *scan, const int16_t *iscan) {
219
0
  (void)iscan;
220
0
  int eob = -1;
221
222
0
  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
223
0
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
224
225
  // Quantization pass: All coefficients with index >= zero_flag are
226
  // skippable. Note: zero_flag can be zero.
227
0
  for (int i = 0; i < n_coeffs; i++) {
228
0
    const int rc = scan[i];
229
0
    const int coeff = coeff_ptr[rc];
230
0
    const int coeff_sign = AOMSIGN(coeff);
231
0
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
232
233
0
    int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
234
0
    tmp = (tmp * quant_ptr[rc != 0]) >> 16;
235
236
0
    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
237
0
    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
238
239
0
    if (tmp) eob = i;
240
0
  }
241
0
  *eob_ptr = eob + 1;
242
0
}
243
244
void av1_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
245
                             const int16_t *zbin_ptr, const int16_t *round_ptr,
246
                             const int16_t *quant_ptr,
247
                             const int16_t *quant_shift_ptr,
248
                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
249
                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
250
0
                             const int16_t *scan, const int16_t *iscan) {
251
0
  quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
252
0
                       quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
253
0
                       eob_ptr, scan, iscan, NULL, NULL, 1);
254
0
}
255
256
void av1_quantize_fp_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
257
                             const int16_t *zbin_ptr, const int16_t *round_ptr,
258
                             const int16_t *quant_ptr,
259
                             const int16_t *quant_shift_ptr,
260
                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
261
                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
262
0
                             const int16_t *scan, const int16_t *iscan) {
263
0
  quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
264
0
                       quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
265
0
                       eob_ptr, scan, iscan, NULL, NULL, 2);
266
0
}
267
268
void av1_quantize_fp_qm_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
269
                          const int16_t *round_ptr, const int16_t *quant_ptr,
270
                          tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
271
                          const int16_t *dequant_ptr, uint16_t *eob_ptr,
272
                          const int16_t *scan, const int16_t *iscan,
273
                          const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr,
274
0
                          int log_scale) {
275
0
  quantize_fp_helper_c(coeff_ptr, n_coeffs, NULL, round_ptr, quant_ptr, NULL,
276
0
                       qcoeff_ptr, dqcoeff_ptr, dequant_ptr, eob_ptr, scan,
277
0
                       iscan, qm_ptr, iqm_ptr, log_scale);
278
0
}
279
280
void av1_quantize_b_qm_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
281
                         const int16_t *zbin_ptr, const int16_t *round_ptr,
282
                         const int16_t *quant_ptr,
283
                         const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
284
                         tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
285
                         uint16_t *eob_ptr, const int16_t *scan,
286
                         const int16_t *iscan, const qm_val_t *qm_ptr,
287
0
                         const qm_val_t *iqm_ptr, int log_scale) {
288
0
  aom_quantize_b_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
289
0
                          quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
290
0
                          eob_ptr, scan, iscan, qm_ptr, iqm_ptr, log_scale);
291
0
}
292
293
void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
294
                            const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
295
                            tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
296
0
                            const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
297
0
  const qm_val_t *qm_ptr = qparam->qmatrix;
298
0
  const qm_val_t *iqm_ptr = qparam->iqmatrix;
299
0
  if (qm_ptr != NULL && iqm_ptr != NULL) {
300
0
    av1_quantize_fp_qm(coeff_ptr, n_coeffs, p->round_fp_QTX, p->quant_fp_QTX,
301
0
                       qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
302
0
                       sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
303
0
  } else {
304
0
    switch (qparam->log_scale) {
305
0
      case 0:
306
0
        av1_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
307
0
                        p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
308
0
                        dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
309
0
                        sc->iscan);
310
0
        break;
311
0
      case 1:
312
0
        av1_quantize_fp_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
313
0
                              p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
314
0
                              dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
315
0
                              sc->iscan);
316
0
        break;
317
0
      case 2:
318
0
        av1_quantize_fp_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
319
0
                              p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
320
0
                              dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
321
0
                              sc->iscan);
322
0
        break;
323
0
      default: assert(0);
324
0
    }
325
0
  }
326
0
}
327
328
void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
329
                           const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
330
                           tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
331
0
                           const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
332
0
  const qm_val_t *qm_ptr = qparam->qmatrix;
333
0
  const qm_val_t *iqm_ptr = qparam->iqmatrix;
334
0
#if !CONFIG_REALTIME_ONLY
335
0
  if (qparam->use_quant_b_adapt) {
336
    // TODO(sarahparker) These quantize_b optimizations need SIMD
337
    // implementations
338
0
    if (qm_ptr != NULL && iqm_ptr != NULL) {
339
0
      aom_quantize_b_adaptive_helper_c(
340
0
          coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
341
0
          p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
342
0
          sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
343
0
    } else {
344
0
      switch (qparam->log_scale) {
345
0
        case 0:
346
0
          aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX,
347
0
                                  p->round_QTX, p->quant_QTX,
348
0
                                  p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
349
0
                                  p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
350
0
          break;
351
0
        case 1:
352
0
          aom_quantize_b_32x32_adaptive(
353
0
              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
354
0
              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
355
0
              eob_ptr, sc->scan, sc->iscan);
356
0
          break;
357
0
        case 2:
358
0
          aom_quantize_b_64x64_adaptive(
359
0
              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
360
0
              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
361
0
              eob_ptr, sc->scan, sc->iscan);
362
0
          break;
363
0
        default: assert(0);
364
0
      }
365
0
    }
366
0
    return;
367
0
  }
368
0
#endif  // !CONFIG_REALTIME_ONLY
369
370
0
  if (qm_ptr != NULL && iqm_ptr != NULL) {
371
0
    av1_quantize_b_qm(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
372
0
                      p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
373
0
                      p->dequant_QTX, eob_ptr, sc->scan, sc->iscan, qm_ptr,
374
0
                      iqm_ptr, qparam->log_scale);
375
0
  } else {
376
0
    switch (qparam->log_scale) {
377
0
      case 0:
378
0
        aom_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
379
0
                       p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
380
0
                       dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
381
0
                       sc->iscan);
382
0
        break;
383
0
      case 1:
384
0
        aom_quantize_b_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
385
0
                             p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
386
0
                             dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
387
0
                             sc->iscan);
388
0
        break;
389
0
      case 2:
390
0
        aom_quantize_b_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
391
0
                             p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
392
0
                             dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
393
0
                             sc->iscan);
394
0
        break;
395
0
      default: assert(0);
396
0
    }
397
0
  }
398
0
}
399
400
static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
401
                        int skip_block, const int16_t *round_ptr,
402
                        const int16_t quant, tran_low_t *qcoeff_ptr,
403
                        tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
404
                        uint16_t *eob_ptr, const qm_val_t *qm_ptr,
405
0
                        const qm_val_t *iqm_ptr, const int log_scale) {
406
0
  const int rc = 0;
407
0
  const int coeff = coeff_ptr[rc];
408
0
  const int coeff_sign = AOMSIGN(coeff);
409
0
  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
410
0
  int64_t tmp;
411
0
  int eob = -1;
412
0
  int32_t tmp32;
413
0
  int dequant;
414
415
0
  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
416
0
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
417
418
0
  if (!skip_block) {
419
0
    const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
420
0
    const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
421
0
    tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
422
0
                INT16_MIN, INT16_MAX);
423
0
    tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS));
424
0
    qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
425
0
    dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
426
0
    const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
427
0
    dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
428
0
    if (tmp32) eob = 0;
429
0
  }
430
0
  *eob_ptr = eob + 1;
431
0
}
432
433
void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
434
                            const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
435
                            tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
436
0
                            const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
437
  // obsolete skip_block
438
0
  const int skip_block = 0;
439
0
  (void)sc;
440
0
  assert(qparam->log_scale >= 0 && qparam->log_scale < (3));
441
0
  const qm_val_t *qm_ptr = qparam->qmatrix;
442
0
  const qm_val_t *iqm_ptr = qparam->iqmatrix;
443
0
  quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
444
0
              p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0],
445
0
              eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale);
446
0
}
447
448
#if CONFIG_AV1_HIGHBITDEPTH
449
void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
450
                                   intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
451
                                   tran_low_t *qcoeff_ptr,
452
                                   tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
453
                                   const SCAN_ORDER *sc,
454
0
                                   const QUANT_PARAM *qparam) {
455
0
  const qm_val_t *qm_ptr = qparam->qmatrix;
456
0
  const qm_val_t *iqm_ptr = qparam->iqmatrix;
457
0
  if (qm_ptr != NULL && iqm_ptr != NULL) {
458
0
    av1_highbd_quantize_fp_qm(coeff_ptr, n_coeffs, p->round_fp_QTX,
459
0
                              p->quant_fp_QTX, qcoeff_ptr, dqcoeff_ptr,
460
0
                              p->dequant_QTX, eob_ptr, sc->scan, sc->iscan,
461
0
                              qm_ptr, iqm_ptr, qparam->log_scale);
462
0
  } else {
463
0
    av1_highbd_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
464
0
                           p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
465
0
                           dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
466
0
                           sc->iscan, qparam->log_scale);
467
0
  }
468
0
}
469
470
void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
471
                                  intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
472
                                  tran_low_t *qcoeff_ptr,
473
                                  tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
474
                                  const SCAN_ORDER *sc,
475
0
                                  const QUANT_PARAM *qparam) {
476
0
  const qm_val_t *qm_ptr = qparam->qmatrix;
477
0
  const qm_val_t *iqm_ptr = qparam->iqmatrix;
478
0
#if !CONFIG_REALTIME_ONLY
479
0
  if (qparam->use_quant_b_adapt) {
480
0
    if (qm_ptr != NULL && iqm_ptr != NULL) {
481
0
      aom_highbd_quantize_b_adaptive_helper_c(
482
0
          coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
483
0
          p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
484
0
          sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
485
0
    } else {
486
0
      switch (qparam->log_scale) {
487
0
        case 0:
488
0
          aom_highbd_quantize_b_adaptive(
489
0
              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
490
0
              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
491
0
              eob_ptr, sc->scan, sc->iscan);
492
0
          break;
493
0
        case 1:
494
0
          aom_highbd_quantize_b_32x32_adaptive(
495
0
              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
496
0
              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
497
0
              eob_ptr, sc->scan, sc->iscan);
498
0
          break;
499
0
        case 2:
500
0
          aom_highbd_quantize_b_64x64_adaptive(
501
0
              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
502
0
              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
503
0
              eob_ptr, sc->scan, sc->iscan);
504
0
          break;
505
0
        default: assert(0);
506
0
      }
507
0
    }
508
0
    return;
509
0
  }
510
0
#endif  // !CONFIG_REALTIME_ONLY
511
512
0
  if (qm_ptr != NULL && iqm_ptr != NULL) {
513
0
    av1_highbd_quantize_b_qm(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
514
0
                             p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
515
0
                             dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
516
0
                             sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
517
0
  } else {
518
0
    switch (qparam->log_scale) {
519
0
      case 0:
520
0
        aom_highbd_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
521
0
                              p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
522
0
                              dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
523
0
                              sc->iscan);
524
0
        break;
525
0
      case 1:
526
0
        aom_highbd_quantize_b_32x32(
527
0
            coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
528
0
            p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
529
0
            eob_ptr, sc->scan, sc->iscan);
530
0
        break;
531
0
      case 2:
532
0
        aom_highbd_quantize_b_64x64(
533
0
            coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
534
0
            p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
535
0
            eob_ptr, sc->scan, sc->iscan);
536
0
        break;
537
0
      default: assert(0);
538
0
    }
539
0
  }
540
0
}
541
542
static inline void highbd_quantize_dc(
543
    const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
544
    const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr,
545
    tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr,
546
0
    const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) {
547
0
  int eob = -1;
548
549
0
  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
550
0
  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
551
552
0
  if (!skip_block) {
553
0
    const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS);
554
0
    const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS);
555
0
    const int coeff = coeff_ptr[0];
556
0
    const int coeff_sign = AOMSIGN(coeff);
557
0
    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
558
0
    const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale);
559
0
    const int64_t tmpw = tmp * wt;
560
0
    const int abs_qcoeff =
561
0
        (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS));
562
0
    qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
563
0
    const int dequant =
564
0
        (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
565
566
0
    const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
567
0
    dqcoeff_ptr[0] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
568
0
    if (abs_qcoeff) eob = 0;
569
0
  }
570
0
  *eob_ptr = eob + 1;
571
0
}
572
573
void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
574
                                   intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
575
                                   tran_low_t *qcoeff_ptr,
576
                                   tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
577
                                   const SCAN_ORDER *sc,
578
0
                                   const QUANT_PARAM *qparam) {
579
  // obsolete skip_block
580
0
  const int skip_block = 0;
581
0
  const qm_val_t *qm_ptr = qparam->qmatrix;
582
0
  const qm_val_t *iqm_ptr = qparam->iqmatrix;
583
0
  (void)sc;
584
585
0
  highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
586
0
                     p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr,
587
0
                     p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr,
588
0
                     qparam->log_scale);
589
0
}
590
591
void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
592
                              const int16_t *zbin_ptr, const int16_t *round_ptr,
593
                              const int16_t *quant_ptr,
594
                              const int16_t *quant_shift_ptr,
595
                              tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
596
                              const int16_t *dequant_ptr, uint16_t *eob_ptr,
597
                              const int16_t *scan, const int16_t *iscan,
598
0
                              int log_scale) {
599
0
  highbd_quantize_fp_helper_c(coeff_ptr, count, zbin_ptr, round_ptr, quant_ptr,
600
0
                              quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
601
0
                              dequant_ptr, eob_ptr, scan, iscan, NULL, NULL,
602
0
                              log_scale);
603
0
}
604
605
void av1_highbd_quantize_fp_qm_c(
606
    const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *round_ptr,
607
    const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
608
    const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan,
609
    const int16_t *iscan, const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr,
610
0
    int log_scale) {
611
0
  highbd_quantize_fp_helper_c(coeff_ptr, n_coeffs, NULL, round_ptr, quant_ptr,
612
0
                              NULL, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
613
0
                              eob_ptr, scan, iscan, qm_ptr, iqm_ptr, log_scale);
614
0
}
615
616
void av1_highbd_quantize_b_qm_c(
617
    const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
618
    const int16_t *round_ptr, const int16_t *quant_ptr,
619
    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
620
    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
621
    const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
622
0
    const qm_val_t *iqm_ptr, int log_scale) {
623
0
  aom_highbd_quantize_b_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr,
624
0
                                 quant_ptr, quant_shift_ptr, qcoeff_ptr,
625
0
                                 dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan,
626
0
                                 qm_ptr, iqm_ptr, log_scale);
627
0
}
628
#endif  // CONFIG_AV1_HIGHBITDEPTH
629
630
0
static void invert_quant(int16_t *quant, int16_t *shift, int d) {
631
0
  uint32_t t;
632
0
  int l, m;
633
0
  t = d;
634
0
  l = get_msb(t);
635
0
  m = 1 + (1 << (16 + l)) / d;
636
0
  *quant = (int16_t)(m - (1 << 16));
637
0
  *shift = 1 << (16 - l);
638
0
}
639
640
0
static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) {
641
0
  const int quant = av1_dc_quant_QTX(q, 0, bit_depth);
642
0
  switch (bit_depth) {
643
0
    case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
644
0
    case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
645
0
    case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
646
0
    default:
647
0
      assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
648
0
      return -1;
649
0
  }
650
0
}
651
652
void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
653
                         int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
654
                         int v_ac_delta_q, QUANTS *const quants,
655
0
                         Dequants *const deq, int sharpness) {
656
0
  int i, q, quant_QTX;
657
0
  const int sharpness_adjustment = 16 * (7 - sharpness) / 7;
658
659
0
  for (q = 0; q < QINDEX_RANGE; q++) {
660
0
    const int qzbin_factor = get_qzbin_factor(q, bit_depth);
661
0
    int qrounding_factor = q == 0 ? 64 : 48;
662
663
0
    for (i = 0; i < 2; ++i) {
664
0
      int qrounding_factor_fp = 64;
665
666
0
      if (sharpness != 0 && q != 0) {
667
0
        qrounding_factor = 64 - sharpness_adjustment;
668
0
        qrounding_factor_fp = 64 - sharpness_adjustment;
669
0
      }
670
671
      // y quantizer with TX scale
672
0
      quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth)
673
0
                         : av1_ac_quant_QTX(q, 0, bit_depth);
674
0
      invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i],
675
0
                   quant_QTX);
676
0
      quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX;
677
0
      quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
678
0
      quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
679
0
      quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
680
0
      deq->y_dequant_QTX[q][i] = quant_QTX;
681
682
      // u quantizer with TX scale
683
0
      quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth)
684
0
                         : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth);
685
0
      invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i],
686
0
                   quant_QTX);
687
0
      quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX;
688
0
      quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
689
0
      quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
690
0
      quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
691
0
      deq->u_dequant_QTX[q][i] = quant_QTX;
692
693
      // v quantizer with TX scale
694
0
      quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth)
695
0
                         : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth);
696
0
      invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i],
697
0
                   quant_QTX);
698
0
      quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX;
699
0
      quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
700
0
      quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
701
0
      quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
702
0
      deq->v_dequant_QTX[q][i] = quant_QTX;
703
0
    }
704
705
0
    for (i = 2; i < 8; i++) {  // 8: SIMD width
706
0
      quants->y_quant[q][i] = quants->y_quant[q][1];
707
0
      quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
708
0
      quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
709
0
      quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
710
0
      quants->y_zbin[q][i] = quants->y_zbin[q][1];
711
0
      quants->y_round[q][i] = quants->y_round[q][1];
712
0
      deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1];
713
714
0
      quants->u_quant[q][i] = quants->u_quant[q][1];
715
0
      quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1];
716
0
      quants->u_round_fp[q][i] = quants->u_round_fp[q][1];
717
0
      quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1];
718
0
      quants->u_zbin[q][i] = quants->u_zbin[q][1];
719
0
      quants->u_round[q][i] = quants->u_round[q][1];
720
0
      deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1];
721
722
0
      quants->v_quant[q][i] = quants->v_quant[q][1];
723
0
      quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1];
724
0
      quants->v_round_fp[q][i] = quants->v_round_fp[q][1];
725
0
      quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1];
726
0
      quants->v_zbin[q][i] = quants->v_zbin[q][1];
727
0
      quants->v_round[q][i] = quants->v_round[q][1];
728
0
      deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1];
729
0
    }
730
0
  }
731
0
}
732
733
static inline bool deltaq_params_have_changed(
734
    const DeltaQuantParams *prev_deltaq_params,
735
0
    const CommonQuantParams *quant_params) {
736
0
  return (prev_deltaq_params->y_dc_delta_q != quant_params->y_dc_delta_q ||
737
0
          prev_deltaq_params->u_dc_delta_q != quant_params->u_dc_delta_q ||
738
0
          prev_deltaq_params->v_dc_delta_q != quant_params->v_dc_delta_q ||
739
0
          prev_deltaq_params->u_ac_delta_q != quant_params->u_ac_delta_q ||
740
0
          prev_deltaq_params->v_ac_delta_q != quant_params->v_ac_delta_q ||
741
0
          prev_deltaq_params->sharpness != quant_params->sharpness);
742
0
}
743
744
void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params,
745
                        CommonQuantParams *quant_params,
746
0
                        aom_bit_depth_t bit_depth, int sharpness) {
747
0
  DeltaQuantParams *const prev_deltaq_params =
748
0
      &enc_quant_dequant_params->prev_deltaq_params;
749
0
  quant_params->sharpness = sharpness;
750
751
  // Re-initialize the quantizer only if any of the dc/ac deltaq parameters
752
  // change.
753
0
  if (!deltaq_params_have_changed(prev_deltaq_params, quant_params)) return;
754
0
  QUANTS *const quants = &enc_quant_dequant_params->quants;
755
0
  Dequants *const dequants = &enc_quant_dequant_params->dequants;
756
0
  av1_build_quantizer(bit_depth, quant_params->y_dc_delta_q,
757
0
                      quant_params->u_dc_delta_q, quant_params->u_ac_delta_q,
758
0
                      quant_params->v_dc_delta_q, quant_params->v_ac_delta_q,
759
0
                      quants, dequants, sharpness);
760
761
  // Record the state of deltaq parameters.
762
0
  prev_deltaq_params->y_dc_delta_q = quant_params->y_dc_delta_q;
763
0
  prev_deltaq_params->u_dc_delta_q = quant_params->u_dc_delta_q;
764
0
  prev_deltaq_params->v_dc_delta_q = quant_params->v_dc_delta_q;
765
0
  prev_deltaq_params->u_ac_delta_q = quant_params->u_ac_delta_q;
766
0
  prev_deltaq_params->v_ac_delta_q = quant_params->v_ac_delta_q;
767
0
  prev_deltaq_params->sharpness = sharpness;
768
0
}
769
770
/*!\brief Update quantize parameters in MACROBLOCK
771
 *
772
 * \param[in]  enc_quant_dequant_params This parameter cached the quantize and
773
 *                                      dequantize parameters for all q
774
 *                                      indices.
775
 * \param[in]  qindex                   Quantize index used for the current
776
 *                                      superblock.
777
 * \param[out] x                        A superblock data structure for
778
 *                                      encoder.
779
 */
780
static void set_q_index(const EncQuantDequantParams *enc_quant_dequant_params,
781
0
                        int qindex, MACROBLOCK *x) {
782
0
  const QUANTS *const quants = &enc_quant_dequant_params->quants;
783
0
  const Dequants *const dequants = &enc_quant_dequant_params->dequants;
784
0
  x->qindex = qindex;
785
0
  x->seg_skip_block =
786
0
      0;  // TODO(angiebird): Find a proper place to init this variable.
787
788
  // Y
789
0
  x->plane[0].quant_QTX = quants->y_quant[qindex];
790
0
  x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex];
791
0
  x->plane[0].round_fp_QTX = quants->y_round_fp[qindex];
792
0
  x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex];
793
0
  x->plane[0].zbin_QTX = quants->y_zbin[qindex];
794
0
  x->plane[0].round_QTX = quants->y_round[qindex];
795
0
  x->plane[0].dequant_QTX = dequants->y_dequant_QTX[qindex];
796
797
  // U
798
0
  x->plane[1].quant_QTX = quants->u_quant[qindex];
799
0
  x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex];
800
0
  x->plane[1].round_fp_QTX = quants->u_round_fp[qindex];
801
0
  x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex];
802
0
  x->plane[1].zbin_QTX = quants->u_zbin[qindex];
803
0
  x->plane[1].round_QTX = quants->u_round[qindex];
804
0
  x->plane[1].dequant_QTX = dequants->u_dequant_QTX[qindex];
805
806
  // V
807
0
  x->plane[2].quant_QTX = quants->v_quant[qindex];
808
0
  x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex];
809
0
  x->plane[2].round_fp_QTX = quants->v_round_fp[qindex];
810
0
  x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex];
811
0
  x->plane[2].zbin_QTX = quants->v_zbin[qindex];
812
0
  x->plane[2].round_QTX = quants->v_round[qindex];
813
0
  x->plane[2].dequant_QTX = dequants->v_dequant_QTX[qindex];
814
0
}
815
816
/*!\brief Update quantize matrix in MACROBLOCKD based on segment id
817
 *
818
 * \param[in]  quant_params  Quantize parameters used by encoder and decoder
819
 * \param[in]  segment_id    Segment id.
820
 * \param[out] xd            A superblock data structure used by encoder and
821
 * decoder.
822
 */
823
static void set_qmatrix(const CommonQuantParams *quant_params, int segment_id,
824
0
                        MACROBLOCKD *xd) {
825
0
  const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id);
826
0
  const int qmlevel_y =
827
0
      use_qmatrix ? quant_params->qmatrix_level_y : NUM_QM_LEVELS - 1;
828
0
  const int qmlevel_u =
829
0
      use_qmatrix ? quant_params->qmatrix_level_u : NUM_QM_LEVELS - 1;
830
0
  const int qmlevel_v =
831
0
      use_qmatrix ? quant_params->qmatrix_level_v : NUM_QM_LEVELS - 1;
832
0
  const int qmlevel_ls[MAX_MB_PLANE] = { qmlevel_y, qmlevel_u, qmlevel_v };
833
0
  for (int i = 0; i < MAX_MB_PLANE; ++i) {
834
0
    const int qmlevel = qmlevel_ls[i];
835
0
    memcpy(&xd->plane[i].seg_qmatrix[segment_id],
836
0
           quant_params->gqmatrix[qmlevel][i],
837
0
           sizeof(quant_params->gqmatrix[qmlevel][i]));
838
0
    memcpy(&xd->plane[i].seg_iqmatrix[segment_id],
839
0
           quant_params->giqmatrix[qmlevel][i],
840
0
           sizeof(quant_params->giqmatrix[qmlevel][i]));
841
0
  }
842
0
}
843
844
void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
845
0
                               int segment_id, const int do_update) {
846
0
  const AV1_COMMON *const cm = &cpi->common;
847
0
  const CommonQuantParams *const quant_params = &cm->quant_params;
848
0
  const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
849
0
  const int boost_index = AOMMIN(15, (cpi->ppi->p_rc.gfu_boost / 100));
850
0
  const int layer_depth = AOMMIN(gf_group->layer_depth[cpi->gf_frame_index], 6);
851
0
  const FRAME_TYPE frame_type = cm->current_frame.frame_type;
852
0
  int qindex_rd;
853
854
0
  const int current_qindex =
855
0
      clamp(cm->delta_q_info.delta_q_present_flag
856
0
                ? quant_params->base_qindex + x->delta_qindex
857
0
                : quant_params->base_qindex,
858
0
            0, QINDEX_RANGE - 1);
859
0
  const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex);
860
861
0
  if (cpi->oxcf.sb_qp_sweep) {
862
0
    const int current_rd_qindex =
863
0
        clamp(cm->delta_q_info.delta_q_present_flag
864
0
                  ? quant_params->base_qindex + x->rdmult_delta_qindex
865
0
                  : quant_params->base_qindex,
866
0
              0, QINDEX_RANGE - 1);
867
0
    qindex_rd = av1_get_qindex(&cm->seg, segment_id, current_rd_qindex);
868
0
  } else {
869
0
    if (cpi->cb_delta_rdmult_enabled) {
870
0
      const int current_rd_qindex =
871
0
          clamp(quant_params->base_qindex + x->rdmult_delta_qindex, 0,
872
0
                QINDEX_RANGE - 1);
873
0
      qindex_rd = av1_get_qindex(&cm->seg, segment_id, current_rd_qindex);
874
0
    } else {
875
0
      qindex_rd = qindex;
876
0
    }
877
0
  }
878
879
0
  const int qindex_rdmult = qindex_rd + quant_params->y_dc_delta_q;
880
0
  const int rdmult = av1_compute_rd_mult(
881
0
      qindex_rdmult, cm->seq_params->bit_depth,
882
0
      cpi->ppi->gf_group.update_type[cpi->gf_frame_index], layer_depth,
883
0
      boost_index, frame_type, cpi->oxcf.q_cfg.use_fixed_qp_offsets,
884
0
      is_stat_consumption_stage(cpi), cpi->oxcf.tune_cfg.tuning,
885
0
      cpi->oxcf.mode);
886
887
0
  const int qindex_change = x->qindex != qindex;
888
0
  if (qindex_change || do_update) {
889
0
    set_q_index(&cpi->enc_quant_dequant_params, qindex, x);
890
0
  }
891
892
0
  MACROBLOCKD *const xd = &x->e_mbd;
893
0
  if ((segment_id != x->prev_segment_id) ||
894
0
      av1_use_qmatrix(quant_params, xd, segment_id)) {
895
0
    set_qmatrix(quant_params, segment_id, xd);
896
0
  }
897
898
0
  x->seg_skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
899
900
0
  av1_set_error_per_bit(&x->errorperbit, rdmult);
901
0
  av1_set_sad_per_bit(cpi, &x->sadperbit, qindex_rd);
902
903
0
  x->prev_segment_id = segment_id;
904
0
}
905
906
0
void av1_frame_init_quantizer(AV1_COMP *cpi) {
907
0
  MACROBLOCK *const x = &cpi->td.mb;
908
0
  MACROBLOCKD *const xd = &x->e_mbd;
909
0
  x->prev_segment_id = -1;
910
0
  av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 1);
911
0
}
912
913
0
static int adjust_hdr_cb_deltaq(int base_qindex) {
914
0
  double baseQp = base_qindex / QP_SCALE_FACTOR;
915
0
  const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET;
916
0
  const double dcbQP = CHROMA_CB_QP_SCALE * chromaQp * QP_SCALE_FACTOR;
917
0
  int dqpCb = (int)(dcbQP + (dcbQP < 0 ? -0.5 : 0.5));
918
0
  dqpCb = AOMMIN(0, dqpCb);
919
0
  dqpCb = (int)CLIP(dqpCb, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR);
920
0
  return dqpCb;
921
0
}
922
923
0
static int adjust_hdr_cr_deltaq(int base_qindex) {
924
0
  double baseQp = base_qindex / QP_SCALE_FACTOR;
925
0
  const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET;
926
0
  const double dcrQP = CHROMA_CR_QP_SCALE * chromaQp * QP_SCALE_FACTOR;
927
0
  int dqpCr = (int)(dcrQP + (dcrQP < 0 ? -0.5 : 0.5));
928
0
  dqpCr = AOMMIN(0, dqpCr);
929
0
  dqpCr = (int)CLIP(dqpCr, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR);
930
0
  return dqpCr;
931
0
}
932
933
void av1_set_quantizer(AV1_COMMON *const cm, int min_qmlevel, int max_qmlevel,
934
                       int q, int enable_chroma_deltaq, int enable_hdr_deltaq,
935
0
                       bool is_allintra, aom_tune_metric tuning) {
936
  // quantizer has to be reinitialized with av1_init_quantizer() if any
937
  // delta_q changes.
938
0
  CommonQuantParams *quant_params = &cm->quant_params;
939
0
  quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
940
0
  quant_params->y_dc_delta_q = 0;
941
942
  // Disable deltaq in lossless mode.
943
0
  if (enable_chroma_deltaq && q) {
944
0
    if (tuning == AOM_TUNE_IQ || tuning == AOM_TUNE_SSIMULACRA2) {
945
0
      int chroma_dc_delta_q = 0;
946
0
      int chroma_ac_delta_q = 0;
947
948
0
      if (cm->seq_params->subsampling_x == 1 &&
949
0
          cm->seq_params->subsampling_y == 1) {
950
        // 4:2:0 subsampling: Constant chroma delta_q decrease (i.e. improved
951
        // chroma quality relative to luma) with gradual ramp-down for very low
952
        // qindexes.
953
        // Lowering chroma delta_q by 16 was found to improve SSIMULACRA 2
954
        // BD-Rate by 1.5-2% on Daala's subset1, as well as reducing chroma
955
        // artifacts (smudging, discoloration) during subjective quality
956
        // evaluations.
957
        // The ramp-down of chroma increase was determined by generating the
958
        // convex hull of SSIMULACRA 2 scores (for all boosts from 0-16), and
959
        // finding a linear equation that fits the convex hull.
960
        // For the SSIMULACRA 2 tune only: a convex hull of SSIMULACRA 2 scores
961
        // (mean, 10th percentile) was generated by decreasing chroma delta_q
962
        // by 3 different values (16, 20 and 24). 20 was selected as it had the
963
        // best 10th percentile performance.
964
0
        int offset = (tuning == AOM_TUNE_SSIMULACRA2) ? 20 : 16;
965
0
        chroma_dc_delta_q =
966
0
            -clamp((quant_params->base_qindex / 2) - 14, 0, offset);
967
0
        chroma_ac_delta_q = chroma_dc_delta_q;
968
0
      } else if (cm->seq_params->subsampling_x == 1 &&
969
0
                 cm->seq_params->subsampling_y == 0) {
970
        // 4:2:2 subsampling: Constant chroma AC delta_q increase (i.e. improved
971
        // luma quality relative to chroma) with gradual ramp-down for very low
972
        // qindexes.
973
        // SSIMULACRA 2 appears to have some issues correctly scoring 4:2:2
974
        // material. Solely optimizing for maximum scores suggests a chroma AC
975
        // delta_q of 12 is the most efficient. However, visual inspection on
976
        // difficult-to-encode material resulted in chroma quality degrading too
977
        // much relative to luma, and chroma channels ending up being too small
978
        // compared to equivalent 4:4:4 or 4:2:0 encodes.
979
        // A chroma AC delta_q of 6 was selected because encoded chroma channels
980
        // have a much closer size to 4:4:4 and 4:2:0 encodes, and have more
981
        // favorable visual quality characteristics.
982
        // The ramp-down of chroma decrease was put into place to match 4:2:0
983
        // and 4:4:4 behavior. There were no special considerations on
984
        // SSIMULACRA 2 scores.
985
0
        chroma_dc_delta_q = 0;
986
0
        chroma_ac_delta_q = clamp((quant_params->base_qindex / 2), 0, 6);
987
0
      } else if (cm->seq_params->subsampling_x == 0 &&
988
0
                 cm->seq_params->subsampling_y == 0) {
989
        // 4:4:4 subsampling: Constant chroma AC delta_q increase (i.e. improved
990
        // luma quality relative to chroma) with gradual ramp-down for very low
991
        // qindexes.
992
        // Raising chroma AC delta_q by 24 was found to improve SSIMULACRA 2
993
        // BD-Rate by 2.5-3% on Daala's subset1, as well as providing a more
994
        // balanced bit allocation between the (relatively-starved) luma and
995
        // chroma channels.
996
        // Raising chroma DC delta_q appears to be harmful, both for SSIMULACRA
997
        // 2 scores and subjective quality (harshens blocking artifacts).
998
        // The ramp-down of chroma decrease was put into place so (lossy) QP 0
999
        // encodes still score within 0.1 SSIMULACRA 2 points of the equivalent
1000
        // with no chroma delta_q (with a small efficiency improvement), while
1001
        // encodes in the SSIMULACRA 2 <=90 range yield full benefits from this
1002
        // adjustment.
1003
0
        chroma_dc_delta_q = 0;
1004
0
        chroma_ac_delta_q = clamp((quant_params->base_qindex / 2), 0, 24);
1005
0
      }
1006
1007
      // TODO: bug https://crbug.com/aomedia/375221136 - find chroma_delta_q
1008
      // values for 4:2:2 subsampling mode.
1009
0
      quant_params->u_dc_delta_q = chroma_dc_delta_q;
1010
0
      quant_params->u_ac_delta_q = chroma_ac_delta_q;
1011
0
      quant_params->v_dc_delta_q = chroma_dc_delta_q;
1012
0
      quant_params->v_ac_delta_q = chroma_ac_delta_q;
1013
0
    } else {
1014
      // TODO(aomedia:2717): need to design better delta
1015
0
      quant_params->u_dc_delta_q = 2;
1016
0
      quant_params->u_ac_delta_q = 2;
1017
0
      quant_params->v_dc_delta_q = 2;
1018
0
      quant_params->v_ac_delta_q = 2;
1019
0
    }
1020
0
  } else {
1021
0
    quant_params->u_dc_delta_q = 0;
1022
0
    quant_params->u_ac_delta_q = 0;
1023
0
    quant_params->v_dc_delta_q = 0;
1024
0
    quant_params->v_ac_delta_q = 0;
1025
0
  }
1026
1027
  // following section 8.3.2 in T-REC-H.Sup15 document
1028
  // to apply to AV1 qindex in the range of [0, 255]
1029
0
  if (enable_hdr_deltaq && q) {
1030
0
    int dqpCb = adjust_hdr_cb_deltaq(quant_params->base_qindex);
1031
0
    int dqpCr = adjust_hdr_cr_deltaq(quant_params->base_qindex);
1032
0
    quant_params->u_dc_delta_q = quant_params->u_ac_delta_q = dqpCb;
1033
0
    quant_params->v_dc_delta_q = quant_params->v_ac_delta_q = dqpCr;
1034
0
    if (dqpCb != dqpCr) {
1035
0
      cm->seq_params->separate_uv_delta_q = 1;
1036
0
    }
1037
0
  }
1038
1039
  // Select the best luma and chroma QM formulas based on encoding mode and
1040
  // tuning
1041
0
  int (*get_luma_qmlevel)(int, int, int);
1042
0
  int (*get_chroma_qmlevel)(int, int, int);
1043
1044
0
  if (tuning == AOM_TUNE_IQ || tuning == AOM_TUNE_SSIMULACRA2) {
1045
0
    if (tuning == AOM_TUNE_SSIMULACRA2) {
1046
      // Use luma QM formula specifically tailored for tune SSIMULACRA2
1047
0
      get_luma_qmlevel = aom_get_qmlevel_luma_ssimulacra2;
1048
0
    } else {
1049
0
      get_luma_qmlevel = aom_get_qmlevel_allintra;
1050
0
    }
1051
1052
0
    if (cm->seq_params->subsampling_x == 0 &&
1053
0
        cm->seq_params->subsampling_y == 0) {
1054
      // 4:4:4 subsampling mode has 4x the number of chroma coefficients
1055
      // compared to 4:2:0 (2x on each dimension). This means the encoder
1056
      // should use lower chroma QM levels that more closely match the scaling
1057
      // of an equivalent 4:2:0 chroma QM.
1058
0
      get_chroma_qmlevel = aom_get_qmlevel_444_chroma;
1059
0
    } else {
1060
      // For all other chroma subsampling modes, use the all intra QM formula
1061
0
      get_chroma_qmlevel = aom_get_qmlevel_allintra;
1062
0
    }
1063
0
  } else if (is_allintra) {
1064
0
    get_luma_qmlevel = aom_get_qmlevel_allintra;
1065
0
    get_chroma_qmlevel = aom_get_qmlevel_allintra;
1066
0
  } else {
1067
0
    get_luma_qmlevel = aom_get_qmlevel;
1068
0
    get_chroma_qmlevel = aom_get_qmlevel;
1069
0
  }
1070
1071
0
  quant_params->qmatrix_level_y =
1072
0
      get_luma_qmlevel(quant_params->base_qindex, min_qmlevel, max_qmlevel);
1073
0
  quant_params->qmatrix_level_u =
1074
0
      get_chroma_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q,
1075
0
                         min_qmlevel, max_qmlevel);
1076
1077
0
  if (cm->seq_params->separate_uv_delta_q) {
1078
0
    quant_params->qmatrix_level_v = get_chroma_qmlevel(
1079
0
        quant_params->base_qindex + quant_params->v_ac_delta_q, min_qmlevel,
1080
0
        max_qmlevel);
1081
0
  } else {
1082
0
    quant_params->qmatrix_level_v = quant_params->qmatrix_level_u;
1083
0
  }
1084
0
}
1085
1086
// Table that converts 0-63 Q-range values passed in outside to the Qindex
1087
// range used internally.
1088
static const int quantizer_to_qindex[] = {
1089
  0,   4,   8,   12,  16,  20,  24,  28,  32,  36,  40,  44,  48,
1090
  52,  56,  60,  64,  68,  72,  76,  80,  84,  88,  92,  96,  100,
1091
  104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
1092
  156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
1093
  208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
1094
};
1095
1096
0
int av1_quantizer_to_qindex(int quantizer) {
1097
0
  return quantizer_to_qindex[quantizer];
1098
0
}
1099
1100
0
int av1_qindex_to_quantizer(int qindex) {
1101
0
  int quantizer;
1102
1103
0
  for (quantizer = 0; quantizer < 64; ++quantizer)
1104
0
    if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
1105
1106
0
  return 63;
1107
0
}