Coverage Report

Created: 2026-07-30 06:27

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