Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/md_process.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
*
4
* This source code is subject to the terms of the BSD 2 Clause License and
5
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
* was not distributed with this source code in the LICENSE file, you can
7
* obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
8
* Media Patent License 1.0 was not distributed with this source code in the
9
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
10
*/
11
12
#include <stdlib.h>
13
14
#include "utility.h"
15
#include "md_process.h"
16
#include "lambda_rate_tables.h"
17
#include "rc_process.h"
18
#include "enc_mode_config.h"
19
20
const uint8_t quantizer_to_qindex[64] = {
21
    0,   4,   8,   12,  16,  20,  24,  28,  32,  36,  40,  44,  48,  52,  56,  60,  64,  68,  72,  76,  80,  84,
22
    88,  92,  96,  100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172,
23
    176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255};
24
25
const int percents[2][FIXED_QP_OFFSET_COUNT] = {
26
    {75, 70, 60, 20, 15, 0}, {76, 60, 30, 15, 8, 4} // libaom offsets
27
};
28
29
const uint8_t uni_psy_bias[64] = {
30
    85, 85, 85, 85, 85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  85,  95,  95,  95,  95,  95, 95,
31
    95, 95, 95, 95, 95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95, 95,
32
    95, 95, 95, 95, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
33
};
34
35
1.53k
static void mode_decision_context_dctor(EbPtr p) {
36
1.53k
    ModeDecisionContext* obj = (ModeDecisionContext*)p;
37
38
    // MD palette search
39
1.53k
    if (obj->palette_buffer) {
40
0
        EB_FREE(obj->palette_buffer);
41
0
    }
42
1.53k
    if (obj->palette_cand_array) {
43
        // Free fields in palette_cand_array before freeing palette_cand_array
44
0
        for (int cd = 0; cd < MAX_PAL_CAND; cd++) {
45
0
            if (obj->palette_cand_array[cd].color_idx_map) {
46
0
                EB_FREE_ARRAY(obj->palette_cand_array[cd].color_idx_map);
47
0
            }
48
0
        }
49
50
0
        EB_FREE_ARRAY(obj->palette_cand_array);
51
0
    }
52
1.53k
    if (obj->palette_size_array_0) {
53
0
        EB_FREE_ARRAY(obj->palette_size_array_0);
54
0
    }
55
9.19k
    for (CandClass cand_class_it = CAND_CLASS_0; cand_class_it < CAND_CLASS_TOTAL; cand_class_it++) {
56
7.66k
        EB_FREE_ARRAY(obj->cand_buff_indices[cand_class_it]);
57
7.66k
    }
58
1.53k
    EB_FREE_ARRAY(obj->best_candidate_index_array);
59
60
1.53k
    EB_FREE_ARRAY(obj->above_txfm_context);
61
1.53k
    EB_FREE_ARRAY(obj->left_txfm_context);
62
    // Per-block coeff_tmp/recon_tmp are borrowed from these pools (freed once each).
63
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->coeff_tmp_pool);
64
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->recon_tmp_pool);
65
    // cand_bf_ptr_array[] entries are borrowed from cand_bf_pool; free the pool + the (alias)
66
    // pointer array once each — do NOT per-element delete.
67
1.53k
    EB_FREE_ARRAY(obj->cand_bf_pool);
68
1.53k
    EB_FREE_ARRAY(obj->cand_bf_ptr_array);
69
    // Candidate pred/rec_coeff/quant are borrowed from these pools (freed once each).
70
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->cand_pred_pool);
71
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->cand_rec_coeff_pool);
72
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->cand_quant_pool);
73
1.53k
    EB_FREE_ARRAY(obj->cand_bf_tx_depth_1->cand);
74
1.53k
    EB_DELETE(obj->cand_bf_tx_depth_1);
75
1.53k
    EB_FREE_ARRAY(obj->cand_bf_tx_depth_2->cand);
76
1.53k
    EB_DELETE(obj->cand_bf_tx_depth_2);
77
1.53k
    EB_FREE_ALIGNED_ARRAY(obj->cfl_temp_luma_recon16bit);
78
1.53k
    EB_FREE_ALIGNED_ARRAY(obj->cfl_temp_luma_recon);
79
1.53k
    EB_FREE_ALIGNED_ARRAY(obj->pred_buf_q3);
80
1.53k
    EB_FREE_ALIGNED_ARRAY(obj->tmp_conv_buf);
81
1.53k
    EB_FREE_ALIGNED_ARRAY(obj->seg_mask_buf);
82
1.53k
    EB_FREE_ARRAY(obj->fast_cand_array);
83
1.53k
    EB_FREE_2D(obj->injected_mvs);
84
1.53k
    EB_FREE_ARRAY(obj->injected_ref_types);
85
1.53k
    EB_FREE_ARRAY(obj->fast_cost_array);
86
1.53k
    EB_FREE_ARRAY(obj->full_cost_array);
87
1.53k
    if (obj->md_blk_arr_nsq) {
88
6.13k
        for (int i = 0; i < 3; i++) {
89
4.59k
            EB_FREE_ARRAY(obj->md_blk_arr_nsq[0].neigh_left_recon_16bit[i]);
90
4.59k
            EB_FREE_ARRAY(obj->md_blk_arr_nsq[0].neigh_top_recon_16bit[i]);
91
4.59k
            EB_FREE_ARRAY(obj->md_blk_arr_nsq[0].neigh_left_recon[i]);
92
4.59k
            EB_FREE_ARRAY(obj->md_blk_arr_nsq[0].neigh_top_recon[i]);
93
4.59k
        }
94
1.53k
    }
95
1.53k
    if (obj->md_blk_arr_nsq) {
96
1.53k
        EB_FREE_ARRAY(obj->md_blk_arr_nsq[0].av1xd);
97
1.53k
    }
98
1.53k
    EB_FREE_ARRAY(obj->mds);
99
1.53k
    EB_FREE_ARRAY(obj->pc_tree);
100
1.53k
    EB_FREE_ARRAY(obj->tested_blk);
101
1.53k
    EB_FREE_ARRAY(obj->uv_cand_buff_indices);
102
1.53k
    obj->blocks_to_alloc = 0;
103
1.53k
    EB_FREE_ARRAY(obj->md_blk_arr_nsq);
104
1.53k
    EB_FREE_ARRAY(obj->pd0_mds0_best_cost);
105
1.53k
    if (obj->rate_est_table) {
106
0
        EB_FREE_ARRAY(obj->rate_est_table);
107
0
    }
108
109
7.66k
    for (int i = 0; i < NEAREST_NEAR_MV_CNT; i++) {
110
6.13k
        if (obj->cmp_store.pred0_buf[i]) {
111
0
            EB_FREE(obj->cmp_store.pred0_buf[i]);
112
0
        }
113
6.13k
        if (obj->cmp_store.pred1_buf[i]) {
114
0
            EB_FREE(obj->cmp_store.pred1_buf[i]);
115
0
        }
116
6.13k
    }
117
1.53k
    if (obj->residual1) {
118
0
        EB_FREE(obj->residual1);
119
0
    }
120
1.53k
    if (obj->diff10) {
121
0
        EB_FREE(obj->diff10);
122
0
    }
123
124
1.53k
    if (obj->intrapred_buf) {
125
0
        EB_FREE_2D(obj->intrapred_buf);
126
0
    }
127
128
1.53k
    if (obj->obmc_buff_0) {
129
0
        EB_FREE(obj->obmc_buff_0);
130
0
    }
