Coverage Report

Created: 2026-06-10 07:00

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
430
#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
430
#define EB_PictureManagerProcessInitCount               1
88
#define EB_RateControlProcessInitCount                  1
89
860
#define EB_PacketizationProcessInitCount                1
90
91
// Output Buffer Transfer Parameters
92
430
#define TPL_INPUT_PORT_SOP                              0
93
430
#define TPL_INPUT_PORT_TPL                              1
94
2.63k
#define TPL_INPUT_PORT_INVALID                          -1
95
430
#define ENCDEC_INPUT_PORT_MDC                           0
96
430
#define ENCDEC_INPUT_PORT_ENCDEC                        1
97
2.63k
#define ENCDEC_INPUT_PORT_INVALID                       -1
98
99
860
#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
430
static uint16_t get_num_refs_in_one_mg(uint32_t hierarchical_levels, uint32_t referencing_scheme) {
106
430
    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
430
    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
860
        tot_refs += svt_aom_is_pic_used_as_ref(
117
860
            hierarchical_levels, hierarchical_levels, pic_idx, referencing_scheme, 0);
118
860
    }
119
120
430
    return tot_refs;
121
430
}
122
123
860
static const char* get_asm_level_name_str(EbCpuFlags cpu_flags) {
124
    // clang-format off
125
860
    static const struct {
126
860
        const char *name;
127
860
        EbCpuFlags  flags;
128
860
    } param_maps[] = {
129
860
        {"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
860
    };
151
    // clang-format on
152
860
    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
860
        if (param_maps[i].flags & cpu_flags) {
156
0
            return param_maps[i].name;
157
0
        }
158
860
    }
159
860
    return "c";
160
860
}
161
162
//Get Number of logical processors
163
430
static uint32_t get_num_processors() {
164
#ifdef _WIN32
165
    return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
166
#else
167
430
    return sysconf(_SC_NPROCESSORS_ONLN);
168
430
#endif
169
430
}
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
430
static void enc_switch_to_real_time() {
181
430
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
182
430
    if (!geteuid()) {
183
430
        (void)pthread_setschedparam(pthread_self(), SCHED_FIFO, &(struct sched_param){.sched_priority = 99});
184
430
    }
185
430
#endif
186
430
}
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
860
static uint32_t get_max_wavefronts(uint32_t width, uint32_t height, uint32_t blk_size) {
209
860
    assert(width > 0 && height > 0);
210
860
    return (MIN(width, height) + (blk_size - 1)) / blk_size;
211
860
}
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
430
void set_segments_numbers(SequenceControlSet* scs) {
227
430
    const uint32_t lp = scs->lp;
228
229
430
    scs->enc_dec_segment_row_count_array =
230
430
        (lp == PARALLEL_LEVEL_1 || is_pic_dimension_single_sb(scs->super_block_size, scs->max_input_luma_width)) ? 1
231
430
        : (scs->super_block_size == 128) ? MAX((int32_t)((scs->max_input_luma_height + 64) / 128), 1)
232
402
                                         : MAX((int32_t)((scs->max_input_luma_height + 32) / 64), 1);
233
430
    scs->enc_dec_segment_col_count_array =
234
430
        (lp == PARALLEL_LEVEL_1 || is_pic_dimension_single_sb(scs->super_block_size, scs->max_input_luma_height)) ? 1
235
430
        : (scs->super_block_size == 128) ? MAX((int32_t)((scs->max_input_luma_width + 64) / 128), 1)
236
407
                                         : MAX((int32_t)((scs->max_input_luma_width + 32) / 64), 1);
237
238
430
    scs->me_segment_row_count_array = scs->tf_segment_row_count = (lp == PARALLEL_LEVEL_1) ? 1
239
430
        : (((scs->max_input_luma_height + 32) / BLOCK_SIZE_64) < 6)                        ? 1
240
430
                                                                                           : 8;
241
430
    scs->me_segment_col_count_array = scs->tf_segment_column_count = (lp == PARALLEL_LEVEL_1) ? 1
242
430
        : (((scs->max_input_luma_width + 32) / BLOCK_SIZE_64) < 10)                           ? 1
243
430
                                                                                              : 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
430
    scs->tile_group_col_count_array = 1;
252
430
    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
430
    scs->tpl_segment_row_count_array = (lp == PARALLEL_LEVEL_1 ||
256
430
                                        is_pic_dimension_single_sb(64, scs->max_input_luma_width))
257
430
        ? 1
258
430
        : MAX((int32_t)((scs->max_input_luma_height + 32) / 64), 1);
259
260
430
    scs->tpl_segment_col_count_array = (lp == PARALLEL_LEVEL_1)
261
430
        ? 1
262
430
        : MAX((int32_t)((scs->max_input_luma_width + 32) / 64), 1);
263
264
430
    scs->cdef_segment_row_count    = (lp == PARALLEL_LEVEL_1)          ? 1
265
430
           : (((scs->max_input_luma_height + 32) / BLOCK_SIZE_64) < 6) ? 1
266
430
           : (scs->input_resolution <= INPUT_SIZE_1080p_RANGE)         ? 2
267
0
                                                                       : 4;
268
430
    scs->cdef_segment_column_count = (lp == PARALLEL_LEVEL_1)       ? 1
269
430
        : (((scs->max_input_luma_width + 32) / BLOCK_SIZE_64) < 10) ? 1
270
430
        : (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
430
    const uint32_t unit_size       = RESTORATION_UNITSIZE_MAX;
276
430
    const uint32_t rest_seg_w      = MAX((scs->max_input_luma_width / 2 + (unit_size >> 1)) / unit_size, 1);
277
430
    const uint32_t rest_seg_h      = MAX((scs->max_input_luma_height / 2 + (unit_size >> 1)) / unit_size, 1);
278
430
    scs->rest_segment_column_count = (lp == PARALLEL_LEVEL_1) ? 1
279
430
        : scs->input_resolution <= INPUT_SIZE_1080p_RANGE     ? MIN(rest_seg_w, 6)
280
430
                                                              : MIN(rest_seg_w, 9);
281
430
    scs->rest_segment_row_count    = (lp == PARALLEL_LEVEL_1) ? 1
282
430
           : scs->input_resolution <= INPUT_SIZE_1080p_RANGE  ? MIN(rest_seg_h, 4)
283
430
                                                              : MIN(rest_seg_h, 6);
284
430
}
285
286
430
static EbErrorType load_default_buffer_configuration_settings(SequenceControlSet* scs) {
287
430
    EbErrorType return_error = EB_ErrorNone;
288
430
    uint32_t    core_count   = get_num_processors();
289
290
430
    uint32_t lp = scs->static_config.level_of_parallelism;
291
430
    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
430
    scs->lp = lp;
309
430
    set_segments_numbers(scs);
310
311
430
    const bool is_low_delay = (scs->static_config.pred_structure == LOW_DELAY);
312
    // adjust buffer count for superres
313
430
    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
430
        ? 1
317
430
        : 0;
318
319
    //#====================== Data Structures and Picture Buffers ======================
320
321
430
    uint32_t min_input, min_parent, min_child, min_paref, min_ref, min_tpl_ref, min_overlay, min_recon, min_me;
322
430
    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
430
    uint32_t      mg_size = 1 << scs->static_config.hierarchical_levels;
327
430
    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
430
    const uint8_t eos_delay = is_low_delay || scs->allintra ? 0 : 1;
333
334
    //Minimum input pictures needed in the pipeline
335
430
    uint16_t lad_mg_pictures = (1 + mg_size + overlay) *
336
430
        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
430
    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
430
    min_input = return_ppcs;
341
342
430
    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
430
    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
430
    min_child                          = 1;
351
430
    const uint16_t num_ref_from_cur_mg = get_num_refs_in_one_mg(scs->static_config.hierarchical_levels,
352
430
                                                                scs->mrp_ctrls.referencing_scheme) +
353
430
        1; //+1: to accomodate one for a delayed-I
354
430
    const uint16_t num_ref_lad_mgs = num_ref_from_cur_mg * scs->lad_mg;
355
430
    const uint8_t  dpb_frames =
356
430
        REF_FRAMES; // up to dpb_frame refs from prev MGs can be used (AV1 spec allows holding up to 8 frames for references)
357
430
    min_ref     = (scs->enable_dec_order) ? dpb_frames + 1 : num_ref_from_cur_mg + num_ref_lad_mgs + dpb_frames;
358
430
    min_tpl_ref = scs->tpl ? dpb_frames + 1 : 0; // TPL pictures are processed in decode order
359
430
    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
430
    } else {
365
430
        min_me = 1;
366
430
    }
367
368
    //PA REF
369
430
    const uint16_t num_pa_ref_from_cur_mg =
370
430
        mg_size; //ref+nref; nRef PA buffers are processed in PicAnalysis and used in TF
371
430
    min_paref = num_pa_ref_from_cur_mg + lad_mg_pictures + scs->scd_delay + eos_delay + dpb_frames;
372
373
430
    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
430
    min_overlay = scs->static_config.enable_overlays ? return_ppcs : 0;
381
430
    min_recon   = min_ref;
382
383
430
    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
430
    uint32_t n_extra_mg;
416
430
    if (lp <= PARALLEL_LEVEL_3 || is_low_delay) {
417
0
        n_extra_mg = 0;
418
430
    } else if (lp <= PARALLEL_LEVEL_4) {
419
430
        n_extra_mg = 1;
420
430
    } 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
430
    max_input  = min_input + (1 + mg_size) * n_extra_mg;
429
430
    max_parent = max_input;
430
430
    max_child  = (mg_size / 2) * (n_extra_mg + 1);
431
430
    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
430
    if (is_low_delay) {
434
0
        max_child = 1;
435
0
    }
436
437
    // max_ref defines here to avoid cppcheck warning
438
430
    uint32_t max_ref = min_ref + num_ref_from_cur_mg * n_extra_mg;
439
430
    max_paref        = min_paref + (1 + mg_size) * n_extra_mg;
440
430
    max_me           = min_me + (1 + mg_size) * n_extra_mg;
441
430
    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
430
    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
430
    scs->input_buffer_fifo_init_count            = clamp(max_input, min_input, max_input);
450
430
    scs->picture_control_set_pool_init_count     = clamp(max_parent, min_parent, max_parent);
451
430
    scs->pa_reference_picture_buffer_init_count  = clamp(max_paref, min_paref, max_paref);
452
430
    scs->tpl_reference_picture_buffer_init_count = min_tpl_ref;
453
430
    scs->output_recon_buffer_fifo_init_count = scs->reference_picture_buffer_init_count = clamp(
454
430
        max_recon, min_recon, max_recon);
455
430
    scs->me_pool_init_count                      = clamp(max_me, min_me, max_me);
456
430
    scs->overlay_input_picture_buffer_init_count = min_overlay;
457
458
430
    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
430
    } 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
430
    } 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
430
    } else if (lp <= PARALLEL_LEVEL_4) {
486
430
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count = clamp(
487
430
                                                                                            12, min_child, max_child) +
488
430
            superres_count;
489
430
    } 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
430
    if (scs->static_config.avif) {
503
430
        scs->input_buffer_fifo_init_count              = 4;
504
430
        scs->picture_control_set_pool_init_count       = 4;
505
430
        scs->pa_reference_picture_buffer_init_count    = 4;
506
430
        scs->tpl_reference_picture_buffer_init_count   = 0;
507
430
        scs->output_recon_buffer_fifo_init_count       = 1;
508
430
        scs->reference_picture_buffer_init_count       = 2;
509
430
        scs->picture_control_set_pool_init_count_child = 1;
510
430
        scs->enc_dec_pool_init_count                   = 1;
511
430
        scs->me_pool_init_count                        = 1;
512
430
        scs->overlay_input_picture_buffer_init_count   = 0;
513
430
        scs->allintra                                  = true;
514
430
        scs->static_config.intra_period_length         = 0;
515
430
    }
516
517
    //#====================== Inter process Fifos ======================
518
430
    const uint32_t tot_tf_segs  = scs->tf_segment_column_count * scs->tf_segment_row_count;
519
430
    const uint32_t tot_me_segs  = scs->me_segment_col_count_array * scs->me_segment_row_count_array;
520
430
    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
430
    const bool     allow_recode     = scs->static_config.recode_loop != DISALLOW_RECODE;
524
430
    const bool     is_superres      = scs->static_config.superres_mode != SUPERRES_NONE;
525
430
    const uint32_t tot_enc_dec_segs = scs->enc_dec_segment_col_count_array * scs->enc_dec_segment_row_count_array;
526
430
    const uint32_t tot_cdef_segs    = scs->cdef_segment_column_count * scs->cdef_segment_row_count;
527
430
    const uint32_t tot_rest_segs    = scs->rest_segment_column_count * scs->rest_segment_row_count;
528
430
    const uint32_t tot_tiles        = MIN(9,
529
430
                                   (1 << scs->static_config.tile_columns) *
530
430
                                       (1 << scs->static_config.tile_rows)); //Jing: Too many tiles may drain the fifo
531
430
    const uint32_t max_fifo         = 300;
532
533
    // Open loop
534
430
    scs->resource_coordination_fifo_init_count = MIN(
535
430
        max_fifo, scs->picture_control_set_pool_init_count); // outputs one pic @ a time to pic analysis (no segments)
536
430
    scs->picture_analysis_fifo_init_count = MIN(
537
430
        max_fifo, scs->picture_control_set_pool_init_count); // output from pic analysis to PD process (single threaded)
538
430
    scs->enc_ctx->picture_decision_reorder_queue_size = scs->picture_control_set_pool_init_count;
539
430
    scs->picture_decision_fifo_init_count             = MIN(
540
430
        max_fifo, scs->picture_control_set_pool_init_count * MAX(tot_me_segs, tot_tf_segs));
541
430
    scs->motion_estimation_fifo_init_count = MIN(
542
430
        max_fifo, scs->picture_control_set_pool_init_count); // output from ME to init_rc_process (single threaded)
543
430
    scs->initial_rate_control_fifo_init_count = MIN(
544
430
        max_fifo, scs->picture_control_set_pool_init_count); // output from irc to src_ops (single threaded)
545
430
    scs->tpl_disp_fifo_init_count = MIN(max_fifo,
546
430
                                        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
430
    scs->picture_demux_fifo_init_count = MIN(
550
430
        max_fifo,
551
430
        scs->picture_control_set_pool_init_count +
552
430
            2 * scs->picture_control_set_pool_init_count_child); // input to pic mgr from src ops, rest, and packetization
553
430
    scs->enc_ctx->pic_mgr_input_pic_list_size = scs->picture_control_set_pool_init_count;
554
555
    // Closed loop
556
430
    scs->rate_control_tasks_fifo_init_count = MIN(
557
430
        max_fifo,
558
430
        2 * scs->picture_control_set_pool_init_count_child); // inputs to rc form pic manager and EC/packetization
559
430
    scs->rate_control_fifo_init_count                = MIN(max_fifo,
560
430
                                            scs->picture_control_set_pool_init_count_child); // inputs to MDC from rc
561
430
    scs->mode_decision_configuration_fifo_init_count = MIN(
562
430
        max_fifo,
563
430
        scs->picture_control_set_pool_init_count_child * tot_tiles * tot_enc_dec_segs *
564
430
            (1 + allow_recode + is_superres)); // input to MD from MDC
565
430
    scs->enc_dec_fifo_init_count = MIN(max_fifo,
566
430
                                       scs->picture_control_set_pool_init_count_child); // TODO: Add DLF segments
567
430
    scs->dlf_fifo_init_count     = MIN(
568
430
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_cdef_segs); // input to CDEF from DLF
569
430
    scs->cdef_fifo_init_count = MIN(
570
430
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_rest_segs); // input to rest from CDEF
571
430
    scs->rest_fifo_init_count = MIN(
572
430
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_tiles); // input to EC from rest
573
430
    scs->entropy_coding_fifo_init_count = MIN(
574
430
        max_fifo, scs->picture_control_set_pool_init_count_child); // EC outputs to packetization (single threaded)
575
430
    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
430
    scs->output_stream_buffer_fifo_init_count = scs->picture_control_set_pool_init_count +
578
430
        2; // +2 b/c used to signal EOS @ resource coord and packetization
579
    //#====================== Processes number ======================
580
430
    scs->total_process_init_count = 0;
581
582
430
    uint32_t max_pa_proc, max_me_proc, max_tpl_proc, max_mdc_proc, max_md_proc, max_ec_proc, max_dlf_proc,
583
430
        max_cdef_proc, max_rest_proc;
584
585
430
    max_pa_proc  = max_input;
586
430
    max_me_proc  = max_me * tot_me_segs;
587
430
    max_tpl_proc = get_max_wavefronts(scs->max_input_luma_width, scs->max_input_luma_height, 64);
588
430
    max_mdc_proc = scs->picture_control_set_pool_init_count_child;
589
430
    max_md_proc  = scs->picture_control_set_pool_init_count_child *
590
430
        get_max_wavefronts(scs->max_input_luma_width, scs->max_input_luma_height, scs->super_block_size);
591
430
    max_ec_proc   = scs->picture_control_set_pool_init_count_child;
592
430
    max_dlf_proc  = scs->picture_control_set_pool_init_count_child;
593
430
    max_cdef_proc = scs->picture_control_set_pool_init_count_child * scs->cdef_segment_column_count *
594
430
        scs->cdef_segment_row_count;
595
430
    max_rest_proc = scs->picture_control_set_pool_init_count_child * scs->rest_segment_column_count *
596
430
        scs->rest_segment_row_count;
597
598
430
    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
430
    } 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
