Coverage Report

Created: 2026-08-31 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/rd_cost.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 2 Clause License and
6
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
7
* was not distributed with this source code in the LICENSE file, you can
8
* obtain it at https://www.aomedia.org/license/software-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
/***************************************
14
* Includes
15
***************************************/
16
#include "rd_cost.h"
17
#include "mcomp.h" // svt_mv_cost (shared MV-rate helper; replaces local duplicate)
18
#include "common_utils.h"
19
#include "aom_dsp_rtcd.h"
20
#include "svt_log.h"
21
#include "enc_inter_prediction.h"
22
#include "full_loop.h"
23
#include "entropy_coding.h"
24
25
#include <assert.h>
26
27
0
#define MV_COST_WEIGHT 108
28
int svt_aom_get_reference_mode_context_new(const MacroBlockD* xd);
29
int svt_av1_get_pred_context_uni_comp_ref_p(const MacroBlockD* xd);
30
int svt_av1_get_pred_context_uni_comp_ref_p1(const MacroBlockD* xd);
31
int svt_av1_get_pred_context_uni_comp_ref_p2(const MacroBlockD* xd);
32
int svt_aom_get_comp_reference_type_context_new(const MacroBlockD* xd);
33
34
int  svt_aom_get_palette_bsize_ctx(BlockSize bsize);
35
int  svt_aom_get_palette_mode_ctx(const MacroBlockD* xd);
36
int  svt_aom_write_uniform_cost(int n, int v);
37
int  svt_get_palette_cache_y(const MacroBlockD* const xd, uint16_t* cache);
38
int  svt_av1_palette_color_cost_y(const PaletteModeInfo* const pmi, uint16_t* color_cache, const int palette_size,
39
                                  int n_cache, int bit_depth);
40
int  svt_av1_cost_color_map(ModeDecisionCandidate* cand, MdRateEstimationContext* rate_table,
41
42
                            BlkStruct* blk_ptr, int plane, BlockSize bsize, COLOR_MAP_TYPE type);
43
void svt_aom_get_block_dimensions(BlockSize bsize, int plane, const MacroBlockD* xd, int* width, int* height,
44
                                  int* rows_within_bounds, int* cols_within_bounds);
45
int  svt_aom_allow_palette(int allow_screen_content_tools, BlockSize bsize);
46
int  svt_aom_allow_intrabc(const FrameHeader* frm_hdr, SliceType slice_type);
47
48
0
int32_t svt_av1_mv_bit_cost_light(const Mv mv, const Mv ref) {
49
0
    const uint32_t factor     = 50;
50
0
    const uint32_t absmvdiffx = ABS(mv.x - ref.x);
51
0
    const uint32_t absmvdiffy = ABS(mv.y - ref.y);
52
0
    const uint32_t mv_rate    = 1296 + (factor * (absmvdiffx + absmvdiffy));
53
0
    return mv_rate;
54
0
}
55
56
int32_t svt_av1_mv_bit_cost(const Mv mv, const Mv ref, const int32_t* mvjcost, const int32_t* const mvcost[2],
57
0
                            int32_t weight) {
58
    // Restrict the size of the MV diff to be within the max AV1 range.  If the MV diff
59
    // is outside this range, the diff will index beyond the cost array, causing a seg fault.
60
    // Both the MVs and the MV diffs should be within the allowable range for accessing the MV cost
61
    // infrastructure.
62
0
    const int16_t x         = MIN(MAX(mv.x - ref.x, MV_LOW), MV_UPP);
63
0
    const int16_t y         = MIN(MAX(mv.y - ref.y, MV_LOW), MV_UPP);
64
0
    Mv            temp_diff = {{x, y}};
65
66
0
    return ROUND_POWER_OF_TWO(svt_mv_cost(temp_diff, mvjcost, mvcost) * weight, 7);
67
0
}
68
69
/////////////////////////////COEFFICIENT CALCULATION //////////////////////////////////////////////
70
0
static INLINE int32_t get_golomb_cost(int32_t abs_qc) {
71
0
    if (abs_qc >= 1 + NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
72
0
        const int32_t r      = abs_qc - COEFF_BASE_RANGE - NUM_BASE_LEVELS;
73
0
        const int32_t length = get_msb(r) + 1;
74
0
        return av1_cost_literal(2 * length - 1);
75
0
    }
76
0
    return 0;
77
0
}
78
79
void svt_av1_txb_init_levels_c(const TranLow* const coeff, const int32_t width, const int32_t height,
80
0
                               uint8_t* const levels) {
81
0
    uint8_t* ls = levels;
82
83
0
    for (int32_t i = 0; i < height; i++) {
84
0
        for (int32_t j = 0; j < width; j++) {
85
0
            *ls++ = (uint8_t)clamp(abs(coeff[i * width + j]), 0, INT8_MAX);
86
0
        }
87
0
        for (int32_t j = 0; j < TX_PAD_HOR; j++) {
88
0
            *ls++ = 0;
89
0
        }
90
0
    }
91
0
}
92
93
static int32_t av1_transform_type_rate_estimation(ModeDecisionContext* ctx, uint8_t allow_update_cdf, FRAME_CONTEXT* fc,
94
                                                  ModeDecisionCandidateBuffer* cand_bf, bool is_inter,
95
                                                  TxSize transform_size, TxType transform_type,
96
0
                                                  bool reduced_tx_set_used) {
97
    // const MbModeInfo *mbmi = &xd->mi[0]->mbmi;
98
    // const int32_t is_inter = is_inter_block(mbmi);
99
100
0
    if (get_ext_tx_types(transform_size, is_inter, reduced_tx_set_used) >
101
0
        1 /*&&    !xd->lossless[xd->mi[0]->mbmi.segment_id]  WE ARE NOT LOSSLESS*/) {
102
0
        const TxSize square_tx_size = txsize_sqr_map[transform_size];
103
0
        assert(square_tx_size < EXT_TX_SIZES);
104
105
0
        const int32_t ext_tx_set = get_ext_tx_set(transform_size, is_inter, reduced_tx_set_used);
106
0
        if (is_inter) {
107
0
            if (ext_tx_set > 0) {
108
0
                if (allow_update_cdf) {
109
0
                    const TxSetType tx_set_type = get_ext_tx_set_type(transform_size, is_inter, reduced_tx_set_used);
110
111
0
                    update_cdf(fc->inter_ext_tx_cdf[ext_tx_set][square_tx_size],
112
0
                               av1_ext_tx_ind[tx_set_type][transform_type],
113
0
                               av1_num_ext_tx_set[tx_set_type]);
114
0
                }
115
0
                return ctx->md_rate_est_ctx->inter_tx_type_fac_bits[ext_tx_set][square_tx_size][transform_type];
116
0
            }
117
0
        } else {
118
0
            if (ext_tx_set > 0) {
119
0
                PredictionMode intra_dir;
120
0
                if (cand_bf->cand->block_mi.filter_intra_mode != FILTER_INTRA_MODES) {
121
0
                    intra_dir = fimode_to_intradir[cand_bf->cand->block_mi.filter_intra_mode];
122
0
                } else {
123
0
                    intra_dir = cand_bf->cand->block_mi.mode;
124
0
                }
125
0
                assert(intra_dir < INTRA_MODES);
126
0
                const TxSetType tx_set_type = get_ext_tx_set_type(transform_size, is_inter, reduced_tx_set_used);
127
128
0
                if (allow_update_cdf) {
129
0
                    update_cdf(fc->intra_ext_tx_cdf[ext_tx_set][square_tx_size][intra_dir],
130
0
                               av1_ext_tx_ind[tx_set_type][transform_type],
131
0
                               av1_num_ext_tx_set[tx_set_type]);
132
0
                }
133
0
                return ctx->md_rate_est_ctx
134
0
                    ->intra_tx_type_fac_bits[ext_tx_set][square_tx_size][intra_dir][transform_type];
135
0
            }
136
0
        }
137
0
    }
138
0
    return 0;
139
0
}
140
141
// Update the eob-related CDFs. Function assumes allow_update_cdf is true
142
// as the only action of the function is to update the CDFs.
143
0
static void update_eob_context(int eob, TxSize tx_size, TxClass tx_class, PlaneType plane, FRAME_CONTEXT* ec_ctx) {
144
0
    int          eob_extra;
145
0
    const int    eob_pt  = get_eob_pos_token(eob, &eob_extra);
146
0
    const TxSize txs_ctx = (TxSize)((txsize_sqr_map[tx_size] + txsize_sqr_up_map[tx_size] + 1) >> 1);
147
0
    assert(txs_ctx < TX_SIZES);
148
0
    const int eob_multi_size = txsize_log2_minus4[tx_size];
149
0
    const int eob_multi_ctx  = (tx_class == TX_CLASS_2D) ? 0 : 1;
150
151
0
    switch (eob_multi_size) {
152
0
    case 0:
153
0
        update_cdf(ec_ctx->eob_flag_cdf16[plane][eob_multi_ctx], eob_pt - 1, 5);
154
0
        break;
155
0
    case 1:
156
0
        update_cdf(ec_ctx->eob_flag_cdf32[plane][eob_multi_ctx], eob_pt - 1, 6);
157
0
        break;
158
0
    case 2:
159
0
        update_cdf(ec_ctx->eob_flag_cdf64[plane][eob_multi_ctx], eob_pt - 1, 7);
160
0
        break;
161
0
    case 3:
162
0
        update_cdf(ec_ctx->eob_flag_cdf128[plane][eob_multi_ctx], eob_pt - 1, 8);
163
0
        break;
164
0
    case 4:
165
0
        update_cdf(ec_ctx->eob_flag_cdf256[plane][eob_multi_ctx], eob_pt - 1, 9);
166
0
        break;
167
0
    case 5:
168
0
        update_cdf(ec_ctx->eob_flag_cdf512[plane][eob_multi_ctx], eob_pt - 1, 10);
169
0
        break;
170
0
    case 6:
171
0
    default:
172
0
        update_cdf(ec_ctx->eob_flag_cdf1024[plane][eob_multi_ctx], eob_pt - 1, 11);
173
0
        break;
174
0
    }
175
176
0
    if (eob_pt > 2) {
177
0
        const int cnt = eob_pt - 3;
178
0
        const int bit = (eob_extra >> cnt) & 1;
179
0
        update_cdf(ec_ctx->eob_extra_cdf[txs_ctx][plane][cnt], bit, 2);
180
0
    }
181
0
}
182
183
// Transform end of block bit estimation
184
9.67k
int get_eob_cost(int eob, const LvMapEobCost* txb_eob_costs, const LvMapCoeffCost* txb_costs, TxClass tx_class) {
185
9.67k
    int       eob_extra;
186
9.67k
    const int eob_pt        = get_eob_pos_token(eob, &eob_extra);
187
9.67k
    const int eob_multi_ctx = (tx_class == TX_CLASS_2D) ? 0 : 1;
188
9.67k
    int       eob_cost      = txb_eob_costs->eob_cost[eob_multi_ctx][eob_pt - 1];
189
190
9.67k
    if (eob_pt > 2) {
191
0
        const int cnt = eob_pt - 3;
192
0
        const int bit = (eob_extra >> cnt) & 1;
193
0
        eob_cost += txb_costs->eob_extra_cost[cnt][bit];
194
0
        eob_cost += av1_cost_literal(cnt);
195
0
    }
196
9.67k
    return eob_cost;
197
9.67k
}
198
199
static INLINE int32_t av1_cost_skip_txb(ModeDecisionContext* ctx, uint8_t allow_update_cdf, FRAME_CONTEXT* ec_ctx,
200
0
                                        TxSize transform_size, PlaneType plane_type, int16_t txb_skip_ctx) {
201
0
    const TxSize txs_ctx = (TxSize)((txsize_sqr_map[transform_size] + txsize_sqr_up_map[transform_size] + 1) >> 1);
202
0
    assert(txs_ctx < TX_SIZES);
203
0
    const LvMapCoeffCost* const coeff_costs = &ctx->md_rate_est_ctx->coeff_fac_bits[txs_ctx][plane_type];
204
0
    if (allow_update_cdf) {
205
0
        update_cdf(ec_ctx->txb_skip_cdf[txs_ctx][txb_skip_ctx], 1, 2);
206
0
    }
207
0
    return coeff_costs->txb_skip_cost[txb_skip_ctx][1];
208
0
}
209
210
static INLINE int32_t av1_cost_coeffs_txb_loop_cost_one_eob(const TranLow* const qcoeff, int8_t* const coeff_contexts,
211
0
                                                            const LvMapCoeffCost* coeff_costs, int16_t dc_sign_ctx) {
212
0
    const TranLow v         = qcoeff[0];
213
0
    const int32_t level     = abs(v);
214
0
    const int32_t coeff_ctx = coeff_contexts[0];
215
216
0
    assert((AOMMIN(level, 3) - 1) >= 0);
217
0
    int32_t cost = coeff_costs->base_eob_cost[coeff_ctx][AOMMIN(level, 3) - 1];
218
219
0
    if (v != 0) {
220
0
        const int32_t sign = (v < 0) ? 1 : 0;
221
        // sign bit cost
222
0
        cost += coeff_costs->dc_sign_cost[dc_sign_ctx][sign];
223
224
0
        if (level > NUM_BASE_LEVELS) {
225
0
            const int32_t base_range = level - 1 - NUM_BASE_LEVELS;
226
227
0
            if (base_range < COEFF_BASE_RANGE) {
228
0
                cost += coeff_costs->lps_cost[0][base_range];
229
0
            } else {
230
0
                cost += coeff_costs->lps_cost[0][COEFF_BASE_RANGE];
231
0
            }
232
233
0
            if (level >= 1 + NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
234
0
                cost += get_golomb_cost(level);
235
0
            }
236
0
        }
237
0
    }
238
0
    return cost;
239
0
}
240
241
static INLINE int32_t av1_cost_coeffs_txb_loop_cost_eob(ModeDecisionContext* md_ctx, uint16_t eob,
242
                                                        const int16_t* const scan, const TranLow* const qcoeff,
243
                                                        int8_t* const coeff_contexts, const LvMapCoeffCost* coeff_costs,
244
                                                        int16_t dc_sign_ctx, uint8_t* const levels, const int32_t bwl,
245
0
                                                        TxType transform_type) {
246
0
    const uint32_t cost_literal = av1_cost_literal(1);
247
0
    int32_t        cost         = 0;
248
249
    //Optimized/simplified function when eob is 1
250
0
    if (eob == 1) {
251
0
        return av1_cost_coeffs_txb_loop_cost_one_eob(qcoeff, coeff_contexts, coeff_costs, dc_sign_ctx);
252
0
    }
253
254
    //  first (eob - 1) index
255
0
    {
256
0
        const int32_t pos       = scan[eob - 1];
257
0
        const TranLow v         = qcoeff[pos];
258
0
        const int32_t level     = abs(v);
259
0
        const int32_t coeff_ctx = coeff_contexts[pos];
260
261
0
        assert((AOMMIN(level, 3) - 1) >= 0);
262
0
        cost += coeff_costs->base_eob_cost[coeff_ctx][AOMMIN(level, 3) - 1];
263
264
0
        if (v != 0) {
265
0
            cost += cost_literal;
266
0
            if (level > NUM_BASE_LEVELS) {
267
0
                int32_t       ctx        = get_br_ctx(levels, pos, bwl, tx_type_to_class[transform_type]);
268
0
                const int32_t base_range = level - 1 - NUM_BASE_LEVELS;
269
270
0
                if (base_range < COEFF_BASE_RANGE) {
271
0
                    cost += coeff_costs->lps_cost[ctx][base_range];
272
0
                } else {
273
0
                    cost += coeff_costs->lps_cost[ctx][COEFF_BASE_RANGE];
274
0
                }
275
276
0
                if (level >= 1 + NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
277
0
                    cost += get_golomb_cost(level);
278
0
                }
279
0
            }
280
0
        }
281
0
    }
282
    // last (0) index
283
0
    {
284
0
        const TranLow v         = qcoeff[0];
285
0
        const int32_t level     = abs(v);
286
0
        const int32_t coeff_ctx = coeff_contexts[0];
287
288
0
        cost += coeff_costs->base_cost[coeff_ctx][AOMMIN(level, 3)];
289
290
0
        if (v != 0) {
291
0
            const int32_t sign = (v < 0) ? 1 : 0;
292
            // sign bit cost
293
294
0
            cost += coeff_costs->dc_sign_cost[dc_sign_ctx][sign];
295
296
0
            if (level > NUM_BASE_LEVELS) {
297
0
                int32_t       ctx        = get_br_ctx(levels, 0, bwl, tx_type_to_class[transform_type]);
298
0
                const int32_t base_range = level - 1 - NUM_BASE_LEVELS;
299
300
0
                if (base_range < COEFF_BASE_RANGE) {
301
0
                    cost += coeff_costs->lps_cost[ctx][base_range];
302
0
                } else {
303
0
                    cost += coeff_costs->lps_cost[ctx][COEFF_BASE_RANGE];
304
0
                }
305
306
0
                if (level >= 1 + NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
307
0
                    cost += get_golomb_cost(level);
308
0
                }
309
0
            }
310
0
        }
311
0
    }
312
0
    int32_t c;
313
    /* Optimized Loop, omitted first (eob - 1) and last (0) index */
314
    // Estimate the rate of the first(eob / fast_coeff_est_level) coeff(s), DC and last coeff only
315
0
    int32_t  c_start = MIN(eob - 2, eob / MAX(1, (int)(md_ctx->mds_fast_coeff_est_level - md_ctx->mds_subres_step)));
316
0
    uint32_t cost_literal_cnt = 0;
317
0
    for (c = c_start; c >= 1; --c) {
318
0
        const int32_t pos = scan[c];
319
0
        cost_literal_cnt += !!(qcoeff[pos]);
320
0
        const int32_t level = abs(qcoeff[pos]);
321
0
        if (level > NUM_BASE_LEVELS) {
322
0
            int32_t       ctx        = get_br_ctx(levels, pos, bwl, tx_type_to_class[transform_type]);
323
0
            const int32_t base_range = level - 1 - NUM_BASE_LEVELS;
324
325
0
            cost += coeff_costs->base_cost[coeff_contexts[pos]][3];
326
0
            if (base_range < COEFF_BASE_RANGE) {
327
0
                cost += coeff_costs->lps_cost[ctx][base_range];
328
0
            } else {
329
0
                cost += get_golomb_cost(level) + coeff_costs->lps_cost[ctx][COEFF_BASE_RANGE];
330
0
            }
331
0
        } else {
332
0
            cost += coeff_costs->base_cost[coeff_contexts[pos]][level];
333
0
        }
334
0
    }
335
0
    cost += cost_literal_cnt * cost_literal;
336
337
0
    return cost;
338
0
}
339
340
// Note: don't call this function when eob is 0.
341
uint64_t svt_av1_cost_coeffs_txb(ModeDecisionContext* ctx, uint8_t allow_update_cdf, FRAME_CONTEXT* ec_ctx,
342
                                 ModeDecisionCandidateBuffer* cand_bf, const TranLow* const qcoeff, uint16_t eob,
343
                                 PlaneType plane_type, TxSize transform_size, TxType transform_type,
344
                                 int16_t txb_skip_ctx, int16_t dc_sign_ctx, bool reduced_transform_set_flag)