131
1.53k
    if (obj->obmc_buff_1) {
132
0
        EB_FREE(obj->obmc_buff_1);
133
0
    }
134
1.53k
    if (obj->obmc_conv_buf) {
135
0
        EB_FREE(obj->obmc_conv_buf);
136
0
    }
137
1.53k
    if (obj->wsrc_buf) {
138
0
        EB_FREE(obj->wsrc_buf);
139
0
    }
140
1.53k
    if (obj->mask_buf) {
141
0
        EB_FREE(obj->mask_buf);
142
0
    }
143
    // Per-TX recon/coeff buffers are borrowed from these pools (freed once each).
144
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->tx_recon_coeff_pool);
145
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->tx_recon_pool);
146
1.53k
    svt_aom_pic_buf_desc_pool_dctor(&obj->tx_quant_coeff_pool);
147
1.53k
    EB_DELETE(obj->tx_coeffs);
148
1.53k
    EB_DELETE(obj->scratch_prediction_ptr);
149
1.53k
    EB_DELETE(obj->temp_residual);
150
1.53k
    EB_DELETE(obj->temp_recon_ptr);
151
1.53k
    EB_FREE_ARRAY(obj->full_cost_ssim_array);
152
1.53k
}
153
154
void svt_aom_set_nics(SequenceControlSet* scs, NicScalingCtrls* scaling_ctrls, uint32_t mds1_count[CAND_CLASS_TOTAL],
155
                      uint32_t mds2_count[CAND_CLASS_TOTAL], uint32_t mds3_count[CAND_CLASS_TOTAL], uint8_t pic_type,
156
                      uint32_t qp);
157
158
static void setup_mds(SequenceControlSet* scs, MdScan* mds, uint32_t* mds_idx, int index, BlockSize bsize,
159
130k
                      const int min_sq_size) {
160
130k
    mds->mds_idx = *mds_idx;
161
130k
    mds->bsize   = bsize;
162
130k
    mds->index   = index;
163
164
    // If applicable, add split depths
165
130k
    const BlockGeom* blk_geom = get_blk_geom_mds(scs->blk_geom_mds, *mds_idx);
166
130k
    const int        sq_size  = block_size_wide[bsize];
167
130k
    if (sq_size > min_sq_size) {
168
32.1k
        const BlockSize subsize             = get_partition_subsize(bsize, PARTITION_SPLIT);
169
32.1k
        const int       sq_subsize          = block_size_wide[subsize];
170
32.1k
        int             blocks_per_subdepth = (sq_subsize / min_sq_size) * (sq_subsize / min_sq_size);
171
32.1k
        int             blocks_to_skip      = 0;
172
173
73.5k
        for (int i = min_sq_size; i <= sq_subsize; i <<= 1, blocks_per_subdepth >>= 2) {
174
41.3k
            blocks_to_skip += blocks_per_subdepth;
175
41.3k
        }
176
177
32.1k
        *mds_idx += blk_geom->d1_depth_offset;
178
160k
        for (int i = 0; i < SUB_PARTITIONS_SPLIT; ++i) {
179
128k
            mds->split[i] = mds + i * blocks_to_skip + 1;
180
128k
            setup_mds(scs, mds->split[i], mds_idx, i, subsize, min_sq_size);
181
128k
        }
182
98.1k
    } else {
183
98.1k
        *mds_idx += blk_geom->ns_depth_offset;
184
98.1k
    }
185
130k
}
186
187
static void setup_pc_tree(PC_TREE* pc_tree, bool (*test_blk_array)[PART_S][4], int index, BlockSize bsize,
188
130k
                          const int min_sq_size) {
189
130k
    pc_tree->bsize      = bsize;
190
130k
    pc_tree->index      = index;
191
130k
    pc_tree->tested_blk = test_blk_array[0];
192
193
    // If applicable, add split depths
194
130k
    const int sq_size = block_size_wide[bsize];
195
130k
    if (sq_size > min_sq_size) {
196
32.1k
        const BlockSize subsize             = get_partition_subsize(bsize, PARTITION_SPLIT);
197
32.1k
        const int       sq_subsize          = block_size_wide[subsize];
198
32.1k
        int             blocks_per_subdepth = (sq_subsize / min_sq_size) * (sq_subsize / min_sq_size);
199
32.1k
        int             blocks_to_skip      = 0;
200
201
73.5k
        for (int i = min_sq_size; i <= sq_subsize; i <<= 1, blocks_per_subdepth >>= 2) {
202
41.3k
            blocks_to_skip += blocks_per_subdepth;
203
41.3k
        }
204
205
160k
        for (int i = 0; i < SUB_PARTITIONS_SPLIT; ++i) {
206
128k
            pc_tree->split[i]         = pc_tree + i * blocks_to_skip + 1;
207
128k
            pc_tree->split[i]->parent = pc_tree;
208
128k
            setup_pc_tree(pc_tree->split[i], test_blk_array + i * blocks_to_skip + 1, i, subsize, min_sq_size);
209
128k
        }
210
32.1k
    }
211
130k
}
212
213
/******************************************************
214
 * Mode Decision Context Constructor
215
 ******************************************************/
