Coverage Report

Created: 2025-06-22 08:04

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