Coverage Report

Created: 2026-10-17 06:56

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