Coverage Report

Created: 2026-09-13 06:34

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
553
#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
553
#define EB_PictureManagerProcessInitCount               1
89
#define EB_RateControlProcessInitCount                  1
90
1.10k
#define EB_PacketizationProcessInitCount                1
91
92
// Output Buffer Transfer Parameters
93
553
#define TPL_INPUT_PORT_SOP                              0
94
553
#define TPL_INPUT_PORT_TPL                              1
95
2.76k
#define TPL_INPUT_PORT_INVALID                          -1
96
553
#define ENCDEC_INPUT_PORT_MDC                           0
97
553
#define ENCDEC_INPUT_PORT_ENCDEC                        1
98
3.96k
#define ENCDEC_INPUT_PORT_INVALID                       -1
99
100
1.10k
#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
553
static uint16_t get_num_refs_in_one_mg(uint32_t hierarchical_levels, uint32_t referencing_scheme) {
107
553
    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
553
    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.65k
    for (uint16_t pic_idx = 0; pic_idx < (uint32_t)(1 << hierarchical_levels); pic_idx += 2) {
117
1.10k
        tot_refs += svt_aom_is_pic_used_as_ref(
118
1.10k
            hierarchical_levels, hierarchical_levels, pic_idx, referencing_scheme, 0);
119
1.10k
    }
120
121
553
    return tot_refs;
122
553
}
123
124
1.10k
static const char* get_asm_level_name_str(EbCpuFlags cpu_flags) {
125
    // clang-format off
126
1.10k
    static const struct {
127
1.10k
        const char *name;
128
1.10k
        EbCpuFlags  flags;
129
1.10k
    } param_maps[] = {
130
1.10k
        {"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
1.10k
    };
152
    // clang-format on
153
1.10k
    static const uint32_t para_map_size = sizeof(param_maps) / sizeof(param_maps[0]);
154
155
2.21k
    for (int32_t i = para_map_size - 1; i >= 0; --i) {
156
1.10k
        if (param_maps[i].flags & cpu_flags) {
157
0
            return param_maps[i].name;
158
0
        }
159
1.10k
    }
160
1.10k
    return "c";
161
1.10k
}
162
163
//Get Number of logical processors
164
553
static uint32_t get_num_processors() {
165
#ifdef _WIN32
166
    return GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
167
#else
168
553
    return sysconf(_SC_NPROCESSORS_ONLN);
169
553
#endif
170
553
}
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
553
static void enc_switch_to_real_time() {
182
553
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
183
553
    if (!geteuid()) {
184
553
        (void)pthread_setschedparam(pthread_self(), SCHED_FIFO, &(struct sched_param){.sched_priority = 99});
185
553
    }
186
553
#endif
187
553
}
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
553
static uint32_t get_max_wavefronts(uint32_t width, uint32_t height, uint32_t blk_size) {
227
553
    assert(width > 0 && height > 0);
228
553
    return (MIN(width, height) + (blk_size - 1)) / blk_size;
229
553
}
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.65k
static bool is_pic_dimension_single_sb(uint32_t sb_size, uint16_t pic_dimension) {
238
1.65k
    return ((pic_dimension + sb_size - 1) / sb_size) == 1;
239
1.65k
}
240
241
/*********************************************************************************
242
* set_segments_numbers: Set the segment numbers for difference processes
243
***********************************************************************************/
244
553
void set_segments_numbers(SequenceControlSet* scs) {
245
553
    const uint32_t lp = scs->lp;
246
247
553
    scs->enc_dec_segment_row_count_array =
248
553
        (lp == PARALLEL_LEVEL_1 || is_pic_dimension_single_sb(scs->super_block_size, scs->max_input_luma_width)) ? 1
249
553
        : (scs->super_block_size == 128) ? MAX((int32_t)((scs->max_input_luma_height + 64) / 128), 1)
250
519
                                         : MAX((int32_t)((scs->max_input_luma_height + 32) / 64), 1);
251
553
    scs->enc_dec_segment_col_count_array =
252
553
        (lp == PARALLEL_LEVEL_1 || is_pic_dimension_single_sb(scs->super_block_size, scs->max_input_luma_height)) ? 1
253
553
        : (scs->super_block_size == 128) ? MAX((int32_t)((scs->max_input_luma_width + 64) / 128), 1)
254
523
                                         : MAX((int32_t)((scs->max_input_luma_width + 32) / 64), 1);
255
256
553
    scs->me_segment_row_count_array = scs->tf_segment_row_count = (lp == PARALLEL_LEVEL_1) ? 1
257
553
        : (((scs->max_input_luma_height + 32) / BLOCK_SIZE_64) < 6)                        ? 1
258
553
                                                                                           : 8;
259
553
    scs->me_segment_col_count_array = scs->tf_segment_column_count = (lp == PARALLEL_LEVEL_1) ? 1
260
553
        : (((scs->max_input_luma_width + 32) / BLOCK_SIZE_64) < 10)                           ? 1
261
553
                                                                                              : 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
553
    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
553
    } else {
274
        // by default, do not use tile parallel. to enable, one can set one tile-group per tile.
275
553
        scs->tile_group_col_count_array = 1;
276
553
        scs->tile_group_row_count_array = 1;
277
553
    }
278
279
    // TPL processed in 64x64 blocks, so check width against 64x64 block size (even if SB is 128x128)
280
553
    scs->tpl_segment_row_count_array = (lp == PARALLEL_LEVEL_1 ||
281
553
                                        is_pic_dimension_single_sb(64, scs->max_input_luma_width))
282
553
        ? 1
283
553
        : MAX((int32_t)((scs->max_input_luma_height + 32) / 64), 1);
284
285
553
    scs->tpl_segment_col_count_array = (lp == PARALLEL_LEVEL_1)
286
553
        ? 1
287
553
        : MAX((int32_t)((scs->max_input_luma_width + 32) / 64), 1);
288
289
553
    scs->cdef_segment_row_count    = (lp == PARALLEL_LEVEL_1)          ? 1
290
553
           : (((scs->max_input_luma_height + 32) / BLOCK_SIZE_64) < 6) ? 1
291
553
           : (scs->input_resolution <= INPUT_SIZE_1080p_RANGE)         ? 2
292
0
                                                                       : 4;
293
553
    scs->cdef_segment_column_count = (lp == PARALLEL_LEVEL_1)       ? 1
294
553
        : (((scs->max_input_luma_width + 32) / BLOCK_SIZE_64) < 10) ? 1
295
553
        : (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
553
    const uint32_t unit_size       = RESTORATION_UNITSIZE_MAX;
301
553
    const uint32_t rest_seg_w      = MAX((scs->max_input_luma_width / 2 + (unit_size >> 1)) / unit_size, 1);
302
553
    const uint32_t rest_seg_h      = MAX((scs->max_input_luma_height / 2 + (unit_size >> 1)) / unit_size, 1);
303
553
    scs->rest_segment_column_count = (lp == PARALLEL_LEVEL_1) ? 1
304
553
        : scs->input_resolution <= INPUT_SIZE_1080p_RANGE     ? MIN(rest_seg_w, 6)
305
553
                                                              : MIN(rest_seg_w, 9);
306
553
    scs->rest_segment_row_count    = (lp == PARALLEL_LEVEL_1) ? 1
307
553
           : scs->input_resolution <= INPUT_SIZE_1080p_RANGE  ? MIN(rest_seg_h, 4)
308
553
                                                              : MIN(rest_seg_h, 6);
309
553
}
310
311
553
static EbErrorType load_default_buffer_configuration_settings(SequenceControlSet* scs) {
312
553
    EbErrorType return_error = EB_ErrorNone;
313
553
    uint32_t    core_count   = get_num_processors();
314
315
553
    uint32_t lp = scs->static_config.level_of_parallelism;
316
553
    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
553
    scs->lp = lp;
322
553
    set_segments_numbers(scs);
323
324
553
    const bool is_low_delay = (scs->static_config.pred_structure == LOW_DELAY);
325
    // adjust buffer count for superres
326
553
    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
553
        ? 1
330
553
        : 0;
331
332
    //#====================== Data Structures and Picture Buffers ======================
333
334
553
    uint32_t min_input, min_parent, min_child, min_paref, min_ref, min_tpl_ref, min_overlay, min_recon, min_me;
335
553
    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
553
    uint32_t      mg_size = 1 << scs->static_config.hierarchical_levels;
340
553
    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
553
    const uint8_t eos_delay = is_low_delay || scs->allintra ? 0 : 1;
346
347
    //Minimum input pictures needed in the pipeline
348
553
    uint16_t lad_mg_pictures = (1 + mg_size + overlay) *
349
553
        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
553
    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
553
    min_input = return_ppcs;
354
355
553
    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
553
    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
553
    min_child                          = 1;
364
553
    const uint16_t num_ref_from_cur_mg = get_num_refs_in_one_mg(scs->static_config.hierarchical_levels,
365
553
                                                                scs->mrp_ctrls.referencing_scheme) +
366
553
        1; //+1: to accomodate one for a delayed-I
367
553
    const uint16_t num_ref_lad_mgs = num_ref_from_cur_mg * scs->lad_mg;
368
553
    const uint8_t  dpb_frames =
369
553
        REF_FRAMES; // up to dpb_frame refs from prev MGs can be used (AV1 spec allows holding up to 8 frames for references)
370
553
    min_ref     = (scs->enable_dec_order) ? dpb_frames + 1 : num_ref_from_cur_mg + num_ref_lad_mgs + dpb_frames;
371
553
    min_tpl_ref = scs->tpl ? dpb_frames + 1 : 0; // TPL pictures are processed in decode order
372
553
    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
553
    } else {
378
553
        min_me = 1;
379
553
    }
380
381
    //PA REF
382
553
    const uint16_t num_pa_ref_from_cur_mg =
383
553
        mg_size; //ref+nref; nRef PA buffers are processed in PicAnalysis and used in TF
384
553
    min_paref = num_pa_ref_from_cur_mg + lad_mg_pictures + scs->scd_delay + eos_delay + dpb_frames;
385
386
553
    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
553
    min_overlay = scs->static_config.enable_overlays ? return_ppcs : 0;
394
553
    min_recon   = min_ref;
395
396
553
    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
553
    uint32_t n_extra_mg;
436
553
    if (lp <= PARALLEL_LEVEL_3 || is_low_delay) {
437
0
        n_extra_mg = 0;
438
553
    } else if (lp <= PARALLEL_LEVEL_4) {
439
553
        n_extra_mg = 1;
440
553
    } 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
553
    max_input  = min_input + (1 + mg_size) * n_extra_mg;
449
553
    max_parent = max_input;
450
553
    max_child  = (mg_size / 2) * (n_extra_mg + 1);
451
553
    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
553
    if (is_low_delay) {
454
0
        max_child = 1;
455
0
    }
456
457
    // max_ref defines here to avoid cppcheck warning
458
553
    uint32_t max_ref = min_ref + num_ref_from_cur_mg * n_extra_mg;
459
553
    max_paref        = min_paref + (1 + mg_size) * n_extra_mg;
460
553
    max_me           = min_me + (1 + mg_size) * n_extra_mg;
461
553
    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
553
    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
553
    scs->input_buffer_fifo_init_count            = clamp(max_input, min_input, max_input);
470
553
    scs->picture_control_set_pool_init_count     = clamp(max_parent, min_parent, max_parent);
471
553
    scs->pa_reference_picture_buffer_init_count  = clamp(max_paref, min_paref, max_paref);
472
553
    scs->tpl_reference_picture_buffer_init_count = min_tpl_ref;
473
553
    scs->output_recon_buffer_fifo_init_count = scs->reference_picture_buffer_init_count = clamp(
474
553
        max_recon, min_recon, max_recon);
475
553
    scs->me_pool_init_count                      = clamp(max_me, min_me, max_me);
476
553
    scs->overlay_input_picture_buffer_init_count = min_overlay;
477
478
553
    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
553
    } 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
553
    } 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
553
    } else if (lp <= PARALLEL_LEVEL_4) {
506
553
        scs->picture_control_set_pool_init_count_child = scs->enc_dec_pool_init_count = clamp(
507
553
                                                                                            12, min_child, max_child) +
508
553
            superres_count;
509
553
    } 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
553
    if (scs->static_config.avif) {
523
553
        scs->input_buffer_fifo_init_count              = 4;
524
553
        scs->picture_control_set_pool_init_count       = 4;
525
553
        scs->pa_reference_picture_buffer_init_count    = 4;
526
553
        scs->tpl_reference_picture_buffer_init_count   = 0;
527
553
        scs->output_recon_buffer_fifo_init_count       = 1;
528
553
        scs->reference_picture_buffer_init_count       = 2;
529
553
        scs->picture_control_set_pool_init_count_child = 1;
530
553
        scs->enc_dec_pool_init_count                   = 1;
531
553
        scs->me_pool_init_count                        = 1;
532
553
        scs->overlay_input_picture_buffer_init_count   = 0;
533
553
        scs->allintra                                  = true;
534
553
        scs->static_config.intra_period_length         = 0;
535
553
    }
536
537
    //#====================== Inter process Fifos ======================
538
553
    const uint32_t tot_tf_segs  = scs->tf_segment_column_count * scs->tf_segment_row_count;
539
553
    const uint32_t tot_me_segs  = scs->me_segment_col_count_array * scs->me_segment_row_count_array;
540
553
    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
553
    const bool     allow_recode     = scs->static_config.recode_loop != DISALLOW_RECODE;
544
553
    const bool     is_superres      = scs->static_config.superres_mode != SUPERRES_NONE;
545
553
    const uint32_t tot_enc_dec_segs = scs->enc_dec_segment_col_count_array * scs->enc_dec_segment_row_count_array;
546
553
    const uint32_t tot_cdef_segs    = scs->cdef_segment_column_count * scs->cdef_segment_row_count;
547
553
    const uint32_t tot_rest_segs    = scs->rest_segment_column_count * scs->rest_segment_row_count;
548
553
    const uint32_t tot_tiles = MIN(64, (1 << scs->static_config.tile_columns) * (1 << scs->static_config.tile_rows));
549
553
    const uint32_t max_fifo  = 300;
550
551
    // Open loop
552
553
    scs->resource_coordination_fifo_init_count = MIN(
553
553
        max_fifo, scs->picture_control_set_pool_init_count); // outputs one pic @ a time to pic analysis (no segments)
554
553
    scs->picture_analysis_fifo_init_count = MIN(
555
553
        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
553
    scs->enc_ctx->picture_decision_reorder_queue_size = scs->picture_control_set_pool_init_count + 1;
559
553
    scs->picture_decision_fifo_init_count             = MIN(
560
553
        max_fifo, scs->picture_control_set_pool_init_count * MAX(tot_me_segs, tot_tf_segs));
561
553
    scs->motion_estimation_fifo_init_count = MIN(
562
553
        max_fifo, scs->picture_control_set_pool_init_count); // output from ME to init_rc_process (single threaded)
563
553
    scs->initial_rate_control_fifo_init_count = MIN(
564
553
        max_fifo, scs->picture_control_set_pool_init_count); // output from irc to src_ops (single threaded)
565
553
    scs->tpl_disp_fifo_init_count = MIN(max_fifo,
566
553
                                        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
553
    scs->picture_demux_fifo_init_count = MIN(
570
553
        max_fifo,
571
553
        scs->picture_control_set_pool_init_count +
572
553
            2 * scs->picture_control_set_pool_init_count_child); // input to pic mgr from src ops, rest, and packetization
573
553
    scs->enc_ctx->pic_mgr_input_pic_list_size = scs->picture_control_set_pool_init_count;
574
575
    // Closed loop
576
553
    scs->rate_control_tasks_fifo_init_count = MIN(
577
553
        max_fifo,
578
553
        2 * scs->picture_control_set_pool_init_count_child); // inputs to rc form pic manager and EC/packetization
579
553
    scs->rate_control_fifo_init_count                = MIN(max_fifo,
580
553
                                            scs->picture_control_set_pool_init_count_child); // inputs to MDC from rc
581
553
    scs->mode_decision_configuration_fifo_init_count = MIN(
582
553
        max_fifo,
583
553
        scs->picture_control_set_pool_init_count_child * tot_tiles * tot_enc_dec_segs *
584
553
            (1 + allow_recode + is_superres)); // input to MD from MDC
585
553
    scs->enc_dec_fifo_init_count = MIN(max_fifo,
586
553
                                       scs->picture_control_set_pool_init_count_child); // TODO: Add DLF segments
587
553
    scs->dlf_fifo_init_count     = MIN(
588
553
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_cdef_segs); // input to CDEF from DLF
589
553
    scs->cdef_fifo_init_count = MIN(
590
553
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_rest_segs); // input to rest from CDEF
591
553
    scs->rest_fifo_init_count = MIN(
592
553
        max_fifo, scs->picture_control_set_pool_init_count_child * tot_tiles); // input to EC from rest
593
553
    scs->entropy_coding_fifo_init_count = MIN(
594
553
        max_fifo, scs->picture_control_set_pool_init_count_child); // EC outputs to packetization (single threaded)
595
553
    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
553
    scs->output_stream_buffer_fifo_init_count = scs->picture_control_set_pool_init_count + UNDISP_QUEUE_SIZE + 2;
604
605
    //#====================== Processes number ======================
606
553
    scs->total_process_init_count = 0;
607
608
553
    uint32_t max_pa_proc, max_me_proc, max_tpl_proc, max_mdc_proc, max_md_proc, max_ec_proc, max_dlf_proc,
609
553
        max_cdef_proc, max_rest_proc;
610
611
553
    max_pa_proc  = max_input;
612
553
    max_me_proc  = max_me * tot_me_segs;
613
553
    max_tpl_proc = scs->tpl ? get_max_wavefronts(scs->max_input_luma_width, scs->max_input_luma_height, 64) : 1;
614
553
    max_mdc_proc = scs->picture_control_set_pool_init_count_child;
615
553
    max_md_proc  = scs->picture_control_set_pool_init_count_child *
616
553
        get_max_wavefronts(scs->max_input_luma_width, scs->max_input_luma_height, scs->super_block_size);
617
553
    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
553
    uint32_t ld_workers = 1;
623
553
    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
553
    max_dlf_proc  = scs->picture_control_set_pool_init_count_child;
636
553
    max_cdef_proc = scs->picture_control_set_pool_init_count_child * scs->cdef_segment_column_count *
637
553
        scs->cdef_segment_row_count;
638
553
    max_rest_proc = scs->picture_control_set_pool_init_count_child * scs->rest_segment_column_count *
639
553
        scs->rest_segment_row_count;
640
1.10k
#define WORKERS_COUNT(x) (is_low_delay ? ld_workers : (x))
641
553
    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
553
    } 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
553
    } 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