345
346
0
{
347
    //Note: there is a different version of this function in AOM that seems to be efficient as its name is:
348
    //warehouse_efficients_txb
349
350
0
    const TxSize  txs_ctx  = get_txsize_entropy_ctx(transform_size);
351
0
    const TxClass tx_class = tx_type_to_class[transform_type];
352
0
    int32_t       cost;
353
0
    const int32_t bwl    = get_txb_bwl(transform_size);
354
0
    const int32_t width  = get_txb_wide(transform_size);
355
0
    const int32_t height = get_txb_high(transform_size);
356
357
0
    const ScanOrder* const scan_order     = get_scan_order(transform_size, transform_type);
358
0
    const int16_t* const   scan           = scan_order->scan;
359
0
    uint8_t* const         levels         = set_levels(ctx->md_levels_buf, width, height);
360
0
    int8_t* const          coeff_contexts = ctx->md_coeff_contexts;
361
0
    assert(txs_ctx < TX_SIZES);
362
0
    const LvMapCoeffCost* const coeff_costs = &ctx->md_rate_est_ctx->coeff_fac_bits[txs_ctx][plane_type];
363
364
0
    const int32_t             eob_multi_size = txsize_log2_minus4[transform_size];
365
0
    const LvMapEobCost* const eob_bits       = &ctx->md_rate_est_ctx->eob_frac_bits[eob_multi_size][plane_type];
366
    // eob must be greater than 0 here.
367
0
    assert(eob > 0);
368
0
    cost = coeff_costs->txb_skip_cost[txb_skip_ctx][0];
369
370
0
    if (allow_update_cdf) {
371
0
        update_cdf(ec_ctx->txb_skip_cdf[txs_ctx][txb_skip_ctx], eob == 0, 2);
372
0
    }
373
374
0
    if (eob > 1) {
375
0
        svt_av1_txb_init_levels(qcoeff,
376
0
                                width,
377
0
                                height,
378
0
                                levels); // NM - Needs to be optimized - to be combined with the quantisation.
379
0
    }
380
0
    const bool is_inter = is_inter_mode(cand_bf->cand->block_mi.mode);
381
    // Transform type bit estimation
382
0
    cost += plane_type > PLANE_TYPE_Y ? 0
383
0
                                      : av1_transform_type_rate_estimation(ctx,
384
0
                                                                           allow_update_cdf,
385
0
                                                                           ec_ctx,
386
0
                                                                           cand_bf,
387
0
                                                                           is_inter,
388
0
                                                                           transform_size,
389
0
                                                                           transform_type,
390
0
                                                                           reduced_transform_set_flag);
391
392
    // Transform eob bit estimation
393
0
    cost += get_eob_cost(eob, eob_bits, coeff_costs, tx_class);
394
0
    if (allow_update_cdf) {
395
0
        update_eob_context(eob, transform_size, tx_class, plane_type, ec_ctx);
396
0
    }
397
    // Transform non-zero coeff bit estimation
398
0
    svt_av1_get_nz_map_contexts(levels,
399
0
                                scan,
400
0
                                eob,
401
0
                                transform_size,
402
0
                                tx_class,
403
0
                                coeff_contexts); // NM - Assembly version is available in AOM
404
0
    assert(eob <= width * height);
405
0
    if (allow_update_cdf) {
406
0
        for (int c = eob - 1; c >= 0; --c) {
407
0
            const int     pos       = scan[c];
408
0
            const int     coeff_ctx = coeff_contexts[pos];
409
0
            const TranLow v         = qcoeff[pos];
410
0
            const TranLow level     = abs(v);
411
0
            if (c == eob - 1) {
412
0
                assert(coeff_ctx < 4);
413
0
                update_cdf(ec_ctx->coeff_base_eob_cdf[txs_ctx][plane_type][coeff_ctx], AOMMIN(level, 3) - 1, 3);
414
0
            } else {
415
0
                update_cdf(ec_ctx->coeff_base_cdf[txs_ctx][plane_type][coeff_ctx], AOMMIN(level, 3), 4);
416
0
            }
417
418
0
            {
419
0
                if (c == eob - 1) {
420
0
                    assert(coeff_ctx < 4);
421
0
                }
422
0
            }
423
424
0
            if (level > NUM_BASE_LEVELS) {
425
0
                const int base_range = level - 1 - NUM_BASE_LEVELS;
426
0
                int       br_ctx;
427
0
                if (eob == 1) {
428
0
                    br_ctx = 0;
429
0
                } else {
430
0
                    br_ctx = get_br_ctx(levels, pos, bwl, tx_class);
431
0
                }
432
433
0
                for (int idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) {
434
0
                    const int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1);
435
0
                    update_cdf(ec_ctx->coeff_br_cdf[AOMMIN(txs_ctx, TX_32X32)][plane_type][br_ctx], k, BR_CDF_SIZE);
436
0
                    for (int lps = 0; lps < BR_CDF_SIZE - 1; lps++) {
437
0
                        if (lps == k) {
438
0
                            break;
439
0
                        }
440
0
                    }
441
0
                    if (k < BR_CDF_SIZE - 1) {
442
0
                        break;
443
0
                    }
444
0
                }
445
0
            }
446
0
        }
447
448
0
        if (qcoeff[0] != 0) {
449
0
            update_cdf(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], qcoeff[0] < 0, 2);
450
0
        }
451
452
        //TODO: CHKN  for 128x128 where we need more than one TXb, we need to update the txb_context(dc_sign+skip_ctx) in a Txb basis.
453
454
0
        return 0;
455
0
    }
456
457
0
    cost += av1_cost_coeffs_txb_loop_cost_eob(
458
0
        ctx, eob, scan, qcoeff, coeff_contexts, coeff_costs, dc_sign_ctx, levels, bwl, transform_type);
459
0
    return cost;
