Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Globals/enc_settings.c
Line
Count
Source
1
/*
2
* Copyright(c) 2022 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 encoder settings API functions
13
14
/**************************************
15
 * Includes
16
 **************************************/
17
#include <stdbool.h>
18
#include <stdlib.h>
19
#include <stdio.h>
20
#include <stdint.h>
21
#include "EbVersion.h"
22
#include "definitions.h"
23
#include "EbSvtAv1Enc.h"
24
#include "EbSvtAv1Metadata.h"
25
#include "enc_settings.h"
26
#include "entropy_coding.h"
27
28
#include "svt_log.h"
29
#include "utility.h"
30
31
#ifdef _WIN32
32
#include <windows.h>
33
#else
34
#include <errno.h>
35
#include <pthread.h>
36
#include <unistd.h>
37
#endif
38
39
/******************************************
40
* Verify Settings
41
******************************************/
42
604
EbErrorType svt_av1_verify_settings(SequenceControlSet* scs) {
43
604
    EbErrorType               return_error = EB_ErrorNone;
44
604
    EbSvtAv1EncConfiguration* config       = &scs->static_config;
45
604
    if (config->enc_mode > MAX_ENC_PRESET || config->enc_mode < MIN_ENC_PRESET) {
46
0
        SVT_ERROR("EncoderMode must be in the range of [%d-%d]\n", MIN_ENC_PRESET, MAX_ENC_PRESET);
47
0
        return_error = EB_ErrorBadParameter;
48
0
    }
49
604
    if (scs->max_input_luma_width < 1) {
50
0
        SVT_ERROR("Source Width must be at least 1\n");
51
0
        return_error = EB_ErrorBadParameter;
52
0
    }
53
604
    if (scs->max_input_luma_height < 1) {
54
0
        SVT_ERROR("Source Height must be at least 1\n");
55
0
        return_error = EB_ErrorBadParameter;
56
0
    }
57
604
    if (config->pred_structure > RANDOM_ACCESS) {
58
0
        SVT_ERROR("Pred Structure must be [%d (ALL_INTRA), %d (LOW_DELAY), or %d (RANDOM_ACCESS)]\n",
59
0
                  ALL_INTRA,
60
0
                  LOW_DELAY,
61
0
                  RANDOM_ACCESS);
62
0
        return_error = EB_ErrorBadParameter;
63
0
    }
64
604
    if (config->pred_structure == LOW_DELAY && config->pass > 0) {
65
0
        SVT_ERROR("Multi-passes is not support with Low Delay mode \n");
66
0
        return_error = EB_ErrorBadParameter;
67
0
    }
68
604
    if (config->maximum_buffer_size_ms < 20 || config->maximum_buffer_size_ms > 10000) {
69
0
        SVT_ERROR("The maximum buffer size must be between [20, 10000]\n");
70
0
        return_error = EB_ErrorBadParameter;
71
0
    }
72
73
604
    if (config->starting_buffer_level_ms < 20 || config->starting_buffer_level_ms > 10000) {
74
0
        SVT_ERROR("The initial buffer size must be between [20, 10000] \n");
75
0
        return_error = EB_ErrorBadParameter;
76
604
    } else if (config->starting_buffer_level_ms >= config->maximum_buffer_size_ms) {
77
0
        SVT_WARN(
78
0
            "The initial buffer size must be less than maximum buffer size. Defaulting optimal "
79
0
            "buffer size to maximum buffer size - 1 (%u)\n",
80
0
            config->maximum_buffer_size_ms - 1);
81
0
        config->starting_buffer_level_ms = (config->maximum_buffer_size_ms - 1);
82
0
    }
83
84
604
    if (config->optimal_buffer_level_ms < 20 || config->optimal_buffer_level_ms > 10000) {
85
0
        SVT_ERROR("The optimal buffer size must be between [20, 10000]\n");
86
0
        return_error = EB_ErrorBadParameter;
87
604
    } else if (config->optimal_buffer_level_ms >= config->maximum_buffer_size_ms) {
88
0
        SVT_WARN(
89
0
            "The optimal buffer size must be less than maximum buffer size. Defaulting optimal "
90
0
            "buffer size to maximum buffer size - 1 (%u)\n",
91
0
            config->maximum_buffer_size_ms - 1);
92
0
        config->optimal_buffer_level_ms = (config->maximum_buffer_size_ms - 1);
93
0
    }
94
95
604
    if (config->over_shoot_pct > 100) {
96
0
        SVT_ERROR("The overshoot percentage must be between [0, 100] \n");
97
0
        return_error = EB_ErrorBadParameter;
98
0
    }
99
100
604
    if (config->mbr_over_shoot_pct > 100) {
101
0
        SVT_ERROR("The max bitrate overshoot percentage must be between [0, 100] \n");
102
0
        return_error = EB_ErrorBadParameter;
103
0
    }
104
105
604
    if (config->under_shoot_pct > 100) {
106
0
        SVT_ERROR("The undershoot percentage must be between [0, 100] \n");
107
0
        return_error = EB_ErrorBadParameter;
108
0
    }
109
110
604
    if (config->target_bit_rate > 100000000) {
111
0
        SVT_ERROR("The target bit rate must be between [0, 100000] kbps \n");
112
0
        return_error = EB_ErrorBadParameter;
113
0
    }
114
604
    if (config->max_bit_rate > 100000000) {
115
0
        SVT_ERROR("The maximum bit rate must be between [0, 100000] kbps \n");
116
0
        return_error = EB_ErrorBadParameter;
117
0
    }
118
604
    if (config->vbr_max_section_pct > 10000) {
119
0
        SVT_ERROR("The max section percentage must be between [0, 10000] \n");
120
0
        return_error = EB_ErrorBadParameter;
121
0
    }
122
123
604
    if (config->vbr_min_section_pct > 100) {
124
0
        SVT_ERROR("he min section percentage must be between [0, 100] \n");
125
0
        return_error = EB_ErrorBadParameter;
126
0
    }
127
604
    if (config->gop_constraint_rc &&
128
0
        ((config->rate_control_mode != SVT_AV1_RC_MODE_VBR) || config->intra_period_length < 119)) {
129
0
        SVT_ERROR(
130
0
            "Gop constraint rc is only supported with VBR mode when Gop size is "
131
0
            "greater than 119 \n");
132
0
        return_error = EB_ErrorBadParameter;
133
0
    }
134
604
    if (config->gop_constraint_rc) {
135
0
        SVT_WARN(
136
0
            "The GoP constraint RC mode is a work-in-progress project, and is only "
137
0
            "available for demos, experimentation, and further development uses and should not be "
138
0
            "used for benchmarking until fully implemented.\n");
139
0
    }
140
141
604
    if (config->force_key_frames &&
142
0
        (config->rate_control_mode == SVT_AV1_RC_MODE_CBR || config->pred_structure == LOW_DELAY)) {
143
0
        SVT_WARN(
144
0
            "Force key frames is now supported for lowdelay but the force_key_frames flag"
145
0
            " does not need to be set be on. Please follow the app samples shown by the FTR_KF_ON_FLY_SAMPLE"
146
0
            " macro on how to use it. force_key_frames will now be set to 0 \n");
147
0
        config->force_key_frames = 0;
148
0
    }
149
604
    if (config->force_key_frames && config->rate_control_mode == SVT_AV1_RC_MODE_VBR) {
150
0
        SVT_ERROR("Force key frames is not supported for VBR mode \n");
151
0
        return_error = EB_ErrorBadParameter;
152
0
    }
153
604
    if (config->rate_control_mode != SVT_AV1_RC_MODE_CQP_OR_CRF && (config->max_bit_rate != 0)) {
154
0
        SVT_ERROR("Max Bitrate only supported with CRF mode\n");
155
0
        return_error = EB_ErrorBadParameter;
156
0
    }
157
604
    if (config->rate_control_mode == SVT_AV1_RC_MODE_CBR && config->pred_structure != LOW_DELAY) {
158
0
        SVT_ERROR("CBR Rate control is currently not supported for RANDOM_ACCESS/ALL_INTRA, use VBR mode\n");
159
0
        return_error = EB_ErrorBadParameter;
160
0
    }
161
    // Ref-frame management validation: ABI cap + LD-CBR-only when enabled.
162
604
    if (config->max_managed_refs > 4) {
163
0
        SVT_ERROR("max_managed_refs must be in [0, 4] (got %u)\n", (unsigned)config->max_managed_refs);
164
0
        return_error = EB_ErrorBadParameter;
165
0
    }
166
604
    if (config->max_managed_refs > 0 && config->pred_structure != LOW_DELAY) {
167
0
        SVT_ERROR("max_managed_refs > 0 requires pred_structure == LOW_DELAY\n");
168
0
        return_error = EB_ErrorBadParameter;
169
0
    }
170
604
    if (config->max_managed_refs > 0 && config->rate_control_mode != SVT_AV1_RC_MODE_CBR) {
171
        // Only LD-CBR is implemented; LD-CRF's shifted lay1_offset would
172
        // collide with the STORE-safe slot pool. See pd_process.c.
173
0
        SVT_ERROR("max_managed_refs > 0 requires rate_control_mode == CBR (got %u)\n",
174
0
                  (unsigned)config->rate_control_mode);
175
0
        return_error = EB_ErrorBadParameter;
176
0
    }
177
604
    if (config->max_managed_refs > 0 && (config->sframe_dist > 0 || config->sframe_posi.sframe_posis)) {
178
        // An S-frame refreshes all 8 DPB slots and signals no refresh_frame_flags,
179
        // so a decoder unconditionally evicts every anchor. The encoder keeps them
180
        // (the STORE guard masks held slots out of the refresh), and the two DPB
181
        // views diverge from that point on.
182
0
        SVT_ERROR(
183
0
            "max_managed_refs > 0 is not supported with switch frames "
184
0
            "(sframe_dist=%d sframe_num=%u)\n",
185
0
            config->sframe_dist,
186
0
            (unsigned)config->sframe_posi.sframe_num);
187
0
        return_error = EB_ErrorBadParameter;
188
0
    }
189
604
    if (scs->allintra && (config->sframe_dist > 0 || config->sframe_posi.sframe_posis)) {
190
0
        SVT_ERROR("Switch frames are not supported with all-intra or AVIF coding\n");
191
0
        return_error = EB_ErrorBadParameter;
192
0
    }
193
    // Runtime MG-size change: ABI cap, restricted to where MG_SIZE_CHANGE_EVENT
194
    // is accepted, and never below the level count already configured.
195
604
    if (config->max_hierarchical_levels > 2) {
196
0
        SVT_ERROR("max_hierarchical_levels must be in [0, 2] (got %u)\n", (unsigned)config->max_hierarchical_levels);
197
0
        return_error = EB_ErrorBadParameter;
198
0
    }
199
604
    if (config->max_hierarchical_levels > 0 &&
200
0
        !(config->rtc && config->pred_structure == LOW_DELAY && config->rate_control_mode == SVT_AV1_RC_MODE_CBR)) {
201
0
        SVT_ERROR("max_hierarchical_levels > 0 requires RTC low-delay CBR\n");
202
0
        return_error = EB_ErrorBadParameter;
203
0
    }
204
604
    if (config->max_hierarchical_levels > 0 && config->max_hierarchical_levels < config->hierarchical_levels) {
205
0
        SVT_ERROR("max_hierarchical_levels (%u) must be >= hierarchical_levels (%u)\n",
206
0
                  (unsigned)config->max_hierarchical_levels,
207
0
                  (unsigned)config->hierarchical_levels);
208
0
        return_error = EB_ErrorBadParameter;
209
0
    }
210
604
    if (config->max_allowed_consecutive_frames_skips > 0 &&
211
0
        !(config->rtc && config->pred_structure == LOW_DELAY && config->rate_control_mode == SVT_AV1_RC_MODE_CBR)) {
212
0
        SVT_ERROR("max_allowed_consecutive_frames_skips > 0 requires RTC low-delay CBR\n");
213
0
        return_error = EB_ErrorBadParameter;
214
0
    }
215
604
    if (config->rate_control_mode == SVT_AV1_RC_MODE_VBR && config->pred_structure == LOW_DELAY) {
216
0
        SVT_ERROR("VBR Rate control is currently not supported for LOW_DELAY, use CBR mode\n");
217
0
        return_error = EB_ErrorBadParameter;
218
0
    }
219
604
    if (config->rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF && config->target_bit_rate != DEFAULT_TBR) {
220
0
        SVT_ERROR("Target Bitrate only supported when --rc is  1/2 (VBR/CBR). Current --rc: %d\n",
221
0
                  config->rate_control_mode);
222
0
        return_error = EB_ErrorBadParameter;
223
0
    }
224
225
604
    if (config->tier > 1) {
226
0
        SVT_ERROR("Tier must be 0 (Main tier) or 1 (High tier)\n");
227
0
        return_error = EB_ErrorBadParameter;
228
0
    }
229
230
604
    if (scs->max_input_luma_width > 16384) {
231
0
        SVT_ERROR("Source Width must be less than or equal to 16384\n");
232
0
        return_error = EB_ErrorBadParameter;
233
0
    }
234
235
604
    if (scs->max_input_luma_height > 8704) {
236
0
        SVT_ERROR("Source Height must be less than or equal to 8704)\n");
237
0
        return_error = EB_ErrorBadParameter;
238
0
    }
239
240
604
    if (scs->seq_header.max_frame_width < 1) {
241
0
        SVT_ERROR("Forced Max Width must be at least 1\n");
242
0
        return_error = EB_ErrorBadParameter;
243
0
    }
244
604
    if (scs->seq_header.max_frame_height < 1) {
245
0
        SVT_ERROR("Forced Max Height must be at least 1\n");
246
0
        return_error = EB_ErrorBadParameter;
247
0
    }
248
604
    if (scs->seq_header.max_frame_width > 16384) {
249
0
        SVT_ERROR("Forced Max Width must be less than or equal to 16384\n");
250
0
        return_error = EB_ErrorBadParameter;
251
0
    }
252
604
    if (scs->seq_header.max_frame_height > 8704) {
253
0
        SVT_ERROR("Forced Max Height must be less than or equal to 8704)\n");
254
0
        return_error = EB_ErrorBadParameter;
255
0
    }
256
257
    // This is not an AV1 spec limitation, but an implementation limitation in the encoder
258
    // This check will stay in place until restoration filtering can handle these dimensions
259
604
    if ((scs->max_input_luma_width >= 1 && scs->max_input_luma_width < 64) ||
260
532
        (scs->max_input_luma_height >= 1 && scs->max_input_luma_height < 64)) {
261
93
        if (config->aq_mode != 0) {
262
55
            SVT_WARN("AQ mode %i is unsupported with source dimensions (%i / %i), setting AQ mode to 0\n",
263
55
                     config->aq_mode,
264
55
                     scs->max_input_luma_width,
265
55
                     scs->max_input_luma_height);
266
55
            config->aq_mode = 0;
267
55
        }
268
93
        if (config->enable_restoration_filtering != 0) {
269
93
            SVT_WARN(
270
93
                "Restoration Filtering is unsupported with source dimensions (%i / %i), disabling "
271
93
                "Restoration Filtering\n",
272
93
                scs->max_input_luma_width,
273
93
                scs->max_input_luma_height);
274
93
            config->enable_restoration_filtering = 0;
275
93
        }
276
93
    }
277
278
604
    if ((scs->max_input_luma_width > scs->seq_header.max_frame_width) ||
279
604
        (scs->max_input_luma_height > scs->seq_header.max_frame_height)) {
280
0
        SVT_ERROR(
281
0
            "Source Width/Height must be less than or equal to Forced Max "
282
0
            "Width/Height\n");
283
0
        return_error = EB_ErrorBadParameter;
284
0
    }
285
286
604
    if (config->level != 0) {
287
0
        BitstreamLevel bl;
288
0
        bl.major = config->level / 10;
289
0
        bl.minor = config->level % 10;
290
        // Defined AV1 levels only have major versions 2-9 and minor versions 0-3
291
0
        if (bl.minor > LEVEL_MINOR_MAX || bl.major < LEVEL_MAJOR_MIN || bl.major > LEVEL_MAJOR_MAX) {
292
0
            SVT_ERROR("Invalid or undefined level specified: %d.%d. See AV1 spec Annex A for defined levels.\n",
293
0
                      bl.major,
294
0
                      bl.minor);
295
0
            return_error = EB_ErrorBadParameter;
296
0
        } else {
297
            // Some levels in the allowable range are undefined by the spec.
298
0
            const uint8_t seq_level_idx = major_minor_to_seq_level_idx(bl);
299
0
            if (!is_valid_seq_level_idx(seq_level_idx)) {
300
0
                SVT_ERROR("Invalid or undefined level specified: %d.%d. See AV1 spec Annex A for defined levels.\n",
301
0
                          bl.major,
302
0
                          bl.minor);
303
0
                return_error = EB_ErrorBadParameter;
304
0
            }
305
0
        }
306
0
    }
307
308
604
    if (config->qp > MAX_QP_VALUE) {
309
0
        SVT_ERROR("%s must be [0 - %d]\n", config->aq_mode ? "CRF" : "QP", MAX_QP_VALUE);
310
0
        return_error = EB_ErrorBadParameter;
311
0
    }
312
313
604
    if ((config->qp == MAX_QP_VALUE && config->extended_crf_qindex_offset > (7 * 4))) {
314
0
        SVT_ERROR("%s must be [0 - %d]\n", "CRF", 70);
315
0
        return_error = EB_ErrorBadParameter;
316
0
    }
317
318
604
    if (config->hierarchical_levels > 5) {
319
0
        SVT_ERROR("Hierarchical Levels supported: [0-5]\n");
320
0
        return_error = EB_ErrorBadParameter;
321
604
    } else {
322
2.41k
        for (uint8_t i = 0; i < config->hierarchical_levels + 1; ++i) {
323
1.81k
            if (config->qindex_offsets[i] < -64 || config->qindex_offsets[i] > 63) {
324
0
                SVT_ERROR(
325
0
                    "Invalid qindex_offsets for hierarchical level %d. Found %d, qindex_offsets must be [-64 - 63]\n",
326
0
                    i,
327
0
                    config->qindex_offsets[i]);
328
0
                return_error = EB_ErrorBadParameter;
329
0
            }
330
1.81k
        }
331
2.41k
        for (uint8_t i = 0; i < config->hierarchical_levels + 1; ++i) {
332
1.81k
            if (config->chroma_qindex_offsets[i] < -64 || config->chroma_qindex_offsets[i] > 63) {
333
0
                SVT_ERROR(
334
0
                    "Invalid chroma_qindex_offsets for hierarchical level %d. Found %d, chroma_qindex_offsets must be "
335
0
                    "[-64 - 63]\n",
336
0
                    i,
337
0
                    config->chroma_qindex_offsets[i]);
338
0
                return_error = EB_ErrorBadParameter;
339
0
            }
340
1.81k
        }
341
604
    }
342
604
    if ((config->intra_period_length < -2 || config->intra_period_length > 2 * ((1 << 30) - 1)) &&
343
0
        config->rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
344
0
        SVT_ERROR("The intra period must be [-2, 2^31-2]\n");
345
0
        return_error = EB_ErrorBadParameter;
346
0
    }
347
604
    if ((config->intra_period_length < 0) && config->rate_control_mode == SVT_AV1_RC_MODE_VBR) {
348
0
        SVT_ERROR("The intra period must be > 0 for RateControlMode %d\n", config->rate_control_mode);
349
0
        return_error = EB_ErrorBadParameter;
350
0
    }
351
352
604
    if (config->intra_refresh_type > 2 || config->intra_refresh_type < 1) {
353
0
        SVT_ERROR("Invalid intra Refresh Type [1-2]\n");
354
0
        return_error = EB_ErrorBadParameter;
355
0
    }
356
357
604
    if (config->enable_dlf_flag > 2) {
358
0
        SVT_ERROR("Invalid LoopFilterEnable. LoopFilterEnable must be [0 - 2]\n");
359
0
        return_error = EB_ErrorBadParameter;
360
0
    }
361
362
604
    if (config->rate_control_mode > SVT_AV1_RC_MODE_CBR &&
363
0
        (config->pass == ENC_FIRST_PASS || config->rc_stats_buffer.buf)) {
364
0
        SVT_ERROR("Only rate control mode 0~2 are supported for 2-pass \n");
365
0
        return_error = EB_ErrorBadParameter;
366
0
    }
367
    // Stats file is checked by the app in handle_stats_file, but must be re-checked here since ffmpeg calls
368
    // the library but not the app
369
604
    if (config->rate_control_mode == SVT_AV1_RC_MODE_VBR && config->pass == ENC_SECOND_PASS) {
370
0
        if (!config->rc_stats_buffer.buf) {
371
0
            SVT_ERROR("RC stats buffer not available \n");
372
0
            return_error = EB_ErrorBadParameter;
373
0
        } else if (config->rc_stats_buffer.sz == 0) {
374
0
            SVT_ERROR("RC stats buffer size is 0 \n");
375
0
            return_error = EB_ErrorBadParameter;
376
0
        }
377
0
    }
378
604
    if (config->profile > 2) {
379
0
        SVT_ERROR("The maximum allowed profile value is 2 \n");
380
0
        return_error = EB_ErrorBadParameter;
381
0
    }
382
383
    // Check if the current input video is conformant with the Level constraint
384
604
    if (scs->frame_rate > 240) {
385
0
        SVT_ERROR("The maximum allowed frame rate is 240 fps\n");
386
0
        return_error = EB_ErrorBadParameter;
387
0
    }
388
    // Check that the frame_rate is non-zero
389
604
    if (!scs->frame_rate) {
390
0
        SVT_ERROR("The frame rate should be greater than 0 fps \n");
391
0
        return_error = EB_ErrorBadParameter;
392
0
    }
393
604
    if (scs->static_config.frame_rate_numerator == 0 || scs->static_config.frame_rate_denominator == 0) {
394
0
        SVT_ERROR("The frame_rate_numerator and frame_rate_denominator must be greater than 0\n");
395
0
        return_error = EB_ErrorBadParameter;
396
0
    }
397
604
    if (config->recode_loop > 4) {
398
0
        SVT_ERROR("The recode_loop must be [0 - 4] \n");
399
0
        return_error = EB_ErrorBadParameter;
400
0
    }
401
604
    if (config->rate_control_mode > SVT_AV1_RC_MODE_CBR) {
402
0
        SVT_ERROR("The rate control mode must be [0 - 2] \n");
403
0
        return_error = EB_ErrorBadParameter;
404
0
    }
405
604
    if (config->look_ahead_distance > MAX_LAD && config->look_ahead_distance != (uint32_t)~0) {
406
0
        SVT_ERROR("The lookahead distance must be [0 - %d] \n", MAX_LAD);
407
408
0
        return_error = EB_ErrorBadParameter;
409
0
    }
410
604
    if ((unsigned)config->tile_rows > 6 || (unsigned)config->tile_columns > 6) {
411
0
        SVT_ERROR("Log2Tile rows/cols must be [0 - 6] \n");
412
0
        return_error = EB_ErrorBadParameter;
413
0
    }
414
604
    if ((1u << config->tile_rows) * (1u << config->tile_columns) > 128 || config->tile_columns > 4) {
415
0
        SVT_ERROR("MaxTiles is 128 and MaxTileCols is 16 (Annex A.3) \n");
416
0
        return_error = EB_ErrorBadParameter;
417
0
    }
418
604
    if (config->max_qp_allowed > MAX_QP_VALUE) {
419
0
        SVT_ERROR("MaxQpAllowed must be [0 - %d]\n", MAX_QP_VALUE);
420
0
        return_error = EB_ErrorBadParameter;
421
604
    } else if (config->min_qp_allowed > MAX_QP_VALUE) {
422
0
        SVT_ERROR("MinQpAllowed must be [0 - %d]\n", MAX_QP_VALUE);
423
0
        return_error = EB_ErrorBadParameter;
424
604
    } else if (config->min_qp_allowed > config->max_qp_allowed) {
425
0
        SVT_ERROR("MinQpAllowed must be smaller than or equal to MaxQpAllowed\n");
426
0
        return_error = EB_ErrorBadParameter;
427
0
    }
428
604
    if (config->use_fixed_qindex_offsets > 2) {
429
0
        SVT_ERROR("The use_fixed_qindex_offsets must be [0 - 2] \n");
430
0
        return_error = EB_ErrorBadParameter;
431
0
    }
432
433
604
    if (config->key_frame_qindex_offset < -64 || config->key_frame_qindex_offset > 63) {
434
0
        SVT_ERROR("Invalid key_frame_qindex_offset. key_frame_qindex_offset must be [-64 - 63]\n");
435
0
        return_error = EB_ErrorBadParameter;
436
0
    }
437
438
604
    if (config->key_frame_chroma_qindex_offset < -64 || config->key_frame_chroma_qindex_offset > 63) {
439
0
        SVT_ERROR(
440
0
            "Invalid key_frame_chroma_qindex_offset. key_frame_chroma_qindex_offset "
441
0
            "must be [-64 - 63]\n");
442
0
        return_error = EB_ErrorBadParameter;
443
0
    }
444
604
    if (config->luma_y_dc_qindex_offset < -64 || config->luma_y_dc_qindex_offset > 63) {
445
0
        SVT_ERROR(
446
0
            "Invalid luma_y_dc_qindex_offset. luma_y_dc_qindex_offset "
447
0
            "must be [-64 - 63]\n");
448
0
        return_error = EB_ErrorBadParameter;
449
0
    }
450
604
    if (config->chroma_u_dc_qindex_offset < -64 || config->chroma_u_dc_qindex_offset > 63) {
451
0
        SVT_ERROR(
452
0
            "Invalid chroma_u_dc_qindex_offset. chroma_u_dc_qindex_offset "
453
0
            "must be [-64 - 63]\n");
454
0
        return_error = EB_ErrorBadParameter;
455
0
    }
456
604
    if (config->chroma_u_ac_qindex_offset < -64 || config->chroma_u_ac_qindex_offset > 63) {
457
0
        SVT_ERROR(
458
0
            "Invalid chroma_u_ac_qindex_offset. chroma_u_ac_qindex_offset "
459
0
            "must be [-64 - 63]\n");
460
0
        return_error = EB_ErrorBadParameter;
461
0
    }
462
604
    if (config->chroma_v_dc_qindex_offset < -64 || config->chroma_v_dc_qindex_offset > 63) {
463
0
        SVT_ERROR(
464
0
            "Invalid chroma_v_dc_qindex_offset. chroma_v_dc_qindex_offset "
465
0
            "must be [-64 - 63]\n");
466
0
        return_error = EB_ErrorBadParameter;
467
0
    }
468
604
    if (config->chroma_v_ac_qindex_offset < -64 || config->chroma_v_ac_qindex_offset > 63) {
469
0
        SVT_ERROR(
470
0
            "Invalid chroma_v_ac_qindex_offset. chroma_v_ac_qindex_offset "
471
0
            "must be [-64 - 63]\n");
472
0
        return_error = EB_ErrorBadParameter;
473
0
    }
474
475
604
    if (config->startup_qp_offset < -63 || config->startup_qp_offset > 63) {
476
0
        SVT_ERROR("Invalid startup_qp_offset. startup_qp_offset must be [-63 - 63]\n");
477
0
        return_error = EB_ErrorBadParameter;
478
0
    }
479
604
    if (config->stat_report == 1) {
480
0
        SVT_WARN("Enabling StatReport can decrease encoding speed\n");
481
0
    }
482
483
604
    if (config->stat_report > 1) {
484
0
        SVT_ERROR("Invalid StatReport. StatReport must be [0 - 1]\n");
485
0
        return_error = EB_ErrorBadParameter;
486
0
    }
487
604
    if (config->screen_content_mode > 3) {
488
0
        SVT_ERROR("Invalid screen_content_mode. screen_content_mode must be [0 - 3]\n");
489
0
        return_error = EB_ErrorBadParameter;
490
0
    }
491
492
604
    if (scs->static_config.aq_mode > 2) {
493
0
        SVT_ERROR("Invalid adaptive quantization (AQ) mode. AQ mode must be [0-2]\n");
494
0
        return_error = EB_ErrorBadParameter;
495
0
    }
496
#if SVT_RTC_OR_MOBILE_BUILD
497
    // RTC and MOBILE builds code the MD decisions without the EncDec pass (encode_b()): reject what turns the bypass
498
    // off, segmentation (AQ mode 1, ROI maps) and 10-bit input at M7 (svt_aom_get_bypass_encdec_rtc()).
499
    if (config->aq_mode == 1 || config->enable_roi_map) {
500
        SVT_ERROR("AQ mode 1 and ROI maps (segmentation) are not supported by this build\n");
501
        return_error = EB_ErrorBadParameter;
502
    }
503
    if (SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > 8 && config->enc_mode <= ENC_M7) {
504
        SVT_ERROR("10-bit input at presets 7 and below is not supported by this build\n");
505
        return_error = EB_ErrorBadParameter;
506
    }
507
#endif
508
509
604
    if ((SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) != 8) &&
510
0
        (SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) != 10)) {
511
0
        SVT_ERROR("Encoder Bit Depth shall be only 8 or 10 \n");
512
0
        return_error = EB_ErrorBadParameter;
513
0
    }