553
    } else if (lp <= PARALLEL_LEVEL_5 || scs->input_resolution <= INPUT_SIZE_1080p_RANGE) {
687
553
        uint8_t pa_processes = scs->static_config.film_grain_denoise_strength ? 20 : 4;
688
553
        if (scs->static_config.pass == ENC_FIRST_PASS) {
689
0
            pa_processes = lp <= PARALLEL_LEVEL_5 ? 12 : 20;
690
0
        }
691
553
        scs->total_process_init_count += (scs->source_based_operations_process_init_count = 1);
692
553
        scs->total_process_init_count += (scs->picture_analysis_process_init_count = clamp(
693
553
                                              pa_processes, 1, max_pa_proc));
694
553
        scs->total_process_init_count += (scs->motion_estimation_process_init_count = clamp(25, 1, max_me_proc));
695
553
        scs->total_process_init_count += (scs->tpl_disp_process_init_count = clamp(6, 1, max_tpl_proc));
696
553
        scs->total_process_init_count += (scs->mode_decision_configuration_process_init_count = clamp(
697
553
                                              3, 1, max_mdc_proc));
698
553
        scs->total_process_init_count +=
699
553
            (scs->enc_dec_process_init_count = clamp(
700
553
                 WORKERS_COUNT(6), scs->picture_control_set_pool_init_count_child, max_md_proc));
701
553
        scs->total_process_init_count += (scs->entropy_coding_process_init_count = clamp(
702
553
                                              WORKERS_COUNT(4), 1, max_ec_proc));
703
553
        scs->total_process_init_count += (scs->dlf_process_init_count = clamp(3, 1, max_dlf_proc));
704
553
        scs->total_process_init_count += (scs->cdef_process_init_count = clamp(6, 1, max_cdef_proc));
705
553
        scs->total_process_init_count += (scs->rest_process_init_count = clamp(4, 1, max_rest_proc));
706
553
    } 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
553
#undef WORKERS_COUNT
728
553
    scs->total_process_init_count += 6; // single processes count
729
553
    if (scs->static_config.pass == 0 || scs->static_config.pass == 2) {
730
553
        SVT_INFO("Level of Parallelism: %u\n", lp);
731
553
        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
553
        scs->static_config.use_cpu_flags &= 0;
744
553
        SVT_INFO("[asm level on system : up to %s]\n", get_asm_level_name_str(0));
745
553
        SVT_INFO("[asm level selected : up to %s]\n", get_asm_level_name_str(scs->static_config.use_cpu_flags));
746
553
#endif
747
553
    }
748
553
    return return_error;
749
553
}
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
1.10k
                                         uint32_t port_type_index) {
765
1.10k
    uint32_t port_index = 0;
766
1.10k
    uint32_t port_count = 0;
767
768
1.65k
    while ((type != rate_control_ports[port_index].type) && (type != RATE_CONTROL_INPUT_PORT_INVALID)) {
769
553
        port_count += rate_control_ports[port_index++].count;
770
553
    }
771
1.10k
    return (port_count + port_type_index);
772
1.10k
}
773
774
// Rate Control
775
553
static uint32_t rate_control_port_total_count(const RateControlPorts* rate_control_ports) {
776
553
    uint32_t port_index  = 0;
777
553
    uint32_t total_count = 0;
778
779
1.65k
    while (rate_control_ports[port_index].type != RATE_CONTROL_INPUT_PORT_INVALID) {
780
1.10k
        total_count += rate_control_ports[port_index++].count;
781
1.10k
    }
782
553
    return total_count;
783
553
}
784
785
static uint32_t pic_mgr_port_lookup(const PicMgrPorts* pic_mgr_ports, PicMgrInputPortTypes type,
786
1.65k
                                    uint32_t port_type_index) {
787
1.65k
    uint32_t port_index = 0;
788
1.65k
    uint32_t port_count = 0;
789
790
3.31k
    while ((type != pic_mgr_ports[port_index].type) && (type != PIC_MGR_INPUT_PORT_INVALID)) {
791
1.65k
        port_count += pic_mgr_ports[port_index++].count;
792
1.65k
    }
793
1.65k
    return (port_count + port_type_index);
794
1.65k
}
795
796
553
static uint32_t pic_mgr_port_total_count(const PicMgrPorts* pic_mgr_ports) {
797
553
    uint32_t port_index  = 0;
798
553
    uint32_t total_count = 0;
799
800
2.21k
    while (pic_mgr_ports[port_index].type != PIC_MGR_INPUT_PORT_INVALID) {
801
1.65k
        total_count += pic_mgr_ports[port_index++].count;
802
1.65k
    }
803
553
    return total_count;
804
553
}
805
806
// TPL
807
1.10k
static uint32_t tpl_port_lookup(const EncDecPorts_t* tpl_ports, int32_t type, uint32_t port_type_index) {
808
1.10k
    uint32_t port_index = 0;
809
1.10k
    uint32_t port_count = 0;
810
811
1.65k
    while ((type != tpl_ports[port_index].type) && (type != TPL_INPUT_PORT_INVALID)) {
812
553
        port_count += tpl_ports[port_index++].count;
813
553
    }
814
1.10k
    return (port_count + port_type_index);
815
1.10k
}
816
817
553
static uint32_t tpl_port_total_count(const EncDecPorts_t* tpl_ports) {
818
553
    uint32_t port_index  = 0;
819
553
    uint32_t total_count = 0;
820
821
1.65k
    while (tpl_ports[port_index].type != TPL_INPUT_PORT_INVALID) {
822
1.10k
        total_count += tpl_ports[port_index++].count;
823
1.10k
    }
824
553
    return total_count;
825
553
}
826
827
/*****************************************
828
 * Input Port Lookup
829
 *****************************************/
830
// EncDec
831
2.30k
static uint32_t enc_dec_port_lookup(const EncDecPorts_t* enc_dec_ports, int32_t type, uint32_t port_type_index) {
832
2.30k
    uint32_t port_index = 0;
833
2.30k
    uint32_t port_count = 0;
834
835
4.05k
    while ((type != enc_dec_ports[port_index].type) && (type != ENCDEC_INPUT_PORT_INVALID)) {
836
1.74k
        port_count += enc_dec_ports[port_index++].count;
837
1.74k
    }
838
2.30k
    return (port_count + port_type_index);
839
2.30k
}
840
841
// EncDec
842
553
static uint32_t enc_dec_port_total_count(const EncDecPorts_t* enc_dec_ports) {
843
553
    uint32_t port_index  = 0;
844
553
    uint32_t total_count = 0;
845
846
1.65k
    while (enc_dec_ports[port_index].type != ENCDEC_INPUT_PORT_INVALID) {
847
1.10k
        total_count += enc_dec_ports[port_index++].count;
848
1.10k
    }
849
553
    return total_count;
850
553
}
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
553
static void svt_enc_handle_stop_threads(EbEncHandle* enc_handle_ptr) {
859
553
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
860
    // Resource Coordination
861
553
    EB_DESTROY_THREAD(enc_handle_ptr->resource_coordination_thread_handle);
862
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->picture_analysis_thread_handle_array,
863
553
                            scs->picture_analysis_process_init_count);
864
865
    // Picture Decision
866
553
    EB_DESTROY_THREAD(enc_handle_ptr->picture_decision_thread_handle);
867
868
    // Motion Estimation
869
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->motion_estimation_thread_handle_array,
870
553
                            scs->motion_estimation_process_init_count);
871
872
    // Initial Rate Control
873
553
    EB_DESTROY_THREAD(enc_handle_ptr->initial_rate_control_thread_handle);
874
875
    // Source Based Oprations
876
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->source_based_operations_thread_handle_array,
877
553
                            scs->source_based_operations_process_init_count);
878
879
    // TPL dispenser ME
880
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->tpl_disp_thread_handle_array, scs->tpl_disp_process_init_count);
881
882
    // Picture Manager
883
553
    EB_DESTROY_THREAD(enc_handle_ptr->picture_manager_thread_handle);
884
885
    // Rate Control
886
553
    EB_DESTROY_THREAD(enc_handle_ptr->rate_control_thread_handle);
887
888
    // Mode Decision Configuration Process
889
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->mode_decision_configuration_thread_handle_array,
890
553
                            scs->mode_decision_configuration_process_init_count);
891
892
    // EncDec Process
893
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->enc_dec_thread_handle_array, scs->enc_dec_process_init_count);
894
895
    // Dlf Process
896
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->dlf_thread_handle_array, scs->dlf_process_init_count);
897
898
    // Cdef Process
899
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->cdef_thread_handle_array, scs->cdef_process_init_count);
900
901
    // Rest Process
902
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->rest_thread_handle_array, scs->rest_process_init_count);
903
904
    // Entropy Coding Process
905
553
    EB_DESTROY_THREAD_ARRAY(enc_handle_ptr->entropy_coding_thread_handle_array, scs->entropy_coding_process_init_count);
906
907
    // Packetization
908
553
    EB_DESTROY_THREAD(enc_handle_ptr->packetization_thread_handle);
909
553
}
910
911
/**********************************
912
* Encoder Library Handle Deonstructor
913
**********************************/
914
553
static void svt_enc_handle_dctor(EbPtr p) {
915
553
    EbEncHandle* enc_handle_ptr = (EbEncHandle*)p;
916
553
    svt_enc_handle_stop_threads(enc_handle_ptr);
917
553
    EB_FREE(enc_handle_ptr->app_callback_ptr);
918
553
    EB_DELETE(enc_handle_ptr->scs_pool_ptr);
919
553
    EB_DELETE(enc_handle_ptr->picture_parent_control_set_pool_ptr);
920
553
    EB_DELETE(enc_handle_ptr->me_pool_ptr);
921
553
    EB_DELETE(enc_handle_ptr->picture_control_set_pool_ptr);
922
553
    EB_DELETE(enc_handle_ptr->enc_dec_pool_ptr);
923
553
    EB_DELETE(enc_handle_ptr->pa_reference_picture_pool_ptr);
924
553
    EB_DELETE(enc_handle_ptr->tpl_reference_picture_pool_ptr);
925
553
    EB_DELETE(enc_handle_ptr->overlay_input_picture_pool_ptr);
926
553
    EB_DELETE(enc_handle_ptr->reference_picture_pool_ptr);
927
553
    EB_DELETE(enc_handle_ptr->input_cmd_resource_ptr);
928
553
    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
553
    if (enc_handle_ptr->input_buffer_resource_ptr) {
933
2.76k
        for (uint32_t w_i = 0; w_i < enc_handle_ptr->input_buffer_resource_ptr->object_total_count; ++w_i) {
934
2.21k
            EbObjectWrapper*     wrp  = enc_handle_ptr->input_buffer_resource_ptr->wrapper_ptr_pool[w_i];
935
2.21k
            EbBufferHeaderType*  obj  = (EbBufferHeaderType*)wrp->object_ptr;
936
2.21k
            EbPictureBufferDesc* desc = (EbPictureBufferDesc*)obj->p_buffer;
937
2.21k
            desc->y_buffer            = 0;
938
2.21k
        }
939
553
    }
940
553
    EB_DELETE(enc_handle_ptr->input_buffer_resource_ptr);
941
553
    EB_DELETE(enc_handle_ptr->output_stream_buffer_resource_ptr);
942
553
    EB_DELETE(enc_handle_ptr->output_recon_buffer_resource_ptr);
943
553
    EB_DELETE(enc_handle_ptr->resource_coordination_results_resource_ptr);
944
553
    EB_DELETE(enc_handle_ptr->picture_analysis_results_resource_ptr);
945
553
    EB_DELETE(enc_handle_ptr->picture_decision_results_resource_ptr);
946
553
    EB_DELETE(enc_handle_ptr->motion_estimation_results_resource_ptr);
947
553
    EB_DELETE(enc_handle_ptr->initial_rate_control_results_resource_ptr);
948
553
    EB_DELETE(enc_handle_ptr->picture_demux_results_resource_ptr);
949
553
    EB_DELETE(enc_handle_ptr->tpl_disp_res_srm);
950
553
    EB_DELETE(enc_handle_ptr->rate_control_tasks_resource_ptr);
951
553
    EB_DELETE(enc_handle_ptr->rate_control_results_resource_ptr);
952
553
    EB_DELETE(enc_handle_ptr->enc_dec_tasks_resource_ptr);
953
553
    EB_DELETE(enc_handle_ptr->enc_dec_results_resource_ptr);
954
553
    EB_DELETE(enc_handle_ptr->dlf_results_resource_ptr);
955
553
    EB_DELETE(enc_handle_ptr->cdef_results_resource_ptr);
956
553
    EB_DELETE(enc_handle_ptr->rest_results_resource_ptr);
957
553
    EB_DELETE(enc_handle_ptr->entropy_coding_results_resource_ptr);
958
959
553
    EB_DELETE(enc_handle_ptr->resource_coordination_context_ptr);
960
553
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
961
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->picture_analysis_context_ptr_array, scs->picture_analysis_process_init_count);
962
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->motion_estimation_context_ptr_array, scs->motion_estimation_process_init_count);
963
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->tpl_disp_context_ptr_array, scs->tpl_disp_process_init_count);
964
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->source_based_operations_context_ptr_array,
965
553
                        scs->source_based_operations_process_init_count);
966
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->mode_decision_configuration_context_ptr_array,
967
553
                        scs->mode_decision_configuration_process_init_count);
968
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->enc_dec_context_ptr_array, scs->enc_dec_process_init_count);
969
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->dlf_context_ptr_array, scs->dlf_process_init_count);
970
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->cdef_context_ptr_array, scs->cdef_process_init_count);
971
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->rest_context_ptr_array, scs->rest_process_init_count);
972
553
    EB_DELETE_PTR_ARRAY(enc_handle_ptr->entropy_coding_context_ptr_array, scs->entropy_coding_process_init_count);
973
553
    EB_DELETE(enc_handle_ptr->scs_instance);
974
553
    EB_DELETE(enc_handle_ptr->picture_decision_context_ptr);
975
553
    EB_DELETE(enc_handle_ptr->initial_rate_control_context_ptr);
976
553
    EB_DELETE(enc_handle_ptr->picture_manager_context_ptr);
977
553
    EB_DELETE(enc_handle_ptr->rate_control_context_ptr);
978
553
    EB_DELETE(enc_handle_ptr->packetization_context_ptr);
979
553
}
980
981
/**********************************
982
* Encoder Library Handle Constructor
983
**********************************/
984
553
static EbErrorType svt_enc_handle_ctor(EbEncHandle* enc_handle_ptr, EbComponentType* ebHandlePtr) {
985
553
    enc_handle_ptr->dctor = svt_enc_handle_dctor;
986
987
    // Initialize Callbacks
988
553
    EB_MALLOC_OBJECT(enc_handle_ptr->app_callback_ptr);
989
553
    enc_handle_ptr->app_callback_ptr->error_handler = lib_svt_encoder_send_error_exit;
990
553
    enc_handle_ptr->app_callback_ptr->handle        = ebHandlePtr;
991
992
    // Config Set Count
993
553
    enc_handle_ptr->scs_pool_total_count = EB_SequenceControlSetPoolInitCount;
994
    // Initialize Sequence Control Set Instance
995
553
    EB_NEW(enc_handle_ptr->scs_instance, svt_sequence_control_set_instance_ctor);
996
997
553
    enc_handle_ptr->eos_received   = false;
998
553
    enc_handle_ptr->eos_sent       = false;
999
553
    enc_handle_ptr->frame_received = false;
1000
553
    enc_handle_ptr->is_prev_valid  = true;
1001
553
    return EB_ErrorNone;
1002
553
}
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
2.21k
static EbErrorType in_cmd_ctor(InputCommand* context_ptr, EbPtr object_init_data_ptr) {
1020
2.21k
    (void)context_ptr;
1021
2.21k
    (void)object_init_data_ptr;
1022
1023
2.21k
    return EB_ErrorNone;
1024
2.21k
}
1025
1026
/*
1027
* Input Command Constructor
1028
*/
1029
2.21k
EbErrorType svt_input_cmd_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1030
2.21k
    InputCommand* obj;
1031
1032
2.21k
    *object_dbl_ptr = NULL;
1033
2.21k
    EB_NEW(obj, in_cmd_ctor, object_init_data_ptr);
1034
2.21k
    *object_dbl_ptr = obj;
1035
1036
2.21k
    return EB_ErrorNone;
1037
2.21k
}
1038
1039
553
static EbErrorType dlf_results_ctor(DlfResults* context_ptr, EbPtr object_init_data_ptr) {
1040
553
    (void)context_ptr;
1041
553
    (void)object_init_data_ptr;
1042
1043
553
    return EB_ErrorNone;
1044
553
}
1045
1046
553
static EbErrorType dlf_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1047
553
    DlfResults* obj;
1048
1049
553
    *object_dbl_ptr = NULL;
1050
553
    EB_NEW(obj, dlf_results_ctor, object_init_data_ptr);
1051
553
    *object_dbl_ptr = obj;
1052
1053
553
    return EB_ErrorNone;
1054
553
}
1055
1056
/*
1057
   TPL results ctor
1058
*/
1059
23.7k
EbErrorType tpl_disp_results_ctor(TplDispResults* context_ptr, EbPtr object_init_data_ptr) {
1060
23.7k
    (void)context_ptr;
1061
23.7k
    (void)object_init_data_ptr;
1062
1063
23.7k
    return EB_ErrorNone;
1064
23.7k
}
1065
1066
/*
1067
   TPL results creator
1068
*/
1069
23.7k
static EbErrorType tpl_disp_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1070
23.7k
    TplDispResults* obj;
1071
1072
23.7k
    *object_dbl_ptr = NULL;
1073
23.7k
    EB_NEW(obj, tpl_disp_results_ctor, object_init_data_ptr);
1074
23.7k
    *object_dbl_ptr = obj;
1075
1076
23.7k
    return EB_ErrorNone;
1077
23.7k
}
1078
1079
553
static EbErrorType cdef_results_ctor(CdefResults* context_ptr, EbPtr object_init_data_ptr) {
1080
553
    (void)context_ptr;
1081
553
    (void)object_init_data_ptr;
1082
1083
553
    return EB_ErrorNone;
1084
553
}
1085
1086
553
static EbErrorType cdef_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1087
553
    CdefResults* obj;
1088
1089
553
    *object_dbl_ptr = NULL;
1090
553
    EB_NEW(obj, cdef_results_ctor, object_init_data_ptr);
1091
553
    *object_dbl_ptr = obj;
1092
1093
553
    return EB_ErrorNone;
1094
553
}
1095
1096
8.84k
EbErrorType rest_results_ctor(RestResults* context_ptr, EbPtr object_init_data_ptr) {
1097
8.84k
    (void)context_ptr;
1098
8.84k
    (void)object_init_data_ptr;
1099
1100
8.84k
    return EB_ErrorNone;
1101
8.84k
}
1102
1103
8.84k
static EbErrorType rest_results_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
1104
8.84k
    RestResults* obj;
1105
1106
8.84k
    *object_dbl_ptr = NULL;
1107
8.84k
    EB_NEW(obj, rest_results_ctor, object_init_data_ptr);
1108
8.84k
    *object_dbl_ptr = obj;
1109
1110
8.84k
    return EB_ErrorNone;
1111
8.84k
}
1112
1113
553
static int create_pa_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1114
553
    SequenceControlSet*             scs = enc_handle_ptr->scs_instance->scs;
1115
553
    EbPaReferenceObjectDescInitData eb_pa_ref_obj_ect_desc_init_data_structure;
1116
553
    EbPictureBufferDescInitData     ref_pic_buf_desc_init_data;
1117
553
    EbPictureBufferDescInitData     quart_pic_buf_desc_init_data;
1118
553
    EbPictureBufferDescInitData     sixteenth_pic_buf_desc_init_data;
1119
553
    const bool                      allintra = scs->allintra;
1120
    // PA Reference Picture Buffers
1121
    // Currently, only Luma samples are needed in the PA
1122
553
    ref_pic_buf_desc_init_data.max_width    = scs->max_input_luma_width;
1123
553
    ref_pic_buf_desc_init_data.max_height   = scs->max_input_luma_height;
1124
553
    ref_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
1125
553
    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
553
    ref_pic_buf_desc_init_data.buffer_enable_mask = 0;
1129
1130
553
    ref_pic_buf_desc_init_data.border              = scs->border;
1131
553
    ref_pic_buf_desc_init_data.split_mode          = false;
1132
553
    ref_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1133
553
    ref_pic_buf_desc_init_data.mfmv                = 0;