460
0
}
461
462
uint64_t svt_aom_get_intra_uv_fast_rate(PictureControlSet* pcs, ModeDecisionContext* ctx,
463
157k
                                        ModeDecisionCandidateBuffer* cand_bf, bool use_accurate_cfl) {
464
157k
    const BlockGeom* const blk_geom = ctx->blk_geom;
465
157k
    ModeDecisionCandidate* cand     = cand_bf->cand;
466
157k
    assert(ctx->has_uv);
467
157k
    assert(!(svt_aom_allow_intrabc(&pcs->ppcs->frm_hdr, pcs->ppcs->slice_type) && cand->block_mi.use_intrabc));
468
157k
    MdRateEstimationContext* md_rate_est_ctx = ctx->md_rate_est_ctx;
469
157k
    const uint8_t            is_cfl_allowed  = (blk_geom->bwidth <= 32 && blk_geom->bheight <= 32) ? 1 : 0;
470
157k
    PredictionMode           intra_mode      = (PredictionMode)cand->block_mi.mode;
471
    // If CFL alphas are not known yet, calculate the chroma mode bits based on DC Mode. If CFL is selected the chroma mode bits must be updated later
472
157k
    const UvPredictionMode chroma_mode = cand->block_mi.uv_mode == UV_CFL_PRED && !use_accurate_cfl
473
157k
        ? UV_DC_PRED
474
157k
        : cand->block_mi.uv_mode;
475
157k
    const uint32_t         mi_row      = ctx->blk_org_y >> MI_SIZE_LOG2;
476
157k
    const uint32_t         mi_col      = ctx->blk_org_x >> MI_SIZE_LOG2;
477
    // Subsampling assumes YUV 420 content
478
157k
    const uint8_t ss_x = 1;
479
157k
    const uint8_t ss_y = 1;
480
481
157k
    uint64_t chroma_rate = 0;
482
    // Estimate chroma nominal intra mode bits
483
157k
    chroma_rate += (uint64_t)md_rate_est_ctx->intra_uv_mode_fac_bits[is_cfl_allowed][intra_mode][chroma_mode];
484
485
    // Estimate chroma angular mode bits; angular offset only allow for bsize >= 8x8
486
157k
    if (blk_geom->bsize >= BLOCK_8X8 && av1_is_directional_mode(get_uv_mode(chroma_mode))) {
487
0
        chroma_rate +=
488
0
            md_rate_est_ctx->angle_delta_fac_bits[chroma_mode - V_PRED]
489
0
                                                 [MAX_ANGLE_DELTA + cand->block_mi.angle_delta[PLANE_TYPE_UV]];
490
0
    }
491
492
    // Estimate CFL factor bits when CFL is used
493
157k
    if (chroma_mode == UV_CFL_PRED) {
494
0
        chroma_rate += (uint64_t)md_rate_est_ctx->cfl_alpha_fac_bits[cand->block_mi.cfl_alpha_signs][CFL_PRED_U]
495
0
                                                                    [CFL_IDX_U(cand->block_mi.cfl_alpha_idx)] +
496
0
            (uint64_t)md_rate_est_ctx->cfl_alpha_fac_bits[cand->block_mi.cfl_alpha_signs][CFL_PRED_V]
497
0
                                                         [CFL_IDX_V(cand->block_mi.cfl_alpha_idx)];
498
0
    }
499
500
    // Estimate chroma palette mode bits (currently not supported, so just cost of signalling off)
501
157k
    if (chroma_mode == UV_DC_PRED &&
502
157k
        svt_aom_allow_palette(pcs->ppcs->frm_hdr.allow_screen_content_tools, blk_geom->bsize) &&
503
0
        is_chroma_reference(mi_row, mi_col, blk_geom->bsize, ss_x, ss_y)) {
504
0
        const int use_palette_y  = cand->palette_info && (cand->palette_size[0] > 0);
505
0
        const int use_palette_uv = cand->palette_info && (cand->palette_size[1] > 0);
506
0
        chroma_rate += ctx->md_rate_est_ctx->palette_uv_mode_fac_bits[use_palette_y][use_palette_uv];
507
0
    }
508
509
157k
    return chroma_rate;
510
157k
}
511
512
uint64_t svt_aom_intra_fast_cost(PictureControlSet* pcs, ModeDecisionContext* ctx, ModeDecisionCandidateBuffer* cand_bf,
513
157k
                                 uint64_t lambda, uint64_t luma_distortion) {
514
157k
    const BlockGeom*       blk_geom = ctx->blk_geom;
515
157k
    BlkStruct*             blk_ptr  = ctx->blk_ptr;
516
157k
    ModeDecisionCandidate* cand     = cand_bf->cand;
517
157k
    if (svt_aom_allow_intrabc(&pcs->ppcs->frm_hdr, pcs->ppcs->slice_type) && cand->block_mi.use_intrabc) {
518
0
        uint64_t rate = 0;
519
520
0
        Mv         mv        = {.as_int = cand->block_mi.mv[0].as_int};
521
0
        Mv         ref_mv    = {.as_int = cand->pred_mv[0].as_int};
522
0
        const int* dvcost[2] = {(int*)&ctx->md_rate_est_ctx->dv_cost[0][MV_MAX],
523
0
                                (int*)&ctx->md_rate_est_ctx->dv_cost[1][MV_MAX]};
524
0
        int32_t    mv_rate   = svt_av1_mv_bit_cost(
525
0
            mv, ref_mv, ctx->md_rate_est_ctx->dv_joint_cost, dvcost, MV_COST_WEIGHT_SUB);
526
527
0
        rate                      = mv_rate + ctx->md_rate_est_ctx->intrabc_fac_bits[cand->block_mi.use_intrabc];
528
0
        cand_bf->fast_luma_rate   = rate;
529
0
        cand_bf->fast_chroma_rate = 0;
530
0
        return (RDCOST(lambda, rate, luma_distortion));
531
157k
    } else {
532
        // Number of bits for each synatax element
533
157k
        uint64_t       intra_mode_bits_num          = 0;
534
157k
        uint64_t       intra_luma_mode_bits_num     = 0;
535
157k
        uint64_t       intra_luma_ang_mode_bits_num = 0;
536
157k
        uint64_t       intra_filter_mode_bits_num   = 0;
537
157k
        uint64_t       skip_mode_rate               = 0;
538
157k
        const uint8_t  skip_mode_ctx                = ctx->skip_mode_ctx;
539
157k
        PredictionMode intra_mode                   = (PredictionMode)cand->block_mi.mode;
540
        // Luma and chroma rate
541
157k
        uint32_t rate;
542
157k
        uint32_t luma_rate   = 0;
543
157k
        uint32_t chroma_rate = 0;
544
157k
        intra_mode_bits_num  = pcs->slice_type != I_SLICE
545
157k
             ? (uint64_t)ctx->md_rate_est_ctx->mb_mode_fac_bits[eb_size_group_lookup[blk_geom->bsize]][intra_mode]
546
157k
             : ZERO_COST;
547
548
157k
        skip_mode_rate = pcs->slice_type != I_SLICE && pcs->ppcs->frm_hdr.skip_mode_params.skip_mode_flag &&
549
0
                is_comp_ref_allowed(blk_geom->bsize)
550
157k
            ? (uint64_t)ctx->md_rate_est_ctx->skip_mode_fac_bits[skip_mode_ctx][0]
551
157k
            : ZERO_COST;
552
        // Estimate luma nominal intra mode bits for key frame
553
157k
        intra_luma_mode_bits_num = pcs->slice_type == I_SLICE
554
157k
            ? (uint64_t)
555
157k
                  ctx->md_rate_est_ctx->y_mode_fac_bits[ctx->intra_luma_top_ctx][ctx->intra_luma_left_ctx][intra_mode]
556
18.4E
            : ZERO_COST;
557
        // Estimate luma angular mode bits
558
157k
        if (blk_geom->bsize >= BLOCK_8X8 && av1_is_directional_mode(cand->block_mi.mode)) {
559
0
            assert((intra_mode - V_PRED) < 8);
560
0
            assert((intra_mode - V_PRED) >= 0);
561
0
            intra_luma_ang_mode_bits_num =
562
0
                ctx->md_rate_est_ctx->angle_delta_fac_bits[intra_mode - V_PRED]
563
0
                                                          [MAX_ANGLE_DELTA + cand->block_mi.angle_delta[PLANE_TYPE_Y]];
564
0
        }
565
157k
        if (svt_aom_allow_palette(pcs->ppcs->frm_hdr.allow_screen_content_tools, blk_geom->bsize) &&
566
0
            intra_mode == DC_PRED) {
567
0
            const int use_palette = cand->palette_info ? (cand->palette_size[0] > 0) : 0;
568
0
            const int bsize_ctx   = svt_aom_get_palette_bsize_ctx(blk_geom->bsize);
569
0
            const int mode_ctx    = svt_aom_get_palette_mode_ctx(blk_ptr->av1xd);
570
0
            intra_luma_mode_bits_num += ctx->md_rate_est_ctx->palette_ymode_fac_bits[bsize_ctx][mode_ctx][use_palette];
571
0
            if (use_palette) {
572
0
                const uint8_t* const color_map = cand->palette_info->color_idx_map;
573
0
                int                  block_width, block_height, rows, cols;
574
0
                svt_aom_get_block_dimensions(
575
0
                    blk_geom->bsize, 0, blk_ptr->av1xd, &block_width, &block_height, &rows, &cols);
576
0
                const int plt_size = cand->palette_size[0];
577
0
                int       palette_mode_cost =
578
0
                    ctx->md_rate_est_ctx->palette_ysize_fac_bits[bsize_ctx][plt_size - PALETTE_MIN_SIZE] +
579
0
                    svt_aom_write_uniform_cost(plt_size, color_map[0]);
580
0
                uint16_t  color_cache[2 * PALETTE_MAX_SIZE];
581
0
                const int n_cache = svt_get_palette_cache_y(blk_ptr->av1xd, color_cache);
582
0
                palette_mode_cost += svt_av1_palette_color_cost_y(&cand->palette_info->pmi,
583
0
                                                                  color_cache,
584
0
                                                                  cand->palette_size[0],
585
0
                                                                  n_cache,
586
0
                                                                  pcs->ppcs->scs->encoder_bit_depth);
587
0
                palette_mode_cost += svt_av1_cost_color_map(
588
0
                    cand, ctx->md_rate_est_ctx, blk_ptr, 0, blk_geom->bsize, PALETTE_MAP);
589
0
                intra_luma_mode_bits_num += palette_mode_cost;
590
0
            }
591
0
        }
592
593
157k
        if (svt_aom_filter_intra_allowed(pcs->ppcs->scs->seq_header.filter_intra_level,
594
157k
                                         blk_geom->bsize,
595
157k
                                         cand->palette_info ? cand->palette_size[0] : 0,
596
157k
                                         intra_mode)) {
597
0
            intra_filter_mode_bits_num =
598
0
                ctx->md_rate_est_ctx
599
0
                    ->filter_intra_fac_bits[blk_geom->bsize][cand->block_mi.filter_intra_mode != FILTER_INTRA_MODES];
600
0
            if (cand->block_mi.filter_intra_mode != FILTER_INTRA_MODES) {
601
0
                intra_filter_mode_bits_num +=
602
0
                    ctx->md_rate_est_ctx->filter_intra_mode_fac_bits[cand->block_mi.filter_intra_mode];
603
0
            }
604
0
        }
605
157k
        if (ctx->has_uv) {
606
            // CFL info not known in fasta loop, so assume DC mode when CFL is allowed
607
157k
            chroma_rate = (uint32_t)svt_aom_get_intra_uv_fast_rate(pcs, ctx, cand_bf, 0);
608
157k
        }
609
610
157k
        uint32_t is_inter_rate = pcs->slice_type != I_SLICE
611
157k
            ? ctx->md_rate_est_ctx->intra_inter_fac_bits[ctx->is_inter_ctx][0]
612
157k
            : 0;
613
157k
        luma_rate              = (uint32_t)(intra_mode_bits_num + skip_mode_rate + intra_luma_mode_bits_num +
614
157k
                               intra_luma_ang_mode_bits_num + is_inter_rate + intra_filter_mode_bits_num);
615
157k
        if (svt_aom_allow_intrabc(&pcs->ppcs->frm_hdr, pcs->ppcs->slice_type)) {
616
0
            svt_aom_assert_err(cand->block_mi.use_intrabc == 0, "this block ibc should be off\n");
617
0
            luma_rate += ctx->md_rate_est_ctx->intrabc_fac_bits[cand->block_mi.use_intrabc];
618
0
        }
619
        // Keep the Fast Luma and Chroma rate for future use
620
157k
        cand_bf->fast_luma_rate   = luma_rate;
621
157k
        cand_bf->fast_chroma_rate = chroma_rate;
622
157k
        rate                      = luma_rate + chroma_rate;
623
        // Assign fast cost
624
157k
        return (RDCOST(lambda, rate, luma_distortion));
625
157k
    }
626
157k
}
627
628
// This function encodes the reference frame
629
uint64_t estimate_ref_frame_type_bits(ModeDecisionContext* ctx, BlkStruct* blk_ptr, uint8_t ref_frame_type,
630
0
                                      bool is_compound) {
631
0
    uint64_t ref_rate_bits = 0;
632
633
0
    MbModeInfo* const mbmi = blk_ptr->av1xd->mi[0];
634
0
    MvReferenceFrame  ref_type[2];
635
0
    av1_set_ref_frame(ref_type, ref_frame_type);
636
0
    mbmi->block_mi.ref_frame[0] = ref_type[0];
637
0
    mbmi->block_mi.ref_frame[1] = ref_type[1];
638
    //const int is_compound = svt_aom_has_second_ref(mbmi);
639
0
    {
640
0
        if (is_compound) {
641
0
            const CompReferenceType comp_ref_type = has_uni_comp_refs(&mbmi->block_mi) ? UNIDIR_COMP_REFERENCE
642
0
                                                                                       : BIDIR_COMP_REFERENCE;
643
644
0
            ref_rate_bits += ctx->md_rate_est_ctx->comp_ref_type_fac_bits[svt_aom_get_comp_reference_type_context_new(
645
0
                blk_ptr->av1xd)][comp_ref_type];
646
            /*aom_write_symbol(w, comp_ref_type,
647
               svt_aom_get_comp_reference_type_cdf(blk_ptr->av1xd), 2);*/
648
649
0
            if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
650
                // SVT_LOG("ERROR[AN]: UNIDIR_COMP_REFERENCE not supported\n");
651
0
                const int bit = mbmi->block_mi.ref_frame[0] == BWDREF_FRAME;
652
653
0
                ref_rate_bits += ctx->md_rate_est_ctx->uni_comp_ref_fac_bits[svt_av1_get_pred_context_uni_comp_ref_p(
654
0
                    blk_ptr->av1xd)][0][bit];
655
                // blk_ptr->av1xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
656
                // WRITE_REF_BIT(bit, uni_comp_ref_p);
657
658
0
                if (!bit) {
659
0
                    assert(mbmi->block_mi.ref_frame[0] == LAST_FRAME);
660
0
                    const int bit1 = mbmi->block_mi.ref_frame[1] == LAST3_FRAME ||
661
0
                        mbmi->block_mi.ref_frame[1] == GOLDEN_FRAME;
662
0
                    ref_rate_bits +=
663
0
                        ctx->md_rate_est_ctx
664
0
                            ->uni_comp_ref_fac_bits[svt_av1_get_pred_context_uni_comp_ref_p1(blk_ptr->av1xd)][1][bit1];
665
                    // ref_rate_d = blk_ptr->av1xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
666
                    // WRITE_REF_BIT(bit1, uni_comp_ref_p1);
667
0
                    if (bit1) {
668
0
                        const int bit2 = mbmi->block_mi.ref_frame[1] == GOLDEN_FRAME;
669
0
                        ref_rate_bits +=
670
0
                            ctx->md_rate_est_ctx->uni_comp_ref_fac_bits[svt_av1_get_pred_context_uni_comp_ref_p2(
671
0
                                blk_ptr->av1xd)][2][bit2];
672
673
                        // ref_rate_e = blk_ptr->av1xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
674
                        //WRITE_REF_BIT(bit2, uni_comp_ref_p2);
675
0
                    }
676
0
                }
677
0
                return ref_rate_bits;
678
0
            }
679
680
0
            assert(comp_ref_type == BIDIR_COMP_REFERENCE);
681
682
0
            const int bit = (mbmi->block_mi.ref_frame[0] == GOLDEN_FRAME || mbmi->block_mi.ref_frame[0] == LAST3_FRAME);
683
0
            const int pred_ctx = svt_av1_get_pred_context_comp_ref_p(blk_ptr->av1xd);
684
0
            ref_rate_bits += ctx->md_rate_est_ctx->comp_ref_fac_bits[pred_ctx][0][bit];
685
            // ref_rate_f = blk_ptr->av1xd->tile_ctx->comp_ref_cdf[pred_ctx][0];
686
            // WRITE_REF_BIT(bit, comp_ref_p);
687
688
0
            if (!bit) {
689
0
                const int bit1 = mbmi->block_mi.ref_frame[0] == LAST2_FRAME;
690
0
                ref_rate_bits += ctx->md_rate_est_ctx
691
0
                                     ->comp_ref_fac_bits[svt_av1_get_pred_context_comp_ref_p1(blk_ptr->av1xd)][1][bit1];
692
                // ref_rate_g = blk_ptr->av1xd->tile_ctx->comp_ref_cdf[pred_context][1];
693
                // WRITE_REF_BIT(bit1, comp_ref_p1);
694
0
            } else {
695
0
                const int bit2 = mbmi->block_mi.ref_frame[0] == GOLDEN_FRAME;
696
0
                ref_rate_bits += ctx->md_rate_est_ctx
697
0
                                     ->comp_ref_fac_bits[svt_av1_get_pred_context_comp_ref_p2(blk_ptr->av1xd)][2][bit2];
698
                // ref_rate_h = blk_ptr->av1xd->tile_ctx->comp_ref_cdf[pred_context][2];
699
                // WRITE_REF_BIT(bit2, comp_ref_p2);
700
0
            }
701
702
0
            const int bit_bwd    = mbmi->block_mi.ref_frame[1] == ALTREF_FRAME;
703
0
            const int pred_ctx_2 = svt_av1_get_pred_context_comp_bwdref_p(blk_ptr->av1xd);
704
0
            ref_rate_bits += ctx->md_rate_est_ctx->comp_bwd_ref_fac_bits[pred_ctx_2][0][bit_bwd];
705
            // ref_rate_i = blk_ptr->av1xd->tile_ctx->comp_bwdref_cdf[pred_ctx_2][0];
706
            // WRITE_REF_BIT(bit_bwd, comp_bwdref_p);
707
708
0
            if (!bit_bwd) {
709
0
                ref_rate_bits += ctx->md_rate_est_ctx->comp_bwd_ref_fac_bits[svt_av1_get_pred_context_comp_bwdref_p1(
710
0
                    blk_ptr->av1xd)][1][ref_type[1] == ALTREF2_FRAME];
711
                // ref_rate_j = blk_ptr->av1xd->tile_ctx->comp_bwdref_cdf[pred_context][1];
712
                // WRITE_REF_BIT(mbmi->block_mi.ref_frame[1] == ALTREF2_FRAME, comp_bwdref_p1);
713
0
            }
714
0
        } else {
715
0
            const int bit0 = (mbmi->block_mi.ref_frame[0] <= ALTREF_FRAME &&
716
0
                              mbmi->block_mi.ref_frame[0] >= BWDREF_FRAME);
717
0
            ref_rate_bits += ctx->md_rate_est_ctx
718
0
                                 ->single_ref_fac_bits[svt_av1_get_pred_context_single_ref_p1(blk_ptr->av1xd)][0][bit0];
719
            // ref_rate_k =
720
            // blk_ptr->av1xd->tile_ctx->single_ref_cdf[svt_av1_get_pred_context_single_ref_p1(blk_ptr->av1xd)][0];
721
            // WRITE_REF_BIT(bit0, single_ref_p1);
722
723
0
            if (bit0) {
724
0
                const int bit1 = mbmi->block_mi.ref_frame[0] == ALTREF_FRAME;
725
0
                ref_rate_bits += ctx->md_rate_est_ctx->single_ref_fac_bits[svt_av1_get_pred_context_single_ref_p2(
726
0
                    blk_ptr->av1xd)][1][bit1];
727
                // ref_rate_l =
728
                // blk_ptr->av1xd->tile_ctx->single_ref_cdf[svt_av1_get_pred_context_single_ref_p2(blk_ptr->av1xd)][1];
729
                // WRITE_REF_BIT(bit1, single_ref_p2);
730
0
                if (!bit1) {
731
0
                    ref_rate_bits += ctx->md_rate_est_ctx->single_ref_fac_bits[svt_av1_get_pred_context_single_ref_p6(
732
0
                        blk_ptr->av1xd)][5][ref_frame_type == ALTREF2_FRAME];
733
                    // ref_rate_m =
734
                    // blk_ptr->av1xd->tile_ctx->single_ref_cdf[svt_av1_get_pred_context_single_ref_p6(blk_ptr->av1xd)][5];
735
                    // WRITE_REF_BIT(mbmi->block_mi.ref_frame[0] == ALTREF2_FRAME, single_ref_p6);
736
0
                }
737
0
            } else {
738
0
                const int bit2 = (mbmi->block_mi.ref_frame[0] == LAST3_FRAME ||
739
0
                                  mbmi->block_mi.ref_frame[0] == GOLDEN_FRAME);
740
0
                ref_rate_bits += ctx->md_rate_est_ctx->single_ref_fac_bits[svt_av1_get_pred_context_single_ref_p3(
741
0
                    blk_ptr->av1xd)][2][bit2];
742
                // ref_rate_n =
743
                // blk_ptr->av1xd->tile_ctx->single_ref_cdf[svt_av1_get_pred_context_single_ref_p3(blk_ptr->av1xd)][2];
744
                // WRITE_REF_BIT(bit2, single_ref_p3);
745
0
                if (!bit2) {
746
0
                    const int bit3 = mbmi->block_mi.ref_frame[0] != LAST_FRAME;
747
0
                    ref_rate_bits += ctx->md_rate_est_ctx->single_ref_fac_bits[svt_av1_get_pred_context_single_ref_p4(
748
0
                        blk_ptr->av1xd)][3][bit3];
749
                    // ref_rate_o =
750
                    // blk_ptr->av1xd->tile_ctx->single_ref_cdf[svt_av1_get_pred_context_single_ref_p4(blk_ptr->av1xd)][3];
751
                    // WRITE_REF_BIT(bit3, single_ref_p4);
752
0
                } else {
753
0
                    const int bit4 = mbmi->block_mi.ref_frame[0] != LAST3_FRAME;
754
0
                    ref_rate_bits += ctx->md_rate_est_ctx->single_ref_fac_bits[svt_av1_get_pred_context_single_ref_p5(
755
0
                        blk_ptr->av1xd)][4][bit4];
756
                    // ref_rate_p =
757
                    // blk_ptr->av1xd->tile_ctx->single_ref_cdf[svt_av1_get_pred_context_single_ref_p5(blk_ptr->av1xd)][4];
758
                    // WRITE_REF_BIT(bit4, single_ref_p5);
759
0
                }
760
0
            }
761
0
        }
762
0
    }
