Coverage Report

Created: 2026-09-14 06:44

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