Coverage Report

Created: 2026-09-14 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/full_loop.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
4
*
5
* This source code is subject to the terms of the BSD 3-Clause Clear License and
6
* the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear License
7
* was not distributed with this source code in the LICENSE file, you can
8
* obtain it at https://www.aomedia.org/license. If the Alliance for Open
9
* Media Patent License 1.0 was not distributed with this source code in the
10
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
11
*/
12
13
#include "definitions.h"
14
#include "full_loop.h"
15
#include "pcs.h"
16
#include "rd_cost.h"
17
#include "aom_dsp_rtcd.h"
18
#include "sequence_control_set.h"
19
#include "utility.h"
20
#include "ac_bias.h"
21
22
const int av1_get_tx_scale_tab[TX_SIZES_ALL] = {0, 0, 0, 1, 2, 0, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0, 1, 1};
23
24
void     svt_aom_residual_kernel(uint8_t* input, uint32_t input_offset, uint32_t input_stride, uint8_t* pred,
25
                                 uint32_t pred_offset, uint32_t pred_stride, int16_t* residual, uint32_t residual_offset,
26
                                 uint32_t residual_stride, bool hbd, uint32_t area_width, uint32_t area_height);
27
uint64_t svt_spatial_full_distortion_ssim_kernel(uint8_t* input, uint32_t input_offset, uint32_t input_stride,
28
                                                 uint8_t* recon, int32_t recon_offset, uint32_t recon_stride,
29
                                                 uint32_t area_width, uint32_t area_height, bool hbd, double ac_bias);
30
31
void svt_aom_quantize_b_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
32
                          const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
33
                          TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr, uint16_t* eob_ptr,
34
                          const int16_t* scan, const int16_t* iscan, const QmVal* qm_ptr, const QmVal* iqm_ptr,
35
1.03M
                          const int32_t log_scale) {
36
1.03M
    const int32_t zbins[2]  = {ROUND_POWER_OF_TWO(zbin_ptr[0], log_scale), ROUND_POWER_OF_TWO(zbin_ptr[1], log_scale)};
37
1.03M
    const int32_t nzbins[2] = {zbins[0] * -1, zbins[1] * -1};
38
1.03M
    intptr_t      non_zero_count = n_coeffs, eob = -1;
39
1.03M
    (void)iscan;
40
41
1.03M
    memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
42
1.03M
    memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
43
44
    // Pre-scan pass
45
28.0M
    for (intptr_t i = n_coeffs - 1; i >= 0; i--) {
46
27.0M
        const int32_t rc    = scan[i];
47
27.0M
        const QmVal   wt    = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
48
27.0M
        const int32_t coeff = coeff_ptr[rc] * wt;
49
50
27.0M
        if (coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS)) && coeff > (nzbins[rc != 0] * (1 << AOM_QM_BITS))) {
51
26.9M
            non_zero_count--;
52
26.9M
        } else {
53
69.6k
            break;
54
69.6k
        }
55
27.0M
    }
56
57
    // Quantization pass: All coefficients with index >= zero_flag are
58
    // skippable. Note: zero_flag can be zero.
59
1.04M
    for (intptr_t i = 0; i < non_zero_count; i++) {
60
12.4k
        const int32_t rc         = scan[i];
61
12.4k
        const int32_t coeff      = coeff_ptr[rc];
62
12.4k
        const int     coeff_sign = coeff < 0 ? -1 : 0;
63
12.4k
        const int32_t abs_coeff  = (coeff ^ coeff_sign) - coeff_sign;
64
65
12.4k
        const QmVal wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
66
12.4k
        if (abs_coeff * wt >= (zbins[rc != 0] << AOM_QM_BITS)) {
67
12.4k
            int64_t tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale), INT16_MIN, INT16_MAX);
68
12.4k
            tmp *= wt;
69
12.4k
            int32_t tmp32         = (int32_t)(((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * quant_shift_ptr[rc != 0]) >>
70
12.4k
                                      (16 - log_scale + AOM_QM_BITS)); // quantization
71
12.4k
            qcoeff_ptr[rc]        = (tmp32 ^ coeff_sign) - coeff_sign;
72
12.4k
            const int32_t iwt     = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
73
12.4k
            const int32_t dequant = (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
74
12.4k
            const TranLow abs_dqcoeff = (tmp32 * dequant) >> log_scale;
75
12.4k
            dqcoeff_ptr[rc]           = (TranLow)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
76
77
12.4k
            if (tmp32) {
78
12.4k
                eob = i;
79
12.4k
            }
80
12.4k
        }
81
12.4k
    }
82
1.03M
    *eob_ptr = (uint16_t)(eob + 1);
83
1.03M
}
84
85
void svt_aom_highbd_quantize_b_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
86
                                 const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
87
                                 TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr,
88
                                 uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan, const QmVal* qm_ptr,
89
0
                                 const QmVal* iqm_ptr, const int32_t log_scale) {
90
0
    intptr_t eob = -1;
91
0
    (void)iscan;
92
93
0
    memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
94
0
    memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
95
96
0
    const int32_t zbins[2]  = {ROUND_POWER_OF_TWO(zbin_ptr[0], log_scale), ROUND_POWER_OF_TWO(zbin_ptr[1], log_scale)};
97
0
    const int32_t nzbins[2] = {zbins[0] * -1, zbins[1] * -1};
98
0
    intptr_t      idx_arr[4096];
99
0
    int           idx = 0;
100
    // Pre-scan pass
101
0
    for (intptr_t i = 0; i < n_coeffs; i++) {
102
0
        const int32_t rc    = scan[i];
103
0
        const QmVal   wt    = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
104
0
        const int32_t coeff = coeff_ptr[rc] * wt;
105
106
        // If the coefficient is out of the base ZBIN range, keep it for
107
        // quantization.
108
0
        if (coeff >= (zbins[rc != 0] * (1 << AOM_QM_BITS)) || coeff <= (nzbins[rc != 0] * (1 << AOM_QM_BITS))) {
109
0
            idx_arr[idx++] = i;
110
0
        }
111
0
    }
112
113
    // Quantization pass: only process the coefficients selected in
114
    // pre-scan pass. Note: idx can be zero.
115
0
    for (int i = 0; i < idx; i++) {
116
0
        const int32_t rc          = scan[idx_arr[i]];
117
0
        const int32_t coeff       = coeff_ptr[rc];
118
0
        const int     coeff_sign  = coeff < 0 ? -1 : 0;
119
0
        const QmVal   wt          = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
120
0
        const QmVal   iwt         = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
121
0
        const int32_t abs_coeff   = (coeff ^ coeff_sign) - coeff_sign;
122
0
        const int64_t tmp1        = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
123
0
        const int64_t tmpw        = tmp1 * wt;
124
0
        const int64_t tmp2        = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
125
0
        const int32_t abs_qcoeff  = (int32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> (16 - log_scale + AOM_QM_BITS));
126
0
        qcoeff_ptr[rc]            = (TranLow)((abs_qcoeff ^ coeff_sign) - coeff_sign);
127
0
        int32_t       dequant     = (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
128
0
        const TranLow abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
129
0
        dqcoeff_ptr[rc]           = (TranLow)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
130
0
        if (abs_qcoeff) {
131
0
            eob = idx_arr[i];
132
0
        }
133
0
    }
134
135
0
    *eob_ptr = (uint16_t)(eob + 1);
136
0
}
137
138
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
139
void svt_av1_highbd_quantize_b_facade(const TranLow* coeff_ptr, intptr_t n_coeffs, const MacroblockPlane* p,
140
                                      TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, uint16_t* eob_ptr, const ScanOrder* sc,
141
0
                                      const QuantParam* qparam) {
142
0
    const QmVal* qm_ptr  = qparam->qmatrix;
143
0
    const QmVal* iqm_ptr = qparam->iqmatrix;
144
0
    if (qm_ptr || iqm_ptr) {
145
0
        svt_av1_highbd_quantize_b_qm(coeff_ptr,
146
0
                                     n_coeffs,
147
0
                                     p->zbin_qtx,
148
0
                                     p->round_qtx,
149
0
                                     p->quant_qtx,
150
0
                                     p->quant_shift_qtx,
151
0
                                     qcoeff_ptr,
152
0
                                     dqcoeff_ptr,
153
0
                                     p->dequant_qtx,
154
0
                                     eob_ptr,
155
0
                                     sc->scan,
156
0
                                     sc->iscan,
157
0
                                     qm_ptr,
158
0
                                     iqm_ptr,
159
0
                                     qparam->log_scale);
160
0
    } else {
161
0
        svt_aom_highbd_quantize_b(coeff_ptr,
162
0
                                  n_coeffs,
163
0
                                  p->zbin_qtx,
164
0
                                  p->round_qtx,
165
0
                                  p->quant_qtx,
166
0
                                  p->quant_shift_qtx,
167
0
                                  qcoeff_ptr,
168
0
                                  dqcoeff_ptr,
169
0
                                  p->dequant_qtx,
170
0
                                  eob_ptr,
171
0
                                  sc->scan,
172
0
                                  sc->iscan,
173
0
                                  NULL,
174
0
                                  NULL,
175
0
                                  qparam->log_scale);
176
0
    }
177
0
    assert(qparam->log_scale <= 2);
178
0
}
179
#endif
180
181
static void av1_quantize_b_facade_ii(const TranLow* coeff_ptr, intptr_t n_coeffs, const MacroblockPlane* p,
182
                                     TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, uint16_t* eob_ptr, const ScanOrder* sc,
183
880k
                                     const QuantParam* qparam) {
184
880k
    const QmVal* qm_ptr  = qparam->qmatrix;
185
880k
    const QmVal* iqm_ptr = qparam->iqmatrix;
186
880k
    if (qm_ptr || iqm_ptr) {
187
0
        svt_av1_quantize_b_qm(coeff_ptr,
188
0
                              n_coeffs,
189
0
                              p->zbin_qtx,
190
0
                              p->round_qtx,
191
0
                              p->quant_qtx,
192
0
                              p->quant_shift_qtx,
193
0
                              qcoeff_ptr,
194
0
                              dqcoeff_ptr,
195
0
                              p->dequant_qtx,
196
0
                              eob_ptr,
197
0
                              sc->scan,
198
0
                              sc->iscan,
199
0
                              qm_ptr,
200
0
                              iqm_ptr,
201
0
                              qparam->log_scale);
202
880k
    } else {
203
880k
        svt_aom_quantize_b(coeff_ptr,
204
880k
                           n_coeffs,
205
880k
                           p->zbin_qtx,
206
880k
                           p->round_qtx,
207
880k
                           p->quant_qtx,
208
880k
                           p->quant_shift_qtx,
209
880k
                           qcoeff_ptr,
210
880k
                           dqcoeff_ptr,
211
880k
                           p->dequant_qtx,
212
880k
                           eob_ptr,
213
880k
                           sc->scan,
214
880k
                           sc->iscan,
215
880k
                           NULL,
216
880k
                           NULL,
217
880k
                           qparam->log_scale);
218
880k
    }
219
880k
    assert(qparam->log_scale <= 2);
220
880k
}
221
222
static void quantize_fp_helper_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
223
                                 const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
224
                                 TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr,
225
                                 uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan, const QmVal* qm_ptr,
226
21.7k
                                 const QmVal* iqm_ptr, int log_scale) {
227
21.7k
    int       i, eob = -1;
228
21.7k
    const int rounding[2] = {ROUND_POWER_OF_TWO(round_ptr[0], log_scale), ROUND_POWER_OF_TWO(round_ptr[1], log_scale)};
229
21.7k
    (void)zbin_ptr;
230
21.7k
    (void)quant_shift_ptr;
231
21.7k
    (void)iscan;
232
233
21.7k
    memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
234
21.7k
    memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
235
236
21.7k
    if (qm_ptr == NULL && iqm_ptr == NULL) {
237
9.53M
        for (i = 0; i < n_coeffs; i++) {
238
9.51M
            const int     rc         = scan[i];
239
9.51M
            const int32_t thresh     = (int32_t)(dequant_ptr[rc != 0]);
240
9.51M
            const int     coeff      = coeff_ptr[rc];
241
9.51M
            const int     coeff_sign = coeff < 0 ? -1 : 0;
242
9.51M
            int64_t       abs_coeff  = (coeff ^ coeff_sign) - coeff_sign;
243
9.51M
            int           tmp32      = 0;
244
9.51M
            if ((abs_coeff << (1 + log_scale)) >= thresh) {
245
10.2k
                abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX);
246
10.2k
                tmp32     = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale));
247
10.2k
                if (tmp32) {
248
10.1k
                    qcoeff_ptr[rc]            = (tmp32 ^ coeff_sign) - coeff_sign;
249
10.1k
                    const TranLow abs_dqcoeff = (tmp32 * dequant_ptr[rc != 0]) >> log_scale;
250
10.1k
                    dqcoeff_ptr[rc]           = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
251
10.1k
                }
252
10.2k
            }
253
9.51M
            if (tmp32) {
254
10.1k
                eob = i;
255
10.1k
            }
256
9.51M
        }
257
21.7k
    } else {
258
        // Quantization pass: All coefficients with index >= zero_flag are
259
        // skippable. Note: zero_flag can be zero.
260
2
        for (i = 0; i < n_coeffs; i++) {
261
0
            const int   rc         = scan[i];
262
0
            const int   coeff      = coeff_ptr[rc];
263
0
            const QmVal wt         = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS);
264
0
            const QmVal iwt        = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
265
0
            const int   dequant    = (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
266
0
            const int   coeff_sign = coeff < 0 ? -1 : 0;
267
0
            int64_t     abs_coeff  = (coeff ^ coeff_sign) - coeff_sign;
268
0
            int         tmp32      = 0;
269
0
            if (abs_coeff * wt >= (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
270
0
                abs_coeff += rounding[rc != 0];
271
0
                abs_coeff      = clamp64(abs_coeff, INT16_MIN, INT16_MAX);
272
0
                tmp32          = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >> (16 - log_scale + AOM_QM_BITS));
273
0
                qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
274
0
                const TranLow abs_dqcoeff = (tmp32 * dequant) >> log_scale;
275
0
                dqcoeff_ptr[rc]           = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
276
0
            }
277
278
0
            if (tmp32) {
279
0
                eob = i;
280
0
            }
281
0
        }
282
2
    }
283
21.7k
    *eob_ptr = eob + 1;
284
21.7k
}
285
286
void svt_av1_quantize_fp_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
287
                           const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
288
                           TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr, uint16_t* eob_ptr,
289
13.4k
                           const int16_t* scan, const int16_t* iscan) {
290
13.4k
    quantize_fp_helper_c(coeff_ptr,
291
13.4k
                         n_coeffs,
292
13.4k
                         zbin_ptr,
293
13.4k
                         round_ptr,
294
13.4k
                         quant_ptr,
295
13.4k
                         quant_shift_ptr,
296
13.4k
                         qcoeff_ptr,
297
13.4k
                         dqcoeff_ptr,
298
13.4k
                         dequant_ptr,
299
13.4k
                         eob_ptr,
300
13.4k
                         scan,
301
13.4k
                         iscan,
302
13.4k
                         NULL,
303
13.4k
                         NULL,
304
13.4k
                         0);
305
13.4k
}
306
307
void svt_av1_quantize_fp_qm_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
308
                              const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
309
                              TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr, uint16_t* eob_ptr,
310
                              const int16_t* scan, const int16_t* iscan, const QmVal* qm_ptr, const QmVal* iqm_ptr,
