Coverage Report

Created: 2026-08-31 06:22

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