Coverage Report

Created: 2026-10-17 06:56

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