763
0
    return ref_rate_bits;
764
0
}
765
766
int svt_aom_get_comp_group_idx_context_enc(const MacroBlockD* xd);
767
int is_any_masked_compound_used(BlockSize bsize);
768
769
static INLINE uint32_t get_compound_mode_rate(PictureControlSet* pcs, ModeDecisionContext* ctx,
770
0
                                              ModeDecisionCandidate* cand, BlockSize bsize) {
771
0
    BlkStruct*          blk_ptr   = ctx->blk_ptr;
772
0
    SequenceControlSet* scs       = pcs->ppcs->scs;
773
0
    uint32_t            comp_rate = 0;
774
0
    MbModeInfo* const   mbmi      = blk_ptr->av1xd->mi[0];
775
0
    MvReferenceFrame    rf[2]     = {cand->block_mi.ref_frame[0], cand->block_mi.ref_frame[1]};
776
0
    mbmi->block_mi.ref_frame[0]   = rf[0];
777
0
    mbmi->block_mi.ref_frame[1]   = rf[1];
778
779
    //NOTE  :  Make sure, any cuPtr data is already set before   usage
780
781
0
    if (has_second_ref(&mbmi->block_mi)) {
782
0
        const int masked_compound_used = is_any_masked_compound_used(bsize) && scs->seq_header.enable_masked_compound;
783
784
0
        if (masked_compound_used) {
785
0
            const int ctx_comp_group_idx = svt_aom_get_comp_group_idx_context_enc(blk_ptr->av1xd);
786
0
            comp_rate =
787
0
                ctx->md_rate_est_ctx->comp_group_idx_fac_bits[ctx_comp_group_idx][cand->block_mi.comp_group_idx];
788
0
        } else {
789
0
            assert(cand->block_mi.comp_group_idx == 0);
790
0
        }
791
792
0
        if (cand->block_mi.comp_group_idx == 0) {
793
0
            if (cand->block_mi.compound_idx) {
794
0
                assert(cand->block_mi.interinter_comp.type == COMPOUND_AVERAGE);
795
0
            }
796
797
0
            if (scs->seq_header.order_hint_info.enable_jnt_comp) {
798
0
                const int comp_index_ctx = svt_aom_get_comp_index_context_enc(pcs->ppcs,
799
0
                                                                              pcs->ppcs->cur_order_hint,
800
0
                                                                              pcs->ppcs->ref_order_hint[rf[0] - 1],
801
0
                                                                              pcs->ppcs->ref_order_hint[rf[1] - 1],
802
0
                                                                              blk_ptr->av1xd);
803
0
                comp_rate += ctx->md_rate_est_ctx->comp_idx_fac_bits[comp_index_ctx][cand->block_mi.compound_idx];
804
0
            } else {
805
0
                assert(cand->block_mi.compound_idx == 1);
806
0
            }
807
0
        } else {
808
0
            assert(pcs->ppcs->frm_hdr.reference_mode != SINGLE_REFERENCE &&
809
0
                   is_inter_compound_mode(cand->block_mi.mode));
810
0
            assert(masked_compound_used);
811
            // compound_diffwtd, wedge
812
0
            assert(cand->block_mi.interinter_comp.type == COMPOUND_WEDGE ||
813
0
                   cand->block_mi.interinter_comp.type == COMPOUND_DIFFWTD);
814
815
0
            if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
816
0
                comp_rate += ctx->md_rate_est_ctx
817
0
                                 ->compound_type_fac_bits[bsize][cand->block_mi.interinter_comp.type - COMPOUND_WEDGE];
818
0
            }
819
820
0
            if (cand->block_mi.interinter_comp.type == COMPOUND_WEDGE) {
821
0
                assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
822
0
                comp_rate +=
823
0
                    ctx->md_rate_est_ctx->wedge_idx_fac_bits[bsize][cand->block_mi.interinter_comp.wedge_index];
824
0
                comp_rate += av1_cost_literal(1);
825
0
            } else {
826
0
                assert(cand->block_mi.interinter_comp.type == COMPOUND_DIFFWTD);
827
0
                comp_rate += av1_cost_literal(1);
828
0
            }
829
0
        }
830
0
    }
831
832
0
    return comp_rate;
