Coverage Report

Created: 2026-08-13 07:23

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