Coverage Report

Created: 2026-05-16 06:41

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