430
    } 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
430
    } else if (lp <= PARALLEL_LEVEL_5 || scs->input_resolution <= INPUT_SIZE_1080p_RANGE) {
640
430
        uint8_t pa_processes = scs->static_config.film_grain_denoise_strength ? 20 : 4;
641
430
        if (scs->static_config.pass == ENC_FIRST_PASS) {
642
0
            pa_processes = lp <= PARALLEL_LEVEL_5 ? 12 : 20;
643
0
        }
644
430
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
645
430
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = clamp(
646
430
                                              pa_processes, 1, max_pa_proc));
647
430
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = clamp(25, 1, max_me_proc));
648
430
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = clamp(6, 1, max_tpl_proc));
649
430
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = clamp(
650
430
                                              3, 1, max_mdc_proc));
651
430
        scs->total_process_init_count += (scs->enc_dec_process_init_count = clamp(
652
430
                                              6, scs->picture_control_set_pool_init_count_child, max_md_proc));
653
430
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = clamp(4, 1, max_ec_proc));
654
430
        scs->total_process_init_count += (scs->dlf_process_init_count = clamp(3, 1, max_dlf_proc));
655
430
        scs->total_process_init_count += (scs->cdef_process_init_count = clamp(6, 1, max_cdef_proc));
656
430
        scs->total_process_init_count += (scs->rest_process_init_count = clamp(4, 1, max_rest_proc));
657
430
    } 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
430
    scs->total_process_init_count += 6; // single processes count
678
430
    if (scs->static_config.pass == 0 || scs->static_config.pass == 2) {
679
430
        SVT_INFO("Level of Parallelism: %u\n", lp);
680
430
        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
430
        scs->static_config.use_cpu_flags &= 0;
693
430
        SVT_INFO("[asm level on system : up to %s]\n", get_asm_level_name_str(0));
694
430
        SVT_INFO("[asm level selected : up to %s]\n", get_asm_level_name_str(scs->static_config.use_cpu_flags));
695
430
#endif
696
430
    }
697
430
    return return_error;
698
430
}
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
860
static uint32_t rate_control_port_lookup(RateControlInputPortTypes type, uint32_t port_type_index) {
733
860
    uint32_t port_index = 0;
734
860
    uint32_t port_count = 0;
735
736
1.29k
    while ((type != rate_control_ports[port_index].type) && (type != RATE_CONTROL_INPUT_PORT_INVALID)) {
737
430
        port_count += rate_control_ports[port_index++].count;
738
430
    }
739
860
    return (port_count + port_type_index);
740
860
}
741
742
// Rate Control
743
430
static uint32_t rate_control_port_total_count(void) {
744
430
    uint32_t port_index  = 0;
745
430
    uint32_t total_count = 0;
746
747
1.29k
    while (rate_control_ports[port_index].type != RATE_CONTROL_INPUT_PORT_INVALID) {
748
860
        total_count += rate_control_ports[port_index++].count;
749
860
    }
750
430
    return total_count;
751
430
}
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
430
static uint32_t pic_mgr_port_total_count(void) {
764
430
    uint32_t port_index  = 0;
765
430
    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
430
    return total_count;
771
430
}
772
773
// TPL
774
1.77k
static uint32_t tpl_port_lookup(int32_t type, uint32_t port_type_index) {
775
1.77k
    uint32_t port_index = 0;
776
1.77k
    uint32_t port_count = 0;
777
778
3.11k
    while ((type != tpl_ports[port_index].type) && (type != TPL_INPUT_PORT_INVALID)) {
779
1.34k
        port_count += tpl_ports[port_index++].count;
780
1.34k
    }
781
1.77k
    return (port_count + port_type_index);
782
1.77k
}
783
784
430
static uint32_t tpl_port_total_count(void) {
785
430
    uint32_t port_index  = 0;
786
430
    uint32_t total_count = 0;
787
788
1.29k
    while (tpl_ports[port_index].type != TPL_INPUT_PORT_INVALID) {
789
860
        total_count += tpl_ports[port_index++].count;
790
860
    }
791
430
    return total_count;
792
430
}
793
794
/*****************************************
795
 * Input Port Lookup
796
 *****************************************/
797
// EncDec
798
1.77k
static uint32_t enc_dec_port_lookup(int32_t type, uint32_t port_type_index) {
799
1.77k
    uint32_t port_index = 0;
800
1.77k
    uint32_t port_count = 0;
801
802
3.11k
    while ((type != enc_dec_ports[port_index].type) && (type != ENCDEC_INPUT_PORT_INVALID)) {
803
1.34k
        port_count += enc_dec_ports[port_index++].count;
804
1.34k
    }
805
1.77k
    return (port_count + port_type_index);
806
1.77k
}
807
808
// EncDec
809
430
static uint32_t enc_dec_port_total_count(void) {
810
430
    uint32_t port_index  = 0;
811
430
    uint32_t total_count = 0;
812
813
1.29k
    while (enc_dec_ports[port_index].type != ENCDEC_INPUT_PORT_INVALID) {
814
860
        total_count += enc_dec_ports[port_index++].count;
815
860
    }
816
430
    return total_count;
817
430
}
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
430
static void svt_enc_handle_stop_threads(EbEncHandle* enc_handle_ptr) {
826
430
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
827
    // Resource Coordination
828
430
    EB_DESTROY_THREAD(enc_handle_ptr->resource_coordination_thread_handle);
829
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->picture_analysis_thread_handle_array,
830
430
                            scs->picture_analysis_process_init_count);
831
832
    // Picture Decision
833
430
    EB_DESTROY_THREAD(enc_handle_ptr->picture_decision_thread_handle);
834
835
    // Motion Estimation
836
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->motion_estimation_thread_handle_array,
837
430
                            scs->motion_estimation_process_init_count);
838
839
    // Initial Rate Control
840
430
    EB_DESTROY_THREAD(enc_handle_ptr->initial_rate_control_thread_handle);
841
842
    // Source Based Oprations
843
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->source_based_operations_thread_handle_array,
844
430
                            scs->source_based_operations_process_init_count);
845
846
    // TPL dispenser ME
847
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->tpl_disp_thread_handle_array, scs->tpl_disp_process_init_count);
848
849
    // Picture Manager
850
430
    EB_DESTROY_THREAD(enc_handle_ptr->picture_manager_thread_handle);
851
852
    // Rate Control
853
430
    EB_DESTROY_THREAD(enc_handle_ptr->rate_control_thread_handle);
854
855
    // Mode Decision Configuration Process
856
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->mode_decision_configuration_thread_handle_array,
857
430
                            scs->mode_decision_configuration_process_init_count);
858
859
    // EncDec Process
860
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->enc_dec_thread_handle_array, scs->enc_dec_process_init_count);
861
862
    // Dlf Process
863
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->dlf_thread_handle_array, scs->dlf_process_init_count);
864
865
    // Cdef Process
866
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->cdef_thread_handle_array, scs->cdef_process_init_count);
867
868
    // Rest Process
869
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->rest_thread_handle_array, scs->rest_process_init_count);
870
871
    // Entropy Coding Process
872
430
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->entropy_coding_thread_handle_array, scs->entropy_coding_process_init_count);
873
874
    // Packetization
875
430
    EB_DESTROY_THREAD(enc_handle_ptr->packetization_thread_handle);
876
430
}
877
878
/**********************************
879
* Encoder Library Handle Deonstructor
880
**********************************/
881
430
static void svt_enc_handle_dctor(EbPtr p) {
882
430
    EbEncHandle* enc_handle_ptr = (EbEncHandle*)p;
883
430
    svt_enc_handle_stop_threads(enc_handle_ptr);
884
430
    EB_FREE(enc_handle_ptr->app_callback_ptr);
885
430
    EB_DELETE(enc_handle_ptr->scs_pool_ptr);
886
430
    EB_DELETE(enc_handle_ptr->picture_parent_control_set_pool_ptr);
887
430
    EB_DELETE(enc_handle_ptr->me_pool_ptr);
888
430
    EB_DELETE(enc_handle_ptr->picture_control_set_pool_ptr);
889
430
    EB_DELETE(enc_handle_ptr->enc_dec_pool_ptr);
890
430
    EB_DELETE(enc_handle_ptr->pa_reference_picture_pool_ptr);
891
430
    EB_DELETE(enc_handle_ptr->tpl_reference_picture_pool_ptr);
892
430
    EB_DELETE(enc_handle_ptr->overlay_input_picture_pool_ptr);
893
430
    EB_DELETE(enc_handle_ptr->reference_picture_pool_ptr);
894
430
    EB_DELETE(enc_handle_ptr->input_cmd_resource_ptr);
895
430
    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
430
    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
430
    }
907
430
    EB_DELETE(enc_handle_ptr->input_buffer_resource_ptr);
908
430
    EB_DELETE(enc_handle_ptr->output_stream_buffer_resource_ptr);
909
430
    EB_DELETE(enc_handle_ptr->output_recon_buffer_resource_ptr);
910
430
    EB_DELETE(enc_handle_ptr->resource_coordination_results_resource_ptr);
911
430
    EB_DELETE(enc_handle_ptr->picture_analysis_results_resource_ptr);
912
430
    EB_DELETE(enc_handle_ptr->picture_decision_results_resource_ptr);
913
430
    EB_DELETE(enc_handle_ptr->motion_estimation_results_resource_ptr);
914
430
    EB_DELETE(enc_handle_ptr->initial_rate_control_results_resource_ptr);
915
430
    EB_DELETE(enc_handle_ptr->picture_demux_results_resource_ptr);
916
430
    EB_DELETE(enc_handle_ptr->tpl_disp_res_srm);
917
430
    EB_DELETE(enc_handle_ptr->rate_control_tasks_resource_ptr);
918
430
    EB_DELETE(enc_handle_ptr->rate_control_results_resource_ptr);
919
430
    EB_DELETE(enc_handle_ptr->enc_dec_tasks_resource_ptr);
920
430
    EB_DELETE(enc_handle_ptr->enc_dec_results_resource_ptr);
921
430
    EB_DELETE(enc_handle_ptr->dlf_results_resource_ptr);
922
430
    EB_DELETE(enc_handle_ptr->cdef_results_resource_ptr);
923
430
    EB_DELETE(enc_handle_ptr->rest_results_resource_ptr);
924
430
    EB_DELETE(enc_handle_ptr->entropy_coding_results_resource_ptr);
925
926
430
    EB_DELETE(enc_handle_ptr->resource_coordination_context_ptr);
927
430
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
928
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->picture_analysis_context_ptr_array, scs->picture_analysis_process_init_count);
929
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->motion_estimation_context_ptr_array, scs->motion_estimation_process_init_count);
930
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->tpl_disp_context_ptr_array, scs->tpl_disp_process_init_count);
931
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->source_based_operations_context_ptr_array,
932
430
                        scs->source_based_operations_process_init_count);
933
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->mode_decision_configuration_context_ptr_array,
934
430
                        scs->mode_decision_configuration_process_init_count);
935
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->enc_dec_context_ptr_array, scs->enc_dec_process_init_count);
936
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->dlf_context_ptr_array, scs->dlf_process_init_count);
937
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->cdef_context_ptr_array, scs->cdef_process_init_count);
938
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->rest_context_ptr_array, scs->rest_process_init_count);
939
430
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->entropy_coding_context_ptr_array, scs->entropy_coding_process_init_count);
940
430
    EB_DELETE(enc_handle_ptr->scs_instance);
941
430
    EB_DELETE(enc_handle_ptr->picture_decision_context_ptr);
942
430
    EB_DELETE(enc_handle_ptr->initial_rate_control_context_ptr);
943
430
    EB_DELETE(enc_handle_ptr->picture_manager_context_ptr);
944
430
    EB_DELETE(enc_handle_ptr->rate_control_context_ptr);
945
430
    EB_DELETE(enc_handle_ptr->packetization_context_ptr);
946
430
}
947
948
/**********************************
949
* Encoder Library Handle Constructor
950
**********************************/
951
430
static EbErrorType svt_enc_handle_ctor(EbEncHandle* enc_handle_ptr, EbComponentType* ebHandlePtr) {
952
430
    enc_handle_ptr->dctor = svt_enc_handle_dctor;
953
954
    // Initialize Callbacks
955
430
    EB_MALLOC_OBJECT(enc_handle_ptr->app_callback_ptr);
956
430
    enc_handle_ptr->app_callback_ptr->error_handler = lib_svt_encoder_send_error_exit;
957
430
    enc_handle_ptr->app_callback_ptr->handle        = ebHandlePtr;
958
959
    // Config Set Count
960
430
    enc_handle_ptr->scs_pool_total_count = EB_SequenceControlSetPoolInitCount;
961
    // Initialize Sequence Control Set Instance
962
430
    EB_NEW(enc_handle_ptr->scs_instance, svt_sequence_control_set_instance_ctor);
963
964
430
    enc_handle_ptr->eos_received   = false;
965
430
    enc_handle_ptr->eos_sent       = false;
966
430
    enc_handle_ptr->frame_received = false;
967
430
    enc_handle_ptr->is_prev_valid  = true;
968
430
    return EB_ErrorNone;
969
430
}
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
430
static EbErrorType dlf_results_ctor(DlfResults* context_ptr, EbPtr object_init_data_ptr) {
1007
430
    (void)context_ptr;
1008
430
    (void)object_init_data_ptr;
1009
1010
430
    return EB_ErrorNone;
1011
430
}
1012
1013
430
static EbErrorType dlf_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1014
430
    DlfResults* obj;
1015
1016
430
    *object_dbl_ptr = NULL;
1017
430
    EB_NEW(obj, dlf_results_ctor, object_init_data_ptr);
1018
430
    *object_dbl_ptr = obj;
1019
1020
430
    return EB_ErrorNone;
1021
430
}
1022
1023
/*
1024
   TPL results ctor
1025
*/
1026
17.8k
EbErrorType tpl_disp_results_ctor(TplDispResults* context_ptr, EbPtr object_init_data_ptr) {
1027
17.8k
    (void)context_ptr;
1028
17.8k
    (void)object_init_data_ptr;
1029
1030
17.8k
    return EB_ErrorNone;
1031
17.8k
}
1032
1033
/*
1034
   TPL results creator
1035
*/
1036
17.8k
static EbErrorType tpl_disp_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1037
17.8k
    TplDispResults* obj;
1038
1039
17.8k
    *object_dbl_ptr = NULL;
1040
17.8k
    EB_NEW(obj, tpl_disp_results_ctor, object_init_data_ptr);
1041
17.8k
    *object_dbl_ptr = obj;
1042
1043
17.8k
    return EB_ErrorNone;
1044
17.8k
}
1045
1046
430
static EbErrorType cdef_results_ctor(CdefResults* context_ptr, EbPtr object_init_data_ptr) {
1047
430
    (void)context_ptr;
1048
430
    (void)object_init_data_ptr;
1049
1050
430
    return EB_ErrorNone;
1051
430
}
1052
1053
430
static EbErrorType cdef_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1054
430
    CdefResults* obj;
1055
1056
430
    *object_dbl_ptr = NULL;
1057
430
    EB_NEW(obj, cdef_results_ctor, object_init_data_ptr);
1058
430
    *object_dbl_ptr = obj;
1059
1060
430
    return EB_ErrorNone;
1061
430
}
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
430
static int create_pa_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1081
430
    SequenceControlSet*             scs = enc_handle_ptr->scs_instance->scs;
1082
430
    EbPaReferenceObjectDescInitData eb_pa_ref_obj_ect_desc_init_data_structure;
1083
430
    EbPictureBufferDescInitData     ref_pic_buf_desc_init_data;
1084
430
    EbPictureBufferDescInitData     quart_pic_buf_desc_init_data;
1085
430
    EbPictureBufferDescInitData     sixteenth_pic_buf_desc_init_data;
1086
430
    const bool                      allintra = scs->allintra;
1087
    // PA Reference Picture Buffers
1088
    // Currently, only Luma samples are needed in the PA
1089
430
    ref_pic_buf_desc_init_data.max_width    = scs->max_input_luma_width;
1090
430
    ref_pic_buf_desc_init_data.max_height   = scs->max_input_luma_height;
1091
430
    ref_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
1092
430
    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
430
    ref_pic_buf_desc_init_data.buffer_enable_mask = 0;
1096
1097
430
    ref_pic_buf_desc_init_data.border              = scs->border;
1098
430
    ref_pic_buf_desc_init_data.split_mode          = false;
1099
430
    ref_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1100
430
    ref_pic_buf_desc_init_data.mfmv                = 0;
1101
430
    ref_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1102
