Coverage Report

Created: 2026-09-01 06:57

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