514
#if !CONFIG_ENABLE_HIGH_BIT_DEPTH
515
    if (config->encoder_bit_depth != 8) {
516
        SVT_ERROR("Encoder bit depth %u is not supported by this 8-bit build\n", config->encoder_bit_depth);
517
        return_error = EB_ErrorBadParameter;
518
    }
519
#endif
520
#if !CONFIG_ENABLE_LOSSLESS
521
    if (config->lossless) {
522
        SVT_ERROR("Lossless coding is not supported by this build\n");
523
        return_error = EB_ErrorBadParameter;
524
    }
525
#else
526
    // RTC coding is not lossless at M9 and has no 8x8 blocks at M10+, which lossless frames need.
527
604
    if (config->lossless && SVT_RTC_TUNE(scs)) {
528
0
        SVT_ERROR("Lossless coding is not supported in RTC mode\n");
529
0
        return_error = EB_ErrorBadParameter;
530
0
    }
531
604
#endif
532
    // Check if the EncoderBitDepth is conformant with the Profile constraint
533
604
    if ((config->profile == 0 || config->profile == 1) && SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) > 10) {
534
0
        SVT_ERROR("The encoder bit depth shall be equal to 8 or 10 for Main/High Profile\n");
535
0
        return_error = EB_ErrorBadParameter;
536
0
    }
537
538
604
    if (config->encoder_color_format != EB_YUV420) {
539
0
        SVT_ERROR("Only support 420 now \n");
540
0
        return_error = EB_ErrorBadParameter;
541
0
    }
542
543
604
    if (config->profile == 0 && config->encoder_color_format > EB_YUV420) {
544
0
        SVT_ERROR("Non 420 color format requires profile 1 or 2\n");
545
0
        return_error = EB_ErrorBadParameter;
546
0
    }
547
548
604
    if (config->profile == 1 && config->encoder_color_format != EB_YUV444) {
549
0
        SVT_ERROR("Profile 1 requires 4:4:4 color format\n");
550
0
        return_error = EB_ErrorBadParameter;
551
0
    }
552
553
604
    if (config->profile == 2 && SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) <= 10 &&
554
0
        config->encoder_color_format != EB_YUV422) {
555
0
        SVT_ERROR("Profile 2 bit-depth < 10 requires 4:2:2 color format\n");
556
0
        return_error = EB_ErrorBadParameter;
557
0
    }
558
559
604
    if (config->use_cpu_flags & EB_CPU_FLAGS_INVALID) {
560
#ifdef ARCH_AARCH64
561
        SVT_ERROR(
562
            "param '--asm' have invalid value.\n"
563
            "Value should be [0 - 6] or [c, neon, crc32, neon_dotprod, neon_i8mm, sve, sve2, max]\n");
564
#else
565
0
        SVT_ERROR(
566
0
            "param '--asm' have invalid value.\n"
567
0
            "Value should be [0 - 11] or [c, mmx, sse, sse2, sse3, ssse3, sse4_1, sse4_2, avx, "
568
0
            "avx2, avx512, avx512icl, max]\n");
569
0
#endif
570
0
        return_error = EB_ErrorBadParameter;
571
0
    }
572
573
    // HBD mode decision
574
604
    if (scs->enable_hbd_mode_decision < (int8_t)(-1) || scs->enable_hbd_mode_decision > 2) {
575
0
        SVT_ERROR("Invalid HBD mode decision flag [-1 - 2], your input: %d\n", scs->enable_hbd_mode_decision);
576
0
        return_error = EB_ErrorBadParameter;
577
0
    }
578
579
    // CDEF
580
604
    if (config->cdef_level > 10 || config->cdef_level < -1) {
581
0
        SVT_ERROR("Invalid CDEF level [0 - 10, -1 for auto], your input: %d\n", config->cdef_level);
582
0
        return_error = EB_ErrorBadParameter;
583
0
    }
584
585
    // Restoration Filtering
586
604
    if (config->enable_restoration_filtering != 0 && config->enable_restoration_filtering != 1 &&
587
511
        config->enable_restoration_filtering != -1) {
588
0
        SVT_ERROR("Invalid restoration flag [0 - 1, -1 for auto], your input: %d\n",
589
0
                  config->enable_restoration_filtering);
590
0
        return_error = EB_ErrorBadParameter;
591
0
    }
592
593
604
    if (config->enable_mfmv != 0 && config->enable_mfmv != 1 && config->enable_mfmv != -1) {
594
0
        SVT_ERROR(
595
0
            "Invalid motion field motion vector flag [0/1 or -1 for auto], your "
596
0
            "input: %d\n",
597
0
            config->enable_mfmv);
598
0
        return_error = EB_ErrorBadParameter;
599
0
    }
600
604
    if (config->fast_decode > 2) {
601
0
        SVT_ERROR(
602
0
            "Invalid fast decode flag [0 - 2, 0 for no decoder-targeted optimization], your "
603
0
            "input: %d\n",
604
0
            config->fast_decode);
605
0
        return_error = EB_ErrorBadParameter;
606
0
    }