430
    ref_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1103
1104
430
    quart_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width >> 1;
1105
430
    quart_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height >> 1;
1106
430
    quart_pic_buf_desc_init_data.bit_depth           = EB_EIGHT_BIT;
1107
430
    quart_pic_buf_desc_init_data.color_format        = EB_YUV420;
1108
430
    quart_pic_buf_desc_init_data.buffer_enable_mask  = allintra ? 0 : PICTURE_BUFFER_DESC_LUMA_MASK;
1109
430
    quart_pic_buf_desc_init_data.border              = scs->b64_size >> 1;
1110
430
    quart_pic_buf_desc_init_data.split_mode          = false;
1111
430
    quart_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1112
430
    quart_pic_buf_desc_init_data.mfmv                = 0;
1113
430
    quart_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1114
430
    quart_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1115
1116
430
    sixteenth_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width >> 2;
1117
430
    sixteenth_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height >> 2;
1118
430
    sixteenth_pic_buf_desc_init_data.bit_depth           = EB_EIGHT_BIT;
1119
430
    sixteenth_pic_buf_desc_init_data.color_format        = EB_YUV420;
1120
430
    sixteenth_pic_buf_desc_init_data.buffer_enable_mask  = allintra ? 0 : PICTURE_BUFFER_DESC_LUMA_MASK;
1121
430
    sixteenth_pic_buf_desc_init_data.border              = scs->b64_size >> 2;
1122
430
    sixteenth_pic_buf_desc_init_data.split_mode          = false;
1123
430
    sixteenth_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1124
430
    sixteenth_pic_buf_desc_init_data.mfmv                = 0;
1125
430
    sixteenth_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1126
430
    sixteenth_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1127
1128
430
    eb_pa_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1129
430
    eb_pa_ref_obj_ect_desc_init_data_structure.quarter_picture_desc_init_data   = quart_pic_buf_desc_init_data;
1130
430
    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
430
    EB_NEW(enc_handle_ptr->pa_reference_picture_pool_ptr,
1133
430
           svt_system_resource_ctor,
1134
430
           scs->pa_reference_picture_buffer_init_count,
1135
430
           EB_PictureDecisionProcessInitCount,
1136
430
           0,
1137
430
           svt_pa_reference_object_creator,
1138
430
           &(eb_pa_ref_obj_ect_desc_init_data_structure),
1139
430
           NULL,
1140
430
           (scs->lp == 1));
1141
    // Set the SequenceControlSet Picture Pool Fifo Ptrs
1142
430
    enc_handle_ptr->scs_instance->enc_ctx->pa_reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1143
430
        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
430
    return 0;
1148
430
}
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
430
static int create_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1194
430
    EbReferenceObjectDescInitData eb_ref_obj_ect_desc_init_data_structure;
1195
430
    EbPictureBufferDescInitData   ref_pic_buf_desc_init_data;
1196
430
    SequenceControlSet*           scs      = enc_handle_ptr->scs_instance->scs;
1197
430
    bool                          is_16bit = scs->static_config.encoder_bit_depth > EB_EIGHT_BIT;
1198
    // Initialize the various Picture types
1199
430
    ref_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width;
1200
430
    ref_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height;
1201
430
    ref_pic_buf_desc_init_data.bit_depth           = scs->encoder_bit_depth;
1202
430
    ref_pic_buf_desc_init_data.color_format        = scs->static_config.encoder_color_format;
1203
430
    ref_pic_buf_desc_init_data.buffer_enable_mask  = PICTURE_BUFFER_DESC_FULL_MASK;
1204
430
    ref_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1205
430
    ref_pic_buf_desc_init_data.sb_total_count      = scs->b64_total_count;
1206
430
    uint16_t padding                               = scs->super_block_size + 32;
1207
430
    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
430
    ref_pic_buf_desc_init_data.border            = padding;
1212
430
    ref_pic_buf_desc_init_data.mfmv              = scs->mfmv_enabled;
1213
430
    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
430
    ref_pic_buf_desc_init_data.split_mode = false;
1217
430
    if (is_16bit) {
1218
0
        ref_pic_buf_desc_init_data.bit_depth = EB_TEN_BIT;
1219
0
    }
1220
1221
430
    eb_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1222
430
    eb_ref_obj_ect_desc_init_data_structure.hbd_md                           = scs->enable_hbd_mode_decision;
1223
430
    eb_ref_obj_ect_desc_init_data_structure.static_config                    = &scs->static_config;
1224
    // Reference Picture Buffers
1225
430
    EB_NEW(enc_handle_ptr->reference_picture_pool_ptr,
1226
430
           svt_system_resource_ctor,
1227
430
           scs->reference_picture_buffer_init_count,
1228
430
           EB_PictureManagerProcessInitCount,
1229
430
           0,
1230
430
           svt_reference_object_creator,
1231
430
           &(eb_ref_obj_ect_desc_init_data_structure),
1232
430
           NULL,
1233
430
           (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
430
    const uint32_t ref_pic_list_length = scs->enable_dec_order ? scs->pa_reference_picture_buffer_init_count
1240
430
                                                               : scs->reference_picture_buffer_init_count;
1241
430
    enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list_length = ref_pic_list_length;
1242
430
    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
860
        EB_NEW(enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list[idx], svt_aom_reference_queue_entry_ctor);
1246
860
    }
1247
430
#if CONFIG_SINGLE_THREAD_KERNEL
1248
430
    if (scs->lp > 1)
1249
430
#endif
1250
430
    {
1251
430
        EB_CREATE_SEMAPHORE(scs->ref_buffer_available_semaphore, ref_pic_list_length, ref_pic_list_length);
1252
430
    }
1253
430
    enc_handle_ptr->scs_instance->enc_ctx->reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1254
430
        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
430
    return 0;
1261
430
}
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
430
EB_API EbErrorType svt_av1_enc_init(EbComponentType* svt_enc_component) {
1285
430
    if (svt_enc_component == NULL) {
1286
0
        return EB_ErrorBadParameter;
1287
0
    }
1288
430
    EbEncHandle*        enc_handle_ptr = (EbEncHandle*)svt_enc_component->p_component_private;
1289
430
    EbErrorType         return_error   = EB_ErrorNone;
1290
430
    SequenceControlSet* scs            = enc_handle_ptr->scs_instance->scs;
1291
430
    EbColorFormat       color_format   = scs->static_config.encoder_color_format;
1292
430
    const bool          single_thread  = (scs->lp == 1);
1293
1294
430
    svt_aom_setup_common_rtcd_internal(scs->static_config.use_cpu_flags);
1295
430
    svt_aom_setup_rtcd_internal(scs->static_config.use_cpu_flags);
1296
430
    svt_run_once(&global_tables_once, init_global_tables);
1297
1298
    // Per-instance block geometry table allocation
1299
430
    EB_MALLOC_ARRAY(scs->blk_geom_mds, scs->max_block_cnt);
1300
430
    svt_aom_build_blk_geom(scs->svt_aom_geom_idx, scs->blk_geom_mds);
1301
    /************************************
1302
     * Sequence Control Set
1303
     ************************************/
1304
430
    EB_NEW(enc_handle_ptr->scs_pool_ptr,
1305
430
           svt_system_resource_ctor,
1306
430
           enc_handle_ptr->scs_pool_total_count,
1307
430
           1,
1308
430
           0,
1309
430
           svt_aom_scs_set_creator,
1310
430
           NULL,
1311
430
           NULL,
1312
430
           single_thread);
1313
    /************************************
1314
    * Picture Control Set: Parent
1315
    ************************************/
1316
430
    {
1317
        // The segment Width & Height Arrays are in units of SBs, not samples
1318
430
        PictureControlSetInitData input_data;
1319
430
        input_data.picture_width        = scs->max_input_luma_width;
1320
430
        input_data.picture_height       = scs->max_input_luma_height;
1321
430
        input_data.border               = scs->border;
1322
430
        input_data.color_format         = color_format;
1323
430
        input_data.b64_size             = scs->b64_size;
1324
430
        input_data.enc_mode             = scs->static_config.enc_mode;
1325
430
        input_data.hbd_md               = scs->enable_hbd_mode_decision;
1326
430
        input_data.bit_depth            = scs->static_config.encoder_bit_depth;
1327
430
        input_data.log2_tile_rows       = scs->static_config.tile_rows;
1328
430
        input_data.log2_tile_cols       = scs->static_config.tile_columns;
1329
430
        input_data.log2_sb_size         = (scs->super_block_size == 128) ? 5 : 4;
1330
430
        input_data.is_16bit_pipeline    = scs->is_16bit_pipeline;
1331
430
        input_data.non_m8_pad_w         = scs->max_input_pad_right;
1332
430
        input_data.non_m8_pad_h         = scs->max_input_pad_bottom;
1333
430
        input_data.enable_tpl_la        = scs->tpl;
1334
430
        input_data.enc_dec_segment_col  = (uint16_t)scs->tpl_segment_col_count_array;
1335
430
        input_data.enc_dec_segment_row  = (uint16_t)scs->tpl_segment_row_count_array;
1336
430
        MrpCtrls* mrp_ctrl              = &(scs->mrp_ctrls);
1337
430
#if TUNE_SIMPLIFY_SETTINGS
1338
430
        input_data.ref_count_used_list0 = MAX(mrp_ctrl->base_ref_list0_count, mrp_ctrl->non_base_ref_list0_count);
1339
430
        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
430
        input_data.tpl_synth_size = svt_aom_set_tpl_group(NULL,
1351
430
                                                          svt_aom_get_tpl_group_level(1, scs->static_config.enc_mode),
1352
430
                                                          input_data.picture_width,
1353
430
                                                          input_data.picture_height);
1354
430
        input_data.aq_mode        = scs->static_config.aq_mode;
1355
1356
430
        input_data.calculate_variance = scs->calculate_variance;
1357
430
        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
430
        input_data.tpl_lad_mg       = scs->tpl_lad_mg;
1362
430
        input_data.input_resolution = scs->input_resolution;
1363
430
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1364
430
            scs->static_config.resize_mode > RESIZE_NONE;
1365
430
        input_data.rtc_tune            = scs->static_config.rtc;
1366
430
        input_data.variance_octile     = scs->static_config.variance_octile;
1367
430
        input_data.adaptive_film_grain = scs->static_config.adaptive_film_grain;
1368
430
        input_data.hbd_mds             = scs->static_config.hbd_mds;
1369
430
        input_data.static_config       = scs->static_config;
1370
430
        input_data.allintra            = scs->allintra;
1371
430
        input_data.use_flat_ipp        = scs->use_flat_ipp;
1372
430
        EB_NEW(enc_handle_ptr->picture_parent_control_set_pool_ptr,
1373
430
               svt_system_resource_ctor,
1374
430
               scs->picture_control_set_pool_init_count, //enc_handle_ptr->pcs_pool_total_count,
1375
430
               1,
1376
430
               0,
1377
430
               svt_aom_picture_parent_control_set_creator,
1378
430
               &input_data,
1379
430
               NULL,
1380
430
               single_thread);
1381
#if SRM_REPORT
1382
        enc_handle_ptr->picture_parent_control_set_pool_ptr->empty_queue->log = 0;
1383
#endif
1384
430
        EB_NEW(enc_handle_ptr->me_pool_ptr,
1385
430
               svt_system_resource_ctor,
1386
430
               scs->me_pool_init_count,
1387
430
               1,
1388
430
               0,
1389
430
               svt_aom_me_creator,
1390
430
               &input_data,
1391
430
               NULL,
1392
430
               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
430
    }
1398
1399
    /************************************
1400
    * Enc Dec
1401
    ************************************/
1402
430
    {
1403
        // The segment Width & Height Arrays are in units of SBs, not samples
1404
430
        PictureControlSetInitData input_data;
1405
430
        input_data.enc_dec_segment_col = (uint16_t)scs->enc_dec_segment_col_count_array;
1406
430
        input_data.enc_dec_segment_row = (uint16_t)scs->enc_dec_segment_row_count_array;
1407
1408
430
        input_data.picture_width  = scs->max_input_luma_width;
1409
430
        input_data.picture_height = scs->max_input_luma_height;
1410
430
        input_data.border         = scs->border;
1411
430
        input_data.bit_depth      = scs->encoder_bit_depth;
1412
430
        input_data.color_format   = color_format;
1413
430
        input_data.b64_size       = scs->b64_size;
1414
430
        input_data.sb_size        = scs->super_block_size;
1415
430
        input_data.hbd_md         = scs->enable_hbd_mode_decision;
1416
430
        input_data.mfmv           = scs->mfmv_enabled;
1417
        //Jing: Get tile info from parent_pcs
1418
430
        PictureParentControlSet* parent_pcs =
1419
430
            (PictureParentControlSet*)enc_handle_ptr->picture_parent_control_set_pool_ptr->wrapper_ptr_pool[0]
1420
430
                ->object_ptr;
1421
430
        input_data.tile_row_count    = parent_pcs->av1_cm->tiles_info.tile_rows;
1422
430
        input_data.tile_column_count = parent_pcs->av1_cm->tiles_info.tile_cols;
1423
430
        input_data.is_16bit_pipeline = scs->is_16bit_pipeline;
1424
430
        input_data.av1_cm            = parent_pcs->av1_cm;
1425
430
        input_data.enc_mode          = scs->static_config.enc_mode;
1426
1427
430
        input_data.input_resolution = scs->input_resolution;
1428
430
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1429
430
            scs->static_config.resize_mode > RESIZE_NONE;
1430
1431
430
        input_data.rtc_tune     = scs->static_config.rtc;
1432
430
        input_data.allintra     = scs->allintra;
1433
430
        input_data.use_flat_ipp = scs->use_flat_ipp;
1434
430
        EB_NEW(enc_handle_ptr->enc_dec_pool_ptr,
1435
430
               svt_system_resource_ctor,
1436
430
               scs->enc_dec_pool_init_count, //EB_PictureControlSetPoolInitCountChild,
1437
430
               1,
1438
430
               0,
1439
430
               svt_aom_recon_coef_creator,
1440
430
               &input_data,
1441
430
               NULL,
1442
430
               single_thread);
1443
430
    }
1444
1445
    /************************************
1446
        * Picture Control Set: Child
1447
        ************************************/
1448
430
    {
1449
        // The segment Width & Height Arrays are in units of SBs, not samples
1450
430
        PictureControlSetInitData input_data;
1451
430
        input_data.enc_dec_segment_col = (uint16_t)scs->enc_dec_segment_col_count_array;
1452
430
        input_data.enc_dec_segment_row = (uint16_t)scs->enc_dec_segment_row_count_array;
1453
430
        input_data.picture_width       = scs->max_input_luma_width;
1454
430
        input_data.picture_height      = scs->max_input_luma_height;
1455
430
        input_data.border              = scs->border;
1456
430
        input_data.bit_depth           = scs->encoder_bit_depth;
1457
430
        input_data.color_format        = color_format;
1458
430
        input_data.b64_size            = scs->b64_size;
1459
430
        input_data.sb_size             = scs->super_block_size;
1460
430
        input_data.hbd_md              = scs->enable_hbd_mode_decision;
1461
430
        input_data.mfmv                = scs->mfmv_enabled;
1462
        //Jing: Get tile info from parent_pcs
1463
430
        PictureParentControlSet* parent_pcs =
1464
430
            (PictureParentControlSet*)enc_handle_ptr->picture_parent_control_set_pool_ptr->wrapper_ptr_pool[0]
1465
430
                ->object_ptr;
1466
430
        input_data.tile_row_count    = parent_pcs->av1_cm->tiles_info.tile_rows;
1467
430
        input_data.tile_column_count = parent_pcs->av1_cm->tiles_info.tile_cols;
1468
430
        input_data.is_16bit_pipeline = scs->is_16bit_pipeline;
1469
430
        input_data.av1_cm            = parent_pcs->av1_cm;
1470
430
        input_data.enc_mode          = scs->static_config.enc_mode;
1471
430
        input_data.static_config     = scs->static_config;
1472
1473
430
        input_data.input_resolution = scs->input_resolution;
1474
430
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1475
430
            scs->static_config.resize_mode > RESIZE_NONE;
1476
1477
430
        input_data.rtc_tune     = scs->static_config.rtc;
1478
430
        input_data.allintra     = scs->allintra;
1479
430
        input_data.use_flat_ipp = scs->use_flat_ipp;
1480
430
        EB_NEW(enc_handle_ptr->picture_control_set_pool_ptr,
1481
430
               svt_system_resource_ctor,
1482
430
               scs->picture_control_set_pool_init_count_child, //EB_PictureControlSetPoolInitCountChild,
1483
430
               1,
1484
430
               0,
1485
430
               svt_aom_picture_control_set_creator,
1486
430
               &input_data,
1487
430
               NULL,
1488
430
               single_thread);
1489
430
    }
1490
1491
    /************************************
1492
    * Picture Buffers
1493
    ************************************/
1494
    // Allocate Resource Arrays
1495
430
    pic_mgr_ports[PIC_MGR_INPUT_PORT_SOP].count           = scs->source_based_operations_process_init_count;
1496
430
    pic_mgr_ports[PIC_MGR_INPUT_PORT_PACKETIZATION].count = EB_PacketizationProcessInitCount;
1497
430
    pic_mgr_ports[PIC_MGR_INPUT_PORT_REST].count          = scs->rest_process_init_count;
1498
    // Rate Control
1499
430
    rate_control_ports[RATE_CONTROL_INPUT_PORT_INLME].count         = EB_PictureManagerProcessInitCount;
1500
430
    rate_control_ports[RATE_CONTROL_INPUT_PORT_PACKETIZATION].count = EB_PacketizationProcessInitCount;
1501
1502
430
    enc_dec_ports[ENCDEC_INPUT_PORT_MDC].count    = scs->mode_decision_configuration_process_init_count;
1503
430
    enc_dec_ports[ENCDEC_INPUT_PORT_ENCDEC].count = scs->enc_dec_process_init_count;
1504
430
    tpl_ports[TPL_INPUT_PORT_SOP].count           = scs->source_based_operations_process_init_count;
1505
430
    tpl_ports[TPL_INPUT_PORT_TPL].count           = scs->tpl_disp_process_init_count;
1506
430
    {
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
430
        PictureControlSet* pcs =
1510
430
            (PictureControlSet*)enc_handle_ptr->picture_control_set_pool_ptr->wrapper_ptr_pool[0]->object_ptr;
1511
430
        scs->rest_units_per_tile = pcs->rst_info[0 /*Y-plane*/].units_per_tile;
1512
430
        scs->b64_total_count     = pcs->b64_total_count;
1513
430
        create_ref_buf_descs(enc_handle_ptr);
1514
430
        if (scs->tpl) {
1515
0
            create_tpl_ref_buf_descs(enc_handle_ptr);
1516
0
        }
1517
1518
430
        create_pa_ref_buf_descs(enc_handle_ptr);
1519
1520
430
        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
430
    }
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
430
    EB_NEW(enc_handle_ptr->input_cmd_resource_ptr,
1541
430
           svt_system_resource_ctor,
1542
430
           scs->resource_coordination_fifo_init_count,
1543
430
           1,
1544
430
           EB_ResourceCoordinationProcessInitCount,
1545
430
           svt_input_cmd_creator,
1546
430
           scs,
1547
430
           NULL,
1548
430
           single_thread);
1549
430
    enc_handle_ptr->input_cmd_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1550
430
        enc_handle_ptr->input_cmd_resource_ptr, 0);
1551
1552
    //Picture Buffer SRM to hold (uv8b + yuv2b)
1553
430
    EB_NEW(enc_handle_ptr->input_buffer_resource_ptr,
1554
430
           svt_system_resource_ctor,
1555
430
           scs->input_buffer_fifo_init_count,
1556
430
           1,
1557
430
           0, //1/2 SRM; no consumer FIFO
1558
430
           svt_input_buffer_header_creator,
1559
430
           scs,
1560
430
           svt_input_buffer_header_destroyer,
1561
430
           single_thread);
1562
430
    enc_handle_ptr->input_buffer_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1563
430
        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
430
    EB_NEW(enc_handle_ptr->input_y8b_buffer_resource_ptr,
1567
430
           svt_system_resource_ctor,
1568
430
           MAX(scs->input_buffer_fifo_init_count, scs->pa_reference_picture_buffer_init_count),
1569
430
           1,
1570
430
           0, //1/2 SRM; no consumer FIFO
1571
430
           svt_input_y8b_creator,
1572
430
           scs,
1573
430
           svt_input_y8b_destroyer,
1574
430
           single_thread);
1575
1576
#if SRM_REPORT
1577
    enc_handle_ptr->input_y8b_buffer_resource_ptr->empty_queue->log = 1;
1578
#endif
1579
430
    enc_handle_ptr->input_y8b_buffer_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1580
430
        enc_handle_ptr->input_y8b_buffer_resource_ptr, 0);