311
0
                              int16_t log_scale) {
312
0
    quantize_fp_helper_c(coeff_ptr,
313
0
                         n_coeffs,
314
0
                         zbin_ptr,
315
0
                         round_ptr,
316
0
                         quant_ptr,
317
0
                         quant_shift_ptr,
318
0
                         qcoeff_ptr,
319
0
                         dqcoeff_ptr,
320
0
                         dequant_ptr,
321
0
                         eob_ptr,
322
0
                         scan,
323
0
                         iscan,
324
0
                         qm_ptr,
325
0
                         iqm_ptr,
326
0
                         log_scale);
327
0
}
328
329
static void highbd_quantize_fp_helper_c(const TranLow* coeff_ptr, intptr_t count, const int16_t* zbin_ptr,
330
                                        const int16_t* round_ptr, const int16_t* quant_ptr,
331
                                        const int16_t* quant_shift_ptr, TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr,
332
                                        const int16_t* dequant_ptr, uint16_t* eob_ptr, const int16_t* scan,
333
                                        const int16_t* iscan, const QmVal* qm_ptr, const QmVal* iqm_ptr,
334
0
                                        int16_t log_scale) {
335
0
    int       i;
336
0
    int       eob   = -1;
337
0
    const int shift = 16 - log_scale;
338
0
    (void)zbin_ptr;
339
0
    (void)quant_shift_ptr;
340
0
    (void)iscan;
341
342
0
    if (qm_ptr || iqm_ptr) {
343
        // Quantization pass: All coefficients with index >= zero_flag are
344
        // skippable. Note: zero_flag can be zero.
345
0
        for (i = 0; i < count; i++) {
346
0
            const int     rc         = scan[i];
347
0
            const int     coeff      = coeff_ptr[rc];
348
0
            const QmVal   wt         = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
349
0
            const QmVal   iwt        = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
350
0
            const int     dequant    = (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
351
0
            const int     coeff_sign = coeff < 0 ? -1 : 0;
352
0
            const int64_t abs_coeff  = (coeff ^ coeff_sign) - coeff_sign;
353
0
            if (abs_coeff * wt >= (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
354
0
                const int64_t tmp         = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
355
0
                const int     abs_qcoeff  = (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
356
0
                qcoeff_ptr[rc]            = (TranLow)((abs_qcoeff ^ coeff_sign) - coeff_sign);
357
0
                const TranLow abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
358
0
                dqcoeff_ptr[rc]           = (TranLow)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
359
0
                if (abs_qcoeff) {
360
0
                    eob = i;
361
0
                }
362
0
            } else {
363
0
                qcoeff_ptr[rc]  = 0;
364
0
                dqcoeff_ptr[rc] = 0;
365
0
            }
366
0
        }
367
0
    } else {
368
0
        const int log_scaled_round_arr[2] = {
369
0
            ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
370
0
            ROUND_POWER_OF_TWO(round_ptr[1], log_scale),
371
0
        };
372
0
        for (i = 0; i < count; i++) {
373
0
            const int rc               = scan[i];
374
0
            const int coeff            = coeff_ptr[rc];
375
0
            const int rc01             = (rc != 0);
376
0
            const int coeff_sign       = coeff < 0 ? -1 : 0;
377
0
            const int abs_coeff        = (coeff ^ coeff_sign) - coeff_sign;
378
0
            const int log_scaled_round = log_scaled_round_arr[rc01];
379
0
            if ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) {
380
0
                const int     quant       = quant_ptr[rc01];
381
0
                const int     dequant     = dequant_ptr[rc01];
382
0
                const int64_t tmp         = (int64_t)abs_coeff + log_scaled_round;
383
0
                const int     abs_qcoeff  = (int)((tmp * quant) >> shift);
384
0
                qcoeff_ptr[rc]            = (TranLow)((abs_qcoeff ^ coeff_sign) - coeff_sign);
385
0
                const TranLow abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
386
0
                if (abs_qcoeff) {
387
0
                    eob = i;
388
0
                }
389
0
                dqcoeff_ptr[rc] = (TranLow)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
390
0
            } else {
391
0
                qcoeff_ptr[rc]  = 0;
392
0
                dqcoeff_ptr[rc] = 0;
393
0
            }
394
0
        }
395
0
    }
396
0
    *eob_ptr = eob + 1;
397
0
}
398
399
void svt_av1_highbd_quantize_fp_c(const TranLow* coeff_ptr, intptr_t count, const int16_t* zbin_ptr,
400
                                  const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
401
                                  TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr,
402
0
                                  uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan, int16_t log_scale) {
403
0
    highbd_quantize_fp_helper_c(coeff_ptr,
404
0
                                count,
405
0
                                zbin_ptr,
406
0
                                round_ptr,
407
0
                                quant_ptr,
408
0
                                quant_shift_ptr,
409
0
                                qcoeff_ptr,
410
0
                                dqcoeff_ptr,
411
0
                                dequant_ptr,
412
0
                                eob_ptr,
413
0
                                scan,
414
0
                                iscan,
415
0
                                NULL,
416
0
                                NULL,
417
0
                                log_scale);
418
0
}
419
420
void svt_av1_quantize_fp_32x32_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
421
                                 const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
422
                                 TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr,
423
5.73k
                                 uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan) {
424
5.73k
    quantize_fp_helper_c(coeff_ptr,
425
5.73k
                         n_coeffs,
426
5.73k
                         zbin_ptr,
427
5.73k
                         round_ptr,
428
5.73k
                         quant_ptr,
429
5.73k
                         quant_shift_ptr,
430
5.73k
                         qcoeff_ptr,
431
5.73k
                         dqcoeff_ptr,
432
5.73k
                         dequant_ptr,
433
5.73k
                         eob_ptr,
434
5.73k
                         scan,
435
5.73k
                         iscan,
436
5.73k
                         NULL,
437
5.73k
                         NULL,
438
5.73k
                         1);
439
5.73k
}
440
441
void svt_av1_quantize_fp_64x64_c(const TranLow* coeff_ptr, intptr_t n_coeffs, const int16_t* zbin_ptr,
442
                                 const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
443
                                 TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr,
444
2.56k
                                 uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan) {
445
2.56k
    quantize_fp_helper_c(coeff_ptr,
446
2.56k
                         n_coeffs,
447
2.56k
                         zbin_ptr,
448
2.56k
                         round_ptr,
449
2.56k
                         quant_ptr,
450
2.56k
                         quant_shift_ptr,
451
2.56k
                         qcoeff_ptr,
452
2.56k
                         dqcoeff_ptr,
453
2.56k
                         dequant_ptr,
454
2.56k
                         eob_ptr,
455
2.56k
                         scan,
456
2.56k
                         iscan,
457
2.56k
                         NULL,
458
2.56k
                         NULL,
459
2.56k
                         2);
460
2.56k
}
461
462
void svt_av1_quantize_fp_facade(const TranLow* coeff_ptr, intptr_t n_coeffs, const MacroblockPlane* p,
463
                                TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, uint16_t* eob_ptr, const ScanOrder* sc,
464
21.8k
                                const QuantParam* qparam) {
465
21.8k
    const QmVal* qm_ptr  = qparam->qmatrix;
466
21.8k
    const QmVal* iqm_ptr = qparam->iqmatrix;
467
468
21.8k
    if (qm_ptr || iqm_ptr) {
469
0
        svt_av1_quantize_fp_qm(coeff_ptr,
470
0
                               n_coeffs,
471
0
                               p->zbin_qtx,
472
0
                               p->round_fp_qtx,
473
0
                               p->quant_fp_qtx,
474
0
                               p->quant_shift_qtx,
475
0
                               qcoeff_ptr,
476
0
                               dqcoeff_ptr,
477
0
                               p->dequant_qtx,
478
0
                               eob_ptr,
479
0
                               sc->scan,
480
0
                               sc->iscan,
481
0
                               qm_ptr,
482
0
                               iqm_ptr,
483
0
                               qparam->log_scale);
484
21.8k
    } else {
485
21.8k
        switch (qparam->log_scale) {
486
13.4k
        case 0:
487
13.4k
            svt_av1_quantize_fp(coeff_ptr,
488
13.4k
                                n_coeffs,
489
13.4k
                                p->zbin_qtx,
490
13.4k
                                p->round_fp_qtx,
491
13.4k
                                p->quant_fp_qtx,
492
13.4k
                                p->quant_shift_qtx,
493
13.4k
                                qcoeff_ptr,
494
13.4k
                                dqcoeff_ptr,
495
13.4k
                                p->dequant_qtx,
496
13.4k
                                eob_ptr,
497
13.4k
                                sc->scan,
498
13.4k
                                sc->iscan);
499
13.4k
            break;
500
5.73k
        case 1:
501
5.73k
            svt_av1_quantize_fp_32x32(coeff_ptr,
502
5.73k
                                      n_coeffs,
503
5.73k
                                      p->zbin_qtx,
504
5.73k
                                      p->round_fp_qtx,
505
5.73k
                                      p->quant_fp_qtx,
506
5.73k
                                      p->quant_shift_qtx,
507
5.73k
                                      qcoeff_ptr,
508
5.73k
                                      dqcoeff_ptr,
509
5.73k
                                      p->dequant_qtx,
510
5.73k
                                      eob_ptr,
511
5.73k
                                      sc->scan,
512
5.73k
                                      sc->iscan);
513
5.73k
            break;
514
2.56k
        case 2:
515
2.56k
            svt_av1_quantize_fp_64x64(coeff_ptr,
516
2.56k
                                      n_coeffs,
517
2.56k
                                      p->zbin_qtx,
518
2.56k
                                      p->round_fp_qtx,
519
2.56k
                                      p->quant_fp_qtx,
520
2.56k
                                      p->quant_shift_qtx,
521
2.56k
                                      qcoeff_ptr,
522
2.56k
                                      dqcoeff_ptr,
523
2.56k
                                      p->dequant_qtx,
524
2.56k
                                      eob_ptr,
525
2.56k
                                      sc->scan,
526
2.56k
                                      sc->iscan);
527
2.56k
            break;
528
0
        default:
529
0
            assert(0);
530
21.8k
        }
531
21.8k
    }
532
21.8k
}
533
534
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
535
void svt_av1_highbd_quantize_fp_facade(const TranLow* coeff_ptr, intptr_t n_coeffs, const MacroblockPlane* p,
536
                                       TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, uint16_t* eob_ptr,
537
0
                                       const ScanOrder* sc, const QuantParam* qparam) {
538
0
    const QmVal* qm_ptr  = qparam->qmatrix;
539
0
    const QmVal* iqm_ptr = qparam->iqmatrix;
540
0
    if (qm_ptr != NULL && iqm_ptr != NULL) {
541
0
        svt_av1_highbd_quantize_fp_qm(coeff_ptr,
542
0
                                      n_coeffs,
543
0
                                      p->zbin_qtx,
544
0
                                      p->round_fp_qtx,
545
0
                                      p->quant_fp_qtx,
546
0
                                      p->quant_shift_qtx,
547
0
                                      qcoeff_ptr,
548
0
                                      dqcoeff_ptr,
549
0
                                      p->dequant_qtx,
550
0
                                      eob_ptr,
551
0
                                      sc->scan,
552
0
                                      sc->iscan,
553
0
                                      qm_ptr,
554
0
                                      iqm_ptr,
555
0
                                      qparam->log_scale);
556
0
    } else {
557
0
        svt_av1_highbd_quantize_fp(coeff_ptr,
558
0
                                   n_coeffs,
559
0
                                   p->zbin_qtx,
560
0
                                   p->round_fp_qtx,
561
0
                                   p->quant_fp_qtx,
562
0
                                   p->quant_shift_qtx,
563
0
                                   qcoeff_ptr,
564
0
                                   dqcoeff_ptr,
565
0
                                   p->dequant_qtx,
566
0
                                   eob_ptr,
567
0
                                   sc->scan,
568
0
                                   sc->iscan,
569
0
                                   qparam->log_scale);
570
0
    }
571
0
}
572
#endif
573
574
void svt_av1_highbd_quantize_fp_qm_c(const TranLow* coeff_ptr, intptr_t count, const int16_t* zbin_ptr,
575
                                     const int16_t* round_ptr, const int16_t* quant_ptr, const int16_t* quant_shift_ptr,
576
                                     TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, const int16_t* dequant_ptr,
577
                                     uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan, const QmVal* qm_ptr,
578
0
                                     const QmVal* iqm_ptr, int16_t log_scale) {
579
0
    highbd_quantize_fp_helper_c(coeff_ptr,
580
0
                                count,
581
0
                                zbin_ptr,
582
0
                                round_ptr,
583
0
                                quant_ptr,
584
0
                                quant_shift_ptr,
585
0
                                qcoeff_ptr,
586
0
                                dqcoeff_ptr,
587
0
                                dequant_ptr,
588
0
                                eob_ptr,
589
0
                                scan,
590
0
                                iscan,
591
0
                                qm_ptr,
592
0
                                iqm_ptr,
593
0
                                log_scale);
594
0
}
595
596
static INLINE int get_lower_levels_ctx_general(int is_last, int scan_idx, int bwl, int height, const uint8_t* levels,
597
8.40k
                                               int coeff_idx, TxSize tx_size, TxClass tx_class) {
598
8.40k
    if (is_last) {
599
8.40k
        if (scan_idx == 0) {
600
8.40k
            return 0;
601
8.40k
        }
602
18.4E
        if (scan_idx <= (height << bwl) >> 3) {
603
0
            return 1;
604
0
        }
605
18.4E
        if (scan_idx <= (height << bwl) >> 2) {
606
0
            return 2;
607
0
        }
608
18.4E
        return 3;
609
18.4E
    }
610
18.4E
    return get_lower_levels_ctx(levels, coeff_idx, bwl, tx_size, tx_class);
611
8.40k
}
612
613
16.4k
static INLINE int32_t get_golomb_cost(int32_t abs_qc) {
614
16.4k
    if (abs_qc >= 1 + NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
615
14.8k
        const int32_t r      = abs_qc - COEFF_BASE_RANGE - NUM_BASE_LEVELS;
616
14.8k
        const int32_t length = get_msb(r) + 1;
617
14.8k
        return av1_cost_literal(2 * length - 1);
618
14.8k
    }
619
1.57k
    return 0;
620
16.4k
}
621
622
16.4k
static INLINE int get_br_cost(TranLow level, const int* coeff_lps) {
623
16.4k
    const int base_range = AOMMIN(level - 1 - NUM_BASE_LEVELS, COEFF_BASE_RANGE);
624
16.4k
    return coeff_lps[base_range] + get_golomb_cost(level);
625
16.4k
}
626
627
static INLINE int get_coeff_cost_general(int is_last, int ci, TranLow abs_qc, int sign, int coeff_ctx, int dc_sign_ctx,
628
                                         const LvMapCoeffCost* txb_costs, int bwl, TxClass tx_class,
629
16.8k
                                         const uint8_t* levels) {
630
16.8k
    int cost = 0;
631
16.8k
    if (is_last) {
632
16.8k
        cost += txb_costs->base_eob_cost[coeff_ctx][AOMMIN(abs_qc, 3) - 1];
633
16.8k
    } else {
634
0
        cost += txb_costs->base_cost[coeff_ctx][AOMMIN(abs_qc, 3)];
635
0
    }
636
    // All callers invoke this only on the non-zero coeff path, so abs_qc != 0 always.
637
16.8k
    if (ci == 0) {
638
16.8k
        cost += txb_costs->dc_sign_cost[dc_sign_ctx][sign];
639
16.8k
    } else {
640
0
        cost += av1_cost_literal(1);
641
0
    }
642
16.8k
    if (abs_qc > NUM_BASE_LEVELS) {
643
16.4k
        int br_ctx;
644
16.4k
        if (is_last) {
645
16.4k
            br_ctx = get_br_ctx_eob(ci, bwl, tx_class);
646
16.4k
        } else {
647
0
            br_ctx = get_br_ctx(levels, ci, bwl, tx_class);
648
0
        }
649
16.4k
        cost += get_br_cost(abs_qc, txb_costs->lps_cost[br_ctx]);
650
16.4k
    }
651
16.8k
    return cost;
652
16.8k
}
653
654
28.7k
static INLINE int64_t get_coeff_dist(TranLow tcoeff, TranLow dqcoeff, int shift) {
655
28.7k
    return SQR(((int64_t)tcoeff - dqcoeff) * (int64_t)(1lu << shift));
656
28.7k
}
657
658
8.40k
static INLINE void get_qc_dqc_low(TranLow abs_qc, int sign, int dqv, int shift, TranLow* qc_low, TranLow* dqc_low) {
659
8.40k
    TranLow abs_qc_low = abs_qc - 1;
660
8.40k
    *qc_low            = (-sign ^ abs_qc_low) + sign;
661
8.40k
    assert((sign ? -abs_qc_low : abs_qc_low) == *qc_low);
662
8.40k
    TranLow abs_dqc_low = (abs_qc_low * dqv) >> shift;
663
8.40k
    *dqc_low            = (-sign ^ abs_dqc_low) + sign;
664
8.40k
    assert((sign ? -abs_dqc_low : abs_dqc_low) == *dqc_low);
665
8.40k
}
666
667
static const int golomb_bits_cost[32] = {0,       512,     512 * 3, 512 * 3, 512 * 5, 512 * 5, 512 * 5, 512 * 5,
668
                                         512 * 7, 512 * 7, 512 * 7, 512 * 7, 512 * 7, 512 * 7, 512 * 7, 512 * 7,
669
                                         512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9,
670
                                         512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9, 512 * 9};
671
static const int golomb_cost_diff[32] = {0,       512, 512 * 2, 0, 512 * 2, 0, 0, 0, 512 * 2, 0, 0, 0, 0, 0, 0, 0,
672
                                         512 * 2, 0,   0,       0, 0,       0, 0, 0, 0,       0, 0, 0, 0, 0, 0, 0};
673
674
0
static INLINE int get_br_cost_with_diff(TranLow level, const int* coeff_lps, int* diff) {
675
0
    const int base_range  = AOMMIN(level - 1 - NUM_BASE_LEVELS, COEFF_BASE_RANGE);
676
0
    int       golomb_bits = 0;
677
0
    if (level <= COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS) {
678
0
        *diff += coeff_lps[base_range + COEFF_BASE_RANGE + 1];
679
0
    }
680
681
0
    if (level >= COEFF_BASE_RANGE + 1 + NUM_BASE_LEVELS) {
682
0
        int r = level - COEFF_BASE_RANGE - NUM_BASE_LEVELS;
683
0
        if (r < 32) {
684
0
            golomb_bits = golomb_bits_cost[r];
685
0
            *diff += golomb_cost_diff[r];
686
0
        } else {
687
0
            golomb_bits = get_golomb_cost(level);
688
0
            *diff += (r & (r - 1)) == 0 ? 1024 : 0;
689
0
        }
690
0
    }
691
692
0
    return coeff_lps[base_range] + golomb_bits;
693
0
}
694
695
static AOM_FORCE_INLINE int get_two_coeff_cost_simple(int ci, TranLow abs_qc, int coeff_ctx,
696
                                                      const LvMapCoeffCost* txb_costs, int bwl, TxClass tx_class,
697
0
                                                      const uint8_t* levels, int* cost_low) {
698
    // this simple version assumes the coeff's scan_idx is not DC (scan_idx != 0)
699
    // and not the last (scan_idx != eob - 1)
700
0
    assert(ci > 0);
701
    //assert(abs_qc + 4 < 4);
702
0
    int cost = txb_costs->base_cost[coeff_ctx][AOMMIN(abs_qc, 3)];
703
0
    int diff = 0;
704
0
    if (abs_qc <= 3) {
705
0
        diff = txb_costs->base_cost[coeff_ctx][abs_qc + 4];
706
0
    }
707
    // Caller (update_coeff_simple) only invokes this with abs_qc != 0.
708
0
    cost += av1_cost_literal(1);
709
0
    if (abs_qc > NUM_BASE_LEVELS) {
710
0
        const int br_ctx      = get_br_ctx(levels, ci, bwl, tx_class);
711
0
        int       brcost_diff = 0;
712
0
        cost += get_br_cost_with_diff(abs_qc, txb_costs->lps_cost[br_ctx], &brcost_diff);
713
0
        diff += brcost_diff;
714
0
    }
715
0
    *cost_low = cost - diff;
716
717
0
    return cost;
718
0
}
719
720
static INLINE int get_coeff_cost_eob(int ci, TranLow abs_qc, int sign, int coeff_ctx, int dc_sign_ctx,
721
1.76k
                                     const LvMapCoeffCost* txb_costs, int bwl, TxClass tx_class) {
722
1.76k
    int cost = 0;
723
1.76k
    cost += txb_costs->base_eob_cost[coeff_ctx][AOMMIN(abs_qc, 3) - 1];
724
    // Callers only invoke this on the non-zero coeff path, so abs_qc != 0 always.
725
1.76k
    if (ci == 0) {
726
1.76k
        cost += txb_costs->dc_sign_cost[dc_sign_ctx][sign];
727
1.76k
    } else {
728
0
        cost += av1_cost_literal(1);
729
0
    }
730
1.76k
    if (abs_qc > NUM_BASE_LEVELS) {
731
0
        const int br_ctx = get_br_ctx_eob(ci, bwl, tx_class);
732
0
        cost += get_br_cost(abs_qc, txb_costs->lps_cost[br_ctx]);
733
0
    }
734
1.76k
    return cost;
735
1.76k
}
736
737
8.40k
static INLINE int get_dqv(const int16_t* dequant, int coeff_idx, const QmVal* iqm_ptr) {
738
8.40k
    int dqv = dequant[!!coeff_idx];
739
8.40k
    if (iqm_ptr != NULL) {
740
0
        dqv = ((iqm_ptr[coeff_idx] * dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
741
0
    }
742
8.40k
    return dqv;
743
8.40k
}
744
745
static AOM_FORCE_INLINE void update_coeff_eob(int* accu_rate, int64_t* accu_dist, uint16_t* eob, int* nz_num,
746
                                              int* nz_ci, int si, TxSize tx_size, TxClass tx_class, int bwl, int height,
747
                                              int dc_sign_ctx, int64_t rdmult, int shift, const int16_t* dequant,
748
                                              const int16_t* scan, const LvMapEobCost* txb_eob_costs,
749
                                              const LvMapCoeffCost* txb_costs, const TranLow* tcoeff, TranLow* qcoeff,
750
0
                                              TranLow* dqcoeff, uint8_t* levels, int sharpness, const QmVal* iqm_ptr) {
751
0
    assert(si != *eob - 1);
752
0
    const int     ci        = scan[si];
753
0
    const TranLow qc        = qcoeff[ci];
754
0
    const int     coeff_ctx = get_lower_levels_ctx(levels, ci, bwl, tx_size, tx_class);
755
0
    if (qc == 0) {
756
0
        *accu_rate += txb_costs->base_cost[coeff_ctx][0];
757
0
    } else {
758
0
        int           lower_level = 0;
759
0
        const TranLow abs_qc      = abs(qc);
760
0
        const TranLow tqc         = tcoeff[ci];
761
0
        const TranLow dqc         = dqcoeff[ci];
762
0
        const int     sign        = (qc < 0) ? 1 : 0;
763
0
        const int64_t dist0       = get_coeff_dist(tqc, 0, shift);
764
0
        int64_t       dist        = get_coeff_dist(tqc, dqc, shift) - dist0;
765
0
        int           rate        = get_coeff_cost_general(
766
0
            0, ci, abs_qc, sign, coeff_ctx, dc_sign_ctx, txb_costs, bwl, tx_class, levels);
767
0
        int64_t rd = RDCOST(rdmult, *accu_rate + rate, *accu_dist + dist);
768
769
0
        TranLow qc_low, dqc_low;
770
0
        TranLow abs_qc_low;
771
0
        int64_t dist_low, rd_low;
772
0
        int     rate_low;
773
0
        if (abs_qc == 1) {
774
0
            abs_qc_low = 0;
775
0
            dqc_low = qc_low = 0;
776
0
            dist_low         = 0;
777
0
            rate_low         = txb_costs->base_cost[coeff_ctx][0];
778
0
            rd_low           = RDCOST(rdmult, *accu_rate + rate_low, *accu_dist);
779
0
        } else {
780
0
            const int dqv = get_dqv(dequant, ci, iqm_ptr);
781
0
            get_qc_dqc_low(abs_qc, sign, dqv, shift, &qc_low, &dqc_low);
782
0
            abs_qc_low = abs_qc - 1;
783
0
            dist_low   = get_coeff_dist(tqc, dqc_low, shift) - dist0;
784
0
            rate_low   = get_coeff_cost_general(
785
0
                0, ci, abs_qc_low, sign, coeff_ctx, dc_sign_ctx, txb_costs, bwl, tx_class, levels);
786
0
            rd_low = RDCOST(rdmult, *accu_rate + rate_low, *accu_dist + dist_low);
787
0
        }
788
789
0
        int       lower_level_new_eob = 0;
790
0
        const int new_eob             = si + 1;
791
0
        const int coeff_ctx_new_eob   = get_lower_levels_ctx_eob(bwl, height, si);
792
0
        const int new_eob_cost        = get_eob_cost(new_eob, txb_eob_costs, txb_costs, tx_class);
793
0
        int       rate_coeff_eob      = new_eob_cost +
794
0
            get_coeff_cost_eob(ci, abs_qc, sign, coeff_ctx_new_eob, dc_sign_ctx, txb_costs, bwl, tx_class);
795
0
        int64_t dist_new_eob = dist;
796
0
        int64_t rd_new_eob   = RDCOST(rdmult, rate_coeff_eob, dist_new_eob);
797
798
0
        if (abs_qc_low > 0) {
799
0
            const int rate_coeff_eob_low = new_eob_cost +
800
0
                get_coeff_cost_eob(ci, abs_qc_low, sign, coeff_ctx_new_eob, dc_sign_ctx, txb_costs, bwl, tx_class);
801
0
            const int64_t dist_new_eob_low = dist_low;
802
0
            const int64_t rd_new_eob_low   = RDCOST(rdmult, rate_coeff_eob_low, dist_new_eob_low);
803
0
            if (rd_new_eob_low < rd_new_eob) {
804
0
                lower_level_new_eob = 1;
805
0
                rd_new_eob          = rd_new_eob_low;
806
0
                rate_coeff_eob      = rate_coeff_eob_low;
807
0
                dist_new_eob        = dist_new_eob_low;
808
0
            }
809
0
        }
810
811
0
        if (rd_low < rd) {
812
0
            lower_level = 1;
813
0
            rd          = rd_low;
814
0
            rate        = rate_low;
815
0
            dist        = dist_low;
816
0
        }
817
818
0
        if (sharpness == 0 && rd_new_eob < rd) {
819
0
            for (int ni = 0; ni < *nz_num; ++ni) {
820
0
                int last_ci                          = nz_ci[ni];
821
0
                levels[get_padded_idx(last_ci, bwl)] = 0;
822
0
                qcoeff[last_ci]                      = 0;
823
0
                dqcoeff[last_ci]                     = 0;
824
0
            }
825
0
            *eob        = new_eob;
826
0
            *nz_num     = 0;
827
0
            *accu_rate  = rate_coeff_eob;
828
0
            *accu_dist  = dist_new_eob;
829
0
            lower_level = lower_level_new_eob;
830
0
        } else {
831
0
            *accu_rate += rate;
832
0
            *accu_dist += dist;
833
0
        }
834
835
0
        if (lower_level) {
836
0
            qcoeff[ci]                      = qc_low;
837
0
            dqcoeff[ci]                     = dqc_low;
838
0
            levels[get_padded_idx(ci, bwl)] = AOMMIN(abs_qc_low, INT8_MAX);
839
0
        }
840
0
        if (qcoeff[ci]) {
841
0
            nz_ci[*nz_num] = ci;
842
0
            ++*nz_num;
843
0
        }
844
0
    }
845
0
}
846
847
static INLINE void update_coeff_general(int* accu_rate, int64_t* accu_dist, int si, int eob, TxSize tx_size,
848
                                        TxClass tx_class, int bwl, int height, int64_t rdmult, int shift,
849
                                        int dc_sign_ctx, const int16_t* dequant, const int16_t* scan,
850
                                        const LvMapCoeffCost* txb_costs, const TranLow* tcoeff, TranLow* qcoeff,
851
8.40k
                                        TranLow* dqcoeff, uint8_t* levels, const QmVal* iqm_ptr) {
852
8.40k
    const int     ci        = scan[si];
853
8.40k
    const TranLow qc        = qcoeff[ci];
854
8.40k
    const int     is_last   = si == (eob - 1);
855
8.40k
    const int     coeff_ctx = get_lower_levels_ctx_general(is_last, si, bwl, height, levels, ci, tx_size, tx_class);
856
8.40k
    if (qc == 0) {
857
0
        *accu_rate += txb_costs->base_cost[coeff_ctx][0];
858
8.40k
    } else {
859
18.4E
        const int     sign   = (qc < 0) ? 1 : 0;
860
8.40k
        const TranLow abs_qc = abs(qc);
861
8.40k
        const TranLow tqc    = tcoeff[ci];
862
8.40k
        const TranLow dqc    = dqcoeff[ci];
863
8.40k
        const int64_t dist   = get_coeff_dist(tqc, dqc, shift);
864
8.40k
        const int64_t dist0  = get_coeff_dist(tqc, 0, shift);
865
8.40k
        const int     rate   = get_coeff_cost_general(
866
8.40k
            is_last, ci, abs_qc, sign, coeff_ctx, dc_sign_ctx, txb_costs, bwl, tx_class, levels);
867
8.40k
        const int64_t rd = RDCOST(rdmult, rate, dist);
868
869
8.40k
        TranLow qc_low, dqc_low;
870
8.40k
        TranLow abs_qc_low;
871
8.40k
        int64_t dist_low, rd_low;
872
8.40k
        int     rate_low;
873
8.40k
        if (abs_qc == 1) {
874
0
            abs_qc_low = qc_low = dqc_low = 0;
875
0
            dist_low                      = dist0;
876
0
            rate_low                      = txb_costs->base_cost[coeff_ctx][0];
877
8.40k
        } else {
878
8.40k
            const int dqv = get_dqv(dequant, ci, iqm_ptr);
879
8.40k
            get_qc_dqc_low(abs_qc, sign, dqv, shift, &qc_low, &dqc_low);
880
8.40k
            abs_qc_low = abs_qc - 1;
881
8.40k
            dist_low   = get_coeff_dist(tqc, dqc_low, shift);
882
8.40k
            rate_low   = get_coeff_cost_general(
883
8.40k
                is_last, ci, abs_qc_low, sign, coeff_ctx, dc_sign_ctx, txb_costs, bwl, tx_class, levels);
884
8.40k
        }
885
886
8.40k
        rd_low = RDCOST(rdmult, rate_low, dist_low);
887
8.40k
        if (rd_low < rd) {
888
114
            qcoeff[ci]                      = qc_low;
889
114
            dqcoeff[ci]                     = dqc_low;
890
114
            levels[get_padded_idx(ci, bwl)] = AOMMIN(abs_qc_low, INT8_MAX);
891
114
            *accu_rate += rate_low;
892
114
            *accu_dist += dist_low - dist0;
893
8.28k
        } else {
894
8.28k
            *accu_rate += rate;
895
8.28k
            *accu_dist += dist - dist0;
896
8.28k
        }
897
8.40k
    }
898
8.40k
}
899
900
static AOM_FORCE_INLINE void update_coeff_simple(int* accu_rate, int si, int eob, TxSize tx_size, TxClass tx_class,
901
                                                 int bwl, int64_t rdmult, int shift, const int16_t* dequant,
902
                                                 const int16_t* scan, const LvMapCoeffCost* txb_costs,
903
                                                 const TranLow* tcoeff, TranLow* qcoeff, TranLow* dqcoeff,
904
0
                                                 uint8_t* levels, const QmVal* iqm_ptr) {
905
0
    (void)eob;
906
    // this simple version assumes the coeff's scan_idx is not DC (scan_idx != 0)
907
    // and not the last (scan_idx != eob - 1)
908
0
    assert(si != eob - 1);
909
0
    assert(si > 0);
910
0
    const int     ci        = scan[si];
911
0
    const TranLow qc        = qcoeff[ci];
912
0
    const int     coeff_ctx = get_lower_levels_ctx(levels, ci, bwl, tx_size, tx_class);
913
0
    if (qc == 0) {
914
0
        *accu_rate += txb_costs->base_cost[coeff_ctx][0];
915
0
    } else {
916
0
        const TranLow abs_qc   = abs(qc);
917
0
        const TranLow abs_tqc  = abs(tcoeff[ci]);
918
0
        const TranLow abs_dqc  = abs(dqcoeff[ci]);
919
0
        int           rate_low = 0;
920
0
        const int rate = get_two_coeff_cost_simple(ci, abs_qc, coeff_ctx, txb_costs, bwl, tx_class, levels, &rate_low);
921
0
        if (abs_dqc < abs_tqc) {
922
0
            *accu_rate += rate;
923
0
            return;
924
0
        }
925
926
0
        const int64_t dist = get_coeff_dist(abs_tqc, abs_dqc, shift);
927
0
        const int64_t rd   = RDCOST(rdmult, rate, dist);
928
929
0
        const int     dqv         = get_dqv(dequant, ci, iqm_ptr);
930
0
        const TranLow abs_qc_low  = abs_qc - 1;
931
0
        const TranLow abs_dqc_low = (abs_qc_low * dqv) >> shift;
932
0
        const int64_t dist_low    = get_coeff_dist(abs_tqc, abs_dqc_low, shift);
933
0
        const int64_t rd_low      = RDCOST(rdmult, rate_low, dist_low);
934
935
0
        if (rd_low < rd) {
936
0
            const int sign                  = (qc < 0) ? 1 : 0;
937
0
            qcoeff[ci]                      = (-sign ^ abs_qc_low) + sign;
938
0
            dqcoeff[ci]                     = (-sign ^ abs_dqc_low) + sign;
939
0
            levels[get_padded_idx(ci, bwl)] = AOMMIN(abs_qc_low, INT8_MAX);
940
0
            *accu_rate += rate_low;
941
0
        } else {
942
0
            *accu_rate += rate;
943
0
        }
944
0
    }
945
0
}
946
947
static INLINE void update_skip(int* accu_rate, int64_t accu_dist, uint16_t* eob, int nz_num, int* nz_ci, int64_t rdmult,
948
10.1k
                               int skip_cost, int non_skip_cost, TranLow* qcoeff, TranLow* dqcoeff, int sharpness) {
949
10.1k
    const int64_t rd         = RDCOST(rdmult, *accu_rate + non_skip_cost, accu_dist);
950
10.1k
    const int64_t rd_new_eob = RDCOST(rdmult, skip_cost, 0);
951
10.1k
    if (sharpness == 0 && rd_new_eob < rd) {
952
198
        for (int i = 0; i < nz_num; ++i) {
953
99
            const int ci = nz_ci[i];
954
99
            qcoeff[ci]   = 0;
955
99
            dqcoeff[ci]  = 0;
956
            // no need to set up levels because this is the last step
957
            // levels[get_padded_idx(ci, bwl)] = 0;
958
99
        }
959
99
        *accu_rate = 0;
960
99
        *eob       = 0;
961
99
    }
962
10.1k
}
963
964
enum {
965
    NO_AQ             = 0,
966
    VARIANCE_AQ       = 1,
967
    COMPLEXITY_AQ     = 2,
968
    CYCLIC_REFRESH_AQ = 3,
969
    AQ_MODE_COUNT // This should always be the last member of the enum
970
} UENUM1BYTE(AQ_MODE);
971
972
enum {
973
    NO_DELTA_Q   = 0,
974
    DELTA_Q_ONLY = 1,
975
    DELTA_Q_LF   = 2,
976
    DELTAQ_MODE_COUNT // This should always be the last member of the enum
977
} UENUM1BYTE(DELTAQ_MODE);
978
979
// These numbers are empirically obtained.
980
static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
981
    {17, 13},
982
    {16, 10},
983
};
984
985
/*
986
 * Reduce the number of non-zero quantized coefficients before getting to the main/complex RDOQ stage
987
 * (it performs an early check of whether to zero out each of the non-zero quantized coefficients,
988
 * and updates the quantized coeffs if it is determined it can be zeroed out).
989
 */
990
static INLINE void update_coeff_eob_fast(uint16_t* eob, int shift, const int16_t* dequant_ptr, const int16_t* scan,
991
0
                                         const TranLow* coeff_ptr, TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr) {
992
0
    int       eob_out = *eob;
993
0
    const int zbin[2] = {dequant_ptr[0] + ROUND_POWER_OF_TWO(dequant_ptr[0] * 70, 7),
994
0
                         dequant_ptr[1] + ROUND_POWER_OF_TWO(dequant_ptr[1] * 70, 7)};
995
0
    for (int i = *eob - 1; i >= 0; i--) {
996
0
        const int rc         = scan[i];
997
0
        const int qcoeff     = qcoeff_ptr[rc];
998
0
        const int coeff      = coeff_ptr[rc];
999
0
        const int coeff_sign = -(coeff < 0);
1000
0
        int64_t   abs_coeff  = (coeff ^ coeff_sign) - coeff_sign;
1001
0
        if (((abs_coeff << (1 + shift)) < zbin[rc != 0]) || (qcoeff == 0)) {
1002
0
            eob_out--;
1003
0
            qcoeff_ptr[rc]  = 0;
1004
0
            dqcoeff_ptr[rc] = 0;
1005
0
        } else {
1006
0
            break;
1007
0
        }
1008
0
    }
1009
0
    *eob = eob_out;
1010
0
}
1011
1012
static void svt_fast_optimize_b(const TranLow* coeff_ptr, const MacroblockPlane* p, TranLow* qcoeff_ptr,
1013
                                TranLow* dqcoeff_ptr, uint16_t* eob, TxSize tx_size, TxType tx_type)
1014
1015
0
{
1016
0
    const ScanOrder* const scan_order = get_scan_order(tx_size, tx_type);
1017
0
    const int16_t*         scan       = scan_order->scan;
1018
0
    const int              shift      = av1_get_tx_scale_tab[tx_size];
1019
0
    update_coeff_eob_fast(eob, shift, p->dequant_qtx, scan, coeff_ptr, qcoeff_ptr, dqcoeff_ptr);
1020
0
}
1021
1022
static void svt_av1_optimize_b(PictureControlSet* pcs, ModeDecisionContext* ctx, int16_t txb_skip_context,
1023
                               int16_t dc_sign_context, const TranLow* coeff_ptr, const MacroblockPlane* p,
1024
                               TranLow* qcoeff_ptr, TranLow* dqcoeff_ptr, uint16_t* eob, const QuantParam* qparam,
1025
                               TxSize tx_size, TxType tx_type, bool is_inter, uint8_t use_sharpness,
1026
10.1k
                               uint8_t delta_q_present, uint8_t picture_qp, uint32_t lambda, int plane) {
1027
10.1k
    int                    sharpness  = 0; // No Sharpness
1028
10.1k
    const ScanOrder* const scan_order = get_scan_order(tx_size, tx_type);
1029
10.1k
    const int16_t*         scan       = scan_order->scan;
1030
10.1k
    const int              shift      = av1_get_tx_scale_tab[tx_size];
1031
10.1k
    const PlaneType        plane_type = plane;
1032
10.1k
    const TxSize           txs_ctx    = get_txsize_entropy_ctx(tx_size);
1033
10.1k
    const TxClass          tx_class   = tx_type_to_class[tx_type];
1034
10.1k
    const int              bwl        = get_txb_bwl(tx_size);
1035
10.1k
    const int              width      = get_txb_wide(tx_size);
1036
10.1k
    const int              height     = get_txb_high(tx_size);
1037
10.1k
    assert(width == (1 << bwl));
1038
10.1k
    assert(txs_ctx < TX_SIZES);
1039
10.1k
    const LvMapCoeffCost* txb_costs      = &ctx->md_rate_est_ctx->coeff_fac_bits[txs_ctx][plane_type];
1040
10.1k
    const int             eob_multi_size = txsize_log2_minus4[tx_size];
1041
10.1k
    const LvMapEobCost*   txb_eob_costs  = &ctx->md_rate_est_ctx->eob_frac_bits[eob_multi_size][plane_type];
1042
10.1k
    const int             non_skip_cost  = txb_costs->txb_skip_cost[txb_skip_context][0];
1043
10.1k
    const int             skip_cost      = txb_costs->txb_skip_cost[txb_skip_context][1];
1044
10.1k
    const int             eob_cost       = get_eob_cost(*eob, txb_eob_costs, txb_costs, tx_class);
1045
10.1k
    int                   rweight        = 100;
1046
10.1k
    const int32_t         sharpness_val  = CLIP3(0, 7, pcs->scs->static_config.sharpness);
1047
10.1k
    const int             rshift         = MAX(2, (int)sharpness_val);
1048
10.1k
    if (use_sharpness && delta_q_present && plane == 0) {
1049
0
        int diff = ctx->sb_ptr->qindex - quantizer_to_qindex[picture_qp];
1050
0
        if (diff < 0) {
1051
0
            sharpness = 1;
1052
0
            rweight   = 0;
1053
0
        }
1054
0
    }
1055
10.1k
    const int64_t  rdmult = (((((int64_t)lambda * plane_rd_mult[is_inter][plane_type]) * rweight) / 100) + 2) >> rshift;
1056
10.1k
    uint8_t* const levels = set_levels(ctx->md_levels_buf, width, height);
1057
1058
10.1k
    if (*eob > 1) {
1059
0
        svt_av1_txb_init_levels(qcoeff_ptr, width, height, levels);
1060
0
    }
1061
10.1k
    int accu_rate = eob_cost;
1062
1063
10.1k
    int64_t       accu_dist  = 0;
1064
10.1k
    int           si         = *eob - 1;
1065
10.1k
    const int     ci         = scan[si];
1066
10.1k
    const TranLow qc         = qcoeff_ptr[ci];
1067
10.1k
    const TranLow abs_qc     = abs(qc);
1068
10.1k
    const int     sign       = qc < 0;
1069
10.1k
    const int     max_nz_num = 4;
1070
10.1k
    int           nz_num     = 1;
1071
10.1k
    int           nz_ci[5]   = {ci, 0, 0, 0, 0};
1072
10.1k
    if (abs_qc >= 2) {
1073
8.40k
        update_coeff_general(&accu_rate,
1074
8.40k
                             &accu_dist,
1075
8.40k
                             si,
1076
8.40k
                             *eob,
1077
8.40k
                             tx_size,
1078
8.40k
                             tx_class,
1079
8.40k
                             bwl,
1080
8.40k
                             height,
1081
8.40k
                             rdmult,
1082
8.40k
                             shift,
1083
8.40k
                             dc_sign_context,
1084
8.40k
                             p->dequant_qtx,
1085
8.40k
                             scan,
1086
8.40k
                             txb_costs,
1087
8.40k
                             coeff_ptr,
1088
8.40k
                             qcoeff_ptr,
1089
8.40k
                             dqcoeff_ptr,
1090
8.40k
                             levels,
1091
8.40k
                             qparam->iqmatrix);
1092
8.40k
        --si;
1093
8.40k
    } else {
1094
1.77k
        assert(abs_qc == 1);
1095
1.77k
        const int coeff_ctx = get_lower_levels_ctx_eob(bwl, height, si);
1096
1.77k
        accu_rate += get_coeff_cost_eob(ci, abs_qc, sign, coeff_ctx, dc_sign_context, txb_costs, bwl, tx_class);
1097
1098
1.77k
        const TranLow tqc   = coeff_ptr[ci];
1099
1.77k
        const TranLow dqc   = dqcoeff_ptr[ci];
1100
1.77k
        const int64_t dist  = get_coeff_dist(tqc, dqc, shift);
1101
1.77k
        const int64_t dist0 = get_coeff_dist(tqc, 0, shift);
1102
1.77k
        accu_dist += dist - dist0;
1103
1.77k
        --si;
1104
1.77k
    }
1105
10.1k
#define UPDATE_COEFF_EOB_CASE(tx_class_literal)         \
1106
10.1k
    case tx_class_literal:                              \
1107
10.1k
        for (; si >= 0 && nz_num <= max_nz_num; --si) { \
1108
0
            update_coeff_eob(&accu_rate,                \
1109
0
                             &accu_dist,                \
1110
0
                             eob,                       \
1111
0
                             &nz_num,                   \
1112
0
                             nz_ci,                     \
1113
0
                             si,                        \
1114
0
                             tx_size,                   \
1115
0
                             tx_class_literal,          \
1116
0
                             bwl,                       \
1117
0
                             height,                    \
1118
0
                             dc_sign_context,           \
1119
0
                             rdmult,                    \
1120
0
                             shift,                     \
1121
0
                             p->dequant_qtx,            \
1122
0
                             scan,                      \
1123
0
                             txb_eob_costs,             \
1124
0
                             txb_costs,                 \
1125
0
                             coeff_ptr,                 \
1126
0
                             qcoeff_ptr,                \
1127
0
                             dqcoeff_ptr,               \
1128
0
                             levels,                    \
1129
0
                             sharpness,                 \
1130
0
                             qparam->iqmatrix);         \
1131
0
        }                                               \
1132
10.1k
        break;
1133
10.1k
    switch (tx_class) {
1134
10.1k
        UPDATE_COEFF_EOB_CASE(TX_CLASS_2D);
1135
0
        UPDATE_COEFF_EOB_CASE(TX_CLASS_HORIZ);
1136
0
        UPDATE_COEFF_EOB_CASE(TX_CLASS_VERT);
1137
0
#undef UPDATE_COEFF_EOB_CASE
1138
0
    default:
1139
0
        assert(false);
1140
10.1k
    }
1141
1142
10.1k
    if (si == -1 && nz_num <= max_nz_num) {
1143
10.1k
        update_skip(&accu_rate,
1144
10.1k
                    accu_dist,
1145
10.1k
                    eob,
1146
10.1k
                    nz_num,
1147
10.1k
                    nz_ci,
1148
10.1k
                    rdmult,
1149
10.1k
                    skip_cost,
1150
10.1k
                    non_skip_cost,
1151
10.1k
                    qcoeff_ptr,
1152
10.1k
                    dqcoeff_ptr,
1153
10.1k
                    sharpness);
1154
10.1k
    }
1155
1156
    // The "simple" RDOQ loop only runs for coeffs below the eob region (needs si >= si_end,
1157
    // and si_end >= 1). When the eob region already consumed everything (si < 1, e.g. eob==1
1158
    // or <= max_nz_num nonzero coeffs) skip the cut-off divide and the loop dispatch entirely.
1159
10.1k
    if (si >= 1) {
1160
0
        int si_end = 1; // default: full RDOQ
1161
0
        if (ctx->rdoq_ctrls.cut_off_num) {
1162
0
            const int cut_off_coeff = AOMMAX((width * height) >> 7,
1163
0
                                             (*eob * ctx->rdoq_ctrls.cut_off_num) / ctx->rdoq_ctrls.cut_off_denum);
1164
0
            si_end                  = AOMMAX(1, *eob - cut_off_coeff);
1165
0
        }
1166
0
#define UPDATE_COEFF_SIMPLE_CASE(tx_class_literal) \
1167
0
    case tx_class_literal:                         \
1168
0
        for (; si >= si_end; --si) {               \
1169
0
            update_coeff_simple(&accu_rate,        \
1170
0
                                si,                \
1171
0
                                *eob,              \
1172
0
                                tx_size,           \
1173
0
                                tx_class_literal,  \
1174
0
                                bwl,               \
1175
0
                                rdmult,            \
1176
0
                                shift,             \
1177
0
                                p->dequant_qtx,    \
1178
0
                                scan,              \
1179
0
                                txb_costs,         \
1180
0
                                coeff_ptr,         \
1181
0
                                qcoeff_ptr,        \
1182
0
                                dqcoeff_ptr,       \
1183
0
                                levels,            \
1184
0
                                qparam->iqmatrix); \
1185
0
        }                                          \
1186
0
        break;
1187
0
        switch (tx_class) {
1188
0
            UPDATE_COEFF_SIMPLE_CASE(TX_CLASS_2D);
1189
0
            UPDATE_COEFF_SIMPLE_CASE(TX_CLASS_HORIZ);
1190
0
            UPDATE_COEFF_SIMPLE_CASE(TX_CLASS_VERT);
1191
0
#undef UPDATE_COEFF_SIMPLE_CASE
1192
0
        default:
1193
0
            assert(false);
1194
0
        }
1195
0
    }
1196
1197
    // DC position
1198
10.1k
    if (si == 0) {
1199
        // no need to update accu_dist because it's not used after this point
1200
0
        int64_t dummy_dist = 0;
1201
0
        update_coeff_general(&accu_rate,
1202
0
                             &dummy_dist,
1203
0
                             si,
1204
0
                             *eob,
1205
0
                             tx_size,
1206
0
                             tx_class,
1207
0
                             bwl,
1208
0
                             height,
1209
0
                             rdmult,
1210
0
                             shift,
1211
0
                             dc_sign_context,
1212
0
                             p->dequant_qtx,
1213
0
                             scan,
1214
0
                             txb_costs,
1215
0
                             coeff_ptr,
1216
0
                             qcoeff_ptr,
1217
0
                             dqcoeff_ptr,
1218
0
                             levels,
1219
0
                             qparam->iqmatrix);
1220
0
    }
1221
10.1k
}
1222
1223
1.05M
static INLINE TxSize aom_av1_get_adjusted_tx_size(TxSize tx_size) {
1224
1.05M
    switch (tx_size) {
1225
3.01k
    case TX_64X64:
1226
5.14k
    case TX_64X32:
1227
5.14k
    case TX_32X64:
1228
5.14k
        return TX_32X32;
1229
0
    case TX_64X16:
1230
0
        return TX_32X16;
1231
0
    case TX_16X64:
1232
0
        return TX_16X32;
1233
1.05M
    default:
1234
1.05M
        return tx_size;
1235
1.05M
    }
1236
1.05M
}
1237
1238
void svt_aom_quantize_inv_quantize_light(PictureControlSet* pcs, int32_t* coeff, int32_t* quant_coeff,
1239
                                         int32_t* recon_coeff, uint32_t qindex, TxSize txsize, uint16_t* eob,
1240
153k
                                         uint32_t bit_depth, TxType tx_type) {
1241
153k
    EncodeContext* enc_ctx = pcs->scs->enc_ctx;
1242
1243
153k
    uint32_t q_index = qindex;
1244
1245
153k
    const ScanOrder* const scan_order = get_scan_order(txsize, tx_type);
1246
1247
153k
    const int32_t n_coeffs = av1_get_max_eob(txsize);
1248
1249
153k
    int32_t qmatrix_level = (IS_2D_TRANSFORM(tx_type) && pcs->ppcs->frm_hdr.quantization_params.using_qmatrix)
1250
1251
153k
        ? pcs->ppcs->frm_hdr.quantization_params.qm[PLANE_Y]
1252
1253
153k
        : NUM_QM_LEVELS - 1;
1254
1255
153k
    TxSize adjusted_tx_size = aom_av1_get_adjusted_tx_size(txsize);
1256
1257
153k
    const QmVal* q_matrix = pcs->ppcs->gqmatrix[qmatrix_level][PLANE_Y][adjusted_tx_size];
1258
1259
153k
    const QmVal* iq_matrix = pcs->ppcs->giqmatrix[qmatrix_level][PLANE_Y][adjusted_tx_size];
1260
1261
153k
    if (q_matrix == NULL && iq_matrix == NULL) {
1262
153k
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1263
153k
        if (bit_depth > EB_EIGHT_BIT) {
1264
0
            svt_aom_highbd_quantize_b((TranLow*)coeff,
1265
0
                                      n_coeffs,
1266
0
                                      enc_ctx->quants_bd.y_zbin[q_index],
1267
0
                                      enc_ctx->quants_bd.y_round[q_index],
1268
0
                                      enc_ctx->quants_bd.y_quant[q_index],
1269
0
                                      enc_ctx->quants_bd.y_quant_shift[q_index],
1270
0
                                      quant_coeff,
1271
0
                                      (TranLow*)recon_coeff,
1272
0
                                      enc_ctx->deq_bd.v_dequant_qtx[q_index],
1273
0
                                      eob,
1274
0
                                      scan_order->scan,
1275
0
                                      scan_order->iscan,
1276
0
                                      q_matrix,
1277
0
                                      iq_matrix,
1278
0
                                      av1_get_tx_scale_tab[txsize]);
1279
0
        } else
1280
#else
1281
        UNUSED(bit_depth);
1282
#endif
1283
153k
        {
1284
153k
            svt_aom_quantize_b((TranLow*)coeff,
1285
153k
                               n_coeffs,
1286
153k
                               enc_ctx->quants_8bit.v_zbin[q_index],
1287
153k
                               enc_ctx->quants_8bit.v_round[q_index],
1288
153k
                               enc_ctx->quants_8bit.v_quant[q_index],
1289
153k
                               enc_ctx->quants_8bit.v_quant_shift[q_index],
1290
153k
                               quant_coeff,
1291
153k
                               (TranLow*)recon_coeff,
1292
153k
                               enc_ctx->deq_8bit.y_dequant_qtx[q_index],
1293
153k
                               eob,
1294
153k
                               scan_order->scan,
1295
153k
                               scan_order->iscan,
1296
153k
                               q_matrix,
1297
153k
                               iq_matrix,
1298
153k
                               av1_get_tx_scale_tab[txsize]);
1299
153k
        }
1300
18.4E
    } else {
1301
18.4E
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1302
18.4E
        if (bit_depth > EB_EIGHT_BIT) {
1303
0
            svt_av1_highbd_quantize_b_qm((TranLow*)coeff,
1304
0
                                         n_coeffs,
1305
0
                                         enc_ctx->quants_bd.y_zbin[q_index],
1306
0
                                         enc_ctx->quants_bd.y_round[q_index],
1307
0
                                         enc_ctx->quants_bd.y_quant[q_index],
1308
0
                                         enc_ctx->quants_bd.y_quant_shift[q_index],
1309
0
                                         quant_coeff,
1310
0
                                         (TranLow*)recon_coeff,
1311
0
                                         enc_ctx->deq_bd.v_dequant_qtx[q_index],
1312
0
                                         eob,
1313
0
                                         scan_order->scan,
1314
0
                                         scan_order->iscan,
1315
0
                                         q_matrix,
1316
0
                                         iq_matrix,
1317
0
                                         av1_get_tx_scale_tab[txsize]);
1318
0
        } else
1319
18.4E
#endif
1320
18.4E
        {
1321
18.4E
            svt_av1_quantize_b_qm((TranLow*)coeff,
1322
18.4E
                                  n_coeffs,
1323
18.4E
                                  enc_ctx->quants_8bit.v_zbin[q_index],
1324
18.4E
                                  enc_ctx->quants_8bit.v_round[q_index],
1325
18.4E
                                  enc_ctx->quants_8bit.v_quant[q_index],
1326
18.4E
                                  enc_ctx->quants_8bit.v_quant_shift[q_index],
1327
18.4E
                                  quant_coeff,
1328
18.4E
                                  (TranLow*)recon_coeff,
1329
18.4E
                                  enc_ctx->deq_8bit.y_dequant_qtx[q_index],
1330
18.4E
                                  eob,
1331
18.4E
                                  scan_order->scan,
1332
18.4E
                                  scan_order->iscan,
1333
18.4E
                                  q_matrix,
1334
18.4E
                                  iq_matrix,
1335
18.4E
                                  av1_get_tx_scale_tab[txsize]);
1336
18.4E
        }
1337
18.4E
    }
1338
153k
}
1339
1340
// See av1_get_txb_entropy_context in libaom. Reference: sum |quant_coeff| over the eob coded coeffs
1341
// in scan order, capped at COEFF_CONTEXT_MASK; the caller applies the clamp + DC sign. (The SIMD
1342
// kernels additionally switch to a linear whole-block sum for dense blocks; the C reference stays
1343
// simple and eob-bounded.)
1344
int32_t svt_av1_compute_cul_level_c(const int16_t* const scan, const int32_t* const quant_coeff, int32_t eob,
1345
0
                                    int32_t n_coeffs) {
1346
0
    (void)n_coeffs;
1347
0
    int32_t cul_level = 0;
1348
0
    for (int32_t c = 0; c < eob; ++c) {
1349
0
        cul_level += ABS(quant_coeff[scan[c]]);
1350
0
        if (cul_level >= COEFF_CONTEXT_MASK) {
1351
0
            break;
1352
0
        }
1353
0
    }
1354
0
    return cul_level;
1355
0
}
1356
1357
// Retract EOB by removing trailing low-magnitude coefficients separated by zero gaps
1358
// Tracks symbol-count knees at levels 3/6/9/12 and golomb tail at 15+.
1359
0
static INLINE int32_t ec_shave_est_zero_rate_save(int32_t ref_level, int32_t bit_cost) {
1360
0
    int32_t save = ((ref_level > 3) + (ref_level > 6) + (ref_level > 9) + (ref_level > 12)) * bit_cost;
1361
0
    if (ref_level > 14) {
1362
0
        save += get_golomb_cost(ref_level);
1363
0
    }
1364
0
    return save;
1365
0
}
1366
1367
static INLINE uint16_t shave_coeff(int32_t* quant_buf, int32_t* recon_buf, const int32_t* tcoeff, uint16_t eob,
1368
0
                                   TxSize tx_size, TxType tx_type, uint32_t lambda, const CoeffShavingCtrls* ctrls) {
1369
0
    const int16_t* const scan             = get_scan_order(tx_size, tx_type)->scan;
1370
0
    const int            level_th         = ctrls->level_threshold;
1371
0
    const int            gap_th           = ctrls->zero_gap_threshold;
1372
0
    int                  updated_eob      = (int)eob;
1373
0
    int                  prev_nz_scan_idx = updated_eob - 2;
1374
1375
    // Two-phase design rationale:
1376
    // 1) Run a cheap structural pass first (gap/level only, no RD math) to retract EOB quickly.
1377
    // 2) Then run the expensive RD-gated pass only on the shortened tail.
1378
1379
    // Phase 1: trailing coeff zeroing by zero-gap criterion.
1380
0
    while (updated_eob > 1) {
1381
0
        const int     last_scan_idx = updated_eob - 1;
1382
0
        const int     last_pos      = scan[last_scan_idx];
1383
0
        const int32_t val           = quant_buf[last_pos];
1384
0
        const int32_t abs_val       = (val < 0) ? -val : val;
1385
1386
        // Current trailing coeff is not eligible for shaving.
1387
        // Since phase 2 obeys the same level-threshold rule, we are done.
1388
0
        if (abs_val > level_th) {
1389
0
            return (uint16_t)updated_eob;
1390
0
        }
1391
1392
0
        while (prev_nz_scan_idx >= 0) {
1393
0
            const int pos = scan[prev_nz_scan_idx];
1394
0
            if (quant_buf[pos] != 0) {
1395
0
                break;
1396
0
            }
1397
0
            --prev_nz_scan_idx;
1398
0
        }
1399
1400
0
        if (prev_nz_scan_idx < 0) {
1401
0
            break;
1402
0
        }
1403
1404
0
        const int gap = last_scan_idx - prev_nz_scan_idx - 1;
1405
0
        if (gap < gap_th) {
1406
0
            break;
1407
0
        }
1408
1409
0
        quant_buf[last_pos] = 0;
1410
0
        recon_buf[last_pos] = 0;
1411
1412
0
        updated_eob = prev_nz_scan_idx + 1;
1413
0
        --prev_nz_scan_idx;
1414
0
    }
1415
1416
    // Nothing more to do if RD shaving is disabled or no trailing coeff remains.
1417
0
    if (ctrls->rd_zero_strength <= 0 || updated_eob <= 1) {
1418
0
        return (uint16_t)updated_eob;
1419
0
    }
1420
1421
0
    const int     shift         = av1_get_tx_scale_tab[tx_size];
1422
0
    const int32_t bit_cost      = av1_cost_literal(1);
1423
0
    const int64_t rd_rate_scale = (int64_t)ctrls->rd_zero_strength;
1424
1425
    // Fast path: only |level| == 1 is eligible.
1426
0
    if (level_th == 1) {
1427
0
        while (updated_eob > 1) {
1428
0
            const int     last_scan_idx = updated_eob - 1;
1429
0
            const int     last_pos      = scan[last_scan_idx];
1430
0
            const int32_t val           = quant_buf[last_pos];
1431
0
            const int32_t abs_val       = (val >= 0) ? val : -val;
1432
1433
0
            if (abs_val > 1) {
1434
0
                break;
1435
0
            }
1436
1437
0
            const TranLow tqc      = (TranLow)tcoeff[last_pos];
1438
0
            const TranLow dqc_cur  = (TranLow)recon_buf[last_pos];
1439
0
            const int64_t dist_cur = get_coeff_dist(tqc, dqc_cur, shift);
1440
0
            const int64_t dist_new = get_coeff_dist(tqc, 0, shift);
1441
1442
            // For |level| == 1, ec_shave_est_zero_rate_save() contributes 0.
1443
0
            const int64_t rate_save = (int64_t)bit_cost * rd_rate_scale;
1444
1445
0
            const int64_t dist_term = (dist_new - dist_cur) * ((int64_t)1 << RDDIV_BITS);
1446
0
            const int64_t rate_term = ROUND_POWER_OF_TWO(rate_save * lambda, AV1_PROB_COST_SHIFT);
1447
0
            if (dist_term >= rate_term) {
1448
0
                break;
1449
0
            }
1450
1451
0
            quant_buf[last_pos] = 0;
1452
0
            recon_buf[last_pos] = 0;
1453
1454
0
            int next_eob = last_scan_idx;
1455
0
            while (next_eob > 0 && quant_buf[scan[next_eob - 1]] == 0) {
1456
0
                --next_eob;
1457
0
            }
1458
0
            updated_eob = next_eob;
1459
0
        }
1460
1461
0
        return (uint16_t)updated_eob;
1462
0
    }
1463
1464
    // Generic phase 2 for level_threshold > 1.
1465
0
    while (updated_eob > 1) {
1466
0
        const int     last_scan_idx = updated_eob - 1;
1467
0
        const int     last_pos      = scan[last_scan_idx];
1468
0
        const int32_t val           = quant_buf[last_pos];
1469
0
        const int32_t abs_val       = (val >= 0) ? val : -val;
1470
1471
0
        if (abs_val > level_th) {
1472
0
            break;
1473
0
        }
1474
1475
0
        const int64_t rate_save = (int64_t)(ec_shave_est_zero_rate_save(abs_val, bit_cost) + bit_cost) * rd_rate_scale;
1476
1477
0
        const TranLow tqc      = (TranLow)tcoeff[last_pos];
1478
0
        const TranLow dqc_cur  = (TranLow)recon_buf[last_pos];
1479
0
        const int64_t dist_cur = get_coeff_dist(tqc, dqc_cur, shift);
1480
0
        const int64_t dist_new = get_coeff_dist(tqc, 0, shift);
1481
1482
0
        const int64_t dist_term = (dist_new - dist_cur) * ((int64_t)1 << RDDIV_BITS);
1483
0
        const int64_t rate_term = ROUND_POWER_OF_TWO(rate_save * lambda, AV1_PROB_COST_SHIFT);
1484
0
        if (dist_term >= rate_term) {
1485
0
            break;
1486
0
        }
1487
1488
0
        quant_buf[last_pos] = 0;
1489
0
        recon_buf[last_pos] = 0;
1490
1491
0
        int next_eob = last_scan_idx;
1492
0
        while (next_eob > 0 && quant_buf[scan[next_eob - 1]] == 0) {
1493
0
            --next_eob;
1494
0
        }
1495
0
        updated_eob = next_eob;
1496
0
    }
1497
1498
0
    return (uint16_t)updated_eob;
1499
0
}
1500
1501
// eob<=1 is a single (possibly zero) DC coefficient whose raw level is |dc|; eob>1 uses the ISA
1502
// kernel (scan/gather for sparse blocks, linear for dense). The clamp + DC sign is applied here
1503
// once, shared by both paths and all ISA variants.
1504
static INLINE uint8_t compute_cul_level_fast(const int16_t* const scan, const int32_t* const quant_coeff,
1505
0
                                             int32_t n_coeffs, uint16_t* eob) {
1506
0
    int32_t cul_level = (*eob <= 1) ? abs(quant_coeff[0])
1507
0
                                    : svt_av1_compute_cul_level(scan, quant_coeff, *eob, n_coeffs);
1508
0
    cul_level         = AOMMIN(COEFF_CONTEXT_MASK, cul_level);
1509
0
    set_dc_sign(&cul_level, quant_coeff[0]);
1510
0
    return (uint8_t)cul_level;
1511
0
}
1512
1513
uint8_t svt_aom_quantize_inv_quantize(PictureControlSet* pcs, ModeDecisionContext* ctx, int32_t* coeff,
1514
                                      int32_t* quant_coeff, int32_t* recon_coeff, uint32_t qindex,
1515
                                      int32_t segmentation_qp_offset, TxSize txsize, uint16_t* eob,
1516
                                      uint32_t component_type, uint32_t bit_depth, TxType tx_type,
1517
                                      int16_t txb_skip_context, int16_t dc_sign_context, PredictionMode pred_mode,
1518
902k
                                      uint32_t lambda, bool is_encode_pass) {
1519
902k
    SequenceControlSet* scs     = pcs->scs;
1520
902k
    EncodeContext*      enc_ctx = scs->enc_ctx;
1521
902k
    int32_t             plane   = component_type == COMPONENT_LUMA ? PLANE_Y
1522
902k
                                                                   : (component_type == COMPONENT_CHROMA_CB ? PLANE_U : PLANE_V);
1523
1524
902k
    int32_t qmatrix_level = (IS_2D_TRANSFORM(tx_type) && pcs->ppcs->frm_hdr.quantization_params.using_qmatrix)
1525
902k
        ? pcs->ppcs->frm_hdr.quantization_params.qm[plane]
1526
902k
        : NUM_QM_LEVELS - 1;
1527
1528
902k
    TxSize          adjusted_tx_size = aom_av1_get_adjusted_tx_size(txsize);
1529
902k
    MacroblockPlane candidate_plane;
1530
902k
    const QmVal*    q_matrix  = pcs->ppcs->gqmatrix[qmatrix_level][plane][adjusted_tx_size];
1531
902k
    const QmVal*    iq_matrix = pcs->ppcs->giqmatrix[qmatrix_level][plane][adjusted_tx_size];
1532
902k
    int32_t         q_index   = pcs->ppcs->frm_hdr.delta_q_params.delta_q_present
1533
902k
                  ? qindex
1534
902k
                  : pcs->ppcs->frm_hdr.quantization_params.base_q_idx;
1535
902k
    if (segmentation_qp_offset != 0) {
1536
0
        q_index = CLIP3(0, 255, q_index + segmentation_qp_offset);
1537
0
    }
1538
902k
    if (component_type != COMPONENT_LUMA) {
1539
308k
        const int8_t offset = (component_type == COMPONENT_CHROMA_CB)
1540
308k
            ? pcs->ppcs->frm_hdr.quantization_params.delta_q_dc[1] // we are assuming delta_q_ac == delta_q_dc
1541
308k
            : pcs->ppcs->frm_hdr.quantization_params.delta_q_dc[2];
1542
308k
        q_index += offset;
1543
308k
        q_index = (uint32_t)CLIP3(0, 255, (int32_t)q_index);
1544
308k
    }
1545
902k
    if (bit_depth == EB_EIGHT_BIT) {
1546
902k
        if (component_type == COMPONENT_LUMA) {
1547
594k
            candidate_plane.quant_qtx       = enc_ctx->quants_8bit.y_quant[q_index];
1548
594k
            candidate_plane.quant_fp_qtx    = enc_ctx->quants_8bit.y_quant_fp[q_index];
1549
594k
            candidate_plane.round_fp_qtx    = enc_ctx->quants_8bit.y_round_fp[q_index];
1550
594k
            candidate_plane.quant_shift_qtx = enc_ctx->quants_8bit.y_quant_shift[q_index];
1551
594k
            candidate_plane.zbin_qtx        = enc_ctx->quants_8bit.y_zbin[q_index];
1552
594k
            candidate_plane.round_qtx       = enc_ctx->quants_8bit.y_round[q_index];
1553
594k
            candidate_plane.dequant_qtx     = enc_ctx->deq_8bit.y_dequant_qtx[q_index];
1554
594k
        } else if (component_type == COMPONENT_CHROMA_CB) {
1555
154k
            candidate_plane.quant_qtx       = enc_ctx->quants_8bit.u_quant[q_index];
1556
154k
            candidate_plane.quant_fp_qtx    = enc_ctx->quants_8bit.u_quant_fp[q_index];
1557
154k
            candidate_plane.round_fp_qtx    = enc_ctx->quants_8bit.u_round_fp[q_index];
1558
154k
            candidate_plane.quant_shift_qtx = enc_ctx->quants_8bit.u_quant_shift[q_index];
1559
154k
            candidate_plane.zbin_qtx        = enc_ctx->quants_8bit.u_zbin[q_index];
1560
154k
            candidate_plane.round_qtx       = enc_ctx->quants_8bit.u_round[q_index];
1561
154k
            candidate_plane.dequant_qtx     = enc_ctx->deq_8bit.u_dequant_qtx[q_index];
1562
154k
        }
1563
1564
153k
        else {
1565
153k
            candidate_plane.quant_qtx       = enc_ctx->quants_8bit.v_quant[q_index];
1566
153k
            candidate_plane.quant_fp_qtx    = enc_ctx->quants_8bit.v_quant_fp[q_index];
1567
153k
            candidate_plane.round_fp_qtx    = enc_ctx->quants_8bit.v_round_fp[q_index];
1568
153k
            candidate_plane.quant_shift_qtx = enc_ctx->quants_8bit.v_quant_shift[q_index];
1569
153k
            candidate_plane.zbin_qtx        = enc_ctx->quants_8bit.v_zbin[q_index];
1570
153k
            candidate_plane.round_qtx       = enc_ctx->quants_8bit.v_round[q_index];
1571
153k
            candidate_plane.dequant_qtx     = enc_ctx->deq_8bit.v_dequant_qtx[q_index];
1572
153k
        }
1573
902k
    } else {
1574
40
        if (component_type == COMPONENT_LUMA) {
1575
0
            candidate_plane.quant_qtx       = enc_ctx->quants_bd.y_quant[q_index];
1576
0
            candidate_plane.quant_fp_qtx    = enc_ctx->quants_bd.y_quant_fp[q_index];
1577
0
            candidate_plane.round_fp_qtx    = enc_ctx->quants_bd.y_round_fp[q_index];
1578
0
            candidate_plane.quant_shift_qtx = enc_ctx->quants_bd.y_quant_shift[q_index];
1579
0
            candidate_plane.zbin_qtx        = enc_ctx->quants_bd.y_zbin[q_index];
1580
0
            candidate_plane.round_qtx       = enc_ctx->quants_bd.y_round[q_index];
1581
0
            candidate_plane.dequant_qtx     = enc_ctx->deq_bd.y_dequant_qtx[q_index];
1582
0
        }
1583
1584
40
        else if (component_type == COMPONENT_CHROMA_CB) {
1585
0
            candidate_plane.quant_qtx       = enc_ctx->quants_bd.u_quant[q_index];
1586
0
            candidate_plane.quant_fp_qtx    = enc_ctx->quants_bd.u_quant_fp[q_index];
1587
0
            candidate_plane.round_fp_qtx    = enc_ctx->quants_bd.u_round_fp[q_index];
1588
0
            candidate_plane.quant_shift_qtx = enc_ctx->quants_bd.u_quant_shift[q_index];
1589
0
            candidate_plane.zbin_qtx        = enc_ctx->quants_bd.u_zbin[q_index];
1590
0
            candidate_plane.round_qtx       = enc_ctx->quants_bd.u_round[q_index];
1591
0
            candidate_plane.dequant_qtx     = enc_ctx->deq_bd.u_dequant_qtx[q_index];
1592
0
        }
1593
1594
40
        else {
1595
40
            candidate_plane.quant_qtx       = enc_ctx->quants_bd.v_quant[q_index];
1596
40
            candidate_plane.quant_fp_qtx    = enc_ctx->quants_bd.v_quant_fp[q_index];
1597
40
            candidate_plane.round_fp_qtx    = enc_ctx->quants_bd.v_round_fp[q_index];
1598
40
            candidate_plane.quant_shift_qtx = enc_ctx->quants_bd.v_quant_shift[q_index];
1599
40
            candidate_plane.zbin_qtx        = enc_ctx->quants_bd.v_zbin[q_index];
1600
40
            candidate_plane.round_qtx       = enc_ctx->quants_bd.v_round[q_index];
1601
40
            candidate_plane.dequant_qtx     = enc_ctx->deq_bd.v_dequant_qtx[q_index];
1602
40
        }
1603
40
    }
1604
1605
902k
    const ScanOrder* const scan_order = get_scan_order(txsize, tx_type);
1606
1607
902k
    const int32_t n_coeffs = av1_get_max_eob(txsize);
1608
1609
902k
    QuantParam qparam;
1610
1611
902k
    qparam.log_scale = av1_get_tx_scale_tab[txsize];
1612
902k
    qparam.tx_size   = txsize;
1613
902k
    qparam.qmatrix   = q_matrix;
1614
902k
    qparam.iqmatrix  = iq_matrix;
1615
1616
902k
    bool is_inter = (pred_mode >= NEARESTMV);
1617
902k
    bool perform_rdoq;
1618
1619
    // If rdoq_level is specified in the command line instruction, set perform_rdoq accordingly.
1620
902k
    perform_rdoq = !svt_av1_is_lossless_segment(pcs, ctx->blk_ptr->segment_id) &&
1621
21.8k
        ((ctx->mds_do_rdoq || is_encode_pass) && ctx->rdoq_ctrls.enabled);
1622
902k
    if (!is_encode_pass) {
1623
902k
        if ((ctx->rdoq_ctrls.dct_dct_only && tx_type != DCT_DCT) ||
1624
902k
            (ctx->rdoq_ctrls.skip_uv && component_type != COMPONENT_LUMA)) {
1625
0
            perform_rdoq = 0;
1626
0
        }
1627
902k
    }
1628
902k
    if (perform_rdoq) {
1629
21.8k
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1630
21.8k
        if ((bit_depth > EB_EIGHT_BIT) || (is_encode_pass && SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline))) {
1631
0
            svt_av1_highbd_quantize_fp_facade((TranLow*)coeff,
1632
0
                                              n_coeffs,
1633
0
                                              &candidate_plane,
1634
0
                                              quant_coeff,
1635
0
                                              (TranLow*)recon_coeff,
1636
0
                                              eob,
1637
0
                                              scan_order,
1638
0
                                              &qparam);
1639
0
        } else
1640
21.8k
#endif
1641
21.8k
        {
1642
21.8k
            svt_av1_quantize_fp_facade((TranLow*)coeff,
1643
21.8k
                                       n_coeffs,
1644
21.8k
                                       &candidate_plane,
1645
21.8k
                                       quant_coeff,
1646
21.8k
                                       (TranLow*)recon_coeff,
1647
21.8k
                                       eob,
1648
21.8k
                                       scan_order,
1649
21.8k
                                       &qparam);
1650
21.8k
        }
1651
880k
    } else {
1652
880k
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1653
880k
        if ((bit_depth > EB_EIGHT_BIT) || (is_encode_pass && SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline))) {
1654
0
            svt_av1_highbd_quantize_b_facade((TranLow*)coeff,
1655
0
                                             n_coeffs,
1656
0
                                             &candidate_plane,
1657
0
                                             quant_coeff,
1658
0
                                             (TranLow*)recon_coeff,
1659
0
                                             eob,
1660
0
                                             scan_order,
1661
0
                                             &qparam);
1662
0
        } else
1663
880k
#endif
1664
880k
        {
1665
880k
            av1_quantize_b_facade_ii((TranLow*)coeff,
1666
880k
                                     n_coeffs,
1667
880k
                                     &candidate_plane,
1668
880k
                                     quant_coeff,
1669
880k
                                     (TranLow*)recon_coeff,
1670
880k
                                     eob,
1671
880k
                                     scan_order,
1672
880k
                                     &qparam);
1673
880k
        }
1674
880k
    }
1675
902k
    if (perform_rdoq && *eob != 0) {
1676
10.1k
        int width  = tx_size_wide[txsize];
1677
10.1k
        int height = tx_size_high[txsize];
1678
        // eob_perc >= th  <=>  eob*100 >= th*(w*h) for positive integers; avoids a per-TU divide.
1679
10.1k
        const int eob_scaled = (*eob) * 100;
1680
10.1k
        const int wh         = width * height;
1681
10.1k
        if (eob_scaled >= ctx->rdoq_ctrls.eob_th * wh) {
1682
0
            perform_rdoq = 0;
1683
0
        }
1684
10.1k
        if (perform_rdoq && (eob_scaled >= ctx->rdoq_ctrls.eob_fast_th * wh)) {
1685
0
            svt_fast_optimize_b(
1686
0
                (TranLow*)coeff, &candidate_plane, quant_coeff, (TranLow*)recon_coeff, eob, txsize, tx_type);
1687
0
        }
1688
10.1k
        if (perform_rdoq == 0) {
1689
0
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1690
0
            if ((bit_depth > EB_EIGHT_BIT) ||
1691
0
                (is_encode_pass && SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline))) {
1692
0
                svt_av1_highbd_quantize_b_facade((TranLow*)coeff,
1693
0
                                                 n_coeffs,
1694
0
                                                 &candidate_plane,
1695
0
                                                 quant_coeff,
1696
0
                                                 (TranLow*)recon_coeff,
1697
0
                                                 eob,
1698
0
                                                 scan_order,
1699
0
                                                 &qparam);
1700
0
            } else
1701
0
#endif
1702
0
            {
1703
0
                av1_quantize_b_facade_ii((TranLow*)coeff,
1704
0
                                         n_coeffs,
1705
0
                                         &candidate_plane,
1706
0
                                         quant_coeff,
1707
0
                                         (TranLow*)recon_coeff,
1708
0
                                         eob,
1709
0
                                         scan_order,
1710
0
                                         &qparam);
1711
0
            }
1712
0
        }
1713
10.1k
    }