1134
553
    ref_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1135
553
    ref_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1136
1137
553
    quart_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width >> 1;
1138
553
    quart_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height >> 1;
1139
553
    quart_pic_buf_desc_init_data.bit_depth           = EB_EIGHT_BIT;
1140
553
    quart_pic_buf_desc_init_data.color_format        = EB_YUV420;
1141
553
    quart_pic_buf_desc_init_data.buffer_enable_mask  = allintra ? 0 : PICTURE_BUFFER_DESC_LUMA_MASK;
1142
553
    quart_pic_buf_desc_init_data.border              = scs->b64_size >> 1;
1143
553
    quart_pic_buf_desc_init_data.split_mode          = false;
1144
553
    quart_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1145
553
    quart_pic_buf_desc_init_data.mfmv                = 0;
1146
553
    quart_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1147
553
    quart_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1148
1149
553
    sixteenth_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width >> 2;
1150
553
    sixteenth_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height >> 2;
1151
553
    sixteenth_pic_buf_desc_init_data.bit_depth           = EB_EIGHT_BIT;
1152
553
    sixteenth_pic_buf_desc_init_data.color_format        = EB_YUV420;
1153
553
    sixteenth_pic_buf_desc_init_data.buffer_enable_mask  = allintra ? 0 : PICTURE_BUFFER_DESC_LUMA_MASK;
1154
553
    sixteenth_pic_buf_desc_init_data.border              = scs->b64_size >> 2;
1155
553
    sixteenth_pic_buf_desc_init_data.split_mode          = false;
1156
553
    sixteenth_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1157
553
    sixteenth_pic_buf_desc_init_data.mfmv                = 0;
1158
553
    sixteenth_pic_buf_desc_init_data.is_16bit_pipeline   = false;
1159
553
    sixteenth_pic_buf_desc_init_data.sb_total_count      = scs->sb_total_count;
1160
1161
553
    eb_pa_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1162
553
    eb_pa_ref_obj_ect_desc_init_data_structure.quarter_picture_desc_init_data   = quart_pic_buf_desc_init_data;
1163
553
    eb_pa_ref_obj_ect_desc_init_data_structure.sixteenth_picture_desc_init_data = sixteenth_pic_buf_desc_init_data;
1164
553
    eb_pa_ref_obj_ect_desc_init_data_structure.static_config                    = &scs->static_config;
1165
    // Reference Picture Buffers
1166
553
    EB_NEW(enc_handle_ptr->pa_reference_picture_pool_ptr,
1167
553
           svt_system_resource_ctor,
1168
553
           scs->pa_reference_picture_buffer_init_count,
1169
553
           EB_PictureDecisionProcessInitCount,
1170
553
           0,
1171
553
           svt_pa_reference_object_creator,
1172
553
           &(eb_pa_ref_obj_ect_desc_init_data_structure),
1173
553
           NULL,
1174
553
           (scs->lp == 1));
1175
    // Set the SequenceControlSet Picture Pool Fifo Ptrs
1176
553
    enc_handle_ptr->scs_instance->enc_ctx->pa_reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1177
553
        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
553
    return 0;
1182
553
}
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
553
static int create_ref_buf_descs(EbEncHandle* enc_handle_ptr) {
1228
553
    EbReferenceObjectDescInitData eb_ref_obj_ect_desc_init_data_structure;
1229
553
    EbPictureBufferDescInitData   ref_pic_buf_desc_init_data;
1230
553
    SequenceControlSet*           scs = enc_handle_ptr->scs_instance->scs;
1231
553
    bool is_16bit                     = SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) > EB_EIGHT_BIT;
1232
    // Initialize the various Picture types
1233
553
    ref_pic_buf_desc_init_data.max_width           = scs->max_input_luma_width;
1234
553
    ref_pic_buf_desc_init_data.max_height          = scs->max_input_luma_height;
1235
553
    ref_pic_buf_desc_init_data.bit_depth           = scs->encoder_bit_depth;
1236
553
    ref_pic_buf_desc_init_data.color_format        = scs->static_config.encoder_color_format;
1237
553
    ref_pic_buf_desc_init_data.buffer_enable_mask  = PICTURE_BUFFER_DESC_FULL_MASK;
1238
553
    ref_pic_buf_desc_init_data.rest_units_per_tile = scs->rest_units_per_tile;
1239
553
    ref_pic_buf_desc_init_data.sb_total_count      = scs->b64_total_count;
1240
553
    uint16_t padding                               = scs->super_block_size + 32;
1241
553
    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
553
    ref_pic_buf_desc_init_data.border            = padding;
1246
553
    ref_pic_buf_desc_init_data.mfmv              = scs->mfmv_enabled;
1247
553
    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
553
    ref_pic_buf_desc_init_data.split_mode = false;
1251
553
    if (is_16bit) {
1252
0
        ref_pic_buf_desc_init_data.bit_depth = EB_TEN_BIT;
1253
0
    }
1254
1255
553
    eb_ref_obj_ect_desc_init_data_structure.reference_picture_desc_init_data = ref_pic_buf_desc_init_data;
1256
553
    eb_ref_obj_ect_desc_init_data_structure.hbd_md                           = scs->enable_hbd_mode_decision;
1257
553
    eb_ref_obj_ect_desc_init_data_structure.static_config                    = &scs->static_config;
1258
    // Reference Picture Buffers
1259
553
    EB_NEW(enc_handle_ptr->reference_picture_pool_ptr,
1260
553
           svt_system_resource_ctor,
1261
553
           scs->reference_picture_buffer_init_count,
1262
553
           EB_PictureManagerProcessInitCount,
1263
553
           0,
1264
553
           svt_reference_object_creator,
1265
553
           &(eb_ref_obj_ect_desc_init_data_structure),
1266
553
           NULL,
1267
553
           (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
553
    const uint32_t ref_pic_list_length = scs->enable_dec_order ? scs->pa_reference_picture_buffer_init_count
1274
553
                                                               : scs->reference_picture_buffer_init_count;
1275
553
    enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list_length = ref_pic_list_length;
1276
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list, ref_pic_list_length);
1277
1278
1.65k
    for (uint32_t idx = 0; idx < ref_pic_list_length; ++idx) {
1279
1.10k
        EB_NEW(enc_handle_ptr->scs_instance->enc_ctx->ref_pic_list[idx], svt_aom_reference_queue_entry_ctor);
1280
1.10k
    }
1281
553
#if CONFIG_SINGLE_THREAD_KERNEL
1282
553
    if (scs->lp > 1)
1283
553
#endif
1284
553
    {
1285
553
        EB_CREATE_SEMAPHORE(scs->ref_buffer_available_semaphore, ref_pic_list_length, ref_pic_list_length);
1286
553
    }
1287
553
    enc_handle_ptr->scs_instance->enc_ctx->reference_picture_pool_fifo_ptr = svt_system_resource_get_producer_fifo(
1288
553
        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
553
    return 0;
1295
553
}
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
553
EB_API EbErrorType svt_av1_enc_init(EbComponentType* svt_enc_component) {
1330
553
    if (svt_enc_component == NULL) {
1331
0
        return EB_ErrorBadParameter;
1332
0
    }
1333
553
    EbEncHandle*        enc_handle_ptr = (EbEncHandle*)svt_enc_component->p_component_private;
1334
553
    EbErrorType         return_error   = EB_ErrorNone;
1335
553
    SequenceControlSet* scs            = enc_handle_ptr->scs_instance->scs;
1336
553
    EbColorFormat       color_format   = scs->static_config.encoder_color_format;
1337
553
    const bool          single_thread  = (scs->lp == 1);
1338
1339
553
    svt_aom_setup_common_rtcd_internal(scs->static_config.use_cpu_flags);
1340
553
    svt_aom_setup_rtcd_internal(scs->static_config.use_cpu_flags);
1341
553
    svt_run_once(&global_tables_once, init_global_tables);
1342
1343
    // Per-instance block geometry table allocation
1344
553
    EB_MALLOC_ARRAY(scs->blk_geom_mds, scs->max_block_cnt);
1345
553
    svt_aom_build_blk_geom(scs->svt_aom_geom_idx, scs->blk_geom_mds);
1346
    /************************************
1347
     * Sequence Control Set
1348
     ************************************/
1349
553
    EB_NEW(enc_handle_ptr->scs_pool_ptr,
1350
553
           svt_system_resource_ctor,
1351
553
           enc_handle_ptr->scs_pool_total_count,
1352
553
           1,
1353
553
           0,
1354
553
           svt_aom_scs_set_creator,
1355
553
           NULL,
1356
553
           NULL,
1357
553
           single_thread);
1358
    /************************************
1359
    * Picture Control Set: Parent
1360
    ************************************/
1361
553
    {
1362
        // The segment Width & Height Arrays are in units of SBs, not samples
1363
553
        PictureControlSetInitData input_data;
1364
553
        input_data.picture_width        = scs->max_input_luma_width;
1365
553
        input_data.picture_height       = scs->max_input_luma_height;
1366
553
        input_data.border               = scs->border;
1367
553
        input_data.color_format         = color_format;
1368
553
        input_data.b64_size             = scs->b64_size;
1369
553
        input_data.enc_mode             = scs->static_config.enc_mode;
1370
553
        input_data.hbd_md               = scs->enable_hbd_mode_decision;
1371
553
        input_data.bit_depth            = scs->static_config.encoder_bit_depth;
1372
553
        input_data.log2_tile_rows       = scs->static_config.tile_rows;
1373
553
        input_data.log2_tile_cols       = scs->static_config.tile_columns;
1374
553
        input_data.log2_sb_size         = (scs->super_block_size == 128) ? 5 : 4;
1375
553
        input_data.is_16bit_pipeline    = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1376
553
        input_data.non_m8_pad_w         = scs->max_input_pad_right;
1377
553
        input_data.non_m8_pad_h         = scs->max_input_pad_bottom;
1378
553
        input_data.enable_tpl_la        = scs->tpl;
1379
553
        input_data.enc_dec_segment_col  = (uint16_t)scs->tpl_segment_col_count_array;
1380
553
        input_data.enc_dec_segment_row  = (uint16_t)scs->tpl_segment_row_count_array;
1381
553
        MrpCtrls* mrp_ctrl              = &(scs->mrp_ctrls);
1382
553
        input_data.ref_count_used_list0 = MAX(mrp_ctrl->base_ref_list0_count, mrp_ctrl->non_base_ref_list0_count);
1383
553
        input_data.ref_count_used_list1 = MAX(mrp_ctrl->base_ref_list1_count, mrp_ctrl->non_base_ref_list1_count);
1384
553
        input_data.tpl_synth_size       = svt_aom_set_tpl_group(NULL,
1385
553
                                                          svt_aom_get_tpl_group_level(1, scs->static_config.enc_mode),
1386
553
                                                          input_data.picture_width,
1387
553
                                                          input_data.picture_height);
1388
553
        input_data.aq_mode              = scs->static_config.aq_mode;
1389
1390
553
        input_data.calculate_variance = scs->calculate_variance;
1391
553
        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
553
        input_data.tpl_lad_mg       = scs->tpl_lad_mg;
1396
553
        input_data.input_resolution = scs->input_resolution;
1397
553
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1398
553
            scs->static_config.resize_mode > RESIZE_NONE;
1399
553
        input_data.rtc_tune            = scs->static_config.rtc;
1400
553
        input_data.variance_octile     = scs->static_config.variance_octile;
1401
553
        input_data.adaptive_film_grain = scs->static_config.adaptive_film_grain;
1402
553
        input_data.hbd_mds             = scs->static_config.hbd_mds;
1403
553
        input_data.static_config       = scs->static_config;
1404
553
        input_data.allintra            = scs->allintra;
1405
553
        input_data.use_flat_ipp        = scs->static_config.rtc && scs->static_config.hierarchical_levels == 0;
1406
553
        EB_NEW(enc_handle_ptr->picture_parent_control_set_pool_ptr,
1407
553
               svt_system_resource_ctor,
1408
553
               scs->picture_control_set_pool_init_count, //enc_handle_ptr->pcs_pool_total_count,
1409
553
               1,
1410
553
               0,
1411
553
               svt_aom_picture_parent_control_set_creator,
1412
553
               &input_data,
1413
553
               NULL,
1414
553
               single_thread);
1415
#if SRM_REPORT
1416
        enc_handle_ptr->picture_parent_control_set_pool_ptr->empty_queue->log = 0;
1417
#endif
1418
553
        EB_NEW(enc_handle_ptr->me_pool_ptr,
1419
553
               svt_system_resource_ctor,
1420
553
               scs->me_pool_init_count,
1421
553
               1,
1422
553
               0,
1423
553
               svt_aom_me_creator,
1424
553
               &input_data,
1425
553
               NULL,
1426
553
               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
553
    }
1432
1433
    /************************************
1434
    * Enc Dec
1435
    ************************************/
1436
553
    {
1437
        // The segment Width & Height Arrays are in units of SBs, not samples
1438
553
        PictureControlSetInitData input_data;
1439
553
        input_data.enc_dec_segment_col = (uint16_t)scs->enc_dec_segment_col_count_array;
1440
553
        input_data.enc_dec_segment_row = (uint16_t)scs->enc_dec_segment_row_count_array;
1441
1442
553
        input_data.picture_width  = scs->max_input_luma_width;
1443
553
        input_data.picture_height = scs->max_input_luma_height;
1444
553
        input_data.border         = scs->border;
1445
553
        input_data.bit_depth      = scs->encoder_bit_depth;
1446
553
        input_data.color_format   = color_format;
1447
553
        input_data.b64_size       = scs->b64_size;
1448
553
        input_data.sb_size        = scs->super_block_size;
1449
553
        input_data.hbd_md         = scs->enable_hbd_mode_decision;
1450
553
        input_data.mfmv           = scs->mfmv_enabled;
1451
        //Jing: Get tile info from parent_pcs
1452
553
        PictureParentControlSet* parent_pcs =
1453
553
            (PictureParentControlSet*)enc_handle_ptr->picture_parent_control_set_pool_ptr->wrapper_ptr_pool[0]
1454
553
                ->object_ptr;
1455
553
        input_data.tile_row_count    = parent_pcs->av1_cm->tiles_info.tile_rows;
1456
553
        input_data.tile_column_count = parent_pcs->av1_cm->tiles_info.tile_cols;
1457
553
        input_data.is_16bit_pipeline = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1458
553
        input_data.av1_cm            = parent_pcs->av1_cm;
1459
553
        input_data.enc_mode          = scs->static_config.enc_mode;
1460
1461
553
        input_data.input_resolution = scs->input_resolution;
1462
553
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1463
553
            scs->static_config.resize_mode > RESIZE_NONE;
1464
1465
553
        input_data.rtc_tune     = scs->static_config.rtc;
1466
553
        input_data.allintra     = scs->allintra;
1467
553
        input_data.use_flat_ipp = scs->static_config.rtc && scs->static_config.hierarchical_levels == 0;
1468
553
        EB_NEW(enc_handle_ptr->enc_dec_pool_ptr,
1469
553
               svt_system_resource_ctor,
1470
553
               scs->enc_dec_pool_init_count, //EB_PictureControlSetPoolInitCountChild,
1471
553
               1,
1472
553
               0,
1473
553
               svt_aom_recon_coef_creator,
1474
553
               &input_data,
1475
553
               NULL,
1476
553
               single_thread);
1477
553
    }
1478
1479
    /************************************
1480
        * Picture Control Set: Child
1481
        ************************************/
1482
553
    {
1483
        // The segment Width & Height Arrays are in units of SBs, not samples
1484
553
        PictureControlSetInitData input_data;
1485
553
        input_data.enc_dec_segment_col = (uint16_t)scs->enc_dec_segment_col_count_array;
1486
553
        input_data.enc_dec_segment_row = (uint16_t)scs->enc_dec_segment_row_count_array;
1487
553
        input_data.picture_width       = scs->max_input_luma_width;
1488
553
        input_data.picture_height      = scs->max_input_luma_height;
1489
553
        input_data.border              = scs->border;
1490
553
        input_data.bit_depth           = scs->encoder_bit_depth;
1491
553
        input_data.color_format        = color_format;
1492
553
        input_data.b64_size            = scs->b64_size;
1493
553
        input_data.sb_size             = scs->super_block_size;
1494
553
        input_data.hbd_md              = scs->enable_hbd_mode_decision;
1495
553
        input_data.mfmv                = scs->mfmv_enabled;
1496
        //Jing: Get tile info from parent_pcs
1497
553
        PictureParentControlSet* parent_pcs =
1498
553
            (PictureParentControlSet*)enc_handle_ptr->picture_parent_control_set_pool_ptr->wrapper_ptr_pool[0]
1499
553
                ->object_ptr;
1500
553
        input_data.tile_row_count    = parent_pcs->av1_cm->tiles_info.tile_rows;
1501
553
        input_data.tile_column_count = parent_pcs->av1_cm->tiles_info.tile_cols;
1502
553
        input_data.is_16bit_pipeline = SVT_EFFECTIVE_IS_16BIT_PIPELINE(scs->is_16bit_pipeline);
1503
553
        input_data.av1_cm            = parent_pcs->av1_cm;
1504
553
        input_data.enc_mode          = scs->static_config.enc_mode;
1505
553
        input_data.static_config     = scs->static_config;
1506
1507
553
        input_data.input_resolution = scs->input_resolution;
1508
553
        input_data.is_scale         = scs->static_config.superres_mode > SUPERRES_NONE ||
1509
553
            scs->static_config.resize_mode > RESIZE_NONE;
1510
1511
553
        input_data.rtc_tune     = scs->static_config.rtc;
1512
553
        input_data.allintra     = scs->allintra;
1513
553
        input_data.use_flat_ipp = scs->static_config.rtc && scs->static_config.hierarchical_levels == 0;
1514
553
        EB_NEW(enc_handle_ptr->picture_control_set_pool_ptr,
1515
553
               svt_system_resource_ctor,
1516
553
               scs->picture_control_set_pool_init_count_child, //EB_PictureControlSetPoolInitCountChild,
1517
553
               1,
1518
553
               0,
1519
553
               svt_aom_picture_control_set_creator,
1520
553
               &input_data,
1521
553
               NULL,
1522
553
               single_thread);
1523
553
    }
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
553
    const PicMgrPorts pic_mgr_ports[] = {
1534
553
        {PIC_MGR_INPUT_PORT_SOP,           scs->source_based_operations_process_init_count},
1535
553
        {PIC_MGR_INPUT_PORT_PACKETIZATION, EB_PacketizationProcessInitCount},
1536
553
        {PIC_MGR_INPUT_PORT_REST,          scs->rest_process_init_count},
1537
553
        {PIC_MGR_INPUT_PORT_INVALID,       0}
1538
553
    };
1539
553
    const RateControlPorts rate_control_ports[] = {
1540
553
        {RATE_CONTROL_INPUT_PORT_INLME,         EB_PictureManagerProcessInitCount},
1541
553
        {RATE_CONTROL_INPUT_PORT_PACKETIZATION, EB_PacketizationProcessInitCount},
1542
553
        {RATE_CONTROL_INPUT_PORT_INVALID,       0}
1543
553
    };
1544
553
    const EncDecPorts_t enc_dec_ports[] = {
1545
553
        {ENCDEC_INPUT_PORT_MDC,     scs->mode_decision_configuration_process_init_count},
1546
553
        {ENCDEC_INPUT_PORT_ENCDEC,  scs->enc_dec_process_init_count},
1547
553
        {ENCDEC_INPUT_PORT_INVALID, 0}
1548
553
    };
1549
553
    const EncDecPorts_t tpl_ports[] = {
1550
553
        {TPL_INPUT_PORT_SOP,     scs->source_based_operations_process_init_count},
1551
553
        {TPL_INPUT_PORT_TPL,     scs->tpl_disp_process_init_count},
1552
553
        {TPL_INPUT_PORT_INVALID, 0}
1553
553
    };
1554
    // clang-format on
1555
553
    {
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
553
        PictureControlSet* pcs =
1559
553
            (PictureControlSet*)enc_handle_ptr->picture_control_set_pool_ptr->wrapper_ptr_pool[0]->object_ptr;
1560
553
        scs->rest_units_per_tile = pcs->rst_info[0 /*Y-plane*/].units_per_tile;
1561
553
        scs->b64_total_count     = pcs->b64_total_count;
1562
553
        create_ref_buf_descs(enc_handle_ptr);
1563
553
        if (scs->tpl) {
1564
0
            create_tpl_ref_buf_descs(enc_handle_ptr);
1565
0
        }
1566
1567
553
        create_pa_ref_buf_descs(enc_handle_ptr);
1568
1569
553
        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
553
    }
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
553
    EB_NEW(enc_handle_ptr->input_cmd_resource_ptr,
1590
553
           svt_system_resource_ctor,
1591
553
           scs->resource_coordination_fifo_init_count,
1592
553
           1,
1593
553
           EB_ResourceCoordinationProcessInitCount,
1594
553
           svt_input_cmd_creator,
1595
553
           scs,
1596
553
           NULL,
1597
553
           single_thread);
1598
553
    enc_handle_ptr->input_cmd_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1599
553
        enc_handle_ptr->input_cmd_resource_ptr, 0);
1600
1601
    //Picture Buffer SRM to hold (uv8b + yuv2b)
1602
553
    EB_NEW(enc_handle_ptr->input_buffer_resource_ptr,
1603
553
           svt_system_resource_ctor,
1604
553
           scs->input_buffer_fifo_init_count,
1605
553
           1,
1606
553
           0, //1/2 SRM; no consumer FIFO
1607
553
           svt_input_buffer_header_creator,
1608
553
           scs,
1609
553
           svt_input_buffer_header_destroyer,
1610
553
           single_thread);
1611
553
    enc_handle_ptr->input_buffer_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1612
553
        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
553
    EB_NEW(enc_handle_ptr->input_y8b_buffer_resource_ptr,
1616
553
           svt_system_resource_ctor,
1617
553
           MAX(scs->input_buffer_fifo_init_count, scs->pa_reference_picture_buffer_init_count),
1618
553
           1,
1619
553
           0, //1/2 SRM; no consumer FIFO
1620
553
           svt_input_y8b_creator,
1621
553
           scs,
1622
553
           svt_input_y8b_destroyer,
1623
553
           single_thread);
1624
1625
#if SRM_REPORT
1626
    enc_handle_ptr->input_y8b_buffer_resource_ptr->empty_queue->log = 1;
1627
#endif
1628
553
    enc_handle_ptr->input_y8b_buffer_producer_fifo_ptr = svt_system_resource_get_producer_fifo(
1629
553
        enc_handle_ptr->input_y8b_buffer_resource_ptr, 0);
1630
1631
    // EbBufferHeaderType Output Stream
1632
553
    {
1633
553
        EB_NEW(enc_handle_ptr->output_stream_buffer_resource_ptr,
1634
553
               svt_system_resource_ctor,
1635
553
               scs->output_stream_buffer_fifo_init_count,
1636
553
               scs->total_process_init_count, //EB_PacketizationProcessInitCount,
1637
553
               1,
1638
553
               svt_output_buffer_header_creator,
1639
553
               &scs->static_config,
1640
553
               svt_output_buffer_header_destroyer,
1641
553
               single_thread);
1642
553
    }
1643
553
    enc_handle_ptr->output_stream_buffer_consumer_fifo_ptr = svt_system_resource_get_consumer_fifo(
1644
553
        enc_handle_ptr->output_stream_buffer_resource_ptr, 0);
1645
553
    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
553
    {
1664
553
        ResourceCoordinationResultInitData resource_coordination_result_init_data;
1665
553
        EB_NEW(enc_handle_ptr->resource_coordination_results_resource_ptr,
1666
553
               svt_system_resource_ctor,
1667
553
               scs->resource_coordination_fifo_init_count,
1668
553
               EB_ResourceCoordinationProcessInitCount,
1669
553
               scs->picture_analysis_process_init_count,
1670
553
               svt_aom_resource_coordination_result_creator,
1671
553
               &resource_coordination_result_init_data,
1672
553
               NULL,
1673
553
               single_thread);
1674
553
    }
1675
1676
    // Picture Analysis Results
1677
553
    {
1678
553
        PictureAnalysisResultInitData picture_analysis_result_init_data;
1679
553
        EB_NEW(enc_handle_ptr->picture_analysis_results_resource_ptr,
1680
553
               svt_system_resource_ctor,
1681
553
               scs->picture_analysis_fifo_init_count,
1682
553
               scs->picture_analysis_process_init_count,
1683
553
               EB_PictureDecisionProcessInitCount,
1684
553
               svt_aom_picture_analysis_result_creator,
1685
553
               &picture_analysis_result_init_data,
1686
553
               NULL,
1687
553
               single_thread);
1688
553
    }
1689
1690
    // Picture Decision Results
1691
553
    {
1692
553
        PictureDecisionResultInitData picture_decision_result_init_data;
1693
553
        EB_NEW(enc_handle_ptr->picture_decision_results_resource_ptr,
1694
553
               svt_system_resource_ctor,
1695
553
               scs->picture_decision_fifo_init_count,
1696
553
               EB_PictureDecisionProcessInitCount +
1697
553
                   2, // 1 for rate control, another 1 for packetization when superres recoding is on
1698
553
               scs->motion_estimation_process_init_count,
1699
553
               svt_aom_picture_decision_result_creator,
1700
553
               &picture_decision_result_init_data,
1701
553
               NULL,
1702
553
               single_thread);
1703
553
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->picture_decision_reorder_queue,
1704
553
                           scs->enc_ctx->picture_decision_reorder_queue_size);
1705
1706
3.31k
        for (uint32_t picture_index = 0; picture_index < scs->enc_ctx->picture_decision_reorder_queue_size;
1707
2.76k
             ++picture_index) {
1708
2.76k
            EB_NEW(scs->enc_ctx->picture_decision_reorder_queue[picture_index],
1709
2.76k
                   svt_aom_picture_decision_reorder_entry_ctor,
1710
2.76k
                   picture_index);
1711
2.76k
        }
1712
553
    }
1713
1714
    // Motion Estimation Results
1715
553
    {
1716
553
        MotionEstimationResultsInitData motion_estimation_result_init_data;
1717
553
        EB_NEW(enc_handle_ptr->motion_estimation_results_resource_ptr,
1718
553
               svt_system_resource_ctor,
1719
553
               scs->motion_estimation_fifo_init_count,
1720
553
               scs->motion_estimation_process_init_count,
1721
553
               EB_InitialRateControlProcessInitCount,
1722
553
               svt_aom_motion_estimation_results_creator,
1723
553
               &motion_estimation_result_init_data,
1724
553
               NULL,
1725
553
               single_thread);
1726
553
    }
1727
1728
    // Initial Rate Control Results
1729
553
    {
1730
553
        InitialRateControlResultInitData initial_rate_control_result_init_data;
1731
553
        EB_NEW(enc_handle_ptr->initial_rate_control_results_resource_ptr,
1732
553
               svt_system_resource_ctor,
1733
553
               scs->initial_rate_control_fifo_init_count,
1734
553
               EB_InitialRateControlProcessInitCount,
1735
553
               scs->source_based_operations_process_init_count,
1736
553
               svt_aom_initial_rate_control_results_creator,
1737
553
               &initial_rate_control_result_init_data,
1738
553
               NULL,
1739
553
               single_thread);
1740
553
    }
1741
1742
    // Picture Demux Results
1743
553
    {
1744
553
        PictureResultInitData picture_result_init_data;
1745
553
        EB_NEW(enc_handle_ptr->picture_demux_results_resource_ptr,
1746
553
               svt_system_resource_ctor,
1747
553
               scs->picture_demux_fifo_init_count,
1748
553
               pic_mgr_port_total_count(pic_mgr_ports),
1749
553
               EB_PictureManagerProcessInitCount,
1750
553
               svt_aom_picture_results_creator,
1751
553
               &picture_result_init_data,
1752
553
               NULL,
1753
553
               single_thread);
1754
1755
553
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->pic_mgr_input_pic_list, scs->enc_ctx->pic_mgr_input_pic_list_size);
1756
1757
2.76k
        for (uint32_t picture_index = 0; picture_index < scs->enc_ctx->pic_mgr_input_pic_list_size; ++picture_index) {
1758
2.21k
            EB_NEW(scs->enc_ctx->pic_mgr_input_pic_list[picture_index], svt_aom_input_queue_entry_ctor);
1759
2.21k
        }
1760
553
    }