1581
1582
    // EbBufferHeaderType Output Stream
1583
430
    {
1584
430
        EB_NEW(enc_handle_ptr->output_stream_buffer_resource_ptr,
1585
430
               svt_system_resource_ctor,
1586
430
               scs->output_stream_buffer_fifo_init_count,
1587
430
               scs->total_process_init_count, //EB_PacketizationProcessInitCount,
1588
430
               1,
1589
430
               svt_output_buffer_header_creator,
1590
430
               &scs->static_config,
1591
430
               svt_output_buffer_header_destroyer,
1592
430
               single_thread);
1593
430
    }
1594
430
    enc_handle_ptr->output_stream_buffer_consumer_fifo_ptr = svt_system_resource_get_consumer_fifo(
1595
430
        enc_handle_ptr->output_stream_buffer_resource_ptr, 0);
1596
430
    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
430
    {
1615
430
        ResourceCoordinationResultInitData resource_coordination_result_init_data;
1616
430
        EB_NEW(enc_handle_ptr->resource_coordination_results_resource_ptr,
1617
430
               svt_system_resource_ctor,
1618
430
               scs->resource_coordination_fifo_init_count,
1619
430
               EB_ResourceCoordinationProcessInitCount,
1620
430
               scs->picture_analysis_process_init_count,
1621
430
               svt_aom_resource_coordination_result_creator,
1622
430
               &resource_coordination_result_init_data,
1623
430
               NULL,
1624
430
               single_thread);
1625
430
    }
1626
1627
    // Picture Analysis Results
1628
430
    {
1629
430
        PictureAnalysisResultInitData picture_analysis_result_init_data;
1630
430
        EB_NEW(enc_handle_ptr->picture_analysis_results_resource_ptr,
1631
430
               svt_system_resource_ctor,
1632
430
               scs->picture_analysis_fifo_init_count,
1633
430
               scs->picture_analysis_process_init_count,
1634
430
               EB_PictureDecisionProcessInitCount,
1635
430
               svt_aom_picture_analysis_result_creator,
1636
430
               &picture_analysis_result_init_data,
1637
430
               NULL,
1638
430
               single_thread);
1639
430
    }
1640
1641
    // Picture Decision Results
1642
430
    {
1643
430
        PictureDecisionResultInitData picture_decision_result_init_data;
1644
430
        EB_NEW(enc_handle_ptr->picture_decision_results_resource_ptr,
1645
430
               svt_system_resource_ctor,
1646
430
               scs->picture_decision_fifo_init_count,
1647
430
               EB_PictureDecisionProcessInitCount +
1648
430
                   2, // 1 for rate control, another 1 for packetization when superres recoding is on
1649
430
               scs->motion_estimation_process_init_count,
1650
430
               svt_aom_picture_decision_result_creator,
1651
430
               &picture_decision_result_init_data,
1652
430
               NULL,
1653
430
               single_thread);
1654
430
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->picture_decision_reorder_queue,
1655
430
                           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
430
    }
1664
1665
    // Motion Estimation Results
1666
430
    {
1667
430
        MotionEstimationResultsInitData motion_estimation_result_init_data;
1668
430
        EB_NEW(enc_handle_ptr->motion_estimation_results_resource_ptr,
1669
430
               svt_system_resource_ctor,
1670
430
               scs->motion_estimation_fifo_init_count,
1671
430
               scs->motion_estimation_process_init_count,
1672
430
               EB_InitialRateControlProcessInitCount,
1673
430
               svt_aom_motion_estimation_results_creator,
1674
430
               &motion_estimation_result_init_data,
1675
430
               NULL,
1676
430
               single_thread);
1677
430
    }
1678
1679
    // Initial Rate Control Results
1680
430
    {
1681
430
        InitialRateControlResultInitData initial_rate_control_result_init_data;
1682
430
        EB_NEW(enc_handle_ptr->initial_rate_control_results_resource_ptr,
1683
430
               svt_system_resource_ctor,
1684
430
               scs->initial_rate_control_fifo_init_count,
1685
430
               EB_InitialRateControlProcessInitCount,
1686
430
               scs->source_based_operations_process_init_count,
1687
430
               svt_aom_initial_rate_control_results_creator,
1688
430
               &initial_rate_control_result_init_data,
1689
430
               NULL,
1690
430
               single_thread);
1691
430
    }
1692
1693
    // Picture Demux Results
1694
430
    {
1695
430
        PictureResultInitData picture_result_init_data;
1696
430
        EB_NEW(enc_handle_ptr->picture_demux_results_resource_ptr,
1697
430
               svt_system_resource_ctor,
1698
430
               scs->picture_demux_fifo_init_count,
1699
430
               pic_mgr_port_total_count(),
1700
430
               EB_PictureManagerProcessInitCount,
1701
430
               svt_aom_picture_results_creator,
1702
430
               &picture_result_init_data,
1703
430
               NULL,
1704
430
               single_thread);
1705
1706
430
        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
430
    }
1712
1713
    // TPL dispenser Results
1714
430
    {
1715
430
        EntropyCodingResultsInitData tpl_disp_result_init_data;
1716
        //TPL Dispenser tasks
1717
430
        EB_NEW(enc_handle_ptr->tpl_disp_res_srm,
1718
430
               svt_system_resource_ctor,
1719
430
               scs->tpl_disp_fifo_init_count,
1720
430
               tpl_port_total_count(),
1721
430
               scs->tpl_disp_process_init_count,
1722
430
               tpl_disp_results_creator,
1723
430
               &tpl_disp_result_init_data,
1724
430
               NULL,
1725
430
               single_thread);
1726
430
    }
1727
1728
    // Rate Control Tasks
1729
430
    {
1730
430
        RateControlTasksInitData rate_control_tasks_init_data;
1731
430
        EB_NEW(enc_handle_ptr->rate_control_tasks_resource_ptr,
1732
430
               svt_system_resource_ctor,
1733
430
               scs->rate_control_tasks_fifo_init_count,
1734
430
               rate_control_port_total_count(),
1735
430
               EB_RateControlProcessInitCount,
1736
430
               svt_aom_rate_control_tasks_creator,
1737
430
               &rate_control_tasks_init_data,
1738
430
               NULL,
1739
430
               single_thread);
1740
430
    }
1741
1742
    // Rate Control Results
1743
430
    {
1744
430
        RateControlResultsInitData rate_control_result_init_data;
1745
430
        EB_NEW(enc_handle_ptr->rate_control_results_resource_ptr,
1746
430
               svt_system_resource_ctor,
1747
430
               scs->rate_control_fifo_init_count,
1748
430
               EB_RateControlProcessInitCount,
1749
430
               scs->mode_decision_configuration_process_init_count,
1750
430
               svt_aom_rate_control_results_creator,
1751
430
               &rate_control_result_init_data,
1752
430
               NULL,
1753
430
               single_thread);
1754
430
    }
1755
    // EncDec Tasks
1756
430
    {
1757
430
        EncDecTasksInitData mode_decision_result_init_data;
1758
430
        mode_decision_result_init_data.enc_dec_segment_row_count = scs->enc_dec_segment_row_count_array;
1759
430
        EB_NEW(enc_handle_ptr->enc_dec_tasks_resource_ptr,
1760
430
               svt_system_resource_ctor,
1761
430
               scs->mode_decision_configuration_fifo_init_count,
1762
430
               enc_dec_port_total_count(),
1763
430
               scs->enc_dec_process_init_count,
1764
430
               svt_aom_enc_dec_tasks_creator,
1765
430
               &mode_decision_result_init_data,
1766
430
               NULL,
1767
430
               single_thread);
1768
430
    }
1769
1770
    // EncDec Results
1771
430
    {
1772
430
        EncDecResultsInitData enc_dec_result_init_data;
1773
430
        EB_NEW(enc_handle_ptr->enc_dec_results_resource_ptr,
1774
430
               svt_system_resource_ctor,
1775
430
               scs->enc_dec_fifo_init_count,
1776
430
               scs->enc_dec_process_init_count,
1777
430
               scs->dlf_process_init_count,
1778
430
               svt_aom_enc_dec_results_creator,
1779
430
               &enc_dec_result_init_data,
1780
430
               NULL,
1781
430
               single_thread);
1782
430
    }
1783
1784
    //DLF results
1785
430
    {
1786
430
        EntropyCodingResultsInitData delf_result_init_data;
1787
430
        EB_NEW(enc_handle_ptr->dlf_results_resource_ptr,
1788
430
               svt_system_resource_ctor,
1789
430
               scs->dlf_fifo_init_count,
1790
430
               scs->dlf_process_init_count,
1791
430
               scs->cdef_process_init_count,
1792
430
               dlf_results_creator,
1793
430
               &delf_result_init_data,
1794
430
               NULL,
1795
430
               single_thread);
1796
430
    }
1797
    //CDEF results
1798
430
    {
1799
430
        EntropyCodingResultsInitData cdef_result_init_data;
1800
430
        EB_NEW(enc_handle_ptr->cdef_results_resource_ptr,
1801
430
               svt_system_resource_ctor,
1802
430
               scs->cdef_fifo_init_count,
1803
430
               scs->cdef_process_init_count,
1804
430
               scs->rest_process_init_count,
1805
430
               cdef_results_creator,
1806
430
               &cdef_result_init_data,
1807
430
               NULL,
1808
430
               single_thread);
1809
430
    }
1810
    //REST results
1811
430
    {
1812
430
        EntropyCodingResultsInitData rest_result_init_data;
1813
430
        EB_NEW(enc_handle_ptr->rest_results_resource_ptr,
1814
430
               svt_system_resource_ctor,
1815
430
               scs->rest_fifo_init_count,
1816
430
               scs->rest_process_init_count,
1817
430
               scs->entropy_coding_process_init_count,
1818
430
               rest_results_creator,
1819
430
               &rest_result_init_data,
1820
430
               NULL,
1821
430
               single_thread);
1822
430
    }
1823
1824
    // Entropy Coding Results
1825
430
    {
1826
430
        EntropyCodingResultsInitData entropy_coding_results_init_data;
1827
430
        EB_NEW(enc_handle_ptr->entropy_coding_results_resource_ptr,
1828
430
               svt_system_resource_ctor,
1829
430
               scs->entropy_coding_fifo_init_count,
1830
430
               scs->entropy_coding_process_init_count,
1831
430
               EB_PacketizationProcessInitCount,
1832
430
               svt_aom_entropy_coding_results_creator,
1833
430
               &entropy_coding_results_init_data,
1834
430
               NULL,
1835
430
               single_thread);
1836
430
        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
430
    }
1845
1846
    /************************************
1847
    * App Callbacks
1848
    ************************************/
1849
430
    enc_handle_ptr->scs_instance->enc_ctx->app_callback_ptr = enc_handle_ptr->app_callback_ptr;
1850
    // svt Output Buffer Fifo Ptrs
1851
430
    enc_handle_ptr->scs_instance->enc_ctx->stream_output_fifo_ptr = svt_system_resource_get_producer_fifo(
1852
430
        enc_handle_ptr->output_stream_buffer_resource_ptr, 0);
1853
430
    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
430
    EB_NEW(
1863
430
        enc_handle_ptr->resource_coordination_context_ptr, svt_aom_resource_coordination_context_ctor, enc_handle_ptr);
1864
1865
    // Picture Analysis Context
1866
430
    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
430
    EB_NEW(enc_handle_ptr->picture_decision_context_ptr,
1876
430
           svt_aom_picture_decision_context_ctor,
1877
430
           enc_handle_ptr,
1878
430
           scs->calc_hist);
1879
1880
    // Motion Analysis Context
1881
430
    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
430
    EB_NEW(enc_handle_ptr->initial_rate_control_context_ptr,
1891
430
           svt_aom_initial_rate_control_context_ctor,
1892
430
           enc_handle_ptr,
1893
430
           scs->picture_control_set_pool_init_count);
1894
1895
    // Source Based Operations Context
1896
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->source_based_operations_context_ptr_array,
1897
430
                       scs->source_based_operations_process_init_count);
1898
860
    for (uint32_t process_index = 0; process_index < scs->source_based_operations_process_init_count; process_index++) {
1899
430
        EB_NEW(enc_handle_ptr->source_based_operations_context_ptr_array[process_index],
1900
430
               svt_aom_source_based_operations_context_ctor,
1901
430
               enc_handle_ptr,
1902
430
               tpl_port_lookup(TPL_INPUT_PORT_SOP, process_index),
1903
430
               pic_mgr_port_lookup(PIC_MGR_INPUT_PORT_SOP, process_index));
1904
430
    }
1905
1906
    // TPL dispenser
1907
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->tpl_disp_context_ptr_array, scs->tpl_disp_process_init_count);
1908
1.77k
    for (uint32_t process_index = 0; process_index < scs->tpl_disp_process_init_count; process_index++) {
1909
1.34k
        EB_NEW(enc_handle_ptr->tpl_disp_context_ptr_array[process_index],
1910
1.34k
               svt_aom_tpl_disp_context_ctor,
1911
1.34k
               enc_handle_ptr,
1912
1.34k
               process_index,
1913
1.34k
               tpl_port_lookup(TPL_INPUT_PORT_TPL, process_index));
1914
1.34k
    }
1915
1916
    // Picture Manager Context