1714
902k
    if (perform_rdoq && *eob != 0) {
1715
        // Perform rdoq
1716
10.1k
        svt_av1_optimize_b(pcs,
1717
10.1k
                           ctx,
1718
10.1k
                           txb_skip_context,
1719
10.1k
                           dc_sign_context,
1720
10.1k
                           (TranLow*)coeff,
1721
10.1k
                           &candidate_plane,
1722
10.1k
                           quant_coeff,
1723
10.1k
                           (TranLow*)recon_coeff,
1724
10.1k
                           eob,
1725
10.1k
                           &qparam,
1726
10.1k
                           txsize,
1727
10.1k
                           tx_type,
1728
10.1k
                           is_inter,
1729
10.1k
                           scs->vq_ctrls.sharpness_ctrls.rdoq,
1730
10.1k
                           pcs->ppcs->frm_hdr.delta_q_params.delta_q_present,
1731
10.1k
                           pcs->ppcs->picture_qp,
1732
10.1k
                           lambda,
1733
10.1k
                           (component_type == COMPONENT_LUMA) ? 0 : 1);
1734
10.1k
    }
1735
1736
    // Apply coefficient shaving for luma after all quantization/RDOQ is complete.
1737
    // This catches all luma quantize paths (light PD1, regular TX, encode pass)
