Coverage Report

Created: 2026-09-02 06:43

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