1761
1762
    // TPL dispenser Results
1763
553
    {
1764
553
        EntropyCodingResultsInitData tpl_disp_result_init_data;
1765
        //TPL Dispenser tasks
1766
553
        EB_NEW(enc_handle_ptr->tpl_disp_res_srm,
1767
553
               svt_system_resource_ctor,
1768
553
               scs->tpl_disp_fifo_init_count,
1769
553
               tpl_port_total_count(tpl_ports),
1770
553
               scs->tpl_disp_process_init_count,
1771
553
               tpl_disp_results_creator,
1772
553
               &tpl_disp_result_init_data,
1773
553
               NULL,
1774
553
               single_thread);
1775
553
    }
1776
1777
    // Rate Control Tasks
1778
553
    {
1779
553
        RateControlTasksInitData rate_control_tasks_init_data;
1780
553
        EB_NEW(enc_handle_ptr->rate_control_tasks_resource_ptr,
1781
553
               svt_system_resource_ctor,
1782
553
               scs->rate_control_tasks_fifo_init_count,
1783
553
               rate_control_port_total_count(rate_control_ports),
1784
553
               EB_RateControlProcessInitCount,
1785
553
               svt_aom_rate_control_tasks_creator,
1786
553
               &rate_control_tasks_init_data,
1787
553
               NULL,
1788
553
               single_thread);
1789
553
    }
1790
1791
    // Rate Control Results
1792
553
    {
1793
553
        RateControlResultsInitData rate_control_result_init_data;
1794
553
        EB_NEW(enc_handle_ptr->rate_control_results_resource_ptr,
1795
553
               svt_system_resource_ctor,
1796
553
               scs->rate_control_fifo_init_count,
1797
553
               EB_RateControlProcessInitCount,
1798
553
               scs->mode_decision_configuration_process_init_count,
1799
553
               svt_aom_rate_control_results_creator,
1800
553
               &rate_control_result_init_data,
1801
553
               NULL,
1802
553
               single_thread);
1803
553
    }
1804
    // EncDec Tasks
1805
553
    {
1806
553
        EncDecTasksInitData mode_decision_result_init_data;
1807
553
        mode_decision_result_init_data.enc_dec_segment_row_count = scs->enc_dec_segment_row_count_array;
1808
553
        EB_NEW(enc_handle_ptr->enc_dec_tasks_resource_ptr,
1809
553
               svt_system_resource_ctor,
1810
553
               scs->mode_decision_configuration_fifo_init_count,
1811
553
               enc_dec_port_total_count(enc_dec_ports),
1812
553
               scs->enc_dec_process_init_count,
1813
553
               svt_aom_enc_dec_tasks_creator,
1814
553
               &mode_decision_result_init_data,
1815
553
               NULL,
1816
553
               single_thread);
1817
553
    }
1818
1819
    // EncDec Results
1820
553
    {
1821
553
        EncDecResultsInitData enc_dec_result_init_data;
1822
553
        EB_NEW(enc_handle_ptr->enc_dec_results_resource_ptr,
1823
553
               svt_system_resource_ctor,
1824
553
               scs->enc_dec_fifo_init_count,
1825
553
               scs->enc_dec_process_init_count,
1826
553
               scs->dlf_process_init_count,
1827
553
               svt_aom_enc_dec_results_creator,
1828
553
               &enc_dec_result_init_data,
1829
553
               NULL,
1830
553
               single_thread);
1831
553
    }
1832
1833
    //DLF results
1834
553
    {
1835
553
        EntropyCodingResultsInitData delf_result_init_data;
1836
553
        EB_NEW(enc_handle_ptr->dlf_results_resource_ptr,
1837
553
               svt_system_resource_ctor,
1838
553
               scs->dlf_fifo_init_count,
1839
553
               scs->dlf_process_init_count,
1840
553
               scs->cdef_process_init_count,
1841
553
               dlf_results_creator,
1842
553
               &delf_result_init_data,
1843
553
               NULL,
1844
553
               single_thread);
1845
553
    }
1846
    //CDEF results
1847
553
    {
1848
553
        EntropyCodingResultsInitData cdef_result_init_data;
1849
553
        EB_NEW(enc_handle_ptr->cdef_results_resource_ptr,
1850
553
               svt_system_resource_ctor,
1851
553
               scs->cdef_fifo_init_count,
1852
553
               scs->cdef_process_init_count,
1853
553
               scs->rest_process_init_count,
1854
553
               cdef_results_creator,
1855
553
               &cdef_result_init_data,
1856
553
               NULL,
1857
553
               single_thread);
1858
553
    }
1859
    //REST results
1860
553
    {
1861
553
        EntropyCodingResultsInitData rest_result_init_data;
1862
553
        EB_NEW(enc_handle_ptr->rest_results_resource_ptr,
1863
553
               svt_system_resource_ctor,
1864
553
               scs->rest_fifo_init_count,
1865
553
               scs->rest_process_init_count,
1866
553
               scs->entropy_coding_process_init_count,
1867
553
               rest_results_creator,
1868
553
               &rest_result_init_data,
1869
553
               NULL,
1870
553
               single_thread);
1871
553
    }
1872
1873
    // Entropy Coding Results
1874
553
    {
1875
553
        EntropyCodingResultsInitData entropy_coding_results_init_data;
1876
553
        EB_NEW(enc_handle_ptr->entropy_coding_results_resource_ptr,
1877
553
               svt_system_resource_ctor,
1878
553
               scs->entropy_coding_fifo_init_count,
1879
553
               scs->entropy_coding_process_init_count,
1880
553
               EB_PacketizationProcessInitCount,
1881
553
               svt_aom_entropy_coding_results_creator,
1882
553
               &entropy_coding_results_init_data,
1883
553
               NULL,
1884
553
               single_thread);
1885
553
        EB_ALLOC_PTR_ARRAY(scs->enc_ctx->packetization_reorder_queue, scs->enc_ctx->packetization_reorder_queue_size);
1886
1887
2.76k
        for (uint32_t picture_index = 0; picture_index < scs->enc_ctx->packetization_reorder_queue_size;
1888
2.21k
             ++picture_index) {
1889
2.21k
            EB_NEW(scs->enc_ctx->packetization_reorder_queue[picture_index],
1890
2.21k
                   svt_aom_packetization_reorder_entry_ctor,
1891
2.21k
                   picture_index);
1892
2.21k
        }
1893
553
    }
1894
1895
    /************************************
1896
    * App Callbacks
1897
    ************************************/
1898
553
    enc_handle_ptr->scs_instance->enc_ctx->app_callback_ptr = enc_handle_ptr->app_callback_ptr;
1899
    // svt Output Buffer Fifo Ptrs
1900
553
    enc_handle_ptr->scs_instance->enc_ctx->stream_output_fifo_ptr = svt_system_resource_get_producer_fifo(
1901
553
        enc_handle_ptr->output_stream_buffer_resource_ptr, 0);
1902
553
    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
553
    EB_NEW(
1912
553
        enc_handle_ptr->resource_coordination_context_ptr, svt_aom_resource_coordination_context_ctor, enc_handle_ptr);
1913
1914
    // Picture Analysis Context
1915
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->picture_analysis_context_ptr_array, scs->picture_analysis_process_init_count);
1916
2.76k
    for (uint32_t process_index = 0; process_index < scs->picture_analysis_process_init_count; process_index++) {
1917
2.21k
        EB_NEW(enc_handle_ptr->picture_analysis_context_ptr_array[process_index],
1918
2.21k
               svt_aom_picture_analysis_context_ctor,
1919
2.21k
               enc_handle_ptr,
1920
2.21k
               process_index);
1921
2.21k
    }
1922
1923
    // Picture Decision Context
1924
553
    EB_NEW(enc_handle_ptr->picture_decision_context_ptr,
1925
553
           svt_aom_picture_decision_context_ctor,
1926
553
           enc_handle_ptr,
1927
553
           scs->calc_hist);
1928
1929
    // Motion Analysis Context
1930
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->motion_estimation_context_ptr_array, scs->motion_estimation_process_init_count);
1931
3.87k
    for (uint32_t process_index = 0; process_index < scs->motion_estimation_process_init_count; process_index++) {
1932
3.31k
        EB_NEW(enc_handle_ptr->motion_estimation_context_ptr_array[process_index],
1933
3.31k
               svt_aom_motion_estimation_context_ctor,
1934
3.31k
               enc_handle_ptr,
1935
3.31k
               process_index);
1936
3.31k
    }
1937
1938
    // Initial Rate Control Context
1939
553
    EB_NEW(enc_handle_ptr->initial_rate_control_context_ptr,
1940
553
           svt_aom_initial_rate_control_context_ctor,
1941
553
           enc_handle_ptr,
1942
553
           scs->picture_control_set_pool_init_count);
1943
1944
    // Source Based Operations Context
1945
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->source_based_operations_context_ptr_array,
1946
553
                       scs->source_based_operations_process_init_count);
1947
1.10k
    for (uint32_t process_index = 0; process_index < scs->source_based_operations_process_init_count; process_index++) {
1948
553
        EB_NEW(enc_handle_ptr->source_based_operations_context_ptr_array[process_index],
1949
553
               svt_aom_source_based_operations_context_ctor,
1950
553
               enc_handle_ptr,
1951
553
               tpl_port_lookup(tpl_ports, TPL_INPUT_PORT_SOP, process_index),
1952
553
               pic_mgr_port_lookup(pic_mgr_ports, PIC_MGR_INPUT_PORT_SOP, process_index));
1953
553
    }
1954
1955
    // TPL dispenser
1956
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->tpl_disp_context_ptr_array, scs->tpl_disp_process_init_count);
1957
1.10k
    for (uint32_t process_index = 0; process_index < scs->tpl_disp_process_init_count; process_index++) {
1958
553
        EB_NEW(enc_handle_ptr->tpl_disp_context_ptr_array[process_index],
1959
553
               svt_aom_tpl_disp_context_ctor,
1960
553
               enc_handle_ptr,
1961
553
               process_index,
1962
553
               tpl_port_lookup(tpl_ports, TPL_INPUT_PORT_TPL, process_index));
1963
553
    }
1964
1965
    // Picture Manager Context
1966
553
    EB_NEW(enc_handle_ptr->picture_manager_context_ptr,
1967
553
           svt_aom_picture_manager_context_ctor,
1968
553
           enc_handle_ptr,
1969
553
           rate_control_port_lookup(rate_control_ports, RATE_CONTROL_INPUT_PORT_INLME, 0), //Pic-Mgr uses the first Port
1970
553
           scs->picture_control_set_pool_init_count);
1971
1972
    // Rate Control Context
1973
553
    EB_NEW(enc_handle_ptr->rate_control_context_ptr,
1974
553
           svt_aom_rate_control_context_ctor,
1975
553
           enc_handle_ptr,
1976
553
           EB_PictureDecisionProcessInitCount); // me_port_index