1917
430
    EB_NEW(enc_handle_ptr->picture_manager_context_ptr,
1918
430
           svt_aom_picture_manager_context_ctor,
1919
430
           enc_handle_ptr,
1920
430
           rate_control_port_lookup(RATE_CONTROL_INPUT_PORT_INLME, 0), //Pic-Mgr uses the first Port
1921
430
           scs->picture_control_set_pool_init_count);
1922
1923
    // Rate Control Context
1924
430
    EB_NEW(enc_handle_ptr->rate_control_context_ptr,
1925
430
           svt_aom_rate_control_context_ctor,
1926
430
           enc_handle_ptr,
1927
430
           EB_PictureDecisionProcessInitCount); // me_port_index
1928
1929
    // Mode Decision Configuration Contexts
1930
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->mode_decision_configuration_context_ptr_array,
1931
430
                       scs->mode_decision_configuration_process_init_count);
1932
860
    for (uint32_t process_index = 0; process_index < scs->mode_decision_configuration_process_init_count;
1933
430
         process_index++) {
1934
430
        EB_NEW(enc_handle_ptr->mode_decision_configuration_context_ptr_array[process_index],
1935
430
               svt_aom_mode_decision_configuration_context_ctor,
1936
430
               enc_handle_ptr,
1937
430
               process_index,
1938
430
               enc_dec_port_lookup(ENCDEC_INPUT_PORT_MDC, process_index));
1939
430
    }
1940
1941
    // EncDec Contexts
1942
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->enc_dec_context_ptr_array, scs->enc_dec_process_init_count);
1943
1.77k
    for (uint32_t process_index = 0; process_index < scs->enc_dec_process_init_count; process_index++) {
1944
1.34k
        EB_NEW(enc_handle_ptr->enc_dec_context_ptr_array[process_index],
1945
1.34k
               svt_aom_enc_dec_context_ctor,
1946
1.34k
               enc_handle_ptr,
1947
1.34k
               process_index,
1948
1.34k
               enc_dec_port_lookup(ENCDEC_INPUT_PORT_ENCDEC, process_index));
1949
1.34k
    }
1950
1951
    // Dlf Contexts
1952
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->dlf_context_ptr_array, scs->dlf_process_init_count);
1953
860
    for (uint32_t process_index = 0; process_index < scs->dlf_process_init_count; process_index++) {
1954
430
        EB_NEW(enc_handle_ptr->dlf_context_ptr_array[process_index],
1955
430
               svt_aom_dlf_context_ctor,
1956
430
               enc_handle_ptr,
1957
430
               process_index);
1958
430
    }
1959
1960
    //CDEF Contexts
1961
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->cdef_context_ptr_array, scs->cdef_process_init_count);
1962
860
    for (uint32_t process_index = 0; process_index < scs->cdef_process_init_count; process_index++) {
1963
430
        EB_NEW(enc_handle_ptr->cdef_context_ptr_array[process_index],
1964
430
               svt_aom_cdef_context_ctor,
1965
430
               enc_handle_ptr,
1966
430
               process_index);
1967
430
    }
1968
1969
    //Rest Contexts
1970
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->rest_context_ptr_array, scs->rest_process_init_count);
1971
860
    for (uint32_t process_index = 0; process_index < scs->rest_process_init_count; process_index++) {
1972
430
        EB_NEW(enc_handle_ptr->rest_context_ptr_array[process_index],
1973
430
               svt_aom_rest_context_ctor,
1974
430
               enc_handle_ptr,
1975
430
               process_index,
1976
430
               pic_mgr_port_lookup(PIC_MGR_INPUT_PORT_REST, process_index));
1977
430
    }
1978
1979
    // Entropy Coding Contexts
1980
430
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->entropy_coding_context_ptr_array, scs->entropy_coding_process_init_count);
1981
860
    for (uint32_t process_index = 0; process_index < scs->entropy_coding_process_init_count; process_index++) {
1982
430
        EB_NEW(enc_handle_ptr->entropy_coding_context_ptr_array[process_index],
1983
430
               svt_aom_entropy_coding_context_ctor,
1984
430
               enc_handle_ptr,
1985
430
               process_index);
1986
430
    }
1987
1988
    // Packetization Context
1989
430
    EB_NEW(enc_handle_ptr->packetization_context_ptr,
1990
430
           svt_aom_packetization_context_ctor,
1991
430
           enc_handle_ptr,
1992
430
           rate_control_port_lookup(RATE_CONTROL_INPUT_PORT_PACKETIZATION, 0),
1993
430
           pic_mgr_port_lookup(PIC_MGR_INPUT_PORT_PACKETIZATION, 0),
1994
430
           EB_PictureDecisionProcessInitCount + EB_RateControlProcessInitCount); // me_port_index
1995
1996
    /************************************
1997
    * Thread Handles
1998
    ************************************/
1999
430
#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
430
    svt_kernel_dispatcher_init(&enc_handle_ptr->kernel_dispatcher);
2003
430
    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
430
#endif
2133
430
    {
2134
430
        EB_CREATE_THREAD(enc_handle_ptr->resource_coordination_thread_handle,
2135
430
                         svt_aom_resource_coordination_kernel,
2136
430
                         enc_handle_ptr->resource_coordination_context_ptr);
2137
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->picture_analysis_thread_handle_array,
2138
430
                               scs->picture_analysis_process_init_count,
2139
430
                               svt_aom_picture_analysis_kernel,
2140
430
                               enc_handle_ptr->picture_analysis_context_ptr_array,
2141
430
                               "svt-picana");
2142
2143
        // Picture Decision
2144
430
        EB_CREATE_THREAD(enc_handle_ptr->picture_decision_thread_handle,
2145
430
                         svt_aom_picture_decision_kernel,
2146
430
                         enc_handle_ptr->picture_decision_context_ptr);
2147
2148
        // Motion Estimation
2149
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->motion_estimation_thread_handle_array,
2150
430
                               scs->motion_estimation_process_init_count,
2151
430
                               svt_aom_motion_estimation_kernel,
2152
430
                               enc_handle_ptr->motion_estimation_context_ptr_array,
2153
430
                               "svt-me");
2154
2155
        // Initial Rate Control
2156
430
        EB_CREATE_THREAD(enc_handle_ptr->initial_rate_control_thread_handle,
2157
430
                         svt_aom_initial_rate_control_kernel,
2158
430
                         enc_handle_ptr->initial_rate_control_context_ptr);
2159
2160
        // Source Based Oprations
2161
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->source_based_operations_thread_handle_array,
2162
430
                               scs->source_based_operations_process_init_count,
2163
430
                               svt_aom_source_based_operations_kernel,
2164
430
                               enc_handle_ptr->source_based_operations_context_ptr_array,
2165
430
                               "svt-srcops");
2166
2167
        // TPL dispenser
2168
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->tpl_disp_thread_handle_array,
2169
430
                               scs->tpl_disp_process_init_count,
2170
430
                               svt_aom_tpl_disp_kernel, //TODOOMK
2171
430
                               enc_handle_ptr->tpl_disp_context_ptr_array,
2172
430
                               "svt-tpl");
2173
        // Picture Manager
2174
430
        EB_CREATE_THREAD(enc_handle_ptr->picture_manager_thread_handle,
2175
430
                         svt_aom_picture_manager_kernel,
2176
430
                         enc_handle_ptr->picture_manager_context_ptr);
2177
        // Rate Control
2178
430
        EB_CREATE_THREAD(enc_handle_ptr->rate_control_thread_handle,
2179
430
                         svt_aom_rate_control_kernel,
2180
430
                         enc_handle_ptr->rate_control_context_ptr);
2181
2182
        // Mode Decision Configuration Process
2183
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->mode_decision_configuration_thread_handle_array,
2184
430
                               scs->mode_decision_configuration_process_init_count,
2185
430
                               svt_aom_mode_decision_configuration_kernel,
2186
430
                               enc_handle_ptr->mode_decision_configuration_context_ptr_array,
2187
430
                               "svt-mdcfg");
2188
2189
        // EncDec Process
2190
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->enc_dec_thread_handle_array,
2191
430
                               scs->enc_dec_process_init_count,
2192
430
                               svt_aom_mode_decision_kernel,
2193
430
                               enc_handle_ptr->enc_dec_context_ptr_array,
2194
430
                               "svt-md");
2195
2196
        // Dlf Process
2197
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->dlf_thread_handle_array,
2198
430
                               scs->dlf_process_init_count,
2199
430
                               svt_aom_dlf_kernel,
2200
430
                               enc_handle_ptr->dlf_context_ptr_array,
2201
430
                               "svt-dlf");
2202
2203
        // Cdef Process
2204
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->cdef_thread_handle_array,
2205
430
                               scs->cdef_process_init_count,
2206
430
                               svt_aom_cdef_kernel,
2207
430
                               enc_handle_ptr->cdef_context_ptr_array,
2208
430
                               "svt-cdef");
2209
2210
        // Rest Process
2211
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->rest_thread_handle_array,
2212
430
                               scs->rest_process_init_count,
2213
430
                               svt_aom_rest_kernel,
2214
430
                               enc_handle_ptr->rest_context_ptr_array,
2215
430
                               "svt-rest");
2216
2217
        // Entropy Coding Process
2218
430
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->entropy_coding_thread_handle_array,
2219
430
                               scs->entropy_coding_process_init_count,
2220
430
                               svt_aom_entropy_coding_kernel,
2221
430
                               enc_handle_ptr->entropy_coding_context_ptr_array,
2222
430
                               "svt-ec");
2223
        // Packetization
2224
430
        EB_CREATE_THREAD(enc_handle_ptr->packetization_thread_handle,
2225
430
                         svt_aom_packetization_kernel,
2226
430
                         enc_handle_ptr->packetization_context_ptr);
2227
430
    } // end of thread creation block
2228
2229
430
    svt_print_memory_usage();
2230
2231
430
    return return_error;
2232
430
}
2233
2234
430
static EbErrorType enc_drain_queue(EbComponentType* svt_enc_component) {
2235
430
    bool eos = false;
2236
430
    do {
2237
430
        EbBufferHeaderType* receive_buffer = NULL;
2238
430
        EbErrorType         return_error;
2239
430
        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
430
        case EB_NoErrorEmptyQueue:
2243
430
            eos = true;
2244
430
            break;
2245
0
        default:
2246
0
            break;
2247
430
        }
2248
430
        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
430
    } while (!eos);
2254
430
    return EB_ErrorNone;
2255
430
}
2256
2257
/**********************************
2258
* DeInitialize Encoder Library
2259
**********************************/
2260
430
EB_API EbErrorType svt_av1_enc_deinit(EbComponentType* svt_enc_component) {
2261
430
    if (!svt_enc_component || !svt_enc_component->p_component_private) {
2262
0
        return EB_ErrorBadParameter;
2263
0
    }
2264
2265
430
    EbEncHandle* handle = svt_enc_component->p_component_private;
2266
2267
430
    if (handle->input_y8b_buffer_producer_fifo_ptr && handle->frame_received) {
2268
430
        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
430
        EbErrorType return_error = enc_drain_queue(svt_enc_component);
2274
430
        if (return_error != EB_ErrorNone) {
2275
0
            return return_error;
2276
0
        }
2277
430
    }
2278
2279
    // Free per-instance block geometry table
2280
430
    if (handle->scs_instance && handle->scs_instance->scs && handle->scs_instance->scs->blk_geom_mds != NULL) {
2281
430
        EB_FREE_ARRAY(handle->scs_instance->scs->blk_geom_mds);
2282
430
    }
2283
2284
430
    svt_shutdown_process(handle->input_buffer_resource_ptr);
2285
430
    svt_shutdown_process(handle->input_cmd_resource_ptr);
2286
430
    svt_shutdown_process(handle->resource_coordination_results_resource_ptr);
2287
430
    svt_shutdown_process(handle->picture_analysis_results_resource_ptr);
2288
430
    svt_shutdown_process(handle->picture_decision_results_resource_ptr);
2289
430
    svt_shutdown_process(handle->motion_estimation_results_resource_ptr);
2290
430
    svt_shutdown_process(handle->initial_rate_control_results_resource_ptr);
2291
430
    svt_shutdown_process(handle->picture_demux_results_resource_ptr);
2292
430
    svt_shutdown_process(handle->tpl_disp_res_srm);
2293
430
    svt_shutdown_process(handle->rate_control_tasks_resource_ptr);
2294
430
    svt_shutdown_process(handle->rate_control_results_resource_ptr);
2295
430
    svt_shutdown_process(handle->enc_dec_tasks_resource_ptr);
2296
430
    svt_shutdown_process(handle->enc_dec_results_resource_ptr);
2297
430
    svt_shutdown_process(handle->entropy_coding_results_resource_ptr);
2298
430
    svt_shutdown_process(handle->dlf_results_resource_ptr);
2299
430
    svt_shutdown_process(handle->cdef_results_resource_ptr);
2300
430
    svt_shutdown_process(handle->rest_results_resource_ptr);
2301
2302
430
    return EB_ErrorNone;
2303
430
}
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
430
{
2315
430
    if (p_handle == NULL) {
2316
0
        return EB_ErrorBadParameter;
2317
0
    }
2318
2319
430
    EB_MALLOC_OBJECT(*p_handle);
2320
    // Init Component OS objects (threads, semaphores, etc.)
2321
    // also links the various Component control functions
2322
430
    EbErrorType return_error = init_svt_av1_encoder_handle(*p_handle);
2323
2324
430
    if (return_error == EB_ErrorNone) {
2325
430
        return_error = svt_av1_set_default_params(config_ptr);
2326
430
    }
2327
430
    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
430
    svt_increase_component_count();
2334
430
    return return_error;
2335
430
}
2336
2337
/**********************************
2338
* Encoder Componenet DeInit
2339
**********************************/
2340
430
EbErrorType svt_av1_enc_component_de_init(EbComponentType* svt_enc_component) {
2341
430
    EbErrorType return_error = EB_ErrorNone;
2342
2343
430
    if (svt_enc_component->p_component_private) {
2344
430
        EbEncHandle* handle = (EbEncHandle*)svt_enc_component->p_component_private;
2345
430
        EB_DELETE(handle);
2346
430
        svt_enc_component->p_component_private = NULL;
2347
430
    } else {
2348
0
        return_error = EB_ErrorUndefined;
2349
0
    }
2350
430
    return return_error;
2351
430
}
2352
2353
/**********************************
2354
* svt_av1_enc_deinit_handle
2355
**********************************/
2356
430
EB_API EbErrorType svt_av1_enc_deinit_handle(EbComponentType* svt_enc_component) {
2357
430
    if (svt_enc_component) {
2358
430
        EbErrorType return_error = svt_av1_enc_component_de_init(svt_enc_component);
2359
2360
430
        EB_FREE(svt_enc_component);
2361
430
        svt_decrease_component_count();
2362
430
        return return_error;
2363
430
    }
2364
0
    return EB_ErrorInvalidComponent;
2365
430
}
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
430
static uint32_t compute_default_look_ahead(EbSvtAv1EncConfiguration* config) {
2387
430
    int32_t  lad;
2388
430
    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
430
    uint32_t eos_delay    = 1;
2394
430
    uint32_t max_tf_delay = 6;
2395
2396
430
    if (config->rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
2397
430
        lad = (1 + mg_size) * (1 + MIN_LAD_MG) + max_tf_delay + eos_delay;
2398
430
    } else {
2399
0
        lad = (1 + mg_size) * (1 + RC_DEFAULT_LAD_MG) + max_tf_delay + eos_delay;
2400
0
    }
2401
2402
430
    lad = lad > MAX_LAD ? MAX_LAD : lad; // clip to max allowed lad
2403
430
    return lad;
2404
430
}
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
430
void tf_controls(SequenceControlSet* scs, uint8_t tf_level) {
2561
430
    switch (tf_level) {
2562
430
    case 0:
2563
        // I_SLICE TF Params
2564
430
        scs->tf_params_per_type[0].enabled = 0;
2565
2566
        // BASE TF Params
2567
430
        scs->tf_params_per_type[1].enabled = 0;
2568
2569
        // L1 TF Params
2570
430
        scs->tf_params_per_type[2].enabled = 0;
2571
430
        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
430
    }
3219
430
    scs->tf_params_per_type[0].use_zz_based_filter = 0;
3220
430
    scs->tf_params_per_type[1].use_zz_based_filter = 0;
3221
430
    scs->tf_params_per_type[2].use_zz_based_filter = 0;
3222
430
}
3223
3224
/*
3225
 * Derive tune Params; 0: use objective mode params, 1: use subjective mode params
3226
 */
3227
430
static void derive_vq_params(SequenceControlSet* scs) {
3228
430
    VqCtrls* vq_ctrl = &scs->vq_ctrls;
3229
3230
430
    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
430
    } else {
3240
        // Sharpness
3241
430
        vq_ctrl->sharpness_ctrls.scene_transition = 1;
3242
430
        vq_ctrl->sharpness_ctrls.tf               = 0;
3243
430
        vq_ctrl->sharpness_ctrls.unipred_bias     = 0;
3244
430
        vq_ctrl->sharpness_ctrls.ifs              = 0;
3245
430
        vq_ctrl->sharpness_ctrls.cdef             = 0;
3246
430
        vq_ctrl->sharpness_ctrls.restoration      = 0;
3247
430
        vq_ctrl->sharpness_ctrls.rdoq             = 0;
3248
430
    }