216
EbErrorType svt_aom_mode_decision_context_ctor(ModeDecisionContext* ctx, SequenceControlSet* scs,
217
                                               EbColorFormat color_format, uint8_t sb_size, EncMode enc_mode,
218
                                               uint16_t max_block_cnt, uint32_t encoder_bit_depth,
219
                                               EbFifo* mode_decision_configuration_input_fifo_ptr,
220
                                               EbFifo* mode_decision_output_fifo_ptr, uint8_t enable_hbd_mode_decision,
221
1.53k
                                               uint8_t seq_qp_mod) {
222
1.53k
    const bool allintra = scs->allintra;
223
1.53k
    const bool rtc_tune = scs->static_config.rtc;
224
1.53k
    uint32_t   buffer_index;
225
1.53k
    uint32_t   cand_index;
226
227
1.53k
    ctx->intrabc_last_dv.as_int = 0; // no last DV yet (seeds the RTC IntraBC BVP fallback)
228
1.53k
    ctx->init_max_block_cnt     = max_block_cnt;
229
1.53k
    uint32_t block_max_count_sb = max_block_cnt;
230
231
1.53k
    ctx->sb_size = sb_size;
232
1.53k
    (void)color_format;
233
234
1.53k
    ctx->dctor  = mode_decision_context_dctor;
235
1.53k
    ctx->hbd_md = enable_hbd_mode_decision;
236
237
    // Zero the tail of md_levels_buf once; it serves as permanent bottom-padding
238
    // for set_levels() and is never overwritten by svt_av1_txb_init_levels().
239
1.53k
    memset(ctx->md_levels_buf + LEVELS_TAIL_OFFSET, 0, TX_PAD_2D - LEVELS_TAIL_OFFSET);
240
241
    // Input/Output System Resource Manager FIFOs
242
1.53k
    ctx->mode_decision_configuration_input_fifo_ptr = mode_decision_configuration_input_fifo_ptr;
243
1.53k
    ctx->mode_decision_output_fifo_ptr              = mode_decision_output_fifo_ptr;
244
245
    // Maximum number of candidates MD can support
246
    // determine MAX_NICS for a given preset
247
    // get the min scaling level (the smallest scaling level is the most conservative)
248
1.53k
    uint8_t min_nic_scaling_level = NICS_SCALING_LEVELS - 1;
249
1.53k
    uint8_t stage1_scaling_num;
250
1.53k
    if (allintra) {
251
1.53k
        uint8_t nic_level  = svt_aom_get_nic_level_allintra(enc_mode);
252
1.53k
        stage1_scaling_num = MD_STAGE_NICS_SCAL_NUM[svt_aom_set_nic_controls(NULL, nic_level)][MD_STAGE_1];
253
1.53k
    } else if (rtc_tune) {
254
0
        uint8_t nic_level  = svt_aom_get_nic_level_rtc(enc_mode);
255
0
        stage1_scaling_num = MD_STAGE_NICS_SCAL_NUM[svt_aom_set_nic_controls(NULL, nic_level)][MD_STAGE_1];
256
0
    } else {
257
0
        for (uint8_t is_base = 0; is_base < 2; is_base++) {
258
0
            uint8_t nic_level         = svt_aom_get_nic_level_default(enc_mode, is_base);
259
0
            uint8_t nic_scaling_level = svt_aom_set_nic_controls(NULL, nic_level);
260
0
            min_nic_scaling_level     = MIN(min_nic_scaling_level, nic_scaling_level);
261
0
        }
262
263
0
        stage1_scaling_num = MD_STAGE_NICS_SCAL_NUM[min_nic_scaling_level][MD_STAGE_1];
264
0
    }
265
    // scale max_nics
266
1.53k
    uint32_t max_nics = 0;
267
1.53k
    {
268
1.53k
        NicScalingCtrls scaling_ctrls;
269
1.53k
        scaling_ctrls.stage1_scaling_num = stage1_scaling_num;
270
1.53k
        scaling_ctrls.stage2_scaling_num = stage1_scaling_num;
271
1.53k
        scaling_ctrls.stage3_scaling_num = stage1_scaling_num;
272
1.53k
        uint32_t mds1_count[CAND_CLASS_TOTAL];
273
1.53k
        uint32_t mds2_count[CAND_CLASS_TOTAL];
274
1.53k
        uint32_t mds3_count[CAND_CLASS_TOTAL];
275
6.13k
        for (uint8_t pic_type = 0; pic_type < NICS_PIC_TYPE; pic_type++) {
276
298k
            for (uint8_t qp = MIN_QP_VALUE; qp <= MAX_QP_VALUE; qp++) {
277
294k
                svt_aom_set_nics(scs, &scaling_ctrls, mds1_count, mds2_count, mds3_count, pic_type, qp);
278
279
294k
                uint32_t nics = 0;
280
1.76M
                for (CandClass cidx = CAND_CLASS_0; cidx < CAND_CLASS_TOTAL; cidx++) {
281
1.47M
                    nics += mds1_count[cidx];
282
1.47M
                }
283
294k
                max_nics = MAX(max_nics, nics);
284
294k
            }
285
4.59k
        }
286
1.53k
    }
287
288
    // If independent chroma search is used, need to allocate additional 84 candidate buffers
289
1.53k
    bool is_chroma_mode_0;
290
1.53k
    if (allintra) {
291
1.53k
        is_chroma_mode_0 = svt_aom_set_chroma_controls(NULL, svt_aom_get_chroma_level_allintra(enc_mode)) ==
292
1.53k
            CHROMA_MODE_0;
293
1.53k
    } else if (scs->static_config.rtc) {
294
0
        is_chroma_mode_0 = svt_aom_set_chroma_controls(NULL, svt_aom_get_chroma_level_rtc(enc_mode)) == CHROMA_MODE_0;
295
0
    } else {
296
0
        for (uint8_t is_i_slice = 0; is_i_slice < 2; is_i_slice++) {
297
0
            is_chroma_mode_0 = svt_aom_set_chroma_controls(
298
0
                                   NULL, svt_aom_get_chroma_level_default(enc_mode, is_i_slice)) == CHROMA_MODE_0;
299
0
            if (is_chroma_mode_0) {
300
0
                break;
301
0
            }
302
0
        }
303
0
    }
304
1.53k
    const uint8_t ind_uv_cands = is_chroma_mode_0 ? 84 : 0;
305
1.53k
    max_nics += CAND_CLASS_TOTAL; //need one extra temp buffer for each fast loop call
306
1.53k
    ctx->max_nics    = max_nics;
307
1.53k
    ctx->max_nics_uv = max_nics + ind_uv_cands;
308
1.53k
    EB_MALLOC_ARRAY(ctx->uv_cand_buff_indices, ctx->max_nics_uv);
309
    // Cfl scratch memory
310
1.53k
    if (SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) > EB_8_BIT_MD) {
311
0
        EB_MALLOC_ALIGNED(ctx->cfl_temp_luma_recon16bit, sizeof(uint16_t) * sb_size * sb_size);
312
0
    }
313
1.53k
    if (SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) != EB_10_BIT_MD) {
314
1.53k
        EB_MALLOC_ALIGNED(ctx->cfl_temp_luma_recon, sizeof(uint8_t) * sb_size * sb_size);
315
1.53k
    }
316
1.53k
    EB_MALLOC_ALIGNED(ctx->pred_buf_q3, CFL_BUF_SQUARE);
317
    // Hoisted inter-prediction scratch (previously large on-stack arrays).
318
1.53k
    EB_MALLOC_ALIGNED_ARRAY(ctx->tmp_conv_buf, MAX_SB_SQUARE);
319
1.53k
    EB_MALLOC_ALIGNED_ARRAY(ctx->seg_mask_buf, 2 * MAX_SB_SQUARE);
320
1.53k
    uint8_t use_update_cdf = 0;
321
1.53k
    if (allintra) {
322
1.53k
        use_update_cdf = svt_aom_get_update_cdf_level_allintra(enc_mode);
323
1.53k
    } else if (rtc_tune) {
324
0
        for (uint8_t is_islice = 0; is_islice < 2; is_islice++) {
325
0
            if (use_update_cdf) {
326
0
                break;
327
0
            }
328
0
            use_update_cdf |= svt_aom_get_update_cdf_level_rtc(enc_mode, is_islice);
329
0
        }
330
0
    } else {
331
0
        for (uint8_t is_islice = 0; is_islice < 2; is_islice++) {
332
0
            for (uint8_t is_base = 0; is_base < 2; is_base++) {
333
0
                if (use_update_cdf) {
334
0
                    break;
335
0
                }
336
0
                use_update_cdf |= svt_aom_get_update_cdf_level_default(enc_mode, is_islice, is_base);
337
0
            }
338
0
        }
339
0
    }
340
1.53k
    if (use_update_cdf) {
341
0
        EB_CALLOC_ARRAY(ctx->rate_est_table, 1);
342
1.53k
    } else {
343
1.53k
        ctx->rate_est_table = NULL;
344
1.53k
    }
345
    // Allocate buffer for inter-inter compound prediction
346
1.53k
    if (get_inter_compound_level(enc_mode)) {
347
0
        const uint8_t bits = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) > EB_8_BIT_MD ? 2 : 1;
348
0
        for (int i = 0; i < NEAREST_NEAR_MV_CNT; i++) {
349
0
            EB_MALLOC(ctx->cmp_store.pred0_buf[i], sb_size * sb_size * bits * sizeof(uint8_t));
350
0
            EB_MALLOC(ctx->cmp_store.pred1_buf[i], sb_size * sb_size * bits * sizeof(uint8_t));
351
0
        }
352
0
        EB_MALLOC(ctx->residual1, sb_size * sb_size * sizeof(ctx->residual1[0]));