1977
1978
    // Mode Decision Configuration Contexts
1979
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->mode_decision_configuration_context_ptr_array,
1980
553
                       scs->mode_decision_configuration_process_init_count);
1981
1.10k
    for (uint32_t process_index = 0; process_index < scs->mode_decision_configuration_process_init_count;
1982
553
         process_index++) {
1983
553
        EB_NEW(enc_handle_ptr->mode_decision_configuration_context_ptr_array[process_index],
1984
553
               svt_aom_mode_decision_configuration_context_ctor,
1985
553
               enc_handle_ptr,
1986
553
               process_index,
1987
553
               enc_dec_port_lookup(enc_dec_ports, ENCDEC_INPUT_PORT_MDC, process_index));
1988
553
    }
1989
1990
    // EncDec Contexts
1991
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->enc_dec_context_ptr_array, scs->enc_dec_process_init_count);
1992
2.30k
    for (uint32_t process_index = 0; process_index < scs->enc_dec_process_init_count; process_index++) {
1993
1.74k
        EB_NEW(enc_handle_ptr->enc_dec_context_ptr_array[process_index],
1994
1.74k
               svt_aom_enc_dec_context_ctor,
1995
1.74k
               enc_handle_ptr,
1996
1.74k
               process_index,
1997
1.74k
               enc_dec_port_lookup(enc_dec_ports, ENCDEC_INPUT_PORT_ENCDEC, process_index));
1998
1.74k
    }
1999
2000
    // Dlf Contexts
2001
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->dlf_context_ptr_array, scs->dlf_process_init_count);
2002
1.10k
    for (uint32_t process_index = 0; process_index < scs->dlf_process_init_count; process_index++) {
2003
553
        EB_NEW(enc_handle_ptr->dlf_context_ptr_array[process_index],
2004
553
               svt_aom_dlf_context_ctor,
2005
553
               enc_handle_ptr,
2006
553
               process_index);
2007
553
    }
2008
2009
    //CDEF Contexts
2010
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->cdef_context_ptr_array, scs->cdef_process_init_count);
2011
1.10k
    for (uint32_t process_index = 0; process_index < scs->cdef_process_init_count; process_index++) {
2012
553
        EB_NEW(enc_handle_ptr->cdef_context_ptr_array[process_index],
2013
553
               svt_aom_cdef_context_ctor,
2014
553
               enc_handle_ptr,
2015
553
               process_index);
2016
553
    }
2017
2018
    //Rest Contexts
2019
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->rest_context_ptr_array, scs->rest_process_init_count);
2020
1.10k
    for (uint32_t process_index = 0; process_index < scs->rest_process_init_count; process_index++) {
2021
553
        EB_NEW(enc_handle_ptr->rest_context_ptr_array[process_index],
2022
553
               svt_aom_rest_context_ctor,
2023
553
               enc_handle_ptr,
2024
553
               process_index,
2025
553
               pic_mgr_port_lookup(pic_mgr_ports, PIC_MGR_INPUT_PORT_REST, process_index));
2026
553
    }
2027
2028
    // Entropy Coding Contexts
2029
553
    EB_ALLOC_PTR_ARRAY(enc_handle_ptr->entropy_coding_context_ptr_array, scs->entropy_coding_process_init_count);
2030
1.10k
    for (uint32_t process_index = 0; process_index < scs->entropy_coding_process_init_count; process_index++) {
2031
553
        EB_NEW(enc_handle_ptr->entropy_coding_context_ptr_array[process_index],
2032
553
               svt_aom_entropy_coding_context_ctor,
2033
553
               enc_handle_ptr,
2034
553
               process_index);
2035
553
    }
2036
2037
    // Packetization Context
2038
553
    EB_NEW(enc_handle_ptr->packetization_context_ptr,
2039
553
           svt_aom_packetization_context_ctor,
2040
553
           enc_handle_ptr,
2041
553
           rate_control_port_lookup(rate_control_ports, RATE_CONTROL_INPUT_PORT_PACKETIZATION, 0),
2042
553
           pic_mgr_port_lookup(pic_mgr_ports, PIC_MGR_INPUT_PORT_PACKETIZATION, 0),
2043
553
           EB_PictureDecisionProcessInitCount + EB_RateControlProcessInitCount); // me_port_index
2044
2045
    /************************************
2046
    * Thread Handles
2047
    ************************************/
2048
553
#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
553
    svt_kernel_dispatcher_init(&enc_handle_ptr->kernel_dispatcher);
2052
553
    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
553
#endif
2182
553
    {
2183
553
        EB_CREATE_THREAD(enc_handle_ptr->resource_coordination_thread_handle,
2184
553
                         svt_aom_resource_coordination_kernel,
2185
553
                         enc_handle_ptr->resource_coordination_context_ptr);
2186
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->picture_analysis_thread_handle_array,
2187
553
                               scs->picture_analysis_process_init_count,
2188
553
                               svt_aom_picture_analysis_kernel,
2189
553
                               enc_handle_ptr->picture_analysis_context_ptr_array,
2190
553
                               "svt-picana");
2191
2192
        // Picture Decision
2193
553
        EB_CREATE_THREAD(enc_handle_ptr->picture_decision_thread_handle,
2194
553
                         svt_aom_picture_decision_kernel,
2195
553
                         enc_handle_ptr->picture_decision_context_ptr);
2196
2197
        // Motion Estimation
2198
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->motion_estimation_thread_handle_array,
2199
553
                               scs->motion_estimation_process_init_count,
2200
553
                               svt_aom_motion_estimation_kernel,
2201
553
                               enc_handle_ptr->motion_estimation_context_ptr_array,
2202
553
                               "svt-me");
2203
2204
        // Initial Rate Control
2205
553
        EB_CREATE_THREAD(enc_handle_ptr->initial_rate_control_thread_handle,
2206
553
                         svt_aom_initial_rate_control_kernel,
2207
553
                         enc_handle_ptr->initial_rate_control_context_ptr);
2208
2209
        // Source Based Oprations
2210
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->source_based_operations_thread_handle_array,
2211
553
                               scs->source_based_operations_process_init_count,
2212
553
                               svt_aom_source_based_operations_kernel,
2213
553
                               enc_handle_ptr->source_based_operations_context_ptr_array,
2214
553
                               "svt-srcops");
2215
2216
        // TPL dispenser
2217
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->tpl_disp_thread_handle_array,
2218
553
                               scs->tpl_disp_process_init_count,
2219
553
                               svt_aom_tpl_disp_kernel, //TODOOMK
2220
553
                               enc_handle_ptr->tpl_disp_context_ptr_array,
2221
553
                               "svt-tpl");
2222
        // Picture Manager
2223
553
        EB_CREATE_THREAD(enc_handle_ptr->picture_manager_thread_handle,
2224
553
                         svt_aom_picture_manager_kernel,
2225
553
                         enc_handle_ptr->picture_manager_context_ptr);
2226
        // Rate Control
2227
553
        EB_CREATE_THREAD(enc_handle_ptr->rate_control_thread_handle,
2228
553
                         svt_aom_rate_control_kernel,
2229
553
                         enc_handle_ptr->rate_control_context_ptr);
2230
2231
        // Mode Decision Configuration Process
2232
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->mode_decision_configuration_thread_handle_array,
2233
553
                               scs->mode_decision_configuration_process_init_count,
2234
553
                               svt_aom_mode_decision_configuration_kernel,
2235
553
                               enc_handle_ptr->mode_decision_configuration_context_ptr_array,
2236
553
                               "svt-mdcfg");
2237
2238
        // EncDec Process
2239
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->enc_dec_thread_handle_array,
2240
553
                               scs->enc_dec_process_init_count,
2241
553
                               svt_aom_mode_decision_kernel,
2242
553
                               enc_handle_ptr->enc_dec_context_ptr_array,
2243
553
                               "svt-md");
2244
2245
        // Dlf Process
2246
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->dlf_thread_handle_array,
2247
553
                               scs->dlf_process_init_count,
2248
553
                               svt_aom_dlf_kernel,
2249
553
                               enc_handle_ptr->dlf_context_ptr_array,
2250
553
                               "svt-dlf");
2251
2252
        // Cdef Process
2253
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->cdef_thread_handle_array,
2254
553
                               scs->cdef_process_init_count,
2255
553
                               svt_aom_cdef_kernel,
2256
553
                               enc_handle_ptr->cdef_context_ptr_array,
2257
553
                               "svt-cdef");
2258
2259
        // Rest Process
2260
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->rest_thread_handle_array,
2261
553
                               scs->rest_process_init_count,
2262
553
                               svt_aom_rest_kernel,
2263
553
                               enc_handle_ptr->rest_context_ptr_array,
2264
553
                               "svt-rest");
2265
2266
        // Entropy Coding Process
2267
553
        EB_CREATE_THREAD_ARRAY(enc_handle_ptr->entropy_coding_thread_handle_array,
2268
553
                               scs->entropy_coding_process_init_count,
2269
553
                               svt_aom_entropy_coding_kernel,
2270
553
                               enc_handle_ptr->entropy_coding_context_ptr_array,
2271
553
                               "svt-ec");
2272
        // Packetization
2273
553
        EB_CREATE_THREAD(enc_handle_ptr->packetization_thread_handle,
2274
553
                         svt_aom_packetization_kernel,
2275
553
                         enc_handle_ptr->packetization_context_ptr);
2276
553
    } // end of thread creation block
2277
2278
553
    svt_print_memory_usage();
2279
2280
553
    return return_error;
2281
553
}
2282
2283
553
static EbErrorType enc_drain_queue(EbComponentType* svt_enc_component) {
2284
553
    bool eos = false;
2285
553
    do {
2286
553
        EbBufferHeaderType* receive_buffer = NULL;
2287
553
        EbErrorType         return_error;
2288
553
        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
553
        case EB_NoErrorEmptyQueue:
2292
553
            eos = true;
2293
553
            break;
2294
0
        default:
2295
0
            break;
2296
553
        }
2297
553
        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
553
    } while (!eos);
2303
553
    return EB_ErrorNone;
2304
553
}
2305
2306
/**********************************
2307
* DeInitialize Encoder Library
2308
**********************************/
2309
553
EB_API EbErrorType svt_av1_enc_deinit(EbComponentType* svt_enc_component) {
2310
553
    if (!svt_enc_component || !svt_enc_component->p_component_private) {
2311
0
        return EB_ErrorBadParameter;
2312
0
    }
2313
2314
553
    EbEncHandle* handle = svt_enc_component->p_component_private;
2315
2316
553
    if (handle->input_y8b_buffer_producer_fifo_ptr && handle->frame_received) {
2317
553
        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
553
        if (handle->eos_received) {
2326
553
            EbErrorType return_error = enc_drain_queue(svt_enc_component);
2327
553
            if (return_error != EB_ErrorNone) {
2328
0
                return return_error;
2329
0
            }
2330
553
        }
2331
553
    }
2332
2333
    // Free per-instance block geometry table
2334
553
    if (handle->scs_instance && handle->scs_instance->scs && handle->scs_instance->scs->blk_geom_mds != NULL) {
2335
553
        EB_FREE_ARRAY(handle->scs_instance->scs->blk_geom_mds);
2336
553
    }
2337
2338
553
    svt_shutdown_process(handle->input_buffer_resource_ptr);
2339
553
    svt_shutdown_process(handle->input_cmd_resource_ptr);
2340
553
    svt_shutdown_process(handle->resource_coordination_results_resource_ptr);
2341
553
    svt_shutdown_process(handle->picture_analysis_results_resource_ptr);
2342
553
    svt_shutdown_process(handle->picture_decision_results_resource_ptr);
2343
553
    svt_shutdown_process(handle->motion_estimation_results_resource_ptr);
2344
553
    svt_shutdown_process(handle->initial_rate_control_results_resource_ptr);
2345
553
    svt_shutdown_process(handle->picture_demux_results_resource_ptr);
2346
553
    svt_shutdown_process(handle->tpl_disp_res_srm);
2347
553
    svt_shutdown_process(handle->rate_control_tasks_resource_ptr);
2348
553
    svt_shutdown_process(handle->rate_control_results_resource_ptr);
2349
553
    svt_shutdown_process(handle->enc_dec_tasks_resource_ptr);
2350
553
    svt_shutdown_process(handle->enc_dec_results_resource_ptr);
2351
553
    svt_shutdown_process(handle->entropy_coding_results_resource_ptr);
2352
553
    svt_shutdown_process(handle->dlf_results_resource_ptr);
2353
553
    svt_shutdown_process(handle->cdef_results_resource_ptr);
2354
553
    svt_shutdown_process(handle->rest_results_resource_ptr);
2355
2356
553
    return EB_ErrorNone;
2357
553
}
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
553
{
2369
553
    if (p_handle == NULL) {
2370
0
        return EB_ErrorBadParameter;
2371
0
    }
2372
2373
553
    EB_MALLOC_OBJECT(*p_handle);
2374
    // Init Component OS objects (threads, semaphores, etc.)
2375
    // also links the various Component control functions
2376
553
    EbErrorType return_error = init_svt_av1_encoder_handle(*p_handle);
2377
2378
553
    if (return_error == EB_ErrorNone) {
2379
553
        return_error = svt_av1_set_default_params(config_ptr);
2380
553
    }
2381
553
    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
553
    svt_increase_component_count();
2388
553
    return return_error;
2389
553
}
2390
2391
/**********************************
2392
* Encoder Componenet DeInit
2393
**********************************/
2394
553
EbErrorType svt_av1_enc_component_de_init(EbComponentType* svt_enc_component) {
2395
553
    EbErrorType return_error = EB_ErrorNone;
2396
2397
553
    if (svt_enc_component->p_component_private) {
2398
553
        EbEncHandle* handle = (EbEncHandle*)svt_enc_component->p_component_private;
2399
553
        EB_DELETE(handle);
2400
553
        svt_enc_component->p_component_private = NULL;
2401
553
    } else {
2402
0
        return_error = EB_ErrorUndefined;
2403
0
    }
2404
553
    return return_error;
2405
553
}
2406
2407
/**********************************
2408
* svt_av1_enc_deinit_handle
2409
**********************************/
2410
553
EB_API EbErrorType svt_av1_enc_deinit_handle(EbComponentType* svt_enc_component) {
2411
553
    if (svt_enc_component) {
2412
553
        EbErrorType return_error = svt_av1_enc_component_de_init(svt_enc_component);
2413
2414
553
        EB_FREE(svt_enc_component);
2415
553
        svt_decrease_component_count();
2416
553
        return return_error;
2417
553
    }
2418
0
    return EB_ErrorInvalidComponent;
2419
553
}
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
553
static uint32_t compute_default_look_ahead(EbSvtAv1EncConfiguration* config) {
2441
553
    int32_t  lad;
2442
553
    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
553
    uint32_t eos_delay    = 1;
2448
553
    uint32_t max_tf_delay = 6;
2449
2450
553
    if (config->rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
2451
553
        lad = (1 + mg_size) * (1 + MIN_LAD_MG) + max_tf_delay + eos_delay;
2452
553
    } else {
2453
0
        lad = (1 + mg_size) * (1 + RC_DEFAULT_LAD_MG) + max_tf_delay + eos_delay;
2454
0
    }
2455
2456
553
    lad = lad > MAX_LAD ? MAX_LAD : lad; // clip to max allowed lad
2457
553
    return lad;
2458
553
}
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
553
void tf_controls(SequenceControlSet* scs, uint8_t tf_level) {
2615
553
    switch (tf_level) {
2616
553
    case 0:
2617
        // I_SLICE TF Params
2618
553
        scs->tf_params_per_type[0].enabled = 0;
2619
2620
        // BASE TF Params
2621
553
        scs->tf_params_per_type[1].enabled = 0;
2622
2623
        // L1 TF Params
2624
553
        scs->tf_params_per_type[2].enabled = 0;
2625
553
        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
553
    }
3273
553
    scs->tf_params_per_type[0].use_zz_based_filter = 0;
3274
553
    scs->tf_params_per_type[1].use_zz_based_filter = 0;
3275
553
    scs->tf_params_per_type[2].use_zz_based_filter = 0;
3276
553
}
3277
3278
/*
3279
 * Derive tune Params; 0: use objective mode params, 1: use subjective mode params
3280
 */
3281
553
static void derive_vq_params(SequenceControlSet* scs) {
3282
553
    VqCtrls* vq_ctrl = &scs->vq_ctrls;
3283
3284
553
    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
553
    } else {
3294
        // Sharpness
3295
553
        vq_ctrl->sharpness_ctrls.scene_transition = 1;
3296
553
        vq_ctrl->sharpness_ctrls.tf               = 0;
3297
553
        vq_ctrl->sharpness_ctrls.unipred_bias     = 0;
3298
553
        vq_ctrl->sharpness_ctrls.ifs              = 0;
3299
553
        vq_ctrl->sharpness_ctrls.cdef             = 0;
3300
553
        vq_ctrl->sharpness_ctrls.restoration      = 0;
3301
553
        vq_ctrl->sharpness_ctrls.rdoq             = 0;
3302
553
    }
3303
    // Do not use scene_transition if LD or 1st pass or middle pass
3304
553
    if (scs->static_config.pred_structure != RANDOM_ACCESS || scs->static_config.pass == ENC_FIRST_PASS) {
3305
553
        vq_ctrl->sharpness_ctrls.scene_transition = 0;
3306
553
    }
3307
553
}
3308
3309
/*
3310
 * Derive TF Params
3311
 */
3312
553
static void derive_tf_params(SequenceControlSet* scs) {
3313
553
    const uint32_t hierarchical_levels = scs->static_config.hierarchical_levels;
3314
    // Do not perform TF if LD or 1 Layer or 1st pass
3315
553
    const bool    do_tf    = scs->static_config.enable_tf && hierarchical_levels >= 1 && !scs->static_config.lossless;
3316
553
    const EncMode enc_mode = scs->static_config.enc_mode;
3317
553
    uint8_t       tf_level = 0;
3318
553
    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
553
    if (do_tf == 0) {
3325
553
        tf_level = 0;
3326
553
    } 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
553
    tf_controls(scs, tf_level);
3336
553
}
3337
3338
/*
3339
 * Set the MRP control
3340
 */
3341
553
static void set_mrp_ctrl_with_level(const SequenceControlSet* scs, MrpCtrls* mrp_ctrl, uint8_t mrp_level) {
3342
553
    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
553
    case 9:
3472
553
        mrp_ctrl->referencing_scheme       = 0;
3473
553
        mrp_ctrl->base_ref_list0_count     = 3;
3474
553
        mrp_ctrl->base_ref_list1_count     = 2;
3475
553
        mrp_ctrl->non_base_ref_list0_count = 1;
3476
553
        mrp_ctrl->non_base_ref_list1_count = 1;
3477
553
        mrp_ctrl->more_5L_refs             = 0;
3478
553
        mrp_ctrl->safe_limit_nref          = 2;
3479
553
        mrp_ctrl->safe_limit_zz_th         = 60000;
3480
553
        mrp_ctrl->only_l_bwd               = 1;
3481
553
        mrp_ctrl->pme_ref0_only            = 1;
3482
553
        mrp_ctrl->use_best_references      = 3;
3483
553
        mrp_ctrl->early_hme_l0_prune_th    = 150;
3484
553
        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
553
    }
3517
    // For low delay mode, list1 references are not used
3518
553
    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
553
    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