3249
    // Do not use scene_transition if LD or 1st pass or middle pass
3250
430
    if (scs->static_config.pred_structure != RANDOM_ACCESS || scs->static_config.pass == ENC_FIRST_PASS) {
3251
430
        vq_ctrl->sharpness_ctrls.scene_transition = 0;
3252
430
    }
3253
430
}
3254
3255
/*
3256
 * Derive TF Params
3257
 */
3258
430
static void derive_tf_params(SequenceControlSet* scs) {
3259
430
    const uint32_t hierarchical_levels = scs->static_config.hierarchical_levels;
3260
    // Do not perform TF if LD or 1 Layer or 1st pass
3261
430
    const bool    do_tf    = scs->static_config.enable_tf && hierarchical_levels >= 1 && !scs->static_config.lossless;
3262
430
    const EncMode enc_mode = scs->static_config.enc_mode;
3263
430
    uint8_t       tf_level = 0;
3264
430
    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
430
    if (do_tf == 0) {
3284
430
        tf_level = 0;
3285
430
    } 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
430
    tf_controls(scs, tf_level);
3295
430
}
3296
3297
/*
3298
 * Set the MRP control
3299
 */
3300
430
static void set_mrp_ctrl_with_level(const SequenceControlSet* scs, MrpCtrls* mrp_ctrl, uint8_t mrp_level) {
3301
430
    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
430
    case 9:
3528
430
        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
430
        mrp_ctrl->base_ref_list0_count        = 3;
3536
430
        mrp_ctrl->base_ref_list1_count        = 2;
3537
430
        mrp_ctrl->non_base_ref_list0_count    = 1;
3538
430
        mrp_ctrl->non_base_ref_list1_count    = 1;
3539
430
        mrp_ctrl->more_5L_refs                = 0;
3540
430
        mrp_ctrl->safe_limit_nref             = 2;
3541
430
        mrp_ctrl->safe_limit_zz_th            = 60000;
3542
430
        mrp_ctrl->only_l_bwd                  = 1;
3543
430
        mrp_ctrl->pme_ref0_only               = 1;
3544
430
        mrp_ctrl->use_best_references         = 3;
3545
430
#if OPT_MRP_HME_L0_DETECT
3546
430
        mrp_ctrl->early_hme_l0_prune_th = 0;
3547
430
#endif
3548
430
        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
430
    }
3597
    // For low delay mode, list1 references are not used
3598
430
    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
430
    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
430
    } else {
3680
430
        mrp_ctrl->ld_reduce_ref_buffs = 0;
3681
430
    }
3682
430
}
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
430
static void set_mrp_ctrl(const SequenceControlSet* scs, MrpCtrls* mrp_ctrl, EncMode enc_mode) {
3688
430
    uint8_t mrp_level;
3689
430
#if TUNE_SIMPLIFY_SETTINGS
3690
430
    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
430
    else {
3739
430
        if (enc_mode <= ENC_MR) {
3740
0
            mrp_level = 1;
3741
430
        } else if (enc_mode <= ENC_M2) {
3742
0
            mrp_level = 2;
3743
430
        } else if (enc_mode <= ENC_M4) {
3744
0
            mrp_level = 4;
3745
430
        } else if (enc_mode <= ENC_M8) {
3746
0
            mrp_level = 6;
3747
430
        } else if (enc_mode <= ENC_M9) {
3748
430
            mrp_level = scs->static_config.pred_structure == RANDOM_ACCESS ? 7 : 9;
3749
430
        } 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
430
    }
3757
430
    set_mrp_ctrl_with_level(scs, mrp_ctrl, mrp_level);
3758
430
}
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
430
                       bool allintra) {
3815
430
    if (allintra) {
3816
430
        SVT_WARN("TPL is disabled for all-intra coding\n");
3817
430
        return 0;
3818
430
    } 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
430
}
3836
3837
/*
3838
* Set multi Pass Params
3839
*/
3840
430
void set_multi_pass_params(SequenceControlSet* scs) {
3841
430
    EbSvtAv1EncConfiguration* config = &scs->static_config;
3842
3843
    // Update passes
3844
430
    if (scs->static_config.pass != ENC_SINGLE_PASS) {
3845
0
        scs->passes = MAX_ENCODE_PASS;
3846
430
    } else {
3847
430
        scs->passes = 1;
3848
430
    }
3849
3850
430
    switch (config->pass) {
3851
430
    case ENC_SINGLE_PASS: {
3852
430
        scs->first_pass_downsample = false;
3853
430
        scs->final_pass_preset     = config->enc_mode;
3854
430
        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
430
    }
3880
3881
430
    int do_downsample = scs->first_pass_downsample && scs->max_input_luma_width >= 128 &&
3882
0
            scs->max_input_luma_height >= 128
3883
430
        ? 1
3884
430
        : 0;
3885
3886
430
    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
430
    if (scs->lap_rc) {
3893
0
        scs->static_config.intra_refresh_type = SVT_AV1_KF_REFRESH;
3894
0
    }
3895
430
    if (scs->static_config.pass == ENC_FIRST_PASS && scs->final_pass_preset > ENC_M6) {
3896
0
        scs->rc_stat_gen_pass_mode = 1;
3897
430
    } else {
3898
430
        scs->rc_stat_gen_pass_mode = 0;
3899
430
    }
3900
3901
430
    if (scs->static_config.recode_loop > 0 &&
3902
430
        ((scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF && scs->static_config.max_bit_rate == 0) ||
3903
430
         (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
430
        scs->static_config.recode_loop = DISALLOW_RECODE;
3906
430
    } 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
430
    scs->enc_ctx->recode_loop = scs->static_config.recode_loop;
3917
430
}
3918
3919
430
static void validate_scaling_params(SequenceControlSet* scs) {
3920
430
    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
430
    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
430
    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
430
    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
430
}
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
430
void set_qp_based_th_scaling_ctrls_all_intra(SequenceControlSet* scs) {
4028
430
    QpBasedThScaling* qp_ctrls = &scs->qp_based_th_scaling_ctrls;
4029
430
    const EncMode     enc_mode = scs->static_config.enc_mode;
4030
4031
430
#if FIX_MR_STILL_IMAGE
4032
430
    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
430
    } 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
430
    } 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
430
    } else {
4078
430
        qp_ctrls->tf_me_qp_based_th_scaling        = 1;
4079
430
        qp_ctrls->tf_ref_qp_based_th_scaling       = 1;
4080
430
        qp_ctrls->depths_qp_based_th_scaling       = 1;
4081
430
        qp_ctrls->hme_qp_based_th_scaling          = 1;
4082
430
        qp_ctrls->me_qp_based_th_scaling           = 1;
4083
430
        qp_ctrls->nsq_qp_based_th_scaling          = 1;
4084
430
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
4085
430
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
4086
430
        qp_ctrls->pme_qp_based_th_scaling          = 1;
4087
430
        qp_ctrls->txt_qp_based_th_scaling          = 1;
4088
430
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
4089
430
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
4090
430
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
4091
430
    }
4092
430
}
4093
4094
430
static void set_param_based_on_input(SequenceControlSet* scs) {
4095
430
    const bool allintra = scs->allintra;
4096
430
    const bool rtc_tune = scs->static_config.rtc;
4097
430
    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
430
    validate_scaling_params(scs);
4102
430
    scs->tpl               = get_tpl(scs->static_config.pred_structure,
4103
430
                       scs->static_config.superres_mode,
4104
430
                       scs->static_config.resize_mode,
4105
430
                       scs->static_config.aq_mode,
4106
430
                       allintra);
4107
430
    uint16_t subsampling_x = scs->subsampling_x;
4108
430
    uint16_t subsampling_y = scs->subsampling_y;
4109
    // Update picture width, and picture height
4110
430
    if (scs->max_input_luma_width % MIN_BLOCK_SIZE) {
4111
304
        scs->max_input_pad_right  = MIN_BLOCK_SIZE - (scs->max_input_luma_width % MIN_BLOCK_SIZE);
4112
304
        scs->max_input_luma_width = scs->max_input_luma_width + scs->max_input_pad_right;
4113
304
    } else {
4114
126
        scs->max_input_pad_right = 0;
4115
126
    }
4116
4117
430
    if (scs->max_input_luma_height % MIN_BLOCK_SIZE) {
4118
291
        scs->max_input_pad_bottom  = MIN_BLOCK_SIZE - (scs->max_input_luma_height % MIN_BLOCK_SIZE);
4119
291
        scs->max_input_luma_height = scs->max_input_luma_height + scs->max_input_pad_bottom;
4120
291
    } else {
4121
139
        scs->max_input_pad_bottom = 0;
4122
139
    }
4123
430
    scs->max_initial_input_luma_width  = scs->max_input_luma_width;
4124
430
    scs->max_initial_input_luma_height = scs->max_input_luma_height;
4125
430
    scs->max_initial_input_pad_bottom  = scs->max_input_pad_bottom;
4126
430
    scs->max_initial_input_pad_right   = scs->max_input_pad_right;
4127
4128
430
    scs->chroma_width  = scs->max_input_luma_width >> subsampling_x;
4129
430
    scs->chroma_height = scs->max_input_luma_height >> subsampling_y;
4130
4131
430
    scs->static_config.source_width  = scs->max_input_luma_width;
4132
430
    scs->static_config.source_height = scs->max_input_luma_height;
4133
430
    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
430
    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
430
    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
430
    svt_aom_derive_input_resolution(&scs->input_resolution, scs->max_input_luma_width * scs->max_input_luma_height);
4185
4186
430
    scs->seq_qp_mod = 2;
4187
4188
430
    (allintra       ? set_qp_based_th_scaling_ctrls_all_intra
4189
430
         : 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
430
    derive_vq_params(scs);
4194
4195
    // Set TF level
4196
430
    derive_tf_params(scs);
4197
4198
    //Future frames window in Scene Change Detection (SCD) / TemporalFiltering
4199
430
    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
430
    uint32_t scd_delay_islice = 0;
4204
430
    if (scs->static_config.intra_period_length == 0) {
4205
430
        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
430
    }
4214
4215
    // Update the scd_delay based on the the number of future frames @ BASE
4216
430
    uint32_t scd_delay_base = 0;
4217
430
    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
430
    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
430
    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
430
    if (allintra || scs->static_config.pred_structure == LOW_DELAY) {
4234
430
        scs->lad_mg = scs->tpl_lad_mg = 0;
4235
430
    } 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
430
    if ((scs->static_config.fast_decode && scs->static_config.qp <= 56 &&
4267
0
         !(scs->input_resolution <= INPUT_SIZE_360p_RANGE)) ||
4268
430
        scs->static_config.resize_mode > RESIZE_NONE || scs->static_config.rtc ||
4269
430
        (scs->input_resolution == INPUT_SIZE_240p_RANGE) || scs->static_config.enable_variance_boost) {
4270
430
        scs->super_block_size = 64;
4271
430
    } 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
430
    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
430
    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
430
    } else {
4299
430
        scs->seq_header.sb_size      = BLOCK_64X64;
4300
430
        scs->sb_size                 = 64;
4301
430
        scs->seq_header.sb_mi_size   = 16; // Size of the superblock in units of MI blocks
4302
430
        scs->seq_header.sb_size_log2 = 4;
4303
430
    }
4304
4305
430
    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
430
    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
430
    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
430
    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
430
    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
430
    bool    disallow_nsq  = true;
4330
430
    uint8_t allow_HVA_HVB = 0;
4331
430
    uint8_t allow_HV4     = 0;
4332
430
    uint8_t h_v_only      = 1;
4333
430
    uint8_t min_nsq_bsize = 0;
4334
430
    uint8_t no_8x4_4x8    = 1;
4335
430
    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
430
    bool disallow_8x8;
4360
430
    bool disallow_4x4;
4361
430
    if (scs->allintra) {
4362
430
        disallow_4x4 = svt_aom_get_disallow_4x4_allintra(scs->static_config.enc_mode);
4363
430
        disallow_8x8 = svt_aom_get_disallow_8x8_allintra();
4364
430
    } 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
430
    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
430
    } else {
4385
        //SB 64x64
4386
430
        if (disallow_nsq && disallow_4x4 && disallow_8x8) {
4387
0
            scs->svt_aom_geom_idx = GEOM_0;
4388
0
            scs->max_block_cnt    = 21;
4389
430
        } 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
430
        } else if (disallow_nsq && disallow_4x4) {
4393
430
            scs->svt_aom_geom_idx = GEOM_2;
4394
430
            scs->max_block_cnt    = 85;
4395
430
        } 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
430
    }
4415
    // Configure the padding
4416
430
    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
430
    { scs->border += 4; }
4422
4423
430
    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
430
        ? 0
4426
430
        : scs->static_config.enable_overlays;
4427
4428
    // Enforce starting frame in decode order (at PicMgr)
4429
    // Does not wait for feedback from PKT
4430
430
    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
430
    } else {
4433
430
        scs->enable_pic_mgr_dec_order = 0;
4434
430
    }
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
430
    if (scs->static_config.level_of_parallelism == 1 || scs->static_config.pred_structure == LOW_DELAY) {
4441
0
        scs->enable_dec_order = 1;
4442
430
    } else {
4443
430
        scs->enable_dec_order = 0;
4444
430
    }
4445
430
#endif
4446
    // 1: Use boundary pixels in restoration filter search.
4447
    // 0: Do not use boundary pixels in the restoration filter search.
4448
430
    scs->use_boundaries_in_rest_search = 0;
4449
4450
430
    svt_aom_set_mfmv_config(scs, scs->static_config.enc_mode);
4451
4452
430
    scs->list0_only_base = scs->static_config.enc_mode > ENC_M2;
4453
4454
430
    if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR ||
4455
430
        scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR || scs->input_resolution >= INPUT_SIZE_4K_RANGE ||
4456
430
        scs->static_config.pred_structure != RANDOM_ACCESS || scs->static_config.pass != ENC_SINGLE_PASS) {
4457
430
        scs->enable_dg = 0;
4458
430
    } 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
430
    if (scs->static_config.encoder_bit_depth < 10) {
4463
430
        scs->enable_hbd_mode_decision = 0;
4464
430
    }
4465
4466
    // Throws a warning when scene change is on, as the feature is not optimal and may produce false detections
4467
430
    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
430
    set_mrp_ctrl(scs, &scs->mrp_ctrls, scs->static_config.enc_mode);
4483
430
    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
430
    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
430
    scs->mrp_ctrls_init = scs->mrp_ctrls;
4519
    // set to 1 if multipass and less than 200 frames in resourcecordination
4520
430
    scs->is_short_clip = scs->static_config.gop_constraint_rc ? 1 : 0;
4521
430
    if (allintra || scs->static_config.aq_mode == 1 || scs->static_config.scene_change_detection == 1 ||
4522
430
        scs->vq_ctrls.sharpness_ctrls.tf == 1 || scs->static_config.enable_variance_boost) {
4523
430
        scs->calculate_variance = 1;
4524
430
    } else {
4525
0
        scs->calculate_variance = 0;
4526
0
    }
4527
4528
430
    scs->resize_pending_params.resize_state = ORIG;
4529
430
    scs->resize_pending_params.resize_denom = SCALE_NUMERATOR;
4530
4531
430
#if OPT_GATE_SB_LAMBDA_MOD
4532
430
#if TUNE_SHIFT_PRESETS_RTC
4533
430
    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
430
    scs->fast_aa_aware_screen_detection_mode = (scs->static_config.enc_mode >= ENC_M3) ? 1 : 0;