607
604
    if (config->tune > TUNE_VMAF) {
608
0
        SVT_ERROR(
609
0
            "Invalid tune flag [0 - 5, 0 for VQ, 1 for PSNR, 2 for SSIM, 3 for IQ, 4 for MS_SSIM, and 5 for VMAF], "
610
0
            "your input: "
611
0
            "%d\n",
612
0
            config->tune);
613
0
        return_error = EB_ErrorBadParameter;
614
0
    }
615
    // RC: SSIM, IQ, MS_SSIM, VMAF -> CRF only (VBR, CBR not supported)
616
604
    if (config->tune == TUNE_SSIM || config->tune == TUNE_IQ || config->tune == TUNE_MS_SSIM ||
617
604
        config->tune == TUNE_VMAF) {
618
0
        if (config->rate_control_mode != 0) {
619
0
            SVT_ERROR("Tune %s only supports CRF rate control mode\n",
620
0
                      config->tune == TUNE_SSIM       ? "SSIM"
621
0
                          : config->tune == TUNE_IQ   ? "IQ"
622
0
                          : config->tune == TUNE_VMAF ? "VMAF"
623
0
                                                      : "MS_SSIM");
624
0
            return_error = EB_ErrorBadParameter;
625
0
        }
626
0
    }
627
628
    // pred_struct: SSIM, MS_SSIM -> ALL_INTRA and RA only (LOW_DELAY not supported)
629
604
    if (config->tune == TUNE_SSIM || config->tune == TUNE_MS_SSIM) {
630
0
        if (config->pred_structure == LOW_DELAY) {
631
0
            SVT_ERROR("Tune %s only supports all-intra and random access prediction structures\n",
632
0
                      config->tune == TUNE_SSIM ? "SSIM" : "MS_SSIM");
633
0
            return_error = EB_ErrorBadParameter;
634
0
        }
635
0
    }
636
637
    // pred_struct: VMAF -> RA only (ALL_INTRA and LOW_DELAY not supported)
638
604
    if (config->tune == TUNE_VMAF && (config->pred_structure == ALL_INTRA || config->pred_structure == LOW_DELAY)) {
639
0
        SVT_ERROR("Tune VMAF only supports random access prediction structure\n");
640
0
        return_error = EB_ErrorBadParameter;
641
0
    }
642
643
    // pred_struct: IQ -> ALL_INTRA and LOW_DELAY only (RA not supported); LOW_DELAY is experimental
644
604
    if (config->tune == TUNE_IQ && config->pred_structure == RANDOM_ACCESS) {
645
0
        SVT_ERROR("Tune IQ only supports all-intra and low delay (experimental) prediction structures\n");
646
0
        return_error = EB_ErrorBadParameter;
647
0
    }
648
604
    if (config->tune == TUNE_IQ && config->pred_structure == LOW_DELAY) {
649
0
        SVT_WARN("Tune IQ with low delay prediction structure is experimental\n");
650
0
    }
651
652
604
    if (config->superres_mode > SUPERRES_AUTO) {
653
0
        SVT_ERROR("invalid superres-mode %d, should be in the range [%d - %d]\n",
654
0
                  config->superres_mode,
655
0
                  SUPERRES_NONE,
656
0
                  SUPERRES_AUTO);
657
0
        return_error = EB_ErrorBadParameter;
658
0
    }
659
604
    if (config->superres_mode > 0 && ((config->rc_stats_buffer.sz || config->pass == ENC_FIRST_PASS))) {
660
0
        SVT_ERROR("superres is not supported for 2-pass\n");
661
0
        return_error = EB_ErrorBadParameter;
662
0
    }
663
664
604
    if (config->superres_qthres > MAX_QP_VALUE) {
665
0
        SVT_ERROR("Invalid superres-qthres %d, should be in the range [%d - %d]\n",
666
0
                  config->superres_qthres,
667
0
                  MIN_QP_VALUE,
668
0
                  MAX_QP_VALUE);
669
0
        return_error = EB_ErrorBadParameter;
670
0
    }
671
672
604
    if (config->superres_kf_qthres > MAX_QP_VALUE) {
673
0
        SVT_ERROR("Invalid superres-kf-qthres %d, should be in the range [%d - %d]\n",
674
0
                  config->superres_kf_qthres,
675
0
                  MIN_QP_VALUE,
676
0
                  MAX_QP_VALUE);
677
0
        return_error = EB_ErrorBadParameter;
678
0
    }
679
680
604
    if (config->superres_kf_denom < MIN_SUPERRES_DENOM || config->superres_kf_denom > MAX_SUPERRES_DENOM) {
681
0
        SVT_ERROR("Invalid superres-kf-denom %d, should be in the range [%d - %d]\n",
682
0
                  config->superres_kf_denom,
683
0
                  MIN_SUPERRES_DENOM,
684
0
                  MAX_SUPERRES_DENOM);
685
0
        return_error = EB_ErrorBadParameter;
686
0
    }
687
688
604
    if (config->superres_denom < MIN_SUPERRES_DENOM || config->superres_denom > MAX_SUPERRES_DENOM) {
689
0
        SVT_ERROR("Invalid superres-denom %d, should be in the range [%d - %d]\n",
690
0
                  config->superres_denom,
691
0
                  MIN_SUPERRES_DENOM,
692
0
                  MAX_SUPERRES_DENOM);
693
0
        return_error = EB_ErrorBadParameter;
694
0
    }
695
696
604
    if (config->resize_mode > RESIZE_RANDOM_ACCESS) {
697
0
        SVT_ERROR("Invalid resize-mode %d, should be in the range [%d - %d]\n",
698
0
                  config->resize_mode,
699
0
                  RESIZE_NONE,
700
0
                  RESIZE_RANDOM_ACCESS);
701
0
        return_error = EB_ErrorBadParameter;
702
0
    }
703
704
604
    if (config->resize_kf_denom < MIN_RESIZE_DENOM || config->resize_kf_denom > MAX_RESIZE_DENOM) {
705
0
        SVT_ERROR("Invalid resize-kf-denom %d, should be in the range [%d - %d]\n",
706
0
                  config->resize_kf_denom,
707
0
                  MIN_RESIZE_DENOM,
708
0
                  MAX_RESIZE_DENOM);
709
0
        return_error = EB_ErrorBadParameter;
710
0
    }
711
712
604
    if (config->resize_denom < MIN_RESIZE_DENOM || config->resize_denom > MAX_RESIZE_DENOM) {
713
0
        SVT_ERROR("Invalid resize-denom %d, should be in the range [%d - %d]\n",
714
0
                  config->resize_denom,
715
0
                  MIN_RESIZE_DENOM,
716
0
                  MAX_RESIZE_DENOM);
717
0
        return_error = EB_ErrorBadParameter;
718
0
    }
719
720
604
    if (config->matrix_coefficients == 0 && config->encoder_color_format != EB_YUV444) {
721
0
        SVT_ERROR(
722
0
            "Identity matrix (matrix_coefficient = 0) may be used only with 4:4:4 "
723
0
            "color format.\n");
724
0
        return_error = EB_ErrorBadParameter;
725
0
    }
726
727
604
    if (config->rate_control_mode == SVT_AV1_RC_MODE_VBR && config->intra_period_length == -1) {
728
0
        SVT_ERROR(
729
0
            "keyint = -1 is not supported for modes other than CRF rate control "
730
0
            "encoding modes.\n");
731
0
        return_error = EB_ErrorBadParameter;
732
0
    }
733
    // Block the use of M4 or lower for resolutions higher than 4K, unless allintra coding is used (due to memory constraints)
734
604
    if (!scs->allintra && (uint64_t)(scs->max_input_luma_width * scs->max_input_luma_height) > INPUT_SIZE_4K_TH &&
735
0
        config->enc_mode <= ENC_M4) {
736
0
        SVT_ERROR("8k+ resolution support is limited to M5 and faster presets.\n");
737
0
        return_error = EB_ErrorBadParameter;
738
0
    }
739
604
    if (config->pass > 0 && scs->static_config.enable_overlays) {
740
0
        SVT_ERROR(
741
0
            "The overlay frames feature is currently not supported with multi-pass "
742
0
            "encoding\n");
743
0
        return_error = EB_ErrorBadParameter;
744
0
    }
745
604
    int pass = config->pass;
746
747
604
    if (pass < 0 || pass > 2) {
748
0
        SVT_ERROR("%d pass encode is not supported. --pass has a range of [0-2]\n", pass);
749
0
        return_error = EB_ErrorBadParameter;
750
0
    }
751
752
604
    if (config->intra_refresh_type != 2 && pass > 0) {
753
0
        SVT_ERROR("Multi-pass encode only supports closed-gop configurations.\n");
754
0
        return_error = EB_ErrorBadParameter;
755
0
    }
756
604
    if (config->intra_refresh_type == SVT_AV1_FWDKF_REFRESH && config->rate_control_mode == SVT_AV1_RC_MODE_CBR) {
757
0
        SVT_ERROR("Forward key frames (intra refresh type 1) are not supported with CBR.\n");
758
0
        return_error = EB_ErrorBadParameter;
759
0
    }
760
604
    if (config->pass > 1 && config->rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
761
0
        SVT_ERROR("CRF does not support multi-pass. Use single pass.\n");
762
0
        return_error = EB_ErrorBadParameter;
763
0
    }
764
765
604
    if (config->aq_mode == 0 && config->rate_control_mode) {
766
0
        SVT_ERROR("Adaptive quantization can not be turned OFF when RC ON\n");
767
0
        return_error = EB_ErrorBadParameter;
768
0
    }
769
770
604
    if (config->sframe_dist < 0) {
771
0
        SVT_ERROR("Switch frame interval must be >= 0\n");
772
0
        return_error = EB_ErrorBadParameter;
773
0
    }
774
604
    if (config->sframe_dist > 0 && config->hierarchical_levels == 0) {
775
0
        SVT_ERROR("Switch frame feature does not support flat IPPP\n");
776
0
        return_error = EB_ErrorBadParameter;
777
0
    }
778
604
    if (config->sframe_dist > 0 &&
779
0
        (config->sframe_mode < SFRAME_STRICT_BASE || config->sframe_mode > SFRAME_DEC_POSI_BASE)) {
780
0
        SVT_ERROR("Invalid switch frame mode %d, should be in the range [%d - %d]\n",
781
0
                  config->sframe_mode,
782
0
                  SFRAME_STRICT_BASE,
783
0
                  SFRAME_DEC_POSI_BASE);
784
0
        return_error = EB_ErrorBadParameter;
785
0
    }
786
604
    if (config->sframe_posi.sframe_posis && !IS_SFRAME_FLEXIBLE_INSERT(config->sframe_mode)) {
787
0
        SVT_ERROR("S-Frame positions are only supported in S-Frame Flexible ARF mode\n");
788
0
        return_error = EB_ErrorBadParameter;
789
0
    }
790
604
    if (config->sframe_posi.sframe_qp_num && config->rate_control_mode != SVT_AV1_RC_MODE_CQP_OR_CRF) {
791
0
        SVT_ERROR("S-Frame QP feature only supports CRF/CQP rate control mode\n");
792
0
        return_error = EB_ErrorBadParameter;
793
0
    }
794
604
    if ((config->sframe_posi.sframe_qps && config->sframe_posi.sframe_qp_offsets) ||
795
604
        (config->sframe_qp > 0 && config->sframe_qp_offset != 0)) {
796
0
        SVT_ERROR("S-Frame QP feature cannot support QP value and QP offset at same time\n");
797
0
        return_error = EB_ErrorBadParameter;
798
0
    }
799
800
    /* Warnings about the use of features that are incomplete */
801
604
    if (config->aq_mode == 1) {
802
0
        SVT_WARN(
803
0
            "The adaptive quantization mode using segmentation is at a support level "
804
0
            "only to be available for demos, experimentation, and further development uses and "
805
0
            "should not be used for benchmarking until fully implemented.\n");
806
0
    }
807
808
    // color description
809
604
    if (config->color_primaries == 0 || config->color_primaries == 3 ||
810
604
        (config->color_primaries >= 13 && config->color_primaries <= 21) || config->color_primaries > 22) {
811
0
        SVT_WARN("Value %u for color_primaries is reserved and not recommended for usage.\n", config->color_primaries);
812
0
    }
813
604
    if (config->transfer_characteristics == 0 || config->transfer_characteristics == 3 ||
814
604
        config->transfer_characteristics > 18) {
815
0
        SVT_WARN("Value %u for transfer_characteristics is reserved and not recommended for usage.\n",
816
0
                 config->transfer_characteristics);
817
0
    }
818
819
604
    if (config->matrix_coefficients == 3 || config->matrix_coefficients > 14) {
820
0
        SVT_WARN("Value %u for matrix_coefficients is reserved and not recommended for usage.\n",
821
0
                 config->matrix_coefficients);
822
0
    }
823
824
604
    if (config->chroma_sample_position < EB_CSP_UNKNOWN || config->chroma_sample_position > EB_CSP_COLOCATED) {
825
0
        if (config->chroma_sample_position != EB_CSP_RESERVED) {
826
0
            SVT_ERROR("Chroma sample position %d is unknown.\n", config->chroma_sample_position);
827
0
            return_error = EB_ErrorBadParameter;
828
0
        } else {
829
0
            SVT_WARN(
830
0
                "Value %d for chroma_sample_position is reserved "
831
0
                "and not recommended for usage.\n",
832
0
                config->chroma_sample_position);
833
0
        }
834
0
    }
835
836
604
    if (config->film_grain_denoise_strength > 0 && config->enc_mode > 6) {
837
0
        SVT_WARN(
838
0
            "It is recommended to not use Film Grain for presets greater than 6 as it "
839
0
            "produces a significant compute overhead. This combination should only be used for "
840
0
            "debug purposes.\n");
841
0
    }
842
843
604
    if (config->film_grain_denoise_strength > 50) {
844
0
        SVT_ERROR(
845
0
            "Film grain denoise strength is only supported for values between "
846
0
            "[0,50]\n");
847
0
        return_error = EB_ErrorBadParameter;
848
0
    }
849
850
604
    if (config->film_grain_denoise_apply != 0 && config->film_grain_denoise_apply != 1) {
851
0
        SVT_ERROR("The film grain denoise apply signal can only have a value of 0 or 1\n");
852
0
        return_error = EB_ErrorBadParameter;
853
0
    }
854
855
    // Limit 8K & 16K support
856
604
    if ((uint64_t)(scs->max_input_luma_width * scs->max_input_luma_height) > INPUT_SIZE_4K_TH) {
857
0
        SVT_WARN(
858
0
            "8K and higher resolution support is currently a work-in-progress "
859
0
            "project, and is only available for demos, experimentation, and further development "
860
0
            "uses and should not be used for benchmarking until fully implemented.\n");
861
0
    }
862
863
604
    if (config->pred_structure == LOW_DELAY) {
864
0
        if (config->tune == TUNE_VQ) {
865
0
            SVT_WARN("Tune 0 is not applicable for low-delay, tune will be forced to 1.\n");
866
0
            config->tune = TUNE_PSNR;
867
0
        }
868
869
0
        if (config->superres_mode != 0) {
870
0
            SVT_ERROR("Superres is not supported for low-delay.\n");
871
0
            return_error = EB_ErrorBadParameter;
872
0
        }
873
874
0
        if (config->enable_overlays) {
875
0
            SVT_ERROR("Overlay is not supported for low-delay.\n");
876
0
            return_error = EB_ErrorBadParameter;
877
0
        }
878
0
    }
879
880
604
    if (!config->rtc && config->enc_mode >= ENC_M10) {
881
0
        SVT_WARN("Non-RTC M10+ are meant for automation tooling usage. Visual artifacts may occur otherwise.\n");
882
0
    }
883
884
604
    if (scs->static_config.scene_change_detection) {
885
0
        scs->static_config.scene_change_detection = 0;
886
0
        SVT_WARN(
887
0
            "SVT-AV1 has an integrated mode decision mechanism to handle scene changes and will "
888
0
            "not insert a key frame at scene changes\n");
889
0
    }
890
604
    if ((config->tile_columns > 0 || config->tile_rows > 0)) {
891
604
        SVT_WARN(
892
604
            "If you are using tiles with the intent of increasing the decoder speed, please also "
893
604
            "consider using --fast-decode 1 or 2, especially if the intended decoder is running with "
894
604
            "limited multi-threading capabilities.\n");
895
604
    }
896
604
    if (config->tune == TUNE_VQ && config->fast_decode > 0) {
897
0
        SVT_WARN(
898
0
            "--fast-decode has been developed and optimized with --tune 1. "
899
0
            "Please use it with caution when encoding with --tune 0. You can also consider using "
900
0
            "--tile-columns 1 if you are targeting a high quality encode and a multi-core "
901
0
            "high-performance decoder HW\n");
902
0
    }
903
604
    if (config->enable_qm && config->min_qm_level > config->max_qm_level) {
904
0
        SVT_ERROR("Min quant matrix level must not greater than max quant matrix level\n");
905
0
        return_error = EB_ErrorBadParameter;
906
0
    }