1738
    // in a single place.
1739
902k
    if (component_type == COMPONENT_LUMA && ctx->coeff_shaving_ctrls.enabled && *eob > 1) {
1740
0
        *eob = shave_coeff(quant_coeff, recon_coeff, coeff, *eob, txsize, tx_type, lambda, &ctx->coeff_shaving_ctrls);
1741
0
    }
1742
1743
902k
    if (!ctx->rate_est_ctrls.update_skip_ctx_dc_sign_ctx) {
1744
902k
        return 0;
1745
902k
    }
1746
1747
    // Derive cul_level
1748
18.4E
    return compute_cul_level_fast(scan_order->scan, quant_coeff, n_coeffs, eob);
1749
902k
}
1750
1751
void svt_aom_inv_transform_recon_wrapper(PictureControlSet* pcs, ModeDecisionContext* ctx, uint8_t* pred_buffer,
1752
                                         uint32_t pred_offset, uint32_t pred_stride, uint8_t* rec_buffer,
1753
                                         uint32_t rec_offset, uint32_t rec_stride, int32_t* rec_coeff_buffer,
1754
                                         uint32_t coeff_offset, bool hbd, TxSize txsize, TxType transform_type,
1755
34.7k
                                         PlaneType component_type, uint32_t eob) {
1756
34.7k
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1757
34.7k
    if (hbd) {
1758
0
        svt_aom_inv_transform_recon(rec_coeff_buffer + coeff_offset,
1759
0
                                    CONVERT_TO_BYTEPTR(((uint16_t*)pred_buffer) + pred_offset),
1760
0
                                    pred_stride,
1761
0
                                    CONVERT_TO_BYTEPTR(((uint16_t*)rec_buffer) + rec_offset),
1762
0
                                    rec_stride,
1763
0
                                    txsize,
1764
0
                                    EB_TEN_BIT,
1765
0
                                    transform_type,
1766
0
                                    component_type,
1767
0
                                    eob,
1768
0
                                    svt_av1_is_lossless_segment(pcs, ctx->blk_ptr->segment_id));
1769
0
    } else
1770
#else
1771
    (void)hbd;
1772
#endif
1773
34.7k
    {
1774
34.7k
        svt_aom_inv_transform_recon8bit(rec_coeff_buffer + coeff_offset,
1775
34.7k
                                        pred_buffer + pred_offset,
1776
34.7k
                                        pred_stride,
1777
34.7k
                                        rec_buffer + rec_offset,
1778
34.7k
                                        rec_stride,
1779
34.7k
                                        txsize,
1780
34.7k
                                        transform_type,
1781
34.7k
                                        component_type,
1782
34.7k
                                        eob,
1783
34.7k
                                        svt_av1_is_lossless_segment(pcs, ctx->blk_ptr->segment_id));
1784
34.7k
    }
1785
34.7k
}
1786
1787
// Computes an EOB-based approximation of chroma coefficient rate.
1788
// Returns true if the approximation was applied; false if full estimation is required.
1789
static bool skip_chroma_rate_est(const ModeDecisionContext* ctx, const ModeDecisionCandidateBuffer* cand_bf,
1790
                                 COMPONENT_TYPE component_type, uint32_t tx_width_uv, uint32_t tx_height_uv,
1791
154k
                                 uint64_t* cb_coeff_bits, uint64_t* cr_coeff_bits) {
1792
    // lvl=1 always uses full estimation; lvl=0 and lvl>=2 use approximation
1793
154k
    if (!(ctx->rate_est_ctrls.coeff_rate_est_lvl >= 2 || ctx->rate_est_ctrls.coeff_rate_est_lvl == 0)) {
1794
0
        return false;
1795
0
    }
1796
154k
    const uint64_t th = ((uint64_t)tx_width_uv * tx_height_uv) >> 6;
1797
154k
    if (component_type == COMPONENT_CHROMA || component_type == COMPONENT_CHROMA_CB) {
1798
154k
        if (cand_bf->eob.u[0] < th) {
1799
4.15k
            *cb_coeff_bits = cand_bf->eob.u[0] ? (3000 + (uint64_t)cand_bf->eob.u[0] * 500) : 0;
1800
149k
        } else if (ctx->rate_est_ctrls.coeff_rate_est_lvl == 0) {
1801
149k
            *cb_coeff_bits = cand_bf->eob.u[0] ? (1500 + (uint64_t)cand_bf->eob.u[0] * 50) : 0;
1802
149k
        } else {
1803
0
            return false;
1804
0
        }
1805
154k
    }
1806
154k
    if (component_type == COMPONENT_CHROMA || component_type == COMPONENT_CHROMA_CR) {
1807
154k
        if (cand_bf->eob.v[0] < th) {
1808
4.15k
            *cr_coeff_bits = cand_bf->eob.v[0] ? (3000 + (uint64_t)cand_bf->eob.v[0] * 500) : 0;
1809
149k
        } else if (ctx->rate_est_ctrls.coeff_rate_est_lvl == 0) {
1810
149k
            *cr_coeff_bits = cand_bf->eob.v[0] ? (1500 + (uint64_t)cand_bf->eob.v[0] * 50) : 0;
1811
149k
        } else {
1812
0
            return false;
1813
0
        }
1814
154k
    }
1815
154k
    return true;
1816
154k
}
1817
1818
/*
1819
  tx path for light PD1 chroma
1820
*/
1821
void svt_aom_full_loop_chroma_light_pd1(PictureControlSet* pcs, ModeDecisionContext* ctx,
1822
                                        ModeDecisionCandidateBuffer* cand_bf, EbPictureBufferDesc* input_pic,
1823
                                        uint32_t input_cb_origin_in_index, uint32_t blk_chroma_origin_index,
1824
                                        COMPONENT_TYPE component_type, uint32_t chroma_qindex,
1825
                                        uint64_t cb_full_distortion[DIST_CALC_TOTAL],
1826
                                        uint64_t cr_full_distortion[DIST_CALC_TOTAL], uint64_t* cb_coeff_bits,
1827
0
                                        uint64_t* cr_coeff_bits) {
1828
0
    uint32_t     full_lambda  = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? ctx->full_lambda_md[EB_10_BIT_MD]
1829
0
                                                                  : ctx->full_lambda_md[EB_8_BIT_MD];
1830
0
    const TxSize tx_size_uv   = av1_get_max_uv_txsize(ctx->blk_geom->bsize, 1, 1);
1831
0
    const int    tx_width_uv  = tx_size_wide[tx_size_uv];
1832
0
    const int    tx_height_uv = tx_size_high[tx_size_uv];
1833
1834
0
    TxCoeffShape pf_shape = ctx->pf_ctrls.pf_shape;
1835
    // If Cb component not detected as complex, can use TX shortcuts
1836
0
    if (ctx->use_tx_shortcuts_mds3 &&
1837
0
        (ctx->chroma_complexity == COMPONENT_LUMA || ctx->chroma_complexity == COMPONENT_CHROMA_CR)) {
1838
0
        pf_shape = N4_SHAPE;
1839
0
    } else {
1840
0
        uint8_t use_pfn4_cond = 0;
1841
0
        if (ctx->lpd1_tx_ctrls.use_uv_shortcuts_on_y_coeffs &&
1842
0
            (ctx->chroma_complexity == COMPONENT_LUMA || ctx->chroma_complexity == COMPONENT_CHROMA_CR)) {
1843
0
            const uint16_t th = ((tx_width_uv >> 4) * (tx_height_uv >> 4));
1844
0
            use_pfn4_cond     = (cand_bf->cnt_nz_coeff < th) || !cand_bf->block_has_coeff ? 1 : 0;
1845
0
        }
1846
0
        if (use_pfn4_cond) {
1847
0
            pf_shape = N4_SHAPE;
1848
0
        }
1849
0
    }
1850
0
    assert(tx_size_uv < TX_SIZES_ALL);
1851
0
    const int32_t chroma_shift = (MAX_TX_SCALE - av1_get_tx_scale_tab[tx_size_uv]) * 2;
1852
0
    uint32_t      bwidth       = tx_width_uv;
1853
0
    uint32_t      bheight      = tx_height_uv;
1854
0
    if (pf_shape) {
1855
0
        bwidth  = MAX((bwidth >> pf_shape), 4);
1856
0
        bheight = (bheight >> pf_shape);
1857
0
    }
1858
0
    if (component_type == COMPONENT_CHROMA || component_type == COMPONENT_CHROMA_CB) {
1859
0
        svt_aom_residual_kernel(input_pic->u_buffer,
1860
0
                                input_cb_origin_in_index,
1861
0
                                input_pic->u_stride,
1862
0
                                cand_bf->pred->u_buffer,
1863
0
                                blk_chroma_origin_index,
1864
0
                                cand_bf->pred->u_stride,
1865
0
                                (int16_t*)cand_bf->residual->u_buffer,
1866
0
                                blk_chroma_origin_index,
1867
0
                                cand_bf->residual->u_stride,
1868
0
                                SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
1869
0
                                ctx->blk_geom->bwidth_uv,
1870
0
                                ctx->blk_geom->bheight_uv);
1871
1872
        // Cb Transform
1873
0
        svt_aom_estimate_transform(pcs,
1874
0
                                   ctx,
1875
0
                                   &(((int16_t*)cand_bf->residual->u_buffer)[blk_chroma_origin_index]),
1876
0
                                   cand_bf->residual->u_stride,
1877
0
                                   &(((int32_t*)ctx->tx_coeffs->u_buffer)[0]),
1878
0
                                   NOT_USED_VALUE,
1879
0
                                   tx_size_uv,
1880
0
                                   &ctx->three_quad_energy,
1881
0
                                   SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
1882
0
                                   cand_bf->cand->transform_type_uv,
1883
0
                                   PLANE_TYPE_UV,
1884
0
                                   pf_shape);
1885
0
        cand_bf->quant_dc.u[0] = svt_aom_quantize_inv_quantize(
1886
0
            pcs,
1887
0
            ctx,
1888
0
            &(((int32_t*)ctx->tx_coeffs->u_buffer)[0]),
1889
0
            &(((int32_t*)cand_bf->quant->u_buffer)[0]),
1890
0
            &(((int32_t*)cand_bf->rec_coeff->u_buffer)[0]),
1891
0
            chroma_qindex,
1892
0
            0,
1893
0
            tx_size_uv,
1894
0
            &cand_bf->eob.u[0],
1895
0
            COMPONENT_CHROMA_CB,
1896
0
            SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
1897
0
            cand_bf->cand->transform_type_uv,
1898
0
            0,
1899
0
            0,
1900
0
            cand_bf->cand->block_mi.mode,
1901
0
            full_lambda,
1902
0
            false);
1903
1904
0
        svt_aom_picture_full_distortion32_bits_single(&(((int32_t*)ctx->tx_coeffs->u_buffer)[0]),
1905
0
                                                      &(((int32_t*)cand_bf->rec_coeff->u_buffer)[0]),
1906
0
                                                      tx_width_uv,
1907
0
                                                      bwidth,
1908
0
                                                      bheight,
1909
0
                                                      cb_full_distortion,
1910
0
                                                      cand_bf->eob.u[0]);
1911
0
        cb_full_distortion[DIST_CALC_RESIDUAL]   = RIGHT_SIGNED_SHIFT(cb_full_distortion[DIST_CALC_RESIDUAL],
1912
0
                                                                    chroma_shift);
1913
0
        cb_full_distortion[DIST_CALC_PREDICTION] = RIGHT_SIGNED_SHIFT(cb_full_distortion[DIST_CALC_PREDICTION],
1914
0
                                                                      chroma_shift);
1915
0
        cand_bf->u_has_coeff                     = (cand_bf->eob.u[0] > 0);
1916
0
    }
1917
1918
0
    pf_shape = ctx->pf_ctrls.pf_shape;
1919
    // If Cr component not detected as complex, can use TX shortcuts
1920
0
    if (ctx->use_tx_shortcuts_mds3 &&
1921
0
        (ctx->chroma_complexity == COMPONENT_LUMA || ctx->chroma_complexity == COMPONENT_CHROMA_CB)) {
1922
0
        pf_shape = N4_SHAPE;
1923
0
    } else {
1924
0
        uint8_t use_pfn4_cond = 0;
1925
0
        if (ctx->lpd1_tx_ctrls.use_uv_shortcuts_on_y_coeffs &&
1926
0
            (ctx->chroma_complexity == COMPONENT_LUMA || ctx->chroma_complexity == COMPONENT_CHROMA_CB)) {
1927
0
            const uint16_t th = ((tx_width_uv >> 4) * (tx_height_uv >> 4));
1928
0
            use_pfn4_cond     = (cand_bf->cnt_nz_coeff < th) || !cand_bf->block_has_coeff ? 1 : 0;
1929
0
        }
1930
0
        if (use_pfn4_cond) {
1931
0
            pf_shape = N4_SHAPE;
1932
0
        }
1933
0
    }
1934
0
    bwidth  = tx_width_uv;
1935
0
    bheight = tx_height_uv;
1936
0
    if (pf_shape) {
1937
0
        bwidth  = MAX((bwidth >> pf_shape), 4);
1938
0
        bheight = (bheight >> pf_shape);
1939
0
    }
1940
1941
0
    if (component_type == COMPONENT_CHROMA || component_type == COMPONENT_CHROMA_CR) {
1942
        //Cr Residual
1943
0
        svt_aom_residual_kernel(input_pic->v_buffer,
1944
0
                                input_cb_origin_in_index,
1945
0
                                input_pic->v_stride,
1946
0
                                cand_bf->pred->v_buffer,
1947
0
                                blk_chroma_origin_index,
1948
0
                                cand_bf->pred->v_stride,
1949
0
                                (int16_t*)cand_bf->residual->v_buffer,
1950
0
                                blk_chroma_origin_index,
1951
0
                                cand_bf->residual->v_stride,
1952
0
                                SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
1953
0
                                ctx->blk_geom->bwidth_uv,
1954
0
                                ctx->blk_geom->bheight_uv);
1955
        // Cr Transform
1956
0
        svt_aom_estimate_transform(pcs,
1957
0
                                   ctx,
1958
0
                                   &(((int16_t*)cand_bf->residual->v_buffer)[blk_chroma_origin_index]),
1959
0
                                   cand_bf->residual->v_stride,
1960
0
                                   &(((int32_t*)ctx->tx_coeffs->v_buffer)[0]),
1961
0
                                   NOT_USED_VALUE,
1962
0
                                   tx_size_uv,
1963
0
                                   &ctx->three_quad_energy,
1964
0
                                   SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
1965
0
                                   cand_bf->cand->transform_type_uv,
1966
0
                                   PLANE_TYPE_UV,
1967
0
                                   pf_shape);
1968
0
        cand_bf->quant_dc.v[0] = svt_aom_quantize_inv_quantize(
1969
0
            pcs,
1970
0
            ctx,
1971
0
            &(((int32_t*)ctx->tx_coeffs->v_buffer)[0]),
1972
0
            &(((int32_t*)cand_bf->quant->v_buffer)[0]),
1973
0
            &(((int32_t*)cand_bf->rec_coeff->v_buffer)[0]),
1974
0
            chroma_qindex,
1975
0
            0,
1976
0
            tx_size_uv,
1977
0
            &cand_bf->eob.v[0],
1978
0
            COMPONENT_CHROMA_CR,
1979
0
            SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
1980
0
            cand_bf->cand->transform_type_uv,
1981
0
            0,
1982
0
            0,
1983
0
            cand_bf->cand->block_mi.mode,
1984
0
            full_lambda,
1985
0
            false);
1986
1987
0
        svt_aom_picture_full_distortion32_bits_single(&(((int32_t*)ctx->tx_coeffs->v_buffer)[0]),
1988
0
                                                      &(((int32_t*)cand_bf->rec_coeff->v_buffer)[0]),
1989
0
                                                      tx_width_uv,
1990
0
                                                      bwidth,
1991
0
                                                      bheight,
1992
0
                                                      cr_full_distortion,
1993
0
                                                      cand_bf->eob.v[0]);
1994
1995
0
        cr_full_distortion[DIST_CALC_RESIDUAL]   = RIGHT_SIGNED_SHIFT(cr_full_distortion[DIST_CALC_RESIDUAL],
1996
0
                                                                    chroma_shift);
1997
0
        cr_full_distortion[DIST_CALC_PREDICTION] = RIGHT_SIGNED_SHIFT(cr_full_distortion[DIST_CALC_PREDICTION],
1998
0
                                                                      chroma_shift);
1999
0
        cand_bf->v_has_coeff                     = (cand_bf->eob.v[0] > 0);
2000
0
    }
2001
2002
    //CHROMA-ONLY
2003
0
    if (!skip_chroma_rate_est(ctx, cand_bf, component_type, tx_width_uv, tx_height_uv, cb_coeff_bits, cr_coeff_bits)) {
2004
0
        svt_aom_txb_estimate_coeff_bits(ctx,
2005
0
                                        0,
2006
0
                                        NULL,
2007
0
                                        pcs,
2008
0
                                        cand_bf,
2009
0
                                        NOT_USED_VALUE,
2010
0
                                        0,
2011
0
                                        cand_bf->quant,
2012
0
                                        NOT_USED_VALUE,
2013
0
                                        cand_bf->eob.u[0],
2014
0
                                        cand_bf->eob.v[0],
2015
0
                                        NOT_USED_VALUE,
2016
0
                                        cb_coeff_bits,
2017
0
                                        cr_coeff_bits,
2018
0
                                        NOT_USED_VALUE,
2019
0
                                        tx_size_uv,
2020
0
                                        NOT_USED_VALUE,
2021
0
                                        cand_bf->cand->transform_type_uv,
2022
0
                                        component_type);
2023
0
    }
2024
0
}
2025
2026
/****************************************
2027
 ************  Full loop ****************
2028
****************************************/
2029
void svt_aom_full_loop_uv(PictureControlSet* pcs, ModeDecisionContext* ctx, ModeDecisionCandidateBuffer* cand_bf,
2030
                          EbPictureBufferDesc* input_pic, COMPONENT_TYPE component_type, uint32_t chroma_qindex,
2031
                          uint64_t cb_full_distortion[DIST_TOTAL][DIST_CALC_TOTAL],
2032
                          uint64_t cr_full_distortion[DIST_TOTAL][DIST_CALC_TOTAL], uint64_t* cb_coeff_bits,
2033
154k
                          uint64_t* cr_coeff_bits, bool is_full_loop) {
2034
154k
    EbSpatialFullDistType spatial_full_dist_type_fun = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md)