553
    } else {
3546
553
        mrp_ctrl->ld_reduce_ref_buffs = 0;
3547
553
    }
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
553
}
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
553
static void set_mrp_ctrl(const SequenceControlSet* scs, MrpCtrls* mrp_ctrl, EncMode enc_mode) {
3565
553
    uint8_t mrp_level;
3566
553
    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
553
    else {
3583
553
        if (enc_mode <= ENC_MR) {
3584
0
            mrp_level = 1;
3585
553
        } else if (enc_mode <= ENC_M2) {
3586
0
            mrp_level = 2;
3587
553
        } else if (enc_mode <= ENC_M4) {
3588
0
            mrp_level = 4;
3589
553
        } else if (enc_mode <= ENC_M8) {
3590
0
            mrp_level = 6;
3591
553
        } else if (enc_mode <= ENC_M9) {
3592
553
            mrp_level = scs->static_config.pred_structure == RANDOM_ACCESS ? 7 : 9;
3593
553
        } 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
553
    }
3601
553
    set_mrp_ctrl_with_level(scs, mrp_ctrl, mrp_level);
3602
553
}
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
553
                       bool allintra) {
3647
553
    if (allintra) {
3648
553
        SVT_WARN("TPL is disabled for all-intra coding\n");
3649
553
        return 0;
3650
553
    } 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
553
}
3668
3669
/*
3670
* Set multi Pass Params
3671
*/
3672
553
void set_multi_pass_params(SequenceControlSet* scs) {
3673
553
    EbSvtAv1EncConfiguration* config = &scs->static_config;
3674
3675
    // Update passes
3676
553
    if (scs->static_config.pass != ENC_SINGLE_PASS) {
3677
0
        scs->passes = MAX_ENCODE_PASS;
3678
553
    } else {
3679
553
        scs->passes = 1;
3680
553
    }
3681
3682
553
    switch (config->pass) {
3683
553
    case ENC_SINGLE_PASS: {
3684
553
        scs->first_pass_downsample = false;
3685
553
        scs->final_pass_preset     = config->enc_mode;
3686
553
        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
553
    }
3712
3713
553
    int do_downsample = scs->first_pass_downsample && scs->max_input_luma_width >= 128 &&
3714
0
            scs->max_input_luma_height >= 128
3715
553
        ? 1
3716
553
        : 0;
3717
3718
553
    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
553
    if (scs->lap_rc) {
3725
0
        scs->static_config.intra_refresh_type = SVT_AV1_KF_REFRESH;
3726
0
    }
3727
553
    if (scs->static_config.pass == ENC_FIRST_PASS && scs->final_pass_preset > ENC_M6) {
3728
0
        scs->rc_stat_gen_pass_mode = 1;
3729
553
    } else {
3730
553
        scs->rc_stat_gen_pass_mode = 0;
3731
553
    }
3732
3733
553
    if (scs->static_config.recode_loop > 0 &&
3734
553
        ((scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF && scs->static_config.max_bit_rate == 0) ||
3735
553
         (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
553
        scs->static_config.recode_loop = DISALLOW_RECODE;
3738
553
    } 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
553
    scs->enc_ctx->recode_loop = scs->static_config.recode_loop;
3749
553
}
3750
3751
553
static void validate_scaling_params(SequenceControlSet* scs) {
3752
553
    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
553
    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
553
    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
553
    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
553
}
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
553
void set_qp_based_th_scaling_ctrls_all_intra(SequenceControlSet* scs) {
3826
553
    QpBasedThScaling* qp_ctrls = &scs->qp_based_th_scaling_ctrls;
3827
553
    const EncMode     enc_mode = scs->static_config.enc_mode;
3828
3829
553
    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
553
    } 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
553
    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
553
    } else {
3874
553
        qp_ctrls->tf_me_qp_based_th_scaling        = 1;
3875
553
        qp_ctrls->tf_ref_qp_based_th_scaling       = 1;
3876
553
        qp_ctrls->depths_qp_based_th_scaling       = 1;
3877
553
        qp_ctrls->hme_qp_based_th_scaling          = 1;
3878
553
        qp_ctrls->me_qp_based_th_scaling           = 1;
3879
553
        qp_ctrls->nsq_qp_based_th_scaling          = 1;
3880
553
        qp_ctrls->nic_max_qp_based_th_scaling      = 1;
3881
553
        qp_ctrls->nic_pruning_qp_based_th_scaling  = 1;
3882
553
        qp_ctrls->pme_qp_based_th_scaling          = 1;
3883
553
        qp_ctrls->txt_qp_based_th_scaling          = 1;
3884
553
        qp_ctrls->cap_max_size_qp_based_th_scaling = 1;
3885
553
        qp_ctrls->lpd0_qp_based_th_scaling         = 1;
3886
553
        qp_ctrls->intra_bc_mesh_qp_scaling         = 1;
3887
553
    }
3888
553
}
3889
3890
553
static void set_param_based_on_input(SequenceControlSet* scs) {
3891
553
    const bool allintra = scs->allintra;
3892
553
    const bool rtc_tune = scs->static_config.rtc;
3893
553
    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
553
    validate_scaling_params(scs);
3898
553
    scs->tpl               = get_tpl(scs->static_config.pred_structure,
3899
553
                       scs->static_config.superres_mode,
3900
553
                       scs->static_config.resize_mode,
3901
553
                       scs->static_config.aq_mode,
3902
553
                       allintra);
3903
553
    uint16_t subsampling_x = scs->subsampling_x;
3904
553
    uint16_t subsampling_y = scs->subsampling_y;
3905
    // Update picture width, and picture height
3906
553
    if (scs->max_input_luma_width % MIN_BLOCK_SIZE) {
3907
379
        scs->max_input_pad_right  = MIN_BLOCK_SIZE - (scs->max_input_luma_width % MIN_BLOCK_SIZE);
3908
379
        scs->max_input_luma_width = scs->max_input_luma_width + scs->max_input_pad_right;
3909
379
    } else {
3910
174
        scs->max_input_pad_right = 0;
3911
174
    }
3912
3913
553
    if (scs->max_input_luma_height % MIN_BLOCK_SIZE) {
3914
386
        scs->max_input_pad_bottom  = MIN_BLOCK_SIZE - (scs->max_input_luma_height % MIN_BLOCK_SIZE);
3915
386
        scs->max_input_luma_height = scs->max_input_luma_height + scs->max_input_pad_bottom;
3916
386
    } else {
3917
167
        scs->max_input_pad_bottom = 0;
3918
167
    }
3919
553
    scs->max_initial_input_luma_width  = scs->max_input_luma_width;
3920
553
    scs->max_initial_input_luma_height = scs->max_input_luma_height;
3921
553
    scs->max_initial_input_pad_bottom  = scs->max_input_pad_bottom;
3922
553
    scs->max_initial_input_pad_right   = scs->max_input_pad_right;
3923
3924
553
    scs->chroma_width  = scs->max_input_luma_width >> subsampling_x;
3925
553
    scs->chroma_height = scs->max_input_luma_height >> subsampling_y;
3926
3927
553
    scs->static_config.source_width  = scs->max_input_luma_width;
3928
553
    scs->static_config.source_height = scs->max_input_luma_height;
3929
553
    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
553
    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
553
    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
553
    svt_aom_derive_input_resolution(&scs->input_resolution, scs->max_input_luma_width * scs->max_input_luma_height);
3981
3982
553
    scs->seq_qp_mod = 2;
3983
3984
553
    (allintra       ? set_qp_based_th_scaling_ctrls_all_intra
3985
553
         : 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
553
    derive_vq_params(scs);
3990
3991
    // Set TF level
3992
553
    derive_tf_params(scs);
3993
3994
    //Future frames window in Scene Change Detection (SCD) / TemporalFiltering
3995
553
    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
553
    uint32_t scd_delay_islice = 0;
4000
553
    if (scs->static_config.intra_period_length == 0) {
4001
553
        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
553
    }
4010
4011
    // Update the scd_delay based on the the number of future frames @ BASE
4012
553
    uint32_t scd_delay_base = 0;
4013
553
    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
553
    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
553
    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
553
    if (allintra || scs->static_config.pred_structure == LOW_DELAY) {
4030
553
        scs->lad_mg = scs->tpl_lad_mg = 0;
4031
553
    } 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
553
    if ((scs->static_config.fast_decode && scs->static_config.qp <= 56 &&
4063
0
         !(scs->input_resolution <= INPUT_SIZE_360p_RANGE)) ||
4064
553
        scs->static_config.resize_mode > RESIZE_NONE || scs->static_config.rtc ||
4065
553
        (scs->input_resolution == INPUT_SIZE_240p_RANGE) || scs->static_config.enable_variance_boost) {
4066
553
        scs->super_block_size = 64;
4067
553
    } 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
553
    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
553
    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
553
    } else {
4095
553
        scs->seq_header.sb_size      = BLOCK_64X64;
4096
553
        scs->sb_size                 = 64;
4097
553
        scs->seq_header.sb_mi_size   = 16; // Size of the superblock in units of MI blocks
4098
553
        scs->seq_header.sb_size_log2 = 4;
4099
553
    }
4100
4101
553
    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
553
    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
553
    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
553
    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
553
    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
553
    bool    disallow_nsq  = true;
4126
553
    uint8_t allow_HVA_HVB = 0;
4127
553
    uint8_t allow_HV4     = 0;
4128
553
    uint8_t h_v_only      = 1;
4129
553
    uint8_t min_nsq_bsize = 0;
4130
553
    uint8_t no_8x4_4x8    = 1;
4131
553
    uint8_t no_16x8_8x16  = 1;
4132
3.31k
    for (uint8_t coeff_lvl = 0; coeff_lvl <= HIGH_LVL + 1; coeff_lvl++) {
4133
2.76k
        uint8_t nsq_geom_level;
4134
2.76k
        if (scs->allintra) {
4135
2.76k
            nsq_geom_level = svt_aom_get_nsq_geom_level_allintra(scs->static_config.enc_mode);
4136
2.76k
        } 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.76k
        disallow_nsq               = MIN(disallow_nsq, nsq_geom_level == 0);
4142
2.76k
        uint8_t temp_allow_HVA_HVB = 0, temp_allow_HV4 = 0;
4143
2.76k
        svt_aom_set_nsq_geom_ctrls(NULL, nsq_geom_level, &temp_allow_HVA_HVB, &temp_allow_HV4, &min_nsq_bsize);
4144
2.76k
        allow_HVA_HVB |= temp_allow_HVA_HVB;
4145
2.76k
        allow_HV4 |= temp_allow_HV4;
4146
2.76k
        h_v_only     = h_v_only && !allow_HVA_HVB && !allow_HV4;
4147
2.76k
        no_8x4_4x8   = no_8x4_4x8 && min_nsq_bsize >= 8;
4148
2.76k
        no_16x8_8x16 = no_16x8_8x16 && min_nsq_bsize >= 16;
4149
2.76k
    }
4150
4151
553
    bool disallow_8x8;
4152
553
    bool disallow_4x4;
4153
553
    if (scs->allintra) {
4154
553
        disallow_4x4 = svt_aom_get_disallow_4x4_allintra(scs->static_config.enc_mode);
4155
553
        disallow_8x8 = svt_aom_get_disallow_8x8_allintra();
4156
553
    } 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
553
    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
553
    } else {
4173
        //SB 64x64
4174
553
        if (disallow_nsq && disallow_4x4 && disallow_8x8) {
4175
0
            scs->svt_aom_geom_idx = GEOM_0;
4176
0
            scs->max_block_cnt    = 21;
4177
553
        } 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
553
        } else if (disallow_nsq && disallow_4x4) {
4181
553
            scs->svt_aom_geom_idx = GEOM_2;
4182
553
            scs->max_block_cnt    = 85;
4183
553
        } 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
553
    }
4203
    // Configure the padding
4204
553
    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
553
    { scs->border += 4; }
4210
4211
553
    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
553
        ? 0
4214
553
        : scs->static_config.enable_overlays;
4215
4216
    // Enforce starting frame in decode order (at PicMgr)
4217
    // Does not wait for feedback from PKT
4218
553
    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
553
    } else {
4221
553
        scs->enable_pic_mgr_dec_order = 0;
4222
553
    }
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
553
    if (scs->static_config.level_of_parallelism == 1 || scs->static_config.pred_structure == LOW_DELAY) {
4229
0
        scs->enable_dec_order = 1;
4230
553
    } else {
4231
553
        scs->enable_dec_order = 0;
4232
553
    }
4233
553
#endif
4234
    // 1: Use boundary pixels in restoration filter search.
4235
    // 0: Do not use boundary pixels in the restoration filter search.
4236
553
    scs->use_boundaries_in_rest_search = 0;
4237
4238
553
    svt_aom_set_mfmv_config(scs, scs->static_config.enc_mode);
4239
4240
553
    scs->list0_only_base = scs->static_config.enc_mode > ENC_M2;
4241
4242
553
    if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR ||
4243
553
        scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR || scs->input_resolution >= INPUT_SIZE_4K_RANGE ||
4244
553
        scs->static_config.pred_structure != RANDOM_ACCESS || scs->static_config.pass != ENC_SINGLE_PASS) {
4245
553
        scs->enable_dg = 0;
4246
553
    } 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
553
    if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) < 10) {
4251
553
        scs->enable_hbd_mode_decision = 0;
4252
553
    }
4253
4254
    // Throws a warning when scene change is on, as the feature is not optimal and may produce false detections
4255
553
    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
553
    set_mrp_ctrl(scs, &scs->mrp_ctrls, scs->static_config.enc_mode);
4271
553
    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
553
    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
553
    scs->mrp_ctrls_init = scs->mrp_ctrls;
4307
    // set to 1 if multipass and less than 200 frames in resourcecordination
4308
553
    scs->is_short_clip = scs->static_config.gop_constraint_rc ? 1 : 0;
4309
553
    if (allintra || scs->static_config.aq_mode == 1 || scs->static_config.scene_change_detection == 1 ||
4310
553
        scs->vq_ctrls.sharpness_ctrls.tf == 1 || scs->static_config.enable_variance_boost || scs->static_config.rtc) {
4311
553
        scs->calculate_variance = 1;
4312
553
    } else {
4313
0
        scs->calculate_variance = 0;
4314
0
    }
4315
553
    if (allintra) {
4316
553
        scs->detect_luma_dominant_input = false;
4317
553
    } else {
4318
0
        scs->detect_luma_dominant_input = true;
4319
0
    }
4320
553
    scs->resize_pending_params.resize_state = ORIG;
4321
553
    scs->resize_pending_params.resize_denom = SCALE_NUMERATOR;
4322
4323
553
    scs->stats_based_sb_lambda_modulation = (scs->static_config.enc_mode <= (rtc_tune ? ENC_M10 : ENC_M11)) ? 1 : 0;
4324
4325
553
    scs->fast_aa_aware_screen_detection_mode = (scs->static_config.enc_mode >= ENC_M3) ? 1 : 0;
4326
553
}
4327
4328
553
static void copy_api_from_app(SequenceControlSet* scs, EbSvtAv1EncConfiguration* config_struct) {
4329
553
    scs->max_input_luma_width  = config_struct->source_width;
4330
553
    scs->max_input_luma_height = config_struct->source_height;
4331
    // SB Definitions
4332
553
    scs->static_config.pred_structure = config_struct->pred_structure;
4333
553
    scs->static_config.rtc            = config_struct->rtc;
4334
553
    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
553
    scs->enable_qp_scaling_flag = scs->allintra ? 0 : 1;
4339
    // Set Picture Parameters for statistics gathering
4340
553
    scs->picture_analysis_number_of_regions_per_width  = scs->max_input_luma_width >= 64
4341
553
         ? HIGHER_THAN_CLASS_1_REGION_SPLIT_PER_WIDTH
4342
553
         : 1;
4343
553
    scs->picture_analysis_number_of_regions_per_height = scs->max_input_luma_height >= 64
4344
553
        ? HIGHER_THAN_CLASS_1_REGION_SPLIT_PER_HEIGHT
4345
553
        : 1;
4346
4347
553
    scs->pic_based_rate_est   = false;
4348
553
    scs->block_mean_calc_prec = BLOCK_MEAN_PREC_SUB;
4349
553
    scs->speed_control_flag   = 0;
4350
    // Padding Offsets
4351
553
    scs->b64_size                          = 64;
4352
553
    scs->static_config.intra_period_length = config_struct->intra_period_length;
4353
553
    scs->static_config.avif                = config_struct->avif;
4354
553
    scs->allintra                          = (scs->static_config.intra_period_length == 0 || scs->static_config.avif ||
4355
0
                     scs->static_config.pred_structure == ALL_INTRA);
4356
553
    if (scs->allintra) {
4357
553
        scs->static_config.pred_structure      = ALL_INTRA;
4358
553
        scs->static_config.intra_period_length = 0;
4359
553
    }
4360
553
    scs->static_config.multiply_keyint    = config_struct->multiply_keyint;
4361
553
    scs->static_config.intra_refresh_type = config_struct->intra_refresh_type;
4362
553
    scs->static_config.enc_mode           = config_struct->enc_mode;
4363
553
    if (scs->allintra) {
4364
553
        if (scs->static_config.enc_mode > ENC_M9) {
4365
553
            SVT_WARN("Preset M%d is mapped to M9.\n", scs->static_config.enc_mode);
4366
553
            scs->static_config.enc_mode = ENC_M9;
4367
553
        }
4368
553
    }
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
553
    ResolutionRange input_resolution;
4387
553
    svt_aom_derive_input_resolution(&input_resolution, scs->max_input_luma_width * scs->max_input_luma_height);
4388
553
    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
553
    scs->static_config.use_qp_file                    = config_struct->use_qp_file;
4397
553
    scs->static_config.use_fixed_qindex_offsets       = config_struct->use_fixed_qindex_offsets;
4398
553
    scs->static_config.key_frame_chroma_qindex_offset = config_struct->key_frame_chroma_qindex_offset;
4399
553
    scs->static_config.key_frame_qindex_offset        = config_struct->key_frame_qindex_offset;
4400
553
    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
553
    memcpy(scs->static_config.chroma_qindex_offsets,
4408
553
           config_struct->chroma_qindex_offsets,
4409
553
           MAX_TEMPORAL_LAYERS * sizeof(int32_t));
4410
4411
553
    scs->static_config.lossless = config_struct->lossless;
4412
553
    if (scs->static_config.lossless) {
4413
241
        scs->static_config.luma_y_dc_qindex_offset   = 0;
4414
241
        scs->static_config.chroma_u_dc_qindex_offset = 0;
4415
241
        scs->static_config.chroma_u_ac_qindex_offset = 0;
4416
241
        scs->static_config.chroma_v_dc_qindex_offset = 0;
4417
241
        scs->static_config.chroma_v_ac_qindex_offset = 0;
4418
312
    } else {
4419
312
        scs->static_config.luma_y_dc_qindex_offset   = config_struct->luma_y_dc_qindex_offset;
4420
312
        scs->static_config.chroma_u_dc_qindex_offset = config_struct->chroma_u_dc_qindex_offset;
4421
312
        scs->static_config.chroma_u_ac_qindex_offset = config_struct->chroma_u_ac_qindex_offset;
4422
312
        scs->static_config.chroma_v_dc_qindex_offset = config_struct->chroma_v_dc_qindex_offset;
4423
312
        scs->static_config.chroma_v_ac_qindex_offset = config_struct->chroma_v_ac_qindex_offset;
4424
312
    }
4425
553
    memcpy(scs->static_config.lambda_scale_factors,
4426
553
           config_struct->lambda_scale_factors,
4427
553
           SVT_AV1_FRAME_UPDATE_TYPES * sizeof(int32_t));
4428
4429
553
    scs->static_config.rc_stats_buffer = config_struct->rc_stats_buffer;
4430
553
    scs->static_config.pass            = config_struct->pass;
4431
    // Deblock Filter
4432
553
    scs->static_config.enable_dlf_flag = config_struct->enable_dlf_flag;
4433
4434
    // CDEF
4435
553
    scs->static_config.cdef_level = config_struct->cdef_level;
4436
4437
    // Intra Block Copy
4438
553
    scs->static_config.enable_intrabc = config_struct->enable_intrabc;
4439
4440
    // Restoration filtering
4441
553
    scs->static_config.enable_restoration_filtering = config_struct->enable_restoration_filtering;
4442
4443
    // motion field motion vector
4444
553
    scs->static_config.enable_mfmv = config_struct->enable_mfmv;
4445
4446
    // Dynamic GoP
4447
553
    scs->static_config.enable_dg = config_struct->enable_dg;
4448
4449
    // Decoder Optimization Flag
4450
553
    scs->static_config.fast_decode = config_struct->fast_decode;
4451
4452
    //Film Grain
4453
553
    scs->static_config.film_grain_denoise_strength = config_struct->film_grain_denoise_strength;
4454
553
    scs->static_config.film_grain_denoise_apply    = config_struct->film_grain_denoise_apply;
4455
553
    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
553
    scs->seq_header.film_grain_params_present = (uint8_t)(scs->static_config.film_grain_denoise_strength > 0);
4459
553
    scs->static_config.fgs_table              = config_struct->fgs_table;
4460
4461
    // MD Parameters
4462
553
    scs->enable_hbd_mode_decision = SVT_EFFECTIVE_BIT_DEPTH(config_struct->encoder_bit_depth) > 8 ? DEFAULT : 0;
4463
553
    {
4464
553
        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
553
        } else {
4469
553
            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
553
            } 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
553
            } else {
4476
553
                scs->static_config.tile_rows    = config_struct->tile_rows;
4477
553
                scs->static_config.tile_columns = config_struct->tile_columns;
4478
553
            }
