Coverage Report

Created: 2026-07-16 06:32

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