2035
154k
        ? svt_full_distortion_kernel16_bits
2036
154k
        : svt_spatial_full_distortion_kernel;
2037
154k
    EB_ALIGN(16) uint64_t txb_full_distortion[DIST_TOTAL][3][DIST_CALC_TOTAL];
2038
154k
    const SsimLevel       ssim_level = ctx->tune_ssim_level;
2039
154k
    if (ssim_level > SSIM_LVL_0) {
2040
0
        assert(ctx->pd_pass == PD_PASS_1);
2041
0
        assert(ctx->md_stage == MD_STAGE_3);
2042
0
    }
2043
154k
    cand_bf->u_has_coeff = 0;
2044
154k
    cand_bf->v_has_coeff = 0;
2045
154k
    int16_t* chroma_residual_ptr;
2046
154k
    uint32_t full_lambda = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? ctx->full_lambda_md[EB_10_BIT_MD]
2047
154k
                                                             : ctx->full_lambda_md[EB_8_BIT_MD];
2048
2049
154k
    ctx->three_quad_energy = 0;
2050
2051
154k
    const double effective_ac_bias = get_effective_ac_bias(
2052
154k
        pcs->scs->static_config.ac_bias, pcs->slice_type == I_SLICE, pcs->temporal_layer_index);
2053
154k
    const uint8_t tx_depth     = cand_bf->cand->block_mi.tx_depth;