907
604
    if (config->enable_qm && config->min_chroma_qm_level > config->max_chroma_qm_level) {
908
0
        SVT_ERROR("Min chroma quant matrix level must not greater than max chroma quant matrix level\n");
909
0
        return_error = EB_ErrorBadParameter;
910
0
    }
911
604
    if (config->startup_mg_size != 0 && config->startup_mg_size != 2 && config->startup_mg_size != 3 &&
912
0
        config->startup_mg_size != 4) {
913
0
        SVT_ERROR("Startup MG size supported [0, 2, 3, 4]\n");
914
0
        return_error = EB_ErrorBadParameter;
915
0
    }
916
604
    if (config->startup_mg_size > config->hierarchical_levels) {
917
0
        SVT_ERROR("Startup MG size must less than or equal to hierarchical levels\n");
918
0
        return_error = EB_ErrorBadParameter;
919
0
    }
920
604
    if (config->startup_mg_size != 0 && config->rate_control_mode != SVT_AV1_RC_MODE_CQP_OR_CRF) {
921
0
        SVT_ERROR("Startup MG size feature only supports CRF/CQP rate control mode\n");
922
0
        return_error = EB_ErrorBadParameter;
923
0
    }
924
604
    if (config->startup_qp_offset != 0 && config->rate_control_mode != 0) {
925
0
        SVT_ERROR("Startup QP offset only supports CRF/CQP rate control mode\n");
926
0
        return_error = EB_ErrorBadParameter;
927
0
    }
928
929
604
    if (config->variance_boost_strength < 1 || config->variance_boost_strength > 4) {
930
0
        SVT_ERROR("Variance Boost strength must be between 1 and 4\n");
931
0
        return_error = EB_ErrorBadParameter;
932
0
    }
933
934
604
    if (config->variance_octile < 1 || config->variance_octile > 8) {
935
0
        SVT_ERROR("Variance Boost octile must be between 1 and 8\n");
936
0
        return_error = EB_ErrorBadParameter;
937
0
    }
938
939
604
    if (config->tf_strength > 4) {
940
0
        SVT_ERROR("Temporal filtering strength must be between 0 and 4\n");
941
0
        return_error = EB_ErrorBadParameter;
942
0
    }
943
944
604
    if (config->variance_boost_curve > 2) {
945
0
        SVT_ERROR("Variance Boost curve must be between 0 and 2\n");
946
0
        return_error = EB_ErrorBadParameter;
947
0
    }
948
949
604
    if (config->luminance_qp_bias > 100) {
950
0
        SVT_ERROR("Luminance-based QP bias value must be between 0 and 100\n");
951
0
        return_error = EB_ErrorBadParameter;
952
0
    }
953
954
604
    if (config->sharpness > 7 || config->sharpness < -7) {
955
0
        SVT_ERROR("Sharpness level must be between -7 and 7\n");
956
0
        return_error = EB_ErrorBadParameter;
957
0
    }
958
959
604
    if (config->qp_scale_compress_strength > 3) {
960
0
        SVT_ERROR("QP scale compress strength must be between 0 and 3\n");
961
0
        return_error = EB_ErrorBadParameter;
962
0
    }
963
964
604
    if (config->max_tx_size != 32 && config->max_tx_size != 64) {
965
0
        SVT_ERROR("Supported Max TX size values are 32 and 64\n");
966
0
        return_error = EB_ErrorBadParameter;
967
0
    }
968
969
604
    if (config->ac_bias > 8.0 || config->ac_bias < 0.0) {
970
0
        SVT_ERROR("AC bias strength must be between 0.0 and 8.0\n");
971
0
        return_error = EB_ErrorBadParameter;
972
0
    }
973
974
    //User configurable High Bit Depth Mode Decision Setting
975
604
    if (config->hbd_mds < -1 || config->hbd_mds > 2) {
976
0
        SVT_ERROR("hbd-mds must be -1 (preset default), 0, 1, or 2\n");
977
0
        return_error = EB_ErrorBadParameter;
978
0
    }
979
980
604
    if (SVT_EFFECTIVE_BIT_DEPTH(config->encoder_bit_depth) == 8 && (config->hbd_mds == 1 || config->hbd_mds == 2)) {
981
0
        SVT_WARN("Please use 10-bit encoding if you want to take advantage of hbd-mds 1 and 2.\n");
982
0
        SVT_ERROR("Full high bit depth and hybrid 8/10 mode decision are not supported when encoder bit depth is 8\n");
983
0
        return_error = EB_ErrorBadParameter;
984
0
    }
985
986
604
    return return_error;
987
604
}
988
989
/**********************************
990
Set Default Library Params
991
**********************************/
992
604
EbErrorType svt_av1_set_default_params(EbSvtAv1EncConfiguration* config_ptr) {
993
604
    EbErrorType return_error = EB_ErrorNone;
994
995
604
    if (!config_ptr) {
996
0
        SVT_ERROR("The EbSvtAv1EncConfiguration structure is empty!\n");
997
0
        return EB_ErrorBadParameter;
998
0
    }
999
604
    config_ptr->frame_rate_numerator     = 60000;
1000
604
    config_ptr->frame_rate_denominator   = 1000;
1001
604
    config_ptr->encoder_bit_depth        = 8;
1002
604
    config_ptr->source_width             = 0;
1003
604
    config_ptr->source_height            = 0;
1004
604
    config_ptr->forced_max_frame_width   = 0;
1005
604
    config_ptr->forced_max_frame_height  = 0;
1006
604
    config_ptr->stat_report              = 0;
1007
604
    config_ptr->tile_rows                = DEFAULT;
1008
604
    config_ptr->tile_columns             = DEFAULT;
1009
604
    config_ptr->qp                       = DEFAULT_QP;
1010
604
    config_ptr->use_qp_file              = false;
1011
604
    config_ptr->use_fixed_qindex_offsets = 0;
1012
604
    memset(config_ptr->qindex_offsets, 0, sizeof(config_ptr->qindex_offsets));
1013
604
    config_ptr->key_frame_chroma_qindex_offset = 0;
1014
604
    config_ptr->key_frame_qindex_offset        = 0;
1015
604
    memset(config_ptr->chroma_qindex_offsets, 0, sizeof(config_ptr->chroma_qindex_offsets));
1016
604
    config_ptr->luma_y_dc_qindex_offset   = 0;
1017
604
    config_ptr->chroma_u_dc_qindex_offset = 0;
1018
604
    config_ptr->chroma_u_ac_qindex_offset = 0;
1019
604
    config_ptr->chroma_v_dc_qindex_offset = 0;
1020
604
    config_ptr->chroma_v_ac_qindex_offset = 0;
1021
1022
4.83k
    for (int i = 0; i < SVT_AV1_FRAME_UPDATE_TYPES; i++) {
1023
4.22k
        config_ptr->lambda_scale_factors[i] = 128;
1024
4.22k
    }
1025
1026
604
    config_ptr->scene_change_detection       = 0;
1027
604
    config_ptr->rate_control_mode            = SVT_AV1_RC_MODE_CQP_OR_CRF;
1028
604
    config_ptr->look_ahead_distance          = (uint32_t)~0;
1029
604
    config_ptr->target_bit_rate              = DEFAULT_TBR;
1030
604
    config_ptr->max_bit_rate                 = 0;
1031
604
    config_ptr->max_qp_allowed               = 63;
1032
604
    config_ptr->min_qp_allowed               = MIN_QP_AUTO;
1033
604
    config_ptr->aq_mode                      = 2;
1034
604
    config_ptr->enc_mode                     = ENC_M8;
1035
604
    config_ptr->intra_period_length          = -2;
1036
604
    config_ptr->multiply_keyint              = false;
1037
604
    config_ptr->intra_refresh_type           = 2;
1038
604
    config_ptr->hierarchical_levels          = HIERARCHICAL_LEVELS_AUTO;
1039
604
    config_ptr->pred_structure               = RANDOM_ACCESS;
1040
604
    config_ptr->enable_dlf_flag              = 1;
1041
604
    config_ptr->cdef_level                   = DEFAULT;
1042
604
    config_ptr->enable_restoration_filtering = DEFAULT;
1043
604
    config_ptr->enable_mfmv                  = DEFAULT;
1044
604
    config_ptr->enable_dg                    = 1;
1045
604
    config_ptr->fast_decode                  = 0;
1046
604
    config_ptr->encoder_color_format         = EB_YUV420;
1047
604
    config_ptr->rtc                          = 0;
1048
    // Rate control options
1049
    // Set the default value toward more flexible rate allocation
1050
604
    config_ptr->vbr_min_section_pct      = 0;
1051
604
    config_ptr->vbr_max_section_pct      = 2000;
1052
604
    config_ptr->under_shoot_pct          = (uint32_t)DEFAULT;
1053
604
    config_ptr->over_shoot_pct           = (uint32_t)DEFAULT;
1054
604
    config_ptr->mbr_over_shoot_pct       = 50;
1055
604
    config_ptr->max_intra_bitrate_pct    = 300;
1056
604
    config_ptr->max_inter_bitrate_pct    = 0;
1057
604
    config_ptr->gop_constraint_rc        = 0;
1058
604
    config_ptr->maximum_buffer_size_ms   = 1000; // default settings for CBR
1059
604
    config_ptr->starting_buffer_level_ms = 600; // default settings for CBR
1060
604
    config_ptr->optimal_buffer_level_ms  = 600; // default settings for CBR
1061
604
    config_ptr->recode_loop              = ALLOW_RECODE_DEFAULT;
1062
604
    config_ptr->screen_content_mode      = 2;
1063
604
    config_ptr->enable_intrabc           = true;
1064
1065
    // Annex A parameters
1066
604
    config_ptr->profile = 0;
1067
604
    config_ptr->tier    = 0;
1068
604
    config_ptr->level   = 0;
1069
1070
    // Film grain denoising
1071
604
    config_ptr->film_grain_denoise_strength = 0;
1072
604
    config_ptr->film_grain_denoise_apply    = 0;
1073
1074
    // CPU Flags
1075
604
    config_ptr->use_cpu_flags = EB_CPU_FLAGS_ALL;
1076
1077
    // Channel info
1078
604
    config_ptr->level_of_parallelism = 0;
1079
1080
    // Debug info
1081
604
    config_ptr->recon_enabled = 0;
1082
1083
    // Alt-Ref default values
1084
604
    config_ptr->enable_tf       = 1;
1085
604
    config_ptr->enable_tf_key   = 1;
1086
604
    config_ptr->enable_overlays = false;
1087
604
    config_ptr->tune            = 1;
1088
    // Super-resolution default values
1089
604
    config_ptr->superres_mode      = SUPERRES_NONE;
1090
604
    config_ptr->superres_denom     = SCALE_NUMERATOR;
1091
604
    config_ptr->superres_kf_denom  = SCALE_NUMERATOR;
1092
604
    config_ptr->superres_qthres    = 43; // random threshold, change
1093
604
    config_ptr->superres_kf_qthres = 43; // random threshold, change
1094
1095
    // Reference Scaling default values
1096
604
    config_ptr->resize_mode     = RESIZE_NONE;
1097
604
    config_ptr->resize_denom    = SCALE_NUMERATOR;
1098
604
    config_ptr->resize_kf_denom = SCALE_NUMERATOR;
1099
1100
    // Color description default values
1101
604
    config_ptr->color_primaries          = 2;
1102
604
    config_ptr->transfer_characteristics = 2;
1103
604
    config_ptr->matrix_coefficients      = 2;
1104
604
    config_ptr->color_range              = EB_CR_STUDIO_RANGE;
1105
604
    config_ptr->chroma_sample_position   = EB_CSP_UNKNOWN;
1106
604
    config_ptr->pass                     = 0;
1107
604
    memset(&config_ptr->mastering_display, 0, sizeof(config_ptr->mastering_display));
1108
604
    memset(&config_ptr->content_light_level, 0, sizeof(config_ptr->content_light_level));
1109
1110
    // Switch frame default values
1111
604
    config_ptr->sframe_dist      = 0;
1112
604
    config_ptr->sframe_mode      = SFRAME_NEAREST_BASE;
1113
604
    config_ptr->force_key_frames = 0;
1114
1115
    // Quant Matrices (QM)
1116
604
    config_ptr->enable_qm           = 0;
1117
604
    config_ptr->min_qm_level        = 8;
1118
604
    config_ptr->max_qm_level        = 15;
1119
604
    config_ptr->min_chroma_qm_level = 8;
1120
604
    config_ptr->max_chroma_qm_level = 15;
1121
1122
604
    config_ptr->startup_mg_size                   = 0;
1123
604
    config_ptr->startup_qp_offset                 = 0;
1124
604
    config_ptr->frame_scale_evts.evt_num          = 0;
1125
604
    config_ptr->frame_scale_evts.resize_denoms    = NULL;
1126
604
    config_ptr->frame_scale_evts.resize_kf_denoms = NULL;
1127
604
    config_ptr->frame_scale_evts.start_frame_nums = NULL;
1128
604
    config_ptr->enable_roi_map                    = false;
1129
604
    config_ptr->fgs_table                         = NULL;
1130
604
    config_ptr->enable_variance_boost             = false;
1131
604
    config_ptr->variance_boost_strength           = 2;
1132
604
    config_ptr->variance_octile                   = 5;
1133
604
    config_ptr->tf_strength                       = 3;
1134
604
    config_ptr->variance_boost_curve              = 0;
1135
604
    config_ptr->luminance_qp_bias                 = 0;
1136
604
    config_ptr->sharpness                         = 0;
1137
604
    config_ptr->lossless                          = false;
1138
604
    config_ptr->avif                              = false;
1139
604
    config_ptr->qp_scale_compress_strength        = 0;
1140
604
    config_ptr->sframe_posi.sframe_num            = 0;
1141
604
    config_ptr->sframe_posi.sframe_posis          = NULL;
1142
604
    config_ptr->sframe_posi.sframe_qp_num         = 0;
1143
604
    config_ptr->sframe_posi.sframe_qps            = NULL;
1144
604
    config_ptr->sframe_posi.sframe_qp_offsets     = NULL;
1145
604
    config_ptr->sframe_qp                         = 0;
1146
604
    config_ptr->sframe_qp_offset                  = 0;
1147
604
    config_ptr->adaptive_film_grain               = true;
1148
604
    config_ptr->max_tx_size                       = 64;
1149
604
    config_ptr->extended_crf_qindex_offset        = 0;
1150
604
    config_ptr->ac_bias                           = 0.0;
1151
604
    config_ptr->hbd_mds                           = DEFAULT;
1152
1153
    // Ref-frame management disabled by default → legacy bit-exact behavior
1154
    // and no extra ref-buffer memory allocated.
1155
604
    config_ptr->max_managed_refs = 0;
1156
1157
    // MG size fixed for the session by default → legacy pool sizing.
1158
604
    config_ptr->max_hierarchical_levels = 0;
1159
1160
604
    config_ptr->max_allowed_consecutive_frames_skips = 0;
1161
1162
604
    return return_error;
1163
604
}
1164
1165
604
static const char* tier_to_str(unsigned in) {
1166
604
    switch (in) {
1167
604
    case 0:
1168
604
        return "Main";
1169
0
    case 1:
1170
0
        return "High";
1171
0
    default: {
1172
0
        static char ret[11];
1173
0
        snprintf(ret, sizeof(ret), "%u", in);
1174
0
        return ret;
1175
0
    }
1176
604
    }
1177
604
}
1178
1179
604
static const char* level_to_str(unsigned in) {
1180
604
    if (!in) {
1181
604
        return "(auto)";
1182
604
    }
1183
0
    static char ret[313];
1184
0
    snprintf(ret, 313, "%.1f", in / 10.0);
1185
0
    return ret;
1186
604
}
1187
1188
296
static double get_extended_crf(EbSvtAv1EncConfiguration* config_ptr) {
1189
296
    return (double)config_ptr->qp + (double)config_ptr->extended_crf_qindex_offset / 4;
1190
296
}
1191
1192
//#define DEBUG_BUFFERS
1193
604
void svt_av1_print_lib_params(SequenceControlSet* scs) {
1194
604
    EbSvtAv1EncConfiguration* config = &scs->static_config;
1195
1196
604
    SVT_INFO("-------------------------------------------\n");
1197
604
    if (config->pass == ENC_FIRST_PASS) {
1198
0
        SVT_INFO("SVT [config]: preset \t\t\t\t\t\t\t: Pass 1\n");
1199
604
    } else {
1200
604
        SVT_INFO("SVT [config]: %s\ttier %s\tlevel %s\n",
1201
604
                 config->profile == MAIN_PROFILE               ? "main profile"
1202
604
                     : config->profile == HIGH_PROFILE         ? "high profile"
1203
604
                     : config->profile == PROFESSIONAL_PROFILE ? "professional profile"
1204
604
                                                               : "Unknown profile",
1205
604
                 tier_to_str(config->tier),
1206
604
                 level_to_str(config->level));
1207
604
        SVT_INFO(
1208
604
            "SVT [config]: width / height / fps numerator / fps denominator \t\t: %d / %d / %d / "
1209
604
            "%d\n",
1210
604
            config->source_width,
1211
604
            config->source_height,
1212
604
            config->frame_rate_numerator,
1213
604
            config->frame_rate_denominator);
1214
604
        SVT_INFO(
1215
604
            "SVT [config]: bit-depth / color format \t\t\t\t\t: %d / "
1216
604
            "%s\n",
1217
604
            config->encoder_bit_depth,
1218
604
            config->encoder_color_format == EB_YUV400       ? "YUV400"
1219
604
                : config->encoder_color_format == EB_YUV420 ? "YUV420"
1220
604
                : config->encoder_color_format == EB_YUV422 ? "YUV422"
1221
604
                : config->encoder_color_format == EB_YUV444 ? "YUV444"
1222
604
                                                            : "Unknown color format");
1223
1224
604
        SVT_INFO("SVT [config]: preset / tune / pred struct \t\t\t\t\t: %d / %s / %s\n",
1225
604
                 config->enc_mode,
1226
604
                 config->tune == TUNE_VQ            ? "VQ"
1227
604
                     : config->tune == TUNE_PSNR    ? "PSNR"
1228
604
                     : config->tune == TUNE_SSIM    ? "SSIM"
1229
604
                     : config->tune == TUNE_MS_SSIM ? "MS_SSIM"
1230
604
                     : config->tune == TUNE_VMAF    ? "VMAF"
1231
604
                                                    : "IQ",
1232
604
                 config->pred_structure == LOW_DELAY           ? "low delay"
1233
604
                     : config->pred_structure == RANDOM_ACCESS ? "random access"
1234
604
                     : config->pred_structure == ALL_INTRA     ? "all intra"
1235
604
                                                               : "Unknown pred structure");
1236
604
        SVT_INFO(
1237
604
            "SVT [config]: gop size / mini-gop size / key-frame type \t\t\t: "
1238
604
            "%d / %d / %s\n",
1239
604
            config->intra_period_length + 1,
1240
604
            (1 << config->hierarchical_levels),
1241
604
            config->intra_refresh_type == SVT_AV1_FWDKF_REFRESH    ? "FWD key frame"
1242
604
                : config->intra_refresh_type == SVT_AV1_KF_REFRESH ? "key frame"
1243
604
                                                                   : "Unknown key frame type");
1244
604
        if (config->lossless) {
1245
308
            SVT_INFO("SVT [config]: BRC mode\t\t\t\t\t\t\t: Lossless Coding \n");
1246
308
        } else {
1247
296
            switch (config->rate_control_mode) {
1248
296
            case SVT_AV1_RC_MODE_CQP_OR_CRF:
1249
296
                if (config->max_bit_rate) {
1250
0
                    SVT_INFO(
1251
0
                        "SVT [config]: BRC mode / %s / max bitrate (kbps)\t\t\t: %s / %.2f / "
1252
0
                        "%d\n",
1253
0
                        scs->tpl || scs->static_config.enable_variance_boost ? "rate factor" : "CQP Assignment",
1254
0
                        scs->tpl || scs->static_config.enable_variance_boost ? "capped CRF" : "CQP",
1255
0
                        get_extended_crf(config),
1256
0
                        (int)config->max_bit_rate / 1000);
1257
296
                } else {
1258
296
                    SVT_INFO("SVT [config]: BRC mode / %s \t\t\t\t\t: %s / %.2f \n",
1259
296
                             scs->tpl || scs->static_config.enable_variance_boost ? "rate factor" : "CQP Assignment",
1260
296
                             scs->tpl || scs->static_config.enable_variance_boost ? "CRF" : "CQP",
1261
296
                             get_extended_crf(config));
1262
296
                }
1263
296
                break;
1264
0
            case SVT_AV1_RC_MODE_VBR:
1265
0
                SVT_INFO("SVT [config]: BRC mode / target bitrate (kbps)\t\t\t\t: VBR / %d \n",
1266
0
                         (int)config->target_bit_rate / 1000);
1267
0
                break;
1268
0
            case SVT_AV1_RC_MODE_CBR:
1269
0
                SVT_INFO(
1270
0
                    "SVT [config]: BRC mode / target bitrate (kbps)\t\t\t\t: CBR "
1271
0
                    "/ %d\n",
1272
0
                    (int)config->target_bit_rate / 1000);
1273
0
                break;
1274
296
            }
1275
296
        }
1276
604
        if (config->rate_control_mode != SVT_AV1_RC_MODE_CBR) {
1277
604
            if (!config->enable_variance_boost) {
1278
604
                SVT_INFO("SVT [config]: AQ mode / Variance Boost \t\t\t\t\t: %d / %d\n",
1279
604
                         config->aq_mode,
1280
604
                         config->enable_variance_boost);
1281
604
            } else {
1282
0
                SVT_INFO("SVT [config]: AQ mode / Variance Boost strength / octile / curve \t\t: %d / %d / %d / %d\n",
1283
0
                         config->aq_mode,
1284
0
                         config->variance_boost_strength,
1285
0
                         config->variance_octile,
1286
0
                         config->variance_boost_curve);
1287
0
            }
1288
604
        }
1289
1290
604
        if (config->film_grain_denoise_strength != 0) {
1291
0
            if (config->adaptive_film_grain) {
1292
0
                SVT_INFO(
1293
0
                    "SVT [config]: film grain synth / denoising / level / adaptive blocksize \t: %d / %d / %d / True\n",
1294
0
                    1,
1295
0
                    config->film_grain_denoise_apply,
1296
0
                    config->film_grain_denoise_strength);
1297
0
            } else {
1298
0
                SVT_INFO(
1299
0
                    "SVT [config]: film grain synth / denoising / level / adaptive blocksize \t: %d / %d / %d / "
1300
0
                    "False\n",
1301
0
                    1,
1302
0
                    config->film_grain_denoise_apply,
1303
0
                    config->film_grain_denoise_strength);
1304
0
            }
1305
0
        }
1306
604
        SVT_INFO("SVT [config]: sharpness / luminance-based QP bias \t\t\t\t: %d / %d\n",
1307
604
                 config->sharpness,
1308
604
                 config->luminance_qp_bias);
1309
1310
604
        switch (config->enable_tf) {
1311
0
        case 1:
1312
0
            if (config->tf_strength != 3) {
1313
0
                SVT_INFO("SVT [config]: temporal filtering strength \t\t\t\t\t: %d\n", config->tf_strength);
1314
0
            }
1315
0
            break;
1316
0
        case 2:
1317
0
            SVT_INFO("SVT [config]: temporal filtering strength \t\t\t\t\t: auto\n");
1318
0
            break;
1319
604
        default:
1320
604
            break;
1321
604
        }
1322
1323
604
        SVT_INFO("SVT [config]: QP scale compress strength \t\t\t\t\t: %d\n", config->qp_scale_compress_strength);
1324
1325
604
        if (config->ac_bias) {
1326
0
            SVT_INFO("SVT [config]: AC Bias Strength \t\t\t\t\t\t: %.2f\n", config->ac_bias);
1327
0
        }
1328
1329
604
        if (config->hbd_mds != DEFAULT) {
1330
0
            SVT_INFO("SVT [config]: High Bit Depth Mode Decision setting \t\t\t\t\t: %d\n", config->hbd_mds);
1331
0
        }
1332
604
    }
1333
#if DEBUG_BUFFERS
1334
    SVT_INFO("SVT [config]: INPUT / OUTPUT \t\t\t\t\t\t\t: %d / %d\n",
1335
             scs->input_buffer_fifo_init_count,
1336
             scs->output_stream_buffer_fifo_init_count);
1337
    SVT_INFO("SVT [config]: CPCS / PAREF / REF / ME\t\t\t\t\t\t: %d / %d / %d / %d\n",
1338
             scs->picture_control_set_pool_init_count_child,
1339
             scs->pa_reference_picture_buffer_init_count,
1340
             scs->reference_picture_buffer_init_count,
1341
             scs->me_pool_init_count);
1342
    SVT_INFO("SVT [config]: ME_SEG_W / ME_SEG_H \t\t\t: %u / %u\n",
1343
             scs->me_segment_col_count_array,
1344
             scs->me_segment_row_count_array);
1345
    SVT_INFO("SVT [config]: ENC_DEC_SEG_W / ENC_DEC_SEG_H \t\t\t: %u / %u\n",
1346
             scs->enc_dec_segment_col_count_array,
1347
             scs->enc_dec_segment_row_count_array);
1348
    SVT_INFO(
1349
        "SVT [config]: PA_P / ME_P / SBO_P / MDC_P / ED_P / EC_P \t\t\t: %d / %d / %d / %d / %d / "
1350
        "%d\n",
1351
        scs->picture_analysis_process_init_count,
1352
        scs->motion_estimation_process_init_count,
1353
        scs->source_based_operations_process_init_count,
1354
        scs->mode_decision_configuration_process_init_count,
1355
        scs->enc_dec_process_init_count,
1356
        scs->entropy_coding_process_init_count);
1357
    SVT_INFO("SVT [config]: DLF_P / CDEF_P / REST_P \t\t\t\t\t\t: %d / %d / %d\n",
1358
             scs->dlf_process_init_count,
1359
             scs->cdef_process_init_count,
1360
             scs->rest_process_init_count);
1361
#endif
1362
604
    SVT_INFO("-------------------------------------------\n");
1363
1364
604
    fflush(stdout);
1365
604
}
1366
1367
/**********************************
1368
* Parse Single Parameter
1369
**********************************/
1370
1371
0
static EbErrorType str_to_int64(const char* nptr, int64_t* out, char** nextptr) {
1372
0
    char*   endptr;
1373
0
    int64_t val;
1374
1375
0
    val = strtoll(nptr, &endptr, 0);
1376
1377
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1378
0
        return EB_ErrorBadParameter;
1379
0
    }