353
0
        EB_MALLOC(ctx->diff10, sb_size * sb_size * sizeof(ctx->diff10[0]));
354
0
    }
355
356
    // Allocate buffer for inter-intra prediction
357
1.53k
    uint8_t ii_allowed = 0;
358
4.59k
    for (uint8_t transition_present = 0; transition_present < 2; transition_present++) {
359
3.06k
        if (ii_allowed) {
360
0
            break;
361
0
        }
362
3.06k
        ii_allowed |= svt_aom_get_inter_intra_level(enc_mode, transition_present);
363
3.06k
    }
364
1.53k
    if (ii_allowed) {
365
0
        const uint8_t bits = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) > EB_8_BIT_MD ? 2 : 1;
366
        // MAX block size for inter intra is 32x32
367
0
        EB_MALLOC_2D(ctx->intrapred_buf, INTERINTRA_MODES, 32 * 32 * bits * sizeof(ctx->intrapred_buf[0][0]));
368
0
    }
369
370
    // Allocate buffers for obmc prediction
371
1.53k
    uint8_t obmc_allowed = 0;
372
4.59k
    for (uint8_t is_base = 0; is_base < 2; is_base++) {
373
199k
        for (uint8_t qp = MIN_QP_VALUE; qp <= MAX_QP_VALUE; qp++) {
374
196k
            if (obmc_allowed) {
375
0
                break;
376
0
            }
377
196k
            obmc_allowed |= svt_aom_get_obmc_level(enc_mode, qp, seq_qp_mod);
378
196k
        }
379
3.06k
    }
380
1.53k
    if (obmc_allowed) {
381
0
        const uint8_t bits = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) > EB_8_BIT_MD ? 2 : 1;
382
0
        EB_MALLOC(ctx->obmc_buff_0, sb_size * sb_size * bits * MAX_PLANES * sizeof(ctx->obmc_buff_0[0]));
383
0
        EB_MALLOC(ctx->obmc_buff_1, sb_size * sb_size * bits * MAX_PLANES * sizeof(ctx->obmc_buff_1[0]));
384
0
        EB_MALLOC(ctx->obmc_conv_buf, sb_size * sb_size * sizeof(ctx->obmc_conv_buf[0]));
385
0
        EB_MALLOC(ctx->wsrc_buf, sb_size * sb_size * sizeof(ctx->wsrc_buf[0]));
386
0
        EB_MALLOC(ctx->mask_buf, sb_size * sb_size * sizeof(ctx->mask_buf[0]));
387
0
    }
388
1.53k
    EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq, block_max_count_sb);
389
1.53k
    EB_MALLOC_ARRAY(ctx->pd0_mds0_best_cost, block_max_count_sb);
390
    // Fast Candidate Array
391
1.53k
    uint16_t max_can_count = svt_aom_get_max_can_count(enc_mode, rtc_tune) + ind_uv_cands;
392
1.53k
    EB_MALLOC_ARRAY(ctx->fast_cand_array, max_can_count);
393
394
292k
    for (cand_index = 0; cand_index < max_can_count; ++cand_index) {
395
291k
        ctx->fast_cand_array[cand_index].palette_info = NULL;
396
291k
    }
397
1.53k
    svt_aom_assert_err(max_can_count > ind_uv_cands, "Max. candidates is too low");
398
1.53k
    EB_MALLOC_2D(ctx->injected_mvs, (uint16_t)(max_can_count - ind_uv_cands), 2);
399
1.53k
    EB_MALLOC_ARRAY(ctx->injected_ref_types, (max_can_count - ind_uv_cands));
400
401
    // Set buffers for MD palette search to NULL; will be init'd at runtime if needed
402
1.53k
    ctx->palette_buffer       = NULL;
403
1.53k
    ctx->palette_cand_array   = NULL;
404
1.53k
    ctx->palette_size_array_0 = NULL;
405
406
    // Cost Arrays
407
1.53k
    EB_MALLOC_ARRAY(ctx->fast_cost_array, ctx->max_nics_uv);
408
1.53k
    EB_MALLOC_ARRAY(ctx->full_cost_array, ctx->max_nics_uv);
409
1.53k
    EB_MALLOC_ARRAY(ctx->full_cost_ssim_array, ctx->max_nics_uv);
410
    // Candidate Buffers
411
1.53k
    EB_NEW(ctx->cand_bf_tx_depth_1,
412
1.53k
           svt_aom_mode_decision_scratch_cand_bf_ctor,
413
1.53k
           sb_size,
414
1.53k
           SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT);
415
416
1.53k
    EB_ALLOC_PTR_ARRAY(ctx->cand_bf_tx_depth_1->cand, 1);
417
1.53k
    EB_NEW(ctx->cand_bf_tx_depth_2,
418
1.53k
           svt_aom_mode_decision_scratch_cand_bf_ctor,
419
1.53k
           sb_size,
420
1.53k
           SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT);
421
422
1.53k
    EB_ALLOC_PTR_ARRAY(ctx->cand_bf_tx_depth_2->cand, 1);
423
6.13k
    for (int i = 0; i < 3; i++) {
424
4.59k
        ctx->md_blk_arr_nsq[0].neigh_left_recon[i]       = NULL;
425
4.59k
        ctx->md_blk_arr_nsq[0].neigh_top_recon[i]        = NULL;
426
4.59k
        ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[i] = NULL;
427
4.59k
        ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[i]  = NULL;
428
4.59k
    }
429
1.53k
    uint32_t coded_leaf_index;
430
1.53k
    uint16_t sz = sizeof(uint16_t);
431
1.53k
    if (SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) > EB_8_BIT_MD) {
432
0
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[0], block_max_count_sb * sb_size * sz);
433
0
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[0], block_max_count_sb * sb_size * sz);
434
0
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[1], block_max_count_sb * sb_size * sz >> 1);
435
0
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[1], block_max_count_sb * sb_size * sz >> 1);
436
0
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[2], block_max_count_sb * sb_size * sz >> 1);
437
0
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[2], block_max_count_sb * sb_size * sz >> 1);
438
439
0
        for (coded_leaf_index = 0; coded_leaf_index < block_max_count_sb; ++coded_leaf_index) {
440
0
            size_t offset = coded_leaf_index * sb_size * sz;
441
0
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_left_recon_16bit[0] =
442
0
                ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[0] + offset;
443
0
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_top_recon_16bit[0] =
444
0
                ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[0] + offset;
445
0
            offset >>= 1;
446
0
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_left_recon_16bit[1] =
447
0
                ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[1] + offset;
448
0
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_top_recon_16bit[1] =
449
0
                ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[1] + offset;
450
0
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_left_recon_16bit[2] =
451
0
                ctx->md_blk_arr_nsq[0].neigh_left_recon_16bit[2] + offset;
452
0
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_top_recon_16bit[2] =
453
0
                ctx->md_blk_arr_nsq[0].neigh_top_recon_16bit[2] + offset;
454
0
        }
455
0
    }
456
1.53k
    if (SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) != EB_10_BIT_MD) {
457
1.53k
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_left_recon[0], block_max_count_sb * sb_size);
458
1.53k
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_top_recon[0], block_max_count_sb * sb_size);
459
1.53k
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_left_recon[1], block_max_count_sb * sb_size >> 1);
460
1.53k
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_top_recon[1], block_max_count_sb * sb_size >> 1);
461
1.53k
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_left_recon[2], block_max_count_sb * sb_size >> 1);
462
1.53k
        EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].neigh_top_recon[2], block_max_count_sb * sb_size >> 1);