4542
430
}
4543
4544
430
static void copy_api_from_app(SequenceControlSet* scs, EbSvtAv1EncConfiguration* config_struct) {
4545
430
    scs->max_input_luma_width  = config_struct->source_width;
4546
430
    scs->max_input_luma_height = config_struct->source_height;
4547
    // SB Definitions
4548
430
    scs->static_config.pred_structure = config_struct->pred_structure;
4549
430
    scs->static_config.rtc            = config_struct->rtc;
4550
430
    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
430
    scs->enable_qp_scaling_flag = scs->allintra ? 0 : 1;
4555
    // Set Picture Parameters for statistics gathering
4556
430
    scs->picture_analysis_number_of_regions_per_width  = scs->max_input_luma_width >= 64
4557
430
         ? HIGHER_THAN_CLASS_1_REGION_SPLIT_PER_WIDTH
4558
430
         : 1;
4559
430
    scs->picture_analysis_number_of_regions_per_height = scs->max_input_luma_height >= 64
4560
430
        ? HIGHER_THAN_CLASS_1_REGION_SPLIT_PER_HEIGHT
4561
430
        : 1;
4562
4563
430
    scs->pic_based_rate_est   = false;
4564
430
    scs->block_mean_calc_prec = BLOCK_MEAN_PREC_SUB;
4565
430
    scs->speed_control_flag   = 0;
4566
    // Padding Offsets
4567
430
    scs->b64_size                          = 64;
4568
430
    scs->static_config.intra_period_length = config_struct->intra_period_length;
4569
430
    scs->static_config.avif                = config_struct->avif;
4570
430
    scs->allintra                          = (scs->static_config.intra_period_length == 0 || scs->static_config.avif ||
4571
0
                     scs->static_config.pred_structure == ALL_INTRA);
4572
430
    if (scs->allintra) {
4573
430
        scs->static_config.pred_structure      = ALL_INTRA;
4574
430
        scs->static_config.intra_period_length = 0;
4575
430
    }
4576
430
    scs->static_config.multiply_keyint    = config_struct->multiply_keyint;
4577
430
    scs->static_config.intra_refresh_type = config_struct->intra_refresh_type;
4578
430
    scs->static_config.enc_mode           = config_struct->enc_mode;
4579
430
    if (scs->allintra) {
4580
430
#if FIX_MR_STILL_IMAGE
4581
430
        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
430
            SVT_WARN("Preset M%d is mapped to M9.\n", scs->static_config.enc_mode);
4589
430
            scs->static_config.enc_mode = ENC_M9;
4590
430
        }
4591
430
    }
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
430
    ResolutionRange input_resolution;
4630
430
    svt_aom_derive_input_resolution(&input_resolution, scs->max_input_luma_width * scs->max_input_luma_height);
4631
430
    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
430
    scs->static_config.use_qp_file                    = config_struct->use_qp_file;
4640
430
    scs->static_config.use_fixed_qindex_offsets       = config_struct->use_fixed_qindex_offsets;
4641
430
    scs->static_config.key_frame_chroma_qindex_offset = config_struct->key_frame_chroma_qindex_offset;
4642
430
    scs->static_config.key_frame_qindex_offset        = config_struct->key_frame_qindex_offset;
4643
430
    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
430
    memcpy(scs->static_config.chroma_qindex_offsets,
4651
430
           config_struct->chroma_qindex_offsets,
4652
430
           MAX_TEMPORAL_LAYERS * sizeof(int32_t));
4653
4654
430
    scs->static_config.lossless = config_struct->lossless;
4655
430
    if (scs->static_config.lossless) {
4656
182
        scs->static_config.luma_y_dc_qindex_offset   = 0;
4657
182
        scs->static_config.chroma_u_dc_qindex_offset = 0;
4658
182
        scs->static_config.chroma_u_ac_qindex_offset = 0;
4659
182
        scs->static_config.chroma_v_dc_qindex_offset = 0;
4660
182
        scs->static_config.chroma_v_ac_qindex_offset = 0;
4661
248
    } else {
4662
248
        scs->static_config.luma_y_dc_qindex_offset   = config_struct->luma_y_dc_qindex_offset;
4663
248
        scs->static_config.chroma_u_dc_qindex_offset = config_struct->chroma_u_dc_qindex_offset;
4664
248
        scs->static_config.chroma_u_ac_qindex_offset = config_struct->chroma_u_ac_qindex_offset;
4665
248
        scs->static_config.chroma_v_dc_qindex_offset = config_struct->chroma_v_dc_qindex_offset;
4666
248
        scs->static_config.chroma_v_ac_qindex_offset = config_struct->chroma_v_ac_qindex_offset;
4667
248
    }
4668
430
    memcpy(scs->static_config.lambda_scale_factors,
4669
430
           config_struct->lambda_scale_factors,
4670
430
           SVT_AV1_FRAME_UPDATE_TYPES * sizeof(int32_t));
4671
4672
430
    scs->static_config.rc_stats_buffer = config_struct->rc_stats_buffer;
4673
430
    scs->static_config.pass            = config_struct->pass;
4674
    // Deblock Filter
4675
430
    scs->static_config.enable_dlf_flag = config_struct->enable_dlf_flag;
4676
4677
    // CDEF
4678
430
    scs->static_config.cdef_level = config_struct->cdef_level;
4679
4680
    // Intra Block Copy
4681
430
    scs->static_config.enable_intrabc = config_struct->enable_intrabc;
4682
4683
    // Restoration filtering
4684
430
    scs->static_config.enable_restoration_filtering = config_struct->enable_restoration_filtering;
4685
4686
    // motion field motion vector
4687
430
    scs->static_config.enable_mfmv = config_struct->enable_mfmv;
4688
4689
    // Dynamic GoP
4690
430
    scs->static_config.enable_dg = config_struct->enable_dg;
4691
4692
    // Decoder Optimization Flag
4693
430
    scs->static_config.fast_decode = config_struct->fast_decode;
4694
4695
    //Film Grain
4696
430
    scs->static_config.film_grain_denoise_strength = config_struct->film_grain_denoise_strength;
4697
430
    scs->static_config.film_grain_denoise_apply    = config_struct->film_grain_denoise_apply;
4698
430
    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
430
    scs->seq_header.film_grain_params_present = (uint8_t)(scs->static_config.film_grain_denoise_strength > 0);
4702
430
    scs->static_config.fgs_table              = config_struct->fgs_table;
4703
4704
    // MD Parameters
4705
430
    scs->enable_hbd_mode_decision = config_struct->encoder_bit_depth > 8 ? DEFAULT : 0;
4706
430
    {
4707
430
        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
430
        } else {
4712
430
            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
430
            } 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
430
            } else {
4719
430
                scs->static_config.tile_rows    = config_struct->tile_rows;
4720
430
                scs->static_config.tile_columns = config_struct->tile_columns;
4721
430
            }
4722
430
        }
4723
430
    }
4724
4725
    // Rate Control
4726
430
    scs->static_config.scene_change_detection = config_struct->scene_change_detection;
4727
430
    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
430
    } else {
4731
430
        scs->static_config.rate_control_mode = config_struct->rate_control_mode;
4732
430
    }
4733
430
    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
430
    scs->static_config.tune                = config_struct->tune;
4740
430
    scs->static_config.hierarchical_levels = config_struct->hierarchical_levels;
4741
4742
430
    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
430
    if (scs->static_config.hierarchical_levels == HIERARCHICAL_LEVELS_AUTO) {
4749
430
        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
430
            ? 2
4753
430
            : scs->static_config.pred_structure == LOW_DELAY ? 3
4754
430
            : scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR ||
4755
430
                scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR ||
4756
430
                (input_resolution >= INPUT_SIZE_1080p_RANGE && scs->static_config.enc_mode >= ENC_M8) ||
4757
430
                !(scs->static_config.enc_mode <= ENC_M8) || input_resolution >= INPUT_SIZE_8K_RANGE
4758
430
            ? 4
4759
430
            : 5;
4760
430
    }
4761
430
    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
430
    if (scs->allintra) {
4776
430
        scs->static_config.hierarchical_levels = 2;
4777
430
    }
4778
430
    scs->max_temporal_layers                  = scs->static_config.hierarchical_levels;
4779
430
    scs->static_config.look_ahead_distance    = config_struct->look_ahead_distance;
4780
430
    scs->static_config.frame_rate_denominator = config_struct->frame_rate_denominator;
4781
430
    scs->static_config.frame_rate_numerator   = config_struct->frame_rate_numerator;
4782
4783
430
    scs->static_config.target_bit_rate = config_struct->target_bit_rate;
4784
430
    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
430
    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
430
    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
430
    scs->static_config.max_qp_allowed = scs->static_config.lossless ? MIN_QP_VALUE : config_struct->max_qp_allowed;
4796
4797
430
    scs->static_config.min_qp_allowed      = scs->static_config.lossless ? MIN_QP_VALUE
4798
430
             : config_struct->min_qp_allowed == MIN_QP_AUTO ? scs->static_config.rate_control_mode ? 4 : MIN_QP_VALUE
4799
248
                                                            : config_struct->min_qp_allowed;
4800
430
    scs->static_config.vbr_min_section_pct = config_struct->vbr_min_section_pct;
4801
430
    scs->static_config.vbr_max_section_pct = config_struct->vbr_max_section_pct;
4802
430
    scs->static_config.under_shoot_pct     = config_struct->under_shoot_pct;
4803
430
    scs->static_config.over_shoot_pct      = config_struct->over_shoot_pct;
4804
430
    if (scs->static_config.under_shoot_pct == (uint32_t)DEFAULT) {
4805
430
        if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR) {
4806
0
            scs->static_config.under_shoot_pct = 50;
4807
430
        } else {
4808
430
            scs->static_config.under_shoot_pct = 25;
4809
430
        }
4810
430
    }
4811
4812
430
    if (scs->static_config.over_shoot_pct == (uint32_t)DEFAULT) {
4813
430
        scs->static_config.over_shoot_pct = 25;
4814
430
    }
4815
430
    scs->static_config.mbr_over_shoot_pct       = config_struct->mbr_over_shoot_pct;
4816
430
    scs->static_config.max_intra_bitrate_pct    = config_struct->max_intra_bitrate_pct;
4817
430
    scs->static_config.max_inter_bitrate_pct    = config_struct->max_inter_bitrate_pct;
4818
430
    scs->static_config.gop_constraint_rc        = config_struct->gop_constraint_rc;
4819
430
    scs->static_config.maximum_buffer_size_ms   = config_struct->maximum_buffer_size_ms;
4820
430
    scs->static_config.starting_buffer_level_ms = config_struct->starting_buffer_level_ms;
4821
430
    scs->static_config.optimal_buffer_level_ms  = config_struct->optimal_buffer_level_ms;
4822
430
    scs->static_config.recode_loop              = config_struct->recode_loop;
4823
430
    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
430
    } else {
4826
430
        scs->lap_rc = 0;
4827
430
    }
4828
    // Misc
4829
430
    scs->static_config.encoder_bit_depth    = config_struct->encoder_bit_depth;
4830
430
    scs->static_config.encoder_color_format = config_struct->encoder_color_format;
4831
4832
430
    scs->chroma_format_idc = (uint32_t)(scs->static_config.encoder_color_format);
4833
430
    scs->encoder_bit_depth = (uint32_t)(scs->static_config.encoder_bit_depth);
4834
    //16bit pipeline
4835
430
    scs->is_16bit_pipeline = ((config_struct->encoder_bit_depth) > EB_EIGHT_BIT) ? true : false;
4836
430
    scs->subsampling_x     = (scs->chroma_format_idc == EB_YUV444 ? 0 : 1);
4837
430
    scs->subsampling_y     = (scs->chroma_format_idc >= EB_YUV422 ? 0 : 1);
4838
    // Force screen-content detection OFF when allintra
4839
430
    const bool allintra = scs->allintra;
4840
430
#if TUNE_SIMPLIFY_SETTINGS
4841
430
    const bool rtc = scs->static_config.rtc;
4842
430
#endif
4843
430
#if OPT_SC_STILL_IMAGE
4844
430
    if (allintra) {
4845
430
        if (config_struct->screen_content_mode <= 1) {
4846
0
            scs->static_config.screen_content_mode = config_struct->screen_content_mode;
4847
430
        } else if (scs->static_config.enc_mode <= ENC_M7) {
4848
0
            scs->static_config.screen_content_mode = 3;
4849
430
        } else {
4850
430
            scs->static_config.screen_content_mode = 0;
4851
430
            SVT_WARN(
4852
430
                "Screen-content detection and tools are disabled for all-intra coding at M8 and above; forcing NSC "
4853
430
                "path\n");
4854
430
        }
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
430
    }
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
430
    scs->static_config.profile     = config_struct->profile;
4893
430
    scs->static_config.tier        = config_struct->tier;
4894
430
    scs->static_config.level       = config_struct->level;
4895
430
    scs->static_config.stat_report = config_struct->stat_report;
4896
4897
    // Buffers - Hardcoded(Cleanup)
4898
430
    scs->static_config.use_cpu_flags = config_struct->use_cpu_flags;
4899
4900
430
    scs->static_config.level_of_parallelism = config_struct->level_of_parallelism;
4901
430
    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
430
    scs->static_config.qp            = config_struct->qp;
4911
430
    scs->static_config.recon_enabled = config_struct->recon_enabled;
4912
4913
    // Numerator and Denominator already checked to be non 0
4914
430
    scs->frame_rate = (double)scs->static_config.frame_rate_numerator /
4915
430
        (double)scs->static_config.frame_rate_denominator;
4916
4917
    // Get Default Intra Period if not specified
4918
430
    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
430
    } 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
430
    if (scs->static_config.look_ahead_distance == (uint32_t)~0) {
4925
430
        scs->static_config.look_ahead_distance = compute_default_look_ahead(&scs->static_config);
4926
430
    }
4927
430
    scs->static_config.enable_tf          = scs->allintra ? 0 : config_struct->enable_tf;
4928
430
    scs->static_config.enable_tf_key      = config_struct->enable_tf && config_struct->enable_tf_key;
4929
430
    scs->static_config.enable_overlays    = config_struct->enable_overlays;
4930
430
    scs->static_config.superres_mode      = config_struct->superres_mode;
4931
430
    scs->static_config.superres_denom     = config_struct->superres_denom;
4932
430
    scs->static_config.superres_kf_denom  = config_struct->superres_kf_denom;
4933
430
    scs->static_config.superres_qthres    = config_struct->superres_qthres;
4934
430
    scs->static_config.superres_kf_qthres = config_struct->superres_kf_qthres;
4935
4936
430
    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
430
    scs->static_config.resize_mode     = config_struct->resize_mode;
4944
430
    scs->static_config.resize_denom    = config_struct->resize_denom;
4945
430
    scs->static_config.resize_kf_denom = config_struct->resize_kf_denom;
4946
430
    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
430
    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
430
    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
430
    scs->static_config.frame_scale_evts.evt_num = config_struct->frame_scale_evts.evt_num;
4968
430
    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
430
    scs->static_config.sframe_posi.sframe_num = config_struct->sframe_posi.sframe_num;
4976
430
    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
430
    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
430
    scs->static_config.sframe_posi.sframe_qp_num = config_struct->sframe_posi.sframe_qp_num;
4992
4993
    // Color description
4994
430
    scs->static_config.color_primaries          = config_struct->color_primaries;
4995
430
    scs->static_config.transfer_characteristics = config_struct->transfer_characteristics;
4996
430
    scs->static_config.matrix_coefficients      = config_struct->matrix_coefficients;
4997
430
    scs->static_config.color_range              = config_struct->color_range;
4998
430
    scs->static_config.chroma_sample_position   = config_struct->chroma_sample_position;
4999
430
    scs->static_config.mastering_display        = config_struct->mastering_display;
5000
430
    scs->static_config.content_light_level      = config_struct->content_light_level;
5001
5002
    // switch frame
5003
430
    scs->static_config.sframe_dist      = config_struct->sframe_dist;
5004
430
    scs->static_config.sframe_mode      = config_struct->sframe_mode;
5005
430
    scs->static_config.sframe_qp        = config_struct->sframe_qp;
5006
430
    scs->static_config.sframe_qp_offset = config_struct->sframe_qp_offset;
5007
430
    scs->seq_header.max_frame_width  = config_struct->forced_max_frame_width > 0 ? config_struct->forced_max_frame_width
5008
430
         : scs->static_config.sframe_dist > 0 || scs->static_config.sframe_posi.sframe_posis ? 16384
5009
430
                                                                                             : scs->max_input_luma_width;
5010
430
    scs->seq_header.max_frame_height = config_struct->forced_max_frame_height > 0
5011
430
        ? config_struct->forced_max_frame_height
5012
430
        : scs->static_config.sframe_dist > 0 || scs->static_config.sframe_posi.sframe_posis
5013
430
        ? 8704
5014
430
        : scs->max_input_luma_height;
5015
430
    scs->static_config.force_key_frames = config_struct->force_key_frames;
5016
5017
    // QM
5018
430
    scs->static_config.enable_qm           = config_struct->enable_qm;
5019
430
    scs->static_config.min_qm_level        = config_struct->min_qm_level;
5020
430
    scs->static_config.max_qm_level        = config_struct->max_qm_level;
5021
430
    scs->static_config.min_chroma_qm_level = config_struct->min_chroma_qm_level;
5022
430
    scs->static_config.max_chroma_qm_level = config_struct->max_chroma_qm_level;
5023
430
    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
430
    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
430
    scs->static_config.startup_mg_size   = config_struct->startup_mg_size;
5034
430
    scs->static_config.startup_qp_offset = config_struct->startup_qp_offset;
5035
430
    scs->static_config.enable_roi_map    = config_struct->enable_roi_map;
5036
5037
    // Variance Boost
5038
430
    scs->static_config.enable_variance_boost   = config_struct->enable_variance_boost;
5039
430
    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
430
    scs->static_config.variance_octile = config_struct->variance_octile;
5044
430
#endif
5045
430
    scs->static_config.variance_boost_curve = config_struct->variance_boost_curve;
5046
5047
    // Temporal filtering strength
5048
430
    scs->static_config.tf_strength = config_struct->tf_strength;
5049
5050
    // Frame-level luminance-based QP bias