1380
1381
0
    *out = val;
1382
0
    if (nextptr) {
1383
0
        *nextptr = endptr;
1384
0
    }
1385
0
    return EB_ErrorNone;
1386
0
}
1387
1388
0
static EbErrorType str_to_int(const char* nptr, int32_t* out, char** nextptr) {
1389
0
    char*   endptr;
1390
0
    int32_t val;
1391
1392
0
    val = strtol(nptr, &endptr, 0);
1393
1394
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1395
0
        return EB_ErrorBadParameter;
1396
0
    }
1397
1398
0
    *out = val;
1399
0
    if (nextptr) {
1400
0
        *nextptr = endptr;
1401
0
    }
1402
0
    return EB_ErrorNone;
1403
0
}
1404
1405
0
static EbErrorType str_to_uint64(const char* nptr, uint64_t* out, char** nextptr) {
1406
0
    char*    endptr;
1407
0
    uint64_t val;
1408
1409
0
    if (strtoll(nptr, NULL, 0) < 0) {
1410
0
        return EB_ErrorBadParameter;
1411
0
    }
1412
1413
0
    val = strtoull(nptr, &endptr, 0);
1414
1415
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1416
0
        return EB_ErrorBadParameter;
1417
0
    }
1418
1419
0
    *out = val;
1420
0
    if (nextptr) {
1421
0
        *nextptr = endptr;
1422
0
    }
1423
0
    return EB_ErrorNone;
1424
0
}
1425
1426
0
static EbErrorType str_to_uint(const char* nptr, uint32_t* out, char** nextptr) {
1427
0
    char*    endptr;
1428
0
    uint32_t val;
1429
1430
0
    if (strtol(nptr, NULL, 0) < 0) {
1431
0
        return EB_ErrorBadParameter;
1432
0
    }
1433
1434
0
    val = strtoul(nptr, &endptr, 0);
1435
1436
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1437
0
        return EB_ErrorBadParameter;
1438
0
    }
1439
1440
0
    *out = val;
1441
0
    if (nextptr) {
1442
0
        *nextptr = endptr;
1443
0
    }
1444
0
    return EB_ErrorNone;
1445
0
}
1446
1447
0
static EbErrorType str_to_int8(const char* nptr, int8_t* out, char** nextptr) {
1448
0
    char*   endptr;
1449
0
    int32_t val;
1450
1451
0
    val = strtol(nptr, &endptr, 0);
1452
1453
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1454
0
        return EB_ErrorBadParameter;
1455
0
    }
1456
1457
    // check for the range
1458
0
    if (val < INT8_MIN || val > INT8_MAX) {
1459
0
        return EB_ErrorBadParameter;
1460
0
    }
1461
1462
0
    *out = (int8_t)val;
1463
0
    if (nextptr) {
1464
0
        *nextptr = endptr;
1465
0
    }
1466
0
    return EB_ErrorNone;
1467
0
}
1468
1469
0
static EbErrorType str_to_uint8(const char* nptr, uint8_t* out, char** nextptr) {
1470
0
    char*    endptr;
1471
0
    uint32_t val;
1472
1473
0
    if (strtol(nptr, NULL, 0) < 0) {
1474
0
        return EB_ErrorBadParameter;
1475
0
    }
1476
1477
0
    val = strtoul(nptr, &endptr, 0);
1478
1479
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1480
0
        return EB_ErrorBadParameter;
1481
0
    }
1482
1483
    // check for the range
1484
0
    if (val > UINT8_MAX) {
1485
0
        return EB_ErrorBadParameter;
1486
0
    }
1487
1488
0
    *out = (uint8_t)val;
1489
0
    if (nextptr) {
1490
0
        *nextptr = endptr;
1491
0
    }
1492
0
    return EB_ErrorNone;
1493
0
}
1494
1495
0
#define str_to_int32 str_to_int
1496
0
#define str_to_uint32 str_to_uint
1497
1498
0
static EbErrorType str_to_double(const char* nptr, double* out, char** nextptr) {
1499
0
    char*  endptr;
1500
0
    double val;
1501
1502
0
    val = strtod(nptr, &endptr);
1503
1504
0
    if (endptr == nptr || (!nextptr && *endptr)) {
1505
0
        return EB_ErrorBadParameter;
1506
0
    }
1507
1508
0
    *out = val;
1509
0
    if (nextptr) {
1510
0
        *nextptr = endptr;
1511
0
    }
1512
0
    return EB_ErrorNone;
1513
0
}
1514
1515
//assume the input list of values are in the format of "[v1,v2,v3,...]"
1516
#define PARSE_LIST(list_type)                                                                    \
1517
0
    static EbErrorType parse_list_##list_type(const char* nptr, list_type##_t* list, size_t n) { \
1518
0
        const char* ptr = nptr;                                                                  \
1519
0
        char*       endptr;                                                                      \
1520
0
        size_t      i = 0;                                                                       \
1521
0
        memset(list, 0, n * sizeof(*list));                                                      \
1522
0
        while (*ptr) {                                                                           \
1523
0
            if (*ptr == '[' || *ptr == ']') {                                                    \
1524
0
                ptr++;                                                                           \
1525
0
                continue;                                                                        \
1526
0
            }                                                                                    \
1527
0
            list_type##_t rawval;                                                                \
1528
0
            EbErrorType   err = str_to_##list_type(ptr, &rawval, &endptr);                       \
1529
0
            if (err != EB_ErrorNone)                                                             \
1530
0
                return err;                                                                      \
1531
0
            if (i >= n) {                                                                        \
1532
0
                return EB_ErrorBadParameter;                                                     \
1533
0
            } else if (*endptr == ',' || *endptr == ']') {                                       \
1534
0
                endptr++;                                                                        \
1535
0
            } else if (*endptr) {                                                                \
1536
0
                return EB_ErrorBadParameter;                                                     \
1537
0
            }                                                                                    \
1538
0
            list[i++] = rawval;                                                                  \
1539
0
            ptr       = endptr;                                                                  \
1540
0
        }                                                                                        \
1541
0
        return EB_ErrorNone;                                                                     \
1542
0
    }