833
0
}
834
835
int32_t svt_aom_get_switchable_rate(BlockModeInfo* block_mi, const FrameHeader* const frm_hdr, ModeDecisionContext* ctx,
836
0
                                    const bool enable_dual_filter) {
837
0
    if (frm_hdr->interpolation_filter != SWITCHABLE) {
838
0
        return 0;
839
0
    }
840
841
0
    int32_t   inter_filter_cost = 0;
842
0
    const int max_dir           = enable_dual_filter ? 2 : 1;
843
0
    for (int dir = 0; dir < max_dir; ++dir) {
844
0
        const int32_t pred_ctx = svt_aom_get_pred_context_switchable_interp(
845
0
            block_mi->ref_frame[0], block_mi->ref_frame[1], ctx->blk_ptr->av1xd, dir);
846
0
        const InterpFilter filter = av1_extract_interp_filter(block_mi->interp_filters, dir);
847
0
        assert(pred_ctx < SWITCHABLE_FILTER_CONTEXTS);
848
0
        assert(filter < SWITCHABLE_FILTERS);
849
0
        inter_filter_cost += ctx->md_rate_est_ctx->switchable_interp_fac_bitss[pred_ctx][filter];
850
0
    }
851
0
    return inter_filter_cost;
852
0
}
853
854
int svt_aom_is_interintra_wedge_used(BlockSize bsize);
855
856
static uint64_t av1_inter_fast_cost_light(ModeDecisionContext* ctx, BlkStruct* blk_ptr,
857
                                          ModeDecisionCandidateBuffer* cand_bf, uint64_t luma_distortion,
858
0
                                          uint64_t lambda, PictureControlSet* pcs, CandidateMv* ref_mv_stack) {
859
0
    ModeDecisionCandidate* cand = cand_bf->cand;
860
    // NM - fast inter cost estimation
861
0
    MdRateEstimationContext* r = ctx->md_rate_est_ctx;
862
    //_mm_prefetch(p, _MM_HINT_T2);
863
    // Luma rate
864
0
    uint32_t             luma_rate           = 0;
865
0
    uint64_t             mv_rate             = 0;
866
0
    const PredictionMode inter_mode          = (PredictionMode)cand->block_mi.mode;
867
0
    const uint8_t        have_nearmv         = have_nearmv_in_inter_mode(inter_mode);
868
0
    uint64_t             inter_mode_bits_num = 0;
869
0
    const uint8_t        skip_mode_ctx       = ctx->skip_mode_ctx;
870
0
    MvReferenceFrame     rf[2]               = {cand->block_mi.ref_frame[0], cand->block_mi.ref_frame[1]};
871
0
    const int8_t         ref_frame_type      = av1_ref_frame_type(rf);
872
0
    const uint8_t        is_compound         = is_inter_compound_mode(cand->block_mi.mode);
873
0
    const uint32_t       mode_context        = svt_aom_mode_context_analyzer(ctx->inter_mode_ctx[ref_frame_type], rf);
874
0
    uint64_t             reference_picture_bits_num = 0;
875
0
    if (ctx->approx_inter_rate < 2) {
876
0
        reference_picture_bits_num = ctx->estimate_ref_frames_num_bits[ref_frame_type];
877
0
    }
878
0
    if (is_compound) {
879
0
        assert(INTER_COMPOUND_OFFSET(inter_mode) < INTER_COMPOUND_MODES);
880
0
        inter_mode_bits_num += r->inter_compound_mode_fac_bits[mode_context][INTER_COMPOUND_OFFSET(inter_mode)];
881
0
    } else {
882
0
        int16_t newmv_ctx = mode_context & NEWMV_CTX_MASK;
883
        //aom_write_symbol(ec_writer, mode != NEWMV, frame_context->newmv_cdf[newmv_ctx], 2);
884
0
        inter_mode_bits_num += r->new_mv_mode_fac_bits[newmv_ctx][inter_mode != NEWMV];
885
0
        if (inter_mode != NEWMV) {
886
0
            const int16_t zero_mv_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
887
            //aom_write_symbol(ec_writer, mode != GLOBALMV, frame_context->zeromv_cdf[zero_mv_ctx], 2);
888
0
            inter_mode_bits_num += r->zero_mv_mode_fac_bits[zero_mv_ctx][inter_mode != GLOBALMV];
889
0
            if (inter_mode != GLOBALMV) {
890
0
                int16_t ref_mv_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
891
                /*aom_write_symbol(ec_writer, mode != NEARESTMV, frame_context->refmv_cdf[refmv_ctx], 2);*/
892
0
                inter_mode_bits_num += r->ref_mv_mode_fac_bits[ref_mv_ctx][inter_mode != NEARESTMV];
893
0
            }
894
0
        }
895
0
    }
896
0
    if (inter_mode == NEWMV || inter_mode == NEW_NEWMV || have_nearmv) {
897
        //drLIdex cost estimation
898
0
        const int32_t new_mv = inter_mode == NEWMV || inter_mode == NEW_NEWMV;
899
0
        if (new_mv) {
900
0
            int32_t idx;
901
0
            for (idx = 0; idx < 2; ++idx) {
902
0
                if (blk_ptr->av1xd->ref_mv_count[ref_frame_type] > idx + 1) {
903
0
                    uint8_t drl_1_ctx = av1_drl_ctx(ref_mv_stack, idx);
904
0
                    inter_mode_bits_num += r->drl_mode_fac_bits[drl_1_ctx][cand->drl_index != idx];
905
0
                    if (cand->drl_index == idx) {
906
0
                        break;
907
0
                    }
908
0
                }
909
0
            }
910
0
        }
911
0
        if (have_nearmv) {
912
0
            int32_t idx;
913
0
            for (idx = 1; idx < 3; ++idx) {
914
0
                if (blk_ptr->av1xd->ref_mv_count[ref_frame_type] > idx + 1) {
915
0
                    uint8_t drl_ctx = av1_drl_ctx(ref_mv_stack, idx);
916
0
                    inter_mode_bits_num += r->drl_mode_fac_bits[drl_ctx][cand->drl_index != (idx - 1)];
917
0
                    if (cand->drl_index == (idx - 1)) {
918
0
                        break;
919
0
                    }
920
0
                }
921
0
            }
922
0
        }
923
0
    }
924
0
    if (svt_aom_have_newmv_in_inter_mode(inter_mode)) {
925
0
        const uint16_t factor = pcs->ppcs->frm_hdr.allow_screen_content_tools ? 20 : 50;
926
0
        if (is_compound) {
927
0
            mv_rate = 0;
928
0
            if (inter_mode == NEW_NEWMV) {
929
0
                for (RefList ref_list_idx = 0; ref_list_idx < 2; ++ref_list_idx) {
930
0
                    Mv             mv         = cand->block_mi.mv[ref_list_idx];
931
0
                    Mv             ref_mv     = cand->pred_mv[ref_list_idx];
932
0
                    const uint16_t absmvdiffx = ABS(mv.x - ref_mv.x);
933
0
                    const uint16_t absmvdiffy = ABS(mv.y - ref_mv.y);
934
0
                    mv_rate += 1296 + (factor * (absmvdiffx + absmvdiffy));
935
0
                }
936
0
            } else if (inter_mode == NEAREST_NEWMV || inter_mode == NEAR_NEWMV) {
937
                // New MV is second ref
938
0
                Mv             mv         = cand->block_mi.mv[1];
939
0
                Mv             ref_mv     = cand->pred_mv[1];
940
0
                const uint16_t absmvdiffx = ABS(mv.x - ref_mv.x);
941
0
                const uint16_t absmvdiffy = ABS(mv.y - ref_mv.y);
942
0
                mv_rate += 1296 + (factor * (absmvdiffx + absmvdiffy));
943
0
            } else {
944
0
                assert(inter_mode == NEW_NEARESTMV || inter_mode == NEW_NEARMV);
945
                // New MV is first ref
946
0
                Mv             mv         = cand->block_mi.mv[0];
947
0
                Mv             ref_mv     = cand->pred_mv[0];
948
0
                const uint16_t absmvdiffx = ABS(mv.x - ref_mv.x);
949
0
                const uint16_t absmvdiffy = ABS(mv.y - ref_mv.y);
950
0
                mv_rate += 1296 + (factor * (absmvdiffx + absmvdiffy));
951
0
            }
952
0
        } else {
953
0
            assert(!is_compound); // single ref inter prediction
954
            // unipred MV stored in idx0
955
0
            Mv             mv         = cand->block_mi.mv[0];
956
0
            Mv             ref_mv     = cand->pred_mv[0];
957
0
            const uint16_t absmvdiffx = ABS(mv.x - ref_mv.x);
958
0
            const uint16_t absmvdiffy = ABS(mv.y - ref_mv.y);
959
0
            mv_rate += 1296 + (factor * (absmvdiffx + absmvdiffy));
960
0
        }
961
0
    }
962
    // Get the interpolation filter rate if IFS is performed at MDS0.  Otherwise, the filter is unknown, so the rate will be updated after IFS is performed.
963
0
    uint32_t ifs_rate = 0;
964
0
    if (ctx->ifs_ctrls.level == IFS_MDS0 &&
965
0
        av1_is_interp_needed_md(&cand_bf->cand->block_mi, pcs, ctx->blk_geom->bsize) &&
966
0
        pcs->ppcs->frm_hdr.interpolation_filter == SWITCHABLE) {
967
0
        ifs_rate = svt_aom_get_switchable_rate(
968
0
            &cand_bf->cand->block_mi, &pcs->ppcs->frm_hdr, ctx, pcs->scs->seq_header.enable_dual_filter);
969
0
    }
970
0
    uint32_t is_inter_rate = r->intra_inter_fac_bits[ctx->is_inter_ctx][1];
971
972
0
    uint32_t skip_mode_rate = pcs->ppcs->frm_hdr.skip_mode_params.skip_mode_flag &&
973
0
            is_comp_ref_allowed(ctx->blk_geom->bsize)
974
0
        ? r->skip_mode_fac_bits[skip_mode_ctx][0]
975
0
        : 0;
976
0
    luma_rate = (uint32_t)(reference_picture_bits_num + skip_mode_rate + inter_mode_bits_num + mv_rate + is_inter_rate +
977
0
                           ifs_rate);
978
    // Keep the Fast Luma and Chroma rate for future use
979
0
    cand_bf->fast_luma_rate   = luma_rate;
980
0
    cand_bf->fast_chroma_rate = 0;
981
    // Assign fast cost
982
0
    if (cand->skip_mode_allowed) {
983
0
        skip_mode_rate = r->skip_mode_fac_bits[skip_mode_ctx][1];
984
0
        if (skip_mode_rate < luma_rate) {
985
0
            return (RDCOST(lambda, skip_mode_rate, luma_distortion));
986
0
        }
987
0
    }
988
0
    return (RDCOST(lambda, luma_rate, luma_distortion));
989
0
}
990
991
uint64_t svt_aom_inter_fast_cost(PictureControlSet* pcs, ModeDecisionContext* ctx, ModeDecisionCandidateBuffer* cand_bf,
992
0
                                 uint64_t lambda, uint64_t luma_distortion) {
993
0
    const BlockGeom*       blk_geom       = ctx->blk_geom;
994
0
    BlkStruct*             blk_ptr        = ctx->blk_ptr;
995
0
    ModeDecisionCandidate* cand           = cand_bf->cand;
996
0
    MvReferenceFrame       rf[2]          = {cand->block_mi.ref_frame[0], cand->block_mi.ref_frame[1]};
997
0
    const int8_t           ref_frame_type = av1_ref_frame_type(cand->block_mi.ref_frame);
998
0
    CandidateMv*           ref_mv_stack   = &(ctx->ref_mv_stack[ref_frame_type][0]);
999
1000
0
    if (ctx->approx_inter_rate) {
1001
0
        return av1_inter_fast_cost_light(ctx, blk_ptr, cand_bf, luma_distortion, lambda, pcs, ref_mv_stack);
1002
0
    }
1003
0
    FrameHeader* frm_hdr = &pcs->ppcs->frm_hdr;
1004
1005
    // Luma rate
1006
0
    uint32_t       luma_rate  = 0;
1007
0
    uint64_t       mv_rate    = 0;
1008
0
    PredictionMode inter_mode = (PredictionMode)cand->block_mi.mode;
1009
1010
0
    uint64_t inter_mode_bits_num = 0;
1011
1012
0
    const uint8_t skip_mode_ctx              = ctx->skip_mode_ctx;
1013
0
    const uint8_t is_compound                = is_inter_compound_mode(cand->block_mi.mode);
1014
0
    uint32_t      mode_context               = svt_aom_mode_context_analyzer(ctx->inter_mode_ctx[ref_frame_type], rf);
1015
0
    uint64_t      reference_picture_bits_num = 0;
1016
1017
    //Reference Type and Mode Bit estimation
1018
0
    reference_picture_bits_num = ctx->estimate_ref_frames_num_bits[ref_frame_type];
1019
0
    if (is_compound) {
1020
0
        assert(INTER_COMPOUND_OFFSET(inter_mode) < INTER_COMPOUND_MODES);
1021
0
        inter_mode_bits_num +=
1022
0
            ctx->md_rate_est_ctx->inter_compound_mode_fac_bits[mode_context][INTER_COMPOUND_OFFSET(inter_mode)];
1023
0
    } else {
1024
        // uint32_t newmv_ctx = mode_context & NEWMV_CTX_MASK;
1025
        // inter_mode_bits_num = cand_bf->cand->md_rate_est_ctx->new_mv_mode_fac_bits[mode_ctx][0];
1026
1027
0
        int16_t newmv_ctx = mode_context & NEWMV_CTX_MASK;
1028
        // aom_write_symbol(ec_writer, mode != NEWMV, frame_context->newmv_cdf[newmv_ctx], 2);
1029
0
        inter_mode_bits_num += ctx->md_rate_est_ctx->new_mv_mode_fac_bits[newmv_ctx][inter_mode != NEWMV];
1030
0
        if (inter_mode != NEWMV) {
1031
0
            const int16_t zero_mv_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
1032
            // aom_write_symbol(ec_writer, mode != GLOBALMV, frame_context->zeromv_cdf[zero_mv_ctx],
1033
            // 2);
1034
0
            inter_mode_bits_num += ctx->md_rate_est_ctx->zero_mv_mode_fac_bits[zero_mv_ctx][inter_mode != GLOBALMV];
1035
0
            if (inter_mode != GLOBALMV) {
1036
0
                int16_t ref_mv_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1037
                /*aom_write_symbol(ec_writer, mode != NEARESTMV,
1038
                 * frame_context->refmv_cdf[refmv_ctx], 2);*/
1039
0
                inter_mode_bits_num += ctx->md_rate_est_ctx->ref_mv_mode_fac_bits[ref_mv_ctx][inter_mode != NEARESTMV];
1040
0
            }
1041
0
        }
1042
0
    }
1043
0
    if (inter_mode == NEWMV || inter_mode == NEW_NEWMV || have_nearmv_in_inter_mode(inter_mode)) {
1044
        //drLIdex cost estimation
1045
0
        const int32_t new_mv = inter_mode == NEWMV || inter_mode == NEW_NEWMV;
1046
0
        if (new_mv) {
1047
0
            int32_t idx;
1048
0
            for (idx = 0; idx < 2; ++idx) {
1049
0
                if (blk_ptr->av1xd->ref_mv_count[ref_frame_type] > idx + 1) {
1050
0
                    uint8_t drl_1_ctx = av1_drl_ctx(ref_mv_stack, idx);
1051
0
                    inter_mode_bits_num += ctx->md_rate_est_ctx->drl_mode_fac_bits[drl_1_ctx][cand->drl_index != idx];
1052
0
                    if (cand->drl_index == idx) {
1053
0
                        break;
1054
0
                    }
1055
0
                }
1056
0
            }
1057
0
        }
1058
1059
0
        if (have_nearmv_in_inter_mode(inter_mode)) {
1060
0
            int32_t idx;
1061
0
            for (idx = 1; idx < 3; ++idx) {
1062
0
                if (blk_ptr->av1xd->ref_mv_count[ref_frame_type] > idx + 1) {
1063
0
                    uint8_t drl_ctx = av1_drl_ctx(ref_mv_stack, idx);
1064
0
                    inter_mode_bits_num +=
1065
0
                        ctx->md_rate_est_ctx->drl_mode_fac_bits[drl_ctx][cand->drl_index != (idx - 1)];
1066
1067
0
                    if (cand->drl_index == (idx - 1)) {
1068
0
                        break;
1069
0
                    }
1070
0
                }
1071
0
            }
1072
0
        }
1073
0
    }
1074
1075
0
    if (svt_aom_have_newmv_in_inter_mode(inter_mode)) {
1076
0
        if (is_compound) {
1077
0
            mv_rate = 0;
1078
1079
0
            if (inter_mode == NEW_NEWMV) {
1080
0
                for (RefList ref_list_idx = 0; ref_list_idx < 2; ++ref_list_idx) {
1081
0
                    Mv mv     = cand->block_mi.mv[ref_list_idx];
1082
0
                    Mv ref_mv = cand->pred_mv[ref_list_idx];
1083
0
                    mv_rate += svt_av1_mv_bit_cost(mv,
1084
0
                                                   ref_mv,
1085
0
                                                   ctx->md_rate_est_ctx->nmv_vec_cost,
1086
0
                                                   ctx->md_rate_est_ctx->nmvcoststack,
1087
0
                                                   MV_COST_WEIGHT);
1088
0
                }
1089
0
            } else if (inter_mode == NEAREST_NEWMV || inter_mode == NEAR_NEWMV) {
1090
0
                Mv mv     = cand->block_mi.mv[1];
1091
0
                Mv ref_mv = cand->pred_mv[1];
1092
0
                mv_rate += svt_av1_mv_bit_cost(
1093
0
                    mv, ref_mv, ctx->md_rate_est_ctx->nmv_vec_cost, ctx->md_rate_est_ctx->nmvcoststack, MV_COST_WEIGHT);
1094
0
            } else {
1095
0
                assert(inter_mode == NEW_NEARESTMV || inter_mode == NEW_NEARMV);
1096
0
                Mv mv     = cand->block_mi.mv[0];
1097
0
                Mv ref_mv = cand->pred_mv[0];
1098
0
                mv_rate += svt_av1_mv_bit_cost(
1099
0
                    mv, ref_mv, ctx->md_rate_est_ctx->nmv_vec_cost, ctx->md_rate_est_ctx->nmvcoststack, MV_COST_WEIGHT);
1100
0
            }
1101
0
        } else {
1102
0
            assert(!is_compound); // single ref inter prediction
1103
            // unipred MVs stored in idx0
1104
0
            Mv mv     = cand->block_mi.mv[0];
1105
0
            Mv ref_mv = cand->pred_mv[0];
1106
0
            mv_rate   = svt_av1_mv_bit_cost(
1107
0
                mv, ref_mv, ctx->md_rate_est_ctx->nmv_vec_cost, ctx->md_rate_est_ctx->nmvcoststack, MV_COST_WEIGHT);
1108
0
        }
1109
0
    }
1110
    // inter intra mode rate
1111
0
    if (pcs->ppcs->scs->seq_header.enable_interintra_compound &&
1112
        /* Check if inter-intra is allowed for current block size / mode (even if the feature is off
1113
        * for the current block, we still need to signal inter-intra off.
1114
        */
1115
0
        svt_is_interintra_allowed(true, blk_geom->bsize, cand->block_mi.mode, rf)) {
1116
0
        const int interintra  = cand->block_mi.is_interintra_used;
1117
0
        const int bsize_group = eb_size_group_lookup[blk_geom->bsize];
1118
1119
0
        inter_mode_bits_num +=
1120
0
            ctx->md_rate_est_ctx->inter_intra_fac_bits[bsize_group][cand->block_mi.is_interintra_used];
1121
1122
0
        if (interintra) {
1123
0
            inter_mode_bits_num +=
1124
0
                ctx->md_rate_est_ctx->inter_intra_mode_fac_bits[bsize_group][cand->block_mi.interintra_mode];
1125
1126
0
            if (svt_aom_is_interintra_wedge_used(blk_geom->bsize)) {
1127
0
                inter_mode_bits_num +=
1128
0
                    ctx->md_rate_est_ctx
1129
0
                        ->wedge_inter_intra_fac_bits[blk_geom->bsize][cand->block_mi.use_wedge_interintra];
1130
1131
0
                if (cand->block_mi.use_wedge_interintra) {
1132
0
                    inter_mode_bits_num +=
1133
0
                        ctx->md_rate_est_ctx
1134
0
                            ->wedge_idx_fac_bits[blk_geom->bsize][cand->block_mi.interintra_wedge_index];
1135
0
                }
1136
0
            }
1137
0
        }
1138
0
    }
1139
0
    if (is_inter_singleref_mode(inter_mode) && frm_hdr->is_motion_mode_switchable && rf[1] != INTRA_FRAME) {
1140
0
        assert(!cand->block_mi.is_interintra_used);
1141
0
        const MotionMode motion_mode_rd           = cand->block_mi.motion_mode;
1142
0
        const BlockSize  bsize                    = blk_geom->bsize;
1143
0
        const MotionMode last_motion_mode_allowed = svt_aom_motion_mode_allowed(
1144
0
            pcs, cand->block_mi.num_proj_ref, blk_ptr->overlappable_neighbors, bsize, rf[0], rf[1], inter_mode);
1145
0
        switch (last_motion_mode_allowed) {
1146
0
        case SIMPLE_TRANSLATION:
1147
0
            break;
1148
0
        case OBMC_CAUSAL:
1149
0
            inter_mode_bits_num += ctx->md_rate_est_ctx->motion_mode_fac_bits1[bsize][motion_mode_rd == OBMC_CAUSAL];
1150
0
            break;
1151
0
        default:
1152
0
            inter_mode_bits_num += ctx->md_rate_est_ctx->motion_mode_fac_bits[bsize][motion_mode_rd];
1153
0
        }
1154
0
    }
1155
    // this func return 0 if masked=0 and distance=0
1156
0
    inter_mode_bits_num += get_compound_mode_rate(pcs, ctx, cand, blk_geom->bsize);
1157
    // Get the interpolation filter rate if IFS is performed at MDS0.  Otherwise, the filter is unknown, so the rate will be updated after IFS is performed.
1158
0
    uint32_t ifs_rate = 0;
1159
0
    if (ctx->ifs_ctrls.level == IFS_MDS0 &&
1160
0
        av1_is_interp_needed_md(&cand_bf->cand->block_mi, pcs, ctx->blk_geom->bsize) &&
1161
0
        frm_hdr->interpolation_filter == SWITCHABLE) {
1162
0
        ifs_rate = svt_aom_get_switchable_rate(
1163
0
            &cand_bf->cand->block_mi, frm_hdr, ctx, pcs->scs->seq_header.enable_dual_filter);
1164
0
    }
1165
0
    uint32_t is_inter_rate  = ctx->md_rate_est_ctx->intra_inter_fac_bits[ctx->is_inter_ctx][1];
1166
0
    uint32_t skip_mode_rate = pcs->ppcs->frm_hdr.skip_mode_params.skip_mode_flag && is_comp_ref_allowed(blk_geom->bsize)
1167
0
        ? ctx->md_rate_est_ctx->skip_mode_fac_bits[skip_mode_ctx][0]
1168
0
        : 0;
1169
0
    luma_rate = (uint32_t)(reference_picture_bits_num + skip_mode_rate + inter_mode_bits_num + mv_rate + is_inter_rate +
1170
0
                           ifs_rate);
1171
    // Keep the Fast Luma and Chroma rate for future use
1172
0
    cand_bf->fast_luma_rate   = luma_rate;
1173
0
    cand_bf->fast_chroma_rate = 0;
1174
    // Assign fast cost
1175
0
    if (cand->skip_mode_allowed) {
1176
0
        skip_mode_rate = ctx->md_rate_est_ctx->skip_mode_fac_bits[skip_mode_ctx][1];
1177
0
        if (skip_mode_rate < luma_rate) {
1178
0
            return (RDCOST(lambda, skip_mode_rate, luma_distortion));
1179
0
        }
1180
0
    }
1181
0
    return (RDCOST(lambda, luma_rate, luma_distortion));
1182
0
}
1183
1184
/*
1185
 */
