Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Globals/enc_handle.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
*
4
* This source code is subject to the terms of the BSD 3-Clause Clear License and
5
* the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear License
6
* was not distributed with this source code in the LICENSE file, you can
7
* obtain it at https://www.aomedia.org/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
// SUMMARY
12
//   Contains the API component functions
13
14
/**************************************
15
 * Includes
16
 **************************************/
17
#include <stdlib.h>
18
#include <stdio.h>
19
#include <stdint.h>
20
21
#include "EbVersion.h"
22
#include "svt_threads.h"
23
#include "utility.h"
24
#include "enc_handle.h"
25
#include "enc_settings.h"
26
#include "pcs.h"
27
#include "pic_operators.h"
28
#include "reference_object.h"
29
#include "resource_coordination_process.h"
30
#include "pic_analysis_process.h"
31
#include "pd_process.h"
32
#include "me_process.h"
33
#include "initial_rc_process.h"
34
#include "src_ops_process.h"
35
#include "pic_manager_process.h"
36
#include "rc_process.h"
37
#include "md_config_process.h"
38
#include "enc_dec_process.h"
39
#include "ec_process.h"
40
#include "packetization_process.h"
41
#include "resource_coordination_results.h"
42
#include "pic_analysis_results.h"
43
#include "pd_results.h"
44
#include "me_results.h"
45
#include "initial_rc_results.h"
46
#include "pic_demux_results.h"
47
#include "rc_tasks.h"
48
#include "enc_dec_tasks.h"
49
#include "enc_dec_results.h"
50
#include "ec_results.h"
51
#include "pred_structure.h"
52
#include "rest_process.h"
53
#include "cdef_process.h"
54
#include "dlf_process.h"
55
#include "rc_results.h"
56
#include "definitions.h"
57
#include "metadata_handle.h"
58
#include "grainSynthesis.h"
59
60
#include "pack_unpack_c.h"
61
#include "enc_mode_config.h"
62
#include "hash.h"
63
64
#ifdef ARCH_X86_64
65
#include <immintrin.h>
66
#endif
67
#include "svt_log.h"
68
69
#ifdef _WIN32
70
#include <windows.h>
71
#else
72
#include <errno.h>
73
#include <unistd.h>
74
#endif
75
76
#include "aom_dsp_rtcd.h"
77
#include "common_dsp_rtcd.h"
78
79
/**************************************
80
  * Defines
81
  **************************************/
82
// clang-format off
83
// Config Set Initial Count
84
604
#define EB_SequenceControlSetPoolInitCount              10
85
// Process Instantiation Initial Counts
86
#define EB_ResourceCoordinationProcessInitCount         1
87
#define EB_PictureDecisionProcessInitCount              1
88
#define EB_InitialRateControlProcessInitCount           1
89
604
#define EB_PictureManagerProcessInitCount               1
90
#define EB_RateControlProcessInitCount                  1
91
1.20k
#define EB_PacketizationProcessInitCount                1
92
93
// Output Buffer Transfer Parameters
94
604
#define TPL_INPUT_PORT_SOP                              0
95
604
#define TPL_INPUT_PORT_TPL                              1
96
3.02k
#define TPL_INPUT_PORT_INVALID                          -1
97
604
#define ENCDEC_INPUT_PORT_MDC                           0
98
604
#define ENCDEC_INPUT_PORT_ENCDEC                        1
99
4.24k
#define ENCDEC_INPUT_PORT_INVALID                       -1
100
101
1.20k
#define ENCODE_FIRST_PASS                               1
102
// clang-format on
103
104
uint8_t svt_aom_get_tpl_synthesizer_block_size(int8_t tpl_level, uint32_t picture_width, uint32_t picture_height);
105
106
/* count number of refs in a steady state MG*/
107
604
static uint16_t get_num_refs_in_one_mg(uint32_t hierarchical_levels, uint32_t referencing_scheme) {
108
604
    if (hierarchical_levels == 0) {
109
0
        return 1;
110
0
    }
111
112
    // All internal layer pics will be used as references.  Only top layer pics can be
113
    // not used as refs.
114
604
    uint16_t tot_refs = 1 << (hierarchical_levels - 1);
115
116
    // Top layer pics start at pic_idx 0 and every second pic is a top layer pic
117
1.81k
    for (uint16_t pic_idx = 0; pic_idx < (uint32_t)(1 << hierarchical_levels); pic_idx += 2) {
118
1.20k
        tot_refs += svt_aom_is_pic_used_as_ref(
119
1.20k
            hierarchical_levels, hierarchical_levels, pic_idx, referencing_scheme, 0);
120
1.20k
    }
121
122
604
    return tot_refs;
123
604
}
124
125
1.20k
static const char* get_asm_level_name_str(EbCpuFlags cpu_flags) {
126
    // clang-format off
127
1.20k
    static const struct {
128
1.20k
        const char *name;
129
1.20k
        EbCpuFlags  flags;
130
1.20k
    } param_maps[] = {
131
1.20k
        {"c",            0},
132
#ifdef ARCH_X86_64
133
        {"mmx",          EB_CPU_FLAGS_MMX},
134
        {"sse",          EB_CPU_FLAGS_SSE},
135
        {"sse2",         EB_CPU_FLAGS_SSE2},
136
        {"sse3",         EB_CPU_FLAGS_SSE3},
137
        {"ssse3",        EB_CPU_FLAGS_SSSE3},
138
        {"sse4_1",       EB_CPU_FLAGS_SSE4_1},
139
        {"sse4_2",       EB_CPU_FLAGS_SSE4_2},
140
        {"avx",          EB_CPU_FLAGS_AVX},
141
        {"avx2",         EB_CPU_FLAGS_AVX2},
142
        {"avx512",       EB_CPU_FLAGS_AVX512F},
143
        {"avx512icl",    EB_CPU_FLAGS_AVX512ICL},
144
#elif defined(ARCH_AARCH64)
145
        {"neon",         EB_CPU_FLAGS_NEON},
146
        {"crc32",        EB_CPU_FLAGS_ARM_CRC32},
147
        {"neon_dotprod", EB_CPU_FLAGS_NEON_DOTPROD},
148
        {"neon_i8mm",    EB_CPU_FLAGS_NEON_I8MM},
149
        {"sve",          EB_CPU_FLAGS_SVE},
150
        {"sve2",         EB_CPU_FLAGS_SVE2}
151
#endif
152
1.20k
    };
153
    // clang-format on
154
1.20k
    static const uint32_t para_map_size = sizeof(param_maps) / sizeof(param_maps[0]);
155
156
2.41k
    for (int32_t i = para_map_size - 1; i >= 0; --i) {
157
1.20k
        if (param_maps[i].flags & cpu_flags) {
158
0
            return param_maps[i].name;
159
0
        }
160
1.20k
    }
161
1.20k
    return "c";
162
1.20k
}
163
164
//Get Number of logical processors
165
604
static uint32_t get_num_processors() {
166
#ifdef _WIN32
167
    return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
168
#else
169
604
    return sysconf(_SC_NPROCESSORS_ONLN);
170
604
#endif
171
604
}
172
173
void    svt_aom_asm_set_convolve_asm_table(void);
174
void    svt_aom_asm_set_convolve_hbd_asm_table(void);
175
void    svt_aom_init_intra_dc_predictors_c_internal(void);
176
void    svt_aom_init_intra_predictors_internal(void);
177
void    svt_av1_init_me_luts(void);
178
uint8_t svt_aom_get_tpl_group_level(uint8_t tpl, int8_t enc_mode);
179
uint8_t svt_aom_set_tpl_group(PictureParentControlSet* pcs, uint8_t tpl_group_level, uint32_t source_width,
180
                              uint32_t source_height);
181
182
604
static void enc_switch_to_real_time() {
183
604
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
184
604
    if (!geteuid()) {
185
604
        (void)pthread_setschedparam(pthread_self(), SCHED_FIFO, &(struct sched_param){.sched_priority = 99});
186
604
    }
187
604
#endif
188
604
}
189
190
typedef enum ParallelLevel {
191
    PARALLEL_LEVEL_1     = 1,
192
    PARALLEL_LEVEL_2     = 2,
193
    PARALLEL_LEVEL_3     = 3,
194
    PARALLEL_LEVEL_4     = 4,
195
    PARALLEL_LEVEL_5     = 5,
196
    PARALLEL_LEVEL_6     = 6,
197
    PARALLEL_LEVEL_COUNT = 7
198
} ParallelLevel;
199
200
// When level of parallelism is not specified, the level will be determined
201
// based on the core count of the machine
202
0
#define PARALLEL_LEVEL_1_RANGE 1 // single core count
203
0
#define PARALLEL_LEVEL_2_RANGE 2
204
0
#define PARALLEL_LEVEL_3_RANGE 5
205
0
#define PARALLEL_LEVEL_4_RANGE 11
206
0
#define PARALLEL_LEVEL_5_RANGE 23
207
#define PARALLEL_LEVEL_6_RANGE 47
208
209
// Map a machine core count to the default level of parallelism used when the
210
// user leaves lp unset (lp == 0).
211
0
static uint32_t get_default_level_of_parallelism(uint32_t core_count) {
212
0
    if (core_count <= PARALLEL_LEVEL_1_RANGE) {
213
0
        return PARALLEL_LEVEL_1;
214
0
    } else if (core_count <= PARALLEL_LEVEL_2_RANGE) {
215
0
        return PARALLEL_LEVEL_2;
216
0
    } else if (core_count <= PARALLEL_LEVEL_3_RANGE) {
217
0
        return PARALLEL_LEVEL_3;
218
0
    } else if (core_count <= PARALLEL_LEVEL_4_RANGE) {
219
0
        return PARALLEL_LEVEL_4;
220
0
    } else if (core_count <= PARALLEL_LEVEL_5_RANGE) {
221
0
        return PARALLEL_LEVEL_5;
222
0
    }
223
0
    return PARALLEL_LEVEL_6;
224
0
}
225
226
//return max wavefronts in a given picture
227
604
static uint32_t get_max_wavefronts(uint32_t width, uint32_t height, uint32_t blk_size) {
228
604
    assert(width > 0 && height > 0);
229
604
    return (MIN(width, height) + (blk_size - 1)) / blk_size;
230
604
}
231
232
/*
233
* When the picture dimension is a single SB, must use a single segment (EncDec segments
234
* assume a width of at least 2 SBs)
235
*
236
* Return true if the pic dimension is a single SB width
237
*/
238
1.81k
static bool is_pic_dimension_single_sb(uint32_t sb_size, uint16_t pic_dimension) {
239
1.81k
    return ((pic_dimension + sb_size - 1) / sb_size) == 1;
240
1.81k
}
241
242
/*********************************************************************************
243
* set_segments_numbers: Set the segment numbers for difference processes
244
***********************************************************************************/
245
604
void set_segments_numbers(SequenceControlSet* scs) {
246
604
    const uint32_t lp = scs->lp;
247
248
604
    scs->enc_dec_segment_row_count_array =
249
604
        (lp == PARALLEL_LEVEL_1 || is_pic_dimension_single_sb(scs->super_block_size, scs->max_input_luma_width)) ? 1
250
604
        : (scs->super_block_size == 128) ? MAX((int32_t)((scs->max_input_luma_height + 64) / 128), 1)
251
520
                                         : MAX((int32_t)((scs->max_input_luma_height + 32) / 64), 1);
252
604
    scs->enc_dec_segment_col_count_array =
253
604
        (lp == PARALLEL_LEVEL_1 || is_pic_dimension_single_sb(scs->super_block_size, scs->max_input_luma_height)) ? 1
254
604
        : (scs->super_block_size == 128) ? MAX((int32_t)((scs->max_input_luma_width + 64) / 128), 1)
255
552
                                         : MAX((int32_t)((scs->max_input_luma_width + 32) / 64), 1);
256
257
604
    scs->me_segment_row_count_array = scs->tf_segment_row_count = (lp == PARALLEL_LEVEL_1) ? 1
258
604
        : (((scs->max_input_luma_height + 32) / BLOCK_SIZE_64) < 6)                        ? 1
259
604
                                                                                           : 8;
260
604
    scs->me_segment_col_count_array = scs->tf_segment_column_count = (lp == PARALLEL_LEVEL_1) ? 1
261
604
        : (((scs->max_input_luma_width + 32) / BLOCK_SIZE_64) < 10)                           ? 1
262
604
                                                                                              : 6;
263
264
    // Jing:
265
    // A tile group can be consisted by 1 tile or NxM tiles.
266
    // Segments will be parallelized within a tile group
267
    // We can use tile group to control the threads/parallelism in ED stage
268
    // NOTE:1 col will have better perf for segments for large resolutions
269
604
    if (scs->static_config.pred_structure == LOW_DELAY) {
270
        // Low-delay is picture-serial, so tiles are the only intra-frame parallelism:
271
        // map one tile-group per tile (RA keeps a single tile-group).
272
0
        scs->tile_group_col_count_array = 1 << scs->static_config.tile_columns;
273
0
        scs->tile_group_row_count_array = 1 << scs->static_config.tile_rows;
274
604
    } else {
275
        // by default, do not use tile parallel. to enable, one can set one tile-group per tile.
276
604
        scs->tile_group_col_count_array = 1;
277
604
        scs->tile_group_row_count_array = 1;
278
604
    }
279
280
    // TPL processed in 64x64 blocks, so check width against 64x64 block size (even if SB is 128x128)
281
604
    scs->tpl_segment_row_count_array = (lp == PARALLEL_LEVEL_1 ||
282
604
                                        is_pic_dimension_single_sb(64, scs->max_input_luma_width))
283
604
        ? 1
284
604
        : MAX((int32_t)((scs->max_input_luma_height + 32) / 64), 1);
285
286
604
    scs->tpl_segment_col_count_array = (lp == PARALLEL_LEVEL_1)
287
604
        ? 1
288
604
        : MAX((int32_t)((scs->max_input_luma_width + 32) / 64), 1);
289
290
604
    scs->cdef_segment_row_count    = (lp == PARALLEL_LEVEL_1)       ? 1
291
604
        : (((scs->max_input_luma_height + 32) / BLOCK_SIZE_64) < 6) ? 1
292
604
        : (scs->input_resolution <= INPUT_SIZE_1080p_RANGE)         ? 2
293
0
                                                                    : 4;
294
604
    scs->cdef_segment_column_count = (lp == PARALLEL_LEVEL_1)       ? 1
295
604
        : (((scs->max_input_luma_width + 32) / BLOCK_SIZE_64) < 10) ? 1
296
604
        : (scs->input_resolution <= INPUT_SIZE_1080p_RANGE)         ? 3
297
0
                                                                    : 6;
298
299
    //since restoration unit size is same for Luma and Chroma, Luma segments and chroma segments do not correspond to the same area!
300
    //to keep proper processing, segments have to be configured based on chroma resolution.
301
604
    const uint32_t unit_size       = RESTORATION_UNITSIZE_MAX;
302
604
    const uint32_t rest_seg_w      = MAX((scs->max_input_luma_width / 2 + (unit_size >> 1)) / unit_size, 1);
303
604
    const uint32_t rest_seg_h      = MAX((scs->max_input_luma_height / 2 + (unit_size >> 1)) / unit_size, 1);
304
604
    scs->rest_segment_column_count = (lp == PARALLEL_LEVEL_1) ? 1
305
604
        : scs->input_resolution <= INPUT_SIZE_1080p_RANGE     ? MIN(rest_seg_w, 6)
306
604
                                                              : MIN(rest_seg_w, 9);
307
604
    scs->rest_segment_row_count    = (lp == PARALLEL_LEVEL_1) ? 1
308
604
        : scs->input_resolution <= INPUT_SIZE_1080p_RANGE     ? MIN(rest_seg_h, 4)
309
604
                                                              : MIN(rest_seg_h, 6);
310
311
    // Low-delay ME segment right-sizing, gated to <=540p (INPUT_SIZE_480p_RANGE).
312
    //
313
    // The ME grid set above is resolution-blind: it is a flat 8x6 = 48 segments for every
314
    // resolution >= 640x360, which at 360p is only ~1.25 superblocks of work per segment. In
315
    // low delay n_extra_mg is 0, so max_me == 1 and max_me_proc == tot_me_segs (see below):
316
    // the ME segment count *is* the ME worker pool, and with a single picture in flight a
317
    // segment's cost lands directly on the frame's critical path. Segments beyond what the
318
    // configured parallelism can consume are therefore pure per-segment overhead.
319
    //
320
    // Trim towards whichever floor binds first, and never below it:
321
    //   - two segments per core that this parallelism level represents, so the ME pool keeps
322
    //     slack to absorb the cost variance between segments, and
323
    //   - a bound on the work per segment, so a large frame is never reduced to a handful of
324
    //     coarse segments that serialize the ME stage.
325
    // Both floors err towards more segments: getting them wrong costs some of the saving, it
326
    // does not cost throughput. 720p and above stay on the stock 8x6: pinned 4-core 720p lp3
327
    // regresses when the grid is reduced. VOD/RA, lp1, lp5+, and 1x1 grids (CIF and below)
328
    // are also untouched.
329
604
    if (scs->static_config.pred_structure == LOW_DELAY && lp != PARALLEL_LEVEL_1 && lp <= PARALLEL_LEVEL_4 &&
330
0
        scs->input_resolution <= INPUT_SIZE_480p_RANGE) {
331
0
        const uint32_t max_sbs_per_seg = 20;
332
0
        const uint32_t lp_cores        = (lp == PARALLEL_LEVEL_2) ? PARALLEL_LEVEL_2_RANGE
333
0
            : (lp == PARALLEL_LEVEL_3)                            ? PARALLEL_LEVEL_3_RANGE
334
0
                                                                  : PARALLEL_LEVEL_4_RANGE;
335
0
        const uint32_t sb_total        = ((scs->max_input_luma_width + BLOCK_SIZE_64 - 1) / BLOCK_SIZE_64) *
336
0
            ((scs->max_input_luma_height + BLOCK_SIZE_64 - 1) / BLOCK_SIZE_64);
337
0
        const uint32_t min_segs = MAX(2 * lp_cores, (sb_total + max_sbs_per_seg - 1) / max_sbs_per_seg);
338
339
0
        uint32_t rows = scs->me_segment_row_count_array;
340
0
        uint32_t cols = scs->me_segment_col_count_array;
341
        // Shrink the longer axis one step at a time while staying at or above the floor. Only
342
        // ever shrinks, so a grid that is already at or below the floor is left alone.
343
0
        for (;;) {
344
0
            const uint32_t next_rows = (rows >= cols && rows > 1) ? rows - 1 : rows;
345
0
            const uint32_t next_cols = (next_rows == rows && cols > 1) ? cols - 1 : cols;
346
0
            if ((next_rows == rows && next_cols == cols) || next_rows * next_cols < min_segs) {
347
0
                break;
348
0
            }
349
0
            rows = next_rows;
350
0
            cols = next_cols;
351
0
        }
352
0
        scs->me_segment_row_count_array = scs->tf_segment_row_count = rows;
353
0
        scs->me_segment_col_count_array = scs->tf_segment_column_count = cols;
354
0
    }
355
604
}
356
357
604
static EbErrorType load_default_buffer_configuration_settings(SequenceControlSet* scs) {
358
604
    EbErrorType return_error = EB_ErrorNone;
359
604
    uint32_t    core_count   = get_num_processors();
360
361
604
    uint32_t lp = scs->static_config.level_of_parallelism;
362
604
    if (lp == 0) {
363
        // In the default config (lp == 0) the core count will determine the
364
        // amount of parallelism used
365
0
        lp = get_default_level_of_parallelism(core_count);
366
0
    }
367
604
    scs->lp = lp;
368
604
    set_segments_numbers(scs);
369
370
604
    const bool is_low_delay = (scs->static_config.pred_structure == LOW_DELAY);
371
    // adjust buffer count for superres
372
604
    uint32_t superres_count = (scs->static_config.superres_mode == SUPERRES_AUTO &&
373
0
                               (scs->static_config.superres_auto_search_type == SUPERRES_AUTO_DUAL ||
374
0
                                scs->static_config.superres_auto_search_type == SUPERRES_AUTO_ALL))
375
604
        ? 1
376
604
        : 0;
377
378
    //#====================== Data Structures and Picture Buffers ======================
379
380
604
    uint32_t min_input, min_parent, min_child, min_paref, min_ref, min_tpl_ref, min_overlay, min_recon, min_me;
381
604
    uint32_t max_input, max_parent, max_child, max_paref, max_me, max_recon;
382
383
    /*Look-Ahead. Picture-Decision outputs pictures by group of mini-gops so
384
        the needed pictures for a certain look-ahead distance (LAD) should be rounded up to the next multiple of MiniGopSize.*/
385
604
    uint32_t      mg_size = 1 << scs->static_config.hierarchical_levels;
386
604
    const uint8_t overlay = scs->static_config.enable_overlays ? 1 : 0;
387
388
    /*To accomodate FFMPEG EOS, 1 frame delay is needed in Resource coordination for RA (for the low delay mode, buffering for receiving EOS does not happen).
389
      Note that we have the option to not add 1 frame delay of Resource Coordination. In this case we have wait for first I frame
390
      to be released back to be able to start first base(16). Anyway poc16 needs to wait for poc0 to finish.*/
391
604
    const uint8_t eos_delay = is_low_delay || scs->allintra ? 0 : 1;
392
393
    //Minimum input pictures needed in the pipeline
394
604
    uint16_t lad_mg_pictures = (1 + mg_size + overlay) *
395
604
        scs->lad_mg; //Unit= 1(provision for a potential delayI) + prediction struct + potential overlay        return_ppcs = (1 + mg_size) * (scs->lad_mg + 1)  + scs->scd_delay + eos_delay;
396
604
    uint32_t return_ppcs = (1 + mg_size) * (scs->lad_mg + 1) + scs->scd_delay + eos_delay;
397
    //scs->input_buffer_fifo_init_count = return_ppcs;
398
399
604
    min_input = return_ppcs;
400
401
604
    min_parent = return_ppcs;
402
403
    // If overlay frames are used, each input will be assigned 2 ppcs: one for the regular frame, and one for the potential alt-ref frame
404
604
    if (scs->static_config.enable_overlays) {
405
0
        min_parent *= 2;
406
0
    }
407
408
    //Pic-Manager will inject one child at a time.
409
604
    min_child                          = 1;
410
604
    const uint16_t num_ref_from_cur_mg = get_num_refs_in_one_mg(scs->static_config.hierarchical_levels,
411
604
                                                                scs->mrp_ctrls.referencing_scheme) +
412
604
        1; //+1: to accomodate one for a delayed-I
413
604
    const uint16_t num_ref_lad_mgs = num_ref_from_cur_mg * scs->lad_mg;
414
604
    const uint8_t  dpb_frames =
415
604
        REF_FRAMES; // up to dpb_frame refs from prev MGs can be used (AV1 spec allows holding up to 8 frames for references)
416
604
    min_ref     = (scs->enable_dec_order) ? dpb_frames + 1 : num_ref_from_cur_mg + num_ref_lad_mgs + dpb_frames;
417
604
    min_tpl_ref = scs->tpl ? dpb_frames + 1 : 0; // TPL pictures are processed in decode order
418
604
    if (scs->tpl) {
419
        // PictureDecisionContext.mg_size = mg_size + overlay; see EbPictureDecisionProcess.c line 5680
420
0
        min_me = 1 + // potential delay I
421
0
            lad_mg_pictures + // 16 + 1 ME data used in store_tpl_pictures() at line 5717
422
0
            (mg_size + overlay); // 16 + 1 ME data used in store_tpl_pictures() at line 5729
423
604
    } else {
424
604
        min_me = 1;
425
604
    }
426
427
    //PA REF
428
604
    const uint16_t num_pa_ref_from_cur_mg =
429
604
        mg_size; //ref+nref; nRef PA buffers are processed in PicAnalysis and used in TF
430
604
    min_paref = num_pa_ref_from_cur_mg + lad_mg_pictures + scs->scd_delay + eos_delay + dpb_frames;
431
432
604
    if (scs->static_config.enable_overlays) {
433
        // Need an extra PA ref buffer for each overlay picture. Overlay pics use the same DPB as
434
        // regular pics, so no need to allocate an extra dpb_frames buffers for the ref pics
435
0
        min_paref += num_pa_ref_from_cur_mg + lad_mg_pictures + scs->scd_delay + eos_delay;
436
0
    }
437
    //Overlays
438
    // Each input pic will assign a ppcs and for each potential overlay, will assign a buffer to store the unfiltered input picture
439
604
    min_overlay = scs->static_config.enable_overlays ? return_ppcs : 0;
440
604
    min_recon   = min_ref;
441
442
604
    if (is_low_delay) {
443
0
        uint32_t low_delay_tf_frames = scs->tf_params_per_type[1].max_num_past_pics;
444
0
        min_input = min_parent = 1 + low_delay_tf_frames + scs->scd_delay + eos_delay;
445
0
        min_child              = 1; // max_child is 1 for LD
446
0
        uint8_t max_refs       = dpb_frames;
447
        // For special, known, RPS structures and ref frame counts, we can reduce the number of ref buffers
448
        // A session declaring max_hierarchical_levels may raise its MG size later
449
        // via MG_SIZE_CHANGE_EVENT, so the flat-IPP shortcut would size the pools
450
        // for layers it no longer has. Keep the full sizing for those sessions.
451
0
        const bool mg_size_may_change = scs->static_config.max_hierarchical_levels > 0;
452
0
        if (!mg_size_may_change && scs->static_config.rtc && scs->static_config.hierarchical_levels == 0) {
453
0
            max_refs = scs->mrp_ctrls.flat_max_refs;
454
            // For flat IPP the previous frame is always used as a reference. Therefore, that picture does
455
            // not require a special buffer for use as a TF ref.
456
0
            if (low_delay_tf_frames) {
457
0
                low_delay_tf_frames -= 1;
458
0
            }
459
0
        } else if (scs->mrp_ctrls.ld_reduce_ref_buffs == 1) {
460
0
            max_refs = 4;
461
0
        } else if (scs->mrp_ctrls.ld_reduce_ref_buffs == 2) {
462
0
            max_refs = 2;
463
0
        }
464
        // Set flat_max_refs in case we switch MG size
465
0
        scs->mrp_ctrls.flat_max_refs = max_refs;
466
467
0
        min_ref = 1 /*current pic*/ + max_refs;
468
        // Ref-frame management: app may hold up to max_managed_refs anchors
469
        // simultaneously; grow the ref-buffer pool by that many entries.
470
        // When max_managed_refs == 0 (default), this adds 0 and the legacy
471
        // memory footprint is preserved bit-exactly.
472
0
        min_ref += scs->static_config.max_managed_refs;
473
0
        min_me    = 1;
474
0
        min_paref = 1 /*current pic*/ + low_delay_tf_frames + max_refs + scs->scd_delay + eos_delay;
475
        // Same rationale for the PA-ref pool.
476
0
        min_paref += scs->static_config.max_managed_refs;
477
0
    }
478
479
    //Configure max needed buffers to process 1+n_extra_mg Mini-Gops in the pipeline. n extra MGs to feed to picMgr on top of current one.
480
    // Low delay mode has no extra minigops to process.
481
604
    uint32_t n_extra_mg;
482
604
    if (lp <= PARALLEL_LEVEL_3 || is_low_delay) {
483
0
        n_extra_mg = 0;
484
604
    } else if (lp <= PARALLEL_LEVEL_4) {
485
604
        n_extra_mg = 1;
486
604
    } else if (lp <= PARALLEL_LEVEL_5) {
487
0
        n_extra_mg = 2;
488
0
    } else {
489
0
        n_extra_mg = scs->input_resolution <= INPUT_SIZE_4K_RANGE ? 7
490
0
            : scs->input_resolution <= INPUT_SIZE_8K_RANGE        ? 5
491
0
                                                                  : 0;
492
0
    }
493
494
604
    max_input  = min_input + (1 + mg_size) * n_extra_mg;
495
604
    max_parent = max_input;
496
604
    max_child  = (mg_size / 2) * (n_extra_mg + 1);
497
604
    max_child  = MAX(max_child, 1); //have at least one child for mg_size<2
498
    // In low delay mode, will only have one picture at a time to process
499
604
    if (is_low_delay) {
500
0
        max_child = 1;
501
0
    }
502
503
    // max_ref defines here to avoid cppcheck warning
504
604
    uint32_t max_ref = min_ref + num_ref_from_cur_mg * n_extra_mg;
505
604
    max_paref        = min_paref + (1 + mg_size) * n_extra_mg;
506
604
    max_me           = min_me + (1 + mg_size) * n_extra_mg;
507
604
    max_recon        = max_ref;
508
    // if tpl_la is disabled when super-res fix/random, input speed is much faster than recon output speed,
509
    // recon_output_fifo might be full and freeze at svt_aom_recon_output()
510
604
    if (!scs->tpl && scs->static_config.recon_enabled) {
511
0
        max_recon = min_recon = MAX(max_ref, 30);
512
0
    }
513
514
    //#====================== Process Buffers ======================
515
604
    scs->input_buffer_fifo_init_count            = clamp(max_input, min_input, max_input);
516
604
    scs->picture_control_set_pool_init_count     = clamp(max_parent, min_parent, max_parent);
517
604
    scs->pa_reference_picture_buffer_init_count  = clamp(max_paref, min_paref, max_paref);
518
604
    scs->tpl_reference_picture_buffer_init_count = min_tpl_ref;
519
604
    scs->output_recon_buffer_fifo_init_count = scs->reference_picture_buffer_init_count = clamp(
520
604
        max_recon, min_recon, max_recon);
521
604
    scs->me_pool_init_count                      = clamp(max_me, min_me, max_me);
522
604
    scs->overlay_input_picture_buffer_init_count = min_overlay;
523
524
604
    if (lp <= PARALLEL_LEVEL_1 || MIN_PIC_PARALLELIZATION) {
525
0
        scs->input_buffer_fifo_init_count              = min_input;
526
0
        scs->picture_control_set_pool_init_count       = min_parent;
527
0
        scs->pa_reference_picture_buffer_init_count    = min_paref;
528
0
        scs->tpl_reference_picture_buffer_init_count   = min_tpl_ref;
529
0
        scs->reference_picture_buffer_init_count       = min_ref;
530
0
        scs->picture_control_set_pool_init_count_child = min_child;
531
0
        scs->enc_dec_pool_init_count                   = min_child;
532
0
        scs->me_pool_init_count                        = min_me;
533
0
        scs->overlay_input_picture_buffer_init_count   = min_overlay;
534
535
0
        scs->output_recon_buffer_fifo_init_count = MAX(scs->reference_picture_buffer_init_count, min_recon);
536
0
#if CONFIG_SINGLE_THREAD_KERNEL
537
        // In ST mode the dispatcher processes a full mini-GOP before returning
538
        // to the app.  svt_aom_recon_output() is called from both REST and
539
        // Packetization for each non-alt-ref frame, consuming 2 buffers per
540
        // frame.  The pool must hold enough for the full mini-GOP.
541
0
        if (scs->static_config.recon_enabled) {
542
0
            scs->output_recon_buffer_fifo_init_count = MAX(scs->output_recon_buffer_fifo_init_count, return_ppcs);
543
0
        }
544
0
#endif
545
604
    } else if (lp <= PARALLEL_LEVEL_2) {
546
0
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count = clamp(2, min_child, max_child) +
547
0
            superres_count;
548
604
    } else if (lp <= PARALLEL_LEVEL_3) {
549
0
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count = clamp(8, min_child, max_child) +
550
0
            superres_count;
551
604
    } else if (lp <= PARALLEL_LEVEL_4) {
552
604
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count = clamp(
553
604
                                                                                            12, min_child, max_child) +
554
604
            superres_count;
555
604
    } else if (lp <= PARALLEL_LEVEL_5) {
556
0
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count = clamp(
557
0
                                                                                            16, min_child, max_child) +
558
0
            superres_count;
559
0
    } else {
560
0
        const uint8_t pcs_processes                    = scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR &&
561
0
                scs->static_config.pass == ENC_SECOND_PASS
562
0
            ? 24
563
0
            : 20;
564
0
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count =
565
0
            clamp(pcs_processes, min_child, max_child) + superres_count;
566
0
    }
567
568
604
    if (scs->static_config.avif) {
569
604
        scs->input_buffer_fifo_init_count              = 4;
570
604
        scs->picture_control_set_pool_init_count       = 4;
571
604
        scs->pa_reference_picture_buffer_init_count    = 4;
572
604
        scs->tpl_reference_picture_buffer_init_count   = 0;
573
604
        scs->output_recon_buffer_fifo_init_count       = 2; // the picture's recon + the recon EOS
574
604
        scs->reference_picture_buffer_init_count       = 2;
575
604
        scs->picture_control_set_pool_init_count_child = 1;
576
604
        scs->enc_dec_pool_init_count                   = 1;
577
604
        scs->me_pool_init_count                        = 1;
578
604
        scs->overlay_input_picture_buffer_init_count   = 0;
579
604
        scs->allintra                                  = true;
580
604
        scs->static_config.intra_period_length         = 0;
581
604
    }
582
583
    //#====================== Inter process Fifos ======================
584
604
    const uint32_t tot_tf_segs  = scs->tf_segment_column_count * scs->tf_segment_row_count;
585
604
    const uint32_t tot_me_segs  = scs->me_segment_col_count_array * scs->me_segment_row_count_array;
586
604
    const uint32_t tot_tpl_segs = scs->tpl_segment_col_count_array * scs->tpl_segment_row_count_array;
587
    // For VBR/Capped-CRF and superres, we may use a recode loop, in which case, the enc dec fifo queue should be increased
588
    // to account for the extra potential calls.
589
604
    const bool     allow_recode     = scs->static_config.recode_loop != DISALLOW_RECODE;
590
604
    const bool     is_superres      = scs->static_config.superres_mode != SUPERRES_NONE;
591
604
    const uint32_t tot_enc_dec_segs = scs->enc_dec_segment_col_count_array * scs->enc_dec_segment_row_count_array;
592
604
    const uint32_t tot_cdef_segs    = scs->cdef_segment_column_count * scs->cdef_segment_row_count;
593
604
    const uint32_t tot_rest_segs    = scs->rest_segment_column_count * scs->rest_segment_row_count;
594
604
    const uint32_t tot_tiles = MIN(64, (1 << scs->static_config.tile_columns) * (1 << scs->static_config.tile_rows));
595
604
    const uint32_t max_fifo  = 300;
596
597
    // Open loop
598
604
    scs->resource_coordination_fifo_init_count = MIN(
599
604
        max_fifo, scs->picture_control_set_pool_init_count); // outputs one pic @ a time to pic analysis (no segments)
600
604
    scs->picture_analysis_fifo_init_count = MIN(
601
604
        max_fifo, scs->picture_control_set_pool_init_count); // output from pic analysis to PD process (single threaded)
602
    // +1 b/c release_prev_picture_from_reorder_queue keeps the entry behind the head for the scd
603
    // histogram until the next pass, so the window is one wider than the ppcs pool
604
604
    scs->enc_ctx->picture_decision_reorder_queue_size = scs->picture_control_set_pool_init_count + 1;
605
604
    scs->picture_decision_fifo_init_count             = MIN(
606
604
        max_fifo, scs->picture_control_set_pool_init_count * MAX(tot_me_segs, tot_tf_segs));
607
604
    scs->motion_estimation_fifo_init_count = MIN(
608
604
        max_fifo, scs->picture_control_set_pool_init_count); // output from ME to init_rc_process (single threaded)
609
604
    scs->initial_rate_control_fifo_init_count = MIN(
610
604
        max_fifo, scs->picture_control_set_pool_init_count); // output from irc to src_ops (single threaded)
611
604
    scs->tpl_disp_fifo_init_count = MIN(max_fifo,
612
604
                                        scs->picture_control_set_pool_init_count * tot_tpl_segs); // TPL dispenser
613
614
    // Pic manager (pass through from open loop to closed loop)
615
604
    scs->picture_demux_fifo_init_count = MIN(
616
604
        max_fifo,
617
604
        scs->picture_control_set_pool_init_count +
618
604
            2 * scs->picture_control_set_pool_init_count_child); // input to pic mgr from src ops, rest, and packetization
619
604
    scs->enc_ctx->pic_mgr_input_pic_list_size = scs->picture_control_set_pool_init_count;
620
621
    // Closed loop
622
604
    scs->rate_control_tasks_fifo_init_count = MIN(
623
604
        max_fifo,
624
604
        2 * scs->picture_control_set_pool_init_count_child); // inputs to rc form pic manager and EC/packetization
625
604
    scs->rate_control_fifo_init_count = MIN(max_fifo,
626
604
                                            scs->picture_control_set_pool_init_count_child); // inputs to MDC from rc
627
604
    scs->mode_decision_configuration_fifo_init_count = MIN(
628
604
        max_fifo,
629
604
        scs->picture_control_set_pool_init_count_child * tot_tiles * tot_enc_dec_segs *
630
604
            (1 + allow_recode + is_superres)); // input to MD from MDC
631
604
    scs->enc_dec_fifo_init_count = MIN(max_fifo,
632
604
                                       scs->picture_control_set_pool_init_count_child); // TODO: Add DLF segments
633
604
    scs->dlf_fifo_init_count     = MIN(
634
604
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_cdef_segs); // input to CDEF from DLF
635
604
    scs->cdef_fifo_init_count = MIN(
636
604
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_rest_segs); // input to rest from CDEF
637
604
    scs->rest_fifo_init_count = MIN(
638
604
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_tiles); // input to EC from rest
639
604
    scs->entropy_coding_fifo_init_count = MIN(
640
604
        max_fifo, scs->picture_control_set_pool_init_count_child); // EC outputs to packetization (single threaded)
641
604
    scs->enc_ctx->packetization_reorder_queue_size = scs->picture_control_set_pool_init_count;
642
    // bistream buffer will be allocated at run time. app will free the buffer once written to file.
643
    //
644
    // release_frames frees the reorder slot and its ppcs, but not the output buffer, which only the
645
    // app frees. Holder: 1 per undrained reorder
646
    // slot (<= ppcs pool), 1 per frame parked in the undisplayed queue
647
    // (<= UNDISP_QUEUE_SIZE), +2 to signal EOS @ resource coord
648
    // Upperbound matters. Packetization can block in svt_get_empty_object without a slot.
649
604
    scs->output_stream_buffer_fifo_init_count = scs->picture_control_set_pool_init_count + UNDISP_QUEUE_SIZE + 2;
650
651
    //#====================== Processes number ======================
652
604
    scs->total_process_init_count = 0;
653
654
604
    uint32_t max_pa_proc, max_me_proc, max_tpl_proc, max_mdc_proc, max_md_proc, max_ec_proc, max_dlf_proc,
655
604
        max_cdef_proc, max_rest_proc;
656
657
604
    max_pa_proc  = max_input;
658
604
    max_me_proc  = max_me * tot_me_segs;
659
604
    max_tpl_proc = scs->tpl ? get_max_wavefronts(scs->max_input_luma_width, scs->max_input_luma_height, 64) : 1;
660
604
    max_mdc_proc = scs->picture_control_set_pool_init_count_child;
661
604
    max_md_proc  = scs->picture_control_set_pool_init_count_child *
662
604
        get_max_wavefronts(scs->max_input_luma_width, scs->max_input_luma_height, scs->super_block_size);
663
604
    max_ec_proc = scs->picture_control_set_pool_init_count_child;
664
    // Low-delay is picture-serial, so MD/EC parallelize only across tiles. Raise
665
    // their ceilings to the tile count and target ld_workers below, which doubles
666
    // per --lp level (matching the core-count brackets) so the thread count
667
    // scales with --lp instead of being pinned to 1 (EC) or flat.
668
604
    uint32_t ld_workers = 1;
669
604
    if (is_low_delay) {
670
        // Each tile has its own segment wavefront, so the MD ceiling is the sum
671
        // of per-tile wavefronts (not the single frame-wide one), and EC can run
672
        // one worker per tile.
673
0
        uint32_t per_tile_wf = get_max_wavefronts(MAX(scs->max_input_luma_width / scs->tile_group_col_count_array, 1u),
674
0
                                                  MAX(scs->max_input_luma_height / scs->tile_group_row_count_array, 1u),
675
0
                                                  scs->super_block_size);
676
677
0
        max_md_proc = MAX(max_md_proc, tot_tiles * per_tile_wf);
678
0
        max_ec_proc = MAX(max_ec_proc, tot_tiles);
679
0
        ld_workers  = 1u << (lp - 1);
680
0
    }
681
604
    max_dlf_proc  = scs->picture_control_set_pool_init_count_child;
682
604
    max_cdef_proc = scs->picture_control_set_pool_init_count_child * scs->cdef_segment_column_count *
683
604
        scs->cdef_segment_row_count;
684
604
    max_rest_proc = scs->picture_control_set_pool_init_count_child * scs->rest_segment_column_count *
685
604
        scs->rest_segment_row_count;
686
1.20k
#define WORKERS_COUNT(x) (is_low_delay ? ld_workers : (x))
687
604
    if (lp <= PARALLEL_LEVEL_1) {
688
0
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = 1);
689
0
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = 1);
690
0
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
691
0
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = 1);
692
0
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = 1);
693
0
        scs->total_process_init_count += (scs->enc_dec_process_init_count = 1);
694
0
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = 1);
695
0
        scs->total_process_init_count += (scs->dlf_process_init_count = 1);
696
0
        scs->total_process_init_count += (scs->cdef_process_init_count = 1);
697
0
        scs->total_process_init_count += (scs->rest_process_init_count = 1);
698
604
    } else if (lp <= PARALLEL_LEVEL_2) {
699
0
        const uint8_t pa_processes = scs->static_config.film_grain_denoise_strength ? 16 : 1;
700
0
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
701
0
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = clamp(
702
0
                                              pa_processes, 1, max_pa_proc));
703
0
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = clamp(20, 1, max_me_proc));
704
0
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = clamp(6, 1, max_tpl_proc));
705
0
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = clamp(
706
0
                                              1, 1, max_mdc_proc));
707
0
        scs->total_process_init_count +=
708
0
            (scs->enc_dec_process_init_count = clamp(
709
0
                 WORKERS_COUNT(3), scs->picture_control_set_pool_init_count_child, max_md_proc));
710
0
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = clamp(
711
0
                                              WORKERS_COUNT(1), 1, max_ec_proc));
712
0
        scs->total_process_init_count += (scs->dlf_process_init_count = clamp(1, 1, max_dlf_proc));
713
0
        scs->total_process_init_count += (scs->cdef_process_init_count = clamp(6, 1, max_cdef_proc));
714
0
        scs->total_process_init_count += (scs->rest_process_init_count = clamp(1, 1, max_rest_proc));
715
604
    } else if (lp <= PARALLEL_LEVEL_3) {
716
0
        const uint8_t pa_processes = scs->static_config.film_grain_denoise_strength ? 16 : 1;
717
0
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
718
0
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = clamp(
719
0
                                              pa_processes, 1, max_pa_proc));
720
0
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = clamp(25, 1, max_me_proc));
721
0
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = clamp(6, 1, max_tpl_proc));
722
0
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = clamp(
723
0
                                              2, 1, max_mdc_proc));
724
0
        scs->total_process_init_count +=
725
0
            (scs->enc_dec_process_init_count = clamp(
726
0
                 WORKERS_COUNT(5), scs->picture_control_set_pool_init_count_child, max_md_proc));
727
0
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = clamp(
728
0
                                              WORKERS_COUNT(2), 1, max_ec_proc));
729
0
        scs->total_process_init_count += (scs->dlf_process_init_count = clamp(2, 1, max_dlf_proc));
730
0
        scs->total_process_init_count += (scs->cdef_process_init_count = clamp(6, 1, max_cdef_proc));
731
0
        scs->total_process_init_count += (scs->rest_process_init_count = clamp(2, 1, max_rest_proc));
732
604
    } else if (lp <= PARALLEL_LEVEL_5 || scs->input_resolution <= INPUT_SIZE_1080p_RANGE) {
733
604
        uint8_t pa_processes = scs->static_config.film_grain_denoise_strength ? 20 : 4;
734
604
        if (scs->static_config.pass == ENC_FIRST_PASS) {
735
0
            pa_processes = lp <= PARALLEL_LEVEL_5 ? 12 : 20;
736
0
        }
737
604
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
738
604
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = clamp(
739
604
                                              pa_processes, 1, max_pa_proc));
740
604
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = clamp(25, 1, max_me_proc));
741
604
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = clamp(6, 1, max_tpl_proc));
742
604
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = clamp(
743
604
                                              3, 1, max_mdc_proc));
744
604
        scs->total_process_init_count +=
745
604
            (scs->enc_dec_process_init_count = clamp(
746
604
                 WORKERS_COUNT(6), scs->picture_control_set_pool_init_count_child, max_md_proc));
747
604
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = clamp(
748
604
                                              WORKERS_COUNT(4), 1, max_ec_proc));
749
604
        scs->total_process_init_count += (scs->dlf_process_init_count = clamp(3, 1, max_dlf_proc));
750
604
        scs->total_process_init_count += (scs->cdef_process_init_count = clamp(6, 1, max_cdef_proc));
751
604
        scs->total_process_init_count += (scs->rest_process_init_count = clamp(4, 1, max_rest_proc));
752
604
    } else {
753
0
        const uint8_t pa_processes = (scs->static_config.pass == ENC_FIRST_PASS ||
754
0
                                      scs->static_config.film_grain_denoise_strength)
755
0
            ? 20
756
0
            : 16;
757
0
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
758
0
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = clamp(
759
0
                                              pa_processes, 1, max_pa_proc));
760
0
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = clamp(25, 1, max_me_proc));
761
0
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = clamp(12, 1, max_tpl_proc));
762
0
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = clamp(
763
0
                                              8, 1, max_mdc_proc));
764
0
        scs->total_process_init_count +=
765
0
            (scs->enc_dec_process_init_count = clamp(
766
0
                 WORKERS_COUNT(8), scs->picture_control_set_pool_init_count_child, max_md_proc));
767
0
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = clamp(
768
0
                                              WORKERS_COUNT(10), 1, max_ec_proc));
769
0
        scs->total_process_init_count += (scs->dlf_process_init_count = clamp(8, 1, max_dlf_proc));
770
0
        scs->total_process_init_count += (scs->cdef_process_init_count = clamp(8, 1, max_cdef_proc));
771
0
        scs->total_process_init_count += (scs->rest_process_init_count = clamp(10, 1, max_rest_proc));
772
0
    }
773
604
#undef WORKERS_COUNT
774
604
    scs->total_process_init_count += 6; // single processes count
775
604
    if (scs->static_config.pass == 0 || scs->static_config.pass == 2) {
776
604
        SVT_INFO("Level of Parallelism: %u\n", lp);
777
604
        SVT_INFO("Number of PPCS %u\n", scs->picture_control_set_pool_init_count);
778
779
        /******************************************************************
780
        * Platform detection, limit cpu flags to hardware available CPU
781
        ******************************************************************/
782
#if defined ARCH_X86_64 || defined ARCH_AARCH64
783
        const EbCpuFlags cpu_flags        = svt_aom_get_cpu_flags();
784
        const EbCpuFlags cpu_flags_to_use = svt_aom_get_cpu_flags_to_use();
785
        scs->static_config.use_cpu_flags &= cpu_flags_to_use;
786
        SVT_INFO("[asm level on system : up to %s]\n", get_asm_level_name_str(cpu_flags));
787
        SVT_INFO("[asm level selected : up to %s]\n", get_asm_level_name_str(scs->static_config.use_cpu_flags));
788
#else
789
604
        scs->static_config.use_cpu_flags &= 0;
790
604
        SVT_INFO("[asm level on system : up to %s]\n", get_asm_level_name_str(0));
791
604
        SVT_INFO("[asm level selected : up to %s]\n", get_asm_level_name_str(scs->static_config.use_cpu_flags));
792
604
#endif
793
604
    }
794
604
    return return_error;
795
604
}
796
797
typedef struct {
798
    int32_t  type;
799
    uint32_t count;
800
} EncDecPorts_t;
801
802
// The port-count arrays are built per-instance as locals in svt_av1_enc_init()
803
// and passed to the lookup/total_count helpers below. They must not be
804
// file-scope globals: the .count fields are derived from per-instance,
805
// preset-dependent process counts, so concurrent svt_av1_enc_init() calls at
806
// different presets would race on them (see #2381).
807
808
// Rate Control
809
static uint32_t rate_control_port_lookup(const RateControlPorts* rate_control_ports, RateControlInputPortTypes type,
810
1.20k
                                         uint32_t port_type_index) {
811
1.20k
    uint32_t port_index = 0;
812
1.20k
    uint32_t port_count = 0;
813
814
1.81k
    while ((type != rate_control_ports[port_index].type) && (type != RATE_CONTROL_INPUT_PORT_INVALID)) {
815
604
        port_count += rate_control_ports[port_index++].count;
816
604
    }
817
1.20k
    return (port_count + port_type_index);
818
1.20k
}
819
820
// Rate Control
821
604
static uint32_t rate_control_port_total_count(const RateControlPorts* rate_control_ports) {
822
604
    uint32_t port_index  = 0;
823
604
    uint32_t total_count = 0;
824
825
1.81k
    while (rate_control_ports[port_index].type != RATE_CONTROL_INPUT_PORT_INVALID) {
826
1.20k
        total_count += rate_control_ports[port_index++].count;
827
1.20k
    }
828
604
    return total_count;
829
604
}
830
831
static uint32_t pic_mgr_port_lookup(const PicMgrPorts* pic_mgr_ports, PicMgrInputPortTypes type,
832
1.81k
                                    uint32_t port_type_index) {
833
1.81k
    uint32_t port_index = 0;
834
1.81k
    uint32_t port_count = 0;
835
836
3.62k
    while ((type != pic_mgr_ports[port_index].type) && (type != PIC_MGR_INPUT_PORT_INVALID)) {
837
1.81k
        port_count += pic_mgr_ports[port_index++].count;
838
1.81k
    }
839
1.81k
    return (port_count + port_type_index);
840
1.81k
}
841
842
604
static uint32_t pic_mgr_port_total_count(const PicMgrPorts* pic_mgr_ports) {
843
604
    uint32_t port_index  = 0;
844
604
    uint32_t total_count = 0;
845
846
2.41k
    while (pic_mgr_ports[port_index].type != PIC_MGR_INPUT_PORT_INVALID) {
847
1.81k
        total_count += pic_mgr_ports[port_index++].count;
848
1.81k
    }
849
604
    return total_count;
850
604
}
851
852
// TPL
853
1.20k
static uint32_t tpl_port_lookup(const EncDecPorts_t* tpl_ports, int32_t type, uint32_t port_type_index) {
854
1.20k
    uint32_t port_index = 0;
855
1.20k
    uint32_t port_count = 0;
856
857
1.81k
    while ((type != tpl_ports[port_index].type) && (type != TPL_INPUT_PORT_INVALID)) {
858
604
        port_count += tpl_ports[port_index++].count;
859
604
    }
860
1.20k
    return (port_count + port_type_index);
861
1.20k
}
862
863
604
static uint32_t tpl_port_total_count(const EncDecPorts_t* tpl_ports) {
864
604
    uint32_t port_index  = 0;
865
604
    uint32_t total_count = 0;
866
867
1.81k
    while (tpl_ports[port_index].type != TPL_INPUT_PORT_INVALID) {
868
1.20k
        total_count += tpl_ports[port_index++].count;
869
1.20k
    }
870
604
    return total_count;
871
604
}
872
873
/*****************************************
874
 * Input Port Lookup
875
 *****************************************/
876
// EncDec
877
2.43k
static uint32_t enc_dec_port_lookup(const EncDecPorts_t* enc_dec_ports, int32_t type, uint32_t port_type_index) {
878
2.43k
    uint32_t port_index = 0;
879
2.43k
    uint32_t port_count = 0;
880
881
4.25k
    while ((type != enc_dec_ports[port_index].type) && (type != ENCDEC_INPUT_PORT_INVALID)) {
882
1.82k
        port_count += enc_dec_ports[port_index++].count;
883
1.82k
    }
884
2.43k
    return (port_count + port_type_index);
885
2.43k
}
886
887
// EncDec
888
604
static uint32_t enc_dec_port_total_count(const EncDecPorts_t* enc_dec_ports) {
889
604
    uint32_t port_index  = 0;
890
604
    uint32_t total_count = 0;
891
892
1.81k
    while (enc_dec_ports[port_index].type != ENCDEC_INPUT_PORT_INVALID) {
893
1.20k
        total_count += enc_dec_ports[port_index++].count;
894
1.20k
    }
895
604
    return total_count;
896
604
}
897
898
/*****************************************
899
 * Input Port Total Count
900
 *****************************************/
901
902
static void lib_svt_encoder_send_error_exit(EbPtr hComponent, uint32_t error_code);
903
904
604
static void svt_enc_handle_stop_threads(EbEncHandle* enc_handle_ptr) {
905
604
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
906
    // Resource Coordination
907
604
    EB_DESTROY_THREAD(enc_handle_ptr->resource_coordination_thread_handle);
908
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->picture_analysis_thread_handle_array,
909
604
                            scs->picture_analysis_process_init_count);
910
911
    // Picture Decision
912
604
    EB_DESTROY_THREAD(enc_handle_ptr->picture_decision_thread_handle);
913
914
    // Motion Estimation
915
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->motion_estimation_thread_handle_array,
916
604
                            scs->motion_estimation_process_init_count);
917
918
    // Initial Rate Control
919
604
    EB_DESTROY_THREAD(enc_handle_ptr->initial_rate_control_thread_handle);
920
921
    // Source Based Oprations
922
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->source_based_operations_thread_handle_array,
923
604
                            scs->source_based_operations_process_init_count);
924
925
    // TPL dispenser ME
926
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->tpl_disp_thread_handle_array, scs->tpl_disp_process_init_count);
927
928
    // Picture Manager
929
604
    EB_DESTROY_THREAD(enc_handle_ptr->picture_manager_thread_handle);
930
931
    // Rate Control
932
604
    EB_DESTROY_THREAD(enc_handle_ptr->rate_control_thread_handle);
933
934
    // Mode Decision Configuration Process
935
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->mode_decision_configuration_thread_handle_array,
936
604
                            scs->mode_decision_configuration_process_init_count);
937
938
    // EncDec Process
939
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->enc_dec_thread_handle_array, scs->enc_dec_process_init_count);
940
941
    // Dlf Process
942
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->dlf_thread_handle_array, scs->dlf_process_init_count);
943
944
    // Cdef Process
945
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->cdef_thread_handle_array, scs->cdef_process_init_count);
946
947
    // Rest Process
948
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->rest_thread_handle_array, scs->rest_process_init_count);
949
950
    // Entropy Coding Process
951
604
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->entropy_coding_thread_handle_array, scs->entropy_coding_process_init_count);
952
953
    // Packetization
954
604
    EB_DESTROY_THREAD(enc_handle_ptr->packetization_thread_handle);
955
604
}
956
957
/**********************************
958
* Encoder Library Handle Deonstructor
959
**********************************/
960
604
static void svt_enc_handle_dctor(EbPtr p) {
961
604
    EbEncHandle* enc_handle_ptr = (EbEncHandle*)p;
962
604
    svt_enc_handle_stop_threads(enc_handle_ptr);
963
604
    EB_FREE(enc_handle_ptr->app_callback_ptr);
964
604
    EB_DELETE(enc_handle_ptr->scs_pool_ptr);
965
604
    EB_DELETE(enc_handle_ptr->picture_parent_control_set_pool_ptr);
966
604
    EB_DELETE(enc_handle_ptr->me_pool_ptr);
967
604
    EB_DELETE(enc_handle_ptr->picture_control_set_pool_ptr);
968
604
    EB_DELETE(enc_handle_ptr->enc_dec_pool_ptr);
969
604
    EB_DELETE(enc_handle_ptr->pa_reference_picture_pool_ptr);
970
604
    EB_DELETE(enc_handle_ptr->tpl_reference_picture_pool_ptr);
971
604
    EB_DELETE(enc_handle_ptr->overlay_input_picture_pool_ptr);
972
604
    EB_DELETE(enc_handle_ptr->reference_picture_pool_ptr);
973
604
    EB_DELETE(enc_handle_ptr->input_cmd_resource_ptr);
974
604
    EB_DELETE(enc_handle_ptr->input_y8b_buffer_resource_ptr);
975
976
    //all y_buffer have been redirected to y8b location that just got released.
977
    //to prevent releasing twice, we need to reset the buffer back to NULL
978
604
    if (enc_handle_ptr->input_buffer_resource_ptr) {
979
3.02k
        for (uint32_t w_i = 0; w_i < enc_handle_ptr->input_buffer_resource_ptr->object_total_count; ++w_i) {
980
2.41k
            EbObjectWrapper*     wrp  = enc_handle_ptr->input_buffer_resource_ptr->wrapper_ptr_pool[w_i];
981
2.41k
            EbBufferHeaderType*  obj  = (EbBufferHeaderType*)wrp->object_ptr;
982
2.41k
            EbPictureBufferDesc* desc = (EbPictureBufferDesc*)obj->p_buffer;
983
2.41k
            desc->y_buffer            = 0;
984
2.41k
        }
985
604
    }
986
604
    EB_DELETE(enc_handle_ptr->input_buffer_resource_ptr);
987
604
    EB_DELETE(enc_handle_ptr->output_stream_buffer_resource_ptr);
988
604
    EB_DELETE(enc_handle_ptr->output_recon_buffer_resource_ptr);
989
604
    EB_DELETE(enc_handle_ptr->resource_coordination_results_resource_ptr);
990
604
    EB_DELETE(enc_handle_ptr->picture_analysis_results_resource_ptr);
991
604
    EB_DELETE(enc_handle_ptr->picture_decision_results_resource_ptr);
992
604
    EB_DELETE(enc_handle_ptr->motion_estimation_results_resource_ptr);
993
604
    EB_DELETE(enc_handle_ptr->initial_rate_control_results_resource_ptr);
994
604
    EB_DELETE(enc_handle_ptr->picture_demux_results_resource_ptr);
995
604
    EB_DELETE(enc_handle_ptr->tpl_disp_res_srm);
996
604
    EB_DELETE(enc_handle_ptr->rate_control_tasks_resource_ptr);
997
604
    EB_DELETE(enc_handle_ptr->rate_control_results_resource_ptr);
998
604
    EB_DELETE(enc_handle_ptr->enc_dec_tasks_resource_ptr);
999
604
    EB_DELETE(enc_handle_ptr->enc_dec_results_resource_ptr);
1000
604
    EB_DELETE(enc_handle_ptr->dlf_results_resource_ptr);
1001
604
    EB_DELETE(enc_handle_ptr->cdef_results_resource_ptr);
1002
604
    EB_DELETE(enc_handle_ptr->rest_results_resource_ptr);
1003
604
    EB_DELETE(enc_handle_ptr->entropy_coding_results_resource_ptr);
1004
1005
604
    EB_DELETE(enc_handle_ptr->resource_coordination_context_ptr);
1006
604
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
1007
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->picture_analysis_context_ptr_array, scs->picture_analysis_process_init_count);
1008
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->motion_estimation_context_ptr_array, scs->motion_estimation_process_init_count);
1009
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->tpl_disp_context_ptr_array, scs->tpl_disp_process_init_count);
1010
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->source_based_operations_context_ptr_array,
1011
604
                        scs->source_based_operations_process_init_count);
1012
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->mode_decision_configuration_context_ptr_array,
1013
604
                        scs->mode_decision_configuration_process_init_count);
1014
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->enc_dec_context_ptr_array, scs->enc_dec_process_init_count);
1015
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->dlf_context_ptr_array, scs->dlf_process_init_count);
1016
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->cdef_context_ptr_array, scs->cdef_process_init_count);
1017
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->rest_context_ptr_array, scs->rest_process_init_count);
1018
604
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->entropy_coding_context_ptr_array, scs->entropy_coding_process_init_count);
1019
604
    EB_DELETE(enc_handle_ptr->scs_instance);
1020
604
    EB_DELETE(enc_handle_ptr->picture_decision_context_ptr);
1021
604
    EB_DELETE(enc_handle_ptr->initial_rate_control_context_ptr);
1022
604
    EB_DELETE(enc_handle_ptr->picture_manager_context_ptr);
1023
604
    EB_DELETE(enc_handle_ptr->rate_control_context_ptr);
1024
604
    EB_DELETE(enc_handle_ptr->packetization_context_ptr);
1025
604
}
1026
1027
/**********************************
1028
* Encoder Library Handle Constructor
1029
**********************************/
1030
604
static EbErrorType svt_enc_handle_ctor(EbEncHandle* enc_handle_ptr, EbComponentType* ebHandlePtr) {
1031
604
    enc_handle_ptr->dctor = svt_enc_handle_dctor;
1032
1033
    // Initialize Callbacks
1034
604
    EB_MALLOC_OBJECT(enc_handle_ptr->app_callback_ptr);
1035
604
    enc_handle_ptr->app_callback_ptr->error_handler = lib_svt_encoder_send_error_exit;
1036
604
    enc_handle_ptr->app_callback_ptr->handle        = ebHandlePtr;
1037
1038
    // Config Set Count
1039
604
    enc_handle_ptr->scs_pool_total_count = EB_SequenceControlSetPoolInitCount;
1040
    // Initialize Sequence Control Set Instance
1041
604
    EB_NEW(enc_handle_ptr->scs_instance, svt_sequence_control_set_instance_ctor);
1042
1043
604
    enc_handle_ptr->eos_received   = false;
1044
604
    enc_handle_ptr->eos_sent       = false;
1045
604
    enc_handle_ptr->frame_received = false;
1046
604
    enc_handle_ptr->is_prev_valid  = true;
1047
604
    return EB_ErrorNone;
1048
604
}
1049
1050
EbErrorType svt_input_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr);
1051
1052
EbErrorType svt_output_recon_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr);
1053
1054
EbErrorType svt_overlay_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr);
1055
1056
EbErrorType svt_output_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr);
1057
1058
void svt_input_buffer_header_destroyer(EbPtr p);
1059
void svt_output_recon_buffer_header_destroyer(EbPtr p);
1060
void svt_output_buffer_header_destroyer(EbPtr p);
1061
1062
EbErrorType svt_input_y8b_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr);
1063
void        svt_input_y8b_destroyer(EbPtr p);
1064
1065
2.41k
static EbErrorType in_cmd_ctor(InputCommand* context_ptr, EbPtr object_init_data_ptr) {
1066
2.41k
    (void)context_ptr;
1067
2.41k
    (void)object_init_data_ptr;
1068
1069
2.41k
    return EB_ErrorNone;
1070
2.41k
}
1071
1072
/*
1073
* Input Command Constructor
1074
*/
1075
2.41k
EbErrorType svt_input_cmd_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1076
2.41k
    InputCommand* obj;
1077
1078
2.41k
    *object_dbl_ptr = NULL;
1079
2.41k
    EB_NEW(obj, in_cmd_ctor, object_init_data_ptr);
1080
2.41k
    *object_dbl_ptr = obj;
1081
1082
2.41k
    return EB_ErrorNone;
1083
2.41k
}
1084
1085
604
static EbErrorType dlf_results_ctor(DlfResults* context_ptr, EbPtr object_init_data_ptr) {
1086
604
    (void)context_ptr;
1087
604
    (void)object_init_data_ptr;
1088
1089
604
    return EB_ErrorNone;
1090
604
}
1091
1092
604
static EbErrorType dlf_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1093
604
    DlfResults* obj;
1094
1095
604
    *object_dbl_ptr = NULL;
1096
604
    EB_NEW(obj, dlf_results_ctor, object_init_data_ptr);
1097
604
    *object_dbl_ptr = obj;
1098
1099
604
    return EB_ErrorNone;
1100
604
}
1101
1102
/*
1103
   TPL results ctor
1104
*/
1105
24.0k
EbErrorType tpl_disp_results_ctor(TplDispResults* context_ptr, EbPtr object_init_data_ptr) {
1106
24.0k
    (void)context_ptr;
1107
24.0k
    (void)object_init_data_ptr;
1108
1109
24.0k
    return EB_ErrorNone;
1110
24.0k
}
1111
1112
/*
1113
   TPL results creator
1114
*/
1115
24.0k
static EbErrorType tpl_disp_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1116
24.0k
    TplDispResults* obj;
1117
1118
24.0k
    *object_dbl_ptr = NULL;
1119
24.0k
    EB_NEW(obj, tpl_disp_results_ctor, object_init_data_ptr);
1120
24.0k
    *object_dbl_ptr = obj;
1121
1122
24.0k
    return EB_ErrorNone;
1123
24.0k
}
1124
1125
604
static EbErrorType cdef_results_ctor(CdefResults* context_ptr, EbPtr object_init_data_ptr) {
1126
604
    (void)context_ptr;
1127
604
    (void)object_init_data_ptr;
1128
1129
604
    return EB_ErrorNone;
1130
604
}
1131
1132
604
static EbErrorType cdef_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1133
604
    CdefResults* obj;
1134
1135
604
    *object_dbl_ptr = NULL;
1136
604
    EB_NEW(obj, cdef_results_ctor, object_init_data_ptr);
1137
604
    *object_dbl_ptr = obj;
1138
1139
604
    return EB_ErrorNone;
1140
604
}
1141
1142
9.66k
EbErrorType rest_results_ctor(RestResults* context_ptr, EbPtr object_init_data_ptr) {
1143
9.66k
    (void)context_ptr;
1144
9.66k
    (void)object_init_data_ptr;
1145
1146
9.66k
    return EB_ErrorNone;
1147
9.66k
}
1148
1149
9.66k
static EbErrorType rest_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1150
9.66k
    RestResults* obj;
1151
1152
9.66k
    *object_dbl_ptr = NULL;
1153
9.66k
    EB_NEW(obj, rest_results_ctor, object_init_data_ptr);
1154
9.66k
    *object_dbl_ptr = obj;
1155
1156
9.66k
    return EB_ErrorNone;
1157
9.66k
}
1158
1159
604
static int create_pa_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1160
604
    SequenceControlSet*             scs = enc_handle_ptr->scs_instance->scs;
1161
604
    EbPaReferenceObjectDescInitData eb_pa_ref_obj_ect_desc_init_data_structure;
1162
604
    EbPictureBufferDescInitData     ref_pic_buf_desc_init_data;
1163
604
    EbPictureBufferDescInitData     quart_pic_buf_desc_init_data;
1164
604
    EbPictureBufferDescInitData     sixteenth_pic_buf_desc_init_data;
1165
604
    const bool                      allintra = scs->allintra;
1166
    // PA Reference Picture Buffers
1167
    // Currently, only Luma samples are needed in the PA
1168
604
    ref_pic_buf_desc_init_data.max_width    = scs->max_input_luma_width;
1169
604
    ref_pic_buf_desc_init_data.max_height   = scs->max_input_luma_height;
1170
604
    ref_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
1171
604
    ref_pic_buf_desc_init_data.color_format = EB_YUV420; //use 420 for picture analysis
1172
    //No full-resolution pixel data is allocated for PA REF,
1173
    // it points directly to the Luma input samples of the app data
1174
604
    ref_pic_buf_desc_init_data.buffer_enable_mask = 0;
1175
1176
604
    ref_pic_buf_desc_init_data.border              = scs->border;
1177
604
    ref_pic_buf_desc_init_data.split_mode          = false;
1178
604
    ref_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1179
604
    ref_pic_buf_desc_init_data.mfmv                = 0;
1180
604
    ref_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1181
604
    ref_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1182
1183
604
    quart_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width >> 1;
1184
604
    quart_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height >> 1;
1185
604
    quart_pic_buf_desc_init_data.bit_depth           = EB_EIGHT_BIT;
1186
604
    quart_pic_buf_desc_init_data.color_format        = EB_YUV420;
1187
604
    quart_pic_buf_desc_init_data.buffer_enable_mask  = allintra ? 0 : PICTURE_BUFFER_DESC_LUMA_MASK;
1188
604
    quart_pic_buf_desc_init_data.border              = scs->b64_size >> 1;
1189
604
    quart_pic_buf_desc_init_data.split_mode          = false;
1190
604
    quart_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1191
604
    quart_pic_buf_desc_init_data.mfmv                = 0;
1192
604
    quart_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1193
604
    quart_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1194
1195
604
    sixteenth_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width >> 2;
1196
604
    sixteenth_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height >> 2;
1197
604
    sixteenth_pic_buf_desc_init_data.bit_depth           = EB_EIGHT_BIT;
1198
604
    sixteenth_pic_buf_desc_init_data.color_format        = EB_YUV420;
1199
604
    sixteenth_pic_buf_desc_init_data.buffer_enable_mask  = allintra ? 0 : PICTURE_BUFFER_DESC_LUMA_MASK;
1200
604
    sixteenth_pic_buf_desc_init_data.border              = scs->b64_size >> 2;
1201
604
    sixteenth_pic_buf_desc_init_data.split_mode          = false;
1202
604
    sixteenth_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1203
604
    sixteenth_pic_buf_desc_init_data.mfmv                = 0;
1204
604
    sixteenth_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1205
604
    sixteenth_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1206
1207
604
    eb_pa_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1208
604
    eb_pa_ref_obj_ect_desc_init_data_structure.quarter_picture_desc_init_data   = quart_pic_buf_desc_init_data;
1209
604
    eb_pa_ref_obj_ect_desc_init_data_structure.sixteenth_picture_desc_init_data = sixteenth_pic_buf_desc_init_data;
1210
604
    eb_pa_ref_obj_ect_desc_init_data_structure.static_config                    = &scs->static_config;
1211
    // Reference Picture Buffers
1212
604
    EB_NEW(enc_handle_ptr->pa_reference_picture_pool_ptr,
1213
604
           svt_system_resource_ctor,
1214
604
           scs->pa_reference_picture_buffer_init_count,
1215
604
           EB_PictureDecisionProcessInitCount,
1216
604
           0,
1217
604
           svt_pa_reference_object_creator,
1218
604
           &(eb_pa_ref_obj_ect_desc_init_data_structure),
1219
604
           NULL,
1220
604
           (scs->lp == 1));
1221
    // Set the SequenceControlSet Picture Pool Fifo Ptrs
1222
604
    enc_handle_ptr->scs_instance->enc_ctx->pa_reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1223
604
        enc_handle_ptr->pa_reference_picture_pool_ptr, 0);
1224
#if SRM_REPORT
1225
    enc_handle_ptr->scs_instance->enc_ctx->pa_reference_picture_pool_fifo_ptr->queue_ptr->log = 0;
1226
#endif
1227
604
    return 0;
1228
604
}
1229
1230
0
static int create_tpl_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1231
0
    SequenceControlSet*              scs = enc_handle_ptr->scs_instance->scs;
1232
0
    EbTplReferenceObjectDescInitData eb_tpl_ref_obj_ect_desc_init_data_structure;
1233
0
    EbPictureBufferDescInitData      ref_pic_buf_desc_init_data;
1234
    // PA Reference Picture Buffers
1235
    // Currently, only Luma samples are needed in the PA
1236
0
    ref_pic_buf_desc_init_data.max_width    = scs->max_input_luma_width;
1237
0
    ref_pic_buf_desc_init_data.max_height   = scs->max_input_luma_height;
1238
0
    ref_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
1239
0
    ref_pic_buf_desc_init_data.color_format = EB_YUV420; //use 420 for picture analysis
1240
1241
    // Allocate one ref pic to be used in TPL
1242
0
    ref_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_Y_FLAG;
1243
1244
0
    ref_pic_buf_desc_init_data.border            = TPL_PAD;
1245
0
    ref_pic_buf_desc_init_data.split_mode        = false;
1246
0
    ref_pic_buf_desc_init_data.mfmv              = 0;
1247
0
    ref_pic_buf_desc_init_data.is_16bit_pipeline = false;
1248
1249
0
    ref_pic_buf_desc_init_data.rest_units_per_tile = 0; // rest not needed in tpl scs->rest_units_per_tile;
1250
0
    ref_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1251
1252
0
    eb_tpl_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1253
1254
    // Reference Picture Buffers
1255
0
    EB_NEW(enc_handle_ptr->tpl_reference_picture_pool_ptr,
1256
0
           svt_system_resource_ctor,
1257
0
           scs->tpl_reference_picture_buffer_init_count,
1258
0
           EB_PictureDecisionProcessInitCount,
1259
0
           0,
1260
0
           svt_tpl_reference_object_creator,
1261
0
           &(eb_tpl_ref_obj_ect_desc_init_data_structure),
1262
0
           NULL,
1263
0
           (scs->lp == 1));
1264
    // Set the SequenceControlSet Picture Pool Fifo Ptrs
1265
0
    enc_handle_ptr->scs_instance->enc_ctx->tpl_reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1266
0
        enc_handle_ptr->tpl_reference_picture_pool_ptr, 0);
1267
#if SRM_REPORT
1268
    enc_handle_ptr->scs_instance->enc_ctx->tpl_reference_picture_pool_fifo_ptr->queue_ptr->log = 0;
1269
#endif
1270
0
    return 0;
1271
0
}
1272
1273
604
static int create_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1274
604
    EbReferenceObjectDescInitData eb_ref_obj_ect_desc_init_data_structure;
1275
604
    EbPictureBufferDescInitData   ref_pic_buf_desc_init_data;
1276
604
    SequenceControlSet*           scs = enc_handle_ptr->scs_instance->scs;
1277
604
    bool is_16bit                     = SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) > EB_EIGHT_BIT;
1278
    // Initialize the various Picture types
1279
604
    ref_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width;
1280
604
    ref_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height;
1281
604
    ref_pic_buf_desc_init_data.bit_depth           = scs->encoder_bit_depth;
1282
604
    ref_pic_buf_desc_init_data.color_format        = scs->static_config.encoder_color_format;
1283
604
    ref_pic_buf_desc_init_data.buffer_enable_mask  = PICTURE_BUFFER_DESC_FULL_MASK;
1284
604
    ref_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1285
604
    ref_pic_buf_desc_init_data.sb_total_count      = scs->b64_total_count;
1286
604
    uint16_t padding                               = scs->super_block_size + 32;
1287
604
    if (scs->static_config.superres_mode > SUPERRES_NONE || scs->static_config.resize_mode > RESIZE_NONE) {
1288
0
        padding += scs->super_block_size;
1289
0
    }
1290
1291
604
    ref_pic_buf_desc_init_data.border            = padding;
1292
604
    ref_pic_buf_desc_init_data.mfmv              = scs->mfmv_enabled;
1293
604
    ref_pic_buf_desc_init_data.is_16bit_pipeline = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1294
    // Hsan: split_mode is set @ eb_reference_object_ctor() as both unpacked reference and packed reference are needed for a 10BIT input; unpacked reference @ MD, and packed reference @ EP
1295
1296
604
    ref_pic_buf_desc_init_data.split_mode = false;
1297
604
    if (is_16bit) {
1298
0
        ref_pic_buf_desc_init_data.bit_depth = EB_TEN_BIT;
1299
0
    }
1300
1301
604
    eb_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1302
604
    eb_ref_obj_ect_desc_init_data_structure.hbd_md                           = scs->enable_hbd_mode_decision;
1303
604
    eb_ref_obj_ect_desc_init_data_structure.static_config                    = &scs->static_config;
1304
    // Reference Picture Buffers
1305
604
    EB_NEW(enc_handle_ptr->reference_picture_pool_ptr,
1306
604
           svt_system_resource_ctor,
1307
604
           scs->reference_picture_buffer_init_count,
1308
604
           EB_PictureManagerProcessInitCount,
1309
604
           0,
1310
604
           svt_reference_object_creator,
1311
604
           &(eb_ref_obj_ect_desc_init_data_structure),
1312
604
           NULL,
1313
604
           (scs->lp == 1));
1314
1315
    // Create reference list for Picture Manager
1316
    // When decode-order is not enforced at pic mgr, each reference picture must have an allocated reference buffer (for at least one mini-gop) so the
1317
    // list can be enough to hold only the reference buffers.  When decode-order is enforced, only 9 reference buffers are used, so the list must be at least 1 mini-gop
1318
    // otherwise ref_buffer_available_semaphore will block all required pics from being passed to pic mgr.
1319
604
    const uint32_t ref_pic_list_length = scs->enable_dec_order ? scs->pa_reference_picture_buffer_init_count
1320
604
                                                               : scs->reference_picture_buffer_init_count;
1321
604
    enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list_length = ref_pic_list_length;
1322
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list, ref_pic_list_length);
1323
1324
1.81k
    for (uint32_t idx = 0; idx < ref_pic_list_length; ++idx) {
1325
1.20k
        EB_NEW(enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list[idx], svt_aom_reference_queue_entry_ctor);
1326
1.20k
    }
1327
604
#if CONFIG_SINGLE_THREAD_KERNEL
1328
604
    if (scs->lp > 1)
1329
604
#endif
1330
604
    {
1331
604
        EB_CREATE_SEMAPHORE(scs->ref_buffer_available_semaphore, ref_pic_list_length, ref_pic_list_length);
1332
604
    }
1333
604
    enc_handle_ptr->scs_instance->enc_ctx->reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1334
604
        enc_handle_ptr->reference_picture_pool_ptr, 0);
1335
1336
#if SRM_REPORT
1337
    enc_handle_ptr->scs_instance->enc_ctx->reference_picture_pool_fifo_ptr->queue_ptr->log = 0;
1338
#endif
1339
1340
604
    return 0;
1341
604
}
1342
1343
void init_fn_ptr(void);
1344
void svt_av1_init_wedge_masks(void);
1345
void init_ii_masks(void);
1346
void svt_aom_init_iscan(void);
1347
void svt_aom_build_tx_org(void);
1348
1349
1
static ONCE_ROUTINE(init_global_tables) {
1350
1
    svt_aom_asm_set_convolve_asm_table();
1351
1
    svt_aom_init_intra_dc_predictors_c_internal();
1352
1
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
1353
1
    svt_aom_asm_set_convolve_hbd_asm_table();
1354
1
#endif
1355
1
    svt_aom_init_intra_predictors_internal();
1356
1
    svt_av1_init_me_luts();
1357
1
    init_fn_ptr();
1358
1
    svt_aom_init_iscan();
1359
1
    svt_aom_build_tx_org();
1360
1
#if CONFIG_ENABLE_INTER_COMPOUND && CONFIG_ENABLE_COMPOUND_TYPES
1361
1
    svt_av1_init_wedge_masks();
1362
1
#endif
1363
1
#if CONFIG_ENABLE_INTER_INTRA
1364
1
    init_ii_masks();
1365
1
#endif
1366
1
    svt_av1_crc32c_table_init();
1367
1
    ONCE_ROUTINE_EPILOG;
1368
1
}
1369
1370
DEFINE_ONCE(global_tables_once);
1371
1372
/**********************************
1373
* Initialize Encoder Library
1374
**********************************/
1375
604
EB_API EbErrorType svt_av1_enc_init(EbComponentType* svt_enc_component) {
1376
604
    if (svt_enc_component == NULL) {
1377
0
        return EB_ErrorBadParameter;
1378
0
    }
1379
604
    EbEncHandle*        enc_handle_ptr = (EbEncHandle*)svt_enc_component->p_component_private;
1380
604
    EbErrorType         return_error   = EB_ErrorNone;
1381
604
    SequenceControlSet* scs            = enc_handle_ptr->scs_instance->scs;
1382
604
    EbColorFormat       color_format   = scs->static_config.encoder_color_format;
1383
604
    const bool          single_thread  = (scs->lp == 1);
1384
1385
604
    svt_aom_setup_common_rtcd_internal(scs->static_config.use_cpu_flags);
1386
604
    svt_aom_setup_rtcd_internal(scs->static_config.use_cpu_flags);
1387
604
    svt_run_once(&global_tables_once, init_global_tables);
1388
1389
    // Per-instance block geometry table allocation
1390
604
    EB_MALLOC_ARRAY(scs->blk_geom_mds, scs->max_block_cnt);
1391
604
    svt_aom_build_blk_geom(scs->svt_aom_geom_idx, scs->blk_geom_mds);
1392
    /************************************
1393
     * Sequence Control Set
1394
     ************************************/
1395
604
    EB_NEW(enc_handle_ptr->scs_pool_ptr,
1396
604
           svt_system_resource_ctor,
1397
604
           enc_handle_ptr->scs_pool_total_count,
1398
604
           1,
1399
604
           0,
1400
604
           svt_aom_scs_set_creator,
1401
604
           NULL,
1402
604
           NULL,
1403
604
           single_thread);
1404
    /************************************
1405
    * Picture Control Set: Parent
1406
    ************************************/
1407
604
    {
1408
        // The segment Width & Height Arrays are in units of SBs, not samples
1409
604
        PictureControlSetInitData input_data;
1410
604
        input_data.picture_width        = scs->max_input_luma_width;
1411
604
        input_data.picture_height       = scs->max_input_luma_height;
1412
604
        input_data.border               = scs->border;
1413
604
        input_data.color_format         = color_format;
1414
604
        input_data.b64_size             = scs->b64_size;
1415
604
        input_data.enc_mode             = scs->static_config.enc_mode;
1416
604
        input_data.hbd_md               = scs->enable_hbd_mode_decision;
1417
604
        input_data.bit_depth            = scs->static_config.encoder_bit_depth;
1418
604
        input_data.log2_tile_rows       = scs->static_config.tile_rows;
1419
604
        input_data.log2_tile_cols       = scs->static_config.tile_columns;
1420
604
        input_data.log2_sb_size         = (scs->super_block_size == 128) ? 5 : 4;
1421
604
        input_data.is_16bit_pipeline    = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1422
604
        input_data.non_m8_pad_w         = scs->max_input_pad_right;
1423
604
        input_data.non_m8_pad_h         = scs->max_input_pad_bottom;
1424
604
        input_data.enable_tpl_la        = scs->tpl;
1425
604
        input_data.enc_dec_segment_col  = (uint16_t)scs->tpl_segment_col_count_array;
1426
604
        input_data.enc_dec_segment_row  = (uint16_t)scs->tpl_segment_row_count_array;
1427
604
        MrpCtrls* mrp_ctrl              = &(scs->mrp_ctrls);
1428
604
        input_data.ref_count_used_list0 = MAX(mrp_ctrl->base_ref_list0_count, mrp_ctrl->non_base_ref_list0_count);
1429
604
        input_data.ref_count_used_list1 = MAX(mrp_ctrl->base_ref_list1_count, mrp_ctrl->non_base_ref_list1_count);
1430
604
        input_data.tpl_synth_size = svt_aom_set_tpl_group(NULL,
1431
604
                                                          svt_aom_get_tpl_group_level(1, scs->static_config.enc_mode),
1432
604
                                                          input_data.picture_width,
1433
604
                                                          input_data.picture_height);
1434
604
        input_data.aq_mode        = scs->static_config.aq_mode;
1435
1436
604
        input_data.calculate_variance = scs->calculate_variance;
1437
604
        input_data.calc_hist = scs->calc_hist = scs->allintra == false &&
1438
0
            (scs->static_config.scene_change_detection || scs->vq_ctrls.sharpness_ctrls.scene_transition ||
1439
0
             scs->tf_params_per_type[0].enabled || scs->tf_params_per_type[1].enabled ||
1440
0
             scs->tf_params_per_type[2].enabled);
1441
604
        input_data.tpl_lad_mg       = scs->tpl_lad_mg;
1442
604
        input_data.input_resolution = scs->input_resolution;
1443
604
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1444
604
            scs->static_config.resize_mode > RESIZE_NONE;
1445
604
        input_data.rtc_tune            = scs->static_config.rtc;
1446
604
        input_data.variance_octile     = scs->static_config.variance_octile;
1447
604
        input_data.adaptive_film_grain = scs->static_config.adaptive_film_grain;
1448
604
        input_data.hbd_mds             = scs->static_config.hbd_mds;
1449
604
        input_data.static_config       = scs->static_config;
1450
604
        input_data.allintra            = scs->allintra;
1451
604
        input_data.use_flat_ipp        = scs->static_config.rtc && scs->static_config.hierarchical_levels == 0;
1452
604
        EB_NEW(enc_handle_ptr->picture_parent_control_set_pool_ptr,
1453
604
               svt_system_resource_ctor,
1454
604
               scs->picture_control_set_pool_init_count, //enc_handle_ptr->pcs_pool_total_count,
1455
604
               1,
1456
604
               0,
1457
604
               svt_aom_picture_parent_control_set_creator,
1458
604
               &input_data,
1459
604
               NULL,
1460
604
               single_thread);
1461
#if SRM_REPORT
1462
        enc_handle_ptr->picture_parent_control_set_pool_ptr->empty_queue->log = 0;
1463
#endif
1464
604
        EB_NEW(enc_handle_ptr->me_pool_ptr,
1465
604
               svt_system_resource_ctor,
1466
604
               scs->me_pool_init_count,
1467
604
               1,
1468
604
               0,
1469
604
               svt_aom_me_creator,
1470
604
               &input_data,
1471
604
               NULL,
1472
604
               single_thread);
1473
#if SRM_REPORT
1474
        enc_handle_ptr->me_pool_ptr->empty_queue->log = 0;
1475
        dump_srm_content(enc_handle_ptr->me_pool_ptr, false);
1476
#endif
1477
604
    }
1478
1479
    /************************************
1480
    * Enc Dec
1481
    ************************************/
1482
604
    {
1483
        // The segment Width & Height Arrays are in units of SBs, not samples
1484
604
        PictureControlSetInitData input_data;
1485
604
        input_data.enc_dec_segment_col = (uint16_t)scs->enc_dec_segment_col_count_array;
1486
604
        input_data.enc_dec_segment_row = (uint16_t)scs->enc_dec_segment_row_count_array;
1487
1488
604
        input_data.picture_width  = scs->max_input_luma_width;
1489
604
        input_data.picture_height = scs->max_input_luma_height;
1490
604
        input_data.border         = scs->border;
1491
604
        input_data.bit_depth      = scs->encoder_bit_depth;
1492
604
        input_data.color_format   = color_format;
1493
604
        input_data.b64_size       = scs->b64_size;
1494
604
        input_data.sb_size        = scs->super_block_size;
1495
604
        input_data.hbd_md         = scs->enable_hbd_mode_decision;
1496
604
        input_data.mfmv           = scs->mfmv_enabled;
1497
        //Jing: Get tile info from parent_pcs
1498
604
        PictureParentControlSet* parent_pcs =
1499
604
            (PictureParentControlSet*)enc_handle_ptr->picture_parent_control_set_pool_ptr->wrapper_ptr_pool[0]
1500
604
                ->object_ptr;
1501
604
        input_data.tile_row_count    = parent_pcs->av1_cm->tiles_info.tile_rows;
1502
604
        input_data.tile_column_count = parent_pcs->av1_cm->tiles_info.tile_cols;
1503
604
        input_data.is_16bit_pipeline = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1504
604
        input_data.av1_cm            = parent_pcs->av1_cm;
1505
604
        input_data.enc_mode          = scs->static_config.enc_mode;
1506
1507
604
        input_data.input_resolution = scs->input_resolution;
1508
604
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1509
604
            scs->static_config.resize_mode > RESIZE_NONE;
1510
1511
604
        input_data.rtc_tune     = scs->static_config.rtc;
1512
604
        input_data.allintra     = scs->allintra;
1513
604
        input_data.use_flat_ipp = scs->static_config.rtc && scs->static_config.hierarchical_levels == 0;
1514
604
        EB_NEW(enc_handle_ptr->enc_dec_pool_ptr,
1515
604
               svt_system_resource_ctor,
1516
604
               scs->enc_dec_pool_init_count, //EB_PictureControlSetPoolInitCountChild,
1517
604
               1,
1518
604
               0,
1519
604
               svt_aom_recon_coef_creator,
1520
604
               &input_data,
1521
604
               NULL,
1522
604
               single_thread);
1523
604
    }
1524
1525
    /************************************
1526
        * Picture Control Set: Child
1527
        ************************************/
1528
604
    {
1529
        // The segment Width & Height Arrays are in units of SBs, not samples
1530
604
        PictureControlSetInitData input_data;
1531
604
        input_data.enc_dec_segment_col = (uint16_t)scs->enc_dec_segment_col_count_array;
1532
604
        input_data.enc_dec_segment_row = (uint16_t)scs->enc_dec_segment_row_count_array;
1533
604
        input_data.picture_width       = scs->max_input_luma_width;
1534
604
        input_data.picture_height      = scs->max_input_luma_height;
1535
604
        input_data.border              = scs->border;
1536
604
        input_data.bit_depth           = scs->encoder_bit_depth;
1537
604
        input_data.color_format        = color_format;
1538
604
        input_data.b64_size            = scs->b64_size;
1539
604
        input_data.sb_size             = scs->super_block_size;
1540
604
        input_data.hbd_md              = scs->enable_hbd_mode_decision;
1541
604
        input_data.mfmv                = scs->mfmv_enabled;
1542
        //Jing: Get tile info from parent_pcs
1543
604
        PictureParentControlSet* parent_pcs =
1544
604
            (PictureParentControlSet*)enc_handle_ptr->picture_parent_control_set_pool_ptr->wrapper_ptr_pool[0]
1545
604
                ->object_ptr;
1546
604
        input_data.tile_row_count    = parent_pcs->av1_cm->tiles_info.tile_rows;
1547
604
        input_data.tile_column_count = parent_pcs->av1_cm->tiles_info.tile_cols;
1548
604
        input_data.is_16bit_pipeline = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1549
604
        input_data.av1_cm            = parent_pcs->av1_cm;
1550
604
        input_data.enc_mode          = scs->static_config.enc_mode;
1551
604
        input_data.static_config     = scs->static_config;
1552
1553
604
        input_data.input_resolution = scs->input_resolution;
1554
604
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1555
604
            scs->static_config.resize_mode > RESIZE_NONE;
1556
1557
604
        input_data.rtc_tune     = scs->static_config.rtc;
1558
604
        input_data.allintra     = scs->allintra;
1559
604
        input_data.use_flat_ipp = scs->static_config.rtc && scs->static_config.hierarchical_levels == 0;
1560
604
        EB_NEW(enc_handle_ptr->picture_control_set_pool_ptr,
1561
604
               svt_system_resource_ctor,
1562
604
               scs->picture_control_set_pool_init_count_child, //EB_PictureControlSetPoolInitCountChild,
1563
604
               1,
1564
604
               0,
1565
604
               svt_aom_picture_control_set_creator,
1566
604
               &input_data,
1567
604
               NULL,
1568
604
               single_thread);
1569
604
    }
1570
1571
    /************************************
1572
    * Picture Buffers
1573
    ************************************/
1574
    // Allocate Resource Arrays. These are per-instance locals (not file-scope
1575
    // globals) so concurrent inits at different presets cannot race on the
1576
    // preset-dependent .count fields (see #2381). Slots are in enum order and
1577
    // terminated by the *_INPUT_PORT_INVALID entry.
1578
    // clang-format off
1579
604
    const PicMgrPorts pic_mgr_ports[] = {
1580
604
        {PIC_MGR_INPUT_PORT_SOP,           scs->source_based_operations_process_init_count},
1581
604
        {PIC_MGR_INPUT_PORT_PACKETIZATION, EB_PacketizationProcessInitCount},
1582
604
        {PIC_MGR_INPUT_PORT_REST,          scs->rest_process_init_count},
1583
604
        {PIC_MGR_INPUT_PORT_INVALID,       0}
1584
604
    };
1585
604
    const RateControlPorts rate_control_ports[] = {
1586
604
        {RATE_CONTROL_INPUT_PORT_INLME,         EB_PictureManagerProcessInitCount},
1587
604
        {RATE_CONTROL_INPUT_PORT_PACKETIZATION, EB_PacketizationProcessInitCount},
1588
604
        {RATE_CONTROL_INPUT_PORT_INVALID,       0}
1589
604
    };
1590
604
    const EncDecPorts_t enc_dec_ports[] = {
1591
604
        {ENCDEC_INPUT_PORT_MDC,     scs->mode_decision_configuration_process_init_count},
1592
604
        {ENCDEC_INPUT_PORT_ENCDEC,  scs->enc_dec_process_init_count},
1593
604
        {ENCDEC_INPUT_PORT_INVALID, 0}
1594
604
    };
1595
604
    const EncDecPorts_t tpl_ports[] = {
1596
604
        {TPL_INPUT_PORT_SOP,     scs->source_based_operations_process_init_count},
1597
604
        {TPL_INPUT_PORT_TPL,     scs->tpl_disp_process_init_count},
1598
604
        {TPL_INPUT_PORT_INVALID, 0}
1599
604
    };
1600
    // clang-format on
1601
604
    {
1602
        // Must always allocate mem b/c don't know if restoration is on or off at this point
1603
        // The restoration assumes only 1 tile is used, so only allocate for 1 tile... see svt_av1_alloc_restoration_struct()
1604
604
        PictureControlSet* pcs =
1605
604
            (PictureControlSet*)enc_handle_ptr->picture_control_set_pool_ptr->wrapper_ptr_pool[0]->object_ptr;
1606
604
        scs->rest_units_per_tile = pcs->rst_info[0 /*Y-plane*/].units_per_tile;
1607
604
        scs->b64_total_count     = pcs->b64_total_count;
1608
604
        create_ref_buf_descs(enc_handle_ptr);
1609
604
        if (scs->tpl) {
1610
0
            create_tpl_ref_buf_descs(enc_handle_ptr);
1611
0
        }
1612
1613
604
        create_pa_ref_buf_descs(enc_handle_ptr);
1614
1615
604
        if (scs->static_config.enable_overlays) {
1616
            // Overlay Input Picture Buffers
1617
0
            EB_NEW(enc_handle_ptr->overlay_input_picture_pool_ptr,
1618
0
                   svt_system_resource_ctor,
1619
0
                   scs->overlay_input_picture_buffer_init_count,
1620
0
                   1,
1621
0
                   0,
1622
0
                   svt_overlay_buffer_header_creator,
1623
0
                   scs,
1624
0
                   svt_input_buffer_header_destroyer,
1625
0
                   single_thread);
1626
            // Set the SequenceControlSet Overlay input Picture Pool Fifo Ptrs
1627
0
            enc_handle_ptr->scs_instance->enc_ctx->overlay_input_picture_pool_fifo_ptr =
1628
0
                svt_system_resource_get_producer_fifo(enc_handle_ptr->overlay_input_picture_pool_ptr, 0);
1629
0
        }
1630
604
    }
1631
    /************************************
1632
    * System Resource Managers & Fifos
1633
    ************************************/
1634
    //SRM to link App to Ress-Coordination via Input commands. an Input Command holds 2 picture buffers: y8bit and rest(uv8b + yuv2b)
1635
604
    EB_NEW(enc_handle_ptr->input_cmd_resource_ptr,
1636
604
           svt_system_resource_ctor,
1637
604
           scs->resource_coordination_fifo_init_count,
1638
604
           1,
1639
604
           EB_ResourceCoordinationProcessInitCount,
1640
604
           svt_input_cmd_creator,
1641
604
           scs,
1642
604
           NULL,
1643
604
           single_thread);
1644
604
    enc_handle_ptr->input_cmd_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1645
604
        enc_handle_ptr->input_cmd_resource_ptr, 0);
1646
1647
    //Picture Buffer SRM to hold (uv8b + yuv2b)
1648
604
    EB_NEW(enc_handle_ptr->input_buffer_resource_ptr,
1649
604
           svt_system_resource_ctor,
1650
604
           scs->input_buffer_fifo_init_count,
1651
604
           1,
1652
604
           0, //1/2 SRM; no consumer FIFO
1653
604
           svt_input_buffer_header_creator,
1654
604
           scs,
1655
604
           svt_input_buffer_header_destroyer,
1656
604
           single_thread);
1657
604
    enc_handle_ptr->input_buffer_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1658
604
        enc_handle_ptr->input_buffer_resource_ptr, 0);
1659
1660
    //Picture Buffer SRM to hold y8b to be shared by Pcs->enhanced and Pa_ref
1661
604
    EB_NEW(enc_handle_ptr->input_y8b_buffer_resource_ptr,
1662
604
           svt_system_resource_ctor,
1663
604
           MAX(scs->input_buffer_fifo_init_count, scs->pa_reference_picture_buffer_init_count),
1664
604
           1,
1665
604
           0, //1/2 SRM; no consumer FIFO
1666
604
           svt_input_y8b_creator,
1667
604
           scs,
1668
604
           svt_input_y8b_destroyer,
1669
604
           single_thread);
1670
1671
#if SRM_REPORT
1672
    enc_handle_ptr->input_y8b_buffer_resource_ptr->empty_queue->log = 1;
1673
#endif
1674
604
    enc_handle_ptr->input_y8b_buffer_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1675
604
        enc_handle_ptr->input_y8b_buffer_resource_ptr, 0);
1676
1677
    // EbBufferHeaderType Output Stream
1678
604
    {
1679
604
        EB_NEW(enc_handle_ptr->output_stream_buffer_resource_ptr,
1680
604
               svt_system_resource_ctor,
1681
604
               scs->output_stream_buffer_fifo_init_count,
1682
604
               scs->total_process_init_count, //EB_PacketizationProcessInitCount,
1683
604
               1,
1684
604
               svt_output_buffer_header_creator,
1685
604
               &scs->static_config,
1686
604
               svt_output_buffer_header_destroyer,
1687
604
               single_thread);
1688
604
    }
1689
604
    enc_handle_ptr->output_stream_buffer_consumer_fifo_ptr = svt_system_resource_get_consumer_fifo(
1690
604
        enc_handle_ptr->output_stream_buffer_resource_ptr, 0);
1691
604
    if (scs->static_config.recon_enabled) {
1692
        // EbBufferHeaderType Output Recon
1693
0
        {
1694
0
            EB_NEW(enc_handle_ptr->output_recon_buffer_resource_ptr,
1695
0
                   svt_system_resource_ctor,
1696
0
                   scs->output_recon_buffer_fifo_init_count,
1697
0
                   scs->enc_dec_process_init_count,
1698
0
                   1,
1699
0
                   svt_output_recon_buffer_header_creator,
1700
0
                   scs,
1701
0
                   svt_output_recon_buffer_header_destroyer,
1702
0
                   single_thread);
1703
0
        }
1704
0
        enc_handle_ptr->output_recon_buffer_consumer_fifo_ptr = svt_system_resource_get_consumer_fifo(
1705
0
            enc_handle_ptr->output_recon_buffer_resource_ptr, 0);
1706
0
    }
1707
1708
    // Resource Coordination Results
1709
604
    {
1710
604
        ResourceCoordinationResultInitData resource_coordination_result_init_data;
1711
604
        EB_NEW(enc_handle_ptr->resource_coordination_results_resource_ptr,
1712
604
               svt_system_resource_ctor,
1713
604
               scs->resource_coordination_fifo_init_count,
1714
604
               EB_ResourceCoordinationProcessInitCount,
1715
604
               scs->picture_analysis_process_init_count,
1716
604
               svt_aom_resource_coordination_result_creator,
1717
604
               &resource_coordination_result_init_data,
1718
604
               NULL,
1719
604
               single_thread);
1720
604
    }
1721
1722
    // Picture Analysis Results
1723
604
    {
1724
604
        PictureAnalysisResultInitData picture_analysis_result_init_data;
1725
604
        EB_NEW(enc_handle_ptr->picture_analysis_results_resource_ptr,
1726
604
               svt_system_resource_ctor,
1727
604
               scs->picture_analysis_fifo_init_count,
1728
604
               scs->picture_analysis_process_init_count,
1729
604
               EB_PictureDecisionProcessInitCount,
1730
604
               svt_aom_picture_analysis_result_creator,
1731
604
               &picture_analysis_result_init_data,
1732
604
               NULL,
1733
604
               single_thread);
1734
604
    }
1735
1736
    // Picture Decision Results
1737
604
    {
1738
604
        PictureDecisionResultInitData picture_decision_result_init_data;
1739
604
        EB_NEW(enc_handle_ptr->picture_decision_results_resource_ptr,
1740
604
               svt_system_resource_ctor,
1741
604
               scs->picture_decision_fifo_init_count,
1742
604
               EB_PictureDecisionProcessInitCount +
1743
604
                   2, // 1 for rate control, another 1 for packetization when superres recoding is on
1744
604
               scs->motion_estimation_process_init_count,
1745
604
               svt_aom_picture_decision_result_creator,
1746
604
               &picture_decision_result_init_data,
1747
604
               NULL,
1748
604
               single_thread);
1749
604
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->picture_decision_reorder_queue,
1750
604
                           scs->enc_ctx->picture_decision_reorder_queue_size);
1751
1752
3.62k
        for (uint32_t picture_index = 0; picture_index < scs->enc_ctx->picture_decision_reorder_queue_size;
1753
3.02k
             ++picture_index) {
1754
3.02k
            EB_NEW(scs->enc_ctx->picture_decision_reorder_queue[picture_index],
1755
3.02k
                   svt_aom_picture_decision_reorder_entry_ctor,
1756
3.02k
                   picture_index);
1757
3.02k
        }
1758
604
    }
1759
1760
    // Motion Estimation Results
1761
604
    {
1762
604
        MotionEstimationResultsInitData motion_estimation_result_init_data;
1763
604
        EB_NEW(enc_handle_ptr->motion_estimation_results_resource_ptr,
1764
604
               svt_system_resource_ctor,
1765
604
               scs->motion_estimation_fifo_init_count,
1766
604
               scs->motion_estimation_process_init_count,
1767
604
               EB_InitialRateControlProcessInitCount,
1768
604
               svt_aom_motion_estimation_results_creator,
1769
604
               &motion_estimation_result_init_data,
1770
604
               NULL,
1771
604
               single_thread);
1772
604
    }
1773
1774
    // Initial Rate Control Results
1775
604
    {
1776
604
        InitialRateControlResultInitData initial_rate_control_result_init_data;
1777
604
        EB_NEW(enc_handle_ptr->initial_rate_control_results_resource_ptr,
1778
604
               svt_system_resource_ctor,
1779
604
               scs->initial_rate_control_fifo_init_count,
1780
604
               EB_InitialRateControlProcessInitCount,
1781
604
               scs->source_based_operations_process_init_count,
1782
604
               svt_aom_initial_rate_control_results_creator,
1783
604
               &initial_rate_control_result_init_data,
1784
604
               NULL,
1785
604
               single_thread);
1786
604
    }
1787
1788
    // Picture Demux Results
1789
604
    {
1790
604
        PictureResultInitData picture_result_init_data;
1791
604
        EB_NEW(enc_handle_ptr->picture_demux_results_resource_ptr,
1792
604
               svt_system_resource_ctor,
1793
604
               scs->picture_demux_fifo_init_count,
1794
604
               pic_mgr_port_total_count(pic_mgr_ports),
1795
604
               EB_PictureManagerProcessInitCount,
1796
604
               svt_aom_picture_results_creator,
1797
604
               &picture_result_init_data,
1798
604
               NULL,
1799
604
               single_thread);
1800
1801
604
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->pic_mgr_input_pic_list, scs->enc_ctx->pic_mgr_input_pic_list_size);
1802
1803
3.02k
        for (uint32_t picture_index = 0; picture_index < scs->enc_ctx->pic_mgr_input_pic_list_size; ++picture_index) {
1804
2.41k
            EB_NEW(scs->enc_ctx->pic_mgr_input_pic_list[picture_index], svt_aom_input_queue_entry_ctor);
1805
2.41k
        }
1806
604
    }
1807
1808
    // TPL dispenser Results
1809
604
    {
1810
604
        EntropyCodingResultsInitData tpl_disp_result_init_data;
1811
        //TPL Dispenser tasks
1812
604
        EB_NEW(enc_handle_ptr->tpl_disp_res_srm,
1813
604
               svt_system_resource_ctor,
1814
604
               scs->tpl_disp_fifo_init_count,
1815
604
               tpl_port_total_count(tpl_ports),
1816
604
               scs->tpl_disp_process_init_count,
1817
604
               tpl_disp_results_creator,
1818
604
               &tpl_disp_result_init_data,
1819
604
               NULL,
1820
604
               single_thread);
1821
604
    }
1822
1823
    // Rate Control Tasks
1824
604
    {
1825
604
        RateControlTasksInitData rate_control_tasks_init_data;
1826
604
        EB_NEW(enc_handle_ptr->rate_control_tasks_resource_ptr,
1827
604
               svt_system_resource_ctor,
1828
604
               scs->rate_control_tasks_fifo_init_count,
1829
604
               rate_control_port_total_count(rate_control_ports),
1830
604
               EB_RateControlProcessInitCount,
1831
604
               svt_aom_rate_control_tasks_creator,
1832
604
               &rate_control_tasks_init_data,
1833
604
               NULL,
1834
604
               single_thread);
1835
604
    }
1836
1837
    // Rate Control Results
1838
604
    {
1839
604
        RateControlResultsInitData rate_control_result_init_data;
1840
604
        EB_NEW(enc_handle_ptr->rate_control_results_resource_ptr,
1841
604
               svt_system_resource_ctor,
1842
604
               scs->rate_control_fifo_init_count,
1843
604
               EB_RateControlProcessInitCount,
1844
604
               scs->mode_decision_configuration_process_init_count,
1845
604
               svt_aom_rate_control_results_creator,
1846
604
               &rate_control_result_init_data,
1847
604
               NULL,
1848
604
               single_thread);
1849
604
    }
1850
    // EncDec Tasks
1851
604
    {
1852
604
        EncDecTasksInitData mode_decision_result_init_data;
1853
604
        mode_decision_result_init_data.enc_dec_segment_row_count = scs->enc_dec_segment_row_count_array;
1854
604
        EB_NEW(enc_handle_ptr->enc_dec_tasks_resource_ptr,
1855
604
               svt_system_resource_ctor,
1856
604
               scs->mode_decision_configuration_fifo_init_count,
1857
604
               enc_dec_port_total_count(enc_dec_ports),
1858
604
               scs->enc_dec_process_init_count,
1859
604
               svt_aom_enc_dec_tasks_creator,
1860
604
               &mode_decision_result_init_data,
1861
604
               NULL,
1862
604
               single_thread);
1863
604
    }
1864
1865
    // EncDec Results
1866
604
    {
1867
604
        EncDecResultsInitData enc_dec_result_init_data;
1868
604
        EB_NEW(enc_handle_ptr->enc_dec_results_resource_ptr,
1869
604
               svt_system_resource_ctor,
1870
604
               scs->enc_dec_fifo_init_count,
1871
604
               scs->enc_dec_process_init_count,
1872
604
               scs->dlf_process_init_count,
1873
604
               svt_aom_enc_dec_results_creator,
1874
604
               &enc_dec_result_init_data,
1875
604
               NULL,
1876
604
               single_thread);
1877
604
    }
1878
1879
    //DLF results
1880
604
    {
1881
604
        EntropyCodingResultsInitData delf_result_init_data;
1882
604
        EB_NEW(enc_handle_ptr->dlf_results_resource_ptr,
1883
604
               svt_system_resource_ctor,
1884
604
               scs->dlf_fifo_init_count,
1885
604
               scs->dlf_process_init_count,
1886
604
               scs->cdef_process_init_count,
1887
604
               dlf_results_creator,
1888
604
               &delf_result_init_data,
1889
604
               NULL,
1890
604
               single_thread);
1891
604
    }
1892
    //CDEF results
1893
604
    {
1894
604
        EntropyCodingResultsInitData cdef_result_init_data;
1895
604
        EB_NEW(enc_handle_ptr->cdef_results_resource_ptr,
1896
604
               svt_system_resource_ctor,
1897
604
               scs->cdef_fifo_init_count,
1898
604
               scs->cdef_process_init_count,
1899
604
               scs->rest_process_init_count,
1900
604
               cdef_results_creator,
1901
604
               &cdef_result_init_data,
1902
604
               NULL,
1903
604
               single_thread);
1904
604
    }
1905
    //REST results
1906
604
    {
1907
604
        EntropyCodingResultsInitData rest_result_init_data;
1908
604
        EB_NEW(enc_handle_ptr->rest_results_resource_ptr,
1909
604
               svt_system_resource_ctor,
1910
604
               scs->rest_fifo_init_count,
1911
604
               scs->rest_process_init_count,
1912
604
               scs->entropy_coding_process_init_count,
1913
604
               rest_results_creator,
1914
604
               &rest_result_init_data,
1915
604
               NULL,
1916
604
               single_thread);
1917
604
    }
1918
1919
    // Entropy Coding Results
1920
604
    {
1921
604
        EntropyCodingResultsInitData entropy_coding_results_init_data;
1922
604
        EB_NEW(enc_handle_ptr->entropy_coding_results_resource_ptr,
1923
604
               svt_system_resource_ctor,
1924
604
               scs->entropy_coding_fifo_init_count,
1925
604
               scs->entropy_coding_process_init_count,
1926
604
               EB_PacketizationProcessInitCount,
1927
604
               svt_aom_entropy_coding_results_creator,
1928
604
               &entropy_coding_results_init_data,
1929
604
               NULL,
1930
604
               single_thread);
1931
604
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->packetization_reorder_queue, scs->enc_ctx->packetization_reorder_queue_size);
1932
1933
3.02k
        for (uint32_t picture_index = 0; picture_index < scs->enc_ctx->packetization_reorder_queue_size;
1934
2.41k
             ++picture_index) {
1935
2.41k
            EB_NEW(scs->enc_ctx->packetization_reorder_queue[picture_index],
1936
2.41k
                   svt_aom_packetization_reorder_entry_ctor,
1937
2.41k
                   picture_index);
1938
2.41k
        }
1939
604
    }
1940
1941
    /************************************
1942
    * App Callbacks
1943
    ************************************/
1944
604
    enc_handle_ptr->scs_instance->enc_ctx->app_callback_ptr = enc_handle_ptr->app_callback_ptr;
1945
    // svt Output Buffer Fifo Ptrs
1946
604
    enc_handle_ptr->scs_instance->enc_ctx->stream_output_fifo_ptr = svt_system_resource_get_producer_fifo(
1947
604
        enc_handle_ptr->output_stream_buffer_resource_ptr, 0);
1948
604
    if (enc_handle_ptr->scs_instance->scs->static_config.recon_enabled) {
1949
0
        enc_handle_ptr->scs_instance->enc_ctx->recon_output_fifo_ptr = svt_system_resource_get_producer_fifo(
1950
0
            enc_handle_ptr->output_recon_buffer_resource_ptr, 0);
1951
0
    }
1952
1953
    /************************************
1954
    * Contexts
1955
    ************************************/
1956
    // Resource Coordination Context
1957
604
    EB_NEW(
1958
604
        enc_handle_ptr->resource_coordination_context_ptr, svt_aom_resource_coordination_context_ctor, enc_handle_ptr);
1959
1960
    // Picture Analysis Context
1961
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->picture_analysis_context_ptr_array, scs->picture_analysis_process_init_count);
1962
3.02k
    for (uint32_t process_index = 0; process_index < scs->picture_analysis_process_init_count; process_index++) {
1963
2.41k
        EB_NEW(enc_handle_ptr->picture_analysis_context_ptr_array[process_index],
1964
2.41k
               svt_aom_picture_analysis_context_ctor,
1965
2.41k
               enc_handle_ptr,
1966
2.41k
               process_index);
1967
2.41k
    }
1968
1969
    // Picture Decision Context
1970
604
    EB_NEW(enc_handle_ptr->picture_decision_context_ptr,
1971
604
           svt_aom_picture_decision_context_ctor,
1972
604
           enc_handle_ptr,
1973
604
           scs->calc_hist);
1974
1975
    // Motion Analysis Context
1976
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->motion_estimation_context_ptr_array, scs->motion_estimation_process_init_count);
1977
4.22k
    for (uint32_t process_index = 0; process_index < scs->motion_estimation_process_init_count; process_index++) {
1978
3.62k
        EB_NEW(enc_handle_ptr->motion_estimation_context_ptr_array[process_index],
1979
3.62k
               svt_aom_motion_estimation_context_ctor,
1980
3.62k
               enc_handle_ptr,
1981
3.62k
               process_index);
1982
3.62k
    }
1983
1984
    // Initial Rate Control Context
1985
604
    EB_NEW(enc_handle_ptr->initial_rate_control_context_ptr,
1986
604
           svt_aom_initial_rate_control_context_ctor,
1987
604
           enc_handle_ptr,
1988
604
           scs->picture_control_set_pool_init_count);
1989
1990
    // Source Based Operations Context
1991
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->source_based_operations_context_ptr_array,
1992
604
                       scs->source_based_operations_process_init_count);
1993
1.20k
    for (uint32_t process_index = 0; process_index < scs->source_based_operations_process_init_count; process_index++) {
1994
604
        EB_NEW(enc_handle_ptr->source_based_operations_context_ptr_array[process_index],
1995
604
               svt_aom_source_based_operations_context_ctor,
1996
604
               enc_handle_ptr,
1997
604
               tpl_port_lookup(tpl_ports, TPL_INPUT_PORT_SOP, process_index),
1998
604
               pic_mgr_port_lookup(pic_mgr_ports, PIC_MGR_INPUT_PORT_SOP, process_index));
1999
604
    }
2000
2001
    // TPL dispenser
2002
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->tpl_disp_context_ptr_array, scs->tpl_disp_process_init_count);
2003
1.20k
    for (uint32_t process_index = 0; process_index < scs->tpl_disp_process_init_count; process_index++) {
2004
604
        EB_NEW(enc_handle_ptr->tpl_disp_context_ptr_array[process_index],
2005
604
               svt_aom_tpl_disp_context_ctor,
2006
604
               enc_handle_ptr,
2007
604
               process_index,
2008
604
               tpl_port_lookup(tpl_ports, TPL_INPUT_PORT_TPL, process_index));
2009
604
    }
2010
2011
    // Picture Manager Context
2012
604
    EB_NEW(enc_handle_ptr->picture_manager_context_ptr,
2013
604
           svt_aom_picture_manager_context_ctor,
2014
604
           enc_handle_ptr,
2015
604
           rate_control_port_lookup(rate_control_ports, RATE_CONTROL_INPUT_PORT_INLME, 0), //Pic-Mgr uses the first Port
2016
604
           scs->picture_control_set_pool_init_count);
2017
2018
    // Rate Control Context
2019
604
    EB_NEW(enc_handle_ptr->rate_control_context_ptr,
2020
604
           svt_aom_rate_control_context_ctor,
2021
604
           enc_handle_ptr,
2022
604
           EB_PictureDecisionProcessInitCount); // me_port_index
2023
2024
    // Mode Decision Configuration Contexts
2025
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->mode_decision_configuration_context_ptr_array,
2026
604
                       scs->mode_decision_configuration_process_init_count);
2027
1.20k
    for (uint32_t process_index = 0; process_index < scs->mode_decision_configuration_process_init_count;
2028
604
         process_index++) {
2029
604
        EB_NEW(enc_handle_ptr->mode_decision_configuration_context_ptr_array[process_index],
2030
604
               svt_aom_mode_decision_configuration_context_ctor,
2031
604
               enc_handle_ptr,
2032
604
               process_index,
2033
604
               enc_dec_port_lookup(enc_dec_ports, ENCDEC_INPUT_PORT_MDC, process_index));
2034
604
    }
2035
2036
    // EncDec Contexts
2037
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->enc_dec_context_ptr_array, scs->enc_dec_process_init_count);
2038
2.43k
    for (uint32_t process_index = 0; process_index < scs->enc_dec_process_init_count; process_index++) {
2039
1.82k
        EB_NEW(enc_handle_ptr->enc_dec_context_ptr_array[process_index],
2040
1.82k
               svt_aom_enc_dec_context_ctor,
2041
1.82k
               enc_handle_ptr,
2042
1.82k
               process_index,
2043
1.82k
               enc_dec_port_lookup(enc_dec_ports, ENCDEC_INPUT_PORT_ENCDEC, process_index));
2044
1.82k
    }
2045
2046
    // Dlf Contexts
2047
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->dlf_context_ptr_array, scs->dlf_process_init_count);
2048
1.20k
    for (uint32_t process_index = 0; process_index < scs->dlf_process_init_count; process_index++) {
2049
604
        EB_NEW(enc_handle_ptr->dlf_context_ptr_array[process_index],
2050
604
               svt_aom_dlf_context_ctor,
2051
604
               enc_handle_ptr,
2052
604
               process_index);
2053
604
    }
2054
2055
    //CDEF Contexts
2056
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->cdef_context_ptr_array, scs->cdef_process_init_count);
2057
1.20k
    for (uint32_t process_index = 0; process_index < scs->cdef_process_init_count; process_index++) {
2058
604
        EB_NEW(enc_handle_ptr->cdef_context_ptr_array[process_index],
2059
604
               svt_aom_cdef_context_ctor,
2060
604
               enc_handle_ptr,
2061
604
               process_index);
2062
604
    }
2063
2064
    //Rest Contexts
2065
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->rest_context_ptr_array, scs->rest_process_init_count);
2066
1.20k
    for (uint32_t process_index = 0; process_index < scs->rest_process_init_count; process_index++) {
2067
604
        EB_NEW(enc_handle_ptr->rest_context_ptr_array[process_index],
2068
604
               svt_aom_rest_context_ctor,
2069
604
               enc_handle_ptr,
2070
604
               process_index,
2071
604
               pic_mgr_port_lookup(pic_mgr_ports, PIC_MGR_INPUT_PORT_REST, process_index));
2072
604
    }
2073
2074
    // Entropy Coding Contexts
2075
604
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->entropy_coding_context_ptr_array, scs->entropy_coding_process_init_count);
2076
1.20k
    for (uint32_t process_index = 0; process_index < scs->entropy_coding_process_init_count; process_index++) {
2077
604
        EB_NEW(enc_handle_ptr->entropy_coding_context_ptr_array[process_index],
2078
604
               svt_aom_entropy_coding_context_ctor,
2079
604
               enc_handle_ptr,
2080
604
               process_index);
2081
604
    }
2082
2083
    // Packetization Context
2084
604
    EB_NEW(enc_handle_ptr->packetization_context_ptr,
2085
604
           svt_aom_packetization_context_ctor,
2086
604
           enc_handle_ptr,
2087
604
           rate_control_port_lookup(rate_control_ports, RATE_CONTROL_INPUT_PORT_PACKETIZATION, 0),
2088
604
           pic_mgr_port_lookup(pic_mgr_ports, PIC_MGR_INPUT_PORT_PACKETIZATION, 0),
2089
604
           EB_PictureDecisionProcessInitCount + EB_RateControlProcessInitCount); // me_port_index
2090
2091
    /************************************
2092
    * Thread Handles
2093
    ************************************/
2094
604
#if CONFIG_SINGLE_THREAD_KERNEL
2095
    // Single-thread kernel dispatch: at lp=1, register all kernels for
2096
    // cooperative dispatch instead of creating 16 OS threads.
2097
604
    svt_kernel_dispatcher_init(&enc_handle_ptr->kernel_dispatcher);
2098
604
    if (scs->lp == 1) {
2099
0
        enc_handle_ptr->kernel_dispatcher.active = true;
2100
2101
        // Enable non-blocking FIFO mode on all system resources
2102
0
#define SRM_SET_ST(member) \
2103
0
    svt_system_resource_set_single_thread_mode(enc_handle_ptr->member, &enc_handle_ptr->kernel_dispatcher)
2104
0
        SRM_SET_ST(scs_pool_ptr);
2105
0
        SRM_SET_ST(picture_parent_control_set_pool_ptr);
2106
0
        SRM_SET_ST(me_pool_ptr);
2107
0
        SRM_SET_ST(picture_control_set_pool_ptr);
2108
0
        SRM_SET_ST(enc_dec_pool_ptr);
2109
0
        SRM_SET_ST(reference_picture_pool_ptr);
2110
0
        SRM_SET_ST(tpl_reference_picture_pool_ptr);
2111
0
        SRM_SET_ST(pa_reference_picture_pool_ptr);
2112
0
        SRM_SET_ST(overlay_input_picture_pool_ptr);
2113
0
        SRM_SET_ST(input_buffer_resource_ptr);
2114
0
        SRM_SET_ST(input_y8b_buffer_resource_ptr);
2115
0
        SRM_SET_ST(input_cmd_resource_ptr);
2116
0
        SRM_SET_ST(output_stream_buffer_resource_ptr);
2117
0
        if (enc_handle_ptr->output_recon_buffer_resource_ptr) {
2118
0
            SRM_SET_ST(output_recon_buffer_resource_ptr);
2119
0
        }
2120
0
        SRM_SET_ST(resource_coordination_results_resource_ptr);
2121
0
        SRM_SET_ST(picture_analysis_results_resource_ptr);
2122
0
        SRM_SET_ST(picture_decision_results_resource_ptr);
2123
0
        SRM_SET_ST(motion_estimation_results_resource_ptr);
2124
0
        SRM_SET_ST(initial_rate_control_results_resource_ptr);
2125
0
        SRM_SET_ST(picture_demux_results_resource_ptr);
2126
0
        SRM_SET_ST(tpl_disp_res_srm);
2127
0
        SRM_SET_ST(rate_control_tasks_resource_ptr);
2128
0
        SRM_SET_ST(rate_control_results_resource_ptr);
2129
0
        SRM_SET_ST(enc_dec_tasks_resource_ptr);
2130
0
        SRM_SET_ST(enc_dec_results_resource_ptr);
2131
0
        SRM_SET_ST(entropy_coding_results_resource_ptr);
2132
0
        SRM_SET_ST(dlf_results_resource_ptr);
2133
0
        SRM_SET_ST(cdef_results_resource_ptr);
2134
0
        SRM_SET_ST(rest_results_resource_ptr);
2135
0
#undef SRM_SET_ST
2136
2137
        // Register all 16 pipeline kernels in stage order
2138
0
        SvtKernelDispatcher* d = &enc_handle_ptr->kernel_dispatcher;
2139
0
#define CONSUMER_FIFO(res) svt_system_resource_get_consumer_fifo(enc_handle_ptr->res, 0)
2140
2141
0
        svt_kernel_dispatcher_register(d,
2142
0
                                       svt_aom_resource_coordination_kernel_iter,
2143
0
                                       enc_handle_ptr->resource_coordination_context_ptr->priv,
2144
0
                                       CONSUMER_FIFO(input_cmd_resource_ptr),
2145
0
                                       "ResCoord");
2146
0
        svt_kernel_dispatcher_register(d,
2147
0
                                       svt_aom_picture_analysis_kernel_iter,
2148
0
                                       enc_handle_ptr->picture_analysis_context_ptr_array[0]->priv,
2149
0
                                       CONSUMER_FIFO(resource_coordination_results_resource_ptr),
2150
0
                                       "PicAnalysis");
2151
0
        svt_kernel_dispatcher_register(d,
2152
0
                                       svt_aom_picture_decision_kernel_iter,
2153
0
                                       enc_handle_ptr->picture_decision_context_ptr->priv,
2154
0
                                       CONSUMER_FIFO(picture_analysis_results_resource_ptr),
2155
0
                                       "PicDecision");
2156
0
        svt_kernel_dispatcher_register(d,
2157
0
                                       svt_aom_motion_estimation_kernel_iter,
2158
0
                                       enc_handle_ptr->motion_estimation_context_ptr_array[0]->priv,
2159
0
                                       CONSUMER_FIFO(picture_decision_results_resource_ptr),
2160
0
                                       "ME");
2161
0
        svt_kernel_dispatcher_register(d,
2162
0
                                       svt_aom_initial_rate_control_kernel_iter,
2163
0
                                       enc_handle_ptr->initial_rate_control_context_ptr->priv,
2164
0
                                       CONSUMER_FIFO(motion_estimation_results_resource_ptr),
2165
0
                                       "InitRC");
2166
0
        svt_kernel_dispatcher_register(d,
2167
0
                                       svt_aom_source_based_operations_kernel_iter,
2168
0
                                       enc_handle_ptr->source_based_operations_context_ptr_array[0]->priv,
2169
0
                                       CONSUMER_FIFO(initial_rate_control_results_resource_ptr),
2170
0
                                       "SrcOps");
2171
0
        svt_kernel_dispatcher_register(d,
2172
0
                                       svt_aom_tpl_disp_kernel_iter,
2173
0
                                       enc_handle_ptr->tpl_disp_context_ptr_array[0]->priv,
2174
0
                                       CONSUMER_FIFO(tpl_disp_res_srm),
2175
0
                                       "TPL");
2176
0
        svt_kernel_dispatcher_register(d,
2177
0
                                       svt_aom_picture_manager_kernel_iter,
2178
0
                                       enc_handle_ptr->picture_manager_context_ptr->priv,
2179
0
                                       CONSUMER_FIFO(picture_demux_results_resource_ptr),
2180
0
                                       "PicMgr");
2181
0
        svt_kernel_dispatcher_register(d,
2182
0
                                       svt_aom_rate_control_kernel_iter,
2183
0
                                       enc_handle_ptr->rate_control_context_ptr->priv,
2184
0
                                       CONSUMER_FIFO(rate_control_tasks_resource_ptr),
2185
0
                                       "RC");
2186
0
        svt_kernel_dispatcher_register(d,
2187
0
                                       svt_aom_mode_decision_configuration_kernel_iter,
2188
0
                                       enc_handle_ptr->mode_decision_configuration_context_ptr_array[0]->priv,
2189
0
                                       CONSUMER_FIFO(rate_control_results_resource_ptr),
2190
0
                                       "MDConfig");
2191
0
        svt_kernel_dispatcher_register(d,
2192
0
                                       svt_aom_mode_decision_kernel_iter,
2193
0
                                       enc_handle_ptr->enc_dec_context_ptr_array[0]->priv,
2194
0
                                       CONSUMER_FIFO(enc_dec_tasks_resource_ptr),
2195
0
                                       "EncDec");
2196
0
        svt_kernel_dispatcher_register(d,
2197
0
                                       svt_aom_dlf_kernel_iter,
2198
0
                                       enc_handle_ptr->dlf_context_ptr_array[0]->priv,
2199
0
                                       CONSUMER_FIFO(enc_dec_results_resource_ptr),
2200
0
                                       "DLF");
2201
0
        svt_kernel_dispatcher_register(d,
2202
0
                                       svt_aom_cdef_kernel_iter,
2203
0
                                       enc_handle_ptr->cdef_context_ptr_array[0]->priv,
2204
0
                                       CONSUMER_FIFO(dlf_results_resource_ptr),
2205
0
                                       "CDEF");
2206
0
        svt_kernel_dispatcher_register(d,
2207
0
                                       svt_aom_rest_kernel_iter,
2208
0
                                       enc_handle_ptr->rest_context_ptr_array[0]->priv,
2209
0
                                       CONSUMER_FIFO(cdef_results_resource_ptr),
2210
0
                                       "Rest");
2211
0
        svt_kernel_dispatcher_register(d,
2212
0
                                       svt_aom_entropy_coding_kernel_iter,
2213
0
                                       enc_handle_ptr->entropy_coding_context_ptr_array[0]->priv,
2214
0
                                       CONSUMER_FIFO(rest_results_resource_ptr),
2215
0
                                       "EC");
2216
0
        svt_kernel_dispatcher_register(d,
2217
0
                                       svt_aom_packetization_kernel_iter,
2218
0
                                       enc_handle_ptr->packetization_context_ptr->priv,
2219
0
                                       CONSUMER_FIFO(entropy_coding_results_resource_ptr),
2220
0
                                       "Pack");
2221
2222
0
#undef CONSUMER_FIFO
2223
2224
        // Store ME context for inline TF/MCTF processing in PD
2225
0
        scs->enc_ctx->st_me_context = enc_handle_ptr->motion_estimation_context_ptr_array[0]->priv;
2226
0
    } else
2227
604
#endif
2228
604
    {
2229
604
        EB_CREATE_THREAD(enc_handle_ptr->resource_coordination_thread_handle,
2230
604
                         svt_aom_resource_coordination_kernel,
2231
604
                         enc_handle_ptr->resource_coordination_context_ptr);
2232
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->picture_analysis_thread_handle_array,
2233
604
                               scs->picture_analysis_process_init_count,
2234
604
                               svt_aom_picture_analysis_kernel,
2235
604
                               enc_handle_ptr->picture_analysis_context_ptr_array,
2236
604
                               "svt-picana");
2237
2238
        // Picture Decision
2239
604
        EB_CREATE_THREAD(enc_handle_ptr->picture_decision_thread_handle,
2240
604
                         svt_aom_picture_decision_kernel,
2241
604
                         enc_handle_ptr->picture_decision_context_ptr);
2242
2243
        // Motion Estimation
2244
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->motion_estimation_thread_handle_array,
2245
604
                               scs->motion_estimation_process_init_count,
2246
604
                               svt_aom_motion_estimation_kernel,
2247
604
                               enc_handle_ptr->motion_estimation_context_ptr_array,
2248
604
                               "svt-me");
2249
2250
        // Initial Rate Control
2251
604
        EB_CREATE_THREAD(enc_handle_ptr->initial_rate_control_thread_handle,
2252
604
                         svt_aom_initial_rate_control_kernel,
2253
604
                         enc_handle_ptr->initial_rate_control_context_ptr);
2254
2255
        // Source Based Oprations
2256
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->source_based_operations_thread_handle_array,
2257
604
                               scs->source_based_operations_process_init_count,
2258
604
                               svt_aom_source_based_operations_kernel,
2259
604
                               enc_handle_ptr->source_based_operations_context_ptr_array,
2260
604
                               "svt-srcops");
2261
2262
        // TPL dispenser
2263
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->tpl_disp_thread_handle_array,
2264
604
                               scs->tpl_disp_process_init_count,
2265
604
                               svt_aom_tpl_disp_kernel, //TODOOMK
2266
604
                               enc_handle_ptr->tpl_disp_context_ptr_array,
2267
604
                               "svt-tpl");
2268
        // Picture Manager
2269
604
        EB_CREATE_THREAD(enc_handle_ptr->picture_manager_thread_handle,
2270
604
                         svt_aom_picture_manager_kernel,
2271
604
                         enc_handle_ptr->picture_manager_context_ptr);
2272
        // Rate Control
2273
604
        EB_CREATE_THREAD(enc_handle_ptr->rate_control_thread_handle,
2274
604
                         svt_aom_rate_control_kernel,
2275
604
                         enc_handle_ptr->rate_control_context_ptr);
2276
2277
        // Mode Decision Configuration Process
2278
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->mode_decision_configuration_thread_handle_array,
2279
604
                               scs->mode_decision_configuration_process_init_count,
2280
604
                               svt_aom_mode_decision_configuration_kernel,
2281
604
                               enc_handle_ptr->mode_decision_configuration_context_ptr_array,
2282
604
                               "svt-mdcfg");
2283
2284
        // EncDec Process
2285
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->enc_dec_thread_handle_array,
2286
604
                               scs->enc_dec_process_init_count,
2287
604
                               svt_aom_mode_decision_kernel,
2288
604
                               enc_handle_ptr->enc_dec_context_ptr_array,
2289
604
                               "svt-md");
2290
2291
        // Dlf Process
2292
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->dlf_thread_handle_array,
2293
604
                               scs->dlf_process_init_count,
2294
604
                               svt_aom_dlf_kernel,
2295
604
                               enc_handle_ptr->dlf_context_ptr_array,
2296
604
                               "svt-dlf");
2297
2298
        // Cdef Process
2299
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->cdef_thread_handle_array,
2300
604
                               scs->cdef_process_init_count,
2301
604
                               svt_aom_cdef_kernel,
2302
604
                               enc_handle_ptr->cdef_context_ptr_array,
2303
604
                               "svt-cdef");
2304
2305
        // Rest Process
2306
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->rest_thread_handle_array,
2307
604
                               scs->rest_process_init_count,
2308
604
                               svt_aom_rest_kernel,
2309
604
                               enc_handle_ptr->rest_context_ptr_array,
2310
604
                               "svt-rest");
2311
2312
        // Entropy Coding Process
2313
604
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->entropy_coding_thread_handle_array,
2314
604
                               scs->entropy_coding_process_init_count,
2315
604
                               svt_aom_entropy_coding_kernel,
2316
604
                               enc_handle_ptr->entropy_coding_context_ptr_array,
2317
604
                               "svt-ec");
2318
        // Packetization
2319
604
        EB_CREATE_THREAD(enc_handle_ptr->packetization_thread_handle,
2320
604
                         svt_aom_packetization_kernel,
2321
604
                         enc_handle_ptr->packetization_context_ptr);
2322
604
    } // end of thread creation block
2323
2324
604
    svt_print_memory_usage();
2325
2326
604
    return return_error;
2327
604
}
2328
2329
604
static EbErrorType enc_drain_queue(EbComponentType* svt_enc_component) {
2330
604
    bool eos = false;
2331
604
    do {
2332
604
        EbBufferHeaderType* receive_buffer = NULL;
2333
604
        EbErrorType         return_error;
2334
604
        switch ((return_error = svt_av1_enc_get_packet(svt_enc_component, &receive_buffer, 1))) {
2335
0
        case EB_ErrorMax:
2336
0
            return EB_ErrorMax;
2337
604
        case EB_NoErrorEmptyQueue:
2338
604
            eos = true;
2339
604
            break;
2340
0
        default:
2341
0
            break;
2342
604
        }
2343
604
        if (receive_buffer) {
2344
0
            eos = receive_buffer->flags & EB_BUFFERFLAG_EOS;
2345
0
            svt_av1_enc_release_out_buffer(&receive_buffer);
2346
0
            receive_buffer = NULL;
2347
0
        }
2348
604
    } while (!eos);
2349
604
    return EB_ErrorNone;
2350
604
}
2351
2352
/**********************************
2353
* DeInitialize Encoder Library
2354
**********************************/
2355
604
EB_API EbErrorType svt_av1_enc_deinit(EbComponentType* svt_enc_component) {
2356
604
    if (!svt_enc_component || !svt_enc_component->p_component_private) {
2357
0
        return EB_ErrorBadParameter;
2358
0
    }
2359
2360
604
    EbEncHandle* handle = svt_enc_component->p_component_private;
2361
2362
604
    if (handle->input_y8b_buffer_producer_fifo_ptr && handle->frame_received) {
2363
604
        if (!handle->eos_received) {
2364
0
            SVT_ERROR("deinit called without sending EOS!\n");
2365
0
            svt_av1_enc_send_picture(svt_enc_component, &(EbBufferHeaderType){.flags = EB_BUFFERFLAG_EOS});
2366
0
        }
2367
2368
        // If EOS never made it into the pipeline (pipeline buffers exhausted),
2369
        // no EOS packet will ever be produced and draining would pop from an
2370
        // empty output queue.
2371
604
        if (handle->eos_received) {
2372
604
            EbErrorType return_error = enc_drain_queue(svt_enc_component);
2373
604
            if (return_error != EB_ErrorNone) {
2374
0
                return return_error;
2375
0
            }
2376
604
        }
2377
604
    }
2378
2379
    // Free per-instance block geometry table
2380
604
    if (handle->scs_instance && handle->scs_instance->scs && handle->scs_instance->scs->blk_geom_mds != NULL) {
2381
604
        EB_FREE_ARRAY(handle->scs_instance->scs->blk_geom_mds);
2382
604
    }
2383
2384
604
    svt_shutdown_process(handle->input_buffer_resource_ptr);
2385
604
    svt_shutdown_process(handle->input_cmd_resource_ptr);
2386
604
    svt_shutdown_process(handle->resource_coordination_results_resource_ptr);
2387
604
    svt_shutdown_process(handle->picture_analysis_results_resource_ptr);
2388
604
    svt_shutdown_process(handle->picture_decision_results_resource_ptr);
2389
604
    svt_shutdown_process(handle->motion_estimation_results_resource_ptr);
2390
604
    svt_shutdown_process(handle->initial_rate_control_results_resource_ptr);
2391
604
    svt_shutdown_process(handle->picture_demux_results_resource_ptr);
2392
604
    svt_shutdown_process(handle->tpl_disp_res_srm);
2393
604
    svt_shutdown_process(handle->rate_control_tasks_resource_ptr);
2394
604
    svt_shutdown_process(handle->rate_control_results_resource_ptr);
2395
604
    svt_shutdown_process(handle->enc_dec_tasks_resource_ptr);
2396
604
    svt_shutdown_process(handle->enc_dec_results_resource_ptr);
2397
604
    svt_shutdown_process(handle->entropy_coding_results_resource_ptr);
2398
604
    svt_shutdown_process(handle->dlf_results_resource_ptr);
2399
604
    svt_shutdown_process(handle->cdef_results_resource_ptr);
2400
604
    svt_shutdown_process(handle->rest_results_resource_ptr);
2401
2402
604
    return EB_ErrorNone;
2403
604
}
2404
2405
static EbErrorType init_svt_av1_encoder_handle(EbComponentType* hComponent);
2406
2407
/**********************************
2408
* GetHandle
2409
**********************************/
2410
EB_API EbErrorType svt_av1_enc_init_handle(
2411
    EbComponentType**         p_handle, // Function to be called in the future for manipulating the component
2412
    EbSvtAv1EncConfiguration* config_ptr) // pointer passed back to the client during callbacks
2413
2414
604
{
2415
604
    if (p_handle == NULL) {
2416
0
        return EB_ErrorBadParameter;
2417
0
    }
2418
2419
604
    EB_MALLOC_OBJECT(*p_handle);
2420
    // Init Component OS objects (threads, semaphores, etc.)
2421
    // also links the various Component control functions
2422
604
    EbErrorType return_error = init_svt_av1_encoder_handle(*p_handle);
2423
2424
604
    if (return_error == EB_ErrorNone) {
2425
604
        return_error = svt_av1_set_default_params(config_ptr);
2426
604
    }
2427
604
    if (return_error != EB_ErrorNone) {
2428
0
        svt_av1_enc_deinit(*p_handle);
2429
0
        EB_FREE(*p_handle);
2430
0
        *p_handle = NULL;
2431
0
        return return_error;
2432
0
    }
2433
604
    svt_increase_component_count();
2434
604
    return return_error;
2435
604
}
2436
2437
/**********************************
2438
* Encoder Componenet DeInit
2439
**********************************/
2440
604
EbErrorType svt_av1_enc_component_de_init(EbComponentType* svt_enc_component) {
2441
604
    EbErrorType return_error = EB_ErrorNone;
2442
2443
604
    if (svt_enc_component->p_component_private) {
2444
604
        EbEncHandle* handle = (EbEncHandle*)svt_enc_component->p_component_private;
2445
604
        EB_DELETE(handle);
2446
604
        svt_enc_component->p_component_private = NULL;
2447
604
    } else {
2448
0
        return_error = EB_ErrorUndefined;
2449
0
    }
2450
604
    return return_error;
2451
604
}
2452
2453
/**********************************
2454
* svt_av1_enc_deinit_handle
2455
**********************************/
2456
604
EB_API EbErrorType svt_av1_enc_deinit_handle(EbComponentType* svt_enc_component) {
2457
604
    if (svt_enc_component) {
2458
604
        EbErrorType return_error = svt_av1_enc_component_de_init(svt_enc_component);
2459
2460
604
        EB_FREE(svt_enc_component);
2461
604
        svt_decrease_component_count();
2462
604
        return return_error;
2463
604
    }
2464
0
    return EB_ErrorInvalidComponent;
2465
604
}
2466
2467
// Sets the default intra period the closest possible to 1 second without breaking the minigop
2468
0
static int32_t compute_default_intra_period(SequenceControlSet* scs) {
2469
0
    EbSvtAv1EncConfiguration* config = &scs->static_config;
2470
2471
0
    double  fps           = scs->frame_rate;
2472
0
    int32_t mini_gop_size = (1 << (config->hierarchical_levels));
2473
2474
    // use a 5-sec gop by default.
2475
0
    int32_t intra_period = (int)((fps + mini_gop_size) / mini_gop_size) * mini_gop_size * 5;
2476
0
    if (config->intra_refresh_type == 1) {
2477
0
        intra_period -= 1;
2478
0
    }
2479
2480
0
    return intra_period;
2481
0
}
2482
2483
/*
2484
Calculates the default LAD value
2485
*/
2486
604
static uint32_t compute_default_look_ahead(EbSvtAv1EncConfiguration* config) {
2487
604
    int32_t  lad;
2488
604
    uint32_t mg_size = 1 << config->hierarchical_levels;
2489
2490
    /*To accomodate FFMPEG EOS, 1 frame delay is needed in Resource coordination.
2491
       note that we have the option to not add 1 frame delay of Resource Coordination. In this case we have wait for first I frame
2492
       to be released back to be able to start first base(16). Anyway poc16 needs to wait for poc0 to finish.*/
2493
604
    uint32_t eos_delay    = 1;
2494
604
    uint32_t max_tf_delay = 6;
2495
2496
604
    if (config->rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
2497
604
        lad = (1 + mg_size) * (1 + MIN_LAD_MG) + max_tf_delay + eos_delay;
2498
604
    } else {
2499
0
        lad = (1 + mg_size) * (1 + RC_DEFAULT_LAD_MG) + max_tf_delay + eos_delay;
2500
0
    }
2501
2502
604
    lad = lad > MAX_LAD ? MAX_LAD : lad; // clip to max allowed lad
2503
604
    return lad;
2504
604
}
2505
2506
/*
2507
Updates the LAD value
2508
*/
2509
0
static void update_look_ahead(SequenceControlSet* scs) {
2510
    /*To accomodate FFMPEG EOS, 1 frame delay is needed in Resource coordination.
2511
           note that we have the option to not add 1 frame delay of Resource Coordination. In this case we have wait for first I frame
2512
           to be released back to be able to start first base(16). Anyway poc16 needs to wait for poc0 to finish.*/
2513
0
    uint32_t eos_delay = 1;
2514
2515
0
    uint32_t mg_size = 1 << scs->static_config.hierarchical_levels;
2516
0
    if ((int32_t)(scs->static_config.look_ahead_distance - (eos_delay + scs->scd_delay)) < (int32_t)(mg_size + 1)) {
2517
        // Not enough pictures to form the minigop. update mg_size
2518
0
        scs->static_config.look_ahead_distance = mg_size + 1 + (eos_delay + scs->scd_delay);
2519
0
        SVT_WARN("Minimum lookahead distance to run %dL with TF %d is %d. Force the look_ahead_distance to be %d\n",
2520
0
                 scs->static_config.hierarchical_levels + 1,
2521
0
                 scs->static_config.enable_tf,
2522
0
                 scs->static_config.look_ahead_distance,
2523
0
                 scs->static_config.look_ahead_distance);
2524
0
    }
2525
2526
0
    int32_t picture_in_future = scs->static_config.look_ahead_distance;
2527
    // Subtract pictures used for scd_delay and eos_delay
2528
0
    picture_in_future = MAX(0, (int32_t)(picture_in_future - eos_delay - scs->scd_delay));
2529
    // Subtract pictures used for minigop formation. Unit= 1(provision for a potential delayI)
2530
0
    picture_in_future = MAX(0, (int32_t)(picture_in_future - (1 + mg_size)));
2531
    // Specify the number of mini-gops to be used in the sliding window. 0: 1 mini-gop, 1: 2 mini-gops and 3: 3 mini-gops
2532
0
    scs->lad_mg = (picture_in_future + (mg_size + 1) / 2) / (mg_size + 1);
2533
    // Since TPL is tuned for 0, 1 and 2 mini-gops, we make sure lad_mg is not smaller than tpl_lad_mg
2534
0
    if (scs->lad_mg < scs->tpl_lad_mg) {
2535
0
        scs->lad_mg                            = scs->tpl_lad_mg;
2536
0
        scs->static_config.look_ahead_distance = (1 + mg_size) * (scs->lad_mg + 1) + scs->scd_delay + eos_delay;
2537
0
        SVT_WARN(
2538
0
            "Lookahead distance is not long enough to get best bdrate trade off. Force the look_ahead_distance to be "
2539
0
            "%d\n",
2540
0
            scs->static_config.look_ahead_distance);
2541
0
    } else if (scs->lad_mg > scs->tpl_lad_mg &&
2542
0
               (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF ||
2543
0
                scs->static_config.pass == ENC_FIRST_PASS || scs->static_config.pass == ENC_SECOND_PASS)) {
2544
0
        scs->lad_mg                            = scs->tpl_lad_mg;
2545
0
        scs->static_config.look_ahead_distance = (1 + mg_size) * (scs->lad_mg + 1) + scs->scd_delay + eos_delay;
2546
0
        SVT_WARN(
2547
0
            "For CRF or 2PASS RC mode, the maximum needed Lookahead distance is %d. Force the look_ahead_distance to "
2548
0
            "be %d\n",
2549
0
            scs->static_config.look_ahead_distance,
2550
0
            scs->static_config.look_ahead_distance);
2551
0
    }
2552
0
}
2553
2554
/*
2555
 * Control TF
2556
 */
2557
uint8_t svt_aom_tf_max_ref_per_struct(uint32_t hierarchical_levels, uint8_t type /*I_SLICE, BASE, L1*/,
2558
0
                                      bool direction /*Past, Future*/) {
2559
0
    uint8_t max_ref_per;
2560
0
    (void)direction;
2561
0
    if (type == 0) { // I_SLICE
2562
0
        max_ref_per = 1 << hierarchical_levels;
2563
0
    } else if (type == 1) { // BASE
2564
0
        max_ref_per = TF_MAX_BASE_REF_PICS;
2565
0
    } else { // L1
2566
0
        max_ref_per = hierarchical_levels < 5 ? TF_MAX_L1_REF_PICS_SUB_6L : TF_MAX_L1_REF_PICS_6L;
2567
0
    }
2568
2569
0
    return max_ref_per;
2570
0
}
2571
2572
/******************************************************************************
2573
* tf_ld_controls
2574
* TF control functions for low delay mode
2575
*******************************************************************************/
2576
0
static void tf_ld_controls(SequenceControlSet* scs, uint8_t tf_level) {
2577
0
    switch (tf_level) {
2578
0
    case 0:
2579
        // I_SLICE TF Params
2580
0
        scs->tf_params_per_type[0].enabled = 0;
2581
2582
        // BASE TF Params
2583
0
        scs->tf_params_per_type[1].enabled = 0;
2584
2585
        // L1 TF Params
2586
0
        scs->tf_params_per_type[2].enabled = 0;
2587
0
        break;
2588
2589
0
    case 1:
2590
        // I_SLICE TF Params
2591
0
        scs->tf_params_per_type[0].enabled = 0;
2592
        // BASE TF Params
2593
0
        scs->tf_params_per_type[1].enabled                 = 1;
2594
0
        scs->tf_params_per_type[1].num_past_pics           = 1;
2595
0
        scs->tf_params_per_type[1].num_future_pics         = 0;
2596
0
        scs->tf_params_per_type[1].modulate_pics           = 0;
2597
0
        scs->tf_params_per_type[1].max_num_past_pics       = 1;
2598
0
        scs->tf_params_per_type[1].max_num_future_pics     = 0;
2599
0
        scs->tf_params_per_type[1].hme_me_level            = 4;
2600
0
        scs->tf_params_per_type[1].half_pel_mode           = 0;
2601
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 0;
2602
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
2603
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
2604
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 20 * 32 * 32;
2605
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
2606
0
        scs->tf_params_per_type[1].use_zz_based_filter     = 1;
2607
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
2608
0
        scs->tf_params_per_type[1].use_2tap                = 0;
2609
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
2610
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 0;
2611
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
2612
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
2613
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 1;
2614
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
2615
0
        scs->tf_params_per_type[1].qp_opt                  = 0;
2616
        // L1 TF Params
2617
0
        scs->tf_params_per_type[2].enabled = 0;
2618
0
        break;
2619
0
    case 2:
2620
        // I_SLICE TF Params
2621
0
        scs->tf_params_per_type[0].enabled = 0;
2622
        // BASE TF Params
2623
0
        scs->tf_params_per_type[1].enabled                 = 1;
2624
0
        scs->tf_params_per_type[1].num_past_pics           = 1;
2625
0
        scs->tf_params_per_type[1].num_future_pics         = 0;
2626
0
        scs->tf_params_per_type[1].modulate_pics           = 0;
2627
0
        scs->tf_params_per_type[1].max_num_past_pics       = 1;
2628
0
        scs->tf_params_per_type[1].max_num_future_pics     = 0;
2629
0
        scs->tf_params_per_type[1].hme_me_level            = 4;
2630
0
        scs->tf_params_per_type[1].half_pel_mode           = 0;
2631
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 0;
2632
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
2633
0
        scs->tf_params_per_type[1].chroma_lvl              = 2;
2634
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = (uint64_t)~0;
2635
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
2636
0
        scs->tf_params_per_type[1].use_zz_based_filter     = 1;
2637
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
2638
0
        scs->tf_params_per_type[1].use_2tap                = 0;
2639
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
2640
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 0;
2641
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
2642
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
2643
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 0;
2644
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
2645
0
        scs->tf_params_per_type[1].qp_opt                  = 0;
2646
        // L1 TF Params
2647
0
        scs->tf_params_per_type[2].enabled = 0;
2648
0
        break;
2649
2650
0
    default:
2651
0
        assert(0);
2652
0
        break;
2653
0
    }
2654
    // 8x8 path not supported in LD TF
2655
0
    scs->tf_params_per_type[0].enable_8x8_pred = 0;
2656
0
    scs->tf_params_per_type[1].enable_8x8_pred = 0;
2657
0
    scs->tf_params_per_type[2].enable_8x8_pred = 0;
2658
0
}
2659
2660
604
void tf_controls(SequenceControlSet* scs, uint8_t tf_level) {
2661
604
    switch (tf_level) {
2662
604
    case 0:
2663
        // I_SLICE TF Params
2664
604
        scs->tf_params_per_type[0].enabled = 0;
2665
2666
        // BASE TF Params
2667
604
        scs->tf_params_per_type[1].enabled = 0;
2668
2669
        // L1 TF Params
2670
604
        scs->tf_params_per_type[2].enabled = 0;
2671
604
        break;
2672
2673
0
    case 1:
2674
        // I_SLICE TF Params
2675
0
        scs->tf_params_per_type[0].enabled             = 1;
2676
0
        scs->tf_params_per_type[0].num_future_pics     = 24;
2677
0
        scs->tf_params_per_type[0].modulate_pics       = 1;
2678
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
2679
0
            (1 << scs->static_config.hierarchical_levels),
2680
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
2681
0
        scs->tf_params_per_type[0].hme_me_level            = 1;
2682
0
        scs->tf_params_per_type[0].half_pel_mode           = 1;
2683
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
2684
0
        scs->tf_params_per_type[0].eight_pel_mode          = 1;
2685
0
        scs->tf_params_per_type[0].chroma_lvl              = 1;
2686
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = 0;
2687
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 1;
2688
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 0;
2689
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 0;
2690
0
        scs->tf_params_per_type[0].use_2tap                = 0;
2691
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 0;
2692
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
2693
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 0;
2694
0
        scs->tf_params_per_type[0].me_exit_th              = 0;
2695
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 0;
2696
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
2697
0
        scs->tf_params_per_type[0].qp_opt                  = 0;
2698
        // BASE TF Params
2699
0
        scs->tf_params_per_type[1].enabled           = 1;
2700
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
2701
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
2702
0
        scs->tf_params_per_type[1].modulate_pics     = 1;
2703
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
2704
0
            (1 << scs->static_config.hierarchical_levels),
2705
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
2706
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
2707
0
            (1 << scs->static_config.hierarchical_levels),
2708
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
2709
0
        scs->tf_params_per_type[1].hme_me_level            = 1;
2710
0
        scs->tf_params_per_type[1].half_pel_mode           = 1;
2711
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
2712
0
        scs->tf_params_per_type[1].eight_pel_mode          = 1;
2713
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
2714
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 0;
2715
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 1;
2716
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
2717
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
2718
0
        scs->tf_params_per_type[1].use_2tap                = 0;
2719
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
2720
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
2721
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
2722
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
2723
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 0;
2724
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
2725
0
        scs->tf_params_per_type[1].qp_opt                  = 0;
2726
        // L1 TF Params
2727
0
        scs->tf_params_per_type[2].enabled           = 1;
2728
0
        scs->tf_params_per_type[2].num_past_pics     = 1;
2729
0
        scs->tf_params_per_type[2].num_future_pics   = 1;
2730
0
        scs->tf_params_per_type[2].modulate_pics     = 1;
2731
0
        scs->tf_params_per_type[2].max_num_past_pics = MIN(
2732
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2733
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 0));
2734
0
        scs->tf_params_per_type[2].max_num_future_pics = MIN(
2735
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2736
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 1));
2737
0
        scs->tf_params_per_type[2].hme_me_level            = 1;
2738
0
        scs->tf_params_per_type[2].half_pel_mode           = 1;
2739
0
        scs->tf_params_per_type[2].quarter_pel_mode        = 1;
2740
0
        scs->tf_params_per_type[2].eight_pel_mode          = 1;
2741
0
        scs->tf_params_per_type[2].chroma_lvl              = 1;
2742
0
        scs->tf_params_per_type[2].pred_error_32x32_th     = 0;
2743
0
        scs->tf_params_per_type[2].enable_8x8_pred         = 1;
2744
0
        scs->tf_params_per_type[2].sub_sampling_shift      = 0;
2745
0
        scs->tf_params_per_type[2].avoid_2d_qpel           = 0;
2746
0
        scs->tf_params_per_type[2].use_2tap                = 0;
2747
0
        scs->tf_params_per_type[2].use_intra_for_noise_est = 0;
2748
0
        scs->tf_params_per_type[2].use_8bit_subpel         = 1;
2749
0
        scs->tf_params_per_type[2].use_pred_64x64_only_th  = 0;
2750
0
        scs->tf_params_per_type[2].me_exit_th              = 0;
2751
0
        scs->tf_params_per_type[2].subpel_early_exit_th    = 0;
2752
0
        scs->tf_params_per_type[2].ref_frame_factor        = 1;
2753
0
        scs->tf_params_per_type[2].qp_opt                  = 0;
2754
0
        break;
2755
2756
0
    case 2:
2757
        // I_SLICE TF Params
2758
0
        scs->tf_params_per_type[0].enabled             = 1;
2759
0
        scs->tf_params_per_type[0].num_future_pics     = 24;
2760
0
        scs->tf_params_per_type[0].modulate_pics       = 1;
2761
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
2762
0
            (1 << scs->static_config.hierarchical_levels),
2763
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
2764
0
        scs->tf_params_per_type[0].hme_me_level            = 1;
2765
0
        scs->tf_params_per_type[0].half_pel_mode           = 1;
2766
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
2767
0
        scs->tf_params_per_type[0].eight_pel_mode          = 1;
2768
0
        scs->tf_params_per_type[0].chroma_lvl              = 1;
2769
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = 8 * 32 * 32;
2770
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 1;
2771
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 0;
2772
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 0;
2773
0
        scs->tf_params_per_type[0].use_2tap                = 0;
2774
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 0;
2775
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
2776
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 0;
2777
0
        scs->tf_params_per_type[0].me_exit_th              = 0;
2778
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 0;
2779
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
2780
0
        scs->tf_params_per_type[0].qp_opt                  = 0;
2781
        // BASE TF Params
2782
0
        scs->tf_params_per_type[1].enabled           = 1;
2783
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
2784
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
2785
0
        scs->tf_params_per_type[1].modulate_pics     = 2;
2786
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
2787
0
            (1 << scs->static_config.hierarchical_levels),
2788
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
2789
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
2790
0
            (1 << scs->static_config.hierarchical_levels),
2791
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
2792
0
        scs->tf_params_per_type[1].hme_me_level            = 1;
2793
0
        scs->tf_params_per_type[1].half_pel_mode           = 1;
2794
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
2795
0
        scs->tf_params_per_type[1].eight_pel_mode          = 1;
2796
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
2797
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 8 * 32 * 32;
2798
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 1;
2799
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
2800
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
2801
0
        scs->tf_params_per_type[1].use_2tap                = 0;
2802
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
2803
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
2804
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
2805
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
2806
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 0;
2807
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
2808
0
        scs->tf_params_per_type[1].qp_opt                  = 0;
2809
        // L1 TF Params
2810
0
        scs->tf_params_per_type[2].enabled           = 1;
2811
0
        scs->tf_params_per_type[2].num_past_pics     = 1;
2812
0
        scs->tf_params_per_type[2].num_future_pics   = 1;
2813
0
        scs->tf_params_per_type[2].modulate_pics     = 1;
2814
0
        scs->tf_params_per_type[2].max_num_past_pics = MIN(
2815
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2816
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 0));
2817
0
        scs->tf_params_per_type[2].max_num_future_pics = MIN(
2818
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2819
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 1));
2820
0
        scs->tf_params_per_type[2].hme_me_level            = 1;
2821
0
        scs->tf_params_per_type[2].half_pel_mode           = 1;
2822
0
        scs->tf_params_per_type[2].quarter_pel_mode        = 1;
2823
0
        scs->tf_params_per_type[2].eight_pel_mode          = 1;
2824
0
        scs->tf_params_per_type[2].chroma_lvl              = 1;
2825
0
        scs->tf_params_per_type[2].pred_error_32x32_th     = 8 * 32 * 32;
2826
0
        scs->tf_params_per_type[2].enable_8x8_pred         = 1;
2827
0
        scs->tf_params_per_type[2].sub_sampling_shift      = 0;
2828
0
        scs->tf_params_per_type[2].avoid_2d_qpel           = 0;
2829
0
        scs->tf_params_per_type[2].use_2tap                = 0;
2830
0
        scs->tf_params_per_type[2].use_intra_for_noise_est = 0;
2831
0
        scs->tf_params_per_type[2].use_8bit_subpel         = 1;
2832
0
        scs->tf_params_per_type[2].use_pred_64x64_only_th  = 0;
2833
0
        scs->tf_params_per_type[2].me_exit_th              = 0;
2834
0
        scs->tf_params_per_type[2].subpel_early_exit_th    = 0;
2835
0
        scs->tf_params_per_type[2].ref_frame_factor        = 1;
2836
0
        scs->tf_params_per_type[2].qp_opt                  = 0;
2837
0
        break;
2838
2839
0
    case 3:
2840
        // I_SLICE TF Params
2841
0
        scs->tf_params_per_type[0].enabled             = 1;
2842
0
        scs->tf_params_per_type[0].num_future_pics     = 24;
2843
0
        scs->tf_params_per_type[0].modulate_pics       = 1;
2844
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
2845
0
            (1 << scs->static_config.hierarchical_levels),
2846
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
2847
0
        scs->tf_params_per_type[0].hme_me_level            = 1;
2848
0
        scs->tf_params_per_type[0].half_pel_mode           = 1;
2849
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
2850
0
        scs->tf_params_per_type[0].eight_pel_mode          = 1;
2851
0
        scs->tf_params_per_type[0].chroma_lvl              = 1;
2852
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = 8 * 32 * 32;
2853
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 1;
2854
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 0;
2855
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 0;
2856
0
        scs->tf_params_per_type[0].use_2tap                = 0;
2857
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 0;
2858
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
2859
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 0;
2860
0
        scs->tf_params_per_type[0].me_exit_th              = 0;
2861
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 0;
2862
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
2863
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
2864
2865
        // BASE TF Params
2866
0
        scs->tf_params_per_type[1].enabled           = 1;
2867
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
2868
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
2869
0
        scs->tf_params_per_type[1].modulate_pics     = 2;
2870
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
2871
0
            (1 << scs->static_config.hierarchical_levels),
2872
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
2873
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
2874
0
            (1 << scs->static_config.hierarchical_levels),
2875
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
2876
0
        scs->tf_params_per_type[1].hme_me_level            = 1;
2877
0
        scs->tf_params_per_type[1].half_pel_mode           = 1;
2878
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
2879
0
        scs->tf_params_per_type[1].eight_pel_mode          = 1;
2880
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
2881
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 8 * 32 * 32;
2882
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
2883
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
2884
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
2885
0
        scs->tf_params_per_type[1].use_2tap                = 0;
2886
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
2887
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
2888
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
2889
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
2890
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 0;
2891
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
2892
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
2893
2894
        // L1 TF Params
2895
0
        scs->tf_params_per_type[2].enabled           = 1;
2896
0
        scs->tf_params_per_type[2].num_past_pics     = 1;
2897
0
        scs->tf_params_per_type[2].num_future_pics   = 1;
2898
0
        scs->tf_params_per_type[2].modulate_pics     = 1;
2899
0
        scs->tf_params_per_type[2].max_num_past_pics = MIN(
2900
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2901
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 0));
2902
0
        scs->tf_params_per_type[2].max_num_future_pics = MIN(
2903
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2904
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 1));
2905
0
        scs->tf_params_per_type[2].hme_me_level            = 1;
2906
0
        scs->tf_params_per_type[2].half_pel_mode           = 1;
2907
0
        scs->tf_params_per_type[2].quarter_pel_mode        = 1;
2908
0
        scs->tf_params_per_type[2].eight_pel_mode          = 1;
2909
0
        scs->tf_params_per_type[2].chroma_lvl              = 1;
2910
0
        scs->tf_params_per_type[2].pred_error_32x32_th     = 8 * 32 * 32;
2911
0
        scs->tf_params_per_type[2].enable_8x8_pred         = 0;
2912
0
        scs->tf_params_per_type[2].sub_sampling_shift      = 0;
2913
0
        scs->tf_params_per_type[2].avoid_2d_qpel           = 0;
2914
0
        scs->tf_params_per_type[2].use_2tap                = 0;
2915
0
        scs->tf_params_per_type[2].use_intra_for_noise_est = 0;
2916
0
        scs->tf_params_per_type[2].use_8bit_subpel         = 1;
2917
0
        scs->tf_params_per_type[2].use_pred_64x64_only_th  = 0;
2918
0
        scs->tf_params_per_type[2].me_exit_th              = 0;
2919
0
        scs->tf_params_per_type[2].subpel_early_exit_th    = 0;
2920
0
        scs->tf_params_per_type[2].ref_frame_factor        = 1;
2921
0
        scs->tf_params_per_type[2].qp_opt                  = 1;
2922
0
        break;
2923
0
    case 4:
2924
        // I_SLICE TF Params
2925
0
        scs->tf_params_per_type[0].enabled             = 1;
2926
0
        scs->tf_params_per_type[0].num_future_pics     = 24;
2927
0
        scs->tf_params_per_type[0].modulate_pics       = 1;
2928
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
2929
0
            (1 << scs->static_config.hierarchical_levels),
2930
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
2931
0
        scs->tf_params_per_type[0].hme_me_level            = 2;
2932
0
        scs->tf_params_per_type[0].half_pel_mode           = 1;
2933
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
2934
0
        scs->tf_params_per_type[0].eight_pel_mode          = 0;
2935
0
        scs->tf_params_per_type[0].chroma_lvl              = 1;
2936
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = 8 * 32 * 32;
2937
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 0;
2938
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 0;
2939
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 0;
2940
0
        scs->tf_params_per_type[0].use_2tap                = 0;
2941
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 0;
2942
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
2943
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 0;
2944
0
        scs->tf_params_per_type[0].me_exit_th              = 0;
2945
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 1;
2946
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
2947
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
2948
2949
        // BASE TF Params
2950
0
        scs->tf_params_per_type[1].enabled           = 1;
2951
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
2952
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
2953
0
        scs->tf_params_per_type[1].modulate_pics     = 2;
2954
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
2955
0
            (1 << scs->static_config.hierarchical_levels),
2956
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
2957
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
2958
0
            (1 << scs->static_config.hierarchical_levels),
2959
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
2960
0
        scs->tf_params_per_type[1].hme_me_level            = 2;
2961
0
        scs->tf_params_per_type[1].half_pel_mode           = 1;
2962
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
2963
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
2964
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
2965
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 8 * 32 * 32;
2966
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
2967
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
2968
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
2969
0
        scs->tf_params_per_type[1].use_2tap                = 0;
2970
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
2971
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
2972
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
2973
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
2974
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 1;
2975
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
2976
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
2977
2978
        // L1 TF Params
2979
0
        scs->tf_params_per_type[2].enabled           = 1;
2980
0
        scs->tf_params_per_type[2].num_past_pics     = 1;
2981
0
        scs->tf_params_per_type[2].num_future_pics   = 1;
2982
0
        scs->tf_params_per_type[2].modulate_pics     = 1;
2983
0
        scs->tf_params_per_type[2].max_num_past_pics = MIN(
2984
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2985
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 0));
2986
0
        scs->tf_params_per_type[2].max_num_future_pics = MIN(
2987
0
            (1 << scs->static_config.hierarchical_levels) / 2,
2988
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 1));
2989
0
        scs->tf_params_per_type[2].hme_me_level            = 2;
2990
0
        scs->tf_params_per_type[2].half_pel_mode           = 1;
2991
0
        scs->tf_params_per_type[2].quarter_pel_mode        = 1;
2992
0
        scs->tf_params_per_type[2].eight_pel_mode          = 1;
2993
0
        scs->tf_params_per_type[2].chroma_lvl              = 1;
2994
0
        scs->tf_params_per_type[2].pred_error_32x32_th     = 8 * 32 * 32;
2995
0
        scs->tf_params_per_type[2].enable_8x8_pred         = 0;
2996
0
        scs->tf_params_per_type[2].sub_sampling_shift      = 0;
2997
0
        scs->tf_params_per_type[2].avoid_2d_qpel           = 0;
2998
0
        scs->tf_params_per_type[2].use_2tap                = 0;
2999
0
        scs->tf_params_per_type[2].use_intra_for_noise_est = 0;
3000
0
        scs->tf_params_per_type[2].use_8bit_subpel         = 1;
3001
0
        scs->tf_params_per_type[2].use_pred_64x64_only_th  = 0;
3002
0
        scs->tf_params_per_type[2].me_exit_th              = 0;
3003
0
        scs->tf_params_per_type[2].subpel_early_exit_th    = 0;
3004
0
        scs->tf_params_per_type[2].ref_frame_factor        = 1;
3005
0
        scs->tf_params_per_type[2].qp_opt                  = 1;
3006
0
        break;
3007
0
    case 5:
3008
        // I_SLICE TF Params
3009
0
        scs->tf_params_per_type[0].enabled             = 1;
3010
0
        scs->tf_params_per_type[0].num_future_pics     = 24;
3011
0
        scs->tf_params_per_type[0].modulate_pics       = 1;
3012
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
3013
0
            (1 << scs->static_config.hierarchical_levels),
3014
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
3015
0
        scs->tf_params_per_type[0].hme_me_level            = 2;
3016
0
        scs->tf_params_per_type[0].half_pel_mode           = 2;
3017
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
3018
0
        scs->tf_params_per_type[0].eight_pel_mode          = 0;
3019
0
        scs->tf_params_per_type[0].chroma_lvl              = 1;
3020
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = 20 * 32 * 32;
3021
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 0;
3022
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 0;
3023
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 0;
3024
0
        scs->tf_params_per_type[0].use_2tap                = 1;
3025
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 0;
3026
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
3027
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 0;
3028
0
        scs->tf_params_per_type[0].me_exit_th              = 0;
3029
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 1;
3030
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
3031
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
3032
3033
        // BASE TF Params
3034
0
        scs->tf_params_per_type[1].enabled           = 1;
3035
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
3036
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
3037
0
        scs->tf_params_per_type[1].modulate_pics     = 3;
3038
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
3039
0
            (1 << scs->static_config.hierarchical_levels),
3040
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
3041
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
3042
0
            (1 << scs->static_config.hierarchical_levels),
3043
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
3044
0
        scs->tf_params_per_type[1].hme_me_level            = 2;
3045
0
        scs->tf_params_per_type[1].half_pel_mode           = 2;
3046
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
3047
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
3048
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
3049
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 20 * 32 * 32;
3050
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
3051
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
3052
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
3053
0
        scs->tf_params_per_type[1].use_2tap                = 1;
3054
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 0;
3055
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
3056
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
3057
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
3058
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 1;
3059
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
3060
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
3061
3062
        // L1 TF Params
3063
0
        scs->tf_params_per_type[2].enabled           = 1;
3064
0
        scs->tf_params_per_type[2].num_past_pics     = 1;
3065
0
        scs->tf_params_per_type[2].num_future_pics   = 1;
3066
0
        scs->tf_params_per_type[2].modulate_pics     = 2;
3067
0
        scs->tf_params_per_type[2].max_num_past_pics = MIN(
3068
0
            (1 << scs->static_config.hierarchical_levels) / 2,
3069
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 0));
3070
0
        scs->tf_params_per_type[2].max_num_future_pics = MIN(
3071
0
            (1 << scs->static_config.hierarchical_levels) / 2,
3072
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 2, 1));
3073
0
        scs->tf_params_per_type[2].hme_me_level            = 2;
3074
0
        scs->tf_params_per_type[2].half_pel_mode           = 2;
3075
0
        scs->tf_params_per_type[2].quarter_pel_mode        = 1;
3076
0
        scs->tf_params_per_type[2].eight_pel_mode          = 0;
3077
0
        scs->tf_params_per_type[2].chroma_lvl              = 1;
3078
0
        scs->tf_params_per_type[2].pred_error_32x32_th     = 20 * 32 * 32;
3079
0
        scs->tf_params_per_type[2].enable_8x8_pred         = 0;
3080
0
        scs->tf_params_per_type[2].sub_sampling_shift      = 0;
3081
0
        scs->tf_params_per_type[2].avoid_2d_qpel           = 0;
3082
0
        scs->tf_params_per_type[2].use_2tap                = 1;
3083
0
        scs->tf_params_per_type[2].use_intra_for_noise_est = 0;
3084
0
        scs->tf_params_per_type[2].use_8bit_subpel         = 1;
3085
0
        scs->tf_params_per_type[2].use_pred_64x64_only_th  = 0;
3086
0
        scs->tf_params_per_type[2].me_exit_th              = 0;
3087
0
        scs->tf_params_per_type[2].subpel_early_exit_th    = 1;
3088
0
        scs->tf_params_per_type[2].ref_frame_factor        = 1;
3089
0
        scs->tf_params_per_type[2].qp_opt                  = 1;
3090
0
        break;
3091
0
    case 6:
3092
        // I_SLICE TF Params
3093
0
        scs->tf_params_per_type[0].enabled             = 1;
3094
0
        scs->tf_params_per_type[0].num_future_pics     = (scs->static_config.hierarchical_levels < 5) ? 8 : 16;
3095
0
        scs->tf_params_per_type[0].modulate_pics       = 0;
3096
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
3097
0
            (1 << scs->static_config.hierarchical_levels),
3098
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
3099
0
        scs->tf_params_per_type[0].hme_me_level            = 2;
3100
0
        scs->tf_params_per_type[0].half_pel_mode           = 2;
3101
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
3102
0
        scs->tf_params_per_type[0].eight_pel_mode          = 0;
3103
0
        scs->tf_params_per_type[0].chroma_lvl              = 0;
3104
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = (uint64_t)~0;
3105
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 0;
3106
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 1;
3107
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 1;
3108
0
        scs->tf_params_per_type[0].use_2tap                = 1;
3109
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 1;
3110
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
3111
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 0;
3112
0
        scs->tf_params_per_type[0].me_exit_th              = 0;
3113
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 1;
3114
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
3115
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
3116
        // BASE TF Params
3117
0
        scs->tf_params_per_type[1].enabled           = 1;
3118
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
3119
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
3120
0
        scs->tf_params_per_type[1].modulate_pics     = 3;
3121
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
3122
0
            (1 << scs->static_config.hierarchical_levels),
3123
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
3124
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
3125
0
            (1 << scs->static_config.hierarchical_levels),
3126
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
3127
0
        scs->tf_params_per_type[1].hme_me_level            = 2;
3128
0
        scs->tf_params_per_type[1].half_pel_mode           = 2;
3129
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
3130
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
3131
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
3132
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 20 * 32 * 32;
3133
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
3134
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
3135
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
3136
0
        scs->tf_params_per_type[1].use_2tap                = 1;
3137
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 1;
3138
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
3139
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 0;
3140
0
        scs->tf_params_per_type[1].me_exit_th              = 0;
3141
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 1;
3142
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
3143
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
3144
        // L1 TF Params
3145
0
        scs->tf_params_per_type[2].enabled = 0;
3146
0
        break;
3147
0
    case 7:
3148
        // I_SLICE TF Params
3149
0
        scs->tf_params_per_type[0].enabled             = 1;
3150
0
        scs->tf_params_per_type[0].num_future_pics     = (scs->static_config.hierarchical_levels < 5) ? 8 : 16;
3151
0
        scs->tf_params_per_type[0].modulate_pics       = 0;
3152
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
3153
0
            (1 << scs->static_config.hierarchical_levels),
3154
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
3155
0
        scs->tf_params_per_type[0].hme_me_level            = 2;
3156
0
        scs->tf_params_per_type[0].half_pel_mode           = 2;
3157
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
3158
0
        scs->tf_params_per_type[0].eight_pel_mode          = 0;
3159
0
        scs->tf_params_per_type[0].chroma_lvl              = 0;
3160
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = (uint64_t)~0;
3161
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 0;
3162
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 1;
3163
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 1;
3164
0
        scs->tf_params_per_type[0].use_2tap                = 1;
3165
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 1;
3166
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
3167
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 35;
3168
0
        scs->tf_params_per_type[0].me_exit_th              = 16 * 16;
3169
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 1;
3170
0
        scs->tf_params_per_type[0].ref_frame_factor        = 1;
3171
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
3172
        // BASE TF Params
3173
0
        scs->tf_params_per_type[1].enabled           = 1;
3174
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
3175
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
3176
0
        scs->tf_params_per_type[1].modulate_pics     = 3;
3177
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
3178
0
            (1 << scs->static_config.hierarchical_levels),
3179
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
3180
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
3181
0
            (1 << scs->static_config.hierarchical_levels),
3182
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
3183
0
        scs->tf_params_per_type[1].hme_me_level            = 2;
3184
0
        scs->tf_params_per_type[1].half_pel_mode           = 2;
3185
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
3186
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
3187
0
        scs->tf_params_per_type[1].chroma_lvl              = 1;
3188
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = 20 * 32 * 32;
3189
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
3190
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 0;
3191
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 0;
3192
0
        scs->tf_params_per_type[1].use_2tap                = 1;
3193
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 1;
3194
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
3195
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 35;
3196
0
        scs->tf_params_per_type[1].me_exit_th              = 16 * 16;
3197
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 1;
3198
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
3199
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
3200
        // L1 TF Params
3201
0
        scs->tf_params_per_type[2].enabled = 0;
3202
0
        break;
3203
0
    case 8:
3204
        // I_SLICE TF Params
3205
0
        scs->tf_params_per_type[0].enabled             = 1;
3206
0
        scs->tf_params_per_type[0].num_future_pics     = 8;
3207
0
        scs->tf_params_per_type[0].modulate_pics       = 0;
3208
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
3209
0
            (1 << scs->static_config.hierarchical_levels),
3210
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
3211
0
        scs->tf_params_per_type[0].hme_me_level            = 2;
3212
0
        scs->tf_params_per_type[0].half_pel_mode           = 2;
3213
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
3214
0
        scs->tf_params_per_type[0].eight_pel_mode          = 0;
3215
0
        scs->tf_params_per_type[0].chroma_lvl              = 0;
3216
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = (uint64_t)~0;
3217
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 0;
3218
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 1;
3219
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 1;
3220
0
        scs->tf_params_per_type[0].use_2tap                = 1;
3221
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 1;
3222
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
3223
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 35;
3224
0
        scs->tf_params_per_type[0].me_exit_th              = 16 * 16;
3225
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 4;
3226
0
        scs->tf_params_per_type[0].ref_frame_factor        = 2;
3227
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
3228
        // BASE TF Params
3229
0
        scs->tf_params_per_type[1].enabled           = 1;
3230
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
3231
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
3232
0
        scs->tf_params_per_type[1].modulate_pics     = 4;
3233
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
3234
0
            (1 << scs->static_config.hierarchical_levels),
3235
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
3236
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
3237
0
            (1 << scs->static_config.hierarchical_levels),
3238
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
3239
0
        scs->tf_params_per_type[1].hme_me_level            = 2;
3240
0
        scs->tf_params_per_type[1].half_pel_mode           = 2;
3241
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
3242
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
3243
0
        scs->tf_params_per_type[1].chroma_lvl              = 0;
3244
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = (uint64_t)~0;
3245
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
3246
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 1;
3247
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 1;
3248
0
        scs->tf_params_per_type[1].use_2tap                = 1;
3249
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 1;
3250
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
3251
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 35;
3252
0
        scs->tf_params_per_type[1].me_exit_th              = 16 * 16;
3253
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 4;
3254
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
3255
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
3256
        // L1 TF Params
3257
0
        scs->tf_params_per_type[2].enabled = 0;
3258
0
        break;
3259
0
    case 9:
3260
        // I_SLICE TF Params
3261
0
        scs->tf_params_per_type[0].enabled             = 1;
3262
0
        scs->tf_params_per_type[0].num_future_pics     = 8;
3263
0
        scs->tf_params_per_type[0].modulate_pics       = 0;
3264
0
        scs->tf_params_per_type[0].max_num_future_pics = MIN(
3265
0
            (1 << scs->static_config.hierarchical_levels),
3266
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 0, 1));
3267
0
        scs->tf_params_per_type[0].hme_me_level            = 3;
3268
0
        scs->tf_params_per_type[0].half_pel_mode           = 2;
3269
0
        scs->tf_params_per_type[0].quarter_pel_mode        = 1;
3270
0
        scs->tf_params_per_type[0].eight_pel_mode          = 0;
3271
0
        scs->tf_params_per_type[0].chroma_lvl              = 0;
3272
0
        scs->tf_params_per_type[0].pred_error_32x32_th     = (uint64_t)~0;
3273
0
        scs->tf_params_per_type[0].enable_8x8_pred         = 0;
3274
0
        scs->tf_params_per_type[0].sub_sampling_shift      = 1;
3275
0
        scs->tf_params_per_type[0].avoid_2d_qpel           = 1;
3276
0
        scs->tf_params_per_type[0].use_2tap                = 1;
3277
0
        scs->tf_params_per_type[0].use_intra_for_noise_est = 1;
3278
0
        scs->tf_params_per_type[0].use_8bit_subpel         = 1;
3279
0
        scs->tf_params_per_type[0].use_pred_64x64_only_th  = 35;
3280
0
        scs->tf_params_per_type[0].me_exit_th              = 16 * 16;
3281
0
        scs->tf_params_per_type[0].subpel_early_exit_th    = 4;
3282
0
        scs->tf_params_per_type[0].ref_frame_factor        = 2;
3283
0
        scs->tf_params_per_type[0].qp_opt                  = 1;
3284
        // BASE TF Params
3285
0
        scs->tf_params_per_type[1].enabled           = 1;
3286
0
        scs->tf_params_per_type[1].num_past_pics     = 1;
3287
0
        scs->tf_params_per_type[1].num_future_pics   = 1;
3288
0
        scs->tf_params_per_type[1].modulate_pics     = 4;
3289
0
        scs->tf_params_per_type[1].max_num_past_pics = MIN(
3290
0
            (1 << scs->static_config.hierarchical_levels),
3291
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 0));
3292
0
        scs->tf_params_per_type[1].max_num_future_pics = MIN(
3293
0
            (1 << scs->static_config.hierarchical_levels),
3294
0
            svt_aom_tf_max_ref_per_struct(scs->static_config.hierarchical_levels, 1, 1));
3295
0
        scs->tf_params_per_type[1].hme_me_level            = 3;
3296
0
        scs->tf_params_per_type[1].half_pel_mode           = 2;
3297
0
        scs->tf_params_per_type[1].quarter_pel_mode        = 1;
3298
0
        scs->tf_params_per_type[1].eight_pel_mode          = 0;
3299
0
        scs->tf_params_per_type[1].chroma_lvl              = 0;
3300
0
        scs->tf_params_per_type[1].pred_error_32x32_th     = (uint64_t)~0;
3301
0
        scs->tf_params_per_type[1].enable_8x8_pred         = 0;
3302
0
        scs->tf_params_per_type[1].sub_sampling_shift      = 1;
3303
0
        scs->tf_params_per_type[1].avoid_2d_qpel           = 1;
3304
0
        scs->tf_params_per_type[1].use_2tap                = 1;
3305
0
        scs->tf_params_per_type[1].use_intra_for_noise_est = 1;
3306
0
        scs->tf_params_per_type[1].use_8bit_subpel         = 1;
3307
0
        scs->tf_params_per_type[1].use_pred_64x64_only_th  = 35;
3308
0
        scs->tf_params_per_type[1].me_exit_th              = 16 * 16;
3309
0
        scs->tf_params_per_type[1].subpel_early_exit_th    = 4;
3310
0
        scs->tf_params_per_type[1].ref_frame_factor        = 1;
3311
0
        scs->tf_params_per_type[1].qp_opt                  = 1;
3312
        // L1 TF Params
3313
0
        scs->tf_params_per_type[2].enabled = 0;
3314
0
        break;
3315
0
    default:
3316
0
        assert(0);
3317
0
        break;
3318
604
    }
3319
604
    scs->tf_params_per_type[0].use_zz_based_filter = 0;
3320
604
    scs->tf_params_per_type[1].use_zz_based_filter = 0;
3321
604
    scs->tf_params_per_type[2].use_zz_based_filter = 0;
3322
604
}
3323
3324
/*
3325
 * Derive tune Params; 0: use objective mode params, 1: use subjective mode params
3326
 */
3327
604
static void derive_vq_params(SequenceControlSet* scs) {
3328
604
    VqCtrls* vq_ctrl = &scs->vq_ctrls;
3329
3330
604
    if (scs->static_config.tune == TUNE_VQ) {
3331
        // Sharpness
3332
0
        vq_ctrl->sharpness_ctrls.scene_transition = 1;
3333
0
        vq_ctrl->sharpness_ctrls.tf               = 1;
3334
0
        vq_ctrl->sharpness_ctrls.unipred_bias     = 1;
3335
0
        vq_ctrl->sharpness_ctrls.ifs              = 1;
3336
0
        vq_ctrl->sharpness_ctrls.cdef             = 1;
3337
0
        vq_ctrl->sharpness_ctrls.restoration      = 1;
3338
0
        vq_ctrl->sharpness_ctrls.rdoq             = 1;
3339
604
    } else {
3340
        // Sharpness
3341
604
        vq_ctrl->sharpness_ctrls.scene_transition = 1;
3342
604
        vq_ctrl->sharpness_ctrls.tf               = 0;
3343
604
        vq_ctrl->sharpness_ctrls.unipred_bias     = 0;
3344
604
        vq_ctrl->sharpness_ctrls.ifs              = 0;
3345
604
        vq_ctrl->sharpness_ctrls.cdef             = 0;
3346
604
        vq_ctrl->sharpness_ctrls.restoration      = 0;
3347
604
        vq_ctrl->sharpness_ctrls.rdoq             = 0;
3348
604
    }
3349
    // Do not use scene_transition if LD or 1st pass or middle pass
3350
604
    if (scs->static_config.pred_structure != RANDOM_ACCESS || scs->static_config.pass == ENC_FIRST_PASS) {
3351
604
        vq_ctrl->sharpness_ctrls.scene_transition = 0;
3352
604
    }
3353
604
}
3354
3355
/*
3356
 * Derive TF Params
3357
 */
3358
604
static void derive_tf_params(SequenceControlSet* scs) {
3359
604
    const uint32_t hierarchical_levels = scs->static_config.hierarchical_levels;
3360
    // Do not perform TF if LD or 1 Layer or 1st pass
3361
604
    const bool    do_tf    = scs->static_config.enable_tf && hierarchical_levels >= 1 && !scs->static_config.lossless;
3362
604
    const EncMode enc_mode = SVT_ENC_MODE(scs->static_config.enc_mode);
3363
604
    uint8_t       tf_level = 0;
3364
604
    if (scs->static_config.pred_structure == LOW_DELAY) {
3365
        // TF disabled for all LD
3366
0
        tf_level = 0;
3367
0
        tf_ld_controls(scs, tf_level);
3368
0
        return;
3369
0
    }
3370
604
    if (do_tf == 0) {
3371
604
        tf_level = 0;
3372
604
    } else if (enc_mode <= ENC_M1) {
3373
0
        tf_level = 1;
3374
0
    } else if (enc_mode <= ENC_M2) {
3375
0
        tf_level = 2;
3376
0
    } else if (enc_mode <= ENC_M7) {
3377
0
        tf_level = 5;
3378
0
    } else {
3379
0
        tf_level = 9;
3380
0
    }
3381
604
    tf_controls(scs, tf_level);
3382
604
}
3383
3384
/*
3385
 * Set the MRP control
3386
 */
3387
604
static void set_mrp_ctrl_with_level(const SequenceControlSet* scs, MrpCtrls* mrp_ctrl, uint8_t mrp_level) {
3388
604
    switch (mrp_level) {
3389
0
    case 0:
3390
0
        mrp_ctrl->referencing_scheme       = 0;
3391
0
        mrp_ctrl->base_ref_list0_count     = 1;
3392
0
        mrp_ctrl->base_ref_list1_count     = 0;
3393
0
        mrp_ctrl->non_base_ref_list0_count = 1;
3394
0
        mrp_ctrl->non_base_ref_list1_count = 0;
3395
0
        mrp_ctrl->more_5L_refs             = 0;
3396
0
        mrp_ctrl->safe_limit_nref          = 0;
3397
0
        mrp_ctrl->safe_limit_zz_th         = 0;
3398
0
        mrp_ctrl->only_l_bwd               = 0;
3399
0
        mrp_ctrl->pme_ref0_only            = 0;
3400
0
        mrp_ctrl->use_best_references      = 0;
3401
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3402
0
        break;
3403
3404
0
    case 1:
3405
0
        mrp_ctrl->referencing_scheme       = 1;
3406
0
        mrp_ctrl->base_ref_list0_count     = 4;
3407
0
        mrp_ctrl->base_ref_list1_count     = 3;
3408
0
        mrp_ctrl->non_base_ref_list0_count = 4;
3409
0
        mrp_ctrl->non_base_ref_list1_count = 3;
3410
0
        mrp_ctrl->more_5L_refs             = 1;
3411
0
        mrp_ctrl->safe_limit_nref          = 0;
3412
0
        mrp_ctrl->safe_limit_zz_th         = 0;
3413
0
        mrp_ctrl->only_l_bwd               = 0;
3414
0
        mrp_ctrl->pme_ref0_only            = 0;
3415
0
        mrp_ctrl->use_best_references      = 0;
3416
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3417
0
        break;
3418
3419
0
    case 2:
3420
0
        mrp_ctrl->referencing_scheme       = 1;
3421
0
        mrp_ctrl->base_ref_list0_count     = 4;
3422
0
        mrp_ctrl->base_ref_list1_count     = 3;
3423
0
        mrp_ctrl->non_base_ref_list0_count = 4;
3424
0
        mrp_ctrl->non_base_ref_list1_count = 3;
3425
0
        mrp_ctrl->more_5L_refs             = 1;
3426
0
        mrp_ctrl->safe_limit_nref          = 0;
3427
0
        mrp_ctrl->safe_limit_zz_th         = 0;
3428
0
        mrp_ctrl->only_l_bwd               = 1;
3429
0
        mrp_ctrl->pme_ref0_only            = 0;
3430
0
        mrp_ctrl->use_best_references      = 0;
3431
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3432
0
        break;
3433
0
    case 3:
3434
0
        mrp_ctrl->referencing_scheme       = 1;
3435
0
        mrp_ctrl->base_ref_list0_count     = 4;
3436
0
        mrp_ctrl->base_ref_list1_count     = 3;
3437
0
        mrp_ctrl->non_base_ref_list0_count = 4;
3438
0
        mrp_ctrl->non_base_ref_list1_count = 3;
3439
0
        mrp_ctrl->more_5L_refs             = 1;
3440
0
        mrp_ctrl->safe_limit_nref          = 0;
3441
0
        mrp_ctrl->safe_limit_zz_th         = 0;
3442
0
        mrp_ctrl->only_l_bwd               = 1;
3443
0
        mrp_ctrl->pme_ref0_only            = 0;
3444
0
        mrp_ctrl->use_best_references      = 2;
3445
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3446
0
        break;
3447
0
    case 4:
3448
0
        mrp_ctrl->referencing_scheme       = 1;
3449
0
        mrp_ctrl->base_ref_list0_count     = 4;
3450
0
        mrp_ctrl->base_ref_list1_count     = 3;
3451
0
        mrp_ctrl->non_base_ref_list0_count = 4;
3452
0
        mrp_ctrl->non_base_ref_list1_count = 3;
3453
0
        mrp_ctrl->more_5L_refs             = 1;
3454
0
        mrp_ctrl->safe_limit_nref          = 1;
3455
0
        mrp_ctrl->safe_limit_zz_th         = 60000;
3456
0
        mrp_ctrl->only_l_bwd               = 1;
3457
0
        mrp_ctrl->pme_ref0_only            = 1;
3458
0
        mrp_ctrl->use_best_references      = 3;
3459
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3460
0
        break;
3461
0
    case 5:
3462
0
        mrp_ctrl->referencing_scheme       = 0;
3463
0
        mrp_ctrl->base_ref_list0_count     = 4;
3464
0
        mrp_ctrl->base_ref_list1_count     = 3;
3465
0
        mrp_ctrl->non_base_ref_list0_count = 4;
3466
0
        mrp_ctrl->non_base_ref_list1_count = 3;
3467
0
        mrp_ctrl->more_5L_refs             = 0;
3468
0
        mrp_ctrl->safe_limit_nref          = 2;
3469
0
        mrp_ctrl->safe_limit_zz_th         = 60000;
3470
0
        mrp_ctrl->only_l_bwd               = 1;
3471
0
        mrp_ctrl->pme_ref0_only            = 1;
3472
0
        mrp_ctrl->use_best_references      = 3;
3473
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3474
0
        break;
3475
0
    case 6:
3476
0
        mrp_ctrl->referencing_scheme       = 0;
3477
0
        mrp_ctrl->base_ref_list0_count     = 3;
3478
0
        mrp_ctrl->base_ref_list1_count     = 2;
3479
0
        mrp_ctrl->non_base_ref_list0_count = 3;
3480
0
        mrp_ctrl->non_base_ref_list1_count = 2;
3481
0
        mrp_ctrl->more_5L_refs             = 0;
3482
0
        mrp_ctrl->safe_limit_nref          = 2;
3483
0
        mrp_ctrl->safe_limit_zz_th         = 60000;
3484
0
        mrp_ctrl->only_l_bwd               = 1;
3485
0
        mrp_ctrl->pme_ref0_only            = 1;
3486
0
        mrp_ctrl->use_best_references      = 3;
3487
0
        mrp_ctrl->early_hme_l0_prune_th    = 170;
3488
0
        break;
3489
0
    case 7:
3490
0
        mrp_ctrl->referencing_scheme       = 0;
3491
0
        mrp_ctrl->base_ref_list0_count     = 3;
3492
0
        mrp_ctrl->base_ref_list1_count     = 2;
3493
0
        mrp_ctrl->non_base_ref_list0_count = 3;
3494
0
        mrp_ctrl->non_base_ref_list1_count = 2;
3495
0
        mrp_ctrl->more_5L_refs             = 0;
3496
0
        mrp_ctrl->safe_limit_nref          = 2;
3497
0
        mrp_ctrl->safe_limit_zz_th         = 60000;
3498
0
        mrp_ctrl->only_l_bwd               = 1;
3499
0
        mrp_ctrl->pme_ref0_only            = 1;
3500
0
        mrp_ctrl->use_best_references      = 3;
3501
0
        mrp_ctrl->early_hme_l0_prune_th    = 150;
3502
0
        break;
3503
0
    case 8:
3504
0
        mrp_ctrl->referencing_scheme       = 0;
3505
0
        mrp_ctrl->base_ref_list0_count     = 3;
3506
0
        mrp_ctrl->base_ref_list1_count     = 2;
3507
0
        mrp_ctrl->non_base_ref_list0_count = 2;
3508
0
        mrp_ctrl->non_base_ref_list1_count = 2;
3509
0
        mrp_ctrl->more_5L_refs             = 0;
3510
0
        mrp_ctrl->safe_limit_nref          = 2;
3511
0
        mrp_ctrl->safe_limit_zz_th         = 60000;
3512
0
        mrp_ctrl->only_l_bwd               = 1;
3513
0
        mrp_ctrl->pme_ref0_only            = 1;
3514
0
        mrp_ctrl->use_best_references      = 3;
3515
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3516
0
        break;
3517
604
    case 9:
3518
604
        mrp_ctrl->referencing_scheme       = 0;
3519
604
        mrp_ctrl->base_ref_list0_count     = 3;
3520
604
        mrp_ctrl->base_ref_list1_count     = 2;
3521
604
        mrp_ctrl->non_base_ref_list0_count = 1;
3522
604
        mrp_ctrl->non_base_ref_list1_count = 1;
3523
604
        mrp_ctrl->more_5L_refs             = 0;
3524
604
        mrp_ctrl->safe_limit_nref          = 2;
3525
604
        mrp_ctrl->safe_limit_zz_th         = 60000;
3526
604
        mrp_ctrl->only_l_bwd               = 1;
3527
604
        mrp_ctrl->pme_ref0_only            = 1;
3528
604
        mrp_ctrl->use_best_references      = 3;
3529
604
        mrp_ctrl->early_hme_l0_prune_th    = 150;
3530
604
        break;
3531
0
    case 10:
3532
0
        mrp_ctrl->referencing_scheme       = 0;
3533
0
        mrp_ctrl->base_ref_list0_count     = 2;
3534
0
        mrp_ctrl->base_ref_list1_count     = 2;
3535
0
        mrp_ctrl->non_base_ref_list0_count = 1;
3536
0
        mrp_ctrl->non_base_ref_list1_count = 1;
3537
0
        mrp_ctrl->more_5L_refs             = 0;
3538
0
        mrp_ctrl->safe_limit_nref          = 2;
3539
0
        mrp_ctrl->safe_limit_zz_th         = 60000;
3540
0
        mrp_ctrl->only_l_bwd               = 1;
3541
0
        mrp_ctrl->pme_ref0_only            = 1;
3542
0
        mrp_ctrl->use_best_references      = 3;
3543
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3544
0
        break;
3545
0
    case 11:
3546
0
        mrp_ctrl->referencing_scheme       = 0;
3547
0
        mrp_ctrl->base_ref_list0_count     = 1;
3548
0
        mrp_ctrl->base_ref_list1_count     = 1;
3549
0
        mrp_ctrl->non_base_ref_list0_count = 1;
3550
0
        mrp_ctrl->non_base_ref_list1_count = 1;
3551
0
        mrp_ctrl->more_5L_refs             = 0;
3552
0
        mrp_ctrl->safe_limit_nref          = 0;
3553
0
        mrp_ctrl->safe_limit_zz_th         = 0;
3554
0
        mrp_ctrl->only_l_bwd               = 0;
3555
0
        mrp_ctrl->pme_ref0_only            = 0;
3556
0
        mrp_ctrl->use_best_references      = 0;
3557
0
        mrp_ctrl->early_hme_l0_prune_th    = 0;
3558
0
        break;
3559
0
    default:
3560
0
        assert(0);
3561
0
        break;
3562
604
    }
3563
    // For low delay mode, list1 references are not used
3564
604
    if (scs->static_config.pred_structure == LOW_DELAY && scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR) {
3565
0
        mrp_ctrl->base_ref_list1_count     = 0;
3566
0
        mrp_ctrl->non_base_ref_list1_count = 0;
3567
0
        if (scs->static_config.rtc && scs->static_config.hierarchical_levels == 0) {
3568
0
            mrp_ctrl->referencing_scheme  = 0;
3569
0
            mrp_ctrl->more_5L_refs        = 0;
3570
0
            mrp_ctrl->safe_limit_nref     = 0;
3571
0
            mrp_ctrl->only_l_bwd          = 0;
3572
0
            mrp_ctrl->pme_ref0_only       = 0;
3573
0
            mrp_ctrl->use_best_references = 0;
3574
0
        }
3575
0
    }
3576
3577
604
    if (scs->static_config.pred_structure == LOW_DELAY) {
3578
0
        if (scs->static_config.rtc && scs->static_config.hierarchical_levels == 0) {
3579
0
            mrp_ctrl->flat_max_refs = MAX(MAX(mrp_ctrl->base_ref_list0_count, mrp_ctrl->base_ref_list1_count),
3580
0
                                          MAX(mrp_ctrl->non_base_ref_list0_count, mrp_ctrl->non_base_ref_list1_count));
3581
0
        }
3582
3583
0
        mrp_ctrl->ld_reduce_ref_buffs = (mrp_ctrl->base_ref_list0_count <= 1 && mrp_ctrl->base_ref_list1_count <= 1 &&
3584
0
                                         mrp_ctrl->non_base_ref_list0_count <= 1 &&
3585
0
                                         mrp_ctrl->non_base_ref_list1_count <= 1)
3586
0
            ? 2
3587
0
            : (mrp_ctrl->base_ref_list0_count <= 2 && mrp_ctrl->base_ref_list1_count <= 2 &&
3588
0
               mrp_ctrl->non_base_ref_list0_count <= 2 && mrp_ctrl->non_base_ref_list1_count <= 2)
3589
0
            ? 1
3590
0
            : 0;
3591
604
    } else {
3592
604
        mrp_ctrl->ld_reduce_ref_buffs = 0;
3593
604
    }
3594
#if !CONFIG_ENABLE_INTER_COMPOUND
3595
    // Compound prediction is disabled in this build, so the compound (jnt) convolve
3596
    // path is stripped (inter_prediction.c). That is only safe if no block can ever
3597
    // have a 2nd reference, i.e. single-reference only. If this fires, an RTC preset
3598
    // was retuned to use >1 reference while compound is compiled out -> re-enable
3599
    // CONFIG_ENABLE_INTER_COMPOUND or keep RTC single-ref.
3600
    if (scs->static_config.rtc) {
3601
        assert(mrp_ctrl->base_ref_list0_count <= 1 && mrp_ctrl->non_base_ref_list0_count <= 1 &&
3602
               mrp_ctrl->base_ref_list1_count == 0 && mrp_ctrl->non_base_ref_list1_count == 0);
3603
    }
3604
#endif
3605
604
}
3606
3607
// Preset-driven entry point for setting mrp_ctrl. Owns the
3608
// enc_mode->mrp_level cascade.
3609
604
static void set_mrp_ctrl(const SequenceControlSet* scs, MrpCtrls* mrp_ctrl, EncMode enc_mode) {
3610
604
    uint8_t mrp_level;
3611
604
    if (scs->static_config.rtc) {
3612
0
        if (scs->static_config.hierarchical_levels == 0) {
3613
0
            if (enc_mode <= ENC_M8) {
3614
0
                mrp_level = 6;
3615
0
            } else {
3616
0
                mrp_level = 0;
3617
0
            }
3618
0
        } else {
3619
0
            if (enc_mode <= ENC_M8) {
3620
0
                mrp_level = 6;
3621
0
            } else {
3622
0
                mrp_level = 0;
3623
0
            }
3624
0
        }
3625
0
    }
3626
3627
604
    else {
3628
604
        if (enc_mode <= ENC_MR) {
3629
0
            mrp_level = 1;
3630
604
        } else if (enc_mode <= ENC_M2) {
3631
0
            mrp_level = 2;
3632
604
        } else if (enc_mode <= ENC_M4) {
3633
0
            mrp_level = 4;
3634
604
        } else if (enc_mode <= ENC_M8) {
3635
0
            mrp_level = 6;
3636
604
        } else if (enc_mode <= ENC_M9) {
3637
604
            mrp_level = scs->static_config.pred_structure == RANDOM_ACCESS ? 7 : 9;
3638
604
        } else {
3639
0
            if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) == EB_EIGHT_BIT) {
3640
0
                mrp_level = scs->static_config.pred_structure == RANDOM_ACCESS ? 11 : 0;
3641
0
            } else {
3642
0
                mrp_level = scs->static_config.pred_structure == RANDOM_ACCESS ? 7 : 0;
3643
0
            }
3644
0
        }
3645
604
    }
3646
604
    set_mrp_ctrl_with_level(scs, mrp_ctrl, mrp_level);
3647
604
}
3648
3649
// Mutate mrp_ctrls mode-decision fields in place for the runtime preset.
3650
// Structural fields (ld_reduce_ref_buffs, flat_max_refs) are never written
3651
// — they're locked to the init-time DPB allocation. Per-field writes are
3652
// hardware-atomic; same lock-free runtime-update pattern as
3653
// update_rate_info / update_frame_rate_info.
3654
0
void svt_aom_clamp_mrp_ctrls_to_runtime_preset(SequenceControlSet* scs, EncMode runtime_enc_mode) {
3655
    // Defensive zero-init: set_mrp_ctrl writes most but not all fields (e.g.
3656
    // flat_max_refs only in the flat-IPP path). We don't read the unset
3657
    // fields, but zero-init prevents propagation of garbage if a future
3658
    // edit adds a copy-back for one.
3659
0
    MrpCtrls tmp = {0};
3660
    // mrp_ctrls_init is populated at end of set_param_based_on_input; if 0
3661
    // here, init never ran and we shouldn't be processing frames.
3662
0
    assert(scs->mrp_ctrls_init.base_ref_list0_count > 0);
3663
0
    set_mrp_ctrl(scs, &tmp, runtime_enc_mode);
3664
3665
    // Clamp list counts to the init buffer envelope (runtime can shrink but
3666
    // never grow past what was allocated).
3667
0
#define CLAMP(field) tmp.field = MIN(scs->mrp_ctrls_init.field, tmp.field)
3668
0
    CLAMP(base_ref_list0_count);
3669
0
    CLAMP(base_ref_list1_count);
3670
0
    CLAMP(non_base_ref_list0_count);
3671
0
    CLAMP(non_base_ref_list1_count);
3672
0
#undef CLAMP
3673
3674
    // Publish mutable fields one-by-one. NOT updating ld_reduce_ref_buffs
3675
    // or flat_max_refs — readers in pd_process use those to interpret DPB
3676
    // layout, which is locked at init.
3677
0
    scs->mrp_ctrls.referencing_scheme       = tmp.referencing_scheme;
3678
0
    scs->mrp_ctrls.base_ref_list0_count     = tmp.base_ref_list0_count;
3679
0
    scs->mrp_ctrls.base_ref_list1_count     = tmp.base_ref_list1_count;
3680
0
    scs->mrp_ctrls.non_base_ref_list0_count = tmp.non_base_ref_list0_count;
3681
0
    scs->mrp_ctrls.non_base_ref_list1_count = tmp.non_base_ref_list1_count;
3682
0
    scs->mrp_ctrls.more_5L_refs             = tmp.more_5L_refs;
3683
0
    scs->mrp_ctrls.safe_limit_nref          = tmp.safe_limit_nref;
3684
0
    scs->mrp_ctrls.safe_limit_zz_th         = tmp.safe_limit_zz_th;
3685
0
    scs->mrp_ctrls.only_l_bwd               = tmp.only_l_bwd;
3686
0
    scs->mrp_ctrls.pme_ref0_only            = tmp.pme_ref0_only;
3687
0
    scs->mrp_ctrls.use_best_references      = tmp.use_best_references;
3688
0
}
3689
3690
static uint8_t get_tpl(uint8_t pred_structure, uint8_t superres_mode, uint8_t resize_mode, uint8_t aq_mode,
3691
604
                       bool allintra) {
3692
604
    if (allintra) {
3693
604
        SVT_WARN("TPL is disabled for all-intra coding\n");
3694
604
        return 0;
3695
604
    } else if (aq_mode == 0) {
3696
0
        SVT_WARN("TPL is disabled for aq_mode 0\n");
3697
0
        return 0;
3698
0
    } else if (pred_structure == LOW_DELAY) {
3699
0
        SVT_WARN("TPL is disabled in low delay applications.\n");
3700
0
        return 0;
3701
0
    }
3702
    // allow TPL with auto-dual and auto-all
3703
0
    else if (superres_mode > SUPERRES_NONE && superres_mode != SUPERRES_AUTO && superres_mode != SUPERRES_QTHRESH) {
3704
0
        SVT_WARN("TPL will be disabled when super resolution is enabled!\n");
3705
0
        return 0;
3706
0
    } else if (resize_mode > RESIZE_NONE) {
3707
0
        SVT_WARN("TPL will be disabled when reference scalings (resize) is enabled!\n");
3708
0
        return 0;
3709
0
    } else {
3710
0
        return 1;
3711
0
    }
3712
604
}
3713
3714
/*
3715
* Set multi Pass Params
3716
*/
3717
604
void set_multi_pass_params(SequenceControlSet* scs) {
3718
604
    EbSvtAv1EncConfiguration* config = &scs->static_config;
3719
3720
    // Update passes
3721
604
    if (scs->static_config.pass != ENC_SINGLE_PASS) {
3722
0
        scs->passes = MAX_ENCODE_PASS;
3723
604
    } else {
3724
604
        scs->passes = 1;
3725
604
    }
3726
3727
604
    switch (config->pass) {
3728
604
    case ENC_SINGLE_PASS: {
3729
604
        scs->first_pass_downsample = false;
3730
604
        scs->final_pass_preset     = config->enc_mode;
3731
604
        break;
3732
0
    }
3733
0
    case ENC_FIRST_PASS: {
3734
0
        scs->first_pass_downsample = config->enc_mode > ENC_M8;
3735
0
        scs->final_pass_preset     = config->enc_mode;
3736
0
        if (scs->final_pass_preset <= ENC_M6) {
3737
0
            scs->static_config.enc_mode = ENC_M9;
3738
0
        } else {
3739
0
            scs->static_config.enc_mode = MAX_ENC_PRESET;
3740
0
        }
3741
0
        scs->static_config.rate_control_mode  = SVT_AV1_RC_MODE_CQP_OR_CRF;
3742
0
        scs->static_config.qp                 = 43;
3743
0
        scs->static_config.intra_refresh_type = SVT_AV1_KF_REFRESH;
3744
0
        scs->static_config.max_bit_rate       = 0;
3745
0
        break;
3746
0
    }
3747
0
    case ENC_SECOND_PASS: {
3748
0
        scs->final_pass_preset                = config->enc_mode;
3749
0
        scs->static_config.intra_refresh_type = SVT_AV1_KF_REFRESH;
3750
0
        break;
3751
0
    }
3752
0
    default: {
3753
0
        assert(0);
3754
0
        break;
3755
0
    }
3756
604
    }
3757
3758
604
    int do_downsample = scs->first_pass_downsample && scs->max_input_luma_width >= 128 &&
3759
0
            scs->max_input_luma_height >= 128
3760
604
        ? 1
3761
604
        : 0;
3762
3763
604
    if (do_downsample) {
3764
        // To make sure the down scaled video has width and height of multiple of 2
3765
0
        scs->max_input_luma_width  = (scs->max_input_luma_width >> 2) << 1;
3766
0
        scs->max_input_luma_height = (scs->max_input_luma_height >> 2) << 1;
3767
0
    }
3768
3769
604
    if (scs->lap_rc) {
3770
0
        scs->static_config.intra_refresh_type = SVT_AV1_KF_REFRESH;
3771
0
    }
3772
604
    if (scs->static_config.pass == ENC_FIRST_PASS && scs->final_pass_preset > ENC_M6) {
3773
0
        scs->rc_stat_gen_pass_mode = 1;
3774
604
    } else {
3775
604
        scs->rc_stat_gen_pass_mode = 0;
3776
604
    }
3777
3778
604
    if (scs->static_config.recode_loop > 0 &&
3779
604
        ((scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF && scs->static_config.max_bit_rate == 0) ||
3780
604
         (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR && !scs->static_config.rtc))) {
3781
        // Only allow re-encoding for VBR, RTC CBR or capped CRF, otherwise force recode_loop to DISALLOW_RECODE
3782
604
        scs->static_config.recode_loop = DISALLOW_RECODE;
3783
604
    } else if (scs->static_config.recode_loop == ALLOW_RECODE_DEFAULT) {
3784
        // capped CRF has reencde enabled for base layer frames for all presets
3785
0
        if (!scs->static_config.rate_control_mode && scs->static_config.max_bit_rate) {
3786
0
            scs->static_config.recode_loop = ALLOW_RECODE_KFARFGF;
3787
0
        } else {
3788
0
            scs->static_config.recode_loop = scs->static_config.enc_mode <= ENC_M3 ? ALLOW_RECODE_KFARFGF
3789
0
                                                                                   : ALLOW_RECODE_KFMAXBW;
3790
0
        }
3791
0
    }
3792
3793
604
    scs->enc_ctx->recode_loop = scs->static_config.recode_loop;
3794
604
}
3795
3796
604
static void validate_scaling_params(SequenceControlSet* scs) {
3797
604
    if (scs->static_config.superres_mode == SUPERRES_FIXED && scs->static_config.superres_denom == SCALE_NUMERATOR &&
3798
0
        scs->static_config.superres_kf_denom == SCALE_NUMERATOR) {
3799
0
        scs->static_config.superres_mode = SUPERRES_NONE;
3800
0
    }
3801
604
    if (scs->static_config.resize_mode == RESIZE_DYNAMIC) {
3802
0
        if (scs->static_config.pred_structure != LOW_DELAY || scs->static_config.pass != ENC_SINGLE_PASS ||
3803
0
            scs->static_config.rate_control_mode != SVT_AV1_RC_MODE_CBR) {
3804
0
            SVT_WARN("Resize dynamic mode only works at 1-pass CBR low delay mode!\n");
3805
0
            scs->static_config.resize_mode = RESIZE_NONE;
3806
0
        }
3807
0
    }
3808
604
    if (scs->static_config.superres_mode == SUPERRES_QTHRESH && scs->static_config.superres_qthres == MAX_QP_VALUE &&
3809
0
        scs->static_config.superres_kf_qthres == MAX_QP_VALUE) {
3810
0
        scs->static_config.superres_mode = SUPERRES_NONE;
3811
0
    }
3812
604
    if (scs->static_config.resize_mode == RESIZE_FIXED && scs->static_config.resize_denom == SCALE_NUMERATOR &&
3813
0
        scs->static_config.resize_kf_denom == SCALE_NUMERATOR) {
3814
0
        scs->static_config.resize_mode = RESIZE_NONE;
3815
0
    }
3816
604
}
3817
3818
0
void set_qp_based_th_scaling_ctrls_default(SequenceControlSet* scs) {
3819
0
    QpBasedThScaling* qp_ctrls = &scs->qp_based_th_scaling_ctrls;
3820
0
    const EncMode     enc_mode = SVT_ENC_MODE(scs->static_config.enc_mode);
3821
3822
0
    if (enc_mode <= ENC_MR) {
3823
0
        qp_ctrls->tf_me_qp_based_th_scaling        = 0;
3824
0
        qp_ctrls->tf_ref_qp_based_th_scaling       = 0;
3825
0
        qp_ctrls->depths_qp_based_th_scaling       = 0;
3826
0
        qp_ctrls->hme_qp_based_th_scaling          = 0;
3827
0
        qp_ctrls->me_qp_based_th_scaling           = 0;
3828
0
        qp_ctrls->nsq_qp_based_th_scaling          = 0;
3829
0
        qp_ctrls->nic_max_qp_based_th_scaling      = 0;
3830
0
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 0;
3831
0
        qp_ctrls->pme_qp_based_th_scaling          = 0;
3832
0
        qp_ctrls->txt_qp_based_th_scaling          = 0;
3833
0
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3834
0
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3835
0
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3836
0
    } else {
3837
0
        qp_ctrls->tf_me_qp_based_th_scaling        = 1;
3838
0
        qp_ctrls->tf_ref_qp_based_th_scaling       = 1;
3839
0
        qp_ctrls->depths_qp_based_th_scaling       = 1;
3840
0
        qp_ctrls->hme_qp_based_th_scaling          = 1;
3841
0
        qp_ctrls->me_qp_based_th_scaling           = 1;
3842
0
        qp_ctrls->nsq_qp_based_th_scaling          = 1;
3843
0
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3844
0
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3845
0
        qp_ctrls->pme_qp_based_th_scaling          = 1;
3846
0
        qp_ctrls->txt_qp_based_th_scaling          = 1;
3847
0
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3848
0
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3849
0
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3850
0
    }
3851
0
}
3852
3853
0
void set_qp_based_th_scaling_ctrls_rtc(SequenceControlSet* scs) {
3854
0
    QpBasedThScaling* qp_ctrls                 = &scs->qp_based_th_scaling_ctrls;
3855
0
    qp_ctrls->tf_me_qp_based_th_scaling        = 1;
3856
0
    qp_ctrls->tf_ref_qp_based_th_scaling       = 1;
3857
0
    qp_ctrls->depths_qp_based_th_scaling       = 1;
3858
0
    qp_ctrls->hme_qp_based_th_scaling          = 1;
3859
0
    qp_ctrls->me_qp_based_th_scaling           = 1;
3860
0
    qp_ctrls->nsq_qp_based_th_scaling          = 1;
3861
0
    qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3862
0
    qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3863
0
    qp_ctrls->pme_qp_based_th_scaling          = 1;
3864
0
    qp_ctrls->txt_qp_based_th_scaling          = 1;
3865
0
    qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3866
0
    qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3867
0
    qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3868
0
}
3869
3870
604
void set_qp_based_th_scaling_ctrls_all_intra(SequenceControlSet* scs) {
3871
604
    QpBasedThScaling* qp_ctrls = &scs->qp_based_th_scaling_ctrls;
3872
604
    const EncMode     enc_mode = SVT_ENC_MODE(scs->static_config.enc_mode);
3873
3874
604
    if (enc_mode <= ENC_MR) {
3875
0
        qp_ctrls->tf_me_qp_based_th_scaling        = 0;
3876
0
        qp_ctrls->tf_ref_qp_based_th_scaling       = 0;
3877
0
        qp_ctrls->depths_qp_based_th_scaling       = 0;
3878
0
        qp_ctrls->hme_qp_based_th_scaling          = 0;
3879
0
        qp_ctrls->me_qp_based_th_scaling           = 0;
3880
0
        qp_ctrls->nsq_qp_based_th_scaling          = 0;
3881
0
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3882
0
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3883
0
        qp_ctrls->pme_qp_based_th_scaling          = 0;
3884
0
        qp_ctrls->txt_qp_based_th_scaling          = 1;
3885
0
        qp_ctrls->cap_max_size_qp_based_th_scaling = 0;
3886
0
        qp_ctrls->lpd0_qp_based_th_scaling         = 0;
3887
0
        qp_ctrls->intra_bc_mesh_qp_scaling         = 0;
3888
604
    } else if (enc_mode <= ENC_M3) {
3889
0
        qp_ctrls->tf_me_qp_based_th_scaling        = 0;
3890
0
        qp_ctrls->tf_ref_qp_based_th_scaling       = 0;
3891
0
        qp_ctrls->depths_qp_based_th_scaling       = 0;
3892
0
        qp_ctrls->hme_qp_based_th_scaling          = 0;
3893
0
        qp_ctrls->me_qp_based_th_scaling           = 0;
3894
0
        qp_ctrls->nsq_qp_based_th_scaling          = 0;
3895
0
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3896
0
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3897
0
        qp_ctrls->pme_qp_based_th_scaling          = 0;
3898
0
        qp_ctrls->txt_qp_based_th_scaling          = 1;
3899
0
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3900
0
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3901
0
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3902
0
    }
3903
3904
604
    else if (enc_mode <= ENC_M6) {
3905
0
        qp_ctrls->tf_me_qp_based_th_scaling        = 0;
3906
0
        qp_ctrls->tf_ref_qp_based_th_scaling       = 0;
3907
0
        qp_ctrls->depths_qp_based_th_scaling       = 0;
3908
0
        qp_ctrls->hme_qp_based_th_scaling          = 0;
3909
0
        qp_ctrls->me_qp_based_th_scaling           = 0;
3910
0
        qp_ctrls->nsq_qp_based_th_scaling          = 1;
3911
0
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3912
0
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3913
0
        qp_ctrls->pme_qp_based_th_scaling          = 0;
3914
0
        qp_ctrls->txt_qp_based_th_scaling          = 1;
3915
0
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3916
0
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3917
0
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3918
604
    } else {
3919
604
        qp_ctrls->tf_me_qp_based_th_scaling        = 1;
3920
604
        qp_ctrls->tf_ref_qp_based_th_scaling       = 1;
3921
604
        qp_ctrls->depths_qp_based_th_scaling       = 1;
3922
604
        qp_ctrls->hme_qp_based_th_scaling          = 1;
3923
604
        qp_ctrls->me_qp_based_th_scaling           = 1;
3924
604
        qp_ctrls->nsq_qp_based_th_scaling          = 1;
3925
604
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3926
604
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3927
604
        qp_ctrls->pme_qp_based_th_scaling          = 1;
3928
604
        qp_ctrls->txt_qp_based_th_scaling          = 1;
3929
604
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3930
604
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3931
604
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3932
604
    }
3933
604
}
3934
3935
604
static void set_param_based_on_input(SequenceControlSet* scs) {
3936
604
    const bool allintra = scs->allintra;
3937
604
    const bool rtc_tune = scs->static_config.rtc;
3938
604
    set_multi_pass_params(scs);
3939
3940
    // superres_mode and resize_mode may be updated,
3941
    // so should call get_tpl_level() after validate_scaling_params()
3942
604
    validate_scaling_params(scs);
3943
604
    scs->tpl               = get_tpl(scs->static_config.pred_structure,
3944
604
                                     scs->static_config.superres_mode,
3945
604
                                     scs->static_config.resize_mode,
3946
604
                                     scs->static_config.aq_mode,
3947
604
                                     allintra);
3948
604
    uint16_t subsampling_x = scs->subsampling_x;
3949
604
    uint16_t subsampling_y = scs->subsampling_y;
3950
    // Update picture width, and picture height
3951
604
    if (scs->max_input_luma_width % MIN_BLOCK_SIZE) {
3952
488
        scs->max_input_pad_right  = MIN_BLOCK_SIZE - (scs->max_input_luma_width % MIN_BLOCK_SIZE);
3953
488
        scs->max_input_luma_width = scs->max_input_luma_width + scs->max_input_pad_right;
3954
488
    } else {
3955
116
        scs->max_input_pad_right = 0;
3956
116
    }
3957
3958
604
    if (scs->max_input_luma_height % MIN_BLOCK_SIZE) {
3959
489
        scs->max_input_pad_bottom  = MIN_BLOCK_SIZE - (scs->max_input_luma_height % MIN_BLOCK_SIZE);
3960
489
        scs->max_input_luma_height = scs->max_input_luma_height + scs->max_input_pad_bottom;
3961
489
    } else {
3962
115
        scs->max_input_pad_bottom = 0;
3963
115
    }
3964
604
    scs->max_initial_input_luma_width  = scs->max_input_luma_width;
3965
604
    scs->max_initial_input_luma_height = scs->max_input_luma_height;
3966
604
    scs->max_initial_input_pad_bottom  = scs->max_input_pad_bottom;
3967
604
    scs->max_initial_input_pad_right   = scs->max_input_pad_right;
3968
3969
604
    scs->chroma_width  = scs->max_input_luma_width >> subsampling_x;
3970
604
    scs->chroma_height = scs->max_input_luma_height >> subsampling_y;
3971
3972
604
    scs->static_config.source_width  = scs->max_input_luma_width;
3973
604
    scs->static_config.source_height = scs->max_input_luma_height;
3974
604
    if (scs->static_config.superres_mode > SUPERRES_NONE) {
3975
0
        if (scs->static_config.tile_rows || scs->static_config.tile_columns) {
3976
            // disable tiles if super-res is on
3977
0
            SVT_WARN("Tiles will be disabled when super resolution is enabled!\n");
3978
0
            scs->static_config.tile_rows    = 0;
3979
0
            scs->static_config.tile_columns = 0;
3980
0
        }
3981
0
        if (scs->static_config.superres_mode == SUPERRES_RANDOM) {
3982
0
            SVT_WARN(
3983
0
                "Super resolution random mode is designed for test and debugging purpose,\n"
3984
0
                "it creates array of picture buffers for all scaling denominators (up to 8) of each reference frame.\n"
3985
0
                "This mode retains a significant amount of memory, much more than other modes!\n");
3986
0
        }
3987
0
    }
3988
604
    if (scs->static_config.resize_mode > RESIZE_NONE) {
3989
0
        if (scs->static_config.tile_rows || scs->static_config.tile_columns) {
3990
            // disable tiles if resize is on
3991
0
            SVT_WARN("Tiles will be disabled when resize is enabled!\n");
3992
0
            scs->static_config.tile_rows    = 0;
3993
0
            scs->static_config.tile_columns = 0;
3994
0
        }
3995
0
        if (scs->static_config.resize_mode == RESIZE_RANDOM) {
3996
0
            SVT_WARN(
3997
0
                "Resize random mode is designed for test and debugging purpose,\n"
3998
0
                "it creates array of picture buffers for all scaling denominators (up to 8) of each reference frame.\n"
3999
0
                "This mode retains a significant amount of memory, much more than other modes!\n");
4000
0
        }
4001
0
    }
4002
    // Set initial qp for vbr and middle pass
4003
604
    if ((scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR) || (scs->static_config.pass == ENC_FIRST_PASS)) {
4004
0
        if (scs->static_config.qp != DEFAULT_QP) {
4005
0
            SVT_WARN("The input q value is ignored in vbr mode %d\n", scs->static_config.qp);
4006
0
        }
4007
0
        const uint8_t  tbr_bands[5]    = {1, 2, 4, 6, 8};
4008
0
        const uint64_t src_samples     = (uint64_t)(scs->seq_header.max_frame_width * scs->seq_header.max_frame_height);
4009
0
        const uint64_t target_bit_rate = (uint64_t)((double)scs->static_config.target_bit_rate * 60.0 /
4010
0
                                                    (scs->frame_rate * (double)src_samples));
4011
0
        if (target_bit_rate < tbr_bands[0]) {
4012
0
            scs->static_config.qp = 55;
4013
0
        } else if (target_bit_rate < tbr_bands[1]) {
4014
0
            scs->static_config.qp = 50;
4015
0
        } else if (target_bit_rate < tbr_bands[2]) {
4016
0
            scs->static_config.qp = 45;
4017
0
        } else if (target_bit_rate < tbr_bands[3]) {
4018
0
            scs->static_config.qp = 40;
4019
0
        } else if (target_bit_rate < tbr_bands[4]) {
4020
0
            scs->static_config.qp = 35;
4021
0
        } else {
4022
0
            scs->static_config.qp = 30;
4023
0
        }
4024
0
    }
4025
604
    svt_aom_derive_input_resolution(&scs->input_resolution, scs->max_input_luma_width * scs->max_input_luma_height);
4026
4027
604
    scs->seq_qp_mod = 2;
4028
4029
604
    (allintra       ? set_qp_based_th_scaling_ctrls_all_intra
4030
604
         : rtc_tune ? set_qp_based_th_scaling_ctrls_rtc
4031
0
                    : set_qp_based_th_scaling_ctrls_default)(scs);
4032
4033
    // Set tune params
4034
604
    derive_vq_params(scs);
4035
4036
    // Set TF level
4037
604
    derive_tf_params(scs);
4038
4039
    //Future frames window in Scene Change Detection (SCD) / TemporalFiltering
4040
604
    scs->scd_delay = 0;
4041
4042
    // Update the scd_delay based on the the number of future frames @ ISLICE
4043
    // This case is needed for non-delayed Intra (intra_period_length == 0)
4044
604
    uint32_t scd_delay_islice = 0;
4045
604
    if (scs->static_config.intra_period_length == 0) {
4046
604
        if (scs->tf_params_per_type[0].enabled) {
4047
0
            scd_delay_islice = MIN(
4048
0
                scs->tf_params_per_type[0].num_future_pics +
4049
0
                    (scs->tf_params_per_type[0].modulate_pics
4050
0
                         ? TF_MAX_EXTENSION
4051
0
                         : 0), // number of future picture(s) used for ISLICE + max picture(s) after noise-based adjustement (=6)
4052
0
                scs->tf_params_per_type[0].max_num_future_pics);
4053
0
        }
4054
604
    }
4055
4056
    // Update the scd_delay based on the the number of future frames @ BASE
4057
604
    uint32_t scd_delay_base = 0;
4058
604
    if (scs->tf_params_per_type[1].enabled) {
4059
0
        scd_delay_base = MIN(
4060
0
            scs->tf_params_per_type[1].num_future_pics +
4061
0
                (scs->tf_params_per_type[1].modulate_pics
4062
0
                     ? TF_MAX_EXTENSION
4063
0
                     : 0), // number of future picture(s) used for BASE + max picture(s) after filtered adjustement (=3)
4064
0
            scs->tf_params_per_type[1].max_num_future_pics);
4065
0
    }
4066
604
    scs->scd_delay = MAX(scd_delay_islice, scd_delay_base);
4067
    // Update the scd_delay based on SCD, 1first pass
4068
    // Delay needed for SCD , 1first pass of (2pass and 1pass VBR)
4069
604
    if (scs->static_config.scene_change_detection || scs->vq_ctrls.sharpness_ctrls.scene_transition || scs->lap_rc) {
4070
0
        scs->scd_delay = MAX(scs->scd_delay, 2);
4071
0
    }
4072
4073
    // no future minigop is used for lowdelay prediction structure
4074
604
    if (allintra || scs->static_config.pred_structure == LOW_DELAY) {
4075
604
        scs->lad_mg = scs->tpl_lad_mg = 0;
4076
604
    } else {
4077
0
        uint8_t tpl_lad_mg =
4078
0
            1; // Specify the number of mini-gops to be used as LAD. 0: 1 mini-gop, 1: 2 mini-gops and 3: 3 mini-gops
4079
0
        uint32_t mg_size = 1 << scs->static_config.hierarchical_levels;
4080
        // If the lookahead is specified to be less than one mini-gop, then use only the current mini-gop for TPL (the current MG is always required to encode).
4081
        // Otherwise, set tpl_lad_mg to 1 when TPL is used, regardless of the specified lookahead, because TPL has been optimized to use 1 MG lookahead. Using
4082
        // more lookahead MGs may result in disadvantageous trade-offs (speed/BDR/memory).
4083
0
        if (scs->static_config.look_ahead_distance < mg_size) {
4084
0
            tpl_lad_mg = 0;
4085
0
        } else if (scs->tpl) {
4086
0
            tpl_lad_mg = 1;
4087
0
        } else {
4088
0
            tpl_lad_mg = 0;
4089
0
        }
4090
4091
        // special conditions for higher resolutions in order to decrease memory usage for tpl_lad_mg
4092
0
        if (scs->input_resolution >= INPUT_SIZE_8K_RANGE) {
4093
0
            tpl_lad_mg = 0;
4094
0
        }
4095
0
        scs->tpl_lad_mg = MIN(
4096
0
            2, tpl_lad_mg); // lad_mg is capped to 2 because tpl was optimised only for 1,2 and 3 mini-gops
4097
0
        if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
4098
0
            scs->lad_mg = scs->tpl_lad_mg;
4099
0
        } else {
4100
            // update the look ahead size
4101
0
            update_look_ahead(scs);
4102
0
        }
4103
0
    }
4104
    // when resize mode is used, use sb 64 because of a r2r when 128 is used
4105
    // In low delay mode, sb size is set to 64
4106
    // in 240P resolution, sb size is set to 64
4107
604
    if ((scs->static_config.fast_decode && scs->static_config.qp <= 56 &&
4108
0
         !(scs->input_resolution <= INPUT_SIZE_360p_RANGE)) ||
4109
604
        scs->static_config.resize_mode > RESIZE_NONE || scs->static_config.rtc ||
4110
604
        (scs->input_resolution == INPUT_SIZE_240p_RANGE) || scs->static_config.enable_variance_boost) {
4111
604
        scs->super_block_size = 64;
4112
604
    } else if (allintra) {
4113
0
        if (scs->static_config.enc_mode <= ENC_M1) {
4114
0
            scs->super_block_size = 128;
4115
0
        } else {
4116
0
            scs->super_block_size = 64;
4117
0
        }
4118
0
    } else if (scs->static_config.enc_mode <= ENC_MR) {
4119
0
        scs->super_block_size = 128;
4120
0
    } else if (scs->static_config.enc_mode <= ENC_M5) {
4121
0
        if (scs->static_config.qp <= 57) {
4122
0
            scs->super_block_size = 64;
4123
0
        } else {
4124
0
            scs->super_block_size = 128;
4125
0
        }
4126
0
    } else {
4127
0
        scs->super_block_size = 64;
4128
0
    }
4129
    // When switch frame is on, all renditions must have same super block size. See spec 5.5.1, 5.9.15.
4130
604
    if (scs->static_config.sframe_dist != 0 || scs->static_config.sframe_posi.sframe_posis) {
4131
0
        scs->super_block_size = 64;
4132
0
    }
4133
    // Set config info related to SB size
4134
604
    if (scs->super_block_size == 128) {
4135
0
        scs->seq_header.sb_size      = BLOCK_128X128;
4136
0
        scs->sb_size                 = 128;
4137
0
        scs->seq_header.sb_mi_size   = 32; // Size of the superblock in units of MI blocks
4138
0
        scs->seq_header.sb_size_log2 = 5;
4139
604
    } else {
4140
604
        scs->seq_header.sb_size      = BLOCK_64X64;
4141
604
        scs->sb_size                 = 64;
4142
604
        scs->seq_header.sb_mi_size   = 16; // Size of the superblock in units of MI blocks
4143
604
        scs->seq_header.sb_size_log2 = 4;
4144
604
    }
4145
4146
604
    if (scs->static_config.enable_variance_boost && scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR) {
4147
0
        scs->static_config.enable_variance_boost = false;
4148
0
        SVT_WARN("Variance Boost is incompatible with CBR rate control, disabling Variance Boost\n");
4149
0
    }
4150
604
    if (scs->static_config.enable_variance_boost && scs->static_config.aq_mode == 1) {
4151
0
        scs->static_config.enable_variance_boost = false;
4152
0
        SVT_WARN("Variance AQ based on segmentation with Variance Boost not supported, disabling Variance Boost\n");
4153
0
    }
4154
604
    if (scs->static_config.variance_boost_strength >= 4) {
4155
0
        SVT_WARN(
4156
0
            "Aggressive Variance Boost strength used. This is a curve that's only useful under specific situations. "
4157
0
            "Use with caution!\n");
4158
0
    }
4159
604
    if (scs->static_config.max_tx_size == 32 && scs->static_config.qp >= 25 && scs->static_config.tune != 3) {
4160
0
        SVT_WARN(
4161
0
            "Restricting transform sizes to a max of 32x32 might reduce coding efficiency at low to medium fidelity "
4162
0
            "settings. Use with caution!\n");
4163
0
    }
4164
604
    if (scs->static_config.intra_refresh_type == SVT_AV1_FWDKF_REFRESH && scs->static_config.hierarchical_levels != 4) {
4165
0
        scs->static_config.hierarchical_levels = 4;
4166
0
        SVT_WARN(
4167
0
            "Fwd key frame is only supported for hierarchical levels 4 at this point. Hierarchical levels are set to "
4168
0
            "4\n");
4169
0
    }
4170
604
    bool    disallow_nsq  = true;
4171
604
    uint8_t allow_HVA_HVB = 0;
4172
604
    uint8_t allow_HV4     = 0;
4173
604
    uint8_t h_v_only      = 1;
4174
604
    uint8_t min_nsq_bsize = 0;
4175
604
    uint8_t no_8x4_4x8    = 1;
4176
604
    uint8_t no_16x8_8x16  = 1;
4177
3.62k
    for (uint8_t coeff_lvl = 0; coeff_lvl <= HIGH_LVL + 1; coeff_lvl++) {
4178
3.02k
        uint8_t nsq_geom_level;
4179
3.02k
        if (scs->allintra) {
4180
3.02k
            nsq_geom_level = svt_aom_get_nsq_geom_level_allintra(scs->static_config.enc_mode);
4181
3.02k
        } else if (scs->static_config.rtc) {
4182
0
            nsq_geom_level = svt_aom_get_nsq_geom_level_rtc();
4183
0
        } else {
4184
0
            nsq_geom_level = svt_aom_get_nsq_geom_level_default(scs->static_config.enc_mode, coeff_lvl);
4185
0
        }
4186
3.02k
        disallow_nsq               = MIN(disallow_nsq, nsq_geom_level == 0);
4187
3.02k
        uint8_t temp_allow_HVA_HVB = 0, temp_allow_HV4 = 0;
4188
3.02k
        svt_aom_set_nsq_geom_ctrls(NULL, nsq_geom_level, &temp_allow_HVA_HVB, &temp_allow_HV4, &min_nsq_bsize);
4189
3.02k
        allow_HVA_HVB |= temp_allow_HVA_HVB;
4190
3.02k
        allow_HV4 |= temp_allow_HV4;
4191
3.02k
        h_v_only     = h_v_only && !allow_HVA_HVB && !allow_HV4;
4192
3.02k
        no_8x4_4x8   = no_8x4_4x8 && min_nsq_bsize >= 8;
4193
3.02k
        no_16x8_8x16 = no_16x8_8x16 && min_nsq_bsize >= 16;
4194
3.02k
    }
4195
4196
604
    bool disallow_8x8;
4197
604
    bool disallow_4x4;
4198
604
    if (scs->allintra) {
4199
604
        disallow_4x4 = svt_aom_get_disallow_4x4_allintra(scs->static_config.enc_mode);
4200
604
        disallow_8x8 = svt_aom_get_disallow_8x8_allintra();
4201
604
    } else if (scs->static_config.rtc) {
4202
0
        disallow_4x4 = svt_aom_get_disallow_4x4_rtc();
4203
0
        disallow_8x8 = svt_aom_get_disallow_8x8_rtc(
4204
0
            scs->static_config.enc_mode, scs->max_input_luma_width, scs->max_input_luma_height);
4205
0
    } else {
4206
0
        disallow_4x4 = svt_aom_get_disallow_4x4_default(scs->static_config.enc_mode);
4207
0
        disallow_8x8 = svt_aom_get_disallow_8x8_default();
4208
0
    }
4209
604
    if (scs->super_block_size == 128) {
4210
0
        if (!allow_HVA_HVB && disallow_4x4) {
4211
0
            scs->svt_aom_geom_idx = GEOM_10;
4212
0
            scs->max_block_cnt    = 2377;
4213
0
        } else {
4214
0
            scs->svt_aom_geom_idx = GEOM_9;
4215
0
            scs->max_block_cnt    = 4421;
4216
0
        }
4217
604
    } else {
4218
        //SB 64x64
4219
604
        if (disallow_nsq && disallow_4x4 && disallow_8x8) {
4220
0
            scs->svt_aom_geom_idx = GEOM_0;
4221
0
            scs->max_block_cnt    = 21;
4222
604
        } else if (h_v_only && disallow_4x4 && disallow_8x8 && no_16x8_8x16) {
4223
0
            scs->svt_aom_geom_idx = GEOM_1;
4224
0
            scs->max_block_cnt    = 41;
4225
604
        } else if (disallow_nsq && disallow_4x4) {
4226
604
            scs->svt_aom_geom_idx = GEOM_2;
4227
604
            scs->max_block_cnt    = 85;
4228
604
        } else if (h_v_only && disallow_4x4 && no_16x8_8x16) {
4229
0
            scs->svt_aom_geom_idx = GEOM_3;
4230
0
            scs->max_block_cnt    = 105;
4231
0
        } else if (h_v_only && disallow_4x4 && no_8x4_4x8) {
4232
0
            scs->svt_aom_geom_idx = GEOM_4;
4233
0
            scs->max_block_cnt    = 169;
4234
0
        } else if (h_v_only && disallow_4x4) {
4235
0
            scs->svt_aom_geom_idx = GEOM_5;
4236
0
            scs->max_block_cnt    = 425;
4237
0
        } else if (h_v_only) {
4238
0
            scs->svt_aom_geom_idx = GEOM_6;
4239
0
            scs->max_block_cnt    = 681;
4240
0
        } else if (!allow_HVA_HVB) {
4241
0
            scs->svt_aom_geom_idx = GEOM_7;
4242
0
            scs->max_block_cnt    = 849;
4243
0
        } else {
4244
0
            scs->svt_aom_geom_idx = GEOM_8;
4245
0
            scs->max_block_cnt    = 1101;
4246
0
        }
4247
604
    }
4248
    // Configure the padding
4249
604
    scs->border = BLOCK_SIZE_64 + 4;
4250
4251
    //for 10bit,  increase the pad of source from 68 to 72 (mutliple of 8) to accomodate 2bit-compression flow
4252
    //we actually need to change the horizontal dimension only, but for simplicity/uniformity we do all directions
4253
    // if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) != EB_EIGHT_BIT)
4254
604
    { scs->border += 4; }
4255
4256
604
    scs->static_config.enable_overlays = !scs->static_config.enable_tf ||
4257
0
            (scs->static_config.rate_control_mode != SVT_AV1_RC_MODE_CQP_OR_CRF)
4258
604
        ? 0
4259
604
        : scs->static_config.enable_overlays;
4260
4261
    // Enforce starting frame in decode order (at PicMgr)
4262
    // Does not wait for feedback from PKT
4263
604
    if (scs->static_config.level_of_parallelism == 1 || scs->static_config.pred_structure == LOW_DELAY) {
4264
0
        scs->enable_pic_mgr_dec_order = 1;
4265
604
    } else {
4266
604
        scs->enable_pic_mgr_dec_order = 0;
4267
604
    }
4268
    // Enforce encoding frame in decode order
4269
    // Wait for feedback from PKT
4270
#if RC_NO_R2R
4271
    scs->enable_dec_order = 1;
4272
#else
4273
604
    if (scs->static_config.level_of_parallelism == 1 || scs->static_config.pred_structure == LOW_DELAY) {
4274
0
        scs->enable_dec_order = 1;
4275
604
    } else {
4276
604
        scs->enable_dec_order = 0;
4277
604
    }
4278
604
#endif
4279
    // 1: Use boundary pixels in restoration filter search.
4280
    // 0: Do not use boundary pixels in the restoration filter search.
4281
604
    scs->use_boundaries_in_rest_search = 0;
4282
4283
604
    svt_aom_set_mfmv_config(scs, scs->static_config.enc_mode);
4284
4285
604
    scs->list0_only_base = scs->static_config.enc_mode > ENC_M2;
4286
4287
604
    if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR ||
4288
604
        scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR || scs->input_resolution >= INPUT_SIZE_4K_RANGE ||
4289
604
        scs->static_config.pred_structure != RANDOM_ACCESS || scs->static_config.pass != ENC_SINGLE_PASS) {
4290
604
        scs->enable_dg = 0;
4291
604
    } else {
4292
0
        scs->enable_dg = scs->static_config.enable_dg;
4293
0
    }
4294
    // Set hbd_md OFF for high encode modes or bitdepth < 10
4295
604
    if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) < 10) {
4296
604
        scs->enable_hbd_mode_decision = 0;
4297
604
    }
4298
4299
    // Throws a warning when scene change is on, as the feature is not optimal and may produce false detections
4300
604
    if (scs->static_config.scene_change_detection == 1) {
4301
0
        SVT_WARN("Scene Change is not optimal and may produce suboptimal keyframe placements\n");
4302
0
    }
4303
604
    set_mrp_ctrl(scs, &scs->mrp_ctrls, scs->static_config.enc_mode);
4304
4305
    // Snapshot; PRESET_CHANGE_EVENT clamps against this.
4306
604
    scs->mrp_ctrls_init = scs->mrp_ctrls;
4307
    // set to 1 if multipass and less than 200 frames in resourcecordination
4308
604
    scs->is_short_clip = scs->static_config.gop_constraint_rc ? 1 : 0;
4309
604
    if (allintra || scs->static_config.aq_mode == 1 || scs->static_config.scene_change_detection == 1 ||
4310
604
        scs->vq_ctrls.sharpness_ctrls.tf == 1 || scs->static_config.enable_variance_boost || scs->static_config.rtc) {
4311
604
        scs->calculate_variance = 1;
4312
604
    } else {
4313
0
        scs->calculate_variance = 0;
4314
0
    }
4315
604
    if (allintra) {
4316
604
        scs->detect_luma_dominant_input = false;
4317
604
    } else {
4318
0
        scs->detect_luma_dominant_input = true;
4319
0
    }
4320
604
    scs->resize_pending_params.resize_state = ORIG;
4321
604
    scs->resize_pending_params.resize_denom = SCALE_NUMERATOR;
4322
4323
604
    scs->stats_based_sb_lambda_modulation = (scs->static_config.enc_mode <= (rtc_tune ? ENC_M10 : ENC_M11)) ? 1 : 0;
4324
4325
604
    scs->fast_aa_aware_screen_detection_mode = (scs->static_config.enc_mode >= ENC_M3) ? 1 : 0;
4326
604
}
4327
4328
604
static void copy_api_from_app(SequenceControlSet* scs, EbSvtAv1EncConfiguration* config_struct) {
4329
604
    scs->max_input_luma_width  = config_struct->source_width;
4330
604
    scs->max_input_luma_height = config_struct->source_height;
4331
    // SB Definitions
4332
604
    scs->static_config.pred_structure = config_struct->pred_structure;
4333
604
    scs->static_config.rtc            = config_struct->rtc;
4334
604
    if (SVT_RTC_TUNE(scs) && scs->static_config.pred_structure != LOW_DELAY) {
4335
0
        scs->static_config.pred_structure = LOW_DELAY;
4336
0
        SVT_WARN("Forcing low delay pred structure for RTC.\n");
4337
0
    }
4338
604
    scs->enable_qp_scaling_flag = scs->allintra ? 0 : 1;
4339
    // Set Picture Parameters for statistics gathering
4340
604
    scs->picture_analysis_number_of_regions_per_width  = scs->max_input_luma_width >= 64
4341
604
        ? HIGHER_THAN_CLASS_1_REGION_SPLIT_PER_WIDTH
4342
604
        : 1;
4343
604
    scs->picture_analysis_number_of_regions_per_height = scs->max_input_luma_height >= 64
4344
604
        ? HIGHER_THAN_CLASS_1_REGION_SPLIT_PER_HEIGHT
4345
604
        : 1;
4346
4347
604
    scs->pic_based_rate_est   = false;
4348
604
    scs->block_mean_calc_prec = BLOCK_MEAN_PREC_SUB;
4349
604
    scs->speed_control_flag   = 0;
4350
    // Padding Offsets
4351
604
    scs->b64_size                          = 64;
4352
604
    scs->static_config.intra_period_length = config_struct->intra_period_length;
4353
604
    scs->static_config.avif                = config_struct->avif;
4354
604
    scs->allintra                          = (scs->static_config.intra_period_length == 0 || scs->static_config.avif ||
4355
0
                                              scs->static_config.pred_structure == ALL_INTRA);
4356
604
    if (scs->allintra) {
4357
604
        scs->static_config.pred_structure      = ALL_INTRA;
4358
604
        scs->static_config.intra_period_length = 0;
4359
604
    }
4360
604
    scs->static_config.multiply_keyint    = config_struct->multiply_keyint;
4361
604
    scs->static_config.intra_refresh_type = config_struct->intra_refresh_type;
4362
604
    scs->static_config.enc_mode           = config_struct->enc_mode;
4363
604
    if (scs->allintra) {
4364
604
        if (scs->static_config.enc_mode > ENC_M9) {
4365
604
            SVT_WARN("Preset M%d is mapped to M9.\n", scs->static_config.enc_mode);
4366
604
            scs->static_config.enc_mode = ENC_M9;
4367
604
        }
4368
604
    }
4369
4370
0
    else if (SVT_RTC_TUNE(scs)) {
4371
0
        if (scs->static_config.enc_mode > ENC_M13) {
4372
0
            SVT_WARN("Preset M%d is mapped to M13.\n", scs->static_config.enc_mode);
4373
0
            scs->static_config.enc_mode = ENC_M13;
4374
0
        }
4375
4376
0
        if (scs->static_config.enc_mode == ENC_M13) {
4377
0
            SVT_WARN("Preset M13 is experimental and intended for speed evaluation\n");
4378
0
        }
4379
0
    }
4380
4381
0
    else if (scs->static_config.enc_mode > ENC_M11) {
4382
0
        SVT_WARN("Preset M%d is mapped to M11.\n", scs->static_config.enc_mode);
4383
0
        scs->static_config.enc_mode = ENC_M11;
4384
0
    }
4385
4386
604
    ResolutionRange input_resolution;
4387
604
    svt_aom_derive_input_resolution(&input_resolution, scs->max_input_luma_width * scs->max_input_luma_height);
4388
604
    if (!scs->allintra && scs->static_config.pred_structure == RANDOM_ACCESS && scs->static_config.enc_mode > ENC_M9 &&
4389
0
        input_resolution >= INPUT_SIZE_4K_RANGE) {
4390
0
        scs->static_config.enc_mode = ENC_M9;
4391
0
        SVT_WARN(
4392
0
            "Setting preset to M9 as it is the highest supported preset for 4k and higher resolutions in Random Access "
4393
0
            "mode\n");
4394
0
    }
4395
4396
604
    scs->static_config.use_qp_file                    = config_struct->use_qp_file;
4397
604
    scs->static_config.use_fixed_qindex_offsets       = config_struct->use_fixed_qindex_offsets;
4398
604
    scs->static_config.key_frame_chroma_qindex_offset = config_struct->key_frame_chroma_qindex_offset;
4399
604
    scs->static_config.key_frame_qindex_offset        = config_struct->key_frame_qindex_offset;
4400
604
    if (scs->static_config.use_fixed_qindex_offsets) {
4401
0
        scs->enable_qp_scaling_flag    = scs->static_config.use_fixed_qindex_offsets == 1
4402
0
            ? 0
4403
0
            : 1; // do not shut the auto QPS if use_fixed_qindex_offsets 2
4404
0
        scs->static_config.use_qp_file = 0;
4405
0
        memcpy(scs->static_config.qindex_offsets, config_struct->qindex_offsets, MAX_TEMPORAL_LAYERS * sizeof(int32_t));
4406
0
    }
4407
604
    memcpy(scs->static_config.chroma_qindex_offsets,
4408
604
           config_struct->chroma_qindex_offsets,
4409
604
           MAX_TEMPORAL_LAYERS * sizeof(int32_t));
4410
4411
604
    scs->static_config.lossless = config_struct->lossless;
4412
604
    if (scs->static_config.lossless) {
4413
308
        scs->static_config.luma_y_dc_qindex_offset   = 0;
4414
308
        scs->static_config.chroma_u_dc_qindex_offset = 0;
4415
308
        scs->static_config.chroma_u_ac_qindex_offset = 0;
4416
308
        scs->static_config.chroma_v_dc_qindex_offset = 0;
4417
308
        scs->static_config.chroma_v_ac_qindex_offset = 0;
4418
308
    } else {
4419
296
        scs->static_config.luma_y_dc_qindex_offset   = config_struct->luma_y_dc_qindex_offset;
4420
296
        scs->static_config.chroma_u_dc_qindex_offset = config_struct->chroma_u_dc_qindex_offset;
4421
296
        scs->static_config.chroma_u_ac_qindex_offset = config_struct->chroma_u_ac_qindex_offset;
4422
296
        scs->static_config.chroma_v_dc_qindex_offset = config_struct->chroma_v_dc_qindex_offset;
4423
296
        scs->static_config.chroma_v_ac_qindex_offset = config_struct->chroma_v_ac_qindex_offset;
4424
296
    }
4425
604
    memcpy(scs->static_config.lambda_scale_factors,
4426
604
           config_struct->lambda_scale_factors,
4427
604
           SVT_AV1_FRAME_UPDATE_TYPES * sizeof(int32_t));
4428
4429
604
    scs->static_config.rc_stats_buffer = config_struct->rc_stats_buffer;
4430
604
    scs->static_config.pass            = config_struct->pass;
4431
    // Deblock Filter
4432
604
    scs->static_config.enable_dlf_flag = config_struct->enable_dlf_flag;
4433
4434
    // CDEF
4435
604
    scs->static_config.cdef_level = config_struct->cdef_level;
4436
4437
    // Intra Block Copy
4438
604
    scs->static_config.enable_intrabc = config_struct->enable_intrabc;
4439
4440
    // Restoration filtering
4441
604
    scs->static_config.enable_restoration_filtering = config_struct->enable_restoration_filtering;
4442
4443
    // motion field motion vector
4444
604
    scs->static_config.enable_mfmv = config_struct->enable_mfmv;
4445
4446
    // Dynamic GoP
4447
604
    scs->static_config.enable_dg = config_struct->enable_dg;
4448
4449
    // Decoder Optimization Flag
4450
604
    scs->static_config.fast_decode = config_struct->fast_decode;
4451
4452
    //Film Grain
4453
604
    scs->static_config.film_grain_denoise_strength = config_struct->film_grain_denoise_strength;
4454
604
    scs->static_config.film_grain_denoise_apply    = config_struct->film_grain_denoise_apply;
4455
604
    if (scs->static_config.film_grain_denoise_strength == 0 && scs->static_config.film_grain_denoise_apply == 1) {
4456
0
        SVT_WARN("Film grain denoise apply signal is going to be ignored when film grain is off.\n");
4457
0
    }
4458
604
    scs->seq_header.film_grain_params_present = (uint8_t)(CONFIG_ENABLE_FILM_GRAIN &&
4459
604
                                                          (scs->static_config.film_grain_denoise_strength > 0 ||
4460
604
                                                           config_struct->fgs_table != NULL));
4461
604
    scs->static_config.fgs_table              = config_struct->fgs_table;
4462
4463
    // MD Parameters
4464
604
    scs->enable_hbd_mode_decision = SVT_EFFECTIVE_BIT_DEPTH(config_struct->encoder_bit_depth) > 8 ? DEFAULT : 0;
4465
604
    {
4466
604
        if (config_struct->tile_rows == DEFAULT && config_struct->tile_columns == DEFAULT) {
4467
0
            scs->static_config.tile_rows    = 0;
4468
0
            scs->static_config.tile_columns = 0;
4469
4470
604
        } else {
4471
604
            if (config_struct->tile_rows == DEFAULT) {
4472
0
                scs->static_config.tile_rows    = 0;
4473
0
                scs->static_config.tile_columns = config_struct->tile_columns;
4474
604
            } else if (config_struct->tile_columns == DEFAULT) {
4475
0
                scs->static_config.tile_rows    = config_struct->tile_rows;
4476
0
                scs->static_config.tile_columns = 0;
4477
604
            } else {
4478
604
                scs->static_config.tile_rows    = config_struct->tile_rows;
4479
604
                scs->static_config.tile_columns = config_struct->tile_columns;
4480
604
            }
4481
604
        }
4482
604
    }
4483
4484
    // Rate Control
4485
604
    scs->static_config.scene_change_detection = config_struct->scene_change_detection;
4486
604
    if (config_struct->lossless && config_struct->rate_control_mode) {
4487
0
        scs->static_config.rate_control_mode = SVT_AV1_RC_MODE_CQP_OR_CRF;
4488
0
        SVT_WARN("Switched to CQP mode since lossless coding is enabled\n");
4489
604
    } else {
4490
604
        scs->static_config.rate_control_mode = config_struct->rate_control_mode;
4491
604
    }
4492
604
    if (scs->static_config.pass == ENC_SINGLE_PASS && SVT_RTC_TUNE(scs)) {
4493
0
        if (scs->static_config.enc_mode < ENC_M7) {
4494
0
            scs->static_config.enc_mode = ENC_M7;
4495
0
            SVT_WARN("rtc mode only supports presets [7-%d]. Forcing preset to 7.\n", ENC_M13);
4496
0
        }
4497
0
    }
4498
604
    scs->static_config.tune                = config_struct->tune;
4499
604
    scs->static_config.hierarchical_levels = config_struct->hierarchical_levels;
4500
4501
    // Set the default hierarchical levels
4502
604
    if (scs->static_config.hierarchical_levels == HIERARCHICAL_LEVELS_AUTO) {
4503
604
        scs->static_config.hierarchical_levels = scs->static_config.pred_structure == LOW_DELAY &&
4504
0
                (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR ||
4505
0
                 !(scs->static_config.enc_mode <= ENC_M9))
4506
604
            ? 2
4507
604
            : scs->static_config.pred_structure == LOW_DELAY ? 3
4508
604
            : scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR ||
4509
604
                scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR ||
4510
604
                (input_resolution >= INPUT_SIZE_1080p_RANGE && scs->static_config.enc_mode >= ENC_M8) ||
4511
604
                !(scs->static_config.enc_mode <= ENC_M8) || input_resolution >= INPUT_SIZE_8K_RANGE
4512
604
            ? 4
4513
604
            : 5;
4514
604
    }
4515
604
    if (scs->static_config.pass == ENC_SINGLE_PASS && scs->static_config.pred_structure == LOW_DELAY) {
4516
0
        if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR && scs->static_config.hierarchical_levels > 2) {
4517
0
            scs->static_config.hierarchical_levels = 2;
4518
0
            SVT_WARN("Low delay CBR supports hierarchical_levels [0-2]. Forced hierarchical_levels = 2.\n");
4519
0
        }
4520
0
    }
4521
    // Set hierarchical_levels to 2 to reduce memory allocation; 2 is the minimum currently supported
4522
604
    if (scs->allintra) {
4523
604
        scs->static_config.hierarchical_levels = 2;
4524
604
    }
4525
604
    scs->static_config.look_ahead_distance    = config_struct->look_ahead_distance;
4526
604
    scs->static_config.frame_rate_denominator = config_struct->frame_rate_denominator;
4527
604
    scs->static_config.frame_rate_numerator   = config_struct->frame_rate_numerator;
4528
4529
604
    scs->static_config.target_bit_rate = config_struct->target_bit_rate;
4530
604
    scs->static_config.max_bit_rate    = config_struct->max_bit_rate;
4531
    //TODO: check RC mode and set only when RC is enabled in the final version.
4532
604
    scs->static_config.aq_mode = scs->static_config.lossless ? 0 : config_struct->aq_mode;
4533
4534
    // TPL is disabled for allintra and LD encoding, and when aq_mode is 0
4535
604
    if (scs->static_config.max_bit_rate &&
4536
0
        (scs->static_config.aq_mode == 0 || scs->allintra || scs->static_config.pred_structure == LOW_DELAY)) {
4537
0
        scs->static_config.max_bit_rate = 0;
4538
0
        SVT_WARN("Maximum bit rate only supported with tpl on. max bit rate 0 is used instead.\n");
4539
0
    }
4540
4541
604
    scs->static_config.max_qp_allowed = scs->static_config.lossless ? MIN_QP_VALUE : config_struct->max_qp_allowed;
4542
4543
604
    scs->static_config.min_qp_allowed = scs->static_config.lossless ? MIN_QP_VALUE
4544
604
        : config_struct->min_qp_allowed == MIN_QP_AUTO ? scs->static_config.rate_control_mode ? 4 : MIN_QP_VALUE
4545
296
                                                       : config_struct->min_qp_allowed;
4546
    // The decoder codes a qindex-0 frame as lossless, which builds without lossless coding and RTC mode (no 8x8 blocks
4547
    // at M10+) cannot encode: keep qindex >= 4.
4548
604
    if (!CONFIG_ENABLE_LOSSLESS || SVT_RTC_TUNE(scs)) {
4549
0
        scs->static_config.min_qp_allowed = AOMMAX(scs->static_config.min_qp_allowed, 1);
4550
0
    }
4551
604
    scs->static_config.vbr_min_section_pct = config_struct->vbr_min_section_pct;
4552
604
    scs->static_config.vbr_max_section_pct = config_struct->vbr_max_section_pct;
4553
604
    scs->static_config.under_shoot_pct     = config_struct->under_shoot_pct;
4554
604
    scs->static_config.over_shoot_pct      = config_struct->over_shoot_pct;
4555
604
    if (scs->static_config.under_shoot_pct == (uint32_t)DEFAULT) {
4556
604
        if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR) {
4557
0
            scs->static_config.under_shoot_pct = 50;
4558
604
        } else {
4559
604
            scs->static_config.under_shoot_pct = 25;
4560
604
        }
4561
604
    }
4562
4563
604
    if (scs->static_config.over_shoot_pct == (uint32_t)DEFAULT) {
4564
604
        scs->static_config.over_shoot_pct = 25;
4565
604
    }
4566
604
    scs->static_config.mbr_over_shoot_pct       = config_struct->mbr_over_shoot_pct;
4567
604
    scs->static_config.max_intra_bitrate_pct    = config_struct->max_intra_bitrate_pct;
4568
604
    scs->static_config.max_inter_bitrate_pct    = config_struct->max_inter_bitrate_pct;
4569
604
    scs->static_config.gop_constraint_rc        = config_struct->gop_constraint_rc;
4570
604
    scs->static_config.maximum_buffer_size_ms   = config_struct->maximum_buffer_size_ms;
4571
604
    scs->static_config.starting_buffer_level_ms = config_struct->starting_buffer_level_ms;
4572
604
    scs->static_config.optimal_buffer_level_ms  = config_struct->optimal_buffer_level_ms;
4573
604
    scs->static_config.recode_loop              = config_struct->recode_loop;
4574
604
    if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR && scs->static_config.pass == ENC_SINGLE_PASS) {
4575
0
        scs->lap_rc = 1;
4576
604
    } else {
4577
604
        scs->lap_rc = 0;
4578
604
    }
4579
    // Misc
4580
604
    scs->static_config.encoder_bit_depth    = config_struct->encoder_bit_depth;
4581
604
    scs->static_config.encoder_color_format = config_struct->encoder_color_format;
4582
4583
604
    scs->chroma_format_idc = (uint32_t)(scs->static_config.encoder_color_format);
4584
604
    scs->encoder_bit_depth = (uint32_t)(scs->static_config.encoder_bit_depth);
4585
    //16bit pipeline
4586
604
    scs->is_16bit_pipeline = ((config_struct->encoder_bit_depth) > EB_EIGHT_BIT) ? true : false;
4587
604
    scs->subsampling_x     = (scs->chroma_format_idc == EB_YUV444 ? 0 : 1);
4588
604
    scs->subsampling_y     = (scs->chroma_format_idc >= EB_YUV422 ? 0 : 1);
4589
    // Force screen-content detection OFF when allintra
4590
604
    const bool allintra = scs->allintra;
4591
604
    const bool rtc      = SVT_RTC_TUNE(scs);
4592
604
    if (allintra) {
4593
604
        if (config_struct->screen_content_mode <= 1) {
4594
0
            scs->static_config.screen_content_mode = config_struct->screen_content_mode;
4595
604
        } else if (scs->static_config.enc_mode <= ENC_M7) {
4596
0
            scs->static_config.screen_content_mode = 3;
4597
604
        } else {
4598
604
            scs->static_config.screen_content_mode = 0;
4599
604
            SVT_WARN(
4600
604
                "Screen-content detection and tools are disabled for all-intra coding at M8 and above; forcing NSC "
4601
604
                "path\n");
4602
604
        }
4603
604
    } else if (rtc) {
4604
0
        if (config_struct->screen_content_mode <= 1 && scs->static_config.enc_mode <= ENC_M8) {
4605
0
            scs->static_config.screen_content_mode = config_struct->screen_content_mode;
4606
0
        } else if (scs->static_config.enc_mode <= ENC_M8) {
4607
0
            scs->static_config.screen_content_mode = 3;
4608
0
        } else {
4609
0
            scs->static_config.screen_content_mode = 0;
4610
0
            SVT_WARN(
4611
0
                "Screen-content detection and tools are disabled for RTC mode coding at M9 and above; forcing NSC "
4612
0
                "path\n");
4613
0
        }
4614
0
    } else {
4615
0
        if (config_struct->screen_content_mode <= 1 && scs->static_config.enc_mode <= ENC_M8) {
4616
0
            scs->static_config.screen_content_mode = config_struct->screen_content_mode;
4617
0
        } else if (scs->static_config.enc_mode <= ENC_M8) {
4618
0
            scs->static_config.screen_content_mode = 3;
4619
0
        } else {
4620
0
            scs->static_config.screen_content_mode = 0;
4621
0
            SVT_WARN(
4622
0
                "Screen-content detection and tools are disabled for RA mode coding at M9 and above; forcing NSC "
4623
0
                "path\n");
4624
0
        }
4625
0
    }
4626
    // Annex A parameters
4627
604
    scs->static_config.profile     = config_struct->profile;
4628
604
    scs->static_config.tier        = config_struct->tier;
4629
604
    scs->static_config.level       = config_struct->level;
4630
604
    scs->static_config.stat_report = config_struct->stat_report;
4631
4632
    // Buffers - Hardcoded(Cleanup)
4633
604
    scs->static_config.use_cpu_flags = config_struct->use_cpu_flags;
4634
4635
604
    scs->static_config.level_of_parallelism = config_struct->level_of_parallelism;
4636
604
    if (scs->static_config.level_of_parallelism >= PARALLEL_LEVEL_COUNT) {
4637
0
        SVT_WARN("Level of parallelism supports levels [0-%d]. Setting maximum parallelism level.\n",
4638
0
                 PARALLEL_LEVEL_COUNT - 1);
4639
0
        SVT_WARN(
4640
0
            "Level of parallelism does not correspond to a target number of processors to use. See Docs/Parameters.md "
4641
0
            "for info.\n");
4642
0
        scs->static_config.level_of_parallelism = PARALLEL_LEVEL_6;
4643
0
    }
4644
    // When lp is left unset (0), resolve it to the core-count-based default now,
4645
    // before any pipeline setup reads static_config.level_of_parallelism. This
4646
    // keeps every downstream single-thread check (== 1) consistent with the
4647
    // derived scs->lp used for segment/dispatcher setup; otherwise a 1-core
4648
    // machine gets scs->lp == 1 (ST dispatch) while these checks still see 0.
4649
604
    if (scs->static_config.level_of_parallelism == 0) {
4650
0
        scs->static_config.level_of_parallelism = get_default_level_of_parallelism(get_num_processors());
4651
0
    }
4652
4653
604
    scs->static_config.qp            = config_struct->qp;
4654
604
    scs->static_config.recon_enabled = config_struct->recon_enabled;
4655
4656
    // Numerator and Denominator already checked to be non 0
4657
604
    scs->frame_rate = (double)scs->static_config.frame_rate_numerator /
4658
604
        (double)scs->static_config.frame_rate_denominator;
4659
4660
    // Get Default Intra Period if not specified
4661
604
    if (scs->static_config.intra_period_length == -2) {
4662
0
        scs->static_config.intra_period_length = compute_default_intra_period(scs);
4663
0
        scs->allintra = (scs->static_config.intra_period_length == 0 || scs->static_config.avif);
4664
604
    } else if (scs->static_config.multiply_keyint) {
4665
0
        scs->static_config.intra_period_length = (int32_t)(scs->frame_rate * scs->static_config.intra_period_length);
4666
0
    }
4667
604
    if (scs->static_config.look_ahead_distance == (uint32_t)~0) {
4668
604
        scs->static_config.look_ahead_distance = compute_default_look_ahead(&scs->static_config);
4669
604
    }
4670
604
    scs->static_config.enable_tf          = scs->allintra ? 0 : config_struct->enable_tf;
4671
604
    scs->static_config.enable_tf_key      = config_struct->enable_tf && config_struct->enable_tf_key;
4672
604
    scs->static_config.enable_overlays    = config_struct->enable_overlays;
4673
604
    scs->static_config.superres_mode      = config_struct->superres_mode;
4674
604
    scs->static_config.superres_denom     = config_struct->superres_denom;
4675
604
    scs->static_config.superres_kf_denom  = config_struct->superres_kf_denom;
4676
604
    scs->static_config.superres_qthres    = config_struct->superres_qthres;
4677
604
    scs->static_config.superres_kf_qthres = config_struct->superres_kf_qthres;
4678
4679
604
    if (scs->static_config.superres_mode == SUPERRES_AUTO) {
4680
        // TODO: set search mode based on preset
4681
        //scs->static_config.superres_auto_search_type = SUPERRES_AUTO_SOLO;
4682
0
        scs->static_config.superres_auto_search_type = SUPERRES_AUTO_DUAL;
4683
        //scs->static_config.superres_auto_search_type = SUPERRES_AUTO_ALL;
4684
0
    }
4685
4686
604
    scs->static_config.resize_mode     = config_struct->resize_mode;
4687
604
    scs->static_config.resize_denom    = config_struct->resize_denom;
4688
604
    scs->static_config.resize_kf_denom = config_struct->resize_kf_denom;
4689
604
    if (config_struct->frame_scale_evts.start_frame_nums) {
4690
0
        EB_NO_THROW_MALLOC(scs->static_config.frame_scale_evts.start_frame_nums,
4691
0
                           sizeof(int64_t) * config_struct->frame_scale_evts.evt_num);
4692
0
        memcpy(scs->static_config.frame_scale_evts.start_frame_nums,
4693
0
               config_struct->frame_scale_evts.start_frame_nums,
4694
0
               sizeof(int64_t) * config_struct->frame_scale_evts.evt_num);
4695
0
    }
4696
604
    if (config_struct->frame_scale_evts.resize_kf_denoms) {
4697
0
        EB_NO_THROW_MALLOC(scs->static_config.frame_scale_evts.resize_kf_denoms,
4698
0
                           sizeof(int32_t) * config_struct->frame_scale_evts.evt_num);
4699
0
        memcpy(scs->static_config.frame_scale_evts.resize_kf_denoms,
4700
0
               config_struct->frame_scale_evts.resize_kf_denoms,
4701
0
               sizeof(int32_t) * config_struct->frame_scale_evts.evt_num);
4702
0
    }
4703
604
    if (config_struct->frame_scale_evts.resize_denoms) {
4704
0
        EB_NO_THROW_MALLOC(scs->static_config.frame_scale_evts.resize_denoms,
4705
0
                           sizeof(int32_t) * config_struct->frame_scale_evts.evt_num);
4706
0
        memcpy(scs->static_config.frame_scale_evts.resize_denoms,
4707
0
               config_struct->frame_scale_evts.resize_denoms,
4708
0
               sizeof(int32_t) * config_struct->frame_scale_evts.evt_num);
4709
0
    }
4710
604
    scs->static_config.frame_scale_evts.evt_num = config_struct->frame_scale_evts.evt_num;
4711
604
    if (config_struct->sframe_posi.sframe_posis) {
4712
0
        EB_NO_THROW_MALLOC(scs->static_config.sframe_posi.sframe_posis,
4713
0
                           sizeof(uint64_t) * config_struct->sframe_posi.sframe_num);
4714
0
        memcpy(scs->static_config.sframe_posi.sframe_posis,
4715
0
               config_struct->sframe_posi.sframe_posis,
4716
0
               sizeof(uint64_t) * config_struct->sframe_posi.sframe_num);
4717
0
    }
4718
604
    scs->static_config.sframe_posi.sframe_num = config_struct->sframe_posi.sframe_num;
4719
604
    if (config_struct->sframe_posi.sframe_qps) {
4720
0
        EB_NO_THROW_MALLOC(scs->static_config.sframe_posi.sframe_qps,
4721
0
                           sizeof(config_struct->sframe_posi.sframe_qps[0]) * config_struct->sframe_posi.sframe_qp_num);
4722
0
        memcpy(scs->static_config.sframe_posi.sframe_qps,
4723
0
               config_struct->sframe_posi.sframe_qps,
4724
0
               sizeof(config_struct->sframe_posi.sframe_qps[0]) * config_struct->sframe_posi.sframe_qp_num);
4725
0
    }
4726
604
    if (config_struct->sframe_posi.sframe_qp_offsets) {
4727
0
        EB_NO_THROW_MALLOC(
4728
0
            scs->static_config.sframe_posi.sframe_qp_offsets,
4729
0
            sizeof(config_struct->sframe_posi.sframe_qp_offsets[0]) * config_struct->sframe_posi.sframe_qp_num);
4730
0
        memcpy(scs->static_config.sframe_posi.sframe_qp_offsets,
4731
0
               config_struct->sframe_posi.sframe_qp_offsets,
4732
0
               sizeof(config_struct->sframe_posi.sframe_qp_offsets[0]) * config_struct->sframe_posi.sframe_qp_num);
4733
0
    }
4734
604
    scs->static_config.sframe_posi.sframe_qp_num = config_struct->sframe_posi.sframe_qp_num;
4735
4736
    // Color description
4737
604
    scs->static_config.color_primaries          = config_struct->color_primaries;
4738
604
    scs->static_config.transfer_characteristics = config_struct->transfer_characteristics;
4739
604
    scs->static_config.matrix_coefficients      = config_struct->matrix_coefficients;
4740
604
    scs->static_config.color_range              = config_struct->color_range;
4741
604
    scs->static_config.chroma_sample_position   = config_struct->chroma_sample_position;
4742
604
    scs->static_config.mastering_display        = config_struct->mastering_display;
4743
604
    scs->static_config.content_light_level      = config_struct->content_light_level;
4744
4745
    // switch frame
4746
604
    scs->static_config.sframe_dist      = config_struct->sframe_dist;
4747
604
    scs->static_config.sframe_mode      = config_struct->sframe_mode;
4748
604
    scs->static_config.sframe_qp        = config_struct->sframe_qp;
4749
604
    scs->static_config.sframe_qp_offset = config_struct->sframe_qp_offset;
4750
604
    scs->seq_header.max_frame_width  = config_struct->forced_max_frame_width > 0 ? config_struct->forced_max_frame_width
4751
604
        : scs->static_config.sframe_dist > 0 || scs->static_config.sframe_posi.sframe_posis ? 16384
4752
604
                                                                                            : scs->max_input_luma_width;
4753
604
    scs->seq_header.max_frame_height = config_struct->forced_max_frame_height > 0
4754
604
        ? config_struct->forced_max_frame_height
4755
604
        : scs->static_config.sframe_dist > 0 || scs->static_config.sframe_posi.sframe_posis
4756
604
        ? 8704
4757
604
        : scs->max_input_luma_height;
4758
604
    scs->static_config.force_key_frames = config_struct->force_key_frames;
4759
4760
    // QM
4761
604
    scs->static_config.enable_qm           = config_struct->enable_qm;
4762
604
    scs->static_config.min_qm_level        = config_struct->min_qm_level;
4763
604
    scs->static_config.max_qm_level        = config_struct->max_qm_level;
4764
604
    scs->static_config.min_chroma_qm_level = config_struct->min_chroma_qm_level;
4765
604
    scs->static_config.max_chroma_qm_level = config_struct->max_chroma_qm_level;
4766
604
    if (scs->static_config.enable_qm && scs->static_config.min_qm_level == 15 &&
4767
0
        scs->static_config.max_qm_level == 15 && scs->static_config.min_chroma_qm_level == 15 &&
4768
0
        scs->static_config.max_chroma_qm_level == 15) {
4769
0
        SVT_WARN("Quantization matrices will be forced off since all min/max quant matrix levels are set to 15\n");
4770
0
        scs->static_config.enable_qm = 0;
4771
0
    }
4772
604
    if (scs->static_config.enable_qm && scs->static_config.lossless) {
4773
0
        SVT_WARN("Quantization matrices will be forced off since lossless coding is applied\n");
4774
0
        scs->static_config.enable_qm = 0;
4775
0
    }
4776
604
    scs->static_config.startup_mg_size   = config_struct->startup_mg_size;
4777
604
    scs->static_config.startup_qp_offset = config_struct->startup_qp_offset;
4778
604
    scs->static_config.enable_roi_map    = config_struct->enable_roi_map;
4779
4780
    // Variance Boost
4781
604
    scs->static_config.enable_variance_boost   = config_struct->enable_variance_boost;
4782
604
    scs->static_config.variance_boost_strength = config_struct->variance_boost_strength;
4783
#if OPT_OPERATIONS_BIS
4784
    scs->static_config.variance_octile = scs->static_config.enable_variance_boost ? config_struct->variance_octile : 0;
4785
#else
4786
604
    scs->static_config.variance_octile = config_struct->variance_octile;
4787
604
#endif
4788
604
    scs->static_config.variance_boost_curve = config_struct->variance_boost_curve;
4789
4790
    // Temporal filtering strength
4791
604
    scs->static_config.tf_strength = config_struct->tf_strength;
4792
4793
    // Frame-level luminance-based QP bias
4794
604
    scs->static_config.luminance_qp_bias = config_struct->luminance_qp_bias;
4795
4796
    // Sharpness
4797
604
    scs->static_config.sharpness = config_struct->sharpness;
4798
4799
    // QP scaling compression
4800
604
    scs->static_config.qp_scale_compress_strength = config_struct->qp_scale_compress_strength;
4801
4802
    // Adaptive film grain
4803
604
    scs->static_config.adaptive_film_grain = config_struct->adaptive_film_grain;
4804
4805
    // Max TX size
4806
604
    scs->static_config.max_tx_size = config_struct->max_tx_size;
4807
4808
    // Extended CRF
4809
604
    scs->static_config.extended_crf_qindex_offset = config_struct->extended_crf_qindex_offset;
4810
4811
    // AC bias
4812
604
    scs->static_config.ac_bias = config_struct->ac_bias;
4813
4814
    // HBD-MDS
4815
604
    scs->static_config.hbd_mds = config_struct->hbd_mds;
4816
4817
    // Ref-frame management: propagate caller's max-anchors hint (0 = disabled).
4818
604
    scs->static_config.max_managed_refs = config_struct->max_managed_refs;
4819
4820
    // Runtime MG-size change: propagate caller's ceiling (0 = MG size fixed).
4821
604
    scs->static_config.max_hierarchical_levels = config_struct->max_hierarchical_levels;
4822
4823
    // Application-managed LTR addresses references by frame_id so a decoder can
4824
    // detect a DPB that has diverged from the encoder's under loss. Enabled only
4825
    // for LTR; every other configuration keeps the flag clear.
4826
    //
4827
    // current_frame_id is derived from picture_number, which is only a valid id
4828
    // source while decode order matches input order. LTR requires LOW_DELAY
4829
    // (enforced in enc_settings.c), which is what guarantees that.
4830
604
    scs->seq_header.frame_id_numbers_present_flag = scs->static_config.max_managed_refs > 0;
4831
4832
604
    scs->static_config.max_allowed_consecutive_frames_skips = config_struct->max_allowed_consecutive_frames_skips;
4833
4834
    // Override settings for Still IQ tune
4835
604
    if (scs->static_config.tune == TUNE_IQ) {
4836
0
        SVT_WARN(
4837
0
            "Tune IQ overrides: sharpness, Var. Boost strength/curve, enable-qm and min/max level, max TX size and "
4838
0
            "SCM\n");
4839
0
        scs->static_config.enable_qm               = 1;
4840
0
        scs->static_config.min_qm_level            = 4;
4841
0
        scs->static_config.max_qm_level            = 10;
4842
0
        scs->static_config.min_chroma_qm_level     = 4;
4843
0
        scs->static_config.max_chroma_qm_level     = 10;
4844
0
        scs->static_config.sharpness               = 7;
4845
0
        scs->static_config.enable_variance_boost   = 1;
4846
0
        scs->static_config.variance_boost_strength = 3;
4847
0
        scs->static_config.variance_boost_curve    = 2;
4848
0
        scs->static_config.max_tx_size             = scs->static_config.qp <= 45 ? 32 : 64;
4849
0
        scs->static_config.screen_content_mode     = 3;
4850
604
    } else if (scs->static_config.tune == TUNE_MS_SSIM) {
4851
0
        SVT_WARN("Tune MS_SSIM overrides: sharpness, Var. Boost strength/curve, enable-qm and min/max level\n");
4852
0
        scs->static_config.enable_qm               = 1;
4853
0
        scs->static_config.min_qm_level            = 4;
4854
0
        scs->static_config.max_qm_level            = 10;
4855
0
        scs->static_config.min_chroma_qm_level     = 4;
4856
0
        scs->static_config.max_chroma_qm_level     = 10;
4857
0
        scs->static_config.sharpness               = 7;
4858
0
        scs->static_config.enable_variance_boost   = 1;
4859
0
        scs->static_config.variance_boost_strength = 3;
4860
0
        scs->static_config.variance_boost_curve    = 2;
4861
604
    } else if (scs->static_config.tune == TUNE_VMAF) {
4862
0
        SVT_WARN("Tune VMAF: a pre-processing / unsharp masking is applied\n");
4863
0
    }
4864
#if !CONFIG_ENABLE_QUANT_MATRIX
4865
    // Quantization matrices are compiled out (flat quantizers): never signal them (tunes IQ and MS-SSIM enable them).
4866
    scs->static_config.enable_qm = 0;
4867
#endif
4868
604
    return;
4869
604
}
4870
4871
/**********************************
4872
4873
* Set Parameter
4874
**********************************/
4875
EB_API EbErrorType svt_av1_enc_set_parameter(EbComponentType*          svt_enc_component,
4876
604
                                             EbSvtAv1EncConfiguration* config_struct) {
4877
604
    if (svt_enc_component == NULL) {
4878
0
        return EB_ErrorBadParameter;
4879
0
    }
4880
4881
604
    EbEncHandle*        enc_handle = (EbEncHandle*)svt_enc_component->p_component_private;
4882
604
    SequenceControlSet* scs        = enc_handle->scs_instance->scs;
4883
604
    copy_api_from_app(scs, config_struct);
4884
4885
604
    EbErrorType return_error = svt_av1_verify_settings(scs);
4886
4887
604
    if (return_error == EB_ErrorBadParameter) {
4888
0
        return EB_ErrorBadParameter;
4889
0
    }
4890
#if RTC_BUILD
4891
    // The RTC build is compiled for rtc mode only (SVT_RTC_TUNE, SVT_ALLINTRA): the settings above were derived as
4892
    // rtc and verified against the requested flags; encode in rtc mode.
4893
    if (scs->allintra) {
4894
        SVT_ERROR("All-intra and AVIF coding are not supported by the RTC build\n");
4895
        return EB_ErrorBadParameter;
4896
    }
4897
    scs->static_config.rtc = 1;
4898
#endif
4899
4900
604
    if (scs->static_config.avif) {
4901
604
        scs->seq_header.still_picture                = 1;
4902
604
        scs->seq_header.reduced_still_picture_header = 1;
4903
604
    }
4904
4905
    // Signal initial_display_delay in the sequence header for hierarchical coding.
4906
    // With hierarchical B-frames, the encoder bundles multiple non-displayable reference
4907
    // frames into a single temporal unit (TU). The decoder must process all frames in a
4908
    // TU before displaying the first frame. Without this signal, players may start audio
4909
    // playback before video is ready after a seek, causing A/V desync — especially
4910
    // noticeable with hierarchical_levels >= 4 where the TU can contain 5-6 coded frames.
4911
    //
4912
    // Per AV1 spec section 6.4.1: initial_display_delay is "the number of decoded frames
4913
    // that should be present in the buffer pool before the first presentable frame is
4914
    // displayed." For the TU-based output of SVT-AV1, this equals hierarchical_levels + 1
4915
    // (the base layer frame + all intermediate reference frames that must be decoded
4916
    // before the first leaf frame is displayable).
4917
604
    if (!scs->seq_header.reduced_still_picture_header) {
4918
0
        uint8_t hierarchical_levels = scs->static_config.hierarchical_levels;
4919
        // The display delay equals the number of frames in the first non-keyframe TU:
4920
        // one frame per temporal layer (layers 0 through hierarchical_levels-1 are
4921
        // non-displayable, layer hierarchical_levels is displayable), so the decoder
4922
        // must buffer hierarchical_levels + 1 frames before first display.
4923
        // Capped at 10 per AV1 spec (4 bits, max value 10).
4924
0
        uint8_t display_delay = AOMMIN(hierarchical_levels + 1, 10);
4925
4926
0
        scs->seq_header.initial_display_delay_present_flag                           = 1;
4927
0
        scs->seq_header.operating_point[0].initial_display_delay_present_for_this_op = 1;
4928
0
        scs->seq_header.operating_point[0].initial_display_delay                     = display_delay;
4929
0
    }
4930
4931
604
    set_param_based_on_input(scs);
4932
4933
    // LTR pins anchors in DPB slots {4,5,6,7} (svt_aom_ref_mgmt_storeable_slots_mask).
4934
    // That is only safe while the regular refs stay in the bottom 4, i.e. ref counts
4935
    // <= 2, which is exactly ld_reduce_ref_buffs >= 1. At ld_reduce == 0 the encoder
4936
    // uses 3 refs (LAST3 = long_base = slot 7) and exclusively refreshes slots 4/5,
4937
    // so anchors would collide. Checked here: this is the first point where
4938
    // mrp_ctrls is populated and an error can still be returned.
4939
604
    if (scs->static_config.max_managed_refs > 0 && scs->mrp_ctrls.ld_reduce_ref_buffs == 0) {
4940
0
        SVT_ERROR(
4941
0
            "max_managed_refs > 0 requires a preset whose reference counts are all <= 2 "
4942
0
            "(ld_reduce_ref_buffs >= 1); use enc_mode >= 9 with rtc=1, or enc_mode >= 10 "
4943
0
            "without. Got ld_reduce_ref_buffs=0 (enc_mode=%d rtc=%u list0=%u/%u)\n",
4944
0
            (int)scs->static_config.enc_mode,
4945
0
            (unsigned)scs->static_config.rtc,
4946
0
            (unsigned)scs->mrp_ctrls.base_ref_list0_count,
4947
0
            (unsigned)scs->mrp_ctrls.non_base_ref_list0_count);
4948
0
        return EB_ErrorBadParameter;
4949
0
    }
4950
4951
    // Initialize the Prediction Structure Group. Free any group from a previous
4952
    // svt_av1_enc_set_parameter() call on this handle so it is not leaked.
4953
604
    EB_DELETE(enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr);
4954
604
    EB_NO_THROW_NEW(enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr,
4955
604
                    svt_aom_prediction_structure_group_ctor);
4956
604
    if (!enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr) {
4957
0
        return EB_ErrorInsufficientResources;
4958
0
    }
4959
604
    return_error = load_default_buffer_configuration_settings(scs);
4960
4961
604
    svt_av1_print_lib_params(scs);
4962
4963
    // free frame scale events after copy to encoder
4964
604
    if (config_struct->frame_scale_evts.resize_denoms) {
4965
0
        EB_FREE(config_struct->frame_scale_evts.resize_denoms);
4966
0
    }
4967
604
    if (config_struct->frame_scale_evts.resize_kf_denoms) {
4968
0
        EB_FREE(config_struct->frame_scale_evts.resize_kf_denoms);
4969
0
    }
4970
604
    if (config_struct->frame_scale_evts.start_frame_nums) {
4971
0
        EB_FREE(config_struct->frame_scale_evts.start_frame_nums);
4972
0
    }
4973
604
    memset(&config_struct->frame_scale_evts, 0, sizeof(SvtAv1FrameScaleEvts));
4974
4975
    // free sframe position list
4976
604
    if (config_struct->sframe_posi.sframe_qps) {
4977
0
        EB_FREE(config_struct->sframe_posi.sframe_qps);
4978
0
    }
4979
604
    if (config_struct->sframe_posi.sframe_qp_offsets) {
4980
0
        EB_FREE(config_struct->sframe_posi.sframe_qp_offsets);
4981
0
    }
4982
604
    if (config_struct->sframe_posi.sframe_posis) {
4983
0
        EB_FREE(config_struct->sframe_posi.sframe_posis);
4984
0
    }
4985
604
    memset(&config_struct->sframe_posi, 0, sizeof(SvtAv1SFramePositions));
4986
4987
604
    return return_error;
4988
604
}
4989
4990
EB_API EbErrorType svt_av1_enc_stream_header(EbComponentType*     svt_enc_component,
4991
0
                                             EbBufferHeaderType** output_stream_ptr) {
4992
0
    EbErrorType return_error = EB_ErrorNone;
4993
4994
0
    if (!svt_enc_component) {
4995
0
        return EB_ErrorBadParameter;
4996
0
    }
4997
4998
0
    EbEncHandle*        enc_handle = (EbEncHandle*)svt_enc_component->p_component_private;
4999
0
    SequenceControlSet* scs        = enc_handle->scs_instance->scs;
5000
0
    Bitstream           bitstream;
5001
0
    OutputBitstreamUnit output_bitstream;
5002
0
    EbBufferHeaderType* output_stream_buffer;
5003
0
    uint32_t output_buffer_size = svt_aom_get_out_buffer_size(scs->max_input_luma_width, scs->max_input_luma_height);
5004
0
    memset(&bitstream, 0, sizeof(Bitstream));
5005
0
    memset(&output_bitstream, 0, sizeof(OutputBitstreamUnit));
5006
0
    bitstream.output_bitstream_ptr = &output_bitstream;
5007
0
    EB_MALLOC_OBJECT(output_stream_buffer);
5008
0
    EB_MALLOC_ARRAY_NO_CHECK(output_stream_buffer->p_buffer, output_buffer_size);
5009
0
    if (!output_stream_buffer->p_buffer) {
5010
0
        EB_FREE(output_stream_buffer);
5011
0
        return EB_ErrorInsufficientResources;
5012
0
    }
5013
5014
0
    output_stream_buffer->size          = sizeof(EbBufferHeaderType);
5015
0
    output_stream_buffer->n_alloc_len   = output_buffer_size;
5016
0
    output_stream_buffer->p_app_private = NULL;
5017
0
    output_stream_buffer->pic_type      = EB_AV1_INVALID_PICTURE;
5018
0
    output_stream_buffer->n_filled_len  = 0;
5019
5020
0
    bitstream.output_bitstream_ptr->buffer_begin_av1 = output_stream_buffer->p_buffer;
5021
5022
0
    svt_aom_output_bitstream_reset(bitstream.output_bitstream_ptr);
5023
5024
    // Code the SPS
5025
0
    svt_aom_encode_sps_av1(&bitstream, scs);
5026
5027
0
    output_stream_buffer->n_filled_len = (uint32_t)(bitstream.output_bitstream_ptr->buffer_av1 -
5028
0
                                                    bitstream.output_bitstream_ptr->buffer_begin_av1);
5029
5030
0
    *output_stream_ptr = output_stream_buffer;
5031
5032
0
    return return_error;
5033
0
}
5034
5035
0
EB_API EbErrorType svt_av1_enc_stream_header_release(EbBufferHeaderType* stream_header_ptr) {
5036
0
    EbErrorType return_error = EB_ErrorNone;
5037
5038
0
    if (!stream_header_ptr || !(stream_header_ptr->p_buffer)) {
5039
0
        return EB_ErrorBadParameter;
5040
0
    }
5041
5042
0
    EB_FREE_ARRAY(stream_header_ptr->p_buffer);
5043
0
    EB_FREE(stream_header_ptr);
5044
5045
0
    return return_error;
5046
0
}
5047
5048
/***********************************************
5049
**** Copy the input buffer from the
5050
**** sample application to the library buffers
5051
************************************************/
5052
/*
5053
 Down sample and Copy the input buffer
5054
from the sample application to the library buffers
5055
*/
5056
/********************************************
5057
 * downsample_2d_c_16_zero2bit_skipall
5058
 *      downsample the input by skipping three pixels and zero out the two LSB bit
5059
 ********************************************/
5060
static void downsample_2d_c_16_zero2bit_skipall(uint16_t* input_samples, // input parameter, input samples Ptr
5061
                                                uint32_t  input_stride, // input parameter, input stride
5062
                                                uint32_t  input_area_width, // input parameter, input area width
5063
                                                uint32_t  input_area_height, // input parameter, input area height
5064
                                                uint8_t*  decim_8b_samples, // output parameter, decimated samples Ptr
5065
                                                uint32_t  decim_stride, // input parameter, output stride
5066
                                                uint32_t  decim_step) // input parameter, decimation amount in pixels
5067
0
{
5068
0
    uint32_t       horizontal_index;
5069
0
    uint32_t       vertical_index;
5070
0
    uint32_t       input_stripe_stride = input_stride * decim_step;
5071
0
    uint32_t       decim_horizontal_index;
5072
0
    const uint32_t half_decim_step = decim_step >> 1;
5073
5074
0
    for (input_samples += half_decim_step * input_stride, vertical_index = half_decim_step;
5075
0
         vertical_index < input_area_height;
5076
0
         vertical_index += decim_step) {
5077
0
        uint16_t* prev_input_line = input_samples - input_stride;
5078
0
        for (horizontal_index = half_decim_step, decim_horizontal_index = 0; horizontal_index < input_area_width;
5079
0
             horizontal_index += decim_step, decim_horizontal_index++) {
5080
0
            decim_8b_samples[decim_horizontal_index] = (uint8_t)((prev_input_line[horizontal_index - 1]) >> 2);
5081
0
        }
5082
0
        input_samples += input_stripe_stride;
5083
0
        decim_8b_samples += decim_stride;
5084
0
    }
5085
5086
0
    return;
5087
0
}
5088
5089
/********************************************
5090
 * downsample_2d_c_skipall
5091
 *      downsample the input by skipping three pixels
5092
 ********************************************/
5093
static void downsample_2d_c_skipall(uint8_t* input_samples, // input parameter, input samples Ptr
5094
                                    uint32_t input_stride, // input parameter, input stride
5095
                                    uint32_t input_area_width, // input parameter, input area width
5096
                                    uint32_t input_area_height, // input parameter, input area height
5097
                                    uint8_t* decim_samples, // output parameter, decimated samples Ptr
5098
                                    uint32_t decim_stride, // input parameter, output stride
5099
                                    uint32_t decim_step) // input parameter, decimation amount in pixels
5100
0
{
5101
0
    uint32_t       horizontal_index;
5102
0
    uint32_t       vertical_index;
5103
0
    uint32_t       input_stripe_stride = input_stride * decim_step;
5104
0
    uint32_t       decim_horizontal_index;
5105
0
    const uint32_t half_decim_step = decim_step >> 1;
5106
5107
0
    for (input_samples += half_decim_step * input_stride, vertical_index = half_decim_step;
5108
0
         vertical_index < input_area_height;
5109
0
         vertical_index += decim_step) {
5110
0
        uint8_t* prev_input_line = input_samples - input_stride;
5111
0
        for (horizontal_index = half_decim_step, decim_horizontal_index = 0; horizontal_index < input_area_width;
5112
0
             horizontal_index += decim_step, decim_horizontal_index++) {
5113
0
            decim_samples[decim_horizontal_index] = (uint32_t)prev_input_line[horizontal_index - 1];
5114
0
        }
5115
0
        input_samples += input_stripe_stride;
5116
0
        decim_samples += decim_stride;
5117
0
    }
5118
5119
0
    return;
5120
0
}
5121
5122
/***********************************************
5123
 Down sample and Copy the input buffer
5124
from the sample application to the library buffers
5125
************************************************/
5126
static EbErrorType downsample_copy_frame_buffer(SequenceControlSet* scs, uint8_t* destination, uint8_t* destination_y8b,
5127
0
                                                uint8_t* source, int pass) {
5128
0
    EbErrorType return_error = EB_ErrorNone;
5129
5130
0
    EbPictureBufferDesc* input_pic             = (EbPictureBufferDesc*)destination;
5131
0
    EbPictureBufferDesc* y8b_input_picture_ptr = (EbPictureBufferDesc*)destination_y8b;
5132
0
    EbSvtIOFormat*       input_ptr             = (EbSvtIOFormat*)source;
5133
5134
0
    uint32_t luma_width  = (uint32_t)(input_pic->width - scs->max_input_pad_right);
5135
0
    uint32_t luma_height = (uint32_t)(input_pic->height - scs->max_input_pad_bottom);
5136
5137
0
    const uint8_t  subsampling_x = (input_pic->color_format == EB_YUV444 ? 0 : 1);
5138
0
    const uint8_t  subsampling_y = ((input_pic->color_format == EB_YUV444 || input_pic->color_format == EB_YUV422) ? 0
5139
0
                                                                                                                   : 1);
5140
0
    const uint32_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5141
0
    const uint32_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5142
5143
0
    if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) == EB_EIGHT_BIT) {
5144
0
        downsample_2d_c_skipall(input_ptr->luma,
5145
0
                                input_ptr->y_stride,
5146
0
                                luma_width << 1,
5147
0
                                luma_height << 1,
5148
0
                                y8b_input_picture_ptr->y_buffer,
5149
0
                                input_pic->y_stride,
5150
0
                                2);
5151
5152
0
        if (pass != ENCODE_FIRST_PASS) {
5153
0
            downsample_2d_c_skipall(input_ptr->cb,
5154
0
                                    input_ptr->cb_stride,
5155
0
                                    chroma_width << 1,
5156
0
                                    chroma_height << 1,
5157
0
                                    input_pic->u_buffer,
5158
0
                                    input_pic->u_stride,
5159
0
                                    2);
5160
0
            downsample_2d_c_skipall(input_ptr->cr,
5161
0
                                    input_ptr->cr_stride,
5162
0
                                    chroma_width << 1,
5163
0
                                    chroma_height << 1,
5164
0
                                    input_pic->v_buffer,
5165
0
                                    input_pic->v_stride,
5166
0
                                    2);
5167
0
        }
5168
0
    } else { // 10bit packed
5169
0
        downsample_2d_c_16_zero2bit_skipall((uint16_t*)input_ptr->luma,
5170
0
                                            input_ptr->y_stride,
5171
0
                                            luma_width << 1,
5172
0
                                            luma_height << 1,
5173
0
                                            y8b_input_picture_ptr->y_buffer,
5174
0
                                            y8b_input_picture_ptr->y_stride,
5175
0
                                            2);
5176
5177
0
        memset(
5178
0
            input_pic->y_buffer_bit_inc - ((input_pic->border + (input_pic->y_stride_bit_inc * input_pic->border)) / 4),
5179
0
            0,
5180
0
            input_pic->luma_size / 4);
5181
5182
0
        if (pass != ENCODE_FIRST_PASS) {
5183
0
            downsample_2d_c_16_zero2bit_skipall((uint16_t*)input_ptr->cb,
5184
0
                                                input_ptr->cb_stride,
5185
0
                                                chroma_width << 1,
5186
0
                                                chroma_height << 1,
5187
0
                                                input_pic->u_buffer,
5188
0
                                                y8b_input_picture_ptr->u_stride,
5189
0
                                                2);
5190
5191
0
            memset(input_pic->u_buffer_bit_inc -
5192
0
                       (((input_pic->border >> subsampling_x) +
5193
0
                         (input_pic->u_stride_bit_inc * (input_pic->border >> subsampling_y))) /
5194
0
                        4),
5195
0
                   0,
5196
0
                   input_pic->chroma_size / 4);
5197
5198
0
            downsample_2d_c_16_zero2bit_skipall((uint16_t*)input_ptr->cr,
5199
0
                                                input_ptr->cr_stride,
5200
0
                                                chroma_width << 1,
5201
0
                                                chroma_height << 1,
5202
0
                                                input_pic->v_buffer,
5203
0
                                                y8b_input_picture_ptr->v_stride,
5204
0
                                                2);
5205
5206
0
            memset(input_pic->v_buffer_bit_inc -
5207
0
                       (((input_pic->border >> subsampling_x) +
5208
0
                         (input_pic->v_stride_bit_inc * (input_pic->border >> subsampling_y))) /
5209
0
                        4),
5210
0
                   0,
5211
0
                   input_pic->chroma_size / 4);
5212
0
        }
5213
0
    }
5214
0
    return return_error;
5215
0
}
5216
5217
/*
5218
 Copy the input buffer
5219
from the sample application to the library buffers
5220
*/
5221
5222
static EbErrorType copy_frame_buffer(SequenceControlSet* scs, uint8_t* destination, uint8_t* destination_y8b,
5223
604
                                     uint8_t* source, int pass) {
5224
604
    EbErrorType return_error = EB_ErrorNone;
5225
5226
604
    EbPictureBufferDesc* input_pic             = (EbPictureBufferDesc*)destination;
5227
604
    EbPictureBufferDesc* y8b_input_picture_ptr = (EbPictureBufferDesc*)destination_y8b;
5228
604
    EbSvtIOFormat*       input_ptr             = (EbSvtIOFormat*)source;
5229
5230
604
    uint32_t luma_width  = (uint32_t)(input_pic->width - scs->max_input_pad_right);
5231
604
    uint32_t luma_height = (uint32_t)(input_pic->height - scs->max_input_pad_bottom);
5232
5233
604
    const uint8_t  subsampling_x = (input_pic->color_format == EB_YUV444 ? 0 : 1);
5234
604
    const uint8_t  subsampling_y = ((input_pic->color_format == EB_YUV444 || input_pic->color_format == EB_YUV422) ? 0
5235
604
                                                                                                                   : 1);
5236
604
    const uint32_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5237
604
    const uint32_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5238
5239
604
    if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) == EB_EIGHT_BIT) {
5240
604
        svt_av1_copy_wxh_8bit(input_ptr->luma,
5241
604
                              input_ptr->y_stride,
5242
604
                              y8b_input_picture_ptr->y_buffer,
5243
604
                              input_pic->y_stride,
5244
604
                              luma_height,
5245
604
                              luma_width);
5246
604
        svt_av1_copy_wxh_8bit(
5247
604
            input_ptr->cb, input_ptr->cb_stride, input_pic->u_buffer, input_pic->u_stride, chroma_height, chroma_width);
5248
604
        svt_av1_copy_wxh_8bit(
5249
604
            input_ptr->cr, input_ptr->cr_stride, input_pic->v_buffer, input_pic->v_stride, chroma_height, chroma_width);
5250
604
    } else { // 10bit packed
5251
0
        uint32_t comp_stride_y = input_pic->y_stride / 4;
5252
5253
0
        uint32_t comp_stride_uv = input_pic->u_stride / 4;
5254
5255
0
        svt_unpack_and_2bcompress((uint16_t*)input_ptr->luma,
5256
0
                                  input_ptr->y_stride,
5257
0
                                  y8b_input_picture_ptr->y_buffer,
5258
0
                                  y8b_input_picture_ptr->y_stride,
5259
0
                                  input_pic->y_buffer_bit_inc,
5260
0
                                  comp_stride_y,
5261
0
                                  luma_width,
5262
0
                                  luma_height);
5263
0
        if (pass != ENCODE_FIRST_PASS) {
5264
0
            svt_unpack_and_2bcompress((uint16_t*)input_ptr->cb,
5265
0
                                      input_ptr->cb_stride,
5266
0
                                      input_pic->u_buffer,
5267
0
                                      input_pic->u_stride,
5268
0
                                      input_pic->u_buffer_bit_inc,
5269
0
                                      comp_stride_uv,
5270
0
                                      chroma_width,
5271
0
                                      chroma_height);
5272
5273
0
            svt_unpack_and_2bcompress((uint16_t*)input_ptr->cr,
5274
0
                                      input_ptr->cr_stride,
5275
0
                                      input_pic->v_buffer,
5276
0
                                      input_pic->v_stride,
5277
0
                                      input_pic->v_buffer_bit_inc,
5278
0
                                      comp_stride_uv,
5279
0
                                      chroma_width,
5280
0
                                      chroma_height);
5281
0
        }
5282
0
    }
5283
604
    return return_error;
5284
604
}
5285
5286
0
static EbErrorType copy_private_data_list(EbBufferHeaderType* dst, EbBufferHeaderType* src) {
5287
0
    EbErrorType     return_error = EB_ErrorNone;
5288
0
    EbPrivDataNode* p_src_node   = (EbPrivDataNode*)src->p_app_private;
5289
0
    EbPrivDataNode* p_first_node = NULL;
5290
0
    EbPrivDataNode* p_new_node   = NULL;
5291
0
    while (p_src_node) {
5292
        // skip undefined data type and throw an error in debugging
5293
0
        if (p_src_node->node_type < PRIVATE_DATA || p_src_node->node_type >= PRIVATE_DATA_TYPES) {
5294
0
            svt_aom_assert_err(0, "unknown private data types inserted!");
5295
0
            continue;
5296
0
        }
5297
0
        if (p_first_node == NULL) {
5298
0
            EB_MALLOC(p_new_node, sizeof(*p_src_node));
5299
0
            p_first_node = p_new_node;
5300
0
        } else {
5301
0
            EB_MALLOC(p_new_node->next, sizeof(*p_src_node));
5302
0
            p_new_node = p_new_node->next;
5303
0
        }
5304
0
        p_new_node->node_type = p_src_node->node_type;
5305
0
        p_new_node->size      = p_src_node->size;
5306
        // not copy data from the private data pass through the encoder
5307
0
        if (p_src_node->node_type == PRIVATE_DATA || p_src_node->node_type == ROI_MAP_EVENT) {
5308
0
            p_new_node->data = p_src_node->data;
5309
0
        } else {
5310
0
            EB_MALLOC(p_new_node->data, p_src_node->size);
5311
0
            memcpy(p_new_node->data, p_src_node->data, p_src_node->size);
5312
0
        }
5313
0
        p_new_node->next = NULL;
5314
0
        p_src_node       = p_src_node->next;
5315
0
    }
5316
0
    dst->p_app_private = p_first_node;
5317
0
    return return_error;
5318
0
}
5319
5320
/**************************************
5321
* svt_input_buffer_header_update: update the parameters in input_buffer_header for changing the resolution on the fly
5322
**************************************/
5323
0
EbErrorType svt_input_buffer_header_update(EbBufferHeaderType* input_buffer, SequenceControlSet* scs, bool noy8b) {
5324
0
    EbPictureBufferDescInitData input_pic_buf_desc_init_data;
5325
0
    EbSvtAv1EncConfiguration*   config   = &scs->static_config;
5326
0
    uint8_t                     is_16bit = SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > 8 ? 1 : 0;
5327
5328
0
    input_pic_buf_desc_init_data.max_width = !(scs->max_input_luma_width % 8)
5329
0
        ? scs->max_input_luma_width
5330
0
        : scs->max_input_luma_width + (scs->max_input_luma_width % 8);
5331
5332
0
    input_pic_buf_desc_init_data.max_height = !(scs->max_input_luma_height % 8)
5333
0
        ? scs->max_input_luma_height
5334
0
        : scs->max_input_luma_height + (scs->max_input_luma_height % 8);
5335
5336
0
    input_pic_buf_desc_init_data.bit_depth    = (EbBitDepth)config->encoder_bit_depth;
5337
0
    input_pic_buf_desc_init_data.color_format = (EbColorFormat)config->encoder_color_format;
5338
5339
0
    input_pic_buf_desc_init_data.border = scs->border;
5340
5341
0
    input_pic_buf_desc_init_data.split_mode = is_16bit ? true : false;
5342
5343
0
    input_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
5344
0
    input_pic_buf_desc_init_data.is_16bit_pipeline  = 0;
5345
5346
    // Enhanced Picture Buffer
5347
0
    if (!noy8b) {
5348
0
        svt_picture_buffer_desc_update((EbPictureBufferDesc*)input_buffer->p_buffer,
5349
0
                                       (EbPtr)&input_pic_buf_desc_init_data);
5350
0
    } else {
5351
0
        svt_picture_buffer_desc_noy8b_update((EbPictureBufferDesc*)input_buffer->p_buffer,
5352
0
                                             (EbPtr)&input_pic_buf_desc_init_data);
5353
0
    }
5354
5355
0
    return EB_ErrorNone;
5356
0
}
5357
5358
/**************************************
5359
* svt_input_y8b_update: update the parameters in input_y8b for changing the resolution on the fly
5360
**************************************/
5361
0
EbErrorType svt_input_y8b_update(EbBufferHeaderType* input_buffer, SequenceControlSet* scs) {
5362
0
    EbPictureBufferDescInitData input_pic_buf_desc_init_data;
5363
0
    EbSvtAv1EncConfiguration*   config   = &scs->static_config;
5364
0
    uint8_t                     is_16bit = 0;
5365
5366
0
    input_pic_buf_desc_init_data.max_width = !(scs->max_input_luma_width % 8)
5367
0
        ? scs->max_input_luma_width
5368
0
        : scs->max_input_luma_width + (scs->max_input_luma_width % 8);
5369
5370
0
    input_pic_buf_desc_init_data.max_height   = !(scs->max_input_luma_height % 8)
5371
0
        ? scs->max_input_luma_height
5372
0
        : scs->max_input_luma_height + (scs->max_input_luma_height % 8);
5373
0
    input_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
5374
0
    input_pic_buf_desc_init_data.color_format = (EbColorFormat)config->encoder_color_format;
5375
5376
0
    input_pic_buf_desc_init_data.border = scs->border;
5377
5378
0
    input_pic_buf_desc_init_data.split_mode = is_16bit ? true : false;
5379
5380
0
    input_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_LUMA_MASK; //allocate for 8bit Luma only
5381
0
    input_pic_buf_desc_init_data.is_16bit_pipeline  = 0;
5382
5383
    // Enhanced Picture Buffer
5384
0
    svt_picture_buffer_desc_update((EbPictureBufferDesc*)input_buffer->p_buffer, (EbPtr)&input_pic_buf_desc_init_data);
5385
5386
0
    return EB_ErrorNone;
5387
0
}
5388
5389
/*
5390
    memset the library input buffer(s)
5391
*/
5392
static void memset_input_buffer(SequenceControlSet* scs, EbBufferHeaderType* dst, EbBufferHeaderType* dst_y8b,
5393
0
                                EbBufferHeaderType* src, int pass) {
5394
    // Copy the higher level structure
5395
0
    dst->n_alloc_len  = src->n_alloc_len;
5396
0
    dst->n_filled_len = src->n_filled_len;
5397
0
    dst->flags        = src->flags;
5398
0
    dst->pts          = src->pts;
5399
0
    dst->n_tick_count = src->n_tick_count;
5400
0
    dst->size         = src->size;
5401
0
    dst->qp           = src->qp;
5402
0
    dst->pic_type     = src->pic_type;
5403
0
    if (scs->first_pass_downsample) {
5404
        // memset the picture buffer
5405
0
        if (src->p_buffer != NULL) {
5406
0
            EbPictureBufferDesc* y8b_input_picture_ptr = (EbPictureBufferDesc*)dst_y8b->p_buffer;
5407
0
            EbPictureBufferDesc* input_pic             = (EbPictureBufferDesc*)dst->p_buffer;
5408
0
            memset(y8b_input_picture_ptr->buffer_alloc, 0, y8b_input_picture_ptr->buffer_alloc_sz);
5409
0
            memset(input_pic->buffer_alloc, 0, input_pic->buffer_alloc_sz);
5410
0
        }
5411
0
    } else if (pass != ENCODE_FIRST_PASS) {
5412
        // memset the picture buffer
5413
0
        if (src->p_buffer != NULL) {
5414
0
            EbPictureBufferDesc* y8b_input_picture_ptr = (EbPictureBufferDesc*)dst_y8b->p_buffer;
5415
0
            EbPictureBufferDesc* input_pic             = (EbPictureBufferDesc*)dst->p_buffer;
5416
0
            memset(y8b_input_picture_ptr->buffer_alloc, 0, y8b_input_picture_ptr->buffer_alloc_sz);
5417
0
            memset(input_pic->buffer_alloc, 0, input_pic->buffer_alloc_sz);
5418
            // Copy the metadata array
5419
0
            if (svt_aom_copy_metadata_buffer(dst, src->metadata) != EB_ErrorNone) {
5420
0
                dst->metadata = NULL;
5421
0
            }
5422
0
        }
5423
0
    }
5424
5425
    // Copy the private data list
5426
0
    if (src->p_app_private) {
5427
0
        copy_private_data_list(dst, src);
5428
0
    } else {
5429
0
        dst->p_app_private = NULL;
5430
0
    }
5431
0
}
5432
5433
/*
5434
 Copy the input buffer header content
5435
from the sample application to the library buffers
5436
*/
5437
static void copy_input_buffer(SequenceControlSet* scs, EbBufferHeaderType* dst, EbBufferHeaderType* dst_y8b,
5438
1.20k
                              EbBufferHeaderType* src, int pass) {
5439
    // Copy the higher level structure
5440
1.20k
    dst->n_alloc_len  = src->n_alloc_len;
5441
1.20k
    dst->n_filled_len = src->n_filled_len;
5442
1.20k
    dst->flags        = src->flags;
5443
1.20k
    dst->pts          = src->pts;
5444
1.20k
    dst->n_tick_count = src->n_tick_count;
5445
1.20k
    dst->size         = src->size;
5446
1.20k
    dst->qp           = src->qp;
5447
1.20k
    dst->pic_type     = src->pic_type;
5448
1.20k
    if (scs->first_pass_downsample) {
5449
        // Copy the picture buffer
5450
0
        if (src->p_buffer != NULL) {
5451
0
            downsample_copy_frame_buffer(scs, dst->p_buffer, dst_y8b->p_buffer, src->p_buffer, pass);
5452
0
        }
5453
1.20k
    } else if (pass != ENCODE_FIRST_PASS) {
5454
        // Bypass copy for the unecessary picture in IPPP pass
5455
        // Copy the picture buffer
5456
1.20k
        if (src->p_buffer != NULL) {
5457
604
            copy_frame_buffer(scs, dst->p_buffer, dst_y8b->p_buffer, src->p_buffer, pass);
5458
            // Copy the metadata array
5459
604
            if (svt_aom_copy_metadata_buffer(dst, src->metadata) != EB_ErrorNone) {
5460
604
                dst->metadata = NULL;
5461
604
            }
5462
604
        }
5463
1.20k
    }
5464
5465
    // Copy the private data list
5466
1.20k
    if (src->p_app_private) {
5467
0
        copy_private_data_list(dst, src);
5468
1.20k
    } else {
5469
1.20k
        dst->p_app_private = NULL;
5470
1.20k
    }
5471
1.20k
}
5472
5473
// Update the input picture definitions: resolution of the sequence
5474
static EbErrorType validate_on_the_fly_settings(EbBufferHeaderType* input_ptr, SequenceControlSet* scs,
5475
1.20k
                                                EbHandle config_mutex, bool* has_protected_event) {
5476
1.20k
    *has_protected_event = false;
5477
1.20k
    EbPrivDataNode* node = (EbPrivDataNode*)input_ptr->p_app_private;
5478
1.20k
    while (node) {
5479
0
        *has_protected_event |= node->node_type == REF_FRAME_SCALING_EVENT || node->node_type == REF_STORE_EVENT ||
5480
0
            node->node_type == REF_CLEAR_EVENT || node->node_type == REF_USE_EVENT ||
5481
0
            node->node_type == MG_SIZE_CHANGE_EVENT;
5482
0
        if (node->node_type == FILM_GRAIN_EVENT) {
5483
0
            if (node->size != sizeof(AomFilmGrain) || node->data == NULL) {
5484
0
                SVT_ERROR("FILM_GRAIN_EVENT requires an AomFilmGrain payload\n");
5485
0
                return EB_ErrorBadParameter;
5486
0
            }
5487
0
            const AomFilmGrain* grain = (const AomFilmGrain*)node->data;
5488
0
            if (!svt_aom_film_grain_params_valid(grain) ||
5489
0
                (grain->apply_grain &&
5490
0
                 (uint32_t)grain->bit_depth != SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth))) {
5491
0
                SVT_ERROR("FILM_GRAIN_EVENT contains invalid grain parameters\n");
5492
0
                return EB_ErrorBadParameter;
5493
0
            }
5494
0
            if (!scs->seq_header.film_grain_params_present) {
5495
0
                SVT_ERROR("FILM_GRAIN_EVENT requires film grain signaling enabled at initialization\n");
5496
0
                return EB_ErrorBadParameter;
5497
0
            }
5498
0
        } else if (node->node_type == RES_CHANGE_EVENT) {
5499
0
            SvtAv1InputPicDef* node_data = (SvtAv1InputPicDef*)node->data;
5500
0
            if (input_ptr->pic_type != EB_AV1_KEY_PICTURE) {
5501
0
                SVT_ERROR("Resolution change on the fly not supported for non key frames\n");
5502
0
                return EB_ErrorBadParameter;
5503
0
            } else if ((node_data->input_luma_height > scs->max_initial_input_luma_height) ||
5504
0
                       (node_data->input_luma_width > scs->max_initial_input_luma_width)) {
5505
0
                SVT_ERROR(
5506
0
                    "Resolution cannot be changed to anything greater than the original picture width and height\n");
5507
0
                return EB_ErrorBadParameter;
5508
0
            } else if (scs->static_config.superres_mode > SUPERRES_NONE) {
5509
0
                SVT_ERROR("Resolution change on the fly is not supported when Super-Resolution mode is on\n");
5510
0
                return EB_ErrorBadParameter;
5511
0
            } else if (scs->static_config.resize_mode != RESIZE_NONE) {
5512
0
                SVT_ERROR("Resolution change on the fly is not supported when Reference Scaling mode is on\n");
5513
0
                return EB_ErrorBadParameter;
5514
0
            } else if (scs->static_config.pred_structure != LOW_DELAY) {
5515
0
                SVT_ERROR("Resolution change on the fly is only supported for Low-Delay mode\n");
5516
0
                return EB_ErrorBadParameter;
5517
0
            } else if (scs->static_config.pass != ENC_SINGLE_PASS) {
5518
0
                SVT_ERROR("Resolution change on the fly is only supported for single pass encoding\n");
5519
0
                return EB_ErrorBadParameter;
5520
0
            } else if (scs->static_config.tile_rows || scs->static_config.tile_columns) {
5521
0
                SVT_ERROR("Resolution change on the fly is not supported when tiles are being used\n");
5522
0
                return EB_ErrorBadParameter;
5523
0
            } else if (scs->static_config.aq_mode == 1) {
5524
0
                SVT_ERROR(
5525
0
                    "Resolution change on the fly is not supported for segment based adaptive quantization (--aq-mode "
5526
0
                    "== 1)\n");
5527
0
                return EB_ErrorBadParameter;
5528
0
            } else if (node_data->input_luma_width < 64) {
5529
0
                SVT_ERROR("Resolution change on the fly is not supported for luma width less than 64\n");
5530
0
                return EB_ErrorBadParameter;
5531
0
            } else if (node_data->input_luma_height < 64) {
5532
0
                SVT_ERROR("Resolution change on the fly is not supported for luma height less than 64\n");
5533
0
                return EB_ErrorBadParameter;
5534
0
            } else if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) == EB_TEN_BIT) {
5535
0
                SVT_ERROR("Resolution change on the fly is not supported for 10-bit encoding\n");
5536
0
                return EB_ErrorBadParameter;
5537
0
            } else {
5538
0
                svt_aom_assert_err(node->size == sizeof(SvtAv1InputPicDef),
5539
0
                                   "invalid private data of type RES_CHANGE_EVENT");
5540
0
                SvtAv1InputPicDef* input_pic_def = (SvtAv1InputPicDef*)node->data;
5541
0
                svt_block_on_mutex(config_mutex);
5542
                // Check if a resolution change occurred
5543
0
                scs->max_input_luma_width  = input_pic_def->input_luma_width;
5544
0
                scs->max_input_luma_height = input_pic_def->input_luma_height;
5545
0
                scs->max_input_pad_right   = input_pic_def->input_pad_right;
5546
0
                scs->max_input_pad_bottom  = input_pic_def->input_pad_bottom;
5547
0
                svt_release_mutex(config_mutex);
5548
0
            }
5549
0
        } else if (node->node_type == RATE_CHANGE_EVENT) {
5550
0
            SvtAv1RateInfo* node_data = (SvtAv1RateInfo*)node->data;
5551
0
            if ((scs->static_config.target_bit_rate != node_data->target_bit_rate) &&
5552
0
                !(scs->static_config.rtc && scs->static_config.pred_structure == LOW_DELAY &&
5553
0
                  scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR)) {
5554
0
                SVT_ERROR("TBR change on the fly not supported for any mode other than RTC Low-Delay CBR\n");
5555
0
                return EB_ErrorBadParameter;
5556
0
            }
5557
0
            if (node_data->seq_qp != 0) {
5558
0
                if (node_data->seq_qp > MAX_QP_VALUE) {
5559
0
                    SVT_ERROR("QP change on the fly requires a QP value less than or equal to 63\n");
5560
0
                    return EB_ErrorBadParameter;
5561
0
                }
5562
0
            }
5563
0
            if (node_data->target_bit_rate > 100000000) {
5564
0
                SVT_ERROR("TBR change on the fly requires that the target bit rate must be between [0, 100000] kbps\n");
5565
0
                return EB_ErrorBadParameter;
5566
0
            }
5567
0
        } else if (node->node_type == FRAME_RATE_CHANGE_EVENT) {
5568
0
            SvtAv1FrameRateInfo* node_data = (SvtAv1FrameRateInfo*)node->data;
5569
0
            if (!((scs->static_config.pred_structure == LOW_DELAY) &&
5570
0
                  (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR))) {
5571
0
                SVT_ERROR("Frame rate change on the fly not supported for any mode other than Low-Delay CBR\n");
5572
0
                return EB_ErrorBadParameter;
5573
0
            }
5574
0
            if (node_data->frame_rate_numerator == 0 || node_data->frame_rate_denominator == 0) {
5575
0
                SVT_ERROR(
5576
0
                    "Frame rate change on the fly requires that he frame_rate_numerator and frame_rate_denominator "
5577
0
                    "must be greater than 0\n");
5578
0
                return EB_ErrorBadParameter;
5579
0
            }
5580
0
        } else if (node->node_type == PRESET_CHANGE_EVENT) {
5581
0
            SvtAv1PresetInfo* node_data = (SvtAv1PresetInfo*)node->data;
5582
0
            if (!((scs->static_config.pred_structure == LOW_DELAY) &&
5583
0
                  (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR) && scs->static_config.rtc)) {
5584
0
                SVT_ERROR("Preset change on the fly not supported for any mode other than RTC Low-Delay CBR\n");
5585
0
                return EB_ErrorBadParameter;
5586
0
            }
5587
0
            if (node_data->enc_mode < scs->static_config.enc_mode || node_data->enc_mode > MAX_ENC_PRESET) {
5588
0
                SVT_ERROR("Preset change on the fly requires enc_mode in range [%d, %d]\n",
5589
0
                          scs->static_config.enc_mode,
5590
0
                          MAX_ENC_PRESET);
5591
0
                return EB_ErrorBadParameter;
5592
0
            }
5593
0
        } else if (node->node_type == REF_STORE_EVENT || node->node_type == REF_CLEAR_EVENT ||
5594
0
                   node->node_type == REF_USE_EVENT) {
5595
            // Ref-frame management: per-event validation (FAIL-HARD path).
5596
            // Synchronous-checkable preconditions:
5597
            //   - Payload shape (size + non-NULL data).
5598
            //   - pic_id != 0 (0 is reserved as the "no event" sentinel).
5599
            //   - max_managed_refs > 0 (feature must be enabled at config time).
5600
            //   - pred_structure == LOW_DELAY (feature scope).
5601
            //   - At most ONE event of each type per input (STORE/CLEAR/USE).
5602
            //   - No pic_id collision across STORE/CLEAR/USE on the same input.
5603
            // Conditions requiring per-frame DPB state (duplicate STORE,
5604
            // cap reached, unknown CLEAR/USE, non-base layer, overlay) are
5605
            // detected later in pd_process and logged with SVT_ERROR.
5606
0
            const char* evt_name = (node->node_type == REF_STORE_EVENT) ? "REF_STORE_EVENT"
5607
0
                : (node->node_type == REF_CLEAR_EVENT)                  ? "REF_CLEAR_EVENT"
5608
0
                                                                        : "REF_USE_EVENT";
5609
0
            if (node->size != sizeof(SvtAv1RefFrameCmd) || !node->data) {
5610
0
                input_ptr->flags = EB_BUFFERFLAG_EOS;
5611
0
                SVT_ERROR("%s: invalid private-data size or NULL data\n", evt_name);
5612
0
                return EB_ErrorBadParameter;
5613
0
            }
5614
0
            const uint32_t pic_id = ((const SvtAv1RefFrameCmd*)node->data)->pic_id;
5615
0
            if (pic_id == 0) {
5616
0
                input_ptr->flags = EB_BUFFERFLAG_EOS;
5617
0
                SVT_ERROR("%s: pic_id == 0 is reserved\n", evt_name);
5618
0
                return EB_ErrorBadParameter;
5619
0
            }
5620
0
            if (scs->static_config.max_managed_refs == 0) {
5621
0
                input_ptr->flags = EB_BUFFERFLAG_EOS;
5622
0
                SVT_ERROR("%s requires max_managed_refs > 0\n", evt_name);
5623
0
                return EB_ErrorBadParameter;
5624
0
            }
5625
0
            if (scs->static_config.pred_structure != LOW_DELAY) {
5626
0
                input_ptr->flags = EB_BUFFERFLAG_EOS;
5627
0
                SVT_ERROR("%s requires pred_structure == LOW_DELAY\n", evt_name);
5628
0
                return EB_ErrorBadParameter;
5629
0
            }
5630
            // Walk the rest of the priv-data chain to detect (a) a second
5631
            // node of the same type and (b) a different ref-mgmt node
5632
            // carrying the same pic_id. Both indicate caller misuse.
5633
0
            for (EbPrivDataNode* peer = node->next; peer != NULL; peer = peer->next) {
5634
0
                if (peer->node_type != REF_STORE_EVENT && peer->node_type != REF_CLEAR_EVENT &&
5635
0
                    peer->node_type != REF_USE_EVENT) {
5636
0
                    continue;
5637
0
                }
5638
0
                if (peer->size != sizeof(SvtAv1RefFrameCmd) || !peer->data) {
5639
0
                    continue; // its own validation pass will reject it
5640
0
                }
5641
0
                if (peer->node_type == node->node_type) {
5642
0
                    input_ptr->flags = EB_BUFFERFLAG_EOS;
5643
0
                    SVT_ERROR("%s: duplicate event type on same input\n", evt_name);
5644
0
                    return EB_ErrorBadParameter;
5645
0
                }
5646
0
                if (((const SvtAv1RefFrameCmd*)peer->data)->pic_id == pic_id) {
5647
0
                    input_ptr->flags = EB_BUFFERFLAG_EOS;
5648
0
                    SVT_ERROR("Ref-frame mgmt: pic_id=%u used by multiple events on the same input (STORE/CLEAR/USE)\n",
5649
0
                              (unsigned)pic_id);
5650
0
                    return EB_ErrorBadParameter;
5651
0
                }
5652
0
            }
5653
0
        } else if (node->node_type == MG_SIZE_CHANGE_EVENT) {
5654
0
            SvtAv1MgSizeInfo* node_data = (SvtAv1MgSizeInfo*)node->data;
5655
0
            if (!((scs->static_config.pred_structure == LOW_DELAY) &&
5656
0
                  (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR) && scs->static_config.rtc)) {
5657
0
                input_ptr->flags = EB_BUFFERFLAG_EOS;
5658
0
                SVT_ERROR("MG size change on the fly not supported for any mode other than RTC Low-Delay CBR.\n");
5659
0
                return EB_ErrorBadParameter;
5660
0
            }
5661
0
            if (node_data->hierarchical_levels > 2) {
5662
0
                input_ptr->flags = EB_BUFFERFLAG_EOS;
5663
0
                SVT_ERROR("Low delay CBR supports hierarchical_levels [0-2].\n");
5664
0
                return EB_ErrorBadParameter;
5665
0
            }
5666
0
        }
5667
0
        node = node->next;
5668
0
    }
5669
1.20k
    return EB_ErrorNone;
5670
1.20k
}
5671
5672
/**********************************
5673
* Empty This Buffer
5674
**********************************/
5675
1.20k
EB_API EbErrorType svt_av1_enc_send_picture(EbComponentType* svt_enc_component, EbBufferHeaderType* p_buffer) {
5676
1.20k
    EbErrorType         return_val     = EB_ErrorNone;
5677
1.20k
    EbEncHandle*        enc_handle_ptr = (EbEncHandle*)svt_enc_component->p_component_private;
5678
1.20k
    EbObjectWrapper*    eb_wrapper_ptr;
5679
1.20k
    EbBufferHeaderType* app_hdr    = p_buffer;
5680
1.20k
    enc_handle_ptr->frame_received = true;
5681
5682
1.20k
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
5683
1.20k
    if (scs->static_config.avif && (p_buffer->flags & EB_BUFFERFLAG_EOS) != EB_BUFFERFLAG_EOS && p_buffer->pts == 3) {
5684
0
        p_buffer->flags              = EB_BUFFERFLAG_EOS;
5685
0
        p_buffer->pic_type           = EB_AV1_INVALID_PICTURE;
5686
0
        enc_handle_ptr->eos_received = 1;
5687
0
        return_val                   = EB_ErrorBadParameter;
5688
0
        SVT_ERROR(
5689
0
            "AVIF flag is specified, but more than 3 frames were sent. This will not produce an AVIF image sequence "
5690
0
            "(avis)!\n");
5691
0
    }
5692
5693
    // Exit the library if we detect an invalid API input buffer @ the previous library call
5694
1.20k
    if (enc_handle_ptr->is_prev_valid == false) {
5695
0
        p_buffer->flags              = EB_BUFFERFLAG_EOS;
5696
0
        p_buffer->pic_type           = EB_AV1_INVALID_PICTURE;
5697
0
        enc_handle_ptr->eos_received = 1;
5698
0
        return_val                   = EB_ErrorBadParameter;
5699
0
        SVT_ERROR("Invalid API input buffer size detected. Please ignore the output stream\n");
5700
0
    }
5701
5702
    // Validate any on-the-fly setting changes before acquiring pipeline buffers.
5703
    // A rejected setting change (rate / frame rate / preset / resolution) is a
5704
    // CLEAN REJECT: report EB_ErrorBadParameter but leave the stream intact so
5705
    // the caller can correct the request and keep sending. validate_on_the_fly_
5706
    // settings() leaves EOS clear for these. If EOS is set afterwards it is a
5707
    // fail-hard rejection (ref-frame management misuse) or the caller's own
5708
    // end-of-stream, so fall through and let the encoder drain as before.
5709
1.20k
    bool has_protected_event = false;
5710
1.20k
    if (validate_on_the_fly_settings(p_buffer, scs, enc_handle_ptr->scs_instance->config_mutex, &has_protected_event)) {
5711
0
        return_val = EB_ErrorBadParameter;
5712
0
        if (!(p_buffer->flags & EB_BUFFERFLAG_EOS)) {
5713
0
            return EB_ErrorBadParameter;
5714
0
        }
5715
0
        enc_handle_ptr->eos_received = 1;
5716
0
    }
5717
5718
    // Get new Luma-8b buffer & a new (Chroma-8b + Luma-Chroma-2bit) buffers; Lib will release once done.
5719
    // svt_get_empty_object can fail without writing the out-param (single-thread
5720
    // mode returns instead of blocking), so every acquire below is checked and
5721
    // anything already held is released before returning.
5722
1.20k
    EbObjectWrapper* y8b_wrapper;
5723
1.20k
    if (svt_get_empty_object(enc_handle_ptr->input_y8b_buffer_producer_fifo_ptr, &y8b_wrapper) != EB_ErrorNone) {
5724
0
        return EB_ErrorInsufficientResources;
5725
0
    }
5726
    // if resolution has changed, and the y8b_wrapper settings do not match scs settings, update y8b_wrapper settings
5727
1.20k
    if (buffer_update_needed((EbBufferHeaderType*)y8b_wrapper->object_ptr, scs)) {
5728
0
        svt_input_y8b_update((EbBufferHeaderType*)y8b_wrapper->object_ptr, scs);
5729
0
    }
5730
    //set live count to 1 to be decremented at the end of the encode in RC
5731
1.20k
    svt_object_inc_live_count(y8b_wrapper, 1);
5732
5733
    // svt_object_inc_live_count(y8b_wrapper, 1);
5734
5735
1.20k
    if (svt_get_empty_object(enc_handle_ptr->input_buffer_producer_fifo_ptr, &eb_wrapper_ptr) != EB_ErrorNone) {
5736
0
        svt_release_object(y8b_wrapper);
5737
0
        return EB_ErrorInsufficientResources;
5738
0
    }
5739
    // if resolution has changed, and the input_buffer settings do not match scs settings, update input_buffer settings
5740
1.20k
    if (buffer_update_needed((EbBufferHeaderType*)eb_wrapper_ptr->object_ptr, scs)) {
5741
0
        svt_input_buffer_header_update((EbBufferHeaderType*)eb_wrapper_ptr->object_ptr, scs, true);
5742
0
    }
5743
5744
    //set live count to 1 to be decremented at the end of the encode in RC, and released
5745
    //this would also allow low delay TF to retain pictures
5746
1.20k
    svt_object_inc_live_count(eb_wrapper_ptr, 1);
5747
5748
    // copy the Luma 8bit part into y8b buffer and the rest of samples into the regular buffer
5749
1.20k
    EbBufferHeaderType* lib_y8b_hdr = (EbBufferHeaderType*)y8b_wrapper->object_ptr;
5750
1.20k
    EbBufferHeaderType* lib_reg_hdr = (EbBufferHeaderType*)eb_wrapper_ptr->object_ptr;
5751
5752
    // check whether the n_filled_len has enough samples to be processed
5753
1.20k
    EbPictureBufferDesc*      input_pic      = (EbPictureBufferDesc*)lib_y8b_hdr->p_buffer;
5754
1.20k
    EbSvtAv1EncConfiguration* config         = &scs->static_config;
5755
1.20k
    bool                      is_16bit_input = SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > EB_EIGHT_BIT;
5756
5757
1.20k
    const uint8_t subsampling_x = (config->encoder_color_format == EB_YUV444 ? 0 : 1);
5758
1.20k
    const uint8_t subsampling_y =
5759
1.20k
        ((config->encoder_color_format == EB_YUV444 || config->encoder_color_format == EB_YUV422) ? 0 : 1);
5760
1.20k
    const size_t luma_width    = input_pic->width - scs->max_input_pad_right;
5761
1.20k
    const size_t luma_height   = input_pic->height - scs->max_input_pad_bottom;
5762
1.20k
    const size_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5763
1.20k
    const size_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5764
1.20k
    const size_t read_size     = (luma_width * luma_height + 2 * chroma_width * chroma_height) << is_16bit_input;
5765
5766
1.20k
    if (app_hdr->p_buffer != NULL && read_size > app_hdr->n_filled_len) {
5767
        // memset the library input buffer(s) if the API input buffer is not large enough
5768
        // this operation is necessary to avoid a potential crash when processing an invalid input
5769
        // the library will still process the current input and then exit
5770
0
        memset_input_buffer(scs, lib_reg_hdr, lib_y8b_hdr, app_hdr, 0);
5771
0
        enc_handle_ptr->is_prev_valid = false;
5772
1.20k
    } else {
5773
1.20k
        copy_input_buffer(scs, lib_reg_hdr, lib_y8b_hdr, app_hdr, 0);
5774
1.20k
    }
5775
5776
    //Take a new App-RessCoord command
5777
1.20k
    EbObjectWrapper* input_cmd_wrp;
5778
1.20k
    if (svt_get_empty_object(enc_handle_ptr->input_cmd_producer_fifo_ptr, &input_cmd_wrp) != EB_ErrorNone) {
5779
0
        svt_release_object(eb_wrapper_ptr);
5780
0
        svt_release_object(y8b_wrapper);
5781
0
        return EB_ErrorInsufficientResources;
5782
0
    }
5783
1.20k
    const bool protected_input = (p_buffer->flags & EB_BUFFERFLAG_EOS) || p_buffer->pic_type == EB_AV1_KEY_PICTURE ||
5784
604
        p_buffer->pic_type == EB_AV1_INTRA_ONLY_PICTURE || p_buffer->pic_type == EB_AV1_FW_KEY_PICTURE ||
5785
604
        p_buffer->pic_type == EB_AV1_SWITCH_PICTURE || has_protected_event;
5786
1.20k
    const bool    skip_frame    = svt_av1_rc_try_reserve_frame_skip(scs, protected_input);
5787
1.20k
    InputCommand* input_cmd_obj = (InputCommand*)input_cmd_wrp->object_ptr;
5788
    //Fill the command with two picture buffers
5789
1.20k
    input_cmd_obj->eb_input_wrapper_ptr = eb_wrapper_ptr;
5790
1.20k
    input_cmd_obj->y8b_wrapper          = y8b_wrapper;
5791
1.20k
    input_cmd_obj->skip_frame           = skip_frame;
5792
    // Only now is EOS actually in the pipeline; recording it earlier would make
5793
    // deinit drain for a packet that was never going to be produced.
5794
1.20k
    enc_handle_ptr->eos_received += p_buffer->flags & EB_BUFFERFLAG_EOS;
5795
    //Send to Lib
5796
1.20k
    svt_post_full_object(input_cmd_wrp);
5797
5798
1.20k
#if CONFIG_SINGLE_THREAD_KERNEL
5799
    // In single-thread mode, run the entire pipeline synchronously
5800
1.20k
    if (enc_handle_ptr->kernel_dispatcher.active) {
5801
0
        svt_kernel_dispatcher_run(&enc_handle_ptr->kernel_dispatcher);
5802
0
    }
5803
1.20k
#endif
5804
5805
1.20k
    return return_val != EB_ErrorNone ? return_val : (skip_frame ? EB_NoErrorFrameSkipped : EB_ErrorNone);
5806
1.20k
}
5807
5808
0
static void copy_output_recon_buffer(EbBufferHeaderType* dst, EbBufferHeaderType* src) {
5809
    // copy output Bitstream fileds
5810
0
    dst->size          = src->size;
5811
0
    dst->n_alloc_len   = src->n_alloc_len;
5812
0
    dst->n_filled_len  = src->n_filled_len;
5813
0
    dst->p_app_private = src->p_app_private;
5814
0
    dst->n_tick_count  = src->n_tick_count;
5815
0
    dst->pts           = src->pts;
5816
0
    dst->dts           = src->dts;
5817
0
    dst->flags         = src->flags;
5818
0
    dst->pic_type      = src->pic_type;
5819
5820
    // Copy the metadata array
5821
0
    if (svt_aom_copy_metadata_buffer(dst, src->metadata) != EB_ErrorNone) {
5822
0
        dst->metadata = NULL;
5823
0
    }
5824
5825
    // Copy the picture buffer
5826
0
    if (src->p_buffer) {
5827
0
        svt_memcpy(dst->p_buffer, src->p_buffer, src->n_filled_len);
5828
0
    }
5829
5830
0
    return;
5831
0
}
5832
5833
/**********************************
5834
* svt_av1_enc_get_packet sends out packet
5835
**********************************/
5836
EB_API EbErrorType svt_av1_enc_get_packet(EbComponentType* svt_enc_component, EbBufferHeaderType** p_buffer,
5837
2.41k
                                          unsigned char pic_send_done) {
5838
2.41k
    EbErrorType                     return_error   = EB_ErrorNone;
5839
2.41k
    EbEncHandle*                    enc_handle     = (EbEncHandle*)svt_enc_component->p_component_private;
5840
2.41k
    EbObjectWrapper*                eb_wrapper_ptr = NULL;
5841
2.41k
    EbBufferHeaderType*             packet;
5842
2.41k
    const EbSvtAv1EncConfiguration* cfg = &enc_handle->scs_instance->scs->static_config;
5843
5844
    // check if the user is claiming that the last picture has been sent
5845
    // without actually signalling it through svt_av1_enc_send_picture()
5846
2.41k
    assert(!(!enc_handle->eos_received && pic_send_done));
5847
5848
    // if we have already sent out an EOS, then the user should not be calling
5849
    // this function again, as it will just block inside svt_get_full_object()
5850
2.41k
    if (enc_handle->eos_sent) {
5851
604
        *p_buffer = NULL;
5852
604
        return EB_NoErrorEmptyQueue;
5853
604
    }
5854
5855
1.81k
    if (pic_send_done || cfg->pred_structure == LOW_DELAY) {
5856
1.20k
        svt_get_full_object(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
5857
1.20k
    } else {
5858
604
        svt_get_full_object_non_blocking(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
5859
604
    }
5860
5861
1.81k
    if (eb_wrapper_ptr) {
5862
1.20k
        packet = (EbBufferHeaderType*)eb_wrapper_ptr->object_ptr;
5863
1.20k
        if (packet->flags & EB_BUFFERFLAG_ERROR_MASK) {
5864
0
            return_error = EB_ErrorMax;
5865
0
        }
5866
        // return the output stream buffer
5867
1.20k
        *p_buffer = packet;
5868
5869
        // check if we have reached the end of the output stream
5870
1.20k
        enc_handle->eos_sent += packet->flags & EB_BUFFERFLAG_EOS;
5871
5872
        // save the wrapper pointer for the release
5873
1.20k
        (*p_buffer)->wrapper_ptr = (void*)eb_wrapper_ptr;
5874
1.20k
    } else {
5875
604
        return_error = EB_NoErrorEmptyQueue;
5876
604
    }
5877
1.81k
    return return_error;
5878
2.41k
}
5879
5880
1.20k
EB_API void svt_av1_enc_release_out_buffer(EbBufferHeaderType** p_buffer) {
5881
1.20k
    if (p_buffer && (*p_buffer)->wrapper_ptr) {
5882
1.20k
        if ((*p_buffer)->p_buffer) {
5883
604
            EB_FREE((*p_buffer)->p_buffer);
5884
604
        }
5885
        // Release out put buffer back into the pool
5886
1.20k
        svt_release_object((EbObjectWrapper*)(*p_buffer)->wrapper_ptr);
5887
1.20k
    }
5888
1.20k
    return;
5889
1.20k
}
5890
5891
/**********************************
5892
* Fill This Buffer
5893
**********************************/
5894
0
EB_API EbErrorType svt_av1_get_recon(EbComponentType* svt_enc_component, EbBufferHeaderType* p_buffer) {
5895
0
    EbErrorType      return_error   = EB_ErrorNone;
5896
0
    EbEncHandle*     enc_handle     = (EbEncHandle*)svt_enc_component->p_component_private;
5897
0
    EbObjectWrapper* eb_wrapper_ptr = NULL;
5898
5899
0
    if (enc_handle->scs_instance->scs->static_config.recon_enabled) {
5900
0
        svt_get_full_object_non_blocking(enc_handle->output_recon_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
5901
5902
0
        if (eb_wrapper_ptr) {
5903
0
            EbBufferHeaderType* obj_ptr = (EbBufferHeaderType*)eb_wrapper_ptr->object_ptr;
5904
0
            copy_output_recon_buffer(p_buffer, obj_ptr);
5905
5906
0
            if (p_buffer->flags != EB_BUFFERFLAG_EOS && p_buffer->flags != 0) {
5907
0
                return_error = EB_ErrorMax;
5908
0
            }
5909
0
            if (obj_ptr->metadata) {
5910
0
                svt_metadata_array_free(&obj_ptr->metadata);
5911
0
            }
5912
0
            svt_release_object((EbObjectWrapper*)eb_wrapper_ptr);
5913
0
        } else {
5914
0
            return_error = EB_NoErrorEmptyQueue;
5915
0
        }
5916
0
    } else {
5917
        // recon is not enabled
5918
0
        return_error = EB_ErrorMax;
5919
0
    }
5920
5921
0
    return return_error;
5922
0
}
5923
5924
/**********************************
5925
* Encoder Error Handling
5926
**********************************/
5927
0
static void lib_svt_encoder_send_error_exit(EbPtr hComponent, uint32_t error_code) {
5928
0
    EbComponentType*    svt_enc_component = (EbComponentType*)hComponent;
5929
0
    EbEncHandle*        enc_handle        = (EbEncHandle*)svt_enc_component->p_component_private;
5930
0
    EbObjectWrapper*    eb_wrapper_ptr    = NULL;
5931
0
    EbBufferHeaderType* output_packet;
5932
5933
0
    svt_get_empty_object(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
5934
5935
0
    output_packet = (EbBufferHeaderType*)eb_wrapper_ptr->object_ptr;
5936
5937
0
    output_packet->size     = 0;
5938
0
    output_packet->flags    = error_code;
5939
0
    output_packet->p_buffer = NULL;
5940
5941
0
    svt_post_full_object(eb_wrapper_ptr);
5942
0
}
5943
5944
0
EB_API const char* svt_av1_get_version(void) {
5945
0
    return SVT_AV1_CVS_VERSION;
5946
0
}
5947
5948
604
EB_API void svt_av1_print_version(void) {
5949
604
    SVT_INFO("-------------------------------------------\n");
5950
604
    SVT_INFO("SVT [version]:\tSVT-AV1 Encoder Lib %s\n", SVT_AV1_CVS_VERSION);
5951
604
    const char* compiler =
5952
604
#if defined(__clang__)
5953
604
        __VERSION__ "\t"
5954
#elif defined(__GNUC__)
5955
        "GCC " __VERSION__ "\t"
5956
#elif defined(_MSC_VER) && (_MSC_VER >= 1950)
5957
        "Visual Studio 2026"
5958
#elif defined(_MSC_VER) && (_MSC_VER >= 1930)
5959
        "Visual Studio 2022"
5960
#elif defined(_MSC_VER) && (_MSC_VER >= 1920)
5961
        "Visual Studio 2019"
5962
#elif defined(_MSC_VER) && (_MSC_VER >= 1910)
5963
        "Visual Studio 2017"
5964
#elif defined(_MSC_VER) && (_MSC_VER >= 1900)
5965
        "Visual Studio 2015"
5966
#elif defined(_MSC_VER)
5967
        "Visual Studio (old)"
5968
#else
5969
        "unknown compiler"
5970
#endif
5971
604
        ;
5972
604
    SVT_INFO("SVT [build]  :\t%s %zu bit\n", compiler, sizeof(void*) * 8);
5973
604
#if !REPRODUCIBLE_BUILDS
5974
604
    SVT_INFO("LIB Build date: %s %s\n", __DATE__, __TIME__);
5975
604
#endif
5976
604
    SVT_INFO("-------------------------------------------\n");
5977
604
}
5978
5979
/**
5980
 * Set log callback, wrapper around internal function to ensure public functions are stored in one place.
5981
 */
5982
0
EB_API void svt_av1_set_log_callback(SvtAv1LogCallback callback, void* context) {
5983
0
#if !CONFIG_LOG_QUIET
5984
0
    svt_aom_log_set_callback(callback, context);
5985
#else
5986
    UNUSED(callback);
5987
    UNUSED(context);
5988
#endif
5989
0
}
5990
5991
/**********************************
5992
* Encoder Handle Initialization
5993
**********************************/
5994
604
static EbErrorType init_svt_av1_encoder_handle(EbComponentType* hComponent) {
5995
604
    EbErrorType      return_error      = EB_ErrorNone;
5996
604
    EbComponentType* svt_enc_component = hComponent;
5997
604
    EbEncHandle*     handle;
5998
604
    svt_av1_print_version();
5999
6000
604
    enc_switch_to_real_time();
6001
6002
    // Set Component Size & Version
6003
604
    svt_enc_component->size = sizeof(EbComponentType);
6004
6005
604
    EB_NEW(handle, svt_enc_handle_ctor, svt_enc_component);
6006
604
    svt_enc_component->p_component_private = handle;
6007
6008
604
    return return_error;
6009
604
}
6010
6011
2.41k
static EbErrorType allocate_frame_buffer(SequenceControlSet* scs, EbBufferHeaderType* input_buffer, bool noy8b) {
6012
2.41k
    EbErrorType                 return_error = EB_ErrorNone;
6013
2.41k
    EbPictureBufferDescInitData input_pic_buf_desc_init_data;
6014
2.41k
    EbSvtAv1EncConfiguration*   config   = &scs->static_config;
6015
2.41k
    uint8_t                     is_16bit = SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > 8 ? 1 : 0;
6016
6017
2.41k
    input_pic_buf_desc_init_data.max_width = !(scs->max_input_luma_width % 8)
6018
2.41k
        ? scs->max_input_luma_width
6019
2.41k
        : scs->max_input_luma_width + (scs->max_input_luma_width % 8);
6020
6021
2.41k
    input_pic_buf_desc_init_data.max_height = !(scs->max_input_luma_height % 8)
6022
2.41k
        ? scs->max_input_luma_height
6023
2.41k
        : scs->max_input_luma_height + (scs->max_input_luma_height % 8);
6024
6025
2.41k
    input_pic_buf_desc_init_data.bit_depth    = (EbBitDepth)config->encoder_bit_depth;
6026
2.41k
    input_pic_buf_desc_init_data.color_format = (EbColorFormat)config->encoder_color_format;
6027
6028
2.41k
    input_pic_buf_desc_init_data.border = scs->border;
6029
6030
2.41k
    input_pic_buf_desc_init_data.split_mode = is_16bit ? true : false;
6031
6032
2.41k
    input_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
6033
2.41k
    input_pic_buf_desc_init_data.is_16bit_pipeline  = 0;
6034
6035
    // Enhanced Picture Buffer
6036
2.41k
    {
6037
2.41k
        EbPictureBufferDesc* buf;
6038
2.41k
        if (!noy8b) {
6039
0
            EB_NEW(buf, svt_picture_buffer_desc_ctor, (EbPtr)&input_pic_buf_desc_init_data);
6040
2.41k
        } else {
6041
2.41k
            EB_NEW(buf, svt_picture_buffer_desc_ctor_noy8b, (EbPtr)&input_pic_buf_desc_init_data);
6042
2.41k
        }
6043
2.41k
        input_buffer->p_buffer = (uint8_t*)buf;
6044
2.41k
    }
6045
6046
0
    return return_error;
6047
2.41k
}
6048
6049
/*
6050
  allocate an input sample Luma-8bit buffer
6051
*/
6052
2.41k
static EbErrorType allocate_y8b_frame_buffer(SequenceControlSet* scs, EbBufferHeaderType* input_buffer) {
6053
2.41k
    EbErrorType                 return_error = EB_ErrorNone;
6054
2.41k
    EbPictureBufferDescInitData input_pic_buf_desc_init_data;
6055
2.41k
    EbSvtAv1EncConfiguration*   config   = &scs->static_config;
6056
2.41k
    uint8_t                     is_16bit = 0;
6057
6058
2.41k
    input_pic_buf_desc_init_data.max_width = !(scs->max_input_luma_width % 8)
6059
2.41k
        ? scs->max_input_luma_width
6060
2.41k
        : scs->max_input_luma_width + (scs->max_input_luma_width % 8);
6061
6062
2.41k
    input_pic_buf_desc_init_data.max_height   = !(scs->max_input_luma_height % 8)
6063
2.41k
        ? scs->max_input_luma_height
6064
2.41k
        : scs->max_input_luma_height + (scs->max_input_luma_height % 8);
6065
2.41k
    input_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
6066
2.41k
    input_pic_buf_desc_init_data.color_format = (EbColorFormat)config->encoder_color_format;
6067
6068
2.41k
    input_pic_buf_desc_init_data.border = scs->border;
6069
6070
2.41k
    input_pic_buf_desc_init_data.split_mode = is_16bit ? true : false;
6071
6072
2.41k
    input_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_LUMA_MASK; //allocate for 8bit Luma only
6073
2.41k
    input_pic_buf_desc_init_data.is_16bit_pipeline  = 0;
6074
6075
    // Enhanced Picture Buffer
6076
2.41k
    {
6077
2.41k
        EbPictureBufferDesc* buf;
6078
2.41k
        EB_NEW(buf, svt_picture_buffer_desc_ctor, (EbPtr)&input_pic_buf_desc_init_data);
6079
2.41k
        input_buffer->p_buffer = (uint8_t*)buf;
6080
2.41k
    }
6081
6082
0
    return return_error;
6083
2.41k
}
6084
6085
/*
6086
  create a luma 8bit buffer descriptor
6087
*/
6088
2.41k
EbErrorType svt_input_y8b_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6089
2.41k
    EbBufferHeaderType* input_buffer;
6090
2.41k
    SequenceControlSet* scs = (SequenceControlSet*)object_init_data_ptr;
6091
6092
2.41k
    *object_dbl_ptr = NULL;
6093
2.41k
    EB_CALLOC(input_buffer, 1, sizeof(EbBufferHeaderType));
6094
2.41k
    *object_dbl_ptr = (EbPtr)input_buffer;
6095
    // Initialize Header
6096
2.41k
    input_buffer->size = sizeof(EbBufferHeaderType);
6097
6098
2.41k
    EbErrorType return_error = allocate_y8b_frame_buffer(scs, input_buffer);
6099
2.41k
    if (return_error != EB_ErrorNone) {
6100
0
        return return_error;
6101
0
    }
6102
6103
2.41k
    input_buffer->p_app_private = NULL;
6104
6105
2.41k
    return EB_ErrorNone;
6106
2.41k
}
6107
6108
/*
6109
  free a luma 8bit buffer descriptor
6110
*/
6111
2.41k
void svt_input_y8b_destroyer(EbPtr p) {
6112
2.41k
    EbBufferHeaderType*  obj = (EbBufferHeaderType*)p;
6113
2.41k
    EbPictureBufferDesc* buf = (EbPictureBufferDesc*)obj->p_buffer;
6114
2.41k
    if (buf) {
6115
2.41k
        EB_FREE_ALIGNED_ARRAY(buf->y_buffer_bit_inc);
6116
2.41k
        EB_FREE_ALIGNED_ARRAY(buf->u_buffer_bit_inc);
6117
2.41k
        EB_FREE_ALIGNED_ARRAY(buf->v_buffer_bit_inc);
6118
2.41k
    }
6119
6120
2.41k
    EB_DELETE(buf);
6121
2.41k
    EB_FREE(obj);
6122
2.41k
}
6123
6124
/**************************************
6125
* EbBufferHeaderType Constructor
6126
**************************************/
6127
2.41k
EbErrorType svt_input_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6128
2.41k
    EbBufferHeaderType* input_buffer;
6129
2.41k
    SequenceControlSet* scs = (SequenceControlSet*)object_init_data_ptr;
6130
6131
2.41k
    *object_dbl_ptr = NULL;
6132
2.41k
    EB_CALLOC(input_buffer, 1, sizeof(EbBufferHeaderType));
6133
2.41k
    *object_dbl_ptr = (EbPtr)input_buffer;
6134
    // Initialize Header
6135
2.41k
    input_buffer->size = sizeof(EbBufferHeaderType);
6136
6137
2.41k
    EbErrorType return_error = allocate_frame_buffer(scs, input_buffer, true);
6138
2.41k
    if (return_error != EB_ErrorNone) {
6139
0
        return return_error;
6140
0
    }
6141
6142
2.41k
    input_buffer->p_app_private = NULL;
6143
6144
2.41k
    return EB_ErrorNone;
6145
2.41k
}
6146
6147
2.41k
void svt_input_buffer_header_destroyer(EbPtr p) {
6148
2.41k
    EbBufferHeaderType*  obj = (EbBufferHeaderType*)p;
6149
2.41k
    EbPictureBufferDesc* buf = (EbPictureBufferDesc*)obj->p_buffer;
6150
2.41k
    if (buf) {
6151
2.41k
        EB_FREE_ALIGNED_ARRAY(buf->buffer_alloc);
6152
2.41k
        buf->buffer_alloc_sz  = 0;
6153
2.41k
        buf->y_buffer         = NULL;
6154
2.41k
        buf->u_buffer         = NULL;
6155
2.41k
        buf->v_buffer         = NULL;
6156
2.41k
        buf->y_buffer_bit_inc = NULL;
6157
2.41k
        buf->u_buffer_bit_inc = NULL;
6158
2.41k
        buf->v_buffer_bit_inc = NULL;
6159
2.41k
    }
6160
    // overlay candidates that were never coded keep their copy of the metadata
6161
2.41k
    svt_metadata_array_free(&obj->metadata);
6162
6163
2.41k
    EB_DELETE(buf);
6164
2.41k
    EB_FREE(obj);
6165
2.41k
}
6166
6167
0
EbErrorType svt_overlay_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6168
0
    EbBufferHeaderType* input_buffer;
6169
0
    SequenceControlSet* scs = (SequenceControlSet*)object_init_data_ptr;
6170
6171
0
    *object_dbl_ptr = NULL;
6172
0
    EB_CALLOC(input_buffer, 1, sizeof(EbBufferHeaderType));
6173
0
    *object_dbl_ptr = (EbPtr)input_buffer;
6174
    // Initialize Header
6175
0
    input_buffer->size = sizeof(EbBufferHeaderType);
6176
6177
0
    EbErrorType return_error = allocate_frame_buffer(scs, input_buffer, false);
6178
0
    if (return_error != EB_ErrorNone) {
6179
0
        return return_error;
6180
0
    }
6181
6182
0
    input_buffer->p_app_private = NULL;
6183
6184
0
    return EB_ErrorNone;
6185
0
}
6186
6187
/**************************************
6188
* EbBufferHeaderType Constructor
6189
**************************************/
6190
8.45k
EbErrorType svt_output_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6191
8.45k
    (void)object_init_data_ptr;
6192
8.45k
    EbBufferHeaderType* out_buf_ptr;
6193
6194
8.45k
    *object_dbl_ptr = NULL;
6195
8.45k
    EB_CALLOC(out_buf_ptr, 1, sizeof(EbBufferHeaderType));
6196
8.45k
    *object_dbl_ptr = (EbPtr)out_buf_ptr;
6197
6198
    // Initialize Header
6199
8.45k
    out_buf_ptr->size = sizeof(EbBufferHeaderType);
6200
    // p_buffer and n_alloc_len are dynamically set in EbPacketizationProcess
6201
    // out_buf_ptr->n_alloc_len;
6202
8.45k
    out_buf_ptr->p_app_private = NULL;
6203
6204
8.45k
    return EB_ErrorNone;
6205
8.45k
}
6206
6207
8.45k
void svt_output_buffer_header_destroyer(EbPtr p) {
6208
8.45k
    EbBufferHeaderType* obj = (EbBufferHeaderType*)p;
6209
    // a hidden frame still waiting for its show_existing_frame holds that frame's metadata
6210
8.45k
    svt_metadata_array_free(&obj->metadata);
6211
8.45k
    EB_FREE(obj);
6212
8.45k
}
6213
6214
/**************************************
6215
* EbBufferHeaderType Constructor
6216
**************************************/
6217
0
EbErrorType svt_output_recon_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6218
0
    EbBufferHeaderType* recon_buffer;
6219
0
    SequenceControlSet* scs       = (SequenceControlSet*)object_init_data_ptr;
6220
0
    const uint32_t      luma_size = scs->seq_header.max_frame_width * scs->seq_header.max_frame_height;
6221
    // Chroma width/height should be re-derived using the chroma width/height instead of shifting the
6222
    // luma_size because for odd dimensions, the size of each chroma component may not be exactly a quarter of
6223
    // the luma size. The chroma_size variable includes U and V planes.
6224
0
    const int      ss_x        = scs->subsampling_x;
6225
0
    const int      ss_y        = scs->subsampling_y;
6226
0
    const uint32_t chroma_size = (((scs->seq_header.max_frame_width + ss_x) >> ss_x) *
6227
0
                                  ((scs->seq_header.max_frame_height + ss_y) >> ss_y)) *
6228
0
        2 /*u + v*/;
6229
0
    const uint32_t ten_bit    = (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) > 8);
6230
0
    const uint32_t frame_size = (luma_size + chroma_size) << ten_bit;
6231
6232
0
    *object_dbl_ptr = NULL;
6233
0
    EB_CALLOC(recon_buffer, 1, sizeof(EbBufferHeaderType));
6234
0
    *object_dbl_ptr = (EbPtr)recon_buffer;
6235
6236
    // Initialize Header
6237
0
    recon_buffer->size = sizeof(EbBufferHeaderType);
6238
6239
    // Assign the variables
6240
0
    EB_MALLOC(recon_buffer->p_buffer, frame_size);
6241
6242
0
    recon_buffer->n_alloc_len   = frame_size;
6243
0
    recon_buffer->p_app_private = NULL;
6244
6245
0
    return EB_ErrorNone;
6246
0
}
6247
6248
0
void svt_output_recon_buffer_header_destroyer(EbPtr p) {
6249
0
    EbBufferHeaderType* obj = (EbBufferHeaderType*)p;
6250
0
    EB_FREE(obj->p_buffer);
6251
0
    EB_FREE(obj);
6252
0
}
6253
6254
/**********************************
6255
* svt_av1_enc_get_stream_info get stream information from encoder
6256
**********************************/
6257
EB_API EbErrorType svt_av1_enc_get_stream_info(EbComponentType* svt_enc_component, uint32_t stream_info_id,
6258
0
                                               void* info) {
6259
0
    if (stream_info_id >= SVT_AV1_STREAM_INFO_END || stream_info_id < SVT_AV1_STREAM_INFO_START) {
6260
0
        return EB_ErrorBadParameter;
6261
0
    }
6262
0
    EbEncHandle*    enc_handle       = svt_enc_component->p_component_private;
6263
0
    EncodeContext*  context          = enc_handle->scs_instance->enc_ctx;
6264
0
    SvtAv1FixedBuf* first_pass_stats = info;
6265
0
    first_pass_stats->buf            = context->stats_out.stat;
6266
0
    first_pass_stats->sz             = context->stats_out.size * sizeof(FIRSTPASS_STATS);
6267
0
    return EB_ErrorNone;
6268
0
}