2054
154k
    const TxSize  tx_size      = av1_get_tx_size(ctx->blk_geom->bsize, tx_depth, PLANE_TYPE_Y);
2055
154k
    const TxSize  tx_size_uv   = av1_get_max_uv_txsize(ctx->blk_geom->bsize, 1, 1);
2056
154k
    const int     tx_width_uv  = tx_size_wide[tx_size_uv];
2057
154k
    const int     tx_height_uv = tx_size_high[tx_size_uv];
2058
154k
    const bool    is_inter = (is_inter_mode(cand_bf->cand->block_mi.mode) || cand_bf->cand->block_mi.use_intrabc) ? true
2059
154k
                                                                                                                  : false;
2060
154k
    const int     tu_count = tx_depth ? 1 : tx_blocks_per_depth[ctx->blk_geom->bsize][tx_depth]; //NM: 128x128 exeption
2061
154k
    uint32_t      txb_1d_offset = 0;
2062
2063
154k
    int txb_itr = 0;
2064
154k
    do {
2065
154k
        const uint32_t txb_origin_x        = tx_org[ctx->blk_geom->bsize][is_inter][tx_depth][txb_itr].x;
2066
154k
        const uint32_t txb_origin_y        = tx_org[ctx->blk_geom->bsize][is_inter][tx_depth][txb_itr].y;
2067
154k
        int32_t        cropped_tx_width_uv = MIN(
2068
154k
            (uint32_t)tx_width_uv, (pcs->ppcs->aligned_width >> 1) - ((ROUND_UV(ctx->blk_org_x + txb_origin_x)) >> 1));
2069
154k
        int32_t cropped_tx_height_uv = MIN(
2070
154k
            (uint32_t)tx_height_uv,
2071
154k
            (pcs->ppcs->aligned_height >> 1) - ((ROUND_UV(ctx->blk_org_y + txb_origin_y)) >> 1));
2072
154k
        uint32_t tu_cb_origin_index = (ROUND_UV(txb_origin_x) +
2073
154k
                                       (ROUND_UV(txb_origin_y) * cand_bf->residual->u_stride)) >>
2074
154k
            1;
2075
154k
        uint32_t tu_cr_origin_index = (ROUND_UV(txb_origin_x) +
2076
154k
                                       (ROUND_UV(txb_origin_y) * cand_bf->residual->v_stride)) >>
2077
154k
            1;
2078
154k
        TxCoeffShape pf_shape = ctx->pf_ctrls.pf_shape;
2079
154k
        if (ctx->md_stage == MD_STAGE_3 && ctx->use_tx_shortcuts_mds3 && ctx->chroma_complexity == COMPONENT_LUMA) {
2080
0
            pf_shape = N4_SHAPE;
2081
0
        }
2082
        // for chroma path, use luma coeff info to make shortcut decisions (available even if MDS1 is skipped)
2083
154k
        else if (ctx->tx_shortcut_ctrls.apply_pf_on_coeffs && ctx->md_stage == MD_STAGE_3 &&
2084
0
                 ctx->chroma_complexity == COMPONENT_LUMA) {
2085
0
            uint8_t use_pfn4_cond = 0;
2086
2087
0
            const uint16_t th = (tx_width_uv >> 4) * (tx_height_uv >> 4);
2088
0
            use_pfn4_cond     = (cand_bf->cnt_nz_coeff < th) || !cand_bf->block_has_coeff ? 1 : 0;
2089
2090
0
            if (use_pfn4_cond) {
2091
0
                pf_shape = N4_SHAPE;
2092
0
            }
2093
0
        }
2094
        //    This function replaces the previous Intra Chroma mode if the LM fast
2095
        //    cost is better.
2096
        //    *Note - this might require that we have inv transform in the loop
2097
154k
        if (component_type == COMPONENT_CHROMA_CB || component_type == COMPONENT_CHROMA ||
2098
154k
            component_type == COMPONENT_ALL) {
2099
154k
            ctx->cb_txb_skip_context = 0;
2100
154k
            ctx->cb_dc_sign_context  = 0;
2101
154k
            if (ctx->rate_est_ctrls.update_skip_ctx_dc_sign_ctx) {
2102
0
                svt_aom_get_txb_ctx(pcs,
2103
0
                                    COMPONENT_CHROMA,
2104
0
                                    ctx->cb_dc_sign_level_coeff_na,
2105
0
                                    ROUND_UV(ctx->blk_org_x + txb_origin_x) >> 1,
2106
0
                                    ROUND_UV(ctx->blk_org_y + txb_origin_y) >> 1,
2107
0
                                    ctx->blk_geom->bsize_uv,
2108
0
                                    tx_size_uv,
2109
0
                                    &ctx->cb_txb_skip_context,
2110
0
                                    &ctx->cb_dc_sign_context);
2111
0
            }
2112
            // Configure the Chroma Residual Ptr
2113
2114
154k
            chroma_residual_ptr = &(((int16_t*)cand_bf->residual->u_buffer)[tu_cb_origin_index]);
2115
2116
            // Cb Transform
2117
154k
            svt_aom_estimate_transform(pcs,
2118
154k
                                       ctx,
2119
154k
                                       chroma_residual_ptr,
2120
154k
                                       cand_bf->residual->u_stride,
2121
154k
                                       &(((int32_t*)ctx->tx_coeffs->u_buffer)[txb_1d_offset]),
2122
154k
                                       NOT_USED_VALUE,
2123
154k
                                       tx_size_uv,
2124
154k
                                       &ctx->three_quad_energy,
2125
154k
                                       SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
2126
154k
                                       cand_bf->cand->transform_type_uv,
2127
154k
                                       PLANE_TYPE_UV,
2128
154k
                                       pf_shape);
2129
2130
154k
            int32_t seg_qp               = pcs->ppcs->frm_hdr.segmentation_params.segmentation_enabled
2131
154k
                              ? pcs->ppcs->frm_hdr.segmentation_params.feature_data[ctx->blk_ptr->segment_id][SEG_LVL_ALT_Q]
2132
154k
                              : 0;
2133
154k
            cand_bf->quant_dc.u[txb_itr] = svt_aom_quantize_inv_quantize(
2134
154k
                pcs,
2135
154k
                ctx,
2136
154k
                &(((int32_t*)ctx->tx_coeffs->u_buffer)[txb_1d_offset]),
2137
154k
                &(((int32_t*)cand_bf->quant->u_buffer)[txb_1d_offset]),
2138
154k
                &(((int32_t*)cand_bf->rec_coeff->u_buffer)[txb_1d_offset]),
2139
154k
                chroma_qindex,
2140
154k
                seg_qp,
2141
154k
                tx_size_uv,
2142
154k
                &cand_bf->eob.u[txb_itr],
2143
154k
                COMPONENT_CHROMA_CB,
2144
154k
                SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
2145
154k
                cand_bf->cand->transform_type_uv,
2146
154k
                ctx->cb_txb_skip_context,
2147
154k
                ctx->cb_dc_sign_context,
2148
154k
                cand_bf->cand->block_mi.mode,
2149
154k
                full_lambda,
2150
154k
                false);
2151
2152
154k
            if (is_full_loop && ctx->mds_do_spatial_sse) {
2153
154k
                uint32_t cb_has_coeff = cand_bf->eob.u[txb_itr] > 0;
2154
2155
154k
                if (cb_has_coeff) {
2156
5.78k
                    svt_aom_inv_transform_recon_wrapper(pcs,
2157
5.78k
                                                        ctx,
2158
5.78k
                                                        cand_bf->pred->u_buffer,
2159
5.78k
                                                        tu_cb_origin_index,
2160
5.78k
                                                        cand_bf->pred->u_stride,
2161
5.78k
                                                        cand_bf->recon->u_buffer,
2162
5.78k
                                                        tu_cb_origin_index,
2163
5.78k
                                                        cand_bf->recon->u_stride,
2164
5.78k
                                                        (int32_t*)cand_bf->rec_coeff->u_buffer,
2165
5.78k
                                                        txb_1d_offset,
2166
5.78k
                                                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2167
5.78k
                                                        tx_size_uv,
2168
5.78k
                                                        cand_bf->cand->transform_type_uv,
2169
5.78k
                                                        PLANE_TYPE_UV,
2170
5.78k
                                                        (uint32_t)cand_bf->eob.u[txb_itr]);
2171
148k
                } else {
2172
148k
                    svt_av1_picture_copy_cb(cand_bf->pred,
2173
148k
                                            tu_cb_origin_index,
2174
148k
                                            cand_bf->recon,
2175
148k
                                            tu_cb_origin_index,
2176
148k
                                            tx_width_uv,
2177
148k
                                            tx_height_uv,
2178
148k
                                            SVT_EFFECTIVE_HBD_MD(ctx->hbd_md));
2179
148k
                }
2180
2181
154k
                const uint32_t input_chroma_txb_origin_index = ((ROUND_UV(ctx->blk_org_x + txb_origin_x)) >> 1) +
2182
154k
                    ((ROUND_UV(ctx->blk_org_y + txb_origin_y)) >> 1) * input_pic->u_stride;
2183
154k
                const int32_t txb_uv_origin_index = (ROUND_UV(txb_origin_x) +
2184
154k
                                                     (ROUND_UV(txb_origin_y) * cand_bf->quant->u_stride)) >>
2185
154k
                    1;
2186
2187
154k
                if (ssim_level == SSIM_LVL_1 || ssim_level == SSIM_LVL_3) {
2188
0
                    txb_full_distortion[DIST_SSIM][1][DIST_CALC_PREDICTION] = svt_spatial_full_distortion_ssim_kernel(
2189
0
                        input_pic->u_buffer,
2190
0
                        input_chroma_txb_origin_index,
2191
0
                        input_pic->u_stride,
2192
0
                        cand_bf->pred->u_buffer,
2193
0
                        txb_uv_origin_index,
2194
0
                        cand_bf->pred->u_stride,
2195
0
                        cropped_tx_width_uv,
2196
0
                        cropped_tx_height_uv,
2197
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2198
0
                        effective_ac_bias);
2199
2200
0
                    txb_full_distortion[DIST_SSIM][1][DIST_CALC_RESIDUAL] = svt_spatial_full_distortion_ssim_kernel(
2201
0
                        input_pic->u_buffer,
2202
0
                        input_chroma_txb_origin_index,
2203
0
                        input_pic->u_stride,
2204
0
                        cand_bf->recon->u_buffer,
2205
0
                        txb_uv_origin_index,
2206
0
                        cand_bf->recon->u_stride,
2207
0
                        cropped_tx_width_uv,
2208
0
                        cropped_tx_height_uv,
2209
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2210
0
                        effective_ac_bias);
2211
2212
0
                    txb_full_distortion[DIST_SSIM][1][DIST_CALC_PREDICTION] <<= 4;
2213
0
                    txb_full_distortion[DIST_SSIM][1][DIST_CALC_RESIDUAL] <<= 4;
2214
0
                }
2215
154k
                txb_full_distortion[DIST_SSD][1][DIST_CALC_PREDICTION] = spatial_full_dist_type_fun(
2216
154k
                    input_pic->u_buffer,
2217
154k
                    input_chroma_txb_origin_index,
2218
154k
                    input_pic->u_stride,
2219
154k
                    cand_bf->pred->u_buffer,
2220
154k
                    txb_uv_origin_index,
2221
154k
                    cand_bf->pred->u_stride,
2222
154k
                    cropped_tx_width_uv,
2223
154k
                    cropped_tx_height_uv);
2224
154k
                if (effective_ac_bias) {
2225
0
                    txb_full_distortion[DIST_SSD][1][DIST_CALC_PREDICTION] += get_svt_psy_full_dist(
2226
0
                        input_pic->u_buffer,
2227
0
                        input_chroma_txb_origin_index,
2228
0
                        input_pic->u_stride,
2229
0
                        cand_bf->pred->u_buffer,
2230
0
                        txb_uv_origin_index,
2231
0
                        cand_bf->pred->u_stride,
2232
0
                        cropped_tx_width_uv,
2233
0
                        cropped_tx_height_uv,
2234
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2235
0
                        effective_ac_bias);
2236
0
                }
2237
2238
154k
                txb_full_distortion[DIST_SSD][1][DIST_CALC_RESIDUAL] = spatial_full_dist_type_fun(
2239
154k
                    input_pic->u_buffer,
2240
154k
                    input_chroma_txb_origin_index,
2241
154k
                    input_pic->u_stride,
2242
154k
                    cand_bf->recon->u_buffer,
2243
154k
                    txb_uv_origin_index,
2244
154k
                    cand_bf->recon->u_stride,
2245
154k
                    cropped_tx_width_uv,
2246
154k
                    cropped_tx_height_uv);
2247
154k
                if (effective_ac_bias) {
2248
0
                    txb_full_distortion[DIST_SSD][1][DIST_CALC_RESIDUAL] += get_svt_psy_full_dist(
2249
0
                        input_pic->u_buffer,
2250
0
                        input_chroma_txb_origin_index,
2251
0
                        input_pic->u_stride,
2252
0
                        cand_bf->recon->u_buffer,
2253
0
                        txb_uv_origin_index,
2254
0
                        cand_bf->recon->u_stride,
2255
0
                        cropped_tx_width_uv,
2256
0
                        cropped_tx_height_uv,
2257
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2258
0
                        effective_ac_bias);
2259
0
                }
2260
2261
154k
                txb_full_distortion[DIST_SSD][1][DIST_CALC_PREDICTION] <<= 4;
2262
154k
                txb_full_distortion[DIST_SSD][1][DIST_CALC_RESIDUAL] <<= 4;
2263
18.4E
            } else {
2264
                // *Full Distortion (SSE)
2265
                // *Note - there are known issues with how this distortion metric is currently
2266
                //    calculated.  The amount of scaling between the two arrays is not
2267
                //    equivalent.
2268
18.4E
                uint32_t bwidth  = tx_width_uv;
2269
18.4E
                uint32_t bheight = tx_height_uv;
2270
18.4E
                if (pf_shape) {
2271
0
                    bwidth  = MAX((bwidth >> pf_shape), 4);
2272
0
                    bheight = (bheight >> pf_shape);
2273
0
                }
2274
18.4E
                svt_aom_picture_full_distortion32_bits_single(
2275
18.4E
                    &(((int32_t*)ctx->tx_coeffs->u_buffer)[txb_1d_offset]),
2276
18.4E
                    &(((int32_t*)cand_bf->rec_coeff->u_buffer)[txb_1d_offset]),
2277
18.4E
                    tx_width_uv,
2278
18.4E
                    bwidth,
2279
18.4E
                    bheight,
2280
18.4E
                    txb_full_distortion[DIST_SSD][1],
2281
18.4E
                    cand_bf->eob.u[txb_itr]);
2282
2283
18.4E
                const int32_t chroma_shift = (MAX_TX_SCALE - av1_get_tx_scale_tab[tx_size_uv]) * 2;
2284
18.4E
                txb_full_distortion[DIST_SSD][1][DIST_CALC_RESIDUAL] = RIGHT_SIGNED_SHIFT(
2285
18.4E
                    txb_full_distortion[DIST_SSD][1][DIST_CALC_RESIDUAL], chroma_shift);
2286
18.4E
                txb_full_distortion[DIST_SSD][1][DIST_CALC_PREDICTION] = RIGHT_SIGNED_SHIFT(
2287
18.4E
                    txb_full_distortion[DIST_SSD][1][DIST_CALC_PREDICTION], chroma_shift);
2288
18.4E
            }
2289
154k
            cand_bf->u_has_coeff |= ((cand_bf->eob.u[txb_itr] != 0) << txb_itr);
2290
154k
            cb_full_distortion[DIST_SSIM][DIST_CALC_RESIDUAL] += txb_full_distortion[DIST_SSIM][1][DIST_CALC_RESIDUAL];
2291
154k
            cb_full_distortion[DIST_SSIM][DIST_CALC_PREDICTION] +=
2292
154k
                txb_full_distortion[DIST_SSIM][1][DIST_CALC_PREDICTION];
2293
2294
154k
            cb_full_distortion[DIST_SSD][DIST_CALC_RESIDUAL] += txb_full_distortion[DIST_SSD][1][DIST_CALC_RESIDUAL];
2295
154k
            cb_full_distortion[DIST_SSD][DIST_CALC_PREDICTION] +=
2296
154k
                txb_full_distortion[DIST_SSD][1][DIST_CALC_PREDICTION];
2297
154k
        }
2298
2299
154k
        if (component_type == COMPONENT_CHROMA_CR || component_type == COMPONENT_CHROMA ||
2300
154k
            component_type == COMPONENT_ALL) {
2301
154k
            ctx->cr_txb_skip_context = 0;
2302
154k
            ctx->cr_dc_sign_context  = 0;
2303
154k
            if (ctx->rate_est_ctrls.update_skip_ctx_dc_sign_ctx) {
2304
0
                svt_aom_get_txb_ctx(pcs,
2305
0
                                    COMPONENT_CHROMA,
2306
0
                                    ctx->cr_dc_sign_level_coeff_na,
2307
0
                                    ROUND_UV(ctx->blk_org_x + txb_origin_x) >> 1,
2308
0
                                    ROUND_UV(ctx->blk_org_y + txb_origin_y) >> 1,
2309
0
                                    ctx->blk_geom->bsize_uv,
2310
0
                                    tx_size_uv,
2311
0
                                    &ctx->cr_txb_skip_context,
2312
0
                                    &ctx->cr_dc_sign_context);
2313
0
            }
2314
            // Configure the Chroma Residual Ptr
2315
2316
154k
            chroma_residual_ptr = &(((int16_t*)cand_bf->residual->v_buffer)[tu_cr_origin_index]);
2317
2318
            // Cr Transform
2319
154k
            svt_aom_estimate_transform(pcs,
2320
154k
                                       ctx,
2321
154k
                                       chroma_residual_ptr,
2322
154k
                                       cand_bf->residual->v_stride,
2323
154k
                                       &(((int32_t*)ctx->tx_coeffs->v_buffer)[txb_1d_offset]),
2324
154k
                                       NOT_USED_VALUE,
2325
154k
                                       tx_size_uv,
2326
154k
                                       &ctx->three_quad_energy,
2327
154k
                                       SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
2328
154k
                                       cand_bf->cand->transform_type_uv,
2329
154k
                                       PLANE_TYPE_UV,
2330
154k
                                       pf_shape);
2331
154k
            int32_t seg_qp               = pcs->ppcs->frm_hdr.segmentation_params.segmentation_enabled
2332
154k
                              ? pcs->ppcs->frm_hdr.segmentation_params.feature_data[ctx->blk_ptr->segment_id][SEG_LVL_ALT_Q]
2333
154k
                              : 0;
2334
154k
            cand_bf->quant_dc.v[txb_itr] = svt_aom_quantize_inv_quantize(
2335
154k
                pcs,
2336
154k
                ctx,
2337
154k
                &(((int32_t*)ctx->tx_coeffs->v_buffer)[txb_1d_offset]),
2338
154k
                &(((int32_t*)cand_bf->quant->v_buffer)[txb_1d_offset]),
2339
154k
                &(((int32_t*)cand_bf->rec_coeff->v_buffer)[txb_1d_offset]),
2340
154k
                chroma_qindex,
2341
154k
                seg_qp,
2342
154k
                tx_size_uv,
2343
154k
                &cand_bf->eob.v[txb_itr],
2344
154k
                COMPONENT_CHROMA_CR,
2345
154k
                SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT,
2346
154k
                cand_bf->cand->transform_type_uv,
2347
154k
                ctx->cr_txb_skip_context,
2348
154k
                ctx->cr_dc_sign_context,
2349
154k
                cand_bf->cand->block_mi.mode,
2350
154k
                full_lambda,
2351
154k
                false);
2352
154k
            if (is_full_loop && ctx->mds_do_spatial_sse) {
2353
154k
                uint32_t cr_has_coeff = cand_bf->eob.v[txb_itr] > 0;
2354
2355
154k
                if (cr_has_coeff) {
2356
5.78k
                    svt_aom_inv_transform_recon_wrapper(pcs,
2357
5.78k
                                                        ctx,
2358
5.78k
                                                        cand_bf->pred->v_buffer,
2359
5.78k
                                                        tu_cr_origin_index,
2360
5.78k
                                                        cand_bf->pred->v_stride,
2361
5.78k
                                                        cand_bf->recon->v_buffer,
2362
5.78k
                                                        tu_cr_origin_index,
2363
5.78k
                                                        cand_bf->recon->v_stride,
2364
5.78k
                                                        (int32_t*)cand_bf->rec_coeff->v_buffer,
2365
5.78k
                                                        txb_1d_offset,
2366
5.78k
                                                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2367
5.78k
                                                        tx_size_uv,
2368
5.78k
                                                        cand_bf->cand->transform_type_uv,
2369
5.78k
                                                        PLANE_TYPE_UV,
2370
5.78k
                                                        (uint32_t)cand_bf->eob.v[txb_itr]);
2371
148k
                } else {
2372
148k
                    svt_av1_picture_copy_cr(cand_bf->pred,
2373
148k
                                            tu_cb_origin_index,
2374
148k
                                            cand_bf->recon,
2375
148k
                                            tu_cb_origin_index,
2376
148k
                                            tx_width_uv,
2377
148k
                                            tx_height_uv,
2378
148k
                                            SVT_EFFECTIVE_HBD_MD(ctx->hbd_md));
2379
148k
                }
2380
154k
                const uint32_t input_chroma_txb_origin_index = ((ROUND_UV(ctx->blk_org_x + txb_origin_x)) >> 1) +
2381
154k
                    ((ROUND_UV(ctx->blk_org_y + txb_origin_y)) >> 1) * input_pic->v_stride;
2382
154k
                const int32_t txb_uv_origin_index = (ROUND_UV(txb_origin_x) +
2383
154k
                                                     (ROUND_UV(txb_origin_y) * cand_bf->quant->v_stride)) >>
2384
154k
                    1;
2385
2386
154k
                if (ssim_level == SSIM_LVL_1 || ssim_level == SSIM_LVL_3) {
2387
0
                    txb_full_distortion[DIST_SSIM][2][DIST_CALC_PREDICTION] = svt_spatial_full_distortion_ssim_kernel(
2388
0
                        input_pic->v_buffer,
2389
0
                        input_chroma_txb_origin_index,
2390
0
                        input_pic->v_stride,
2391
0
                        cand_bf->pred->v_buffer,
2392
0
                        txb_uv_origin_index,
2393
0
                        cand_bf->pred->v_stride,
2394
0
                        cropped_tx_width_uv,
2395
0
                        cropped_tx_height_uv,
2396
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2397
0
                        effective_ac_bias);
2398
2399
0
                    txb_full_distortion[DIST_SSIM][2][DIST_CALC_RESIDUAL] = svt_spatial_full_distortion_ssim_kernel(
2400
0
                        input_pic->v_buffer,
2401
0
                        input_chroma_txb_origin_index,
2402
0
                        input_pic->v_stride,
2403
0
                        cand_bf->recon->v_buffer,
2404
0
                        txb_uv_origin_index,
2405
0
                        cand_bf->recon->v_stride,
2406
0
                        cropped_tx_width_uv,
2407
0
                        cropped_tx_height_uv,
2408
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2409
0
                        effective_ac_bias);
2410
2411
0
                    txb_full_distortion[DIST_SSIM][2][DIST_CALC_PREDICTION] <<= 4;
2412
0
                    txb_full_distortion[DIST_SSIM][2][DIST_CALC_RESIDUAL] <<= 4;
2413
0
                }
2414
154k
                txb_full_distortion[DIST_SSD][2][DIST_CALC_PREDICTION] = spatial_full_dist_type_fun(
2415
154k
                    input_pic->v_buffer,
2416
154k
                    input_chroma_txb_origin_index,
2417
154k
                    input_pic->v_stride,
2418
154k
                    cand_bf->pred->v_buffer,
2419
154k
                    txb_uv_origin_index,
2420
154k
                    cand_bf->pred->v_stride,
2421
154k
                    cropped_tx_width_uv,
2422
154k
                    cropped_tx_height_uv);
2423
154k
                if (effective_ac_bias) {
2424
0
                    txb_full_distortion[DIST_SSD][2][DIST_CALC_PREDICTION] += get_svt_psy_full_dist(
2425
0
                        input_pic->v_buffer,
2426
0
                        input_chroma_txb_origin_index,
2427
0
                        input_pic->v_stride,
2428
0
                        cand_bf->pred->v_buffer,
2429
0
                        txb_uv_origin_index,
2430
0
                        cand_bf->pred->v_stride,
2431
0
                        cropped_tx_width_uv,
2432
0
                        cropped_tx_height_uv,
2433
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2434
0
                        effective_ac_bias);
2435
0
                }
2436
2437
154k
                txb_full_distortion[DIST_SSD][2][DIST_CALC_RESIDUAL] = spatial_full_dist_type_fun(
2438
154k
                    input_pic->v_buffer,
2439
154k
                    input_chroma_txb_origin_index,
2440
154k
                    input_pic->v_stride,
2441
154k
                    cand_bf->recon->v_buffer,
2442
154k
                    txb_uv_origin_index,
2443
154k
                    cand_bf->recon->v_stride,
2444
154k
                    cropped_tx_width_uv,
2445
154k
                    cropped_tx_height_uv);
2446
154k
                if (effective_ac_bias) {
2447
0
                    txb_full_distortion[DIST_SSD][2][DIST_CALC_RESIDUAL] += get_svt_psy_full_dist(
2448
0
                        input_pic->v_buffer,
2449
0
                        input_chroma_txb_origin_index,
2450
0
                        input_pic->v_stride,
2451
0
                        cand_bf->recon->v_buffer,
2452
0
                        txb_uv_origin_index,
2453
0
                        cand_bf->recon->v_stride,
2454
0
                        cropped_tx_width_uv,
2455
0
                        cropped_tx_height_uv,
2456
0
                        SVT_EFFECTIVE_HBD_MD(ctx->hbd_md),
2457
0
                        effective_ac_bias);
2458
0
                }
2459
2460
154k
                txb_full_distortion[DIST_SSD][2][DIST_CALC_PREDICTION] <<= 4;
2461
154k
                txb_full_distortion[DIST_SSD][2][DIST_CALC_RESIDUAL] <<= 4;
2462
18.4E
            } else {
2463
                // *Full Distortion (SSE)
2464
                // *Note - there are known issues with how this distortion metric is currently
2465
                //    calculated.  The amount of scaling between the two arrays is not
2466
                //    equivalent.
2467
18.4E
                uint32_t bwidth  = tx_width_uv;
2468
18.4E
                uint32_t bheight = tx_height_uv;
2469
18.4E
                if (pf_shape) {
2470
0
                    bwidth  = MAX((bwidth >> pf_shape), 4);
2471
0
                    bheight = (bheight >> pf_shape);
2472
0
                }
2473
18.4E
                svt_aom_picture_full_distortion32_bits_single(
2474
18.4E
                    &(((int32_t*)ctx->tx_coeffs->v_buffer)[txb_1d_offset]),
2475
18.4E
                    &(((int32_t*)cand_bf->rec_coeff->v_buffer)[txb_1d_offset]),
2476
18.4E
                    tx_width_uv,
2477
18.4E
                    bwidth,
2478
18.4E
                    bheight,
2479
18.4E
                    txb_full_distortion[DIST_SSD][2],
2480
18.4E
                    cand_bf->eob.v[txb_itr]);
2481
2482
18.4E
                const int32_t chroma_shift = (MAX_TX_SCALE - av1_get_tx_scale_tab[tx_size_uv]) * 2;
2483
18.4E
                txb_full_distortion[DIST_SSD][2][DIST_CALC_RESIDUAL] = RIGHT_SIGNED_SHIFT(
2484
18.4E
                    txb_full_distortion[DIST_SSD][2][DIST_CALC_RESIDUAL], chroma_shift);
2485
18.4E
                txb_full_distortion[DIST_SSD][2][DIST_CALC_PREDICTION] = RIGHT_SIGNED_SHIFT(
2486
18.4E
                    txb_full_distortion[DIST_SSD][2][DIST_CALC_PREDICTION], chroma_shift);
2487
18.4E
            }
2488
154k
            cand_bf->v_has_coeff |= ((cand_bf->eob.v[txb_itr] != 0) << txb_itr);
2489
154k
            cr_full_distortion[DIST_SSIM][DIST_CALC_RESIDUAL] += txb_full_distortion[DIST_SSIM][2][DIST_CALC_RESIDUAL];
2490
154k
            cr_full_distortion[DIST_SSIM][DIST_CALC_PREDICTION] +=
2491
154k
                txb_full_distortion[DIST_SSIM][2][DIST_CALC_PREDICTION];
2492
2493
154k
            cr_full_distortion[DIST_SSD][DIST_CALC_RESIDUAL] += txb_full_distortion[DIST_SSD][2][DIST_CALC_RESIDUAL];
2494
154k
            cr_full_distortion[DIST_SSD][DIST_CALC_PREDICTION] +=
2495
154k
                txb_full_distortion[DIST_SSD][2][DIST_CALC_PREDICTION];
2496
154k
        }
2497
2498
154k
        const uint32_t txb_origin_index = txb_origin_x + txb_origin_y * cand_bf->quant->y_stride;
2499
2500
        // Reset the Bit Costs
2501
154k
        uint64_t y_txb_coeff_bits  = 0;
2502
154k
        uint64_t cb_txb_coeff_bits = 0;
2503
154k
        uint64_t cr_txb_coeff_bits = 0;
2504
2505
154k
        if (!skip_chroma_rate_est(
2506
154k
                ctx, cand_bf, component_type, tx_width_uv, tx_height_uv, cb_coeff_bits, cr_coeff_bits)) {
2507
            //CHROMA-ONLY
2508
0
            svt_aom_txb_estimate_coeff_bits(ctx,
2509
0
                                            0,
2510
0
                                            NULL,
2511
0
                                            pcs,
2512
0
                                            cand_bf,
2513
0
                                            txb_origin_index,
2514
0
                                            txb_1d_offset,
2515
0
                                            cand_bf->quant,
2516
0
                                            cand_bf->eob.y[txb_itr],
2517
0
                                            cand_bf->eob.u[txb_itr],
2518
0
                                            cand_bf->eob.v[txb_itr],
2519
0
                                            &y_txb_coeff_bits,
2520
0
                                            &cb_txb_coeff_bits,
2521
0
                                            &cr_txb_coeff_bits,
2522
0
                                            tx_size,
2523
0
                                            tx_size_uv,
2524
0
                                            cand_bf->cand->transform_type[txb_itr],
2525
0
                                            cand_bf->cand->transform_type_uv,
2526
0
                                            component_type);
2527
2528
0
            *cb_coeff_bits += cb_txb_coeff_bits;
2529
0
            *cr_coeff_bits += cr_txb_coeff_bits;
2530
0
        }
2531
154k
        txb_1d_offset += tx_width_uv * tx_height_uv;
2532
2533
154k
        ++txb_itr;
2534
154k
    } while (txb_itr < tu_count);