Unexecuted instantiation: enc_settings.c:parse_list_int32
Unexecuted instantiation: enc_settings.c:parse_list_uint64
Unexecuted instantiation: enc_settings.c:parse_list_uint32
Unexecuted instantiation: enc_settings.c:parse_list_uint8
Unexecuted instantiation: enc_settings.c:parse_list_int8
1543
PARSE_LIST(int8)
1544
PARSE_LIST(uint8)
1545
PARSE_LIST(int32)
1546
PARSE_LIST(uint32)
1547
PARSE_LIST(uint64)
1548
1549
0
static uint32_t count_params(const char* nptr) {
1550
0
    const char* ptr = nptr;
1551
0
    char*       endptr;
1552
0
    uint32_t    i = 0;
1553
0
    while (*ptr) {
1554
0
        if (*ptr == '[' || *ptr == ']') {
1555
0
            ptr++;
1556
0
            continue;
1557
0
        }
1558
1559
0
        strtoll(ptr, &endptr, 10);
1560
0
        if (*endptr == ',' || *endptr == ']') {
1561
0
            endptr++;
1562
0
        } else if (*endptr) {
1563
0
            return i;
1564
0
        }
1565
0
        i++;
1566
0
        ptr = endptr;
1567
0
    }
1568
0
    return i;
1569
0
}
1570
1571
#ifdef _MSC_VER
1572
#define strcasecmp _stricmp
1573
#endif
1574
0
static EbErrorType str_to_bool(const char* nptr, bool* out) {
1575
0
    bool val;
1576
0
    if (!strcmp(nptr, "1") || !strcasecmp(nptr, "true") || !strcasecmp(nptr, "yes")) {
1577
0
        val = true;
1578
0
    } else if (!strcmp(nptr, "0") || !strcasecmp(nptr, "false") || !strcasecmp(nptr, "no")) {
1579
0
        val = false;
1580
0
    } else {
1581
0
        return EB_ErrorBadParameter;
1582
0
    }
1583
1584
0
    *out = val;
1585
0
    return EB_ErrorNone;
1586
0
}
1587
1588
0
static EbErrorType str_to_crf(const char* nptr, EbSvtAv1EncConfiguration* config_struct) {
1589
0
    double      crf;
1590
0
    EbErrorType return_error;
1591
1592
0
    return_error = str_to_double(nptr, &crf, NULL);
1593
1594
0
    if (return_error == EB_ErrorBadParameter) {
1595
0
        return return_error;
1596
0
    }
1597
0
    if (crf < 0) {
1598
0
        return EB_ErrorBadParameter;
1599
0
    }
1600
1601
0
    uint32_t extended_q_index           = (uint32_t)(crf * 4);
1602
0
    uint32_t qp                         = AOMMIN(MAX_QP_VALUE, (uint32_t)crf);
1603
0
    uint32_t extended_crf_qindex_offset = extended_q_index - qp * 4;
1604
1605
0
    config_struct->qp                         = qp;
1606
0
    config_struct->rate_control_mode          = SVT_AV1_RC_MODE_CQP_OR_CRF;
1607
0
    config_struct->aq_mode                    = 2;
1608
0
    config_struct->extended_crf_qindex_offset = extended_crf_qindex_offset;
1609
1610
0
    return EB_ErrorNone;
1611
0
}
1612
1613
0
static EbErrorType str_to_cqp(const char* nptr, EbSvtAv1EncConfiguration* config_struct) {
1614
0
    double      cqp;
1615
0
    EbErrorType return_error;
1616
1617
0
    return_error = str_to_double(nptr, &cqp, NULL);
1618
1619
0
    if (return_error == EB_ErrorBadParameter) {
1620
0
        return return_error;
1621
0
    }
1622
0
    if (cqp < 0) {
1623
0
        return EB_ErrorBadParameter;
1624
0
    }
1625
1626
0
    uint32_t extended_q_index           = (uint32_t)(cqp * 4);
1627
0
    uint32_t qp                         = AOMMIN(MAX_QP_VALUE, (uint32_t)cqp);
1628
0
    uint32_t extended_crf_qindex_offset = extended_q_index - qp * 4;
1629
1630
0
    config_struct->qp                         = qp;
1631
0
    config_struct->rate_control_mode          = SVT_AV1_RC_MODE_CQP_OR_CRF;
1632
0
    config_struct->aq_mode                    = 0;
1633
0
    config_struct->extended_crf_qindex_offset = extended_crf_qindex_offset;
1634
1635
0
    return EB_ErrorNone;
1636
0
}
1637
1638
0
static EbErrorType str_to_keyint(const char* nptr, int32_t* out, bool* multi) {
1639
0
    char*      suff;
1640
0
    const long keyint = strtol(nptr, &suff, 0);
1641
1642
0
    if (keyint > INT32_MAX || keyint < -2) {
1643
0
        return EB_ErrorBadParameter;
1644
0
    }
1645
1646
0
    switch (*suff) {
1647
0
    case 's':
1648
        // signal we need to multiply keyint * frame_rate
1649
0
        *multi = true;
1650
0
        *out   = keyint;
1651
0
        break;
1652
0
    case '\0':
1653
0
        *multi = false;
1654
0
        *out   = keyint < 0 ? keyint : keyint - 1;
1655
0
        break;
1656
0
    default:
1657
        // else leave as untouched, we have an invalid keyint
1658
0
        SVT_ERROR("Invalid keyint value: %s\n", nptr);
1659
0
        return EB_ErrorBadParameter;
1660
0
    }
1661
1662
0
    return EB_ErrorNone;
1663
0
}
1664
1665
0
static EbErrorType str_to_bitrate(const char* nptr, uint32_t* out) {
1666
0
    char*        suff;
1667
0
    const double bitrate = strtod(nptr, &suff);
1668
1669
0
    if (bitrate < 0 || bitrate > UINT32_MAX) {
1670
0
        SVT_ERROR("Invalid bitrate value: %s\n", nptr);
1671
0
        return EB_ErrorBadParameter;
1672
0
    }
1673
1674
0
    switch (*suff) {
1675
0
    case 'b':
1676
0
    case 'B':
1677
0
        *out = (uint32_t)bitrate;
1678
0
        break;
1679
0
    case '\0':
1680
0
    case 'k':
1681
0
    case 'K':
1682
0
        *out = (uint32_t)(1000 * bitrate);
1683
0
        break;
1684
0
    case 'm':
1685
0
    case 'M':
1686
0
        *out = (uint32_t)(1000000 * bitrate);
1687
0
        break;
1688
0
    default:
1689
0
        return EB_ErrorBadParameter;
1690
0
    }
1691
0
    if (*out > 100000000) {
1692
0
        *out = 100000000;
1693
0
        SVT_WARN("Bitrate value: %s has been set to 100000000\n", nptr);
1694
0
    }
1695
0
    return EB_ErrorNone;
1696
0
}
1697
1698
0
static EbErrorType str_to_profile(const char* nptr, EbAv1SeqProfile* out) {
1699
0
    const struct {
1700
0
        const char*     name;
1701
0
        EbAv1SeqProfile profile;
1702
0
    } profiles[] = {
1703
0
        {"main", MAIN_PROFILE},
1704
0
        {"high", HIGH_PROFILE},
1705
0
        {"professional", PROFESSIONAL_PROFILE},
1706
0
    };
1707
1708
0
    const size_t profiles_size = sizeof(profiles) / sizeof(profiles[0]);
1709
1710
0
    for (size_t i = 0; i < profiles_size; i++) {
1711
0
        if (!strcmp(nptr, profiles[i].name)) {
1712
0
            *out = profiles[i].profile;
1713
0
            return EB_ErrorNone;
1714
0
        }
1715
0
    }
1716
1717
0
    return EB_ErrorBadParameter;
1718
0
}
1719
1720
0
static EbErrorType str_to_color_fmt(const char* nptr, EbColorFormat* out) {
1721
0
    const struct {
1722
0
        const char*   name;
1723
0
        EbColorFormat fmt;
1724
0
    } color_formats[] = {
1725
0
        {"mono", EB_YUV400},
1726
0
        {"400", EB_YUV400},
1727
0
        {"420", EB_YUV420},
1728
0
        {"422", EB_YUV422},
1729
0
        {"444", EB_YUV444},
1730
0
    };
1731
1732
0
    const size_t color_format_size = sizeof(color_formats) / sizeof(color_formats[0]);
1733
1734
0
    for (size_t i = 0; i < color_format_size; i++) {
1735
0
        if (!strcmp(nptr, color_formats[i].name)) {
1736
0
            *out = color_formats[i].fmt;
1737
0
            return EB_ErrorNone;
1738
0
        }
1739
0
    }
1740
1741
0
    return EB_ErrorBadParameter;
1742
0
}
1743
1744
0
static EbErrorType str_to_intra_rt(const char* nptr, SvtAv1IntraRefreshType* out) {
1745
0
    const struct {
1746
0
        const char*            name;
1747
0
        SvtAv1IntraRefreshType type;
1748
0
    } refresh_types[] = {
1749
0
        {"cra", SVT_AV1_FWDKF_REFRESH},
1750
0
        {"fwdkf", SVT_AV1_FWDKF_REFRESH},
1751
0
        {"idr", SVT_AV1_KF_REFRESH},
1752
0
        {"kf", SVT_AV1_KF_REFRESH},
1753
0
    };
1754
1755
0
    const size_t refresh_type_size = sizeof(refresh_types) / sizeof(refresh_types[0]);
1756
1757
0
    for (size_t i = 0; i < refresh_type_size; i++) {
1758
0
        if (!strcmp(nptr, refresh_types[i].name)) {
1759
0
            *out = refresh_types[i].type;
1760
0
            return EB_ErrorNone;
1761
0
        }
1762
0
    }
1763
1764
0
    return EB_ErrorBadParameter;
1765
0
}
1766
1767
0
static EbErrorType str_to_asm(const char* nptr, EbCpuFlags* out) {
1768
    // need to handle numbers in here since the numbers to no match the
1769
    // internal representation
1770
0
    const struct {
1771
0
        const char* name;
1772
0
        EbCpuFlags  flag;
1773
0
    } simds[] = {
1774
0
        {"c", 0},
1775
0
        {"0", 0},
1776
#ifdef ARCH_X86_64
1777
        {"mmx", (EB_CPU_FLAGS_MMX << 1) - 1},
1778
        {"1", (EB_CPU_FLAGS_MMX << 1) - 1},
1779
        {"sse", (EB_CPU_FLAGS_SSE << 1) - 1},
1780
        {"2", (EB_CPU_FLAGS_SSE << 1) - 1},
1781
        {"sse2", (EB_CPU_FLAGS_SSE2 << 1) - 1},
1782
        {"3", (EB_CPU_FLAGS_SSE2 << 1) - 1},
1783
        {"sse3", (EB_CPU_FLAGS_SSE3 << 1) - 1},
1784
        {"4", (EB_CPU_FLAGS_SSE3 << 1) - 1},
1785
        {"ssse3", (EB_CPU_FLAGS_SSSE3 << 1) - 1},
1786
        {"5", (EB_CPU_FLAGS_SSSE3 << 1) - 1},
1787
        {"sse4_1", (EB_CPU_FLAGS_SSE4_1 << 1) - 1},
1788
        {"6", (EB_CPU_FLAGS_SSE4_1 << 1) - 1},
1789
        {"sse4_2", (EB_CPU_FLAGS_SSE4_2 << 1) - 1},
1790
        {"7", (EB_CPU_FLAGS_SSE4_2 << 1) - 1},
1791
        {"avx", (EB_CPU_FLAGS_AVX << 1) - 1},
1792
        {"8", (EB_CPU_FLAGS_AVX << 1) - 1},
1793
        {"avx2", (EB_CPU_FLAGS_AVX2 << 1) - 1},
1794
        {"9", (EB_CPU_FLAGS_AVX2 << 1) - 1},
1795
        {"avx512", (EB_CPU_FLAGS_AVX512VL << 1) - 1},
1796
        {"10", (EB_CPU_FLAGS_AVX512VL << 1) - 1},
1797
        {"avx512icl", (EB_CPU_FLAGS_AVX512ICL << 1) - 1},
1798
        {"11", (EB_CPU_FLAGS_AVX512ICL << 1) - 1},
1799
#elif defined(ARCH_AARCH64)
1800
        {"neon", (EB_CPU_FLAGS_NEON << 1) - 1},
1801
        {"1", (EB_CPU_FLAGS_NEON << 1) - 1},
1802
        {"crc32", (EB_CPU_FLAGS_ARM_CRC32 << 1) - 1},
1803
        {"2", (EB_CPU_FLAGS_ARM_CRC32 << 1) - 1},
1804
        {"neon_dotprod", (EB_CPU_FLAGS_NEON_DOTPROD << 1) - 1},
1805
        {"3", (EB_CPU_FLAGS_NEON_DOTPROD << 1) - 1},
1806
        {"neon_i8mm", (EB_CPU_FLAGS_NEON_I8MM << 1) - 1},
1807
        {"4", (EB_CPU_FLAGS_NEON_I8MM << 1) - 1},
1808
        {"sve", (EB_CPU_FLAGS_SVE << 1) - 1},
1809
        {"5", (EB_CPU_FLAGS_SVE << 1) - 1},
1810
        {"sve2", (EB_CPU_FLAGS_SVE2 << 1) - 1},
1811
        {"6", (EB_CPU_FLAGS_SVE2 << 1) - 1},
1812
#endif
1813
0
        {"max", EB_CPU_FLAGS_ALL},
1814
0
        {"100", EB_CPU_FLAGS_ALL},
1815
0
    };
1816
0
    const size_t simds_size = sizeof(simds) / sizeof(simds[0]);
1817
1818
0
    for (size_t i = 0; i < simds_size; i++) {
1819
0
        if (!strcmp(nptr, simds[i].name)) {
1820
0
            *out = simds[i].flag;
1821
0
            return EB_ErrorNone;
1822
0
        }
1823
0
    }
1824
1825
0
    *out = EB_CPU_FLAGS_INVALID;
1826
1827
0
    return EB_ErrorBadParameter;
1828
0
}
1829
1830
0
static EbErrorType str_to_color_primaries(const char* nptr, EbColorPrimaries* out) {
1831
0
    const struct {
1832
0
        const char*      name;
1833
0
        EbColorPrimaries primaries;
1834
0
    } color_primaries[] = {
1835
0
        {"bt709", EB_CICP_CP_BT_709},
1836
0
        {"bt470m", EB_CICP_CP_BT_470_M},
1837
0
        {"bt470bg", EB_CICP_CP_BT_470_B_G},
1838
0
        {"bt601", EB_CICP_CP_BT_601},
1839
0
        {"smpte240", EB_CICP_CP_SMPTE_240},
1840
0
        {"film", EB_CICP_CP_GENERIC_FILM},
1841
0
        {"bt2020", EB_CICP_CP_BT_2020},
1842
0
        {"xyz", EB_CICP_CP_XYZ},
1843
0
        {"smpte431", EB_CICP_CP_SMPTE_431},
1844
0
        {"smpte432", EB_CICP_CP_SMPTE_432},
1845
0
        {"ebu3213", EB_CICP_CP_EBU_3213},
1846
0
    };
1847
1848
0
    const size_t color_primaries_size = sizeof(color_primaries) / sizeof(color_primaries[0]);
1849
1850
0
    for (size_t i = 0; i < color_primaries_size; i++) {
1851
0
        if (!strcmp(nptr, color_primaries[i].name)) {
1852
0
            *out = color_primaries[i].primaries;
1853
0
            return EB_ErrorNone;
1854
0
        }
1855
0
    }
1856
1857
0
    return EB_ErrorBadParameter;
1858
0
}
1859
1860
0
static EbErrorType str_to_transfer_characteristics(const char* nptr, EbTransferCharacteristics* out) {
1861
0
    const struct {
1862
0
        const char*               name;
1863
0
        EbTransferCharacteristics tfc;
1864
0
    } transfer_characteristics[] = {
1865
0
        {"bt709", EB_CICP_TC_BT_709},
1866
0
        {"bt470m", EB_CICP_TC_BT_470_M},
1867
0
        {"bt470bg", EB_CICP_TC_BT_470_B_G},
1868
0
        {"bt601", EB_CICP_TC_BT_601},
1869
0
        {"smpte240", EB_CICP_TC_SMPTE_240},
1870
0
        {"linear", EB_CICP_TC_LINEAR},
1871
0
        {"log100", EB_CICP_TC_LOG_100},
1872
0
        {"log100-sqrt10", EB_CICP_TC_LOG_100_SQRT10},
1873
0
        {"iec61966", EB_CICP_TC_IEC_61966},
1874
0
        {"bt1361", EB_CICP_TC_BT_1361},
1875
0
        {"srgb", EB_CICP_TC_SRGB},
1876
0
        {"bt2020-10", EB_CICP_TC_BT_2020_10_BIT},
1877
0
        {"bt2020-12", EB_CICP_TC_BT_2020_12_BIT},
1878
0
        {"smpte2084", EB_CICP_TC_SMPTE_2084},
1879
0
        {"smpte428", EB_CICP_TC_SMPTE_428},
1880
0
        {"hlg", EB_CICP_TC_HLG},
1881
0
    };
1882
1883
0
    const size_t transfer_characteristics_size = sizeof(transfer_characteristics) / sizeof(transfer_characteristics[0]);
1884
1885
0
    for (size_t i = 0; i < transfer_characteristics_size; i++) {
1886
0
        if (!strcmp(nptr, transfer_characteristics[i].name)) {
1887
0
            *out = transfer_characteristics[i].tfc;
1888
0
            return EB_ErrorNone;
1889
0
        }
1890
0
    }
1891
1892
0
    return EB_ErrorBadParameter;
1893
0
}
1894
1895
0
static EbErrorType str_to_matrix_coefficients(const char* nptr, EbMatrixCoefficients* out) {
1896
0
    const struct {
1897
0
        const char*          name;
1898
0
        EbMatrixCoefficients coeff;
1899
0
    } matrix_coefficients[] = {
1900
0
        {"identity", EB_CICP_MC_IDENTITY},
1901
0
        {"bt709", EB_CICP_MC_BT_709},
1902
0
        {"fcc", EB_CICP_MC_FCC},
1903
0
        {"bt470bg", EB_CICP_MC_BT_470_B_G},
1904
0
        {"bt601", EB_CICP_MC_BT_601},
1905
0
        {"smpte240", EB_CICP_MC_SMPTE_240},
1906
0
        {"ycgco", EB_CICP_MC_SMPTE_YCGCO},
1907
0
        {"bt2020-ncl", EB_CICP_MC_BT_2020_NCL},
1908
0
        {"bt2020-cl", EB_CICP_MC_BT_2020_CL},
1909
0
        {"smpte2085", EB_CICP_MC_SMPTE_2085},
1910
0
        {"chroma-ncl", EB_CICP_MC_CHROMAT_NCL},
1911
0
        {"chroma-cl", EB_CICP_MC_CHROMAT_CL},
1912
0
        {"ictcp", EB_CICP_MC_ICTCP},
1913
0
    };
1914
1915
0
    const size_t matrix_coefficients_size = sizeof(matrix_coefficients) / sizeof(matrix_coefficients[0]);
1916
1917
0
    for (size_t i = 0; i < matrix_coefficients_size; i++) {
1918
0
        if (!strcmp(nptr, matrix_coefficients[i].name)) {
1919
0
            *out = matrix_coefficients[i].coeff;
1920
0
            return EB_ErrorNone;
1921
0
        }
1922
0
    }
1923
1924
0
    return EB_ErrorBadParameter;
1925
0
}
1926
1927
0
static EbErrorType str_to_color_range(const char* nptr, EbColorRange* out) {
1928
0
    const struct {
1929
0
        const char*  name;
1930
0
        EbColorRange range;
1931
0
    } color_range[] = {
1932
0
        {"studio", EB_CR_STUDIO_RANGE},
1933
0
        {"full", EB_CR_FULL_RANGE},
1934
0
    };
1935
1936
0
    const size_t color_range_size = sizeof(color_range) / sizeof(color_range[0]);
1937
1938
0
    for (size_t i = 0; i < color_range_size; i++) {
1939
0
        if (!strcmp(nptr, color_range[i].name)) {
1940
0
            *out = color_range[i].range;
1941
0
            return EB_ErrorNone;
1942
0
        }
1943
0
    }
1944
1945
0
    return EB_ErrorBadParameter;
1946
0
}
1947
1948
0
static EbErrorType str_to_chroma_sample_position(const char* nptr, EbChromaSamplePosition* out) {
1949
0
    const struct {
1950
0
        const char*            name;
1951
0
        EbChromaSamplePosition pos;
1952
0
    } chroma_sample_positions[] = {
1953
0
        {"unknown", EB_CSP_UNKNOWN},
1954
0
        {"vertical", EB_CSP_VERTICAL},
1955
0
        {"left", EB_CSP_VERTICAL},
1956
0
        {"colocated", EB_CSP_COLOCATED},
1957
0
        {"topleft", EB_CSP_COLOCATED},
1958
0
    };
1959
1960
0
    const size_t chroma_sample_positions_size = sizeof(chroma_sample_positions) / sizeof(chroma_sample_positions[0]);
1961
1962
0
    for (size_t i = 0; i < chroma_sample_positions_size; i++) {
1963
0
        if (!strcmp(nptr, chroma_sample_positions[i].name)) {
1964
0
            *out = chroma_sample_positions[i].pos;
1965
0
            return EB_ErrorNone;
1966
0
        }
1967
0
    }
1968
1969
0
    return EB_ErrorBadParameter;
1970
0
}
1971
1972
0
static EbErrorType str_to_sframe_mode(const char* nptr, EbSFrameMode* out) {
1973
0
    const struct {
1974
0
        const char*  name;
1975
0
        EbSFrameMode mode;
1976
0
    } sframe_mode[] = {
1977
0
        {"strict", SFRAME_STRICT_BASE},
1978
0
        {"nearest", SFRAME_NEAREST_BASE},
1979
0
        {"flexible", SFRAME_FLEXIBLE_BASE},
1980
0
        {"decposi", SFRAME_DEC_POSI_BASE},
1981
0
    };
1982
1983
0
    const size_t sframe_mode_size = sizeof(sframe_mode) / sizeof(sframe_mode[0]);
1984
1985
0
    for (size_t i = 0; i < sframe_mode_size; i++) {
1986
0
        if (!strcmp(nptr, sframe_mode[i].name)) {
1987
0
            *out = sframe_mode[i].mode;
1988
0
            return EB_ErrorNone;
1989
0
        }
1990
0
    }
1991
1992
0
    return EB_ErrorBadParameter;
1993
0
}
1994
1995
0
static EbErrorType str_to_rc_mode(const char* nptr, uint8_t* out, uint8_t* aq_mode) {
1996
    // separate rc mode enum to distinguish between cqp and crf modes
1997
0
    enum rc_modes {
1998
0
        RC_MODE_ZERO = 0, // unique mode in case user passes a literal 0
1999
0
        RC_MODE_CQP,
2000
0
        RC_MODE_CRF,
2001
0
        RC_MODE_VBR,
2002
0
        RC_MODE_CBR,
2003
0
        RC_MODE_INVALID,
2004
0
    };
2005
2006
0
    const struct {
2007
0
        const char* name;
2008
0
        uint32_t    mode;
2009
0
    } rc_mode[] = {
2010
0
        {"0", RC_MODE_ZERO},
2011
0
        {"1", RC_MODE_VBR},
2012
0
        {"2", RC_MODE_CBR},
2013
0
        {"cqp", RC_MODE_CQP},
2014
0
        {"crf", RC_MODE_CRF},
2015
0
        {"vbr", RC_MODE_VBR},
2016
0
        {"cbr", RC_MODE_CBR},
2017
0
    };
2018
2019
0
    const size_t rc_mode_size = sizeof(rc_mode) / sizeof(rc_mode[0]);
2020
2021
0
    enum rc_modes mode = RC_MODE_INVALID;
2022
2023
0
    for (size_t i = 0; i < rc_mode_size; i++) {
2024
0
        if (!strcmp(nptr, rc_mode[i].name)) {
2025
0
            mode = rc_mode[i].mode;
2026
0
            break;
2027
0
        }
2028
0
    }
2029
2030
0
    switch (mode) {
2031
0
    case RC_MODE_ZERO:
2032
0
        *out = 0;
2033
0
        break;
2034
0
    case RC_MODE_CQP:
2035
0
        *out     = SVT_AV1_RC_MODE_CQP_OR_CRF;
2036
0
        *aq_mode = 0;
2037
0
        break;
2038
0
    case RC_MODE_CRF:
2039
0
        *out     = SVT_AV1_RC_MODE_CQP_OR_CRF;
2040
0
        *aq_mode = 2;
2041
0
        break;
2042
0
    case RC_MODE_VBR:
2043
0
        *out = SVT_AV1_RC_MODE_VBR;
2044
0
        break;
2045
0
    case RC_MODE_CBR:
2046
0
        *out = SVT_AV1_RC_MODE_CBR;
2047
0
        break;
2048
0
    default:
2049
0
        SVT_ERROR("Invalid rc mode: %s\n", nptr);
2050
0
        return EB_ErrorBadParameter;
2051
0
    }
2052
0
    return EB_ErrorNone;
2053
0
}
2054
2055
0
static EbErrorType str_to_pred_struct(const char* nptr, PredStructure* pred_structure) {
2056
0
    const struct {
2057
0
        const char*   name;
2058
0
        PredStructure mode;
2059
0
    } pred_structs[] = {{"0", ALL_INTRA},
2060
0
                        {"all-intra", ALL_INTRA},
2061
0
                        {"ai", ALL_INTRA},
2062
0
                        {"1", LOW_DELAY},
2063
0
                        {"low-delay", LOW_DELAY},
2064
0
                        {"ld", LOW_DELAY},
2065
0
                        {"2", RANDOM_ACCESS},
2066
0
                        {"random-access", RANDOM_ACCESS},
2067
0
                        {"ra", RANDOM_ACCESS}};
2068
2069
0
    const size_t pred_structs_size = sizeof(pred_structs) / sizeof(pred_structs[0]);
2070
2071
0
    for (size_t i = 0; i < pred_structs_size; i++) {
2072
0
        if (!strcmp(nptr, pred_structs[i].name)) {
2073
0
            *pred_structure = pred_structs[i].mode;
2074
0
            return EB_ErrorNone;
2075
0
        }
2076
0
    }
2077
2078
0
    SVT_ERROR("Invalid pred struct: %s\n", nptr);
2079
0
    return EB_ErrorBadParameter;
2080
0
}
2081
2082
0
static EbErrorType str_to_frm_resz_evts(const char* nptr, SvtAv1FrameScaleEvts* evts) {
2083
0
    const uint32_t param_count = count_params(nptr);
2084
0
    if ((evts->evt_num != 0 && evts->evt_num != param_count) || param_count == 0) {
2085
0
        SVT_ERROR("Error: Size for the list passed to %s doesn't match %u\n", "frame-resz-events", evts->evt_num);
2086
0
        return EB_ErrorBadParameter;
2087
0
    }
2088
0
    if (evts->start_frame_nums) {
2089
0
        EB_FREE(evts->start_frame_nums);
2090
0
    }
2091
0
    EB_MALLOC(evts->start_frame_nums, param_count * sizeof(uint64_t));
2092
0
    evts->evt_num = param_count;
2093
0
    return parse_list_uint64(nptr, evts->start_frame_nums, param_count);
2094
0
}
2095
2096
0
static EbErrorType str_to_resz_kf_denoms(const char* nptr, SvtAv1FrameScaleEvts* evts) {
2097
0
    const uint32_t param_count = count_params(nptr);
2098
0
    if ((evts->evt_num != 0 && evts->evt_num != param_count) || param_count == 0) {
2099
0
        SVT_ERROR("Error: Size for the list passed to %s doesn't match %u\n", "frame-resz-kf-denoms", evts->evt_num);
2100
0
        return EB_ErrorBadParameter;
2101
0
    }
2102
0
    if (evts->resize_kf_denoms) {
2103
0
        EB_FREE(evts->resize_kf_denoms);
2104
0
    }
2105
0
    EB_MALLOC(evts->resize_kf_denoms, param_count * sizeof(uint32_t));
2106
0
    evts->evt_num = param_count;
2107
0
    return parse_list_uint32(nptr, evts->resize_kf_denoms, param_count);
2108
0
}
2109
2110
0
static EbErrorType str_to_resz_denoms(const char* nptr, SvtAv1FrameScaleEvts* evts) {
2111
0
    const uint32_t param_count = count_params(nptr);
2112
0
    if ((evts->evt_num != 0 && evts->evt_num != param_count) || param_count == 0) {
2113
0
        SVT_ERROR("Error: Size for the list passed to %s doesn't match %u\n", "frame-resz-denoms", evts->evt_num);
2114
0
        return EB_ErrorBadParameter;
2115
0
    }
2116
0
    if (evts->resize_denoms) {
2117
0
        EB_FREE(evts->resize_denoms);
2118
0
    }
2119
0
    EB_MALLOC(evts->resize_denoms, param_count * sizeof(uint32_t));
2120
0
    evts->evt_num = param_count;
2121
0
    return parse_list_uint32(nptr, evts->resize_denoms, param_count);
2122
0
}
2123
2124
0
static EbErrorType str_to_sframe_posi(const char* nptr, SvtAv1SFramePositions* posis) {
2125
0
    const uint32_t param_count = count_params(nptr);
2126
0
    if ((posis->sframe_num != 0 && posis->sframe_num != param_count) || param_count == 0) {
2127
0
        SVT_ERROR("Error: Size for the list passed to %s doesn't match %u\n", "sframe-posi", posis->sframe_num);
2128
0
        return EB_ErrorBadParameter;
2129
0
    }
2130
0
    if (posis->sframe_posis) {
2131
0
        EB_FREE(posis->sframe_posis);
2132
0
    }
2133
0
    EB_MALLOC(posis->sframe_posis, param_count * sizeof(uint64_t));
2134
0
    posis->sframe_num = param_count;
2135
0
    return parse_list_uint64(nptr, posis->sframe_posis, param_count);
2136
0
}
2137
2138
0
static EbErrorType str_to_sframe_qp(const char* nptr, SvtAv1SFramePositions* posis, uint8_t* qp) {
2139
0
    const uint32_t param_count = count_params(nptr);
2140
0
    if ((posis->sframe_num != 0 && posis->sframe_num != param_count && param_count != 1) || param_count == 0) {
2141
0
        SVT_ERROR("Error: Size for the list passed to %s doesn't match %u\n", "sframe-qp", posis->sframe_num);
2142
0
        return EB_ErrorBadParameter;
2143
0
    }
2144
0
    if (posis->sframe_qps) {
2145
0
        EB_FREE(posis->sframe_qps);
2146
0
    }
2147
0
    EB_MALLOC(posis->sframe_qps, param_count * sizeof(uint8_t));
2148
0
    posis->sframe_qp_num = param_count;
2149
0
    EbErrorType err      = parse_list_uint8(nptr, posis->sframe_qps, param_count);
2150
    // check if the QP values are valid
2151
0
    for (uint32_t i = 0; i < posis->sframe_qp_num; ++i) {
2152
0
        if (posis->sframe_qps[i] < 1 || posis->sframe_qps[i] > 63) {
2153
0
            SVT_ERROR("Error: Invalid S-Frame QP value. QPs must be [1 - 63]\n");
2154
0
            EB_FREE(posis->sframe_qps);
2155
0
            posis->sframe_qp_num = 0;
2156
0
            err                  = EB_ErrorBadParameter;
2157
0
        }
2158
0
    }
2159
    // If sframe-qp parameter contains only one value, apply it to all S-frames
2160
0
    if (err == EB_ErrorNone && param_count == 1) {
2161
0
        *qp = posis->sframe_qps[0];
2162
0
    }
2163
0
    return err;
2164
0
}
2165
2166
0
static EbErrorType str_to_sframe_qp_offset(const char* nptr, SvtAv1SFramePositions* posis, int8_t* qp_offset) {
2167
0
    const uint32_t param_count = count_params(nptr);
2168
0
    if ((posis->sframe_num != 0 && posis->sframe_num != param_count && param_count != 1) || param_count == 0) {
2169
0
        SVT_ERROR("Error: Size for the list passed to %s doesn't match %u\n", "sframe-qp-offset", posis->sframe_num);
2170
0
        return EB_ErrorBadParameter;
2171
0
    }
2172
0
    if (posis->sframe_qp_offsets) {
2173
0
        EB_FREE(posis->sframe_qp_offsets);
2174
0
    }
2175
0
    EB_MALLOC(posis->sframe_qp_offsets, param_count * sizeof(int8_t));
2176
0
    posis->sframe_qp_num = param_count;
2177
0
    EbErrorType err      = parse_list_int8(nptr, posis->sframe_qp_offsets, param_count);
2178
    // check if the QP offset values are valid
2179
0
    for (uint32_t i = 0; i < posis->sframe_qp_num; ++i) {
2180
0
        if (posis->sframe_qp_offsets[i] < -63 || posis->sframe_qp_offsets[i] > 63) {
2181
0
            SVT_ERROR("Error: Invalid S-Frame QP offset value. QP offsets must be [-63 - 63]\n");
2182
0
            EB_FREE(posis->sframe_qp_offsets);
2183
0
            posis->sframe_qp_num = 0;
2184
0
            err                  = EB_ErrorBadParameter;
2185
0
        }
2186
0
    }
2187
    // If sframe-qp-offset parameter contains only one value, apply it to all S-frames
2188
0
    if (err == EB_ErrorNone && param_count == 1) {
2189
0
        *qp_offset = posis->sframe_qp_offsets[0];
2190
0
    }
2191
0
    return err;
2192
0
}
2193
2194
#define COLOR_OPT(par, opt)                                          \
2195
0
    do {                                                             \
2196
0
        if (!strcmp(name, par)) {                                    \
2197
0
            return_error = str_to_##opt(value, &config_struct->opt); \
2198
0
            if (return_error == EB_ErrorNone)                        \
2199
0
                return return_error;                                 \
2200
0
            uint32_t val;                                            \
2201
0
            return_error = str_to_uint(value, &val, NULL);           \
2202
0
            if (return_error == EB_ErrorNone)                        \
2203
0
                config_struct->opt = val;                            \
2204
0
            return return_error;                                     \
2205
0
        }                                                            \
2206
0
    } while (0)