1186
EbErrorType svt_aom_txb_estimate_coeff_bits_pd0(ModeDecisionContext* ctx, ModeDecisionCandidateBuffer* cand_bf,
1187
                                                uint32_t txb_origin_index, EbPictureBufferDesc* coeff_buffer_sb,
1188
0
                                                uint32_t y_eob, uint64_t* y_txb_coeff_bits, TxSize txsize) {
1189
0
    if (y_eob) {
1190
0
        *y_txb_coeff_bits = svt_av1_cost_coeffs_txb(
1191
0
            ctx,
1192
0
            0,
1193
0
            0,
1194
0
            cand_bf,
1195
0
            (int32_t*)&coeff_buffer_sb->y_buffer[txb_origin_index * sizeof(int32_t)],
1196
0
            (uint16_t)y_eob,
1197
0
            PLANE_TYPE_Y,
1198
0
            txsize,
1199
0
            DCT_DCT,
1200
0
            0,
1201
0
            0,
1202
0
            0);
1203
1204
0
        *y_txb_coeff_bits = (*y_txb_coeff_bits) << ctx->mds_subres_step;
1205
1206
0
    } else {
1207
0
        *y_txb_coeff_bits = av1_cost_skip_txb(ctx, 0, 0, txsize, PLANE_TYPE_Y, 0);
1208
0
    }
1209
1210
0
    return EB_ErrorNone;
1211
0
}
1212
1213
EbErrorType svt_aom_txb_estimate_coeff_bits(ModeDecisionContext* ctx, uint8_t allow_update_cdf, FRAME_CONTEXT* ec_ctx,
1214
                                            PictureControlSet* pcs, ModeDecisionCandidateBuffer* cand_bf,
1215
                                            uint32_t txb_origin_index, uint32_t txb_chroma_origin_index,
1216
                                            EbPictureBufferDesc* coeff_buffer_sb, uint32_t y_eob, uint32_t cb_eob,
1217
                                            uint32_t cr_eob, uint64_t* y_txb_coeff_bits, uint64_t* cb_txb_coeff_bits,
1218
                                            uint64_t* cr_txb_coeff_bits, TxSize txsize, TxSize txsize_uv,
1219
0
                                            TxType tx_type, TxType tx_type_uv, COMPONENT_TYPE component_type) {
1220
0
    EbErrorType return_error = EB_ErrorNone;
1221
1222
0
    FrameHeader* frm_hdr = &pcs->ppcs->frm_hdr;
1223
1224
0
    int32_t* coeff_buffer;
1225
0
    int16_t  luma_txb_skip_context = ctx->luma_txb_skip_context;
1226
0
    int16_t  luma_dc_sign_context  = ctx->luma_dc_sign_context;
1227
0
    int16_t  cb_txb_skip_context   = ctx->cb_txb_skip_context;
1228
0
    int16_t  cb_dc_sign_context    = ctx->cb_dc_sign_context;
1229
0
    int16_t  cr_txb_skip_context   = ctx->cr_txb_skip_context;
1230
0
    int16_t  cr_dc_sign_context    = ctx->cr_dc_sign_context;
1231
1232
0
    bool reduced_transform_set_flag = frm_hdr->reduced_tx_set ? true : false;
1233
1234
    //Estimate the rate of the transform type and coefficient for Luma
1235
1236
0
    if (component_type == COMPONENT_LUMA || component_type == COMPONENT_ALL) {
1237
0
        if (y_eob) {
1238
0
            coeff_buffer = (int32_t*)&coeff_buffer_sb->y_buffer[txb_origin_index * sizeof(int32_t)];
1239
1240
0
            *y_txb_coeff_bits = svt_av1_cost_coeffs_txb(ctx,
1241
0
                                                        allow_update_cdf,
1242
0
                                                        ec_ctx,
1243
0
                                                        cand_bf,
1244
0
                                                        coeff_buffer,
1245
0
                                                        (uint16_t)y_eob,
1246
0
                                                        PLANE_TYPE_Y,
1247
0
                                                        txsize,
1248
0
                                                        tx_type,
1249
0
                                                        luma_txb_skip_context,
1250
0
                                                        luma_dc_sign_context,
1251
0
                                                        reduced_transform_set_flag);
1252
0
            *y_txb_coeff_bits = (*y_txb_coeff_bits) << ctx->mds_subres_step;
1253
0
        } else {
1254
0
            *y_txb_coeff_bits = av1_cost_skip_txb(
1255
0
                ctx, allow_update_cdf, ec_ctx, txsize, PLANE_TYPE_Y, luma_txb_skip_context);
1256
0
        }
1257
0
    }
1258
    // Estimate the rate of the transform type and coefficient for chroma Cb
1259
1260
0
    if (component_type == COMPONENT_CHROMA_CB || component_type == COMPONENT_CHROMA ||
1261
0
        component_type == COMPONENT_ALL) {
1262
0
        if (cb_eob) {
1263
0
            coeff_buffer = (int32_t*)&coeff_buffer_sb->u_buffer[txb_chroma_origin_index * sizeof(int32_t)];
1264
1265
0
            *cb_txb_coeff_bits = svt_av1_cost_coeffs_txb(ctx,
1266
0
                                                         allow_update_cdf,
1267
0
                                                         ec_ctx,
1268
0
                                                         cand_bf,
1269
0
                                                         coeff_buffer,
1270
0
                                                         (uint16_t)cb_eob,
1271
0
                                                         PLANE_TYPE_UV,
1272
0
                                                         txsize_uv,
1273
0
                                                         tx_type_uv,
1274
0
                                                         cb_txb_skip_context,
1275
0
                                                         cb_dc_sign_context,
1276
0
                                                         reduced_transform_set_flag);
1277
0
        } else {
1278
0
            *cb_txb_coeff_bits = av1_cost_skip_txb(
1279
0
                ctx, allow_update_cdf, ec_ctx, txsize_uv, PLANE_TYPE_UV, cb_txb_skip_context);
1280
0
        }
1281
0
    }
1282
1283
0
    if (component_type == COMPONENT_CHROMA_CR || component_type == COMPONENT_CHROMA ||
1284
0
        component_type == COMPONENT_ALL) {
1285
        //Estimate the rate of the transform type and coefficient for chroma Cr
1286
0
        if (cr_eob) {
1287
0
            coeff_buffer = (int32_t*)&coeff_buffer_sb->v_buffer[txb_chroma_origin_index * sizeof(int32_t)];
1288
1289
0
            *cr_txb_coeff_bits = svt_av1_cost_coeffs_txb(ctx,
1290
0
                                                         allow_update_cdf,
1291
0
                                                         ec_ctx,
1292
0
                                                         cand_bf,
1293
0
                                                         coeff_buffer,
1294
0
                                                         (uint16_t)cr_eob,
1295
0
                                                         PLANE_TYPE_UV,
1296
0
                                                         txsize_uv,
1297
0
                                                         tx_type_uv,
1298
0
                                                         cr_txb_skip_context,
1299
0
                                                         cr_dc_sign_context,
1300
0
                                                         reduced_transform_set_flag);
1301
0
        } else {
1302
0
            *cr_txb_coeff_bits = av1_cost_skip_txb(
1303
0
                ctx, allow_update_cdf, ec_ctx, txsize_uv, PLANE_TYPE_UV, cr_txb_skip_context);
1304
0
        }
1305
0
    }
1306
1307
0
    return return_error;
1308
0
}
1309
1310
EbErrorType svt_aom_full_cost_pd0(ModeDecisionContext* ctx, ModeDecisionCandidateBuffer* cand_bf,
1311
157k
                                  uint64_t* y_distortion, uint64_t lambda, uint64_t* y_coeff_bits) {
1312
157k
    EbErrorType return_error = EB_ErrorNone;
1313
1314
157k
    uint64_t coeff_rate = (*y_coeff_bits + (uint64_t)ctx->md_rate_est_ctx->skip_fac_bits[0][0]);
1315
1316
    // Assign full cost
1317
    // Use context index 0 for the partition rate as an approximation to skip call to
1318
    // av1_partition_rate_cost Partition cost is only needed for > 4x4 blocks, but light-PD0 assumes
1319
    // 4x4 blocks are disallowed
1320
157k
    *(cand_bf->full_cost) = RDCOST(
1321
157k
        lambda, coeff_rate + ctx->md_rate_est_ctx->partition_fac_bits[0][PARTITION_NONE], y_distortion[0]);
1322
157k
    return return_error;
1323
157k
}
1324
1325
/*********************************************************************************
1326
 * svt_aom_av1_full_cost function is used to estimate the cost of a candidate mode
1327
 * for full mode decision module.
1328
 **********************************************************************************/