2535
154k
}
2536
2537
/*
2538
  check if we need to do inverse transform and recon
2539
*/
2540
154k
uint8_t svt_aom_do_md_recon(PictureParentControlSet* pcs, ModeDecisionContext* ctx) {
2541
154k
    const uint8_t encdec_bypass = ctx->bypass_encdec &&
2542
154k
        (ctx->pd_pass == PD_PASS_1); // if enc dec is bypassed MD has to produce the final recon
2543
154k
    const uint8_t need_md_rec_for_intra_pred = !ctx->skip_intra ||
2544
0
        ctx->inter_intra_comp_ctrls.enabled; // for intra prediction of current frame
2545
154k
    const uint8_t need_md_rec_for_ref = (pcs->is_ref || pcs->scs->static_config.recon_enabled) &&
2546
0
        encdec_bypass; // for inter prediction of future frame or if recon is being output
2547
154k
    const uint8_t need_md_rec_for_dlf_search  = pcs->dlf_ctrls.enabled; // for DLF levels
2548
154k
    const uint8_t need_md_rec_for_cdef_search = pcs->cdef_search_ctrls.enabled &&
2549
154k
        !pcs->cdef_search_ctrls.use_qp_strength &&
2550
0
        !pcs->cdef_search_ctrls.use_reference_cdef_fs; // CDEF search levels needing the recon samples
2551
154k
    const uint8_t need_md_rec_for_restoration_search = pcs->enable_restoration; // any resoration search level
2552
154k
    const uint8_t need_md_rec_for_quality            = (pcs->compute_psnr || pcs->compute_ssim) &&
2553
0
        (ctx->pd_pass == PD_PASS_1); // stat report needs recon samples for metrics
2554
154k
    uint8_t do_recon;
2555
154k
    if (need_md_rec_for_intra_pred || need_md_rec_for_ref || need_md_rec_for_dlf_search ||
2556
154k
        need_md_rec_for_cdef_search || need_md_rec_for_restoration_search || need_md_rec_for_quality) {
2557
154k
        do_recon = 1;
2558
18.4E
    } else {
2559
18.4E
        do_recon = 0;
2560
18.4E
    }
2561
2562
154k
    return do_recon;
2563
154k
}