Coverage Report

Created: 2026-06-15 06:25

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