1329
void svt_aom_full_cost(PictureControlSet* pcs, ModeDecisionContext* ctx, ModeDecisionCandidateBuffer* cand_bf,
1330
                       uint64_t lambda, uint64_t y_distortion[DIST_TOTAL][DIST_CALC_TOTAL],
1331
                       uint64_t cb_distortion[DIST_TOTAL][DIST_CALC_TOTAL],
1332
                       uint64_t cr_distortion[DIST_TOTAL][DIST_CALC_TOTAL], uint64_t* y_coeff_bits,
1333
157k
                       uint64_t* cb_coeff_bits, uint64_t* cr_coeff_bits) {
1334
157k
    const uint8_t skip_coeff_ctx        = ctx->skip_coeff_ctx;
1335
157k
    const bool    update_full_cost_ssim = ctx->tune_ssim_level > SSIM_LVL_0 ? true : false;
1336
1337
    // Get the TX size rate for skip and non-skip block. Need both to make non-skip decision
1338
157k
    uint64_t non_skip_tx_size_bits = 0, skip_tx_size_bits = 0;
1339
157k
    if (!ctx->shut_fast_rate && pcs->ppcs->frm_hdr.tx_mode == TX_MODE_SELECT) {
1340
157k
        if (cand_bf->block_has_coeff) {
1341
5.97k
            non_skip_tx_size_bits = svt_aom_get_tx_size_bits(
1342
5.97k
                cand_bf, ctx, pcs, cand_bf->cand->block_mi.tx_depth, /*cand_bf->block_has_coeff*/ 1);
1343
5.97k
        }
1344
1345
157k
        skip_tx_size_bits = svt_aom_get_tx_size_bits(
1346
157k
            cand_bf, ctx, pcs, cand_bf->cand->block_mi.tx_depth, /*cand_bf->block_has_coeff*/ 0);
1347
157k
    }
1348
1349
157k
    assert(IMPLIES(is_inter_mode(cand_bf->cand->block_mi.mode), skip_tx_size_bits == 0));
1350
1351
    // Decide if block should be signalled as skip (send no coeffs)
1352
157k
    if (!svt_av1_is_lossless_segment(pcs, ctx->blk_ptr->segment_id) && ctx->blk_skip_decision &&
1353
6.56k
        cand_bf->block_has_coeff && is_inter_mode(cand_bf->cand->block_mi.mode)) {
1354
0
        const uint64_t non_skip_cost = RDCOST(
1355
0
            lambda,
1356
0
            (*y_coeff_bits + *cb_coeff_bits + *cr_coeff_bits + non_skip_tx_size_bits +
1357
0
             (uint64_t)ctx->md_rate_est_ctx->skip_fac_bits[skip_coeff_ctx][0]),
1358
0
            (y_distortion[DIST_SSD][0] + cb_distortion[DIST_SSD][0] + cr_distortion[DIST_SSD][0]));
1359
1360
0
        const uint64_t skip_cost = RDCOST(
1361
0
            lambda,
1362
0
            ((uint64_t)ctx->md_rate_est_ctx->skip_fac_bits[skip_coeff_ctx][1]) + skip_tx_size_bits,
1363
0
            (y_distortion[DIST_SSD][1] + cb_distortion[DIST_SSD][1] + cr_distortion[DIST_SSD][1]));
1364
1365
        // Update signals to correspond to skip_mode values (no coeffs, etc.)
1366
0
        if (skip_cost < non_skip_cost) {
1367
0
            y_distortion[DIST_SSD][0]  = y_distortion[DIST_SSD][1];
1368
0
            cb_distortion[DIST_SSD][0] = cb_distortion[DIST_SSD][1];
1369
0
            cr_distortion[DIST_SSD][0] = cr_distortion[DIST_SSD][1];
1370
1371
0
            y_distortion[DIST_SSIM][0]  = y_distortion[DIST_SSIM][1];
1372
0
            cb_distortion[DIST_SSIM][0] = cb_distortion[DIST_SSIM][1];
1373
0
            cr_distortion[DIST_SSIM][0] = cr_distortion[DIST_SSIM][1];
1374
0
            cand_bf->block_has_coeff    = 0;
1375
0
            cand_bf->y_has_coeff        = 0;
1376
0
            cand_bf->u_has_coeff        = 0;
1377
0
            cand_bf->v_has_coeff        = 0;
1378
0
            cand_bf->cnt_nz_coeff       = 0;
1379
1380
            // For inter modes, signalling skip means no TX depth is used and the TX type will be DCT_DCT
1381
0
            cand_bf->cand->block_mi.tx_depth = 0;
1382
0
            cand_bf->cand->transform_type_uv = DCT_DCT;
1383
0
            memset(cand_bf->cand->transform_type, DCT_DCT, 16 * sizeof(cand_bf->cand->transform_type[0]));
1384
0
            memset(&cand_bf->quant_dc, 0, sizeof(QuantDcData));
1385
0
            memset(&cand_bf->eob, 0, sizeof(EobData));
1386
0
        }
1387
0
    }
1388
1389
157k
    uint64_t coeff_rate = 0;
1390
157k
    if (cand_bf->block_has_coeff) {
1391
5.97k
        coeff_rate = (*y_coeff_bits + *cb_coeff_bits + *cr_coeff_bits + non_skip_tx_size_bits +
1392
5.97k
                      (uint64_t)ctx->md_rate_est_ctx->skip_fac_bits[skip_coeff_ctx][0]);
1393
151k
    } else {
1394
151k
        coeff_rate = ctx->md_rate_est_ctx->skip_fac_bits[skip_coeff_ctx][1] + skip_tx_size_bits;
1395
151k
    }
1396
1397
157k
    uint64_t mode_rate            = cand_bf->fast_luma_rate + cand_bf->fast_chroma_rate + coeff_rate;
1398
157k
    uint64_t mode_distortion      = y_distortion[DIST_SSD][0] + cb_distortion[DIST_SSD][0] + cr_distortion[DIST_SSD][0];
1399
157k
    uint64_t mode_ssim_distortion = update_full_cost_ssim
1400
157k
        ? y_distortion[DIST_SSIM][0] + cb_distortion[DIST_SSIM][0] + cr_distortion[DIST_SSIM][0]
1401
157k
        : 0;
1402
157k
    uint64_t mode_cost            = RDCOST(lambda, mode_rate, mode_distortion);
1403
1404
    // If skip_mode is allowed for this candidate, check cost of skip mode compared to regular cost
1405
157k
    if (cand_bf->cand->skip_mode_allowed == true) {
1406
0
        const uint8_t skip_mode_ctx = ctx->skip_mode_ctx;
1407
1408
        // Skip mode cost
1409
0
        const uint64_t skip_mode_rate       = ctx->md_rate_est_ctx->skip_mode_fac_bits[skip_mode_ctx][1];
1410
0
        const uint64_t skip_mode_distortion = y_distortion[DIST_SSD][1] + cb_distortion[DIST_SSD][1] +
1411
0
            cr_distortion[DIST_SSD][1];
1412
0
        const uint64_t skip_mode_ssim_distortion = update_full_cost_ssim
1413
0
            ? y_distortion[DIST_SSIM][1] + cb_distortion[DIST_SSIM][1] + cr_distortion[DIST_SSIM][1]
1414
0
            : 0;
1415
0
        const uint64_t skip_mode_cost            = RDCOST(lambda, skip_mode_rate, skip_mode_distortion);
1416
1417
0
        cand_bf->cand->block_mi.skip_mode = false;
1418
0
        if (skip_mode_cost <= mode_cost) {
1419
            // Update candidate cost
1420
0
            mode_cost                         = skip_mode_cost;
1421
0
            mode_rate                         = skip_mode_rate;
1422
0
            mode_distortion                   = skip_mode_distortion;
1423
0
            mode_ssim_distortion              = skip_mode_ssim_distortion;
1424
0
            cand_bf->cand->block_mi.skip_mode = true;
1425
1426
            // Update signals to correspond to skip_mode values (no coeffs, etc.)
1427
0
            cand_bf->block_has_coeff         = 0;
1428
0
            cand_bf->y_has_coeff             = 0;
1429
0
            cand_bf->u_has_coeff             = 0;
1430
0
            cand_bf->v_has_coeff             = 0;
1431
0
            cand_bf->cnt_nz_coeff            = 0;
1432
0
            cand_bf->cand->block_mi.tx_depth = 0;
1433
0
            memset(cand_bf->cand->transform_type, DCT_DCT, 16 * sizeof(cand_bf->cand->transform_type[0]));
1434
0
            cand_bf->cand->transform_type_uv = DCT_DCT;
1435
0
            memset(&cand_bf->quant_dc, 0, sizeof(QuantDcData));
1436
0
            memset(&cand_bf->eob, 0, sizeof(EobData));
1437
0
        }
1438
0
    }
1439
1440
    // Assign full cost
1441
157k
    *(cand_bf->full_cost) = mode_cost;
1442
157k
    cand_bf->total_rate   = mode_rate;
1443
157k
    cand_bf->full_dist    = (uint32_t)mode_distortion;
1444
157k
    if (update_full_cost_ssim) {
1445
0
        assert(ctx->pd_pass == PD_PASS_1);
1446
0
        assert(ctx->md_stage == MD_STAGE_3);
1447
0
        *(cand_bf->full_cost_ssim) = RDCOST(lambda, mode_rate, mode_ssim_distortion);
1448
0
    }
1449
157k
    return;
1450
157k
}
1451
1452
/************************************************************
1453
 * Coding Loop Context Generation
1454
 ************************************************************/
1455
157k
void svt_aom_coding_loop_context_generation(PictureControlSet* pcs, ModeDecisionContext* ctx) {
1456
157k
    BlkStruct*   blk_ptr = ctx->blk_ptr;
1457
157k
    MacroBlockD* xd      = blk_ptr->av1xd;
1458
157k
    if (!ctx->shut_fast_rate) {
1459
157k
        if (pcs->slice_type == I_SLICE) {
1460
157k
            svt_aom_get_kf_y_mode_ctx(xd, &ctx->intra_luma_top_ctx, &ctx->intra_luma_left_ctx);
1461
157k
        }
1462
157k
        ctx->is_inter_ctx  = svt_av1_get_intra_inter_context(xd);
1463
157k
        ctx->skip_mode_ctx = av1_get_skip_mode_context(xd);
1464
157k
    }
1465
    // Collect Neighbor ref cout
1466
    // At approx_inter_rate>=2, estimate_ref_frames_num_bits is skipped so ref counts
1467
    // are not consumed in MD. EC has its own call to collect_neighbors_ref_counts_new.
1468
157k
    if ((pcs->slice_type != I_SLICE || pcs->ppcs->frm_hdr.allow_intrabc) && ctx->approx_inter_rate < 2) {
1469
0
        svt_aom_collect_neighbors_ref_counts_new(blk_ptr->av1xd);
1470
0
    }
1471
1472
    // Skip Coeff Context
1473
157k
    ctx->skip_coeff_ctx = ctx->rate_est_ctrls.update_skip_coeff_ctx ? av1_get_skip_context(xd) : 0;
1474
157k
}
1475
1476
325k
static INLINE int block_signals_txsize(BlockSize bsize) {
1477
325k
    return bsize > BLOCK_4X4;
1478
325k
}
1479
1480
0
static INLINE int get_vartx_max_txsize(/*const MbModeInfo *xd,*/ BlockSize bsize, int plane) {
1481
    /* if (xd->lossless[xd->mi[0]->segment_id]) return TX_4X4;*/
1482
0
    const TxSize max_txsize = blocksize_to_txsize[bsize];
1483
0
    if (plane == 0) {
1484
0
        return max_txsize; // luma
1485
0
    }
1486
0
    return av1_get_adjusted_tx_size(max_txsize); // chroma
1487
0
}
1488
1489
0
static INLINE int max_block_wide(const MacroBlockD* xd, BlockSize bsize, int plane) {
1490
0
    int max_blocks_wide = block_size_wide[bsize];
1491
1492
0
    if (xd->mb_to_right_edge < 0) {
1493
0
        max_blocks_wide += xd->mb_to_right_edge >> (3 + !!plane);
1494
0
    }
1495
1496
    // Scale the width in the transform block unit.
1497
0
    return max_blocks_wide >> tx_size_wide_log2[0];
1498
0
}
1499
1500
0
static INLINE int max_block_high(const MacroBlockD* xd, BlockSize bsize, int plane) {
1501
0
    int max_blocks_high = block_size_high[bsize];
1502
1503
0
    if (xd->mb_to_bottom_edge < 0) {
1504
0
        max_blocks_high += xd->mb_to_bottom_edge >> (3 + !!plane);
1505
0
    }
1506
1507
    // Scale the height in the transform block unit.
1508
0
    return max_blocks_high >> tx_size_high_log2[0];
1509
0
}
1510
1511
static INLINE void txfm_partition_update(TXFM_CONTEXT* above_ctx, TXFM_CONTEXT* left_ctx, TxSize tx_size,
1512
0
                                         TxSize txb_size) {
1513
0
    BlockSize bsize = txsize_to_bsize[txb_size];
1514
0
    assert(bsize < BLOCK_SIZES_ALL);
1515
0
    int     bh  = mi_size_high[bsize];
1516
0
    int     bw  = mi_size_wide[bsize];
1517
0
    uint8_t txw = tx_size_wide[tx_size];
1518
0
    uint8_t txh = tx_size_high[tx_size];
1519
0
    int     i;
1520
0
    for (i = 0; i < bh; ++i) {
1521
0
        left_ctx[i] = txh;
1522
0
    }
1523
0
    for (i = 0; i < bw; ++i) {
1524
0
        above_ctx[i] = txw;
1525
0
    }
1526
0
}
1527
1528
0
static INLINE TxSize get_sqr_tx_size(int tx_dim) {
1529
0
    switch (tx_dim) {
1530
0
    case 128:
1531
0
    case 64:
1532
0
        return TX_64X64;
1533
0
        break;
1534
0
    case 32:
1535
0
        return TX_32X32;
1536
0
        break;
1537
0
    case 16:
1538
0
        return TX_16X16;
1539
0
        break;
1540
0
    case 8:
1541
0
        return TX_8X8;
1542
0
        break;
1543
0
    default:
1544
0
        return TX_4X4;
1545
0
    }
1546
0
}
1547
1548
static INLINE int txfm_partition_context(TXFM_CONTEXT* above_ctx, TXFM_CONTEXT* left_ctx, BlockSize bsize,
1549
0
                                         TxSize tx_size) {
1550
0
    const uint8_t txw      = tx_size_wide[tx_size];
1551
0
    const uint8_t txh      = tx_size_high[tx_size];
1552
0
    const int     above    = *above_ctx < txw;
1553
0
    const int     left     = *left_ctx < txh;
1554
0
    int           category = TXFM_PARTITION_CONTEXTS;
1555
1556
    // dummy return, not used by others.
1557
0
    if (tx_size == TX_4X4) {
1558
0
        return 0;
1559
0
    }
1560
1561
0
    TxSize max_tx_size = get_sqr_tx_size(AOMMAX(block_size_wide[bsize], block_size_high[bsize]));
1562
1563
0
    if (max_tx_size >= TX_8X8) {
1564
0
        category = (txsize_sqr_up_map[tx_size] != max_tx_size && max_tx_size > TX_8X8) +
1565
0
            (TX_SIZES - 1 - max_tx_size) * 2;
1566
0
    }
1567
0
    assert(category != TXFM_PARTITION_CONTEXTS);
1568
0
    return category * 3 + above + left;
1569
0
}
1570
1571
static uint64_t cost_tx_size_vartx(MacroBlockD* xd, const MbModeInfo* mbmi, TxSize tx_size, int depth, int blk_row,
1572
                                   int blk_col, MdRateEstimationContext* md_rate_est_ctx, FRAME_CONTEXT* ec_ctx,
1573
0
                                   uint8_t allow_update_cdf) {
1574
0
    uint64_t  bits            = 0;
1575
0
    const int max_blocks_high = max_block_high(xd, mbmi->bsize, 0);
1576
0
    const int max_blocks_wide = max_block_wide(xd, mbmi->bsize, 0);
1577
1578
0
    if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) {
1579
0
        return bits;
1580
0
    }
1581
1582
0
    if (depth == MAX_VARTX_DEPTH) {
1583
0
        txfm_partition_update(xd->above_txfm_context + blk_col, xd->left_txfm_context + blk_row, tx_size, tx_size);
1584
1585
0
        return bits;
1586
0
    }
1587
1588
0
    const int ctx = txfm_partition_context(
1589
0
        xd->above_txfm_context + blk_col, xd->left_txfm_context + blk_row, mbmi->bsize, tx_size);
1590
0
    const int write_txfm_partition = (tx_size == tx_depth_to_tx_size[mbmi->block_mi.tx_depth][mbmi->bsize]);
1591
0
    if (write_txfm_partition) {
1592
0
        bits += md_rate_est_ctx->txfm_partition_fac_bits[ctx][0];
1593
1594
0
        if (allow_update_cdf) {
1595
0
            update_cdf(ec_ctx->txfm_partition_cdf[ctx], 0, 2);
1596
0
        }
1597
1598
0
        txfm_partition_update(xd->above_txfm_context + blk_col, xd->left_txfm_context + blk_row, tx_size, tx_size);
1599
1600
0
    } else {
1601
0
        assert(tx_size < TX_SIZES_ALL);
1602
0
        const TxSize sub_txs = eb_sub_tx_size_map[tx_size];
1603
0
        const int    bsw     = eb_tx_size_wide_unit[sub_txs];
1604
0
        const int    bsh     = eb_tx_size_high_unit[sub_txs];
1605
1606
0
        bits += md_rate_est_ctx->txfm_partition_fac_bits[ctx][1];
1607
1608
0
        if (allow_update_cdf) {
1609
0
            update_cdf(ec_ctx->txfm_partition_cdf[ctx], 1, 2);
1610
0
        }
1611
1612
0
        if (sub_txs == TX_4X4) {
1613
0
            txfm_partition_update(xd->above_txfm_context + blk_col, xd->left_txfm_context + blk_row, sub_txs, tx_size);
1614
1615
0
            return bits;
1616
0
        }
1617
1618
0
        assert(bsw > 0 && bsh > 0);
1619
0
        for (int row = 0; row < eb_tx_size_high_unit[tx_size]; row += bsh) {
1620
0
            for (int col = 0; col < eb_tx_size_wide_unit[tx_size]; col += bsw) {
1621
0
                int offsetr = blk_row + row;
1622
0
                int offsetc = blk_col + col;
1623
0
                bits += cost_tx_size_vartx(
1624
0
                    xd, mbmi, sub_txs, depth + 1, offsetr, offsetc, md_rate_est_ctx, ec_ctx, allow_update_cdf);
1625
0
            }
1626
0
        }
1627
0
    }