2207
2208
#define COLOR_METADATA_OPT(par, opt)                                                                      \
2209
0
    do {                                                                                                  \
2210
0
        if (!strcmp(name, par))                                                                           \
2211
0
            return svt_aom_parse_##opt(&config_struct->opt, value) ? EB_ErrorNone : EB_ErrorBadParameter; \
2212
0
    } while (0)
2213
2214
EB_API EbErrorType svt_av1_enc_parse_parameter(EbSvtAv1EncConfiguration* config_struct, const char* name,
2215
0
                                               const char* value) {
2216
0
    if (config_struct == NULL || name == NULL || value == NULL) {
2217
0
        return EB_ErrorBadParameter;
2218
0
    }
2219
2220
0
    EbErrorType return_error = EB_ErrorBadParameter;
2221
2222
0
    if (!strcmp(name, "keyint")) {
2223
0
        return str_to_keyint(value, &config_struct->intra_period_length, &config_struct->multiply_keyint);
2224
0
    }
2225
2226
0
    if (!strcmp(name, "tbr")) {
2227
0
        return str_to_bitrate(value, &config_struct->target_bit_rate);
2228
0
    }
2229
2230
0
    if (!strcmp(name, "mbr")) {
2231
0
        return str_to_bitrate(value, &config_struct->max_bit_rate);
2232
0
    }
2233
2234
    // options updating more than one field
2235
0
    if (!strcmp(name, "crf")) {
2236
0
        return str_to_crf(value, config_struct);
2237
0
    }
2238
2239
0
    if (!strcmp(name, "cqp")) {
2240
0
        return str_to_cqp(value, config_struct);
2241
0
    }
2242
2243
0
    if (!strcmp(name, "rc")) {
2244
0
        return str_to_rc_mode(value, &config_struct->rate_control_mode, &config_struct->aq_mode);
2245
0
    }
2246
2247
    // custom enum fields
2248
0
    if (!strcmp(name, "profile")) {
2249
0
        return str_to_profile(value, &config_struct->profile) == EB_ErrorBadParameter
2250
0
            ? str_to_uint(value, (uint32_t*)&config_struct->profile, NULL)
2251
0
            : EB_ErrorNone;
2252
0
    }
2253
2254
0
    if (!strcmp(name, "color-format")) {
2255
0
        return str_to_color_fmt(value, &config_struct->encoder_color_format) == EB_ErrorBadParameter
2256
0
            ? str_to_uint(value, (uint32_t*)&config_struct->encoder_color_format, NULL)
2257
0
            : EB_ErrorNone;
2258
0
    }
2259
2260
0
    if (!strcmp(name, "irefresh-type")) {
2261
0
        return str_to_intra_rt(value, &config_struct->intra_refresh_type) == EB_ErrorBadParameter
2262
0
            ? str_to_uint(value, (uint32_t*)&config_struct->intra_refresh_type, NULL)
2263
0
            : EB_ErrorNone;
2264
0
    }
2265
2266
0
    if (!strcmp(name, "sframe-mode")) {
2267
0
        return str_to_sframe_mode(value, &config_struct->sframe_mode) == EB_ErrorBadParameter
2268
0
            ? str_to_uint(value, (uint32_t*)&config_struct->sframe_mode, NULL)
2269
0
            : EB_ErrorNone;
2270
0
    }
2271
2272
0
    if (!strcmp(name, "asm")) {
2273
0
        return str_to_asm(value, &config_struct->use_cpu_flags);
2274
0
    }
2275
2276
0
    if (!strcmp(name, "pred-struct")) {
2277
0
        return str_to_pred_struct(value, &config_struct->pred_structure);
2278
0
    }
2279
2280
0
    COLOR_OPT("color-primaries", color_primaries);
2281
0
    COLOR_OPT("transfer-characteristics", transfer_characteristics);
2282
0
    COLOR_OPT("matrix-coefficients", matrix_coefficients);
2283
0
    COLOR_OPT("color-range", color_range);
2284
0
    COLOR_OPT("chroma-sample-position", chroma_sample_position);
2285
2286
    // custom struct fields
2287
0
    COLOR_METADATA_OPT("mastering-display", mastering_display);
2288
0
    COLOR_METADATA_OPT("content-light", content_light_level);
2289
2290
    // arrays
2291
0
    if (!strcmp(name, "qindex-offsets")) {
2292
0
        return parse_list_int32(value, config_struct->qindex_offsets, EB_MAX_TEMPORAL_LAYERS);
2293
0
    }
2294
2295
0
    if (!strcmp(name, "chroma-qindex-offsets")) {
2296
0
        return parse_list_int32(value, config_struct->chroma_qindex_offsets, EB_MAX_TEMPORAL_LAYERS);
2297
0
    }
2298
2299
0
    if (!strcmp(name, "lambda-scale-factors")) {
2300
0
        return parse_list_int32(value, config_struct->lambda_scale_factors, SVT_AV1_FRAME_UPDATE_TYPES);
2301
0
    }
2302
2303
0
    if (!strcmp(name, "frame-resz-events")) {
2304
0
        return str_to_frm_resz_evts(value, &config_struct->frame_scale_evts);
2305
0
    }
2306
2307
0
    if (!strcmp(name, "frame-resz-kf-denoms")) {
2308
0
        return str_to_resz_kf_denoms(value, &config_struct->frame_scale_evts);
2309
0
    }
2310
2311
0
    if (!strcmp(name, "frame-resz-denoms")) {
2312
0
        return str_to_resz_denoms(value, &config_struct->frame_scale_evts);
2313
0
    }
2314
2315
0
    if (!strcmp(name, "sframe-posi")) {
2316
0
        return str_to_sframe_posi(value, &config_struct->sframe_posi);
2317
0
    }
2318
2319
0
    if (!strcmp(name, "sframe-qp")) {
2320
0
        return str_to_sframe_qp(value, &config_struct->sframe_posi, &config_struct->sframe_qp);
2321
0
    }
2322
2323
0
    if (!strcmp(name, "sframe-qp-offset")) {
2324
0
        return str_to_sframe_qp_offset(value, &config_struct->sframe_posi, &config_struct->sframe_qp_offset);
2325
0
    }
2326
2327
    // uint32_t fields
2328
0
    const struct {
2329
0
        const char* name;
2330
0
        uint32_t*   out;
2331
0
    } uint_opts[] = {
2332
0
        {"w", &config_struct->source_width},
2333
0
        {"width", &config_struct->source_width},
2334
0
        {"h", &config_struct->source_height},
2335
0
        {"height", &config_struct->source_height},
2336
0
        {"q", &config_struct->qp},
2337
0
        {"qp", &config_struct->qp},
2338
0
        {"film-grain", &config_struct->film_grain_denoise_strength},
2339
0
        {"hierarchical-levels", &config_struct->hierarchical_levels},
2340
0
        {"tier", &config_struct->tier},
2341
0
        {"level", &config_struct->level},
2342
0
        {"lp", &config_struct->level_of_parallelism},
2343
0
        {"fps-num", &config_struct->frame_rate_numerator},
2344
0
        {"fps-denom", &config_struct->frame_rate_denominator},
2345
0
        {"lookahead", &config_struct->look_ahead_distance},
2346
0
        {"scd", &config_struct->scene_change_detection},
2347
0
        {"max-qp", &config_struct->max_qp_allowed},
2348
0
        {"min-qp", &config_struct->min_qp_allowed},
2349
0
        {"minsection-pct", &config_struct->vbr_min_section_pct},
2350
0
        {"maxsection-pct", &config_struct->vbr_max_section_pct},
2351
0
        {"undershoot-pct", &config_struct->under_shoot_pct},
2352
0
        {"overshoot-pct", &config_struct->over_shoot_pct},
2353
0
        {"mbr-overshoot-pct", &config_struct->mbr_over_shoot_pct},
2354
0
        {"max-intra-bitrate-pct", &config_struct->max_intra_bitrate_pct},
2355
0
        {"max-inter-bitrate-pct", &config_struct->max_inter_bitrate_pct},
2356
0
        {"recode-loop", &config_struct->recode_loop},
2357
0
        {"enable-stat-report", &config_struct->stat_report},
2358
0
        {"scm", &config_struct->screen_content_mode},
2359
0
        {"input-depth", &config_struct->encoder_bit_depth},
2360
0
        {"forced-max-frame-width", &config_struct->forced_max_frame_width},
2361
0
        {"forced-max-frame-height", &config_struct->forced_max_frame_height},
2362
0
    };
2363
2364
0
    const size_t uint_opts_size = sizeof(uint_opts) / sizeof(uint_opts[0]);
2365
2366
0
    for (size_t i = 0; i < uint_opts_size; i++) {
2367
0
        if (!strcmp(name, uint_opts[i].name)) {
2368
0
            return str_to_uint(value, uint_opts[i].out, NULL);
2369
0
        }
2370
0
    }
2371
2372
    // uint8_t fields
2373
0
    const struct {
2374
0
        const char* name;
2375
0
        uint8_t*    out;
2376
0
    } uint8_opts[] = {
2377
0
        {"aq-mode", &config_struct->aq_mode},
2378
0
        {"superres-mode", &config_struct->superres_mode},
2379
0
        {"superres-qthres", &config_struct->superres_qthres},
2380
0
        {"superres-kf-qthres", &config_struct->superres_kf_qthres},
2381
0
        {"superres-denom", &config_struct->superres_denom},
2382
0
        {"superres-kf-denom", &config_struct->superres_kf_denom},
2383
0
        {"tune", &config_struct->tune},
2384
0
        {"film-grain-denoise", &config_struct->film_grain_denoise_apply},
2385
0
        {"enable-dlf", &config_struct->enable_dlf_flag},
2386
0
        {"resize-mode", &config_struct->resize_mode},
2387
0
        {"resize-denom", &config_struct->resize_denom},
2388
0
        {"resize-kf-denom", &config_struct->resize_kf_denom},
2389
0
        {"qm-min", &config_struct->min_qm_level},
2390
0
        {"qm-max", &config_struct->max_qm_level},
2391
0
        {"chroma-qm-min", &config_struct->min_chroma_qm_level},
2392
0
        {"chroma-qm-max", &config_struct->max_chroma_qm_level},
2393
0
        {"use-fixed-qindex-offsets", &config_struct->use_fixed_qindex_offsets},
2394
0
        {"startup-mg-size", &config_struct->startup_mg_size},
2395
0
        {"variance-boost-strength", &config_struct->variance_boost_strength},
2396
0
        {"variance-octile", &config_struct->variance_octile},
2397
0
        {"variance-boost-curve", &config_struct->variance_boost_curve},
2398
0
        {"qp-scale-compress-strength", &config_struct->qp_scale_compress_strength},
2399
0
        {"fast-decode", &config_struct->fast_decode},
2400
0
        {"luminance-qp-bias", &config_struct->luminance_qp_bias},
2401
0
        {"enable-tf", &config_struct->enable_tf},
2402
0
        {"tf-strength", &config_struct->tf_strength},
2403
0
        {"max-tx-size", &config_struct->max_tx_size},
2404
0
    };
2405
2406
0
    const size_t uint8_opts_size = sizeof(uint8_opts) / sizeof(uint8_opts[0]);
2407
2408
0
    for (size_t i = 0; i < uint8_opts_size; i++) {
2409
0
        if (!strcmp(name, uint8_opts[i].name)) {
2410
0
            uint32_t val;
2411
0
            return_error = str_to_uint(value, &val, NULL);
2412
0
            if (return_error == EB_ErrorNone) {
2413
                // add protection if the input param is roll-over
2414
0
                if (val > 255) {
2415
0
                    return EB_ErrorBadParameter;
2416
0
                }
2417
0
                *uint8_opts[i].out = val;
2418
0
            }
2419
0
            return return_error;
2420
0
        }
2421
0
    }
2422
2423
    // int64_t fields
2424
0
    const struct {
2425
0
        const char* name;
2426
0
        int64_t*    out;
2427
0
    } int64_opts[] = {
2428
0
        {"buf-initial-sz", &config_struct->starting_buffer_level_ms},
2429
0
        {"buf-optimal-sz", &config_struct->optimal_buffer_level_ms},
2430
0
        {"buf-sz", &config_struct->maximum_buffer_size_ms},
2431
0
    };
2432
2433
0
    const size_t int64_opts_size = sizeof(int64_opts) / sizeof(int64_opts[0]);
2434
2435
0
    for (size_t i = 0; i < int64_opts_size; i++) {
2436
0
        if (!strcmp(name, int64_opts[i].name)) {
2437
0
            return str_to_int64(value, int64_opts[i].out, NULL);
2438
0
        }
2439
0
    }
2440
2441
    // double fields
2442
0
    const struct {
2443
0
        const char* name;
2444
0
        double*     out;
2445
0
    } double_opts[] = {
2446
0
        {"ac-bias", &config_struct->ac_bias},
2447
0
    };
2448
2449
0
    const size_t double_opts_size = sizeof(double_opts) / sizeof(double_opts[0]);
2450
2451
0
    for (size_t i = 0; i < double_opts_size; i++) {
2452
0
        if (!strcmp(name, double_opts[i].name)) {
2453
0
            return str_to_double(value, double_opts[i].out, NULL);
2454
0
        }
2455
0
    }
2456
2457
    // int32_t fields
2458
0
    const struct {
2459
0
        const char* name;
2460
0
        int32_t*    out;
2461
0
    } int_opts[] = {
2462
0
        {"key-frame-chroma-qindex-offset", &config_struct->key_frame_chroma_qindex_offset},
2463
0
        {"key-frame-qindex-offset", &config_struct->key_frame_qindex_offset},
2464
0
        {"luma-y-dc-qindex-offset", &config_struct->luma_y_dc_qindex_offset},
2465
0
        {"chroma-u-dc-qindex-offset", &config_struct->chroma_u_dc_qindex_offset},
2466
0
        {"chroma-u-ac-qindex-offset", &config_struct->chroma_u_ac_qindex_offset},
2467
0
        {"chroma-v-dc-qindex-offset", &config_struct->chroma_v_dc_qindex_offset},
2468
0
        {"chroma-v-ac-qindex-offset", &config_struct->chroma_v_ac_qindex_offset},
2469
0
        {"pass", &config_struct->pass},
2470
0
        {"enable-cdef", &config_struct->cdef_level},
2471
0
        {"enable-restoration", &config_struct->enable_restoration_filtering},
2472
0
        {"enable-mfmv", &config_struct->enable_mfmv},
2473
0
        {"intra-period", &config_struct->intra_period_length},
2474
0
        {"tile-rows", &config_struct->tile_rows},
2475
0
        {"tile-columns", &config_struct->tile_columns},
2476
0
        {"sframe-dist", &config_struct->sframe_dist},
2477
0
        {"hbd-mds", &config_struct->hbd_mds},
2478
0
    };
2479
2480
0
    const size_t int_opts_size = sizeof(int_opts) / sizeof(int_opts[0]);
2481
2482
0
    for (size_t i = 0; i < int_opts_size; i++) {
2483
0
        if (!strcmp(name, int_opts[i].name)) {
2484
0
            return str_to_int(value, int_opts[i].out, NULL);
2485
0
        }
2486
0
    }
2487
2488
    // int8_t fields
2489
0
    const struct {
2490
0
        const char* name;
2491
0
        int8_t*     out;
2492
0
    } int8_opts[] = {
2493
0
        {"preset", &config_struct->enc_mode},
2494
0
        {"sharpness", &config_struct->sharpness},
2495
0
        {"startup-qp-offset", &config_struct->startup_qp_offset},
2496
0
    };
2497
2498
0
    const size_t int8_opts_size = sizeof(int8_opts) / sizeof(int8_opts[0]);
2499
2500
0
    for (size_t i = 0; i < int8_opts_size; i++) {
2501
0
        if (!strcmp(name, int8_opts[i].name)) {
2502
0
            int32_t val;
2503
0
            return_error = str_to_int(value, &val, NULL);
2504
0
            if (return_error == EB_ErrorNone) {
2505
                // add protection if the input param is roll-over
2506
0
                if (val > 127 || val < -128) {
2507
0
                    return EB_ErrorBadParameter;
2508
0
                }
2509
0
                *int8_opts[i].out = val;
2510
0
            }
2511
0
            return return_error;
2512
0
        }
2513
0
    }
2514
2515
    // bool fields
2516
0
    const struct {
2517
0
        const char* name;
2518
0
        bool*       out;
2519
0
    } bool_opts[] = {
2520
0
        {"use-q-file", &config_struct->use_qp_file},
2521
0
        {"enable-overlays", &config_struct->enable_overlays},
2522
0
        {"enable-force-key-frames", &config_struct->force_key_frames},
2523
0
#if CONFIG_ENABLE_QUANT_MATRIX
2524
0
        {"enable-qm", &config_struct->enable_qm},
2525
0
#endif
2526
0
        {"enable-dg", &config_struct->enable_dg},
2527
0
        {"gop-constraint-rc", &config_struct->gop_constraint_rc},
2528
0
        {"enable-variance-boost", &config_struct->enable_variance_boost},
2529
0
        {"lossless", &config_struct->lossless},
2530
0
        {"avif", &config_struct->avif},
2531
0
        {"rtc", &config_struct->rtc},
2532
0
        {"adaptive-film-grain", &config_struct->adaptive_film_grain},
2533
0
        {"enable-kf-tf", &config_struct->enable_tf_key},
2534
0
        {"enable-intrabc", &config_struct->enable_intrabc},
2535
0
    };
2536
0
    const size_t bool_opts_size = sizeof(bool_opts) / sizeof(bool_opts[0]);
2537
2538
0
    for (size_t i = 0; i < bool_opts_size; i++) {
2539
0
        if (!strcmp(name, bool_opts[i].name)) {
2540
0
            return str_to_bool(value, bool_opts[i].out);
2541
0
        }
2542
0
    }
2543
2544
0
    return return_error;
2545
0
}