4479
553
        }
4480
553
    }
4481
4482
    // Rate Control
4483
553
    scs->static_config.scene_change_detection = config_struct->scene_change_detection;
4484
553
    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
553
    } else {
4488
553
        scs->static_config.rate_control_mode = config_struct->rate_control_mode;
4489
553
    }
4490
553
    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
553
    scs->static_config.tune                = config_struct->tune;
4497
553
    scs->static_config.hierarchical_levels = config_struct->hierarchical_levels;
4498
4499
    // Set the default hierarchical levels
4500
553
    if (scs->static_config.hierarchical_levels == HIERARCHICAL_LEVELS_AUTO) {
4501
553
        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
553
            ? 2
4505
553
            : scs->static_config.pred_structure == LOW_DELAY ? 3
4506
553
            : scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR ||
4507
553
                scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CBR ||
4508
553
                (input_resolution >= INPUT_SIZE_1080p_RANGE && scs->static_config.enc_mode >= ENC_M8) ||
4509
553
                !(scs->static_config.enc_mode <= ENC_M8) || input_resolution >= INPUT_SIZE_8K_RANGE
4510
553
            ? 4
4511
553
            : 5;
4512
553
    }
4513
553
    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
553
    if (scs->allintra) {
4521
553
        scs->static_config.hierarchical_levels = 2;
4522
553
    }
4523
553
    scs->static_config.look_ahead_distance    = config_struct->look_ahead_distance;
4524
553
    scs->static_config.frame_rate_denominator = config_struct->frame_rate_denominator;
4525
553
    scs->static_config.frame_rate_numerator   = config_struct->frame_rate_numerator;
4526
4527
553
    scs->static_config.target_bit_rate = config_struct->target_bit_rate;
4528
553
    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
553
    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
553
    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
553
    scs->static_config.max_qp_allowed = scs->static_config.lossless ? MIN_QP_VALUE : config_struct->max_qp_allowed;
4540
4541
553
    scs->static_config.min_qp_allowed      = scs->static_config.lossless ? MIN_QP_VALUE
4542
553
             : config_struct->min_qp_allowed == MIN_QP_AUTO ? scs->static_config.rate_control_mode ? 4 : MIN_QP_VALUE
4543
312
                                                            : config_struct->min_qp_allowed;
4544
553
    scs->static_config.vbr_min_section_pct = config_struct->vbr_min_section_pct;
4545
553
    scs->static_config.vbr_max_section_pct = config_struct->vbr_max_section_pct;
4546
553
    scs->static_config.under_shoot_pct     = config_struct->under_shoot_pct;
4547
553
    scs->static_config.over_shoot_pct      = config_struct->over_shoot_pct;
4548
553
    if (scs->static_config.under_shoot_pct == (uint32_t)DEFAULT) {
4549
553
        if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_VBR) {
4550
0
            scs->static_config.under_shoot_pct = 50;
4551
553
        } else {
4552
553
            scs->static_config.under_shoot_pct = 25;
4553
553
        }
4554
553
    }
4555
4556
553
    if (scs->static_config.over_shoot_pct == (uint32_t)DEFAULT) {
4557
553
        scs->static_config.over_shoot_pct = 25;
4558
553
    }
4559
553
    scs->static_config.mbr_over_shoot_pct       = config_struct->mbr_over_shoot_pct;
4560
553
    scs->static_config.max_intra_bitrate_pct    = config_struct->max_intra_bitrate_pct;
4561
553
    scs->static_config.max_inter_bitrate_pct    = config_struct->max_inter_bitrate_pct;
4562
553
    scs->static_config.gop_constraint_rc        = config_struct->gop_constraint_rc;
4563
553
    scs->static_config.maximum_buffer_size_ms   = config_struct->maximum_buffer_size_ms;
4564
553
    scs->static_config.starting_buffer_level_ms = config_struct->starting_buffer_level_ms;
4565
553
    scs->static_config.optimal_buffer_level_ms  = config_struct->optimal_buffer_level_ms;
4566
553
    scs->static_config.recode_loop              = config_struct->recode_loop;
4567
553
    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
553
    } else {
4570
553
        scs->lap_rc = 0;
4571
553
    }
4572
    // Misc
4573
553
    scs->static_config.encoder_bit_depth    = config_struct->encoder_bit_depth;
4574
553
    scs->static_config.encoder_color_format = config_struct->encoder_color_format;
4575
4576
553
    scs->chroma_format_idc = (uint32_t)(scs->static_config.encoder_color_format);
4577
553
    scs->encoder_bit_depth = (uint32_t)(scs->static_config.encoder_bit_depth);
4578
    //16bit pipeline
4579
553
    scs->is_16bit_pipeline = ((config_struct->encoder_bit_depth) > EB_EIGHT_BIT) ? true : false;
4580
553
    scs->subsampling_x     = (scs->chroma_format_idc == EB_YUV444 ? 0 : 1);
4581
553
    scs->subsampling_y     = (scs->chroma_format_idc >= EB_YUV422 ? 0 : 1);
4582
    // Force screen-content detection OFF when allintra
4583
553
    const bool allintra = scs->allintra;
4584
553
    const bool rtc      = scs->static_config.rtc;
4585
553
    if (allintra) {
4586
553
        if (config_struct->screen_content_mode <= 1) {
4587
0
            scs->static_config.screen_content_mode = config_struct->screen_content_mode;
4588
553
        } else if (scs->static_config.enc_mode <= ENC_M7) {
4589
0
            scs->static_config.screen_content_mode = 3;
4590
553
        } else {
4591
553
            scs->static_config.screen_content_mode = 0;
4592
553
            SVT_WARN(
4593
553
                "Screen-content detection and tools are disabled for all-intra coding at M8 and above; forcing NSC "
4594
553
                "path\n");
4595
553
        }
4596
553
    } 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
553
    scs->static_config.profile     = config_struct->profile;
4621
553
    scs->static_config.tier        = config_struct->tier;
4622
553
    scs->static_config.level       = config_struct->level;
4623
553
    scs->static_config.stat_report = config_struct->stat_report;
4624
4625
    // Buffers - Hardcoded(Cleanup)
4626
553
    scs->static_config.use_cpu_flags = config_struct->use_cpu_flags;
4627
4628
553
    scs->static_config.level_of_parallelism = config_struct->level_of_parallelism;
4629
553
    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
553
    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
553
    scs->static_config.qp            = config_struct->qp;
4647
553
    scs->static_config.recon_enabled = config_struct->recon_enabled;
4648
4649
    // Numerator and Denominator already checked to be non 0
4650
553
    scs->frame_rate = (double)scs->static_config.frame_rate_numerator /
4651
553
        (double)scs->static_config.frame_rate_denominator;
4652
4653
    // Get Default Intra Period if not specified
4654
553
    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
553
    } 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
553
    if (scs->static_config.look_ahead_distance == (uint32_t)~0) {
4661
553
        scs->static_config.look_ahead_distance = compute_default_look_ahead(&scs->static_config);
4662
553
    }
4663
553
    scs->static_config.enable_tf          = scs->allintra ? 0 : config_struct->enable_tf;
4664
553
    scs->static_config.enable_tf_key      = config_struct->enable_tf && config_struct->enable_tf_key;
4665
553
    scs->static_config.enable_overlays    = config_struct->enable_overlays;
4666
553
    scs->static_config.superres_mode      = config_struct->superres_mode;
4667
553
    scs->static_config.superres_denom     = config_struct->superres_denom;
4668
553
    scs->static_config.superres_kf_denom  = config_struct->superres_kf_denom;
4669
553
    scs->static_config.superres_qthres    = config_struct->superres_qthres;
4670
553
    scs->static_config.superres_kf_qthres = config_struct->superres_kf_qthres;
4671
4672
553
    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
553
    scs->static_config.resize_mode     = config_struct->resize_mode;
4680
553
    scs->static_config.resize_denom    = config_struct->resize_denom;
4681
553
    scs->static_config.resize_kf_denom = config_struct->resize_kf_denom;
4682
553
    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
553
    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
553
    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
553
    scs->static_config.frame_scale_evts.evt_num = config_struct->frame_scale_evts.evt_num;
4704
553
    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
553
    scs->static_config.sframe_posi.sframe_num = config_struct->sframe_posi.sframe_num;
4712
553
    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
553
    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
553
    scs->static_config.sframe_posi.sframe_qp_num = config_struct->sframe_posi.sframe_qp_num;
4728
4729
    // Color description
4730
553
    scs->static_config.color_primaries          = config_struct->color_primaries;
4731
553
    scs->static_config.transfer_characteristics = config_struct->transfer_characteristics;
4732
553
    scs->static_config.matrix_coefficients      = config_struct->matrix_coefficients;
4733
553
    scs->static_config.color_range              = config_struct->color_range;
4734
553
    scs->static_config.chroma_sample_position   = config_struct->chroma_sample_position;
4735
553
    scs->static_config.mastering_display        = config_struct->mastering_display;
4736
553
    scs->static_config.content_light_level      = config_struct->content_light_level;
4737
4738
    // switch frame
4739
553
    scs->static_config.sframe_dist      = config_struct->sframe_dist;
4740
553
    scs->static_config.sframe_mode      = config_struct->sframe_mode;
4741
553
    scs->static_config.sframe_qp        = config_struct->sframe_qp;
4742
553
    scs->static_config.sframe_qp_offset = config_struct->sframe_qp_offset;
4743
553
    scs->seq_header.max_frame_width  = config_struct->forced_max_frame_width > 0 ? config_struct->forced_max_frame_width
4744
553
         : scs->static_config.sframe_dist > 0 || scs->static_config.sframe_posi.sframe_posis ? 16384
4745
553
                                                                                             : scs->max_input_luma_width;
4746
553
    scs->seq_header.max_frame_height = config_struct->forced_max_frame_height > 0
4747
553
        ? config_struct->forced_max_frame_height
4748
553
        : scs->static_config.sframe_dist > 0 || scs->static_config.sframe_posi.sframe_posis
4749
553
        ? 8704
4750
553
        : scs->max_input_luma_height;
4751
553
    scs->static_config.force_key_frames = config_struct->force_key_frames;
4752
4753
    // QM
4754
553
    scs->static_config.enable_qm           = config_struct->enable_qm;
4755
553
    scs->static_config.min_qm_level        = config_struct->min_qm_level;
4756
553
    scs->static_config.max_qm_level        = config_struct->max_qm_level;
4757
553
    scs->static_config.min_chroma_qm_level = config_struct->min_chroma_qm_level;
4758
553
    scs->static_config.max_chroma_qm_level = config_struct->max_chroma_qm_level;
4759
553
    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
553
    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
553
    scs->static_config.startup_mg_size   = config_struct->startup_mg_size;
4770
553
    scs->static_config.startup_qp_offset = config_struct->startup_qp_offset;
4771
553
    scs->static_config.enable_roi_map    = config_struct->enable_roi_map;
4772
4773
    // Variance Boost
4774
553
    scs->static_config.enable_variance_boost   = config_struct->enable_variance_boost;
4775
553
    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
553
    scs->static_config.variance_octile = config_struct->variance_octile;
4780
553
#endif
4781
553
    scs->static_config.variance_boost_curve = config_struct->variance_boost_curve;
4782
4783
    // Temporal filtering strength
4784
553
    scs->static_config.tf_strength = config_struct->tf_strength;
4785
4786
    // Frame-level luminance-based QP bias
4787
553
    scs->static_config.luminance_qp_bias = config_struct->luminance_qp_bias;
4788
4789
    // Sharpness
4790
553
    scs->static_config.sharpness = config_struct->sharpness;
4791
4792
    // QP scaling compression
4793
553
    scs->static_config.qp_scale_compress_strength = config_struct->qp_scale_compress_strength;
4794
4795
    // Adaptive film grain
4796
553
    scs->static_config.adaptive_film_grain = config_struct->adaptive_film_grain;
4797
4798
    // Max TX size
4799
553
    scs->static_config.max_tx_size = config_struct->max_tx_size;
4800
4801
    // Extended CRF
4802
553
    scs->static_config.extended_crf_qindex_offset = config_struct->extended_crf_qindex_offset;
4803
4804
    // AC bias
4805
553
    scs->static_config.ac_bias = config_struct->ac_bias;
4806
4807
    // HBD-MDS
4808
553
    scs->static_config.hbd_mds = config_struct->hbd_mds;
4809
4810
    // Ref-frame management: propagate caller's max-anchors hint (0 = disabled).
4811
553
    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
553
    scs->static_config.max_hierarchical_levels = config_struct->max_hierarchical_levels;
4815
4816
    // Override settings for Still IQ tune
4817
553
    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
553
    } 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
553
    } 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
553
    return;
4847
553
}
4848
4849
/**********************************
4850
4851
* Set Parameter
4852
**********************************/
4853
EB_API EbErrorType svt_av1_enc_set_parameter(EbComponentType*          svt_enc_component,
4854
553
                                             EbSvtAv1EncConfiguration* config_struct) {
4855
553
    if (svt_enc_component == NULL) {
4856
0
        return EB_ErrorBadParameter;
4857
0
    }
4858
4859
553
    EbEncHandle*        enc_handle = (EbEncHandle*)svt_enc_component->p_component_private;
4860
553
    SequenceControlSet* scs        = enc_handle->scs_instance->scs;
4861
553
    copy_api_from_app(scs, config_struct);
4862
4863
553
    EbErrorType return_error = svt_av1_verify_settings(scs);
4864
4865
553
    if (return_error == EB_ErrorBadParameter) {
4866
0
        return EB_ErrorBadParameter;
4867
0
    }
4868
4869
553
    if (scs->static_config.avif) {
4870
553
        scs->seq_header.still_picture                = 1;
4871
553
        scs->seq_header.reduced_still_picture_header = 1;
4872
553
    }
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
553
    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
553
    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
553
    EB_DELETE(enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr);
4904
553
    EB_NO_THROW_NEW(enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr,
4905
553
                    svt_aom_prediction_structure_group_ctor);
4906
553
    if (!enc_handle->scs_instance->enc_ctx->prediction_structure_group_ptr) {
4907
0
        return EB_ErrorInsufficientResources;
4908
0
    }
4909
553
    return_error = load_default_buffer_configuration_settings(scs);
4910
4911
553
    svt_av1_print_lib_params(scs);
4912
4913
    // free frame scale events after copy to encoder
4914
553
    if (config_struct->frame_scale_evts.resize_denoms) {
4915
0
        EB_FREE(config_struct->frame_scale_evts.resize_denoms);
4916
0
    }
4917
553
    if (config_struct->frame_scale_evts.resize_kf_denoms) {
4918
0
        EB_FREE(config_struct->frame_scale_evts.resize_kf_denoms);
4919
0
    }
4920
553
    if (config_struct->frame_scale_evts.start_frame_nums) {
4921
0
        EB_FREE(config_struct->frame_scale_evts.start_frame_nums);
4922
0
    }
4923
553
    memset(&config_struct->frame_scale_evts, 0, sizeof(SvtAv1FrameScaleEvts));
4924
4925
    // free sframe position list
4926
553
    if (config_struct->sframe_posi.sframe_qps) {
4927
0
        EB_FREE(config_struct->sframe_posi.sframe_qps);
4928
0
    }
4929
553
    if (config_struct->sframe_posi.sframe_qp_offsets) {
4930
0
        EB_FREE(config_struct->sframe_posi.sframe_qp_offsets);
4931
0
    }
4932
553
    if (config_struct->sframe_posi.sframe_posis) {
4933
0
        EB_FREE(config_struct->sframe_posi.sframe_posis);
4934
0
    }
4935
553
    memset(&config_struct->sframe_posi, 0, sizeof(SvtAv1SFramePositions));
4936
4937
553
    return return_error;
4938
553
}
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
553
                                     uint8_t* source, int pass) {
5174
553
    EbErrorType return_error = EB_ErrorNone;
5175
5176
553
    EbPictureBufferDesc* input_pic             = (EbPictureBufferDesc*)destination;
5177
553
    EbPictureBufferDesc* y8b_input_picture_ptr = (EbPictureBufferDesc*)destination_y8b;
5178
553
    EbSvtIOFormat*       input_ptr             = (EbSvtIOFormat*)source;
5179
5180
553
    uint32_t luma_width  = (uint32_t)(input_pic->width - scs->max_input_pad_right);
5181
553
    uint32_t luma_height = (uint32_t)(input_pic->height - scs->max_input_pad_bottom);
5182
5183
553
    const uint8_t  subsampling_x = (input_pic->color_format == EB_YUV444 ? 0 : 1);
5184
553
    const uint8_t  subsampling_y = ((input_pic->color_format == EB_YUV444 || input_pic->color_format == EB_YUV422) ? 0
5185
553
                                                                                                                   : 1);
5186
553
    const uint32_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5187
553
    const uint32_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5188
5189
553
    if (SVT_EFFECTIVE_BIT_DEPTH(scs->static_config.encoder_bit_depth) == EB_EIGHT_BIT) {
5190
553
        svt_av1_copy_wxh_8bit(input_ptr->luma,
5191
553
                              input_ptr->y_stride,
5192
553
                              y8b_input_picture_ptr->y_buffer,
5193
553
                              input_pic->y_stride,
5194
553
                              luma_height,
5195
553
                              luma_width);
5196
553
        svt_av1_copy_wxh_8bit(
5197
553
            input_ptr->cb, input_ptr->cb_stride, input_pic->u_buffer, input_pic->u_stride, chroma_height, chroma_width);
5198
553
        svt_av1_copy_wxh_8bit(
5199
553
            input_ptr->cr, input_ptr->cr_stride, input_pic->v_buffer, input_pic->v_stride, chroma_height, chroma_width);
5200
553
    } 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
553
    return return_error;
5234
553
}
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
1.10k
                              EbBufferHeaderType* src, int pass) {
5389
    // Copy the higher level structure
5390
1.10k
    dst->n_alloc_len  = src->n_alloc_len;
5391
1.10k
    dst->n_filled_len = src->n_filled_len;
5392
1.10k
    dst->flags        = src->flags;
5393
1.10k
    dst->pts          = src->pts;
5394
1.10k
    dst->n_tick_count = src->n_tick_count;
5395
1.10k
    dst->size         = src->size;
5396
1.10k
    dst->qp           = src->qp;
5397
1.10k
    dst->pic_type     = src->pic_type;
5398
1.10k
    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
1.10k
    } else if (pass != ENCODE_FIRST_PASS) {
5404
        // Bypass copy for the unecessary picture in IPPP pass
5405
        // Copy the picture buffer
5406
1.10k
        if (src->p_buffer != NULL) {
5407
553
            copy_frame_buffer(scs, dst->p_buffer, dst_y8b->p_buffer, src->p_buffer, pass);
5408
            // Copy the metadata array
5409
553
            if (svt_aom_copy_metadata_buffer(dst, src->metadata) != EB_ErrorNone) {
5410
553
                dst->metadata = NULL;
5411
553
            }
5412
553
        }
5413
1.10k
    }