5051
430
    scs->static_config.luminance_qp_bias = config_struct->luminance_qp_bias;
5052
5053
    // Sharpness
5054
430
    scs->static_config.sharpness = config_struct->sharpness;
5055
5056
    // QP scaling compression
5057
430
    scs->static_config.qp_scale_compress_strength = config_struct->qp_scale_compress_strength;
5058
5059
    // Adaptive film grain
5060
430
    scs->static_config.adaptive_film_grain = config_struct->adaptive_film_grain;
5061
5062
    // Max TX size
5063
430
    scs->static_config.max_tx_size = config_struct->max_tx_size;
5064
5065
    // Extended CRF
5066
430
    scs->static_config.extended_crf_qindex_offset = config_struct->extended_crf_qindex_offset;
5067
5068
    // AC bias
5069
430
    scs->static_config.ac_bias = config_struct->ac_bias;
5070
5071
    // HBD-MDS
5072
430
    scs->static_config.hbd_mds = config_struct->hbd_mds;
5073
5074
    // Ref-frame management: propagate caller's max-anchors hint (0 = disabled).
5075
430
    scs->static_config.max_managed_refs = config_struct->max_managed_refs;
5076
5077
    // Override settings for Still IQ tune
5078
430
    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
430
    } 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
430
#if FTR_TUNE_VMAF
5106
430
    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
430
#endif
5110
430
    return;
5111
430
}
5112
5113
/**********************************
5114
5115
* Set Parameter
5116
**********************************/
5117
EB_API EbErrorType svt_av1_enc_set_parameter(EbComponentType*          svt_enc_component,
5118
430
                                             EbSvtAv1EncConfiguration* config_struct) {
5119
430
    if (svt_enc_component == NULL) {
5120
0
        return EB_ErrorBadParameter;
5121
0
    }
5122
5123
430
    EbEncHandle*        enc_handle = (EbEncHandle*)svt_enc_component->p_component_private;
5124
430
    SequenceControlSet* scs        = enc_handle->scs_instance->scs;
5125
430
    copy_api_from_app(scs, config_struct);
5126
5127
430
    EbErrorType return_error = svt_av1_verify_settings(scs);
5128
5129
430
    if (return_error == EB_ErrorBadParameter) {
5130
0
        return EB_ErrorBadParameter;
5131
0
    }
5132
5133
430
    if (scs->static_config.avif) {
5134
430
        scs->seq_header.still_picture                = 1;
5135
430
        scs->seq_header.reduced_still_picture_header = 1;
5136
430
    }
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
430
    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
430
    set_param_based_on_input(scs);
5165
    // Initialize the Prediction Structure Group
5166
430
    EB_NO_THROW_NEW(enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr,
5167
430
                    svt_aom_prediction_structure_group_ctor);
5168
430
    if (!enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr) {
5169
0
        return EB_ErrorInsufficientResources;
5170
0
    }
5171
430
    return_error = load_default_buffer_configuration_settings(scs);
5172
5173
430
    svt_av1_print_lib_params(scs);
5174
5175
    // free frame scale events after copy to encoder
5176
430
    if (config_struct->frame_scale_evts.resize_denoms) {
5177
0
        EB_FREE(config_struct->frame_scale_evts.resize_denoms);
5178
0
    }
5179
430
    if (config_struct->frame_scale_evts.resize_kf_denoms) {
5180
0
        EB_FREE(config_struct->frame_scale_evts.resize_kf_denoms);
5181
0
    }
5182
430
    if (config_struct->frame_scale_evts.start_frame_nums) {
5183
0
        EB_FREE(config_struct->frame_scale_evts.start_frame_nums);
5184
0
    }
5185
430
    memset(&config_struct->frame_scale_evts, 0, sizeof(SvtAv1FrameScaleEvts));
5186
5187
    // free sframe position list
5188
430
    if (config_struct->sframe_posi.sframe_qps) {
5189
0
        EB_FREE(config_struct->sframe_posi.sframe_qps);
5190
0
    }
5191
430
    if (config_struct->sframe_posi.sframe_qp_offsets) {
5192
0
        EB_FREE(config_struct->sframe_posi.sframe_qp_offsets);
5193
0
    }
5194
430
    if (config_struct->sframe_posi.sframe_posis) {
5195
0
        EB_FREE(config_struct->sframe_posi.sframe_posis);
5196
0
    }
5197
430
    memset(&config_struct->sframe_posi, 0, sizeof(SvtAv1SFramePositions));
5198
5199
430
    return return_error;
5200
430
}
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
430
                                     uint8_t* source, int pass) {
5436
430
    EbErrorType return_error = EB_ErrorNone;
5437
5438
430
    EbPictureBufferDesc* input_pic             = (EbPictureBufferDesc*)destination;
5439
430
    EbPictureBufferDesc* y8b_input_picture_ptr = (EbPictureBufferDesc*)destination_y8b;
5440
430
    EbSvtIOFormat*       input_ptr             = (EbSvtIOFormat*)source;
5441
5442
430
    uint32_t luma_width  = (uint32_t)(input_pic->width - scs->max_input_pad_right);
5443
430
    uint32_t luma_height = (uint32_t)(input_pic->height - scs->max_input_pad_bottom);
5444
5445
430
    const uint8_t  subsampling_x = (input_pic->color_format == EB_YUV444 ? 0 : 1);
5446
430
    const uint8_t  subsampling_y = ((input_pic->color_format == EB_YUV444 || input_pic->color_format == EB_YUV422) ? 0
5447
430
                                                                                                                   : 1);
5448
430
    const uint32_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5449
430
    const uint32_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5450
5451
430
    if (scs->static_config.encoder_bit_depth == EB_EIGHT_BIT) {
5452
430
        svt_av1_copy_wxh_8bit(input_ptr->luma,
5453
430
                              input_ptr->y_stride,
5454
430
                              y8b_input_picture_ptr->y_buffer,
5455
430
                              input_pic->y_stride,
5456
430
                              luma_height,
5457
430
                              luma_width);
5458
430
        svt_av1_copy_wxh_8bit(
5459
430
            input_ptr->cb, input_ptr->cb_stride, input_pic->u_buffer, input_pic->u_stride, chroma_height, chroma_width);
5460
430
        svt_av1_copy_wxh_8bit(
5461
430
            input_ptr->cr, input_ptr->cr_stride, input_pic->v_buffer, input_pic->v_stride, chroma_height, chroma_width);
5462
430
    } 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
430
    return return_error;
5496
430
}
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
860
                              EbBufferHeaderType* src, int pass) {
5651
    // Copy the higher level structure
5652
860
    dst->n_alloc_len  = src->n_alloc_len;
5653
860
    dst->n_filled_len = src->n_filled_len;
5654
860
    dst->flags        = src->flags;
5655
860
    dst->pts          = src->pts;
5656
860
    dst->n_tick_count = src->n_tick_count;
5657
860
    dst->size         = src->size;
5658
860
    dst->qp           = src->qp;
5659
860
    dst->pic_type     = src->pic_type;
5660
860
    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
860
    } else if (pass != ENCODE_FIRST_PASS) {
5666
        // Bypass copy for the unecessary picture in IPPP pass
5667
        // Copy the picture buffer
5668
860
        if (src->p_buffer != NULL) {
5669
430
            copy_frame_buffer(scs, dst->p_buffer, dst_y8b->p_buffer, src->p_buffer, pass);
5670
            // Copy the metadata array
5671
430
            if (svt_aom_copy_metadata_buffer(dst, src->metadata) != EB_ErrorNone) {
5672
430
                dst->metadata = NULL;
5673
430
            }
5674
430
        }
5675
860
    }
5676
5677
    // Copy the private data list
5678
860
    if (src->p_app_private) {
5679
0
        copy_private_data_list(dst, src);
5680
860
    } else {
5681
860
        dst->p_app_private = NULL;
5682
860
    }
5683
860
}
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
860
                                                EbHandle config_mutex) {
5688
860
    EbPrivDataNode* node = (EbPrivDataNode*)input_ptr->p_app_private;
5689
860
    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
860
    return EB_ErrorNone;
5867
860
}
5868
5869
/**********************************
5870
* Empty This Buffer
5871
**********************************/
5872
860
EB_API EbErrorType svt_av1_enc_send_picture(EbComponentType* svt_enc_component, EbBufferHeaderType* p_buffer) {
5873
860
    EbErrorType         return_val     = EB_ErrorNone;
5874
860
    EbEncHandle*        enc_handle_ptr = (EbEncHandle*)svt_enc_component->p_component_private;
5875
860
    EbObjectWrapper*    eb_wrapper_ptr;
5876
860
    EbBufferHeaderType* app_hdr    = p_buffer;
5877
860
    enc_handle_ptr->frame_received = true;
5878
5879
860
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
5880
860
    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
860
    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
860
    EbObjectWrapper* y8b_wrapper;
5901
860
    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
860
    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
860
    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
860
    svt_object_inc_live_count(y8b_wrapper, 1);
5913
5914
    // svt_object_inc_live_count(y8b_wrapper, 1);
5915
5916
860
    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
860
    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
860
    svt_object_inc_live_count(eb_wrapper_ptr, 1);
5925
5926
860
    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
860
    EbBufferHeaderType* lib_y8b_hdr = (EbBufferHeaderType*)y8b_wrapper->object_ptr;
5930
860
    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
860
    EbPictureBufferDesc*      input_pic      = (EbPictureBufferDesc*)lib_y8b_hdr->p_buffer;
5934
860
    EbSvtAv1EncConfiguration* config         = &scs->static_config;
5935
860
    bool                      is_16bit_input = config->encoder_bit_depth > EB_EIGHT_BIT;
5936
5937
860
    const uint8_t subsampling_x = (config->encoder_color_format == EB_YUV444 ? 0 : 1);
5938
860
    const uint8_t subsampling_y =
5939
860
        ((config->encoder_color_format == EB_YUV444 || config->encoder_color_format == EB_YUV422) ? 0 : 1);
5940
860
    const size_t luma_width    = input_pic->width - scs->max_input_pad_right;
5941
860
    const size_t luma_height   = input_pic->height - scs->max_input_pad_bottom;
5942
860
    const size_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5943
860
    const size_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5944
860
    const size_t read_size     = (luma_width * luma_height + 2 * chroma_width * chroma_height) << is_16bit_input;
5945
5946
860
    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
860
    } else {
5953
860
        copy_input_buffer(scs, lib_reg_hdr, lib_y8b_hdr, app_hdr, 0);
5954
860
    }
5955
5956
    //Take a new App-RessCoord command
5957
860
    EbObjectWrapper* input_cmd_wrp;
5958
860
    svt_get_empty_object(enc_handle_ptr->input_cmd_producer_fifo_ptr, &input_cmd_wrp);
5959
860
    InputCommand* input_cmd_obj = (InputCommand*)input_cmd_wrp->object_ptr;
5960
    //Fill the command with two picture buffers
5961
860
    input_cmd_obj->eb_input_wrapper_ptr = eb_wrapper_ptr;
5962
860
    input_cmd_obj->y8b_wrapper          = y8b_wrapper;
5963
    //Send to Lib
5964
860
    svt_post_full_object(input_cmd_wrp);
5965
5966
860
#if CONFIG_SINGLE_THREAD_KERNEL
5967
    // In single-thread mode, run the entire pipeline synchronously
5968
860
    if (enc_handle_ptr->kernel_dispatcher.active) {
5969
0
        svt_kernel_dispatcher_run(&enc_handle_ptr->kernel_dispatcher);
5970
0
    }
5971
860
#endif
5972
5973
860
    return return_val;
5974
860
}
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
430
        *p_buffer = NULL;
6020
430
        return EB_NoErrorEmptyQueue;
6021
430
    }
6022
6023
1.29k
    if (pic_send_done || cfg->pred_structure == LOW_DELAY) {
6024
860
        svt_get_full_object(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
6025
860
    } else {
6026
430
        svt_get_full_object_non_blocking(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
6027
430
    }
6028
6029
1.29k
    if (eb_wrapper_ptr) {
6030
860
        packet = (EbBufferHeaderType*)eb_wrapper_ptr->object_ptr;
6031
860
        if (packet->flags & EB_BUFFERFLAG_ERROR_MASK) {
6032
0
            return_error = EB_ErrorMax;
6033
0
        }
6034
        // return the output stream buffer
6035
860
        *p_buffer = packet;
6036
6037
        // check if we have reached the end of the output stream
6038
860
        enc_handle->eos_sent += packet->flags & EB_BUFFERFLAG_EOS;
6039
6040
        // save the wrapper pointer for the release
6041
860
        (*p_buffer)->wrapper_ptr = (void*)eb_wrapper_ptr;
6042
860
    } else {
6043
430
        return_error = EB_NoErrorEmptyQueue;
6044
430
    }
6045
1.29k
    return return_error;
6046
1.72k
}
6047
6048
860
EB_API void svt_av1_enc_release_out_buffer(EbBufferHeaderType** p_buffer) {
6049
860
    if (p_buffer && (*p_buffer)->wrapper_ptr) {
6050
860
        if ((*p_buffer)->p_buffer) {
6051
430
            EB_FREE((*p_buffer)->p_buffer);
6052
430
        }
6053
        // Release out put buffer back into the pool
6054
860
        svt_release_object((EbObjectWrapper*)(*p_buffer)->wrapper_ptr);
6055
860
    }
6056
860
    return;
6057
860
}
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
430
EB_API void svt_av1_print_version(void) {
6117
430
    SVT_INFO("-------------------------------------------\n");
6118
430
    SVT_INFO("SVT [version]:\tSVT-AV1 Encoder Lib %s\n", SVT_AV1_CVS_VERSION);
6119
430
    const char* compiler =
6120
430
#if defined(__clang__)
6121
430
        __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
430
        ;
6138
430
    SVT_INFO("SVT [build]  :\t%s %zu bit\n", compiler, sizeof(void*) * 8);
6139
430
#if !REPRODUCIBLE_BUILDS
6140
430
    SVT_INFO("LIB Build date: %s %s\n", __DATE__, __TIME__);
6141
430
#endif
6142
430
    SVT_INFO("-------------------------------------------\n");
6143
430
}
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
430
static EbErrorType init_svt_av1_encoder_handle(EbComponentType* hComponent) {
6161
430
    EbErrorType      return_error      = EB_ErrorNone;
6162
430
    EbComponentType* svt_enc_component = hComponent;
6163
430
    EbEncHandle*     handle;
6164
430
    svt_av1_print_version();
6165
6166
430
    enc_switch_to_real_time();
6167
6168
    // Set Component Size & Version
6169
430
    svt_enc_component->size = sizeof(EbComponentType);
6170
6171
430
    EB_NEW(handle, svt_enc_handle_ctor, svt_enc_component);
6172
430
    svt_enc_component->p_component_private = handle;
6173
6174
430
    return return_error;
6175
430
}
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
    // both u and v
6384
0
    const uint32_t chroma_size = luma_size >> 1;
6385
0
    const uint32_t ten_bit     = (scs->static_config.encoder_bit_depth > 8);
6386
0
    const uint32_t frame_size  = (luma_size + chroma_size) << ten_bit;
6387
6388
0
    *object_dbl_ptr = NULL;
6389
0
    EB_CALLOC(recon_buffer, 1, sizeof(EbBufferHeaderType));
6390
0
    *object_dbl_ptr = (EbPtr)recon_buffer;
6391
6392
    // Initialize Header
6393
0
    recon_buffer->size = sizeof(EbBufferHeaderType);
6394
6395
    // Assign the variables
6396
0
    EB_MALLOC(recon_buffer->p_buffer, frame_size);
6397
6398
0
    recon_buffer->n_alloc_len   = frame_size;
6399
0
    recon_buffer->p_app_private = NULL;
6400
6401
0
    return EB_ErrorNone;
6402
0
}
6403
6404
0
void svt_output_recon_buffer_header_destroyer(EbPtr p) {
6405
0
    EbBufferHeaderType* obj = (EbBufferHeaderType*)p;
6406
0
    EB_FREE(obj->p_buffer);
6407
0
    EB_FREE(obj);
6408
0
}
6409
6410
/**********************************
6411
* svt_av1_enc_get_stream_info get stream information from encoder
6412
**********************************/
6413
EB_API EbErrorType svt_av1_enc_get_stream_info(EbComponentType* svt_enc_component, uint32_t stream_info_id,
6414
0
                                               void* info) {
6415
0
    if (stream_info_id >= SVT_AV1_STREAM_INFO_END || stream_info_id < SVT_AV1_STREAM_INFO_START) {
6416
0
        return EB_ErrorBadParameter;
6417
0
    }
6418
0
    EbEncHandle*    enc_handle       = svt_enc_component->p_component_private;
6419
0
    EncodeContext*  context          = enc_handle->scs_instance->enc_ctx;
6420
0
    SvtAv1FixedBuf* first_pass_stats = info;
6421
0
    first_pass_stats->buf            = context->stats_out.stat;
6422
0
    first_pass_stats->sz             = context->stats_out.size * sizeof(FIRSTPASS_STATS);
6423
0
    return EB_ErrorNone;
6424
0
}