1628
0
    return bits;
1629
0
}
1630
1631
630k
static INLINE void set_txfm_ctx(TXFM_CONTEXT* txfm_ctx, uint8_t txs, int len) {
1632
630k
    int i;
1633
2.04M
    for (i = 0; i < len; ++i) {
1634
1.41M
        txfm_ctx[i] = txs;
1635
1.41M
    }
1636
630k
}
1637
1638
315k
static INLINE void set_txfm_ctxs(TxSize tx_size, int n8_w, int n8_h, int skip, const MacroBlockD* xd) {
1639
315k
    uint8_t bw = tx_size_wide[tx_size];
1640
315k
    uint8_t bh = tx_size_high[tx_size];
1641
1642
315k
    if (skip) {
1643
0
        bw = n8_w * MI_SIZE;
1644
0
        bh = n8_h * MI_SIZE;
1645
0
    }
1646
1647
315k
    set_txfm_ctx(xd->above_txfm_context, bw, n8_w);
1648
315k
    set_txfm_ctx(xd->left_txfm_context, bh, n8_h);
1649
315k
}
1650
1651
10.1k
static INLINE int tx_size_to_depth(TxSize tx_size, BlockSize bsize) {
1652
10.1k
    TxSize ctx_size = blocksize_to_txsize[bsize];
1653
10.1k
    int    depth    = 0;
1654
10.1k
    while (tx_size != ctx_size) {
1655
0
        depth++;
1656
0
        ctx_size = eb_sub_tx_size_map[ctx_size];
1657
0
        assert(depth <= MAX_TX_DEPTH);
1658
0
    }
1659
10.1k
    return depth;
1660
10.1k
}
1661
1662
// Returns a context number for the given MB prediction signal
1663
// The mode info data structure has a one element border above and to the
1664
// left of the entries corresponding to real blocks.
1665
// The prediction flags in these dummy entries are initialized to 0.
1666
10.1k
static INLINE int get_tx_size_context(const MacroBlockD* xd) {
1667
10.1k
    const MbModeInfo*       mbmi        = xd->mi[0];
1668
10.1k
    const MbModeInfo* const above_mbmi  = xd->above_mbmi;
1669
10.1k
    const MbModeInfo* const left_mbmi   = xd->left_mbmi;
1670
10.1k
    const TxSize            max_tx_size = blocksize_to_txsize[mbmi->bsize];
1671
10.1k
    const int               max_tx_wide = tx_size_wide[max_tx_size];
1672
10.1k
    const int               max_tx_high = tx_size_high[max_tx_size];
1673
10.1k
    const int               has_above   = xd->up_available;
1674
10.1k
    const int               has_left    = xd->left_available;
1675
1676
10.1k
    int above = xd->above_txfm_context[0] >= max_tx_wide;
1677
10.1k
    int left  = xd->left_txfm_context[0] >= max_tx_high;
1678
1679
10.1k
    if (has_above) {
1680
2.35k
        if (is_inter_block(&above_mbmi->block_mi)) {
1681
0
            above = block_size_wide[above_mbmi->bsize] >= max_tx_wide;
1682
0
        }
1683
2.35k
    }
1684
1685
10.1k
    if (has_left) {
1686
2.43k
        if (is_inter_block(&left_mbmi->block_mi)) {
1687
0
            left = block_size_high[left_mbmi->bsize] >= max_tx_high;
1688
0
        }
1689
2.43k
    }
1690
1691
10.1k
    if (has_above && has_left) {
1692
151
        return (above + left);
1693
9.99k
    } else if (has_above) {
1694
2.20k
        return above;
1695
7.78k
    } else if (has_left) {
1696
2.27k
        return left;
1697
5.50k
    } else {
1698
5.50k
        return 0;
1699
5.50k
    }
1700
10.1k
}
1701
1702
static uint64_t cost_selected_tx_size(const MacroBlockD* xd, MdRateEstimationContext* md_rate_est_ctx, TxSize tx_size,
1703
10.1k
                                      FRAME_CONTEXT* ec_ctx, uint8_t allow_update_cdf) {
1704
10.1k
    const MbModeInfo* const mbmi  = xd->mi[0];
1705
10.1k
    const BlockSize         bsize = mbmi->bsize;
1706
10.1k
    uint64_t                bits  = 0;
1707
1708
10.1k
    if (block_signals_txsize(bsize)) {
1709
10.1k
        const int tx_size_ctx = get_tx_size_context(xd);
1710
10.1k
        assert(bsize < BLOCK_SIZES_ALL);
1711
10.1k
        const int     depth       = tx_size_to_depth(tx_size, bsize);
1712
10.1k
        const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize);
1713
10.1k
        bits += md_rate_est_ctx->tx_size_fac_bits[tx_size_cat][tx_size_ctx][depth];
1714
1715
10.1k
        if (allow_update_cdf) {
1716
0
            const int max_depths = bsize_to_max_depth(bsize);
1717
0
            assert(depth >= 0 && depth <= max_depths);
1718
0
            assert(!is_inter_block(&mbmi->block_mi));
1719
0
            assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(/*xd,*/ mbmi)));
1720
0
            update_cdf(ec_ctx->tx_size_cdf[tx_size_cat][tx_size_ctx], depth, max_depths + 1);
1721
0
        }
1722
10.1k
    }
1723
1724
10.1k
    return bits;
1725
10.1k
}
1726
1727
/* Get the TXS rate and update the txfm context.  If allow_update_cdf is true, the TX size CDFs will
1728
be updated. */
1729
uint64_t svt_aom_tx_size_bits(PictureControlSet* pcs, uint8_t segment_id, MdRateEstimationContext* md_rate_est_ctx,
1730
                              MacroBlockD* xd, const MbModeInfo* mbmi, TxSize tx_size, TxMode tx_mode, BlockSize bsize,
1731
314k
                              uint8_t skip, FRAME_CONTEXT* ec_ctx, uint8_t allow_update_cdf) {
1732
314k
    uint64_t bits        = 0;
1733
314k
    int      is_inter_tx = is_inter_block(&mbmi->block_mi);
1734
314k
    if (tx_mode == TX_MODE_SELECT && block_signals_txsize(bsize) && !(is_inter_tx && skip) &&
1735
314k
        !svt_av1_is_lossless_segment(pcs, segment_id)) {
1736
10.1k
        if (is_inter_tx) { // This implies skip flag is 0.
1737
0
            const TxSize max_tx_size = get_vartx_max_txsize(/*xd,*/ bsize, 0);
1738
0
            const int    txbh        = eb_tx_size_high_unit[max_tx_size];
1739
0
            const int    txbw        = eb_tx_size_wide_unit[max_tx_size];
1740
0
            const int    width       = block_size_wide[bsize] >> tx_size_wide_log2[0];
1741
0
            const int    height      = block_size_high[bsize] >> tx_size_high_log2[0];
1742
0
            int          idx, idy;
1743
0
            for (idy = 0; idy < height; idy += txbh) {
1744
0
                for (idx = 0; idx < width; idx += txbw) {
1745
0
                    bits += cost_tx_size_vartx(
1746
0
                        xd, mbmi, max_tx_size, 0, idy, idx, md_rate_est_ctx, ec_ctx, allow_update_cdf);
1747
0
                }
1748
0
            }
1749
10.1k
        } else {
1750
10.1k
            bits += cost_selected_tx_size(xd, md_rate_est_ctx, tx_size, ec_ctx, allow_update_cdf);
1751
10.1k
            set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, 0, xd);
1752
10.1k
        }
1753
304k
    } else {
1754
304k
        set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, skip && is_inter_block(&mbmi->block_mi), xd);
1755
304k
    }
1756
1757
314k
    return bits;
1758
314k
}
1759
1760
/* Get the TXS rate.  A dummy txfm context array will be used, so context updates will not be saved for
1761
future blocks. */
1762
uint64_t svt_aom_get_tx_size_bits(ModeDecisionCandidateBuffer* candidateBuffer, ModeDecisionContext* ctx,
1763
315k
                                  PictureControlSet* pcs, uint8_t tx_depth, bool block_has_coeff) {
1764
315k
    NeighborArrayUnit* txfm_context_array = ctx->txfm_context_array;
1765
315k
    const uint8_t*     txfm_above_ptr     = svt_aom_na_top_ptr_pu(txfm_context_array, ctx->blk_org_x);
1766
315k
    const uint8_t*     txfm_left_ptr      = svt_aom_na_left_ptr_pu(txfm_context_array, ctx->blk_org_y);
1767
1768
315k
    TxMode       tx_mode = pcs->ppcs->frm_hdr.tx_mode;
1769
315k
    MacroBlockD* xd      = ctx->blk_ptr->av1xd;
1770
315k
    BlockSize    bsize   = ctx->blk_geom->bsize;
1771
315k
    const TxSize tx_size = tx_depth_to_tx_size[tx_depth][bsize];
1772
315k
    MbModeInfo*  mbmi    = xd->mi[0];
1773
1774
315k
    svt_memcpy(ctx->above_txfm_context, txfm_above_ptr, (ctx->blk_geom->bwidth >> MI_SIZE_LOG2) * sizeof(TXFM_CONTEXT));
1775
315k
    svt_memcpy(ctx->left_txfm_context, txfm_left_ptr, (ctx->blk_geom->bheight >> MI_SIZE_LOG2) * sizeof(TXFM_CONTEXT));
1776
1777
315k
    xd->above_txfm_context      = ctx->above_txfm_context;
1778
315k
    xd->left_txfm_context       = ctx->left_txfm_context;
1779
315k
    mbmi->bsize                 = ctx->blk_geom->bsize;
1780
315k
    mbmi->block_mi.use_intrabc  = candidateBuffer->cand->block_mi.use_intrabc;
1781
315k
    mbmi->block_mi.ref_frame[0] = candidateBuffer->cand->block_mi.ref_frame[0];
1782
315k
    mbmi->block_mi.tx_depth     = tx_depth;
1783
1784
315k
    const uint64_t bits = svt_aom_tx_size_bits(pcs,
1785
315k
                                               ctx->blk_ptr->segment_id,
1786
315k
                                               ctx->md_rate_est_ctx,
1787
315k
                                               xd,
1788
315k
                                               mbmi,
1789
315k
                                               tx_size,
1790
315k
                                               tx_mode,
1791
315k
                                               bsize,
1792
315k
                                               !block_has_coeff,
1793
315k
                                               NULL,
1794
315k
                                               0);
1795
315k
    return bits;
1796
315k
}
1797
1798
/*
1799
 * av1_partition_rate_cost function is used to generate the rate of signaling the
1800
 * partition type for a given block.
1801
 */
1802
int64_t svt_aom_partition_rate_cost(PictureParentControlSet* ppcs, const BlockSize bsize, const int mi_row,
1803
                                    const int mi_col, MdRateEstimationContext* md_rate_est_ctx, PartitionType p,
1804
274k
                                    const PartitionContextType left_ctx, const PartitionContextType above_ctx) {
1805
274k
    if (bsize < BLOCK_8X8) {
1806
0
        return 0;
1807
0
    }
1808
274k
    assert(bsize < BLOCK_SIZES_ALL && mi_size_wide_log2[bsize] == mi_size_high_log2[bsize]);
1809
1810
274k
    const int hbs      = mi_size_wide[bsize] >> 1;
1811
274k
    const int has_rows = (mi_row + hbs) < ppcs->av1_cm->mi_rows;
1812
274k
    const int has_cols = (mi_col + hbs) < ppcs->av1_cm->mi_cols;
1813
    // Don't consider invalid partitions or blocks outside the picture
1814
274k
    if (!has_rows && !has_cols) {
1815
824
        return 0;
1816
824
    }
1817
1818
274k
    const int bsl = mi_size_wide_log2[bsize] - mi_size_wide_log2[BLOCK_8X8];
1819
274k
    assert(bsl >= 0);
1820
1821
274k
    const int      above = (above_ctx >> bsl) & 1, left = (left_ctx >> bsl) & 1;
1822
274k
    const uint32_t context_index = (left * 2 + above) + bsl * PARTITION_PLOFFSET;
1823
1824
274k
    uint64_t split_rate = 0;
1825
1826
274k
    if (has_rows && has_cols) {
1827
257k
        split_rate = (uint64_t)md_rate_est_ctx->partition_fac_bits[context_index][p];
1828
257k
    } else if (!has_rows && has_cols) {
1829
        // 8x8 blocks will not use the split_or_horz or the split_or_vert paritition CDFs, per
1830
        // section 8.3.2 of the AV1 spec (Cdf selection process).  Therefore, only update partition ctx 4+,
1831
        // which corresponds to the paritition CDFs for 16x16 and larger blocks
1832
8.51k
        assert(bsize != BLOCK_8X8);
1833
8.51k
        split_rate = bsize == BLOCK_128X128
1834
8.51k
            ? (uint64_t)md_rate_est_ctx->partition_vert_alike_128x128_fac_bits[context_index][p == PARTITION_SPLIT]
1835
8.51k
            : (uint64_t)md_rate_est_ctx->partition_vert_alike_fac_bits[context_index][p == PARTITION_SPLIT];
1836
8.59k
    } else {
1837
        // 8x8 blocks will not use the split_or_horz or the split_or_vert paritition CDFs, per
1838
        // section 8.3.2 of the AV1 spec (Cdf selection process).  Therefore, only update partition ctx 4+,
1839
        // which corresponds to the paritition CDFs for 16x16 and larger blocks
1840
8.59k
        assert(bsize != BLOCK_8X8);
1841
8.59k
        split_rate = bsize == BLOCK_128X128
1842
8.59k
            ? (uint64_t)md_rate_est_ctx->partition_horz_alike_128x128_fac_bits[context_index][p == PARTITION_SPLIT]
1843
8.59k
            : (uint64_t)md_rate_est_ctx->partition_horz_alike_fac_bits[context_index][p == PARTITION_SPLIT];
1844
8.59k
    }
1845
1846
274k
    return split_rate;
1847
274k
}