463
464
131k
        for (coded_leaf_index = 0; coded_leaf_index < block_max_count_sb; ++coded_leaf_index) {
465
130k
            size_t offset                                             = coded_leaf_index * sb_size;
466
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_left_recon[0] = ctx->md_blk_arr_nsq[0].neigh_left_recon[0] +
467
130k
                offset;
468
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_top_recon[0] = ctx->md_blk_arr_nsq[0].neigh_top_recon[0] +
469
130k
                offset;
470
130k
            offset >>= 1;
471
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_left_recon[1] = ctx->md_blk_arr_nsq[0].neigh_left_recon[1] +
472
130k
                offset;
473
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_top_recon[1] = ctx->md_blk_arr_nsq[0].neigh_top_recon[1] +
474
130k
                offset;
475
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_left_recon[2] = ctx->md_blk_arr_nsq[0].neigh_left_recon[2] +
476
130k
                offset;
477
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].neigh_top_recon[2] = ctx->md_blk_arr_nsq[0].neigh_top_recon[2] +
478
130k
                offset;
479
130k
        }
480
1.53k
    }
481
1.53k
    ctx->md_blk_arr_nsq[0].av1xd = NULL;
482
1.53k
    EB_MALLOC_ARRAY(ctx->md_blk_arr_nsq[0].av1xd, block_max_count_sb);
483
484
    // Alloc mds and pc_tree, which are used to track tested blocks in MD
485
1.53k
    bool    disallow_4x4     = allintra ? svt_aom_get_disallow_4x4_allintra(enc_mode)
486
1.53k
        : rtc_tune                      ? svt_aom_get_disallow_4x4_rtc()
487
0
                                        : svt_aom_get_disallow_4x4_default(enc_mode);
488
1.53k
    bool    disallow_8x8     = allintra ? svt_aom_get_disallow_8x8_allintra()
489
1.53k
        : rtc_tune ? svt_aom_get_disallow_8x8_rtc(enc_mode, scs->max_input_luma_width, scs->max_input_luma_height)
490
0
                   : svt_aom_get_disallow_8x8_default();
491
1.53k
    uint8_t min_bsize        = disallow_8x8 ? 16 : disallow_4x4 ? 8 : 4;
492
1.53k
    int     blocks_per_depth = (sb_size / min_bsize) * (sb_size / min_bsize);
493
1.53k
    int     blocks_to_alloc  = 0;
494
495
7.66k
    for (int i = min_bsize; i <= sb_size; i <<= 1, blocks_per_depth >>= 2) {
496
6.13k
        blocks_to_alloc += blocks_per_depth;
497
6.13k
    }
498
1.53k
    EB_CALLOC_ARRAY(ctx->mds, blocks_to_alloc);
499
1.53k
    uint32_t mds_idx = 0;
500
1.53k
    setup_mds(scs, ctx->mds, &mds_idx, 0, scs->seq_header.sb_size, min_bsize);
501
1.53k
    EB_CALLOC_ARRAY(ctx->pc_tree, blocks_to_alloc);
502
1.53k
    EB_MALLOC_ARRAY(ctx->tested_blk, blocks_to_alloc);
503
1.53k
    setup_pc_tree(ctx->pc_tree, ctx->tested_blk, 0, scs->seq_header.sb_size, min_bsize);
504
1.53k
    ctx->blocks_to_alloc = blocks_to_alloc;
505
506
1.53k
    bool bypass_encdec = allintra ? svt_aom_get_bypass_encdec_allintra(enc_mode)
507
1.53k
        : rtc_tune                ? svt_aom_get_bypass_encdec_rtc(enc_mode, encoder_bit_depth)
508
0
                                  : svt_aom_get_bypass_encdec_default(enc_mode, encoder_bit_depth);
509
    // Per-block coeff_tmp/recon_tmp (bypass-encdec only) share one backing allocation each,
510
    // sliced per block, instead of one allocation per block.
511
1.53k
    EbPictureBufferDescInitData* coeff_tmp_id = NULL;
512
1.53k
    EbPictureBufferDescInitData* recon_tmp_id = NULL;
513
1.53k
    if (bypass_encdec) {
514
1.53k
        EB_MALLOC_ARRAY(coeff_tmp_id, block_max_count_sb);
515
1.53k
        EB_MALLOC_ARRAY(recon_tmp_id, block_max_count_sb);
516
1.53k
    }
517
131k
    for (coded_leaf_index = 0; coded_leaf_index < block_max_count_sb; ++coded_leaf_index) {
518
130k
        ctx->md_blk_arr_nsq[coded_leaf_index].av1xd      = ctx->md_blk_arr_nsq[0].av1xd + coded_leaf_index;
519
130k
        ctx->md_blk_arr_nsq[coded_leaf_index].segment_id = 0;
520
130k
        const BlockGeom* blk_geom                        = get_blk_geom_mds(scs->blk_geom_mds, coded_leaf_index);
521
130k
        if (bypass_encdec) {
522
130k
            EbPictureBufferDescInitData* ci = &coeff_tmp_id[coded_leaf_index];
523
130k
            ci->buffer_enable_mask          = PICTURE_BUFFER_DESC_FULL_MASK;
524
130k
            ci->max_width                   = blk_geom->bwidth;
525
130k
            ci->max_height                  = blk_geom->bheight;
526
130k
            ci->bit_depth                   = EB_THIRTYTWO_BIT;
527
130k
            ci->color_format                = (blk_geom->bwidth > 4 && blk_geom->bheight > 4)
528
130k
                ? EB_YUV420
529
130k
                : EB_YUV444; // PW - must have at least 4x4 for chroma coeffs
530
130k
            ci->border                      = 0;
531
130k
            ci->split_mode                  = false;
532
533
130k
            EbPictureBufferDescInitData* ri = &recon_tmp_id[coded_leaf_index];
534
130k
            ri->buffer_enable_mask          = PICTURE_BUFFER_DESC_FULL_MASK;
535
130k
            ri->max_width                   = blk_geom->bwidth;
536
130k
            ri->max_height                  = blk_geom->bheight;
537
130k
            ri->bit_depth                   = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT;
538
130k
            ri->color_format                = (blk_geom->bwidth > 4 && blk_geom->bheight > 4) ? EB_YUV420 : EB_YUV444;
539
130k
            ri->border                      = 0;
540
130k
            ri->split_mode                  = false;
541
130k
        } else {
542
0
            ctx->md_blk_arr_nsq[coded_leaf_index].coeff_tmp = NULL;
543
0
            ctx->md_blk_arr_nsq[coded_leaf_index].recon_tmp = NULL;
544
0
        }
545
130k
    }
546
1.53k
    if (bypass_encdec) {
547
1.53k
        EbErrorType c_err = svt_aom_pic_buf_desc_pool_ctor_var(&ctx->coeff_tmp_pool, coeff_tmp_id, block_max_count_sb);
548
1.53k
        EbErrorType r_err = svt_aom_pic_buf_desc_pool_ctor_var(&ctx->recon_tmp_pool, recon_tmp_id, block_max_count_sb);
549
1.53k
        EB_FREE_ARRAY(coeff_tmp_id);
550
1.53k
        EB_FREE_ARRAY(recon_tmp_id);
551
1.53k
        if (c_err != EB_ErrorNone) {
552
0
            return c_err;
553
0
        }
554
1.53k
        if (r_err != EB_ErrorNone) {
555
0
            return r_err;
556
0
        }
557
131k
        for (coded_leaf_index = 0; coded_leaf_index < block_max_count_sb; ++coded_leaf_index) {
558
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].coeff_tmp = &ctx->coeff_tmp_pool.descs[coded_leaf_index];
559
130k
            ctx->md_blk_arr_nsq[coded_leaf_index].recon_tmp = &ctx->recon_tmp_pool.descs[coded_leaf_index];
560
130k
        }