5414
5415
    // Copy the private data list
5416
1.10k
    if (src->p_app_private) {
5417
0
        copy_private_data_list(dst, src);
5418
1.10k
    } else {
5419
1.10k
        dst->p_app_private = NULL;
5420
1.10k
    }
5421
1.10k
}
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
1.10k
                                                EbHandle config_mutex) {
5426
1.10k
    EbPrivDataNode* node = (EbPrivDataNode*)input_ptr->p_app_private;
5427
1.10k
    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
1.10k
    return EB_ErrorNone;
5600
1.10k
}
5601
5602
/**********************************
5603
* Empty This Buffer
5604
**********************************/
5605
1.10k
EB_API EbErrorType svt_av1_enc_send_picture(EbComponentType* svt_enc_component, EbBufferHeaderType* p_buffer) {
5606
1.10k
    EbErrorType         return_val     = EB_ErrorNone;
5607
1.10k
    EbEncHandle*        enc_handle_ptr = (EbEncHandle*)svt_enc_component->p_component_private;
5608
1.10k
    EbObjectWrapper*    eb_wrapper_ptr;
5609
1.10k
    EbBufferHeaderType* app_hdr    = p_buffer;
5610
1.10k
    enc_handle_ptr->frame_received = true;
5611
5612
1.10k
    SequenceControlSet* scs = enc_handle_ptr->scs_instance->scs;
5613
1.10k
    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
1.10k
    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
1.10k
    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
1.10k
    EbObjectWrapper* y8b_wrapper;
5652
1.10k
    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
1.10k
    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
1.10k
    svt_object_inc_live_count(y8b_wrapper, 1);
5661
5662
    // svt_object_inc_live_count(y8b_wrapper, 1);
5663
5664
1.10k
    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
1.10k
    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
1.10k
    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
1.10k
    EbBufferHeaderType* lib_y8b_hdr = (EbBufferHeaderType*)y8b_wrapper->object_ptr;
5679
1.10k
    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
1.10k
    EbPictureBufferDesc*      input_pic      = (EbPictureBufferDesc*)lib_y8b_hdr->p_buffer;
5683
1.10k
    EbSvtAv1EncConfiguration* config         = &scs->static_config;
5684
1.10k
    bool                      is_16bit_input = SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > EB_EIGHT_BIT;
5685
5686
1.10k
    const uint8_t subsampling_x = (config->encoder_color_format == EB_YUV444 ? 0 : 1);
5687
1.10k
    const uint8_t subsampling_y =
5688
1.10k
        ((config->encoder_color_format == EB_YUV444 || config->encoder_color_format == EB_YUV422) ? 0 : 1);
5689
1.10k
    const size_t luma_width    = input_pic->width - scs->max_input_pad_right;
5690
1.10k
    const size_t luma_height   = input_pic->height - scs->max_input_pad_bottom;
5691
1.10k
    const size_t chroma_width  = (luma_width + subsampling_x) >> subsampling_x;
5692
1.10k
    const size_t chroma_height = (luma_height + subsampling_y) >> subsampling_y;
5693
1.10k
    const size_t read_size     = (luma_width * luma_height + 2 * chroma_width * chroma_height) << is_16bit_input;
5694
5695
1.10k
    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
1.10k
    } else {
5702
1.10k
        copy_input_buffer(scs, lib_reg_hdr, lib_y8b_hdr, app_hdr, 0);
5703
1.10k
    }
5704
5705
    //Take a new App-RessCoord command
5706
1.10k
    EbObjectWrapper* input_cmd_wrp;
5707
1.10k
    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
1.10k
    InputCommand* input_cmd_obj = (InputCommand*)input_cmd_wrp->object_ptr;
5713
    //Fill the command with two picture buffers
5714
1.10k
    input_cmd_obj->eb_input_wrapper_ptr = eb_wrapper_ptr;
5715
1.10k
    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
1.10k
    enc_handle_ptr->eos_received += p_buffer->flags & EB_BUFFERFLAG_EOS;
5719
    //Send to Lib
5720
1.10k
    svt_post_full_object(input_cmd_wrp);
5721
5722
1.10k
#if CONFIG_SINGLE_THREAD_KERNEL
5723
    // In single-thread mode, run the entire pipeline synchronously
5724
1.10k
    if (enc_handle_ptr->kernel_dispatcher.active) {
5725
0
        svt_kernel_dispatcher_run(&enc_handle_ptr->kernel_dispatcher);
5726
0
    }
5727
1.10k
#endif
5728
5729
1.10k
    return return_val;
5730
1.10k
}
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
2.21k
                                          unsigned char pic_send_done) {
5762
2.21k
    EbErrorType                     return_error   = EB_ErrorNone;
5763
2.21k
    EbEncHandle*                    enc_handle     = (EbEncHandle*)svt_enc_component->p_component_private;
5764
2.21k
    EbObjectWrapper*                eb_wrapper_ptr = NULL;
5765
2.21k
    EbBufferHeaderType*             packet;
5766
2.21k
    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
2.21k
    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
2.21k
    if (enc_handle->eos_sent) {
5775
553
        *p_buffer = NULL;
5776
553
        return EB_NoErrorEmptyQueue;
5777
553
    }
5778
5779
1.65k
    if (pic_send_done || cfg->pred_structure == LOW_DELAY) {
5780
1.10k
        svt_get_full_object(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
5781
1.10k
    } else {
5782
553
        svt_get_full_object_non_blocking(enc_handle->output_stream_buffer_consumer_fifo_ptr, &eb_wrapper_ptr);
5783
553
    }
5784
5785
1.65k
    if (eb_wrapper_ptr) {
5786
1.10k
        packet = (EbBufferHeaderType*)eb_wrapper_ptr->object_ptr;
5787
1.10k
        if (packet->flags & EB_BUFFERFLAG_ERROR_MASK) {
5788
0
            return_error = EB_ErrorMax;
5789
0
        }
5790
        // return the output stream buffer
5791
1.10k
        *p_buffer = packet;
5792
5793
        // check if we have reached the end of the output stream
5794
1.10k
        enc_handle->eos_sent += packet->flags & EB_BUFFERFLAG_EOS;
5795
5796
        // save the wrapper pointer for the release
5797
1.10k
        (*p_buffer)->wrapper_ptr = (void*)eb_wrapper_ptr;
5798
1.10k
    } else {
5799
553
        return_error = EB_NoErrorEmptyQueue;
5800
553
    }
5801
1.65k
    return return_error;
5802
2.21k
}
5803
5804
1.10k
EB_API void svt_av1_enc_release_out_buffer(EbBufferHeaderType** p_buffer) {
5805
1.10k
    if (p_buffer && (*p_buffer)->wrapper_ptr) {
5806
1.10k
        if ((*p_buffer)->p_buffer) {
5807
553
            EB_FREE((*p_buffer)->p_buffer);
5808
553
        }
5809
        // Release out put buffer back into the pool
5810
1.10k
        svt_release_object((EbObjectWrapper*)(*p_buffer)->wrapper_ptr);
5811
1.10k
    }
5812
1.10k
    return;
5813
1.10k
}
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
553
EB_API void svt_av1_print_version(void) {
5873
553
    SVT_INFO("-------------------------------------------\n");
5874
553
    SVT_INFO("SVT [version]:\tSVT-AV1 Encoder Lib %s\n", SVT_AV1_CVS_VERSION);
5875
553
    const char* compiler =
5876
553
#if defined(__clang__)
5877
553
        __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
553
        ;
5896
553
    SVT_INFO("SVT [build]  :\t%s %zu bit\n", compiler, sizeof(void*) * 8);
5897
553
#if !REPRODUCIBLE_BUILDS
5898
553
    SVT_INFO("LIB Build date: %s %s\n", __DATE__, __TIME__);
5899
553
#endif
5900
553
    SVT_INFO("-------------------------------------------\n");
5901
553
}
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
553
static EbErrorType init_svt_av1_encoder_handle(EbComponentType* hComponent) {
5919
553
    EbErrorType      return_error      = EB_ErrorNone;
5920
553
    EbComponentType* svt_enc_component = hComponent;
5921
553
    EbEncHandle*     handle;
5922
553
    svt_av1_print_version();
5923
5924
553
    enc_switch_to_real_time();
5925
5926
    // Set Component Size & Version
5927
553
    svt_enc_component->size = sizeof(EbComponentType);
5928
5929
553
    EB_NEW(handle, svt_enc_handle_ctor, svt_enc_component);
5930
553
    svt_enc_component->p_component_private = handle;
5931
5932
553
    return return_error;
5933
553
}
5934
5935
2.21k
static EbErrorType allocate_frame_buffer(SequenceControlSet* scs, EbBufferHeaderType* input_buffer, bool noy8b) {
5936
2.21k
    EbErrorType                 return_error = EB_ErrorNone;
5937
2.21k
    EbPictureBufferDescInitData input_pic_buf_desc_init_data;
5938
2.21k
    EbSvtAv1EncConfiguration*   config   = &scs->static_config;
5939
2.21k
    uint8_t                     is_16bit = SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > 8 ? 1 : 0;
5940
5941
2.21k
    input_pic_buf_desc_init_data.max_width = !(scs->max_input_luma_width % 8)
5942
2.21k
        ? scs->max_input_luma_width
5943
2.21k
        : scs->max_input_luma_width + (scs->max_input_luma_width % 8);
5944
5945
2.21k
    input_pic_buf_desc_init_data.max_height = !(scs->max_input_luma_height % 8)
5946
2.21k
        ? scs->max_input_luma_height
5947
2.21k
        : scs->max_input_luma_height + (scs->max_input_luma_height % 8);
5948
5949
2.21k
    input_pic_buf_desc_init_data.bit_depth    = (EbBitDepth)config->encoder_bit_depth;
5950
2.21k
    input_pic_buf_desc_init_data.color_format = (EbColorFormat)config->encoder_color_format;
5951
5952
2.21k
    input_pic_buf_desc_init_data.border = scs->border;
5953
5954
2.21k
    input_pic_buf_desc_init_data.split_mode = is_16bit ? true : false;
5955
5956
2.21k
    input_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_FULL_MASK;
5957
2.21k
    input_pic_buf_desc_init_data.is_16bit_pipeline  = 0;
5958
5959
    // Enhanced Picture Buffer
5960
2.21k
    {
5961
2.21k
        EbPictureBufferDesc* buf;
5962
2.21k
        if (!noy8b) {
5963
0
            EB_NEW(buf, svt_picture_buffer_desc_ctor, (EbPtr)&input_pic_buf_desc_init_data);
5964
2.21k
        } else {
5965
2.21k
            EB_NEW(buf, svt_picture_buffer_desc_ctor_noy8b, (EbPtr)&input_pic_buf_desc_init_data);
5966
2.21k
        }
5967
2.21k
        input_buffer->p_buffer = (uint8_t*)buf;
5968
2.21k
    }
5969
5970
0
    return return_error;
5971
2.21k
}
5972
5973
/*
5974
  allocate an input sample Luma-8bit buffer
5975
*/
5976
2.21k
static EbErrorType allocate_y8b_frame_buffer(SequenceControlSet* scs, EbBufferHeaderType* input_buffer) {
5977
2.21k
    EbErrorType                 return_error = EB_ErrorNone;
5978
2.21k
    EbPictureBufferDescInitData input_pic_buf_desc_init_data;
5979
2.21k
    EbSvtAv1EncConfiguration*   config   = &scs->static_config;
5980
2.21k
    uint8_t                     is_16bit = 0;
5981
5982
2.21k
    input_pic_buf_desc_init_data.max_width = !(scs->max_input_luma_width % 8)
5983
2.21k
        ? scs->max_input_luma_width
5984
2.21k
        : scs->max_input_luma_width + (scs->max_input_luma_width % 8);
5985
5986
2.21k
    input_pic_buf_desc_init_data.max_height   = !(scs->max_input_luma_height % 8)
5987
2.21k
          ? scs->max_input_luma_height
5988
2.21k
          : scs->max_input_luma_height + (scs->max_input_luma_height % 8);
5989
2.21k
    input_pic_buf_desc_init_data.bit_depth    = EB_EIGHT_BIT;
5990
2.21k
    input_pic_buf_desc_init_data.color_format = (EbColorFormat)config->encoder_color_format;
5991
5992
2.21k
    input_pic_buf_desc_init_data.border = scs->border;
5993
5994
2.21k
    input_pic_buf_desc_init_data.split_mode = is_16bit ? true : false;
5995
5996
2.21k
    input_pic_buf_desc_init_data.buffer_enable_mask = PICTURE_BUFFER_DESC_LUMA_MASK; //allocate for 8bit Luma only
5997
2.21k
    input_pic_buf_desc_init_data.is_16bit_pipeline  = 0;
5998
5999
    // Enhanced Picture Buffer
6000
2.21k
    {
6001
2.21k
        EbPictureBufferDesc* buf;
6002
2.21k
        EB_NEW(buf, svt_picture_buffer_desc_ctor, (EbPtr)&input_pic_buf_desc_init_data);
6003
2.21k
        input_buffer->p_buffer = (uint8_t*)buf;
6004
2.21k
    }
6005
6006
0
    return return_error;
6007
2.21k
}
6008
6009
/*
6010
  create a luma 8bit buffer descriptor
6011
*/
6012
2.21k
EbErrorType svt_input_y8b_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6013
2.21k
    EbBufferHeaderType* input_buffer;
6014
2.21k
    SequenceControlSet* scs = (SequenceControlSet*)object_init_data_ptr;
6015
6016
2.21k
    *object_dbl_ptr = NULL;
6017
2.21k
    EB_CALLOC(input_buffer, 1, sizeof(EbBufferHeaderType));
6018
2.21k
    *object_dbl_ptr = (EbPtr)input_buffer;
6019
    // Initialize Header
6020
2.21k
    input_buffer->size = sizeof(EbBufferHeaderType);
6021
6022
2.21k
    EbErrorType return_error = allocate_y8b_frame_buffer(scs, input_buffer);
6023
2.21k
    if (return_error != EB_ErrorNone) {
6024
0
        return return_error;
6025
0
    }
6026
6027
2.21k
    input_buffer->p_app_private = NULL;
6028
6029
2.21k
    return EB_ErrorNone;
6030
2.21k
}
6031
6032
/*
6033
  free a luma 8bit buffer descriptor
6034
*/
6035
2.21k
void svt_input_y8b_destroyer(EbPtr p) {
6036
2.21k
    EbBufferHeaderType*  obj = (EbBufferHeaderType*)p;
6037
2.21k
    EbPictureBufferDesc* buf = (EbPictureBufferDesc*)obj->p_buffer;
6038
2.21k
    if (buf) {
6039
2.21k
        EB_FREE_ALIGNED_ARRAY(buf->y_buffer_bit_inc);
6040
2.21k
        EB_FREE_ALIGNED_ARRAY(buf->u_buffer_bit_inc);
6041
2.21k
        EB_FREE_ALIGNED_ARRAY(buf->v_buffer_bit_inc);
6042
2.21k
    }
6043
6044
2.21k
    EB_DELETE(buf);
6045
2.21k
    EB_FREE(obj);
6046
2.21k
}
6047
6048
/**************************************
6049
* EbBufferHeaderType Constructor
6050
**************************************/
6051
2.21k
EbErrorType svt_input_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6052
2.21k
    EbBufferHeaderType* input_buffer;
6053
2.21k
    SequenceControlSet* scs = (SequenceControlSet*)object_init_data_ptr;
6054
6055
2.21k
    *object_dbl_ptr = NULL;
6056
2.21k
    EB_CALLOC(input_buffer, 1, sizeof(EbBufferHeaderType));
6057
2.21k
    *object_dbl_ptr = (EbPtr)input_buffer;
6058
    // Initialize Header
6059
2.21k
    input_buffer->size = sizeof(EbBufferHeaderType);
6060
6061
2.21k
    EbErrorType return_error = allocate_frame_buffer(scs, input_buffer, true);
6062
2.21k
    if (return_error != EB_ErrorNone) {
6063
0
        return return_error;
6064
0
    }
6065
6066
2.21k
    input_buffer->p_app_private = NULL;
6067
6068
2.21k
    return EB_ErrorNone;
6069
2.21k
}
6070
6071
2.21k
void svt_input_buffer_header_destroyer(EbPtr p) {
6072
2.21k
    EbBufferHeaderType*  obj = (EbBufferHeaderType*)p;
6073
2.21k
    EbPictureBufferDesc* buf = (EbPictureBufferDesc*)obj->p_buffer;
6074
2.21k
    if (buf) {
6075
2.21k
        EB_FREE_ALIGNED_ARRAY(buf->buffer_alloc);
6076
2.21k
        buf->buffer_alloc_sz  = 0;
6077
2.21k
        buf->y_buffer         = NULL;
6078
2.21k
        buf->u_buffer         = NULL;
6079
2.21k
        buf->v_buffer         = NULL;
6080
2.21k
        buf->y_buffer_bit_inc = NULL;
6081
2.21k
        buf->u_buffer_bit_inc = NULL;
6082
2.21k
        buf->v_buffer_bit_inc = NULL;
6083
2.21k
    }
6084
6085
2.21k
    EB_DELETE(buf);
6086
2.21k
    EB_FREE(obj);
6087
2.21k
}
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
7.74k
EbErrorType svt_output_buffer_header_creator(EbPtr* object_dbl_ptr, EbPtr object_init_data_ptr) {
6113
7.74k
    (void)object_init_data_ptr;
6114
7.74k
    EbBufferHeaderType* out_buf_ptr;
6115
6116
7.74k
    *object_dbl_ptr = NULL;
6117
7.74k
    EB_CALLOC(out_buf_ptr, 1, sizeof(EbBufferHeaderType));
6118
7.74k
    *object_dbl_ptr = (EbPtr)out_buf_ptr;
6119
6120
    // Initialize Header
6121
7.74k
    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
7.74k
    out_buf_ptr->p_app_private = NULL;
6125
6126
7.74k
    return EB_ErrorNone;
6127
7.74k
}
6128
6129
7.74k
void svt_output_buffer_header_destroyer(EbPtr p) {
6130
7.74k
    EbBufferHeaderType* obj = (EbBufferHeaderType*)p;
6131
7.74k
    EB_FREE(obj);
6132
7.74k
}
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
}