561
1.53k
    }
562
9.19k
    for (CandClass cand_class_it = CAND_CLASS_0; cand_class_it < CAND_CLASS_TOTAL; cand_class_it++) {
563
7.66k
        EB_MALLOC_ARRAY(ctx->cand_buff_indices[cand_class_it], ctx->max_nics_uv);
564
7.66k
    }
565
566
1.53k
    EB_MALLOC_ARRAY(ctx->best_candidate_index_array, ctx->max_nics_uv);
567
1.53k
    EB_MALLOC_ARRAY(ctx->above_txfm_context, (sb_size >> MI_SIZE_LOG2));
568
1.53k
    EB_MALLOC_ARRAY(ctx->left_txfm_context, (sb_size >> MI_SIZE_LOG2));
569
1.53k
    EbPictureBufferDescInitData thirty_two_width_picture_buffer_desc_init_data;
570
1.53k
    EbPictureBufferDescInitData picture_buffer_desc_init_data;
571
572
1.53k
    picture_buffer_desc_init_data.max_width          = sb_size;
573
1.53k
    picture_buffer_desc_init_data.max_height         = sb_size;
574
1.53k
    picture_buffer_desc_init_data.bit_depth          = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT;
575
1.53k
    picture_buffer_desc_init_data.color_format       = EB_YUV420;
576
1.53k
    picture_buffer_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
577
1.53k
    picture_buffer_desc_init_data.border             = 0;
578
1.53k
    picture_buffer_desc_init_data.split_mode         = false;
579
1.53k
    picture_buffer_desc_init_data.is_16bit_pipeline  = false;
580
581
1.53k
    thirty_two_width_picture_buffer_desc_init_data.max_width          = sb_size;
582
1.53k
    thirty_two_width_picture_buffer_desc_init_data.max_height         = sb_size;
583
1.53k
    thirty_two_width_picture_buffer_desc_init_data.bit_depth          = EB_THIRTYTWO_BIT;
584
1.53k
    thirty_two_width_picture_buffer_desc_init_data.color_format       = EB_YUV420;
585
1.53k
    thirty_two_width_picture_buffer_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
586
1.53k
    thirty_two_width_picture_buffer_desc_init_data.border             = 0;
587
1.53k
    thirty_two_width_picture_buffer_desc_init_data.split_mode         = false;
588
1.53k
    thirty_two_width_picture_buffer_desc_init_data.is_16bit_pipeline  = false;
589
    // Per-transform-type recon/coeff buffers share one backing allocation each.
590
1.53k
    EbErrorType tx_err;
591
1.53k
    if ((tx_err = svt_aom_pic_buf_desc_pool_ctor(
592
1.53k
             &ctx->tx_recon_coeff_pool, &thirty_two_width_picture_buffer_desc_init_data, TX_TYPES)) != EB_ErrorNone) {
593
0
        return tx_err;
594
0
    }
595
1.53k
    if ((tx_err = svt_aom_pic_buf_desc_pool_ctor(&ctx->tx_recon_pool, &picture_buffer_desc_init_data, TX_TYPES)) !=
596
1.53k
        EB_ErrorNone) {
597
0
        return tx_err;
598
0
    }
599
1.53k
    if ((tx_err = svt_aom_pic_buf_desc_pool_ctor(
600
1.53k
             &ctx->tx_quant_coeff_pool, &thirty_two_width_picture_buffer_desc_init_data, TX_TYPES)) != EB_ErrorNone) {
601
0
        return tx_err;
602
0
    }
603
26.0k
    for (uint32_t txt_itr = 0; txt_itr < TX_TYPES; ++txt_itr) {
604
24.5k
        ctx->recon_coeff_ptr[txt_itr] = &ctx->tx_recon_coeff_pool.descs[txt_itr];
605
24.5k
        ctx->recon_ptr[txt_itr]       = &ctx->tx_recon_pool.descs[txt_itr];
606
24.5k
        ctx->quant_coeff_ptr[txt_itr] = &ctx->tx_quant_coeff_pool.descs[txt_itr];
607
24.5k
    }
608
1.53k
    EB_NEW(ctx->tx_coeffs, svt_picture_buffer_desc_ctor, (EbPtr)&thirty_two_width_picture_buffer_desc_init_data);
609
1.53k
    EB_NEW(ctx->scratch_prediction_ptr, svt_picture_buffer_desc_ctor, (EbPtr)&picture_buffer_desc_init_data);
610
1.53k
    EbPictureBufferDescInitData double_width_picture_buffer_desc_init_data;
611
1.53k
    double_width_picture_buffer_desc_init_data.max_width          = sb_size;
612
1.53k
    double_width_picture_buffer_desc_init_data.max_height         = sb_size;
613
1.53k
    double_width_picture_buffer_desc_init_data.bit_depth          = EB_SIXTEEN_BIT;
614
1.53k
    double_width_picture_buffer_desc_init_data.color_format       = EB_YUV420;
615
1.53k
    double_width_picture_buffer_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
616
1.53k
    double_width_picture_buffer_desc_init_data.border             = 0;
617
1.53k
    double_width_picture_buffer_desc_init_data.split_mode         = false;
618
1.53k
    double_width_picture_buffer_desc_init_data.is_16bit_pipeline  = false;
619
620
    // The temp_recon_ptr and temp_residual will be shared by all candidates
621
    // If you want to do something with residual or recon, you need to create one
622
1.53k
    EB_NEW(ctx->temp_recon_ptr, svt_picture_buffer_desc_ctor, (EbPtr)&picture_buffer_desc_init_data);
623
1.53k
    EB_NEW(ctx->temp_residual, svt_picture_buffer_desc_ctor, (EbPtr)&double_width_picture_buffer_desc_init_data);
624
625
    // Candidate Buffers
626
1.53k
    EB_ALLOC_PTR_ARRAY(ctx->cand_bf_ptr_array, ctx->max_nics_uv);
627
    // The candidate-buffer structs themselves share one backing allocation (calloc to match
628
    // EB_NEW zero-init) instead of one allocation per candidate.
629
1.53k
    EB_CALLOC_ARRAY(ctx->cand_bf_pool, ctx->max_nics_uv);
630
631
    // pred/rec_coeff/quant for all candidates share one backing allocation each (instead of
632
    // 3 allocations per candidate). Slots [0, max_nics) use the full luma+chroma mask; slots
633
    // [max_nics, max_nics_uv) are chroma-only.
634
1.53k
    EbPictureBufferDescInitData* pred_id = NULL;
635
1.53k
    EbPictureBufferDescInitData* rc_id   = NULL;
636
1.53k
    EbPictureBufferDescInitData* q_id    = NULL;
637
1.53k
    EB_MALLOC_ARRAY(pred_id, ctx->max_nics_uv);
638
1.53k
    EB_MALLOC_ARRAY(rc_id, ctx->max_nics_uv);
639
1.53k
    EB_MALLOC_ARRAY(q_id, ctx->max_nics_uv);
640
16.8k
    for (buffer_index = 0; buffer_index < ctx->max_nics_uv; ++buffer_index) {
641
15.3k
        const uint32_t mask                      = (buffer_index < ctx->max_nics) ? PICTURE_BUFFER_DESC_FULL_MASK
642
15.3k
                                                                                  : PICTURE_BUFFER_DESC_CHROMA_MASK;
643
15.3k
        pred_id[buffer_index].max_width          = sb_size;
644
15.3k
        pred_id[buffer_index].max_height         = sb_size;
645
15.3k
        pred_id[buffer_index].bit_depth          = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) ? EB_TEN_BIT : EB_EIGHT_BIT;
646
15.3k
        pred_id[buffer_index].color_format       = EB_YUV420;
647
15.3k
        pred_id[buffer_index].buffer_enable_mask = mask;
648
15.3k
        pred_id[buffer_index].border             = 0;
649
15.3k
        pred_id[buffer_index].split_mode         = false;
650
15.3k
        pred_id[buffer_index].is_16bit_pipeline  = SVT_EFFECTIVE_HBD_MD(ctx->hbd_md) > EB_8_BIT_MD;
651
        // rec_coeff / quant are identical but 32-bit.
652
15.3k
        rc_id[buffer_index]                   = pred_id[buffer_index];
653
15.3k
        rc_id[buffer_index].bit_depth         = EB_THIRTYTWO_BIT;
654
15.3k
        rc_id[buffer_index].is_16bit_pipeline = true;
655
15.3k
        q_id[buffer_index]                    = rc_id[buffer_index];
656
15.3k
    }
657
1.53k
    EbErrorType cand_err = svt_aom_pic_buf_desc_pool_ctor_var(&ctx->cand_pred_pool, pred_id, ctx->max_nics_uv);
658
1.53k
    if (cand_err == EB_ErrorNone) {
659
1.53k
        cand_err = svt_aom_pic_buf_desc_pool_ctor_var(&ctx->cand_rec_coeff_pool, rc_id, ctx->max_nics_uv);
660
1.53k
    }
661
1.53k
    if (cand_err == EB_ErrorNone) {
662
1.53k
        cand_err = svt_aom_pic_buf_desc_pool_ctor_var(&ctx->cand_quant_pool, q_id, ctx->max_nics_uv);
663
1.53k
    }
664
1.53k
    EB_FREE_ARRAY(pred_id);
665
1.53k
    EB_FREE_ARRAY(rc_id);
666
1.53k
    EB_FREE_ARRAY(q_id);
667
1.53k
    if (cand_err != EB_ErrorNone) {
668
0
        return cand_err;
669
0
    }
670
671
16.8k
    for (buffer_index = 0; buffer_index < ctx->max_nics_uv; ++buffer_index) {
672
15.3k
        ctx->cand_bf_ptr_array[buffer_index] = &ctx->cand_bf_pool[buffer_index];
673
15.3k
        EbErrorType cbf_err = svt_aom_mode_decision_cand_bf_ctor(ctx->cand_bf_ptr_array[buffer_index],
674
15.3k
                                                                 &ctx->cand_pred_pool.descs[buffer_index],
675
15.3k
                                                                 &ctx->cand_rec_coeff_pool.descs[buffer_index],
676
15.3k
                                                                 &ctx->cand_quant_pool.descs[buffer_index],
677
15.3k
                                                                 ctx->temp_residual,
678
15.3k
                                                                 ctx->temp_recon_ptr,
679
15.3k
                                                                 &(ctx->fast_cost_array[buffer_index]),
680
15.3k
                                                                 &(ctx->full_cost_array[buffer_index]),
681
15.3k
                                                                 &(ctx->full_cost_ssim_array[buffer_index]));
682
15.3k
        if (cbf_err != EB_ErrorNone) {
683
0
            return cbf_err;
684
0
        }
685
15.3k
    }
686
687
1.53k
    return EB_ErrorNone;
688
1.53k
}
689
690
/**************************************************
691
 * Reset Mode Decision Neighbor Arrays
692
 *************************************************/
693
5.03k
void svt_aom_reset_mode_decision_neighbor_arrays(PictureControlSet* pcs, uint16_t tile_idx) {
694
5.03k
    uint8_t depth;
695
20.1k
    for (depth = 0; depth < NA_TOT_CNT; depth++) {
696
15.1k
        svt_aom_neighbor_array_unit_reset(pcs->mdleaf_partition_na[depth][tile_idx]);
697
15.1k
        if (SVT_EFFECTIVE_HBD_MD(pcs->hbd_md) != EB_10_BIT_MD) {
698
15.1k
            svt_aom_neighbor_array_unit_reset(pcs->md_luma_recon_na[depth][tile_idx]);
699
15.1k
            svt_aom_neighbor_array_unit_reset(pcs->md_tx_depth_1_luma_recon_na[depth][tile_idx]);
700
15.1k
            svt_aom_neighbor_array_unit_reset(pcs->md_tx_depth_2_luma_recon_na[depth][tile_idx]);
701
15.1k
            svt_aom_neighbor_array_unit_reset(pcs->md_cb_recon_na[depth][tile_idx]);
702
15.1k
            svt_aom_neighbor_array_unit_reset(pcs->md_cr_recon_na[depth][tile_idx]);
703
15.1k
        }
704
15.1k
        if (SVT_EFFECTIVE_HBD_MD(pcs->hbd_md) > EB_8_BIT_MD ||
705
15.1k
            (SVT_EFFECTIVE_BIT_DEPTH(pcs->scs->encoder_bit_depth) > EB_EIGHT_BIT && pcs->pic_bypass_encdec)) {
706
0
            svt_aom_neighbor_array_unit_reset(pcs->md_luma_recon_na_16bit[depth][tile_idx]);
707
0
            svt_aom_neighbor_array_unit_reset(pcs->md_tx_depth_1_luma_recon_na_16bit[depth][tile_idx]);
708
0
            svt_aom_neighbor_array_unit_reset(pcs->md_tx_depth_2_luma_recon_na_16bit[depth][tile_idx]);
709
0
            svt_aom_neighbor_array_unit_reset(pcs->md_cb_recon_na_16bit[depth][tile_idx]);
710
0
            svt_aom_neighbor_array_unit_reset(pcs->md_cr_recon_na_16bit[depth][tile_idx]);
711
0
        }
712
713
15.1k
        svt_aom_neighbor_array_unit_reset(pcs->md_y_dcs_na[depth][tile_idx]);
714
15.1k
        svt_aom_neighbor_array_unit_reset(pcs->md_tx_depth_1_luma_dc_sign_level_coeff_na[depth][tile_idx]);
715
15.1k
        svt_aom_neighbor_array_unit_reset(pcs->md_cb_dc_sign_level_coeff_na[depth][tile_idx]);
716
15.1k
        svt_aom_neighbor_array_unit_reset(pcs->md_cr_dc_sign_level_coeff_na[depth][tile_idx]);
717
15.1k
        svt_aom_neighbor_array_unit_reset(pcs->md_txfm_context_array[depth][tile_idx]);
718
15.1k
    }
719
720
5.03k
    return;
721
5.03k
}
722
723
// If the ref intra percentage is below the TH, applying modulation to the MD lambda
724
0
#define LAMBDA_MOD_INTRA_TH 50
725
0
#define LAMBDA_MOD_INTRA_SCALING_FACTOR 138
726
727
// Set the lambda for each sb.
728
// When lambda tuning is on (blk_lambda_tuning), lambda of each block is set separately (full_lambda_md/fast_lambda_md)
729
// later in svt_aom_set_tuned_blk_lambda
730
// Testing showed that updating SAD lambda based on frame info was not helpful; therefore, the SAD lambda generation is not changed.
731
6.53k
static void av1_lambda_assign_md(PictureControlSet* pcs, ModeDecisionContext* ctx) {
732
6.53k
    ctx->full_lambda_md[0] = svt_aom_compute_rd_mult(pcs, ctx->qp_index, ctx->me_q_index, EB_EIGHT_BIT);
733
6.53k
    ctx->fast_lambda_md[0] = svt_aom_compute_fast_lambda(pcs, ctx->qp_index, ctx->me_q_index, EB_EIGHT_BIT);
734
6.53k
    ctx->full_lambda_md[1] = svt_aom_compute_rd_mult(pcs, ctx->qp_index, ctx->me_q_index, EB_TEN_BIT);
735
6.53k
    ctx->fast_lambda_md[1] = svt_aom_compute_fast_lambda(pcs, ctx->qp_index, ctx->me_q_index, EB_TEN_BIT);
736
737
6.53k
    if (!pcs->scs->static_config.rtc && pcs->scs->stats_based_sb_lambda_modulation) {
738
6.53k
        if (pcs->temporal_layer_index > 0) {
739
0
            if (pcs->ref_intra_percentage < LAMBDA_MOD_INTRA_TH) {
740
0
                ctx->full_lambda_md[0] = (ctx->full_lambda_md[0] * LAMBDA_MOD_INTRA_SCALING_FACTOR) >> 7;
741
0
                ctx->fast_lambda_md[0] = (ctx->fast_lambda_md[0] * LAMBDA_MOD_INTRA_SCALING_FACTOR) >> 7;
742
0
                ctx->full_lambda_md[1] = (ctx->full_lambda_md[1] * LAMBDA_MOD_INTRA_SCALING_FACTOR) >> 7;
743
0
                ctx->fast_lambda_md[1] = (ctx->fast_lambda_md[1] * LAMBDA_MOD_INTRA_SCALING_FACTOR) >> 7;
744
0
            }
745
0
        }
746
6.53k
    }
747
748
6.53k
    if (pcs->lambda_weight) {
749
3.38k
        ctx->full_lambda_md[0] = (uint32_t)((ctx->full_lambda_md[0] * (uint64_t)pcs->lambda_weight) >> 7);
750
3.38k
        ctx->fast_lambda_md[0] = (uint32_t)((ctx->fast_lambda_md[0] * (uint64_t)pcs->lambda_weight) >> 7);
751
3.38k
        ctx->full_lambda_md[1] = (uint32_t)((ctx->full_lambda_md[1] * (uint64_t)pcs->lambda_weight) >> 7);
752
3.38k
        ctx->fast_lambda_md[1] = (uint32_t)((ctx->fast_lambda_md[1] * (uint64_t)pcs->lambda_weight) >> 7);
753
3.38k
    }
754
6.53k
    ctx->full_lambda_md[1] *= 16;
755
6.53k
    ctx->fast_lambda_md[1] *= 4;
756
757
6.53k
    SequenceControlSet* scs          = pcs->scs;
758
6.53k
    uint64_t            scale_factor = scs->static_config.lambda_scale_factors[pcs->ppcs->update_type];
759
6.53k
    ctx->full_lambda_md[0]           = (uint32_t)((ctx->full_lambda_md[0] * scale_factor) >> 7);
760
6.53k
    ctx->full_lambda_md[1]           = (uint32_t)((ctx->full_lambda_md[1] * scale_factor) >> 7);
761
6.53k
    ctx->fast_lambda_md[0]           = (uint32_t)((ctx->fast_lambda_md[0] * scale_factor) >> 7);
762
6.53k
    ctx->fast_lambda_md[1]           = (uint32_t)((ctx->fast_lambda_md[1] * scale_factor) >> 7);
763
764
6.53k
    ctx->full_sb_lambda_md[0] = ctx->full_lambda_md[0];
765
6.53k
    ctx->full_sb_lambda_md[1] = ctx->full_lambda_md[1];
766
6.53k
}
767
768
void svt_aom_reset_mode_decision(SequenceControlSet* scs, ModeDecisionContext* ctx, PictureControlSet* pcs,
769
5.40k
                                 uint16_t tile_group_idx, uint32_t segment_index) {
770
5.40k
    ctx->hbd_md = SVT_EFFECTIVE_HBD_MD(pcs->hbd_md);
771
    // Reset MD rate Estimation table to initial values by copying from md_rate_est_ctx
772
5.40k
    ctx->md_rate_est_ctx = pcs->md_rate_est_ctx;
773
    // Segments are dispatched to EncDec threads dynamically; scoping the last DV to the segment keeps
774
    // the BVP fallback independent of the SB->thread mapping (deterministic at any --lp).
775
5.40k
    ctx->intrabc_last_dv.as_int = 0;
776
    // Reset CABAC Contexts
777
778
    // Reset Neighbor Arrays at start of new Segment / Picture
779
5.40k
    if (segment_index == 0) {
780
492
        for (uint16_t r = pcs->ppcs->tile_group_info[tile_group_idx].tile_group_tile_start_y;
781
2.03k
             r < pcs->ppcs->tile_group_info[tile_group_idx].tile_group_tile_end_y;
782
1.54k
             r++) {
783
1.54k
            for (uint16_t c = pcs->ppcs->tile_group_info[tile_group_idx].tile_group_tile_start_x;
784
6.58k
                 c < pcs->ppcs->tile_group_info[tile_group_idx].tile_group_tile_end_x;
785
5.03k
                 c++) {
786
5.03k
                uint16_t tile_idx = c + r * pcs->ppcs->av1_cm->tiles_info.tile_cols;
787
5.03k
                svt_aom_reset_mode_decision_neighbor_arrays(pcs, tile_idx);
788
5.03k
            }
789
1.54k
        }
790
492
        (void)scs;
791
492
    }
792
    //each segment enherits the bypass encdec from the picture level
793
5.40k
    ctx->bypass_encdec = pcs->pic_bypass_encdec;
794
5.40k
    return;
795
5.40k
}
796
797
/******************************************************
798
 * Mode Decision Configure SB
799
 ******************************************************/
800
void svt_aom_mode_decision_configure_sb(ModeDecisionContext* ctx, PictureControlSet* pcs, uint8_t sb_qp,
801
6.53k
                                        uint8_t me_sb_qp) {
802
    /* Note(CHKN) : when Qp modulation varies QP on a sub-SB(CU) basis,  Lamda has to change based on Cu->QP , and then this code has to move inside the CU loop in MD */
803
804
    // Lambda Assignement
805
6.53k
    ctx->qp_index = pcs->ppcs->frm_hdr.delta_q_params.delta_q_present || pcs->ppcs->r0_delta_qp_md
806
6.53k
        ? sb_qp
807
6.53k
        : (uint8_t)pcs->ppcs->frm_hdr.quantization_params.base_q_idx;
808
809
6.53k
    ctx->me_q_index = me_sb_qp;
810
811
6.53k
    av1_lambda_assign_md(pcs, ctx);
812
813
6.53k
    ctx->hbd_pack_done = 0;
814
815
6.53k
    return;
816
6.53k
}