1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent.
10 */
11 #include <limits.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "config/aom_config.h"
17 #include "config/aom_version.h"
18
19 #include "aom/aomcx.h"
20 #include "aom/aom_encoder.h"
21 #include "aom/aom_external_partition.h"
22 #include "aom/aom_image.h"
23 #include "aom/internal/aom_codec_internal.h"
24 #include "aom_dsp/flow_estimation/flow_estimation.h"
25 #include "aom_mem/aom_mem.h"
26 #include "aom_scale/yv12config.h"
27 #include "aom_util/aom_pthread.h"
28
29 #include "av1/av1_cx_iface.h"
30 #include "av1/av1_iface_common.h"
31 #include "av1/common/av1_common_int.h"
32 #include "av1/common/enums.h"
33 #include "av1/common/scale.h"
34 #include "av1/encoder/bitstream.h"
35 #include "av1/encoder/encoder.h"
36 #include "av1/encoder/encoder_alloc.h"
37 #include "av1/encoder/encoder_utils.h"
38 #include "av1/encoder/ethread.h"
39 #include "av1/encoder/external_partition.h"
40 #include "av1/encoder/firstpass.h"
41 #include "av1/encoder/lookahead.h"
42 #include "av1/encoder/rc_utils.h"
43 #include "av1/arg_defs.h"
44
45 #include "common/args_helper.h"
46
47 struct av1_extracfg {
48 int cpu_used;
49 unsigned int enable_auto_alt_ref;
50 unsigned int enable_auto_bwd_ref;
51 unsigned int noise_sensitivity;
52 unsigned int sharpness;
53 unsigned int static_thresh;
54 unsigned int row_mt;
55 unsigned int fp_mt;
56 unsigned int tile_columns; // log2 number of tile columns
57 unsigned int tile_rows; // log2 number of tile rows
58 unsigned int enable_tpl_model;
59 unsigned int enable_keyframe_filtering;
60 unsigned int arnr_max_frames;
61 unsigned int arnr_strength;
62 unsigned int min_gf_interval;
63 unsigned int max_gf_interval;
64 unsigned int gf_min_pyr_height;
65 unsigned int gf_max_pyr_height;
66 aom_tune_metric tuning;
67 const char *vmaf_model_path;
68 const char *partition_info_path;
69 unsigned int enable_rate_guide_deltaq;
70 const char *rate_distribution_info;
71 aom_dist_metric dist_metric;
72 unsigned int cq_level; // constrained quality level
73 unsigned int rc_max_intra_bitrate_pct;
74 unsigned int rc_max_inter_bitrate_pct;
75 unsigned int gf_cbr_boost_pct;
76 unsigned int lossless;
77 unsigned int enable_cdef;
78 unsigned int enable_restoration;
79 unsigned int force_video_mode;
80 unsigned int enable_obmc;
81 unsigned int disable_trellis_quant;
82 unsigned int enable_qm;
83 unsigned int qm_y;
84 unsigned int qm_u;
85 unsigned int qm_v;
86 unsigned int qm_min;
87 unsigned int qm_max;
88 unsigned int num_tg;
89 unsigned int mtu_size;
90
91 aom_timing_info_type_t timing_info_type;
92 unsigned int frame_parallel_decoding_mode;
93 int enable_dual_filter;
94 unsigned int enable_chroma_deltaq;
95 AQ_MODE aq_mode;
96 DELTAQ_MODE deltaq_mode;
97 int deltaq_strength;
98 int deltalf_mode;
99 unsigned int frame_periodic_boost;
100 aom_bit_depth_t bit_depth;
101 aom_tune_content content;
102 aom_color_primaries_t color_primaries;
103 aom_transfer_characteristics_t transfer_characteristics;
104 aom_matrix_coefficients_t matrix_coefficients;
105 aom_chroma_sample_position_t chroma_sample_position;
106 int color_range;
107 int render_width;
108 int render_height;
109 aom_superblock_size_t superblock_size;
110 unsigned int single_tile_decoding;
111 int error_resilient_mode;
112 int s_frame_mode;
113
114 int film_grain_test_vector;
115 const char *film_grain_table_filename;
116 unsigned int motion_vector_unit_test;
117 #if CONFIG_FPMT_TEST
118 unsigned int fpmt_unit_test;
119 #endif
120 unsigned int cdf_update_mode;
121 int enable_rect_partitions; // enable rectangular partitions for sequence
122 int enable_ab_partitions; // enable AB partitions for sequence
123 int enable_1to4_partitions; // enable 1:4 and 4:1 partitions for sequence
124 int min_partition_size; // min partition size [4,8,16,32,64,128]
125 int max_partition_size; // max partition size [4,8,16,32,64,128]
126 int enable_intra_edge_filter; // enable intra-edge filter for sequence
127 int enable_order_hint; // enable order hint for sequence
128 int enable_tx64; // enable 64-pt transform usage for sequence
129 int enable_flip_idtx; // enable flip and identity transform types
130 int enable_rect_tx; // enable rectangular transform usage for sequence
131 int enable_dist_wtd_comp; // enable dist wtd compound for sequence
132 int max_reference_frames; // maximum number of references per frame
133 int enable_reduced_reference_set; // enable reduced set of references
134 int enable_ref_frame_mvs; // sequence level
135 int allow_ref_frame_mvs; // frame level
136 int enable_masked_comp; // enable masked compound for sequence
137 int enable_onesided_comp; // enable one sided compound for sequence
138 int enable_interintra_comp; // enable interintra compound for sequence
139 int enable_smooth_interintra; // enable smooth interintra mode usage
140 int enable_diff_wtd_comp; // enable diff-wtd compound usage
141 int enable_interinter_wedge; // enable interinter-wedge compound usage
142 int enable_interintra_wedge; // enable interintra-wedge compound usage
143 int enable_global_motion; // enable global motion usage for sequence
144 int enable_warped_motion; // sequence level
145 int allow_warped_motion; // frame level
146 int enable_filter_intra; // enable filter intra for sequence
147 int enable_smooth_intra; // enable smooth intra modes for sequence
148 int enable_paeth_intra; // enable Paeth intra mode for sequence
149 int enable_cfl_intra; // enable CFL uv intra mode for sequence
150 int enable_directional_intra; // enable directional modes for sequence
151 int enable_diagonal_intra; // enable D45 to D203 intra modes for sequence
152 int enable_superres;
153 int enable_overlay; // enable overlay for filtered arf frames
154 int enable_palette;
155 int enable_intrabc;
156 int enable_angle_delta;
157 #if CONFIG_DENOISE
158 float noise_level;
159 int noise_block_size;
160 int enable_dnl_denoising;
161 #endif
162
163 unsigned int chroma_subsampling_x;
164 unsigned int chroma_subsampling_y;
165 int reduced_tx_type_set;
166 int use_intra_dct_only;
167 int use_inter_dct_only;
168 int use_intra_default_tx_only;
169 int enable_tx_size_search;
170 int quant_b_adapt;
171 unsigned int vbr_corpus_complexity_lap;
172 AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
173 // Bit mask to specify which tier each of the 32 possible operating points
174 // conforms to.
175 unsigned int tier_mask;
176 // min_cr / 100 is the target minimum compression ratio for each frame.
177 unsigned int min_cr;
178 COST_UPDATE_TYPE coeff_cost_upd_freq;
179 COST_UPDATE_TYPE mode_cost_upd_freq;
180 COST_UPDATE_TYPE mv_cost_upd_freq;
181 COST_UPDATE_TYPE dv_cost_upd_freq;
182 unsigned int ext_tile_debug;
183 unsigned int sb_multipass_unit_test;
184 // Total number of passes. If this number is -1, then we assume passes = 1 or
185 // 2 (passes = 1 if pass == AOM_RC_ONE_PASS and passes = 2 otherwise).
186 int passes;
187 int fwd_kf_dist;
188
189 LOOPFILTER_CONTROL loopfilter_control;
190 // Indicates if the application of post-processing filters should be skipped
191 // on reconstructed frame.
192 unsigned int skip_postproc_filtering;
193 // the name of the second pass output file when passes > 2
194 const char *two_pass_output;
195 const char *second_pass_log;
196 // Automatically determine whether to disable several intra tools
197 // when "--deltaq-mode=3" is true.
198 // Default as 0.
199 // When set to 1, the encoder will analyze the reconstruction quality
200 // as compared to the source image in the preprocessing pass.
201 // If the recontruction quality is considered high enough, we disable
202 // the following intra coding tools, for better encoding speed:
203 // "--enable_smooth_intra",
204 // "--enable_paeth_intra",
205 // "--enable_cfl_intra",
206 // "--enable_diagonal_intra".
207 int auto_intra_tools_off;
208 int strict_level_conformance;
209 int kf_max_pyr_height;
210 int sb_qp_sweep;
211 };
212
213 #if CONFIG_REALTIME_ONLY
214 // Settings changed for realtime only build:
215 // cpu_used: 7
216 // enable_tpl_model: 0
217 // enable_restoration: 0
218 // enable_obmc: 0
219 // deltaq_mode: NO_DELTA_Q
220 // enable_global_motion usage: 0
221 // enable_warped_motion at sequence level: 0
222 // allow_warped_motion at frame level: 0
223 // coeff_cost_upd_freq: COST_UPD_OFF
224 // mode_cost_upd_freq: COST_UPD_OFF
225 // mv_cost_upd_freq: COST_UPD_OFF
226 // dv_cost_upd_freq: COST_UPD_OFF
227 static const struct av1_extracfg default_extra_cfg = {
228 7, // cpu_used
229 1, // enable_auto_alt_ref
230 0, // enable_auto_bwd_ref
231 0, // noise_sensitivity
232 0, // sharpness
233 0, // static_thresh
234 1, // row_mt
235 0, // fp_mt
236 0, // tile_columns
237 0, // tile_rows
238 0, // enable_tpl_model
239 1, // enable_keyframe_filtering
240 7, // arnr_max_frames
241 5, // arnr_strength
242 0, // min_gf_interval; 0 -> default decision
243 0, // max_gf_interval; 0 -> default decision
244 0, // gf_min_pyr_height
245 5, // gf_max_pyr_height
246 AOM_TUNE_PSNR, // tuning
247 "/usr/local/share/model/vmaf_v0.6.1.json", // VMAF model path
248 ".", // partition info path
249 0, // enable rate guide deltaq
250 "./rate_map.txt", // rate distribution input
251 AOM_DIST_METRIC_PSNR, // dist_metric
252 10, // cq_level
253 0, // rc_max_intra_bitrate_pct
254 0, // rc_max_inter_bitrate_pct
255 0, // gf_cbr_boost_pct
256 0, // lossless
257 1, // enable_cdef
258 0, // enable_restoration
259 0, // force_video_mode
260 0, // enable_obmc
261 3, // disable_trellis_quant
262 0, // enable_qm
263 DEFAULT_QM_Y, // qm_y
264 DEFAULT_QM_U, // qm_u
265 DEFAULT_QM_V, // qm_v
266 DEFAULT_QM_FIRST, // qm_min
267 DEFAULT_QM_LAST, // qm_max
268 1, // max number of tile groups
269 0, // mtu_size
270 AOM_TIMING_UNSPECIFIED, // No picture timing signaling in bitstream
271 0, // frame_parallel_decoding_mode
272 1, // enable dual filter
273 0, // enable delta quant in chroma planes
274 NO_AQ, // aq_mode
275 NO_DELTA_Q, // deltaq_mode
276 100, // deltaq_strength
277 0, // delta lf mode
278 0, // frame_periodic_boost
279 AOM_BITS_8, // Bit depth
280 AOM_CONTENT_DEFAULT, // content
281 AOM_CICP_CP_UNSPECIFIED, // CICP color primaries
282 AOM_CICP_TC_UNSPECIFIED, // CICP transfer characteristics
283 AOM_CICP_MC_UNSPECIFIED, // CICP matrix coefficients
284 AOM_CSP_UNKNOWN, // chroma sample position
285 0, // color range
286 0, // render width
287 0, // render height
288 AOM_SUPERBLOCK_SIZE_DYNAMIC, // superblock_size
289 1, // this depends on large_scale_tile.
290 0, // error_resilient_mode off by default.
291 0, // s_frame_mode off by default.
292 0, // film_grain_test_vector
293 NULL, // film_grain_table_filename
294 0, // motion_vector_unit_test
295 #if CONFIG_FPMT_TEST
296 0, // fpmt_unit_test
297 #endif
298 1, // CDF update mode
299 1, // enable rectangular partitions
300 1, // enable ab shape partitions
301 1, // enable 1:4 and 4:1 partitions
302 4, // min_partition_size
303 128, // max_partition_size
304 1, // enable intra edge filter
305 1, // frame order hint
306 1, // enable 64-pt transform usage
307 1, // enable flip and identity transform
308 1, // enable rectangular transform usage
309 1, // dist-wtd compound
310 7, // max_reference_frames
311 0, // enable_reduced_reference_set
312 1, // enable_ref_frame_mvs sequence level
313 1, // allow ref_frame_mvs frame level
314 1, // enable masked compound at sequence level
315 1, // enable one sided compound at sequence level
316 1, // enable interintra compound at sequence level
317 1, // enable smooth interintra mode
318 1, // enable difference-weighted compound
319 1, // enable interinter wedge compound
320 1, // enable interintra wedge compound
321 0, // enable_global_motion usage
322 0, // enable_warped_motion at sequence level
323 0, // allow_warped_motion at frame level
324 1, // enable filter intra at sequence level
325 1, // enable smooth intra modes usage for sequence
326 1, // enable Paeth intra mode usage for sequence
327 1, // enable CFL uv intra mode usage for sequence
328 1, // enable directional intra mode usage for sequence
329 1, // enable D45 to D203 intra mode usage for sequence
330 1, // superres
331 1, // enable overlay
332 1, // enable palette
333 1, // enable intrabc
334 1, // enable angle delta
335 #if CONFIG_DENOISE
336 0, // noise_level
337 32, // noise_block_size
338 1, // enable_dnl_denoising
339 #endif
340 0, // chroma_subsampling_x
341 0, // chroma_subsampling_y
342 0, // reduced_tx_type_set
343 0, // use_intra_dct_only
344 0, // use_inter_dct_only
345 0, // use_intra_default_tx_only
346 1, // enable_tx_size_search
347 0, // quant_b_adapt
348 0, // vbr_corpus_complexity_lap
349 {
350 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
351 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
352 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
353 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
354 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
355 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
356 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
357 }, // target_seq_level_idx
358 0, // tier_mask
359 0, // min_cr
360 COST_UPD_OFF, // coeff_cost_upd_freq
361 COST_UPD_OFF, // mode_cost_upd_freq
362 COST_UPD_OFF, // mv_cost_upd_freq
363 COST_UPD_OFF, // dv_cost_upd_freq
364 0, // ext_tile_debug
365 0, // sb_multipass_unit_test
366 -1, // passes
367 -1, // fwd_kf_dist
368 LOOPFILTER_ALL, // loopfilter_control
369 0, // skip_postproc_filtering
370 NULL, // two_pass_output
371 NULL, // second_pass_log
372 0, // auto_intra_tools_off
373 0, // strict_level_conformance
374 -1, // kf_max_pyr_height
375 0, // sb_qp_sweep
376 };
377 #else
378 static const struct av1_extracfg default_extra_cfg = {
379 0, // cpu_used
380 1, // enable_auto_alt_ref
381 0, // enable_auto_bwd_ref
382 0, // noise_sensitivity
383 0, // sharpness
384 0, // static_thresh
385 1, // row_mt
386 0, // fp_mt
387 0, // tile_columns
388 0, // tile_rows
389 1, // enable_tpl_model
390 1, // enable_keyframe_filtering
391 7, // arnr_max_frames
392 5, // arnr_strength
393 0, // min_gf_interval; 0 -> default decision
394 0, // max_gf_interval; 0 -> default decision
395 0, // gf_min_pyr_height
396 5, // gf_max_pyr_height
397 AOM_TUNE_PSNR, // tuning
398 "/usr/local/share/model/vmaf_v0.6.1.json", // VMAF model path
399 ".", // partition info path
400 0, // enable rate guide deltaq
401 "./rate_map.txt", // rate distribution input
402 AOM_DIST_METRIC_PSNR, // dist_metric
403 10, // cq_level
404 0, // rc_max_intra_bitrate_pct
405 0, // rc_max_inter_bitrate_pct
406 0, // gf_cbr_boost_pct
407 0, // lossless
408 1, // enable_cdef
409 1, // enable_restoration
410 0, // force_video_mode
411 1, // enable_obmc
412 3, // disable_trellis_quant
413 0, // enable_qm
414 DEFAULT_QM_Y, // qm_y
415 DEFAULT_QM_U, // qm_u
416 DEFAULT_QM_V, // qm_v
417 DEFAULT_QM_FIRST, // qm_min
418 DEFAULT_QM_LAST, // qm_max
419 1, // max number of tile groups
420 0, // mtu_size
421 AOM_TIMING_UNSPECIFIED, // No picture timing signaling in bitstream
422 0, // frame_parallel_decoding_mode
423 1, // enable dual filter
424 0, // enable delta quant in chroma planes
425 NO_AQ, // aq_mode
426 DELTA_Q_OBJECTIVE, // deltaq_mode
427 100, // deltaq_strength
428 0, // delta lf mode
429 0, // frame_periodic_boost
430 AOM_BITS_8, // Bit depth
431 AOM_CONTENT_DEFAULT, // content
432 AOM_CICP_CP_UNSPECIFIED, // CICP color primaries
433 AOM_CICP_TC_UNSPECIFIED, // CICP transfer characteristics
434 AOM_CICP_MC_UNSPECIFIED, // CICP matrix coefficients
435 AOM_CSP_UNKNOWN, // chroma sample position
436 0, // color range
437 0, // render width
438 0, // render height
439 AOM_SUPERBLOCK_SIZE_DYNAMIC, // superblock_size
440 1, // this depends on large_scale_tile.
441 0, // error_resilient_mode off by default.
442 0, // s_frame_mode off by default.
443 0, // film_grain_test_vector
444 NULL, // film_grain_table_filename
445 0, // motion_vector_unit_test
446 #if CONFIG_FPMT_TEST
447 0, // fpmt_unit_test
448 #endif
449 1, // CDF update mode
450 1, // enable rectangular partitions
451 1, // enable ab shape partitions
452 1, // enable 1:4 and 4:1 partitions
453 4, // min_partition_size
454 128, // max_partition_size
455 1, // enable intra edge filter
456 1, // frame order hint
457 1, // enable 64-pt transform usage
458 1, // enable flip and identity transform
459 1, // enable rectangular transform usage
460 1, // dist-wtd compound
461 7, // max_reference_frames
462 0, // enable_reduced_reference_set
463 1, // enable_ref_frame_mvs sequence level
464 1, // allow ref_frame_mvs frame level
465 1, // enable masked compound at sequence level
466 1, // enable one sided compound at sequence level
467 1, // enable interintra compound at sequence level
468 1, // enable smooth interintra mode
469 1, // enable difference-weighted compound
470 1, // enable interinter wedge compound
471 1, // enable interintra wedge compound
472 1, // enable_global_motion usage
473 1, // enable_warped_motion at sequence level
474 1, // allow_warped_motion at frame level
475 1, // enable filter intra at sequence level
476 1, // enable smooth intra modes usage for sequence
477 1, // enable Paeth intra mode usage for sequence
478 1, // enable CFL uv intra mode usage for sequence
479 1, // enable directional intra mode usage for sequence
480 1, // enable D45 to D203 intra mode usage for sequence
481 1, // superres
482 1, // enable overlay
483 1, // enable palette
484 1, // enable intrabc
485 1, // enable angle delta
486 #if CONFIG_DENOISE
487 0, // noise_level
488 32, // noise_block_size
489 1, // enable_dnl_denoising
490 #endif
491 0, // chroma_subsampling_x
492 0, // chroma_subsampling_y
493 0, // reduced_tx_type_set
494 0, // use_intra_dct_only
495 0, // use_inter_dct_only
496 0, // use_intra_default_tx_only
497 1, // enable_tx_size_search
498 0, // quant_b_adapt
499 0, // vbr_corpus_complexity_lap
500 {
501 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
502 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
503 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
504 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
505 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
506 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
507 SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
508 }, // target_seq_level_idx
509 0, // tier_mask
510 0, // min_cr
511 COST_UPD_SB, // coeff_cost_upd_freq
512 COST_UPD_SB, // mode_cost_upd_freq
513 COST_UPD_SB, // mv_cost_upd_freq
514 COST_UPD_SB, // dv_cost_upd_freq
515 0, // ext_tile_debug
516 0, // sb_multipass_unit_test
517 -1, // passes
518 -1, // fwd_kf_dist
519 LOOPFILTER_ALL, // loopfilter_control
520 0, // skip_postproc_filtering
521 NULL, // two_pass_output
522 NULL, // second_pass_log
523 0, // auto_intra_tools_off
524 0, // strict_level_conformance
525 -1, // kf_max_pyr_height
526 0, // sb_qp_sweep
527 };
528 #endif
529
530 struct aom_codec_alg_priv {
531 aom_codec_priv_t base;
532 aom_codec_enc_cfg_t cfg;
533 struct av1_extracfg extra_cfg;
534 aom_rational64_t timestamp_ratio;
535 aom_codec_pts_t pts_offset;
536 unsigned char pts_offset_initialized;
537 AV1EncoderConfig oxcf;
538 AV1_PRIMARY *ppi;
539 unsigned char *cx_data;
540 size_t cx_data_sz;
541 size_t pending_cx_data_sz;
542 aom_image_t preview_img;
543 aom_enc_frame_flags_t next_frame_flags;
544 aom_codec_pkt_list_decl(256) pkt_list;
545 unsigned int fixed_kf_cntr;
546 // BufferPool that holds all reference frames.
547 BufferPool *buffer_pool;
548
549 // lookahead instance variables
550 BufferPool *buffer_pool_lap;
551 FIRSTPASS_STATS *frame_stats_buffer;
552 // Number of stats buffers required for look ahead
553 int num_lap_buffers;
554 STATS_BUFFER_CTX stats_buf_context;
555 bool monochrome_on_init;
556 };
557
gcd(int64_t a,int b)558 static INLINE int gcd(int64_t a, int b) {
559 int remainder;
560 while (b > 0) {
561 remainder = (int)(a % b);
562 a = b;
563 b = remainder;
564 }
565
566 return (int)a;
567 }
568
reduce_ratio(aom_rational64_t * ratio)569 static void reduce_ratio(aom_rational64_t *ratio) {
570 const int denom = gcd(ratio->num, ratio->den);
571 ratio->num /= denom;
572 ratio->den /= denom;
573 }
574
575 // Called by encoder_encode() only. Must not be called by encoder_init()
576 // because the `error` paramerer will be destroyed by aom_codec_enc_init_ver()
577 // after encoder_init() returns an error. See the "IMPORTANT" comment in
578 // aom_codec_enc_init_ver().
update_error_state(aom_codec_alg_priv_t * ctx,const struct aom_internal_error_info * error)579 static aom_codec_err_t update_error_state(
580 aom_codec_alg_priv_t *ctx, const struct aom_internal_error_info *error) {
581 const aom_codec_err_t res = error->error_code;
582
583 if (res != AOM_CODEC_OK)
584 ctx->base.err_detail = error->has_detail ? error->detail : NULL;
585
586 return res;
587 }
588
589 // This function deep copies a string src to *dst. For default string we will
590 // use a string literal, and otherwise we will allocate memory for the string.
allocate_and_set_string(const char * src,const char * default_src,const char ** dst,char * err_detail)591 static aom_codec_err_t allocate_and_set_string(const char *src,
592 const char *default_src,
593 const char **dst,
594 char *err_detail) {
595 if (!src) {
596 snprintf(err_detail, ARG_ERR_MSG_MAX_LEN,
597 "Null pointer given to a string parameter.");
598 return AOM_CODEC_INVALID_PARAM;
599 }
600 if (*dst && strcmp(src, *dst) == 0) return AOM_CODEC_OK;
601 // If the input is exactly the same as default, we will use the string
602 // literal, so do not free here.
603 if (*dst != default_src) {
604 aom_free((void *)*dst);
605 }
606
607 if (default_src && strcmp(src, default_src) == 0) {
608 // default_src should be a string literal
609 *dst = default_src;
610 } else {
611 size_t len = strlen(src) + 1;
612 char *tmp = aom_malloc(len * sizeof(*tmp));
613 if (!tmp) {
614 snprintf(err_detail, ARG_ERR_MSG_MAX_LEN,
615 "Failed to allocate memory for copying parameters.");
616 return AOM_CODEC_MEM_ERROR;
617 }
618 memcpy(tmp, src, len);
619 *dst = tmp;
620 }
621 return 0;
622 }
623
624 #undef ERROR
625 #define ERROR(str) \
626 do { \
627 ctx->base.err_detail = str; \
628 return AOM_CODEC_INVALID_PARAM; \
629 } while (0)
630
631 #define RANGE_CHECK(p, memb, lo, hi) \
632 do { \
633 if (!((p)->memb >= (lo) && (p)->memb <= (hi))) \
634 ERROR(#memb " out of range [" #lo ".." #hi "]"); \
635 } while (0)
636
637 #define RANGE_CHECK_HI(p, memb, hi) \
638 do { \
639 if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
640 } while (0)
641
642 #define RANGE_CHECK_BOOL(p, memb) \
643 do { \
644 if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \
645 } while (0)
646
validate_config(aom_codec_alg_priv_t * ctx,const aom_codec_enc_cfg_t * cfg,const struct av1_extracfg * extra_cfg)647 static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
648 const aom_codec_enc_cfg_t *cfg,
649 const struct av1_extracfg *extra_cfg) {
650 RANGE_CHECK(cfg, g_w, 1, 65536); // 16 bits available
651 RANGE_CHECK(cfg, g_h, 1, 65536); // 16 bits available
652 RANGE_CHECK_HI(cfg, g_forced_max_frame_width, 65536); // 16 bits available
653 RANGE_CHECK_HI(cfg, g_forced_max_frame_height, 65536); // 16 bits available
654 if (cfg->g_forced_max_frame_width) {
655 RANGE_CHECK_HI(cfg, g_w, cfg->g_forced_max_frame_width);
656 }
657 if (cfg->g_forced_max_frame_height) {
658 RANGE_CHECK_HI(cfg, g_h, cfg->g_forced_max_frame_height);
659 }
660 // To avoid integer overflows when multiplying width by height (or values
661 // derived from width and height) using the int type, impose a maximum frame
662 // area (width * height) of 2^30.
663 const unsigned int max_frame_width =
664 cfg->g_forced_max_frame_width ? cfg->g_forced_max_frame_width : cfg->g_w;
665 const unsigned int max_frame_height = cfg->g_forced_max_frame_height
666 ? cfg->g_forced_max_frame_height
667 : cfg->g_h;
668 const int64_t max_frame_area = (int64_t)max_frame_width * max_frame_height;
669 if (max_frame_area > (1 << 30)) {
670 ERROR("max_frame_area out of range [..2^30]");
671 }
672 RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
673 RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
674 RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);
675
676 RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
677 RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
678 RANGE_CHECK_BOOL(extra_cfg, lossless);
679 RANGE_CHECK_HI(extra_cfg, aq_mode, AQ_MODE_COUNT - 1);
680 RANGE_CHECK_HI(extra_cfg, deltaq_mode, DELTA_Q_MODE_COUNT - 1);
681 RANGE_CHECK_HI(extra_cfg, deltalf_mode, 1);
682 RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
683 #if CONFIG_REALTIME_ONLY
684 RANGE_CHECK(cfg, g_usage, AOM_USAGE_REALTIME, AOM_USAGE_REALTIME);
685 #else
686 RANGE_CHECK_HI(cfg, g_usage, AOM_USAGE_ALL_INTRA);
687 #endif
688 RANGE_CHECK_HI(cfg, g_threads, MAX_NUM_THREADS);
689 RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
690 RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
691 RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
692 RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
693 RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
694 RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
695 RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_THIRD_PASS);
696 RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
697 if (cfg->g_usage == AOM_USAGE_ALL_INTRA) {
698 RANGE_CHECK_HI(cfg, g_lag_in_frames, 0);
699 RANGE_CHECK_HI(cfg, kf_max_dist, 0);
700 }
701 RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
702 RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
703 if (extra_cfg->max_gf_interval > 0) {
704 RANGE_CHECK(extra_cfg, max_gf_interval,
705 AOMMAX(2, extra_cfg->min_gf_interval), (MAX_LAG_BUFFERS - 1));
706 }
707 RANGE_CHECK_HI(extra_cfg, gf_min_pyr_height, 5);
708 RANGE_CHECK_HI(extra_cfg, gf_max_pyr_height, 5);
709 if (extra_cfg->gf_min_pyr_height > extra_cfg->gf_max_pyr_height) {
710 ERROR(
711 "gf_min_pyr_height must be less than or equal to "
712 "gf_max_pyramid_height");
713 }
714
715 RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
716 RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
717 SCALE_NUMERATOR << 1);
718 RANGE_CHECK(cfg, rc_resize_kf_denominator, SCALE_NUMERATOR,
719 SCALE_NUMERATOR << 1);
720 RANGE_CHECK_HI(cfg, rc_superres_mode, AOM_SUPERRES_AUTO);
721 RANGE_CHECK(cfg, rc_superres_denominator, SCALE_NUMERATOR,
722 SCALE_NUMERATOR << 1);
723 RANGE_CHECK(cfg, rc_superres_kf_denominator, SCALE_NUMERATOR,
724 SCALE_NUMERATOR << 1);
725 RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63);
726 RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
727 RANGE_CHECK_HI(extra_cfg, cdf_update_mode, 2);
728
729 RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
730 #if CONFIG_FPMT_TEST
731 RANGE_CHECK_HI(extra_cfg, fpmt_unit_test, 1);
732 #endif
733 RANGE_CHECK_HI(extra_cfg, sb_multipass_unit_test, 1);
734 RANGE_CHECK_HI(extra_cfg, ext_tile_debug, 1);
735 RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 1);
736 RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
737 RANGE_CHECK(extra_cfg, cpu_used, 0,
738 (cfg->g_usage == AOM_USAGE_REALTIME) ? 11 : 9);
739 RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
740 RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
741 AOM_SUPERBLOCK_SIZE_DYNAMIC);
742 RANGE_CHECK_HI(cfg, large_scale_tile, 1);
743 RANGE_CHECK_HI(extra_cfg, single_tile_decoding, 1);
744 RANGE_CHECK_HI(extra_cfg, enable_rate_guide_deltaq, 1);
745
746 RANGE_CHECK_HI(extra_cfg, row_mt, 1);
747 RANGE_CHECK_HI(extra_cfg, fp_mt, 1);
748
749 RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
750 RANGE_CHECK_HI(extra_cfg, tile_rows, 6);
751
752 RANGE_CHECK_HI(cfg, monochrome, 1);
753
754 if (cfg->large_scale_tile && extra_cfg->aq_mode)
755 ERROR(
756 "Adaptive quantization are not supported in large scale tile "
757 "coding.");
758
759 RANGE_CHECK_HI(extra_cfg, sharpness, 7);
760 RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
761 RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
762 RANGE_CHECK_HI(extra_cfg, cq_level, 63);
763 RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
764 RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
765 RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);
766
767 if (cfg->g_pass >= AOM_RC_SECOND_PASS) {
768 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
769 const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
770 const FIRSTPASS_STATS *stats;
771
772 if (cfg->rc_twopass_stats_in.buf == NULL)
773 ERROR("rc_twopass_stats_in.buf not set.");
774
775 if (cfg->rc_twopass_stats_in.sz % packet_sz)
776 ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
777
778 if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
779 ERROR("rc_twopass_stats_in requires at least two packets.");
780
781 stats =
782 (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
783
784 if ((int)(stats->count + 0.5) != n_packets - 1)
785 ERROR("rc_twopass_stats_in missing EOS stats packet");
786 }
787
788 if (extra_cfg->passes != -1 && cfg->g_pass == AOM_RC_ONE_PASS &&
789 extra_cfg->passes != 1) {
790 ERROR("One pass encoding but passes != 1.");
791 }
792
793 if (extra_cfg->passes != -1 && (int)cfg->g_pass > extra_cfg->passes) {
794 ERROR("Current pass is larger than total number of passes.");
795 }
796
797 if (cfg->g_profile == (unsigned int)PROFILE_1 && cfg->monochrome) {
798 ERROR("Monochrome is not supported in profile 1");
799 }
800
801 if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
802 cfg->g_bit_depth > AOM_BITS_10) {
803 ERROR("Codec bit-depth 12 not supported in profile < 2");
804 }
805 if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
806 cfg->g_input_bit_depth > 10) {
807 ERROR("Source bit-depth 12 not supported in profile < 2");
808 }
809
810 if (cfg->rc_end_usage == AOM_Q) {
811 RANGE_CHECK_HI(cfg, use_fixed_qp_offsets, 1);
812 } else {
813 if (cfg->use_fixed_qp_offsets > 0) {
814 ERROR("--use_fixed_qp_offsets can only be used with --end-usage=q");
815 }
816 }
817
818 RANGE_CHECK(extra_cfg, color_primaries, AOM_CICP_CP_BT_709,
819 AOM_CICP_CP_EBU_3213); // Need to check range more precisely to
820 // check for reserved values?
821 RANGE_CHECK(extra_cfg, transfer_characteristics, AOM_CICP_TC_BT_709,
822 AOM_CICP_TC_HLG);
823 RANGE_CHECK(extra_cfg, matrix_coefficients, AOM_CICP_MC_IDENTITY,
824 AOM_CICP_MC_ICTCP);
825 RANGE_CHECK(extra_cfg, color_range, 0, 1);
826
827 /* Average corpus complexity is supported only in the case of single pass
828 * VBR*/
829 if (cfg->g_pass == AOM_RC_ONE_PASS && cfg->rc_end_usage == AOM_VBR)
830 RANGE_CHECK_HI(extra_cfg, vbr_corpus_complexity_lap,
831 MAX_VBR_CORPUS_COMPLEXITY);
832 else if (extra_cfg->vbr_corpus_complexity_lap != 0)
833 ERROR(
834 "VBR corpus complexity is supported only in the case of single pass "
835 "VBR mode.");
836
837 #if !CONFIG_TUNE_BUTTERAUGLI
838 if (extra_cfg->tuning == AOM_TUNE_BUTTERAUGLI) {
839 ERROR(
840 "This error may be related to the wrong configuration options: try to "
841 "set -DCONFIG_TUNE_BUTTERAUGLI=1 at the time CMake is run.");
842 }
843 #endif
844
845 #if !CONFIG_TUNE_VMAF
846 if (extra_cfg->tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
847 extra_cfg->tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
848 ERROR(
849 "This error may be related to the wrong configuration options: try to "
850 "set -DCONFIG_TUNE_VMAF=1 at the time CMake is run.");
851 }
852 #endif
853
854 RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_VMAF_SALIENCY_MAP);
855
856 RANGE_CHECK(extra_cfg, dist_metric, AOM_DIST_METRIC_PSNR,
857 AOM_DIST_METRIC_QM_PSNR);
858
859 RANGE_CHECK(extra_cfg, timing_info_type, AOM_TIMING_UNSPECIFIED,
860 AOM_TIMING_DEC_MODEL);
861
862 RANGE_CHECK(extra_cfg, film_grain_test_vector, 0, 16);
863
864 if (extra_cfg->lossless) {
865 if (extra_cfg->aq_mode != 0)
866 ERROR("Only --aq_mode=0 can be used with --lossless=1.");
867 if (extra_cfg->enable_chroma_deltaq)
868 ERROR("Only --enable_chroma_deltaq=0 can be used with --lossless=1.");
869 }
870
871 RANGE_CHECK(extra_cfg, max_reference_frames, 3, 7);
872 RANGE_CHECK(extra_cfg, enable_reduced_reference_set, 0, 1);
873 RANGE_CHECK_HI(extra_cfg, chroma_subsampling_x, 1);
874 RANGE_CHECK_HI(extra_cfg, chroma_subsampling_y, 1);
875
876 RANGE_CHECK_HI(extra_cfg, disable_trellis_quant, 3);
877 RANGE_CHECK(extra_cfg, coeff_cost_upd_freq, 0, 3);
878 RANGE_CHECK(extra_cfg, mode_cost_upd_freq, 0, 3);
879 RANGE_CHECK(extra_cfg, mv_cost_upd_freq, 0, 3);
880 RANGE_CHECK(extra_cfg, dv_cost_upd_freq, 0, 3);
881
882 RANGE_CHECK(extra_cfg, min_partition_size, 4, 128);
883 RANGE_CHECK(extra_cfg, max_partition_size, 4, 128);
884 RANGE_CHECK_HI(extra_cfg, min_partition_size, extra_cfg->max_partition_size);
885
886 for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
887 const int level_idx = extra_cfg->target_seq_level_idx[i];
888 if (!is_valid_seq_level_idx(level_idx) &&
889 level_idx != SEQ_LEVEL_KEEP_STATS) {
890 ERROR("Target sequence level index is invalid");
891 }
892 }
893
894 RANGE_CHECK(extra_cfg, deltaq_strength, 0, 1000);
895 RANGE_CHECK_HI(extra_cfg, loopfilter_control, 3);
896 RANGE_CHECK_BOOL(extra_cfg, skip_postproc_filtering);
897 RANGE_CHECK_HI(extra_cfg, enable_cdef, 2);
898 RANGE_CHECK_BOOL(extra_cfg, auto_intra_tools_off);
899 RANGE_CHECK_BOOL(extra_cfg, strict_level_conformance);
900 RANGE_CHECK_BOOL(extra_cfg, sb_qp_sweep);
901
902 RANGE_CHECK(extra_cfg, kf_max_pyr_height, -1, 5);
903 if (extra_cfg->kf_max_pyr_height != -1 &&
904 extra_cfg->kf_max_pyr_height < (int)extra_cfg->gf_min_pyr_height) {
905 ERROR(
906 "The value of kf-max-pyr-height should not be smaller than "
907 "gf-min-pyr-height");
908 }
909
910 return AOM_CODEC_OK;
911 }
912
validate_img(aom_codec_alg_priv_t * ctx,const aom_image_t * img)913 static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
914 const aom_image_t *img) {
915 switch (img->fmt) {
916 case AOM_IMG_FMT_YV12:
917 case AOM_IMG_FMT_NV12:
918 case AOM_IMG_FMT_I420:
919 case AOM_IMG_FMT_YV1216:
920 case AOM_IMG_FMT_I42016: break;
921 case AOM_IMG_FMT_I444:
922 case AOM_IMG_FMT_I44416:
923 if (ctx->cfg.g_profile == (unsigned int)PROFILE_0 &&
924 !ctx->cfg.monochrome) {
925 ERROR("Invalid image format. I444 images not supported in profile.");
926 }
927 break;
928 case AOM_IMG_FMT_I422:
929 case AOM_IMG_FMT_I42216:
930 if (ctx->cfg.g_profile != (unsigned int)PROFILE_2) {
931 ERROR("Invalid image format. I422 images not supported in profile.");
932 }
933 break;
934 default:
935 ERROR(
936 "Invalid image format. Only YV12, NV12, I420, I422, I444 images are "
937 "supported.");
938 break;
939 }
940
941 if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
942 ERROR("Image size must match encoder init configuration size");
943
944 #if CONFIG_TUNE_BUTTERAUGLI
945 if (ctx->extra_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
946 if (img->bit_depth > 8) {
947 ERROR("Only 8 bit depth images supported in tune=butteraugli mode.");
948 }
949 if (img->mc != 0 && img->mc != AOM_CICP_MC_BT_709 &&
950 img->mc != AOM_CICP_MC_BT_601 && img->mc != AOM_CICP_MC_BT_470_B_G) {
951 ERROR(
952 "Only BT.709 and BT.601 matrix coefficients supported in "
953 "tune=butteraugli mode. Identity matrix is treated as BT.601.");
954 }
955 }
956 #endif
957
958 return AOM_CODEC_OK;
959 }
960
get_image_bps(const aom_image_t * img)961 static int get_image_bps(const aom_image_t *img) {
962 switch (img->fmt) {
963 case AOM_IMG_FMT_YV12:
964 case AOM_IMG_FMT_NV12:
965 case AOM_IMG_FMT_I420: return 12;
966 case AOM_IMG_FMT_I422: return 16;
967 case AOM_IMG_FMT_I444: return 24;
968 case AOM_IMG_FMT_YV1216:
969 case AOM_IMG_FMT_I42016: return 24;
970 case AOM_IMG_FMT_I42216: return 32;
971 case AOM_IMG_FMT_I44416: return 48;
972 default: assert(0 && "Invalid image format"); break;
973 }
974 return 0;
975 }
976
977 // Set appropriate options to disable frame super-resolution.
disable_superres(SuperResCfg * const superres_cfg)978 static void disable_superres(SuperResCfg *const superres_cfg) {
979 superres_cfg->superres_mode = AOM_SUPERRES_NONE;
980 superres_cfg->superres_scale_denominator = SCALE_NUMERATOR;
981 superres_cfg->superres_kf_scale_denominator = SCALE_NUMERATOR;
982 superres_cfg->superres_qthresh = 255;
983 superres_cfg->superres_kf_qthresh = 255;
984 }
985
update_default_encoder_config(const cfg_options_t * cfg,struct av1_extracfg * extra_cfg)986 static void update_default_encoder_config(const cfg_options_t *cfg,
987 struct av1_extracfg *extra_cfg) {
988 extra_cfg->enable_cdef = (cfg->disable_cdef == 0) ? 1 : 0;
989 extra_cfg->enable_restoration = (cfg->disable_lr == 0);
990 extra_cfg->superblock_size =
991 (cfg->super_block_size == 64) ? AOM_SUPERBLOCK_SIZE_64X64
992 : (cfg->super_block_size == 128) ? AOM_SUPERBLOCK_SIZE_128X128
993 : AOM_SUPERBLOCK_SIZE_DYNAMIC;
994 extra_cfg->enable_warped_motion = (cfg->disable_warp_motion == 0);
995 extra_cfg->enable_dist_wtd_comp = (cfg->disable_dist_wtd_comp == 0);
996 extra_cfg->enable_diff_wtd_comp = (cfg->disable_diff_wtd_comp == 0);
997 extra_cfg->enable_dual_filter = (cfg->disable_dual_filter == 0);
998 extra_cfg->enable_angle_delta = (cfg->disable_intra_angle_delta == 0);
999 extra_cfg->enable_rect_partitions = (cfg->disable_rect_partition_type == 0);
1000 extra_cfg->enable_ab_partitions = (cfg->disable_ab_partition_type == 0);
1001 extra_cfg->enable_1to4_partitions = (cfg->disable_1to4_partition_type == 0);
1002 extra_cfg->max_partition_size = cfg->max_partition_size;
1003 extra_cfg->min_partition_size = cfg->min_partition_size;
1004 extra_cfg->enable_intra_edge_filter = (cfg->disable_intra_edge_filter == 0);
1005 extra_cfg->enable_tx64 = (cfg->disable_tx_64x64 == 0);
1006 extra_cfg->enable_flip_idtx = (cfg->disable_flip_idtx == 0);
1007 extra_cfg->enable_masked_comp = (cfg->disable_masked_comp == 0);
1008 extra_cfg->enable_interintra_comp = (cfg->disable_inter_intra_comp == 0);
1009 extra_cfg->enable_smooth_interintra = (cfg->disable_smooth_inter_intra == 0);
1010 extra_cfg->enable_interinter_wedge = (cfg->disable_inter_inter_wedge == 0);
1011 extra_cfg->enable_interintra_wedge = (cfg->disable_inter_intra_wedge == 0);
1012 extra_cfg->enable_global_motion = (cfg->disable_global_motion == 0);
1013 extra_cfg->enable_filter_intra = (cfg->disable_filter_intra == 0);
1014 extra_cfg->enable_smooth_intra = (cfg->disable_smooth_intra == 0);
1015 extra_cfg->enable_paeth_intra = (cfg->disable_paeth_intra == 0);
1016 extra_cfg->enable_cfl_intra = (cfg->disable_cfl == 0);
1017 extra_cfg->enable_obmc = (cfg->disable_obmc == 0);
1018 extra_cfg->enable_palette = (cfg->disable_palette == 0);
1019 extra_cfg->enable_intrabc = (cfg->disable_intrabc == 0);
1020 extra_cfg->disable_trellis_quant = cfg->disable_trellis_quant;
1021 extra_cfg->allow_ref_frame_mvs = (cfg->disable_ref_frame_mv == 0);
1022 extra_cfg->enable_ref_frame_mvs = (cfg->disable_ref_frame_mv == 0);
1023 extra_cfg->enable_onesided_comp = (cfg->disable_one_sided_comp == 0);
1024 extra_cfg->enable_reduced_reference_set = cfg->reduced_reference_set;
1025 extra_cfg->reduced_tx_type_set = cfg->reduced_tx_type_set;
1026 }
1027
set_encoder_config(AV1EncoderConfig * oxcf,const aom_codec_enc_cfg_t * cfg,struct av1_extracfg * extra_cfg)1028 static void set_encoder_config(AV1EncoderConfig *oxcf,
1029 const aom_codec_enc_cfg_t *cfg,
1030 struct av1_extracfg *extra_cfg) {
1031 if (cfg->encoder_cfg.init_by_cfg_file) {
1032 update_default_encoder_config(&cfg->encoder_cfg, extra_cfg);
1033 }
1034
1035 TuneCfg *const tune_cfg = &oxcf->tune_cfg;
1036
1037 FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
1038
1039 TileConfig *const tile_cfg = &oxcf->tile_cfg;
1040
1041 ResizeCfg *const resize_cfg = &oxcf->resize_cfg;
1042
1043 GFConfig *const gf_cfg = &oxcf->gf_cfg;
1044
1045 PartitionCfg *const part_cfg = &oxcf->part_cfg;
1046
1047 IntraModeCfg *const intra_mode_cfg = &oxcf->intra_mode_cfg;
1048
1049 TxfmSizeTypeCfg *const txfm_cfg = &oxcf->txfm_cfg;
1050
1051 CompoundTypeCfg *const comp_type_cfg = &oxcf->comp_type_cfg;
1052
1053 SuperResCfg *const superres_cfg = &oxcf->superres_cfg;
1054
1055 KeyFrameCfg *const kf_cfg = &oxcf->kf_cfg;
1056
1057 DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
1058
1059 RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
1060
1061 QuantizationCfg *const q_cfg = &oxcf->q_cfg;
1062
1063 ColorCfg *const color_cfg = &oxcf->color_cfg;
1064
1065 InputCfg *const input_cfg = &oxcf->input_cfg;
1066
1067 AlgoCfg *const algo_cfg = &oxcf->algo_cfg;
1068
1069 ToolCfg *const tool_cfg = &oxcf->tool_cfg;
1070
1071 const int is_vbr = cfg->rc_end_usage == AOM_VBR;
1072 oxcf->profile = cfg->g_profile;
1073 oxcf->max_threads = (int)cfg->g_threads;
1074
1075 switch (cfg->g_usage) {
1076 case AOM_USAGE_REALTIME: oxcf->mode = REALTIME; break;
1077 case AOM_USAGE_ALL_INTRA: oxcf->mode = ALLINTRA; break;
1078 default: oxcf->mode = GOOD; break;
1079 }
1080
1081 // Set frame-dimension related configuration.
1082 frm_dim_cfg->width = cfg->g_w;
1083 frm_dim_cfg->height = cfg->g_h;
1084 frm_dim_cfg->forced_max_frame_width = cfg->g_forced_max_frame_width;
1085 frm_dim_cfg->forced_max_frame_height = cfg->g_forced_max_frame_height;
1086 frm_dim_cfg->render_width = extra_cfg->render_width;
1087 frm_dim_cfg->render_height = extra_cfg->render_height;
1088
1089 // Set input video related configuration.
1090 input_cfg->input_bit_depth = cfg->g_input_bit_depth;
1091 // guess a frame rate if out of whack, use 30
1092 input_cfg->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
1093 if (cfg->g_pass >= AOM_RC_SECOND_PASS) {
1094 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
1095 const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
1096 input_cfg->limit = n_packets - 1;
1097 } else {
1098 input_cfg->limit = cfg->g_limit;
1099 }
1100 input_cfg->chroma_subsampling_x = extra_cfg->chroma_subsampling_x;
1101 input_cfg->chroma_subsampling_y = extra_cfg->chroma_subsampling_y;
1102 if (input_cfg->init_framerate > 180) {
1103 input_cfg->init_framerate = 30;
1104 dec_model_cfg->timing_info_present = 0;
1105 }
1106
1107 // Set Decoder model configuration.
1108 if (extra_cfg->timing_info_type == AOM_TIMING_EQUAL ||
1109 extra_cfg->timing_info_type == AOM_TIMING_DEC_MODEL) {
1110 dec_model_cfg->timing_info_present = 1;
1111 dec_model_cfg->timing_info.num_units_in_display_tick = cfg->g_timebase.num;
1112 dec_model_cfg->timing_info.time_scale = cfg->g_timebase.den;
1113 dec_model_cfg->timing_info.num_ticks_per_picture = 1;
1114 } else {
1115 dec_model_cfg->timing_info_present = 0;
1116 }
1117 if (extra_cfg->timing_info_type == AOM_TIMING_EQUAL) {
1118 dec_model_cfg->timing_info.equal_picture_interval = 1;
1119 dec_model_cfg->decoder_model_info_present_flag = 0;
1120 dec_model_cfg->display_model_info_present_flag = 1;
1121 } else if (extra_cfg->timing_info_type == AOM_TIMING_DEC_MODEL) {
1122 dec_model_cfg->num_units_in_decoding_tick = cfg->g_timebase.num;
1123 dec_model_cfg->timing_info.equal_picture_interval = 0;
1124 dec_model_cfg->decoder_model_info_present_flag = 1;
1125 dec_model_cfg->display_model_info_present_flag = 1;
1126 }
1127
1128 oxcf->pass = cfg->g_pass;
1129 // For backward compatibility, assume that if extra_cfg->passes==-1, then
1130 // passes = 1 or 2.
1131 if (extra_cfg->passes == -1) {
1132 if (cfg->g_pass == AOM_RC_ONE_PASS) {
1133 oxcf->passes = 1;
1134 } else {
1135 oxcf->passes = 2;
1136 }
1137 } else {
1138 oxcf->passes = extra_cfg->passes;
1139 }
1140
1141 // Set Rate Control configuration.
1142 rc_cfg->max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
1143 rc_cfg->max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
1144 rc_cfg->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
1145 rc_cfg->mode = cfg->rc_end_usage;
1146 rc_cfg->min_cr = extra_cfg->min_cr;
1147 rc_cfg->best_allowed_q =
1148 extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
1149 rc_cfg->worst_allowed_q =
1150 extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_max_quantizer);
1151 rc_cfg->cq_level = av1_quantizer_to_qindex(extra_cfg->cq_level);
1152 rc_cfg->under_shoot_pct = cfg->rc_undershoot_pct;
1153 rc_cfg->over_shoot_pct = cfg->rc_overshoot_pct;
1154 rc_cfg->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
1155 rc_cfg->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
1156 rc_cfg->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
1157 // Convert target bandwidth from Kbit/s to Bit/s
1158 rc_cfg->target_bandwidth = 1000 * cfg->rc_target_bitrate;
1159 rc_cfg->drop_frames_water_mark = cfg->rc_dropframe_thresh;
1160 rc_cfg->vbr_corpus_complexity_lap = extra_cfg->vbr_corpus_complexity_lap;
1161 rc_cfg->vbrbias = cfg->rc_2pass_vbr_bias_pct;
1162 rc_cfg->vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
1163 rc_cfg->vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
1164
1165 // Set Toolset related configuration.
1166 tool_cfg->bit_depth = cfg->g_bit_depth;
1167 tool_cfg->cdef_control = (CDEF_CONTROL)extra_cfg->enable_cdef;
1168 tool_cfg->enable_restoration =
1169 (cfg->g_usage == AOM_USAGE_REALTIME) ? 0 : extra_cfg->enable_restoration;
1170 tool_cfg->force_video_mode = extra_cfg->force_video_mode;
1171 tool_cfg->enable_palette = extra_cfg->enable_palette;
1172 // FIXME(debargha): Should this be:
1173 // tool_cfg->enable_ref_frame_mvs = extra_cfg->allow_ref_frame_mvs &
1174 // extra_cfg->enable_order_hint ?
1175 // Disallow using temporal MVs while large_scale_tile = 1.
1176 tool_cfg->enable_ref_frame_mvs =
1177 extra_cfg->allow_ref_frame_mvs && !cfg->large_scale_tile;
1178 tool_cfg->superblock_size = extra_cfg->superblock_size;
1179 tool_cfg->enable_monochrome = cfg->monochrome;
1180 tool_cfg->full_still_picture_hdr = cfg->full_still_picture_hdr != 0;
1181 tool_cfg->enable_dual_filter = extra_cfg->enable_dual_filter;
1182 tool_cfg->enable_order_hint = extra_cfg->enable_order_hint;
1183 tool_cfg->enable_interintra_comp = extra_cfg->enable_interintra_comp;
1184 tool_cfg->ref_frame_mvs_present =
1185 extra_cfg->enable_ref_frame_mvs & extra_cfg->enable_order_hint;
1186
1187 // Explicitly disable global motion in a few cases:
1188 // * For realtime mode, we never search global motion, and disabling
1189 // it here prevents later code from allocating buffers we don't need
1190 // * For large scale tile mode, some of the intended use cases expect
1191 // all frame headers to be identical. This breaks if global motion is
1192 // used, since global motion data is stored in the frame header.
1193 // eg, see test/lightfield_test.sh, which checks that all frame headers
1194 // are the same.
1195 tool_cfg->enable_global_motion = extra_cfg->enable_global_motion &&
1196 cfg->g_usage != AOM_USAGE_REALTIME &&
1197 !cfg->large_scale_tile;
1198
1199 tool_cfg->error_resilient_mode =
1200 cfg->g_error_resilient | extra_cfg->error_resilient_mode;
1201 tool_cfg->frame_parallel_decoding_mode =
1202 extra_cfg->frame_parallel_decoding_mode;
1203
1204 // Set Quantization related configuration.
1205 q_cfg->using_qm = extra_cfg->enable_qm;
1206 q_cfg->qm_minlevel = extra_cfg->qm_min;
1207 q_cfg->qm_maxlevel = extra_cfg->qm_max;
1208 q_cfg->quant_b_adapt = extra_cfg->quant_b_adapt;
1209 q_cfg->enable_chroma_deltaq = extra_cfg->enable_chroma_deltaq;
1210 q_cfg->aq_mode = extra_cfg->aq_mode;
1211 q_cfg->deltaq_mode = extra_cfg->deltaq_mode;
1212 q_cfg->deltaq_strength = extra_cfg->deltaq_strength;
1213 q_cfg->use_fixed_qp_offsets =
1214 cfg->use_fixed_qp_offsets && (rc_cfg->mode == AOM_Q);
1215 q_cfg->enable_hdr_deltaq =
1216 (q_cfg->deltaq_mode == DELTA_Q_HDR) &&
1217 (cfg->g_bit_depth == AOM_BITS_10) &&
1218 (extra_cfg->color_primaries == AOM_CICP_CP_BT_2020);
1219
1220 tool_cfg->enable_deltalf_mode =
1221 (q_cfg->deltaq_mode != NO_DELTA_Q) && extra_cfg->deltalf_mode;
1222
1223 // Set cost update frequency configuration.
1224 oxcf->cost_upd_freq.coeff = (COST_UPDATE_TYPE)extra_cfg->coeff_cost_upd_freq;
1225 oxcf->cost_upd_freq.mode = (COST_UPDATE_TYPE)extra_cfg->mode_cost_upd_freq;
1226 // Avoid MV cost update for allintra encoding mode.
1227 oxcf->cost_upd_freq.mv = (cfg->kf_max_dist != 0)
1228 ? (COST_UPDATE_TYPE)extra_cfg->mv_cost_upd_freq
1229 : COST_UPD_OFF;
1230 oxcf->cost_upd_freq.dv = (COST_UPDATE_TYPE)extra_cfg->dv_cost_upd_freq;
1231
1232 // Set frame resize mode configuration.
1233 resize_cfg->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
1234 resize_cfg->resize_scale_denominator = (uint8_t)cfg->rc_resize_denominator;
1235 resize_cfg->resize_kf_scale_denominator =
1236 (uint8_t)cfg->rc_resize_kf_denominator;
1237 if (resize_cfg->resize_mode == RESIZE_FIXED &&
1238 resize_cfg->resize_scale_denominator == SCALE_NUMERATOR &&
1239 resize_cfg->resize_kf_scale_denominator == SCALE_NUMERATOR)
1240 resize_cfg->resize_mode = RESIZE_NONE;
1241
1242 // Set encoder algorithm related configuration.
1243 algo_cfg->enable_overlay = extra_cfg->enable_overlay;
1244 algo_cfg->disable_trellis_quant = extra_cfg->disable_trellis_quant;
1245 algo_cfg->sharpness = extra_cfg->sharpness;
1246 algo_cfg->arnr_max_frames = extra_cfg->arnr_max_frames;
1247 algo_cfg->arnr_strength = extra_cfg->arnr_strength;
1248 algo_cfg->cdf_update_mode = (uint8_t)extra_cfg->cdf_update_mode;
1249 // TODO(any): Fix and Enable TPL for resize-mode > 0
1250 algo_cfg->enable_tpl_model =
1251 resize_cfg->resize_mode ? 0 : extra_cfg->enable_tpl_model;
1252 algo_cfg->loopfilter_control = extra_cfg->loopfilter_control;
1253 algo_cfg->skip_postproc_filtering = extra_cfg->skip_postproc_filtering;
1254
1255 // Set two-pass stats configuration.
1256 oxcf->twopass_stats_in = cfg->rc_twopass_stats_in;
1257
1258 if (extra_cfg->two_pass_output)
1259 oxcf->two_pass_output = extra_cfg->two_pass_output;
1260
1261 oxcf->second_pass_log = extra_cfg->second_pass_log;
1262
1263 // Set Key frame configuration.
1264 kf_cfg->fwd_kf_enabled = cfg->fwd_kf_enabled;
1265 kf_cfg->auto_key =
1266 cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
1267 kf_cfg->key_freq_min = cfg->kf_min_dist;
1268 kf_cfg->key_freq_max = cfg->kf_max_dist;
1269 kf_cfg->sframe_dist = cfg->sframe_dist;
1270 kf_cfg->sframe_mode = cfg->sframe_mode;
1271 kf_cfg->enable_sframe = extra_cfg->s_frame_mode;
1272 kf_cfg->enable_keyframe_filtering = extra_cfg->enable_keyframe_filtering;
1273 kf_cfg->fwd_kf_dist = extra_cfg->fwd_kf_dist;
1274 // Disable key frame filtering in all intra mode.
1275 if (cfg->kf_max_dist == 0) {
1276 kf_cfg->enable_keyframe_filtering = 0;
1277 }
1278 kf_cfg->enable_intrabc = extra_cfg->enable_intrabc;
1279
1280 oxcf->speed = extra_cfg->cpu_used;
1281 // TODO(yunqingwang, any) In REALTIME mode, 1080p performance at speed 5 & 6
1282 // is quite bad. Force to use speed 7 for now. Will investigate it when we
1283 // work on rd path optimization later.
1284 if (oxcf->mode == REALTIME && AOMMIN(cfg->g_w, cfg->g_h) >= 1080 &&
1285 oxcf->speed < 7)
1286 oxcf->speed = 7;
1287
1288 // Set Color related configuration.
1289 color_cfg->color_primaries = extra_cfg->color_primaries;
1290 color_cfg->transfer_characteristics = extra_cfg->transfer_characteristics;
1291 color_cfg->matrix_coefficients = extra_cfg->matrix_coefficients;
1292 color_cfg->color_range = extra_cfg->color_range;
1293 color_cfg->chroma_sample_position = extra_cfg->chroma_sample_position;
1294
1295 // Set Group of frames configuration.
1296 // Force lag_in_frames to 0 for REALTIME mode
1297 gf_cfg->lag_in_frames = (oxcf->mode == REALTIME)
1298 ? 0
1299 : clamp(cfg->g_lag_in_frames, 0, MAX_LAG_BUFFERS);
1300 gf_cfg->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
1301 gf_cfg->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
1302 gf_cfg->min_gf_interval = extra_cfg->min_gf_interval;
1303 gf_cfg->max_gf_interval = extra_cfg->max_gf_interval;
1304 gf_cfg->gf_min_pyr_height = extra_cfg->gf_min_pyr_height;
1305 gf_cfg->gf_max_pyr_height = extra_cfg->gf_max_pyr_height;
1306
1307 // Set tune related configuration.
1308 tune_cfg->tuning = extra_cfg->tuning;
1309 tune_cfg->vmaf_model_path = extra_cfg->vmaf_model_path;
1310 tune_cfg->content = extra_cfg->content;
1311 if (cfg->large_scale_tile) {
1312 tune_cfg->film_grain_test_vector = 0;
1313 tune_cfg->film_grain_table_filename = NULL;
1314 } else {
1315 tune_cfg->film_grain_test_vector = extra_cfg->film_grain_test_vector;
1316 tune_cfg->film_grain_table_filename = extra_cfg->film_grain_table_filename;
1317 }
1318 tune_cfg->dist_metric = extra_cfg->dist_metric;
1319 #if CONFIG_DENOISE
1320 oxcf->noise_level = extra_cfg->noise_level;
1321 oxcf->noise_block_size = extra_cfg->noise_block_size;
1322 oxcf->enable_dnl_denoising = extra_cfg->enable_dnl_denoising;
1323 #endif
1324
1325 #if CONFIG_AV1_TEMPORAL_DENOISING
1326 // Temporal denoiser is for nonrd pickmode so disable it for speed < 7.
1327 // Also disable it for speed 7 for now since it needs to be modified for
1328 // the check_partition_merge_mode feature.
1329 if (cfg->g_bit_depth == AOM_BITS_8 && oxcf->speed > 7) {
1330 oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
1331 } else {
1332 oxcf->noise_sensitivity = 0;
1333 }
1334 #endif
1335 // Set Tile related configuration.
1336 tile_cfg->num_tile_groups = extra_cfg->num_tg;
1337 // In large-scale tile encoding mode, num_tile_groups is always 1.
1338 if (cfg->large_scale_tile) tile_cfg->num_tile_groups = 1;
1339 tile_cfg->mtu = extra_cfg->mtu_size;
1340 tile_cfg->enable_large_scale_tile = cfg->large_scale_tile;
1341 tile_cfg->enable_single_tile_decoding =
1342 (tile_cfg->enable_large_scale_tile) ? extra_cfg->single_tile_decoding : 0;
1343 tile_cfg->tile_columns = extra_cfg->tile_columns;
1344 tile_cfg->tile_rows = extra_cfg->tile_rows;
1345 tile_cfg->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS);
1346 tile_cfg->tile_height_count = AOMMIN(cfg->tile_height_count, MAX_TILE_ROWS);
1347 for (int i = 0; i < tile_cfg->tile_width_count; i++) {
1348 tile_cfg->tile_widths[i] = cfg->tile_widths[i];
1349 }
1350 for (int i = 0; i < tile_cfg->tile_height_count; i++) {
1351 tile_cfg->tile_heights[i] = cfg->tile_heights[i];
1352 }
1353 tile_cfg->enable_ext_tile_debug = extra_cfg->ext_tile_debug;
1354
1355 if (tile_cfg->enable_large_scale_tile) {
1356 // The superblock_size can only be AOM_SUPERBLOCK_SIZE_64X64 or
1357 // AOM_SUPERBLOCK_SIZE_128X128 while tile_cfg->enable_large_scale_tile = 1.
1358 // If superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC, hard set it to
1359 // AOM_SUPERBLOCK_SIZE_64X64(default value in large_scale_tile).
1360 if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64 &&
1361 extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_128X128)
1362 tool_cfg->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
1363 }
1364
1365 // Set reference frame related configuration.
1366 oxcf->ref_frm_cfg.max_reference_frames = extra_cfg->max_reference_frames;
1367 oxcf->ref_frm_cfg.enable_reduced_reference_set =
1368 extra_cfg->enable_reduced_reference_set;
1369 oxcf->ref_frm_cfg.enable_onesided_comp = extra_cfg->enable_onesided_comp;
1370
1371 oxcf->row_mt = extra_cfg->row_mt;
1372 oxcf->fp_mt = extra_cfg->fp_mt;
1373
1374 // Set motion mode related configuration.
1375 oxcf->motion_mode_cfg.enable_obmc = extra_cfg->enable_obmc;
1376 oxcf->motion_mode_cfg.enable_warped_motion = extra_cfg->enable_warped_motion;
1377 #if !CONFIG_REALTIME_ONLY
1378 if (cfg->g_usage == AOM_USAGE_REALTIME && oxcf->speed >= 7 &&
1379 oxcf->tune_cfg.content == AOM_CONTENT_SCREEN) {
1380 // TODO(marpan): warped motion is causing a crash for RT mode with screen
1381 // in nonrd (speed >= 7), for non-realtime build.
1382 // Re-enable/allow when the issue is fixed.
1383 oxcf->motion_mode_cfg.enable_warped_motion = 0;
1384 oxcf->motion_mode_cfg.allow_warped_motion = 0;
1385 } else {
1386 oxcf->motion_mode_cfg.allow_warped_motion =
1387 (extra_cfg->allow_warped_motion & extra_cfg->enable_warped_motion);
1388 }
1389 #else
1390 oxcf->motion_mode_cfg.allow_warped_motion =
1391 (cfg->g_usage == AOM_USAGE_REALTIME && oxcf->speed >= 7)
1392 ? false
1393 : (extra_cfg->allow_warped_motion & extra_cfg->enable_warped_motion);
1394 #endif
1395
1396 // Set partition related configuration.
1397 part_cfg->enable_rect_partitions = extra_cfg->enable_rect_partitions;
1398 part_cfg->enable_ab_partitions = extra_cfg->enable_ab_partitions;
1399 part_cfg->enable_1to4_partitions = extra_cfg->enable_1to4_partitions;
1400 part_cfg->min_partition_size = extra_cfg->min_partition_size;
1401 part_cfg->max_partition_size = extra_cfg->max_partition_size;
1402
1403 // Set intra mode configuration.
1404 intra_mode_cfg->enable_angle_delta = extra_cfg->enable_angle_delta;
1405 intra_mode_cfg->enable_intra_edge_filter =
1406 extra_cfg->enable_intra_edge_filter;
1407 intra_mode_cfg->enable_filter_intra = extra_cfg->enable_filter_intra;
1408 intra_mode_cfg->enable_smooth_intra = extra_cfg->enable_smooth_intra;
1409 intra_mode_cfg->enable_paeth_intra = extra_cfg->enable_paeth_intra;
1410 intra_mode_cfg->enable_cfl_intra = extra_cfg->enable_cfl_intra;
1411 intra_mode_cfg->enable_directional_intra =
1412 extra_cfg->enable_directional_intra;
1413 intra_mode_cfg->enable_diagonal_intra = extra_cfg->enable_diagonal_intra;
1414 intra_mode_cfg->auto_intra_tools_off = extra_cfg->auto_intra_tools_off;
1415
1416 // Set transform size/type configuration.
1417 txfm_cfg->enable_tx64 = extra_cfg->enable_tx64;
1418 txfm_cfg->enable_flip_idtx = extra_cfg->enable_flip_idtx;
1419 txfm_cfg->enable_rect_tx = extra_cfg->enable_rect_tx;
1420 txfm_cfg->reduced_tx_type_set = extra_cfg->reduced_tx_type_set;
1421 txfm_cfg->use_intra_dct_only = extra_cfg->use_intra_dct_only;
1422 txfm_cfg->use_inter_dct_only = extra_cfg->use_inter_dct_only;
1423 txfm_cfg->use_intra_default_tx_only = extra_cfg->use_intra_default_tx_only;
1424 txfm_cfg->enable_tx_size_search = extra_cfg->enable_tx_size_search;
1425
1426 // Set compound type configuration.
1427 comp_type_cfg->enable_dist_wtd_comp =
1428 extra_cfg->enable_dist_wtd_comp & extra_cfg->enable_order_hint;
1429 comp_type_cfg->enable_masked_comp = extra_cfg->enable_masked_comp;
1430 comp_type_cfg->enable_diff_wtd_comp =
1431 extra_cfg->enable_masked_comp & extra_cfg->enable_diff_wtd_comp;
1432 comp_type_cfg->enable_interinter_wedge =
1433 extra_cfg->enable_masked_comp & extra_cfg->enable_interinter_wedge;
1434 comp_type_cfg->enable_smooth_interintra =
1435 extra_cfg->enable_interintra_comp && extra_cfg->enable_smooth_interintra;
1436 comp_type_cfg->enable_interintra_wedge =
1437 extra_cfg->enable_interintra_comp & extra_cfg->enable_interintra_wedge;
1438
1439 // Set Super-resolution mode configuration.
1440 if (extra_cfg->lossless || cfg->large_scale_tile) {
1441 disable_superres(superres_cfg);
1442 } else {
1443 superres_cfg->superres_mode = cfg->rc_superres_mode;
1444 superres_cfg->superres_scale_denominator =
1445 (uint8_t)cfg->rc_superres_denominator;
1446 superres_cfg->superres_kf_scale_denominator =
1447 (uint8_t)cfg->rc_superres_kf_denominator;
1448 superres_cfg->superres_qthresh =
1449 av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
1450 superres_cfg->superres_kf_qthresh =
1451 av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh);
1452 if (superres_cfg->superres_mode == AOM_SUPERRES_FIXED &&
1453 superres_cfg->superres_scale_denominator == SCALE_NUMERATOR &&
1454 superres_cfg->superres_kf_scale_denominator == SCALE_NUMERATOR) {
1455 disable_superres(superres_cfg);
1456 }
1457 if (superres_cfg->superres_mode == AOM_SUPERRES_QTHRESH &&
1458 superres_cfg->superres_qthresh == 255 &&
1459 superres_cfg->superres_kf_qthresh == 255) {
1460 disable_superres(superres_cfg);
1461 }
1462 }
1463
1464 superres_cfg->enable_superres =
1465 (superres_cfg->superres_mode != AOM_SUPERRES_NONE) &&
1466 extra_cfg->enable_superres;
1467 if (!superres_cfg->enable_superres) {
1468 disable_superres(superres_cfg);
1469 }
1470
1471 if (input_cfg->limit == 1) {
1472 // still picture mode, display model and timing is meaningless
1473 dec_model_cfg->display_model_info_present_flag = 0;
1474 dec_model_cfg->timing_info_present = 0;
1475 }
1476
1477 oxcf->save_as_annexb = cfg->save_as_annexb;
1478
1479 // Set unit test related configuration.
1480 oxcf->unit_test_cfg.motion_vector_unit_test =
1481 extra_cfg->motion_vector_unit_test;
1482 oxcf->unit_test_cfg.sb_multipass_unit_test =
1483 extra_cfg->sb_multipass_unit_test;
1484
1485 oxcf->border_in_pixels =
1486 av1_get_enc_border_size(av1_is_resize_needed(oxcf),
1487 (oxcf->kf_cfg.key_freq_max == 0), BLOCK_128X128);
1488 memcpy(oxcf->target_seq_level_idx, extra_cfg->target_seq_level_idx,
1489 sizeof(oxcf->target_seq_level_idx));
1490 oxcf->tier_mask = extra_cfg->tier_mask;
1491
1492 oxcf->partition_info_path = extra_cfg->partition_info_path;
1493
1494 oxcf->enable_rate_guide_deltaq = extra_cfg->enable_rate_guide_deltaq;
1495 oxcf->rate_distribution_info = extra_cfg->rate_distribution_info;
1496
1497 oxcf->strict_level_conformance = extra_cfg->strict_level_conformance;
1498
1499 oxcf->kf_max_pyr_height = extra_cfg->kf_max_pyr_height;
1500
1501 oxcf->sb_qp_sweep = extra_cfg->sb_qp_sweep;
1502 }
1503
av1_get_encoder_config(const aom_codec_enc_cfg_t * cfg)1504 AV1EncoderConfig av1_get_encoder_config(const aom_codec_enc_cfg_t *cfg) {
1505 AV1EncoderConfig oxcf;
1506 struct av1_extracfg extra_cfg = default_extra_cfg;
1507 set_encoder_config(&oxcf, cfg, &extra_cfg);
1508 return oxcf;
1509 }
1510
encoder_set_config(aom_codec_alg_priv_t * ctx,const aom_codec_enc_cfg_t * cfg)1511 static aom_codec_err_t encoder_set_config(aom_codec_alg_priv_t *ctx,
1512 const aom_codec_enc_cfg_t *cfg) {
1513 aom_codec_err_t res;
1514 int force_key = 0;
1515
1516 if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) {
1517 if (cfg->g_lag_in_frames > 1 || cfg->g_pass != AOM_RC_ONE_PASS)
1518 ERROR("Cannot change width or height after initialization");
1519 // Note: function encoder_set_config() is allowed to be called multiple
1520 // times. However, when the original frame width or height is less than two
1521 // times of the new frame width or height, a forced key frame should be
1522 // used. To make sure the correct detection of a forced key frame, we need
1523 // to update the frame width and height only when the actual encoding is
1524 // performed. cpi->last_coded_width and cpi->last_coded_height are used to
1525 // track the actual coded frame size.
1526 if (ctx->ppi->cpi->last_coded_width && ctx->ppi->cpi->last_coded_height &&
1527 (!valid_ref_frame_size(ctx->ppi->cpi->last_coded_width,
1528 ctx->ppi->cpi->last_coded_height, cfg->g_w,
1529 cfg->g_h) ||
1530 ((int)cfg->g_w > ctx->ppi->cpi->last_coded_width) ||
1531 ((int)cfg->g_h > ctx->ppi->cpi->last_coded_height))) {
1532 force_key = 1;
1533 }
1534 }
1535
1536 if (ctx->monochrome_on_init && cfg->monochrome == 0) {
1537 // TODO(aomedia:3465): Allow this case to work without requiring re-init
1538 // of encoder.
1539 ERROR("Cannot change to monochrome = 0 after init with monochrome");
1540 }
1541
1542 // Prevent increasing lag_in_frames. This check is stricter than it needs
1543 // to be -- the limit is not increasing past the first lag_in_frames
1544 // value, but we don't track the initial config, only the last successful
1545 // config.
1546 if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
1547 ERROR("Cannot increase lag_in_frames");
1548 // Prevent changing lag_in_frames if Lookahead Processing is enabled
1549 if (cfg->g_lag_in_frames != ctx->cfg.g_lag_in_frames &&
1550 ctx->num_lap_buffers > 0)
1551 ERROR("Cannot change lag_in_frames if LAP is enabled");
1552
1553 res = validate_config(ctx, cfg, &ctx->extra_cfg);
1554
1555 if (res == AOM_CODEC_OK) {
1556 ctx->cfg = *cfg;
1557 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
1558 // On profile change, request a key frame
1559 force_key |= ctx->ppi->seq_params.profile != ctx->oxcf.profile;
1560 bool is_sb_size_changed = false;
1561 av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
1562 for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
1563 av1_change_config(ctx->ppi->parallel_cpi[i], &ctx->oxcf,
1564 is_sb_size_changed);
1565 }
1566 if (ctx->ppi->cpi_lap != NULL) {
1567 av1_change_config(ctx->ppi->cpi_lap, &ctx->oxcf, is_sb_size_changed);
1568 }
1569 }
1570
1571 if (force_key) ctx->next_frame_flags |= AOM_EFLAG_FORCE_KF;
1572
1573 return res;
1574 }
1575
encoder_get_global_headers(aom_codec_alg_priv_t * ctx)1576 static aom_fixed_buf_t *encoder_get_global_headers(aom_codec_alg_priv_t *ctx) {
1577 return av1_get_global_headers(ctx->ppi);
1578 }
1579
ctrl_get_quantizer(aom_codec_alg_priv_t * ctx,va_list args)1580 static aom_codec_err_t ctrl_get_quantizer(aom_codec_alg_priv_t *ctx,
1581 va_list args) {
1582 int *const arg = va_arg(args, int *);
1583 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
1584 *arg = av1_get_quantizer(ctx->ppi->cpi);
1585 return AOM_CODEC_OK;
1586 }
1587
ctrl_get_quantizer64(aom_codec_alg_priv_t * ctx,va_list args)1588 static aom_codec_err_t ctrl_get_quantizer64(aom_codec_alg_priv_t *ctx,
1589 va_list args) {
1590 int *const arg = va_arg(args, int *);
1591 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
1592 *arg = av1_qindex_to_quantizer(av1_get_quantizer(ctx->ppi->cpi));
1593 return AOM_CODEC_OK;
1594 }
1595
ctrl_get_loopfilter_level(aom_codec_alg_priv_t * ctx,va_list args)1596 static aom_codec_err_t ctrl_get_loopfilter_level(aom_codec_alg_priv_t *ctx,
1597 va_list args) {
1598 int *const arg = va_arg(args, int *);
1599 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
1600 *arg = ctx->ppi->cpi->common.lf.filter_level[0];
1601 return AOM_CODEC_OK;
1602 }
1603
ctrl_get_baseline_gf_interval(aom_codec_alg_priv_t * ctx,va_list args)1604 static aom_codec_err_t ctrl_get_baseline_gf_interval(aom_codec_alg_priv_t *ctx,
1605 va_list args) {
1606 int *const arg = va_arg(args, int *);
1607 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
1608 *arg = ctx->ppi->p_rc.baseline_gf_interval;
1609 return AOM_CODEC_OK;
1610 }
1611
update_extra_cfg(aom_codec_alg_priv_t * ctx,const struct av1_extracfg * extra_cfg)1612 static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
1613 const struct av1_extracfg *extra_cfg) {
1614 const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
1615 if (res == AOM_CODEC_OK) {
1616 ctx->extra_cfg = *extra_cfg;
1617 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
1618 av1_check_fpmt_config(ctx->ppi, &ctx->oxcf);
1619 bool is_sb_size_changed = false;
1620 av1_change_config_seq(ctx->ppi, &ctx->oxcf, &is_sb_size_changed);
1621 for (int i = 0; i < ctx->ppi->num_fp_contexts; i++) {
1622 AV1_COMP *const cpi = ctx->ppi->parallel_cpi[i];
1623 struct aom_internal_error_info *const error = cpi->common.error;
1624 if (setjmp(error->jmp)) {
1625 error->setjmp = 0;
1626 return error->error_code;
1627 }
1628 error->setjmp = 1;
1629 av1_change_config(cpi, &ctx->oxcf, is_sb_size_changed);
1630 error->setjmp = 0;
1631 }
1632 if (ctx->ppi->cpi_lap != NULL) {
1633 AV1_COMP *const cpi_lap = ctx->ppi->cpi_lap;
1634 struct aom_internal_error_info *const error = cpi_lap->common.error;
1635 if (setjmp(error->jmp)) {
1636 error->setjmp = 0;
1637 return error->error_code;
1638 }
1639 error->setjmp = 1;
1640 av1_change_config(cpi_lap, &ctx->oxcf, is_sb_size_changed);
1641 error->setjmp = 0;
1642 }
1643 }
1644 return res;
1645 }
1646
ctrl_set_cpuused(aom_codec_alg_priv_t * ctx,va_list args)1647 static aom_codec_err_t ctrl_set_cpuused(aom_codec_alg_priv_t *ctx,
1648 va_list args) {
1649 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1650 extra_cfg.cpu_used = CAST(AOME_SET_CPUUSED, args);
1651 return update_extra_cfg(ctx, &extra_cfg);
1652 }
1653
ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t * ctx,va_list args)1654 static aom_codec_err_t ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t *ctx,
1655 va_list args) {
1656 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1657 extra_cfg.enable_auto_alt_ref = CAST(AOME_SET_ENABLEAUTOALTREF, args);
1658 return update_extra_cfg(ctx, &extra_cfg);
1659 }
1660
ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t * ctx,va_list args)1661 static aom_codec_err_t ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t *ctx,
1662 va_list args) {
1663 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1664 extra_cfg.enable_auto_bwd_ref = CAST(AOME_SET_ENABLEAUTOBWDREF, args);
1665 return update_extra_cfg(ctx, &extra_cfg);
1666 }
1667
ctrl_set_noise_sensitivity(aom_codec_alg_priv_t * ctx,va_list args)1668 static aom_codec_err_t ctrl_set_noise_sensitivity(aom_codec_alg_priv_t *ctx,
1669 va_list args) {
1670 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1671 extra_cfg.noise_sensitivity = CAST(AV1E_SET_NOISE_SENSITIVITY, args);
1672 return update_extra_cfg(ctx, &extra_cfg);
1673 }
1674
ctrl_set_sharpness(aom_codec_alg_priv_t * ctx,va_list args)1675 static aom_codec_err_t ctrl_set_sharpness(aom_codec_alg_priv_t *ctx,
1676 va_list args) {
1677 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1678 extra_cfg.sharpness = CAST(AOME_SET_SHARPNESS, args);
1679 return update_extra_cfg(ctx, &extra_cfg);
1680 }
1681
ctrl_set_static_thresh(aom_codec_alg_priv_t * ctx,va_list args)1682 static aom_codec_err_t ctrl_set_static_thresh(aom_codec_alg_priv_t *ctx,
1683 va_list args) {
1684 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1685 extra_cfg.static_thresh = CAST(AOME_SET_STATIC_THRESHOLD, args);
1686 return update_extra_cfg(ctx, &extra_cfg);
1687 }
1688
ctrl_set_row_mt(aom_codec_alg_priv_t * ctx,va_list args)1689 static aom_codec_err_t ctrl_set_row_mt(aom_codec_alg_priv_t *ctx,
1690 va_list args) {
1691 unsigned int row_mt = CAST(AV1E_SET_ROW_MT, args);
1692 if (row_mt == ctx->extra_cfg.row_mt) return AOM_CODEC_OK;
1693 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1694 extra_cfg.row_mt = row_mt;
1695 return update_extra_cfg(ctx, &extra_cfg);
1696 }
1697
ctrl_set_tile_columns(aom_codec_alg_priv_t * ctx,va_list args)1698 static aom_codec_err_t ctrl_set_tile_columns(aom_codec_alg_priv_t *ctx,
1699 va_list args) {
1700 unsigned int tile_columns = CAST(AV1E_SET_TILE_COLUMNS, args);
1701 if (tile_columns == ctx->extra_cfg.tile_columns) return AOM_CODEC_OK;
1702 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1703 extra_cfg.tile_columns = tile_columns;
1704 return update_extra_cfg(ctx, &extra_cfg);
1705 }
1706
ctrl_set_tile_rows(aom_codec_alg_priv_t * ctx,va_list args)1707 static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
1708 va_list args) {
1709 unsigned int tile_rows = CAST(AV1E_SET_TILE_ROWS, args);
1710 if (tile_rows == ctx->extra_cfg.tile_rows) return AOM_CODEC_OK;
1711 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1712 extra_cfg.tile_rows = tile_rows;
1713 return update_extra_cfg(ctx, &extra_cfg);
1714 }
1715
ctrl_set_enable_tpl_model(aom_codec_alg_priv_t * ctx,va_list args)1716 static aom_codec_err_t ctrl_set_enable_tpl_model(aom_codec_alg_priv_t *ctx,
1717 va_list args) {
1718 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1719 const unsigned int tpl_model_arg = CAST(AV1E_SET_ENABLE_TPL_MODEL, args);
1720 #if CONFIG_REALTIME_ONLY
1721 if (tpl_model_arg) {
1722 ERROR("TPL model can't be turned on in realtime only build.");
1723 }
1724 #endif
1725 extra_cfg.enable_tpl_model = tpl_model_arg;
1726 return update_extra_cfg(ctx, &extra_cfg);
1727 }
1728
ctrl_set_enable_keyframe_filtering(aom_codec_alg_priv_t * ctx,va_list args)1729 static aom_codec_err_t ctrl_set_enable_keyframe_filtering(
1730 aom_codec_alg_priv_t *ctx, va_list args) {
1731 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1732 extra_cfg.enable_keyframe_filtering =
1733 CAST(AV1E_SET_ENABLE_KEYFRAME_FILTERING, args);
1734 return update_extra_cfg(ctx, &extra_cfg);
1735 }
1736
ctrl_set_arnr_max_frames(aom_codec_alg_priv_t * ctx,va_list args)1737 static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
1738 va_list args) {
1739 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1740 extra_cfg.arnr_max_frames = CAST(AOME_SET_ARNR_MAXFRAMES, args);
1741 return update_extra_cfg(ctx, &extra_cfg);
1742 }
1743
ctrl_set_arnr_strength(aom_codec_alg_priv_t * ctx,va_list args)1744 static aom_codec_err_t ctrl_set_arnr_strength(aom_codec_alg_priv_t *ctx,
1745 va_list args) {
1746 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1747 extra_cfg.arnr_strength = CAST(AOME_SET_ARNR_STRENGTH, args);
1748 return update_extra_cfg(ctx, &extra_cfg);
1749 }
1750
ctrl_set_tuning(aom_codec_alg_priv_t * ctx,va_list args)1751 static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx,
1752 va_list args) {
1753 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1754 extra_cfg.tuning = CAST(AOME_SET_TUNING, args);
1755 return update_extra_cfg(ctx, &extra_cfg);
1756 }
1757
ctrl_set_cq_level(aom_codec_alg_priv_t * ctx,va_list args)1758 static aom_codec_err_t ctrl_set_cq_level(aom_codec_alg_priv_t *ctx,
1759 va_list args) {
1760 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1761 extra_cfg.cq_level = CAST(AOME_SET_CQ_LEVEL, args);
1762 return update_extra_cfg(ctx, &extra_cfg);
1763 }
1764
ctrl_set_rc_max_intra_bitrate_pct(aom_codec_alg_priv_t * ctx,va_list args)1765 static aom_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
1766 aom_codec_alg_priv_t *ctx, va_list args) {
1767 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1768 extra_cfg.rc_max_intra_bitrate_pct =
1769 CAST(AOME_SET_MAX_INTRA_BITRATE_PCT, args);
1770 return update_extra_cfg(ctx, &extra_cfg);
1771 }
1772
ctrl_set_rc_max_inter_bitrate_pct(aom_codec_alg_priv_t * ctx,va_list args)1773 static aom_codec_err_t ctrl_set_rc_max_inter_bitrate_pct(
1774 aom_codec_alg_priv_t *ctx, va_list args) {
1775 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1776 extra_cfg.rc_max_inter_bitrate_pct =
1777 CAST(AOME_SET_MAX_INTER_BITRATE_PCT, args);
1778 return update_extra_cfg(ctx, &extra_cfg);
1779 }
1780
ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t * ctx,va_list args)1781 static aom_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t *ctx,
1782 va_list args) {
1783 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1784 extra_cfg.gf_cbr_boost_pct = CAST(AV1E_SET_GF_CBR_BOOST_PCT, args);
1785 return update_extra_cfg(ctx, &extra_cfg);
1786 }
1787
ctrl_set_lossless(aom_codec_alg_priv_t * ctx,va_list args)1788 static aom_codec_err_t ctrl_set_lossless(aom_codec_alg_priv_t *ctx,
1789 va_list args) {
1790 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1791 extra_cfg.lossless = CAST(AV1E_SET_LOSSLESS, args);
1792 return update_extra_cfg(ctx, &extra_cfg);
1793 }
1794
ctrl_set_enable_cdef(aom_codec_alg_priv_t * ctx,va_list args)1795 static aom_codec_err_t ctrl_set_enable_cdef(aom_codec_alg_priv_t *ctx,
1796 va_list args) {
1797 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1798 extra_cfg.enable_cdef = CAST(AV1E_SET_ENABLE_CDEF, args);
1799 return update_extra_cfg(ctx, &extra_cfg);
1800 }
1801
ctrl_set_enable_restoration(aom_codec_alg_priv_t * ctx,va_list args)1802 static aom_codec_err_t ctrl_set_enable_restoration(aom_codec_alg_priv_t *ctx,
1803 va_list args) {
1804 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1805 const unsigned int restoration_arg = CAST(AV1E_SET_ENABLE_RESTORATION, args);
1806 #if CONFIG_REALTIME_ONLY
1807 if (restoration_arg) {
1808 ERROR("Restoration can't be turned on in realtime only build.");
1809 }
1810 #endif
1811 extra_cfg.enable_restoration = restoration_arg;
1812 return update_extra_cfg(ctx, &extra_cfg);
1813 }
1814
ctrl_set_force_video_mode(aom_codec_alg_priv_t * ctx,va_list args)1815 static aom_codec_err_t ctrl_set_force_video_mode(aom_codec_alg_priv_t *ctx,
1816 va_list args) {
1817 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1818 extra_cfg.force_video_mode = CAST(AV1E_SET_FORCE_VIDEO_MODE, args);
1819 return update_extra_cfg(ctx, &extra_cfg);
1820 }
1821
ctrl_set_enable_obmc(aom_codec_alg_priv_t * ctx,va_list args)1822 static aom_codec_err_t ctrl_set_enable_obmc(aom_codec_alg_priv_t *ctx,
1823 va_list args) {
1824 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1825 const unsigned int obmc_arg = CAST(AV1E_SET_ENABLE_OBMC, args);
1826 #if CONFIG_REALTIME_ONLY
1827 if (obmc_arg) {
1828 ERROR("OBMC can't be enabled in realtime only build.");
1829 }
1830 #endif
1831 extra_cfg.enable_obmc = obmc_arg;
1832 return update_extra_cfg(ctx, &extra_cfg);
1833 }
1834
ctrl_set_disable_trellis_quant(aom_codec_alg_priv_t * ctx,va_list args)1835 static aom_codec_err_t ctrl_set_disable_trellis_quant(aom_codec_alg_priv_t *ctx,
1836 va_list args) {
1837 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1838 extra_cfg.disable_trellis_quant = CAST(AV1E_SET_DISABLE_TRELLIS_QUANT, args);
1839 return update_extra_cfg(ctx, &extra_cfg);
1840 }
1841
ctrl_set_enable_qm(aom_codec_alg_priv_t * ctx,va_list args)1842 static aom_codec_err_t ctrl_set_enable_qm(aom_codec_alg_priv_t *ctx,
1843 va_list args) {
1844 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1845 extra_cfg.enable_qm = CAST(AV1E_SET_ENABLE_QM, args);
1846 #if !CONFIG_QUANT_MATRIX
1847 if (extra_cfg.enable_qm) {
1848 ERROR("QM can't be enabled with CONFIG_QUANT_MATRIX=0.");
1849 }
1850 #endif
1851 return update_extra_cfg(ctx, &extra_cfg);
1852 }
ctrl_set_qm_y(aom_codec_alg_priv_t * ctx,va_list args)1853 static aom_codec_err_t ctrl_set_qm_y(aom_codec_alg_priv_t *ctx, va_list args) {
1854 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1855 extra_cfg.qm_y = CAST(AV1E_SET_QM_Y, args);
1856 return update_extra_cfg(ctx, &extra_cfg);
1857 }
ctrl_set_qm_u(aom_codec_alg_priv_t * ctx,va_list args)1858 static aom_codec_err_t ctrl_set_qm_u(aom_codec_alg_priv_t *ctx, va_list args) {
1859 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1860 extra_cfg.qm_u = CAST(AV1E_SET_QM_U, args);
1861 return update_extra_cfg(ctx, &extra_cfg);
1862 }
ctrl_set_qm_v(aom_codec_alg_priv_t * ctx,va_list args)1863 static aom_codec_err_t ctrl_set_qm_v(aom_codec_alg_priv_t *ctx, va_list args) {
1864 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1865 extra_cfg.qm_v = CAST(AV1E_SET_QM_V, args);
1866 return update_extra_cfg(ctx, &extra_cfg);
1867 }
ctrl_set_qm_min(aom_codec_alg_priv_t * ctx,va_list args)1868 static aom_codec_err_t ctrl_set_qm_min(aom_codec_alg_priv_t *ctx,
1869 va_list args) {
1870 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1871 extra_cfg.qm_min = CAST(AV1E_SET_QM_MIN, args);
1872 return update_extra_cfg(ctx, &extra_cfg);
1873 }
1874
ctrl_set_qm_max(aom_codec_alg_priv_t * ctx,va_list args)1875 static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
1876 va_list args) {
1877 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1878 extra_cfg.qm_max = CAST(AV1E_SET_QM_MAX, args);
1879 return update_extra_cfg(ctx, &extra_cfg);
1880 }
1881
ctrl_set_num_tg(aom_codec_alg_priv_t * ctx,va_list args)1882 static aom_codec_err_t ctrl_set_num_tg(aom_codec_alg_priv_t *ctx,
1883 va_list args) {
1884 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1885 extra_cfg.num_tg = CAST(AV1E_SET_NUM_TG, args);
1886 return update_extra_cfg(ctx, &extra_cfg);
1887 }
1888
ctrl_set_mtu(aom_codec_alg_priv_t * ctx,va_list args)1889 static aom_codec_err_t ctrl_set_mtu(aom_codec_alg_priv_t *ctx, va_list args) {
1890 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1891 extra_cfg.mtu_size = CAST(AV1E_SET_MTU, args);
1892 return update_extra_cfg(ctx, &extra_cfg);
1893 }
ctrl_set_timing_info_type(aom_codec_alg_priv_t * ctx,va_list args)1894 static aom_codec_err_t ctrl_set_timing_info_type(aom_codec_alg_priv_t *ctx,
1895 va_list args) {
1896 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1897 extra_cfg.timing_info_type = CAST(AV1E_SET_TIMING_INFO_TYPE, args);
1898 return update_extra_cfg(ctx, &extra_cfg);
1899 }
1900
ctrl_set_enable_dual_filter(aom_codec_alg_priv_t * ctx,va_list args)1901 static aom_codec_err_t ctrl_set_enable_dual_filter(aom_codec_alg_priv_t *ctx,
1902 va_list args) {
1903 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1904 extra_cfg.enable_dual_filter = CAST(AV1E_SET_ENABLE_DUAL_FILTER, args);
1905 return update_extra_cfg(ctx, &extra_cfg);
1906 }
1907
ctrl_set_enable_chroma_deltaq(aom_codec_alg_priv_t * ctx,va_list args)1908 static aom_codec_err_t ctrl_set_enable_chroma_deltaq(aom_codec_alg_priv_t *ctx,
1909 va_list args) {
1910 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1911 extra_cfg.enable_chroma_deltaq = CAST(AV1E_SET_ENABLE_CHROMA_DELTAQ, args);
1912 return update_extra_cfg(ctx, &extra_cfg);
1913 }
1914
ctrl_set_enable_rect_partitions(aom_codec_alg_priv_t * ctx,va_list args)1915 static aom_codec_err_t ctrl_set_enable_rect_partitions(
1916 aom_codec_alg_priv_t *ctx, va_list args) {
1917 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1918 extra_cfg.enable_rect_partitions =
1919 CAST(AV1E_SET_ENABLE_RECT_PARTITIONS, args);
1920 return update_extra_cfg(ctx, &extra_cfg);
1921 }
1922
ctrl_set_enable_ab_partitions(aom_codec_alg_priv_t * ctx,va_list args)1923 static aom_codec_err_t ctrl_set_enable_ab_partitions(aom_codec_alg_priv_t *ctx,
1924 va_list args) {
1925 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1926 extra_cfg.enable_ab_partitions = CAST(AV1E_SET_ENABLE_AB_PARTITIONS, args);
1927 return update_extra_cfg(ctx, &extra_cfg);
1928 }
1929
ctrl_set_enable_1to4_partitions(aom_codec_alg_priv_t * ctx,va_list args)1930 static aom_codec_err_t ctrl_set_enable_1to4_partitions(
1931 aom_codec_alg_priv_t *ctx, va_list args) {
1932 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1933 extra_cfg.enable_1to4_partitions =
1934 CAST(AV1E_SET_ENABLE_1TO4_PARTITIONS, args);
1935 return update_extra_cfg(ctx, &extra_cfg);
1936 }
1937
ctrl_set_min_partition_size(aom_codec_alg_priv_t * ctx,va_list args)1938 static aom_codec_err_t ctrl_set_min_partition_size(aom_codec_alg_priv_t *ctx,
1939 va_list args) {
1940 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1941 extra_cfg.min_partition_size = CAST(AV1E_SET_MIN_PARTITION_SIZE, args);
1942 return update_extra_cfg(ctx, &extra_cfg);
1943 }
1944
ctrl_set_max_partition_size(aom_codec_alg_priv_t * ctx,va_list args)1945 static aom_codec_err_t ctrl_set_max_partition_size(aom_codec_alg_priv_t *ctx,
1946 va_list args) {
1947 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1948 extra_cfg.max_partition_size = CAST(AV1E_SET_MAX_PARTITION_SIZE, args);
1949 return update_extra_cfg(ctx, &extra_cfg);
1950 }
1951
ctrl_set_enable_intra_edge_filter(aom_codec_alg_priv_t * ctx,va_list args)1952 static aom_codec_err_t ctrl_set_enable_intra_edge_filter(
1953 aom_codec_alg_priv_t *ctx, va_list args) {
1954 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1955 extra_cfg.enable_intra_edge_filter =
1956 CAST(AV1E_SET_ENABLE_INTRA_EDGE_FILTER, args);
1957 return update_extra_cfg(ctx, &extra_cfg);
1958 }
1959
ctrl_set_enable_order_hint(aom_codec_alg_priv_t * ctx,va_list args)1960 static aom_codec_err_t ctrl_set_enable_order_hint(aom_codec_alg_priv_t *ctx,
1961 va_list args) {
1962 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1963 extra_cfg.enable_order_hint = CAST(AV1E_SET_ENABLE_ORDER_HINT, args);
1964 return update_extra_cfg(ctx, &extra_cfg);
1965 }
1966
ctrl_set_enable_tx64(aom_codec_alg_priv_t * ctx,va_list args)1967 static aom_codec_err_t ctrl_set_enable_tx64(aom_codec_alg_priv_t *ctx,
1968 va_list args) {
1969 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1970 extra_cfg.enable_tx64 = CAST(AV1E_SET_ENABLE_TX64, args);
1971 return update_extra_cfg(ctx, &extra_cfg);
1972 }
1973
ctrl_set_enable_flip_idtx(aom_codec_alg_priv_t * ctx,va_list args)1974 static aom_codec_err_t ctrl_set_enable_flip_idtx(aom_codec_alg_priv_t *ctx,
1975 va_list args) {
1976 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1977 extra_cfg.enable_flip_idtx = CAST(AV1E_SET_ENABLE_FLIP_IDTX, args);
1978 return update_extra_cfg(ctx, &extra_cfg);
1979 }
1980
ctrl_set_enable_rect_tx(aom_codec_alg_priv_t * ctx,va_list args)1981 static aom_codec_err_t ctrl_set_enable_rect_tx(aom_codec_alg_priv_t *ctx,
1982 va_list args) {
1983 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1984 extra_cfg.enable_rect_tx = CAST(AV1E_SET_ENABLE_RECT_TX, args);
1985 return update_extra_cfg(ctx, &extra_cfg);
1986 }
1987
ctrl_set_enable_dist_wtd_comp(aom_codec_alg_priv_t * ctx,va_list args)1988 static aom_codec_err_t ctrl_set_enable_dist_wtd_comp(aom_codec_alg_priv_t *ctx,
1989 va_list args) {
1990 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1991 extra_cfg.enable_dist_wtd_comp = CAST(AV1E_SET_ENABLE_DIST_WTD_COMP, args);
1992 return update_extra_cfg(ctx, &extra_cfg);
1993 }
1994
ctrl_set_max_reference_frames(aom_codec_alg_priv_t * ctx,va_list args)1995 static aom_codec_err_t ctrl_set_max_reference_frames(aom_codec_alg_priv_t *ctx,
1996 va_list args) {
1997 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1998 extra_cfg.max_reference_frames = CAST(AV1E_SET_MAX_REFERENCE_FRAMES, args);
1999 return update_extra_cfg(ctx, &extra_cfg);
2000 }
2001
ctrl_set_enable_reduced_reference_set(aom_codec_alg_priv_t * ctx,va_list args)2002 static aom_codec_err_t ctrl_set_enable_reduced_reference_set(
2003 aom_codec_alg_priv_t *ctx, va_list args) {
2004 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2005 extra_cfg.enable_reduced_reference_set =
2006 CAST(AV1E_SET_REDUCED_REFERENCE_SET, args);
2007 return update_extra_cfg(ctx, &extra_cfg);
2008 }
2009
ctrl_set_enable_ref_frame_mvs(aom_codec_alg_priv_t * ctx,va_list args)2010 static aom_codec_err_t ctrl_set_enable_ref_frame_mvs(aom_codec_alg_priv_t *ctx,
2011 va_list args) {
2012 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2013 extra_cfg.enable_ref_frame_mvs = CAST(AV1E_SET_ENABLE_REF_FRAME_MVS, args);
2014 return update_extra_cfg(ctx, &extra_cfg);
2015 }
2016
ctrl_set_allow_ref_frame_mvs(aom_codec_alg_priv_t * ctx,va_list args)2017 static aom_codec_err_t ctrl_set_allow_ref_frame_mvs(aom_codec_alg_priv_t *ctx,
2018 va_list args) {
2019 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2020 extra_cfg.allow_ref_frame_mvs = CAST(AV1E_SET_ALLOW_REF_FRAME_MVS, args);
2021 return update_extra_cfg(ctx, &extra_cfg);
2022 }
2023
ctrl_set_enable_masked_comp(aom_codec_alg_priv_t * ctx,va_list args)2024 static aom_codec_err_t ctrl_set_enable_masked_comp(aom_codec_alg_priv_t *ctx,
2025 va_list args) {
2026 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2027 extra_cfg.enable_masked_comp = CAST(AV1E_SET_ENABLE_MASKED_COMP, args);
2028 return update_extra_cfg(ctx, &extra_cfg);
2029 }
2030
ctrl_set_enable_onesided_comp(aom_codec_alg_priv_t * ctx,va_list args)2031 static aom_codec_err_t ctrl_set_enable_onesided_comp(aom_codec_alg_priv_t *ctx,
2032 va_list args) {
2033 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2034 extra_cfg.enable_onesided_comp = CAST(AV1E_SET_ENABLE_ONESIDED_COMP, args);
2035 return update_extra_cfg(ctx, &extra_cfg);
2036 }
2037
ctrl_set_enable_interintra_comp(aom_codec_alg_priv_t * ctx,va_list args)2038 static aom_codec_err_t ctrl_set_enable_interintra_comp(
2039 aom_codec_alg_priv_t *ctx, va_list args) {
2040 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2041 extra_cfg.enable_interintra_comp =
2042 CAST(AV1E_SET_ENABLE_INTERINTRA_COMP, args);
2043 return update_extra_cfg(ctx, &extra_cfg);
2044 }
2045
ctrl_set_enable_smooth_interintra(aom_codec_alg_priv_t * ctx,va_list args)2046 static aom_codec_err_t ctrl_set_enable_smooth_interintra(
2047 aom_codec_alg_priv_t *ctx, va_list args) {
2048 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2049 extra_cfg.enable_smooth_interintra =
2050 CAST(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, args);
2051 return update_extra_cfg(ctx, &extra_cfg);
2052 }
2053
ctrl_set_enable_diff_wtd_comp(aom_codec_alg_priv_t * ctx,va_list args)2054 static aom_codec_err_t ctrl_set_enable_diff_wtd_comp(aom_codec_alg_priv_t *ctx,
2055 va_list args) {
2056 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2057 extra_cfg.enable_diff_wtd_comp = CAST(AV1E_SET_ENABLE_DIFF_WTD_COMP, args);
2058 return update_extra_cfg(ctx, &extra_cfg);
2059 }
2060
ctrl_set_enable_interinter_wedge(aom_codec_alg_priv_t * ctx,va_list args)2061 static aom_codec_err_t ctrl_set_enable_interinter_wedge(
2062 aom_codec_alg_priv_t *ctx, va_list args) {
2063 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2064 extra_cfg.enable_interinter_wedge =
2065 CAST(AV1E_SET_ENABLE_INTERINTER_WEDGE, args);
2066 return update_extra_cfg(ctx, &extra_cfg);
2067 }
2068
ctrl_set_enable_interintra_wedge(aom_codec_alg_priv_t * ctx,va_list args)2069 static aom_codec_err_t ctrl_set_enable_interintra_wedge(
2070 aom_codec_alg_priv_t *ctx, va_list args) {
2071 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2072 extra_cfg.enable_interintra_wedge =
2073 CAST(AV1E_SET_ENABLE_INTERINTRA_WEDGE, args);
2074 return update_extra_cfg(ctx, &extra_cfg);
2075 }
2076
ctrl_set_enable_global_motion(aom_codec_alg_priv_t * ctx,va_list args)2077 static aom_codec_err_t ctrl_set_enable_global_motion(aom_codec_alg_priv_t *ctx,
2078 va_list args) {
2079 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2080 const int global_motion_arg = CAST(AV1E_SET_ENABLE_GLOBAL_MOTION, args);
2081 #if CONFIG_REALTIME_ONLY
2082 if (global_motion_arg) {
2083 ERROR("Global motion can't be enabled in realtime only build.");
2084 }
2085 #endif
2086 extra_cfg.enable_global_motion = global_motion_arg;
2087 return update_extra_cfg(ctx, &extra_cfg);
2088 }
2089
ctrl_set_enable_warped_motion(aom_codec_alg_priv_t * ctx,va_list args)2090 static aom_codec_err_t ctrl_set_enable_warped_motion(aom_codec_alg_priv_t *ctx,
2091 va_list args) {
2092 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2093 const int warped_motion_arg = CAST(AV1E_SET_ENABLE_WARPED_MOTION, args);
2094 #if CONFIG_REALTIME_ONLY
2095 if (warped_motion_arg) {
2096 ERROR("Warped motion can't be enabled in realtime only build.");
2097 }
2098 #endif
2099 extra_cfg.enable_warped_motion = warped_motion_arg;
2100 return update_extra_cfg(ctx, &extra_cfg);
2101 }
2102
ctrl_set_allow_warped_motion(aom_codec_alg_priv_t * ctx,va_list args)2103 static aom_codec_err_t ctrl_set_allow_warped_motion(aom_codec_alg_priv_t *ctx,
2104 va_list args) {
2105 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2106 extra_cfg.allow_warped_motion = CAST(AV1E_SET_ALLOW_WARPED_MOTION, args);
2107 return update_extra_cfg(ctx, &extra_cfg);
2108 }
2109
ctrl_set_enable_filter_intra(aom_codec_alg_priv_t * ctx,va_list args)2110 static aom_codec_err_t ctrl_set_enable_filter_intra(aom_codec_alg_priv_t *ctx,
2111 va_list args) {
2112 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2113 extra_cfg.enable_filter_intra = CAST(AV1E_SET_ENABLE_FILTER_INTRA, args);
2114 return update_extra_cfg(ctx, &extra_cfg);
2115 }
2116
ctrl_set_enable_smooth_intra(aom_codec_alg_priv_t * ctx,va_list args)2117 static aom_codec_err_t ctrl_set_enable_smooth_intra(aom_codec_alg_priv_t *ctx,
2118 va_list args) {
2119 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2120 extra_cfg.enable_smooth_intra = CAST(AV1E_SET_ENABLE_SMOOTH_INTRA, args);
2121 return update_extra_cfg(ctx, &extra_cfg);
2122 }
2123
ctrl_set_enable_directional_intra(aom_codec_alg_priv_t * ctx,va_list args)2124 static aom_codec_err_t ctrl_set_enable_directional_intra(
2125 aom_codec_alg_priv_t *ctx, va_list args) {
2126 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2127 extra_cfg.enable_directional_intra =
2128 CAST(AV1E_SET_ENABLE_DIRECTIONAL_INTRA, args);
2129 return update_extra_cfg(ctx, &extra_cfg);
2130 }
2131
ctrl_set_enable_diagonal_intra(aom_codec_alg_priv_t * ctx,va_list args)2132 static aom_codec_err_t ctrl_set_enable_diagonal_intra(aom_codec_alg_priv_t *ctx,
2133 va_list args) {
2134 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2135 extra_cfg.enable_diagonal_intra = CAST(AV1E_SET_ENABLE_DIAGONAL_INTRA, args);
2136 return update_extra_cfg(ctx, &extra_cfg);
2137 }
2138
ctrl_set_enable_paeth_intra(aom_codec_alg_priv_t * ctx,va_list args)2139 static aom_codec_err_t ctrl_set_enable_paeth_intra(aom_codec_alg_priv_t *ctx,
2140 va_list args) {
2141 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2142 extra_cfg.enable_paeth_intra = CAST(AV1E_SET_ENABLE_PAETH_INTRA, args);
2143 return update_extra_cfg(ctx, &extra_cfg);
2144 }
2145
ctrl_set_enable_cfl_intra(aom_codec_alg_priv_t * ctx,va_list args)2146 static aom_codec_err_t ctrl_set_enable_cfl_intra(aom_codec_alg_priv_t *ctx,
2147 va_list args) {
2148 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2149 extra_cfg.enable_cfl_intra = CAST(AV1E_SET_ENABLE_CFL_INTRA, args);
2150 return update_extra_cfg(ctx, &extra_cfg);
2151 }
2152
ctrl_set_enable_superres(aom_codec_alg_priv_t * ctx,va_list args)2153 static aom_codec_err_t ctrl_set_enable_superres(aom_codec_alg_priv_t *ctx,
2154 va_list args) {
2155 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2156 extra_cfg.enable_superres = CAST(AV1E_SET_ENABLE_SUPERRES, args);
2157 return update_extra_cfg(ctx, &extra_cfg);
2158 }
2159
ctrl_set_enable_overlay(aom_codec_alg_priv_t * ctx,va_list args)2160 static aom_codec_err_t ctrl_set_enable_overlay(aom_codec_alg_priv_t *ctx,
2161 va_list args) {
2162 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2163 extra_cfg.enable_overlay = CAST(AV1E_SET_ENABLE_OVERLAY, args);
2164 return update_extra_cfg(ctx, &extra_cfg);
2165 }
2166
ctrl_set_enable_palette(aom_codec_alg_priv_t * ctx,va_list args)2167 static aom_codec_err_t ctrl_set_enable_palette(aom_codec_alg_priv_t *ctx,
2168 va_list args) {
2169 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2170 extra_cfg.enable_palette = CAST(AV1E_SET_ENABLE_PALETTE, args);
2171 return update_extra_cfg(ctx, &extra_cfg);
2172 }
2173
ctrl_set_enable_intrabc(aom_codec_alg_priv_t * ctx,va_list args)2174 static aom_codec_err_t ctrl_set_enable_intrabc(aom_codec_alg_priv_t *ctx,
2175 va_list args) {
2176 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2177 extra_cfg.enable_intrabc = CAST(AV1E_SET_ENABLE_INTRABC, args);
2178 return update_extra_cfg(ctx, &extra_cfg);
2179 }
2180
ctrl_set_enable_angle_delta(aom_codec_alg_priv_t * ctx,va_list args)2181 static aom_codec_err_t ctrl_set_enable_angle_delta(aom_codec_alg_priv_t *ctx,
2182 va_list args) {
2183 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2184 extra_cfg.enable_angle_delta = CAST(AV1E_SET_ENABLE_ANGLE_DELTA, args);
2185 return update_extra_cfg(ctx, &extra_cfg);
2186 }
2187
ctrl_set_error_resilient_mode(aom_codec_alg_priv_t * ctx,va_list args)2188 static aom_codec_err_t ctrl_set_error_resilient_mode(aom_codec_alg_priv_t *ctx,
2189 va_list args) {
2190 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2191 extra_cfg.error_resilient_mode = CAST(AV1E_SET_ERROR_RESILIENT_MODE, args);
2192 return update_extra_cfg(ctx, &extra_cfg);
2193 }
2194
ctrl_set_s_frame_mode(aom_codec_alg_priv_t * ctx,va_list args)2195 static aom_codec_err_t ctrl_set_s_frame_mode(aom_codec_alg_priv_t *ctx,
2196 va_list args) {
2197 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2198 extra_cfg.s_frame_mode = CAST(AV1E_SET_S_FRAME_MODE, args);
2199 return update_extra_cfg(ctx, &extra_cfg);
2200 }
2201
ctrl_set_frame_parallel_decoding_mode(aom_codec_alg_priv_t * ctx,va_list args)2202 static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
2203 aom_codec_alg_priv_t *ctx, va_list args) {
2204 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2205 extra_cfg.frame_parallel_decoding_mode =
2206 CAST(AV1E_SET_FRAME_PARALLEL_DECODING, args);
2207 return update_extra_cfg(ctx, &extra_cfg);
2208 }
2209
ctrl_set_single_tile_decoding(aom_codec_alg_priv_t * ctx,va_list args)2210 static aom_codec_err_t ctrl_set_single_tile_decoding(aom_codec_alg_priv_t *ctx,
2211 va_list args) {
2212 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2213 extra_cfg.single_tile_decoding = CAST(AV1E_SET_SINGLE_TILE_DECODING, args);
2214 return update_extra_cfg(ctx, &extra_cfg);
2215 }
2216
ctrl_set_aq_mode(aom_codec_alg_priv_t * ctx,va_list args)2217 static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
2218 va_list args) {
2219 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2220 extra_cfg.aq_mode = CAST(AV1E_SET_AQ_MODE, args);
2221
2222 // Skip AQ mode if using fixed QP for current frame.
2223 if (ctx->ppi->cpi->rc.use_external_qp_one_pass) extra_cfg.aq_mode = 0;
2224 return update_extra_cfg(ctx, &extra_cfg);
2225 }
2226
ctrl_set_reduced_tx_type_set(aom_codec_alg_priv_t * ctx,va_list args)2227 static aom_codec_err_t ctrl_set_reduced_tx_type_set(aom_codec_alg_priv_t *ctx,
2228 va_list args) {
2229 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2230 extra_cfg.reduced_tx_type_set = CAST(AV1E_SET_REDUCED_TX_TYPE_SET, args);
2231 return update_extra_cfg(ctx, &extra_cfg);
2232 }
2233
ctrl_set_intra_dct_only(aom_codec_alg_priv_t * ctx,va_list args)2234 static aom_codec_err_t ctrl_set_intra_dct_only(aom_codec_alg_priv_t *ctx,
2235 va_list args) {
2236 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2237 extra_cfg.use_intra_dct_only = CAST(AV1E_SET_INTRA_DCT_ONLY, args);
2238 return update_extra_cfg(ctx, &extra_cfg);
2239 }
2240
ctrl_set_inter_dct_only(aom_codec_alg_priv_t * ctx,va_list args)2241 static aom_codec_err_t ctrl_set_inter_dct_only(aom_codec_alg_priv_t *ctx,
2242 va_list args) {
2243 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2244 extra_cfg.use_inter_dct_only = CAST(AV1E_SET_INTER_DCT_ONLY, args);
2245 return update_extra_cfg(ctx, &extra_cfg);
2246 }
2247
ctrl_set_intra_default_tx_only(aom_codec_alg_priv_t * ctx,va_list args)2248 static aom_codec_err_t ctrl_set_intra_default_tx_only(aom_codec_alg_priv_t *ctx,
2249 va_list args) {
2250 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2251 extra_cfg.use_intra_default_tx_only =
2252 CAST(AV1E_SET_INTRA_DEFAULT_TX_ONLY, args);
2253 return update_extra_cfg(ctx, &extra_cfg);
2254 }
2255
ctrl_set_enable_tx_size_search(aom_codec_alg_priv_t * ctx,va_list args)2256 static aom_codec_err_t ctrl_set_enable_tx_size_search(aom_codec_alg_priv_t *ctx,
2257 va_list args) {
2258 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2259 extra_cfg.enable_tx_size_search = CAST(AV1E_SET_ENABLE_TX_SIZE_SEARCH, args);
2260 return update_extra_cfg(ctx, &extra_cfg);
2261 }
2262
ctrl_set_quant_b_adapt(aom_codec_alg_priv_t * ctx,va_list args)2263 static aom_codec_err_t ctrl_set_quant_b_adapt(aom_codec_alg_priv_t *ctx,
2264 va_list args) {
2265 #if CONFIG_REALTIME_ONLY
2266 (void)ctx;
2267 (void)args;
2268 return AOM_CODEC_INCAPABLE;
2269 #else
2270 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2271 extra_cfg.quant_b_adapt = CAST(AV1E_SET_QUANT_B_ADAPT, args);
2272 return update_extra_cfg(ctx, &extra_cfg);
2273 #endif
2274 }
2275
ctrl_set_vbr_corpus_complexity_lap(aom_codec_alg_priv_t * ctx,va_list args)2276 static aom_codec_err_t ctrl_set_vbr_corpus_complexity_lap(
2277 aom_codec_alg_priv_t *ctx, va_list args) {
2278 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2279 extra_cfg.vbr_corpus_complexity_lap =
2280 CAST(AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP, args);
2281 return update_extra_cfg(ctx, &extra_cfg);
2282 }
ctrl_set_coeff_cost_upd_freq(aom_codec_alg_priv_t * ctx,va_list args)2283 static aom_codec_err_t ctrl_set_coeff_cost_upd_freq(aom_codec_alg_priv_t *ctx,
2284 va_list args) {
2285 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2286 extra_cfg.coeff_cost_upd_freq = CAST(AV1E_SET_COEFF_COST_UPD_FREQ, args);
2287 return update_extra_cfg(ctx, &extra_cfg);
2288 }
2289
ctrl_set_mode_cost_upd_freq(aom_codec_alg_priv_t * ctx,va_list args)2290 static aom_codec_err_t ctrl_set_mode_cost_upd_freq(aom_codec_alg_priv_t *ctx,
2291 va_list args) {
2292 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2293 extra_cfg.mode_cost_upd_freq = CAST(AV1E_SET_MODE_COST_UPD_FREQ, args);
2294 return update_extra_cfg(ctx, &extra_cfg);
2295 }
2296
ctrl_set_mv_cost_upd_freq(aom_codec_alg_priv_t * ctx,va_list args)2297 static aom_codec_err_t ctrl_set_mv_cost_upd_freq(aom_codec_alg_priv_t *ctx,
2298 va_list args) {
2299 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2300 extra_cfg.mv_cost_upd_freq = CAST(AV1E_SET_MV_COST_UPD_FREQ, args);
2301 return update_extra_cfg(ctx, &extra_cfg);
2302 }
2303
ctrl_set_dv_cost_upd_freq(aom_codec_alg_priv_t * ctx,va_list args)2304 static aom_codec_err_t ctrl_set_dv_cost_upd_freq(aom_codec_alg_priv_t *ctx,
2305 va_list args) {
2306 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2307 extra_cfg.dv_cost_upd_freq = CAST(AV1E_SET_DV_COST_UPD_FREQ, args);
2308 return update_extra_cfg(ctx, &extra_cfg);
2309 }
2310
ctrl_set_vmaf_model_path(aom_codec_alg_priv_t * ctx,va_list args)2311 static aom_codec_err_t ctrl_set_vmaf_model_path(aom_codec_alg_priv_t *ctx,
2312 va_list args) {
2313 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2314 const char *str = CAST(AV1E_SET_VMAF_MODEL_PATH, args);
2315 const aom_codec_err_t ret = allocate_and_set_string(
2316 str, default_extra_cfg.vmaf_model_path, &extra_cfg.vmaf_model_path,
2317 ctx->ppi->error.detail);
2318 if (ret != AOM_CODEC_OK) return ret;
2319 return update_extra_cfg(ctx, &extra_cfg);
2320 }
2321
ctrl_set_partition_info_path(aom_codec_alg_priv_t * ctx,va_list args)2322 static aom_codec_err_t ctrl_set_partition_info_path(aom_codec_alg_priv_t *ctx,
2323 va_list args) {
2324 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2325 const char *str = CAST(AV1E_SET_PARTITION_INFO_PATH, args);
2326 const aom_codec_err_t ret = allocate_and_set_string(
2327 str, default_extra_cfg.partition_info_path,
2328 &extra_cfg.partition_info_path, ctx->ppi->error.detail);
2329 if (ret != AOM_CODEC_OK) return ret;
2330 return update_extra_cfg(ctx, &extra_cfg);
2331 }
2332
ctrl_enable_rate_guide_deltaq(aom_codec_alg_priv_t * ctx,va_list args)2333 static aom_codec_err_t ctrl_enable_rate_guide_deltaq(aom_codec_alg_priv_t *ctx,
2334 va_list args) {
2335 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2336 extra_cfg.enable_rate_guide_deltaq =
2337 CAST(AV1E_ENABLE_RATE_GUIDE_DELTAQ, args);
2338 return update_extra_cfg(ctx, &extra_cfg);
2339 }
2340
ctrl_set_rate_distribution_info(aom_codec_alg_priv_t * ctx,va_list args)2341 static aom_codec_err_t ctrl_set_rate_distribution_info(
2342 aom_codec_alg_priv_t *ctx, va_list args) {
2343 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2344 const char *str = CAST(AV1E_SET_RATE_DISTRIBUTION_INFO, args);
2345 const aom_codec_err_t ret = allocate_and_set_string(
2346 str, default_extra_cfg.rate_distribution_info,
2347 &extra_cfg.rate_distribution_info, ctx->ppi->error.detail);
2348 if (ret != AOM_CODEC_OK) return ret;
2349 return update_extra_cfg(ctx, &extra_cfg);
2350 }
2351
ctrl_set_film_grain_test_vector(aom_codec_alg_priv_t * ctx,va_list args)2352 static aom_codec_err_t ctrl_set_film_grain_test_vector(
2353 aom_codec_alg_priv_t *ctx, va_list args) {
2354 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2355 extra_cfg.film_grain_test_vector =
2356 CAST(AV1E_SET_FILM_GRAIN_TEST_VECTOR, args);
2357 return update_extra_cfg(ctx, &extra_cfg);
2358 }
2359
ctrl_set_film_grain_table(aom_codec_alg_priv_t * ctx,va_list args)2360 static aom_codec_err_t ctrl_set_film_grain_table(aom_codec_alg_priv_t *ctx,
2361 va_list args) {
2362 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2363 const char *str = CAST(AV1E_SET_FILM_GRAIN_TABLE, args);
2364 if (str == NULL) {
2365 // this parameter allows NULL as its value
2366 extra_cfg.film_grain_table_filename = str;
2367 } else {
2368 const aom_codec_err_t ret = allocate_and_set_string(
2369 str, default_extra_cfg.film_grain_table_filename,
2370 &extra_cfg.film_grain_table_filename, ctx->ppi->error.detail);
2371 if (ret != AOM_CODEC_OK) return ret;
2372 }
2373 return update_extra_cfg(ctx, &extra_cfg);
2374 }
2375
ctrl_set_denoise_noise_level(aom_codec_alg_priv_t * ctx,va_list args)2376 static aom_codec_err_t ctrl_set_denoise_noise_level(aom_codec_alg_priv_t *ctx,
2377 va_list args) {
2378 #if !CONFIG_DENOISE
2379 (void)ctx;
2380 (void)args;
2381 return AOM_CODEC_INCAPABLE;
2382 #else
2383 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2384 extra_cfg.noise_level =
2385 ((float)CAST(AV1E_SET_DENOISE_NOISE_LEVEL, args)) / 10.0f;
2386 return update_extra_cfg(ctx, &extra_cfg);
2387 #endif
2388 }
2389
ctrl_set_denoise_block_size(aom_codec_alg_priv_t * ctx,va_list args)2390 static aom_codec_err_t ctrl_set_denoise_block_size(aom_codec_alg_priv_t *ctx,
2391 va_list args) {
2392 #if !CONFIG_DENOISE
2393 (void)ctx;
2394 (void)args;
2395 return AOM_CODEC_INCAPABLE;
2396 #else
2397 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2398 extra_cfg.noise_block_size = CAST(AV1E_SET_DENOISE_BLOCK_SIZE, args);
2399 return update_extra_cfg(ctx, &extra_cfg);
2400 #endif
2401 }
2402
ctrl_set_enable_dnl_denoising(aom_codec_alg_priv_t * ctx,va_list args)2403 static aom_codec_err_t ctrl_set_enable_dnl_denoising(aom_codec_alg_priv_t *ctx,
2404 va_list args) {
2405 #if !CONFIG_DENOISE
2406 (void)ctx;
2407 (void)args;
2408 return AOM_CODEC_INCAPABLE;
2409 #else
2410 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2411 extra_cfg.enable_dnl_denoising = CAST(AV1E_SET_ENABLE_DNL_DENOISING, args);
2412 return update_extra_cfg(ctx, &extra_cfg);
2413 #endif
2414 }
2415
ctrl_set_deltaq_mode(aom_codec_alg_priv_t * ctx,va_list args)2416 static aom_codec_err_t ctrl_set_deltaq_mode(aom_codec_alg_priv_t *ctx,
2417 va_list args) {
2418 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2419 const DELTAQ_MODE deltaq_arg = CAST(AV1E_SET_DELTAQ_MODE, args);
2420 #if CONFIG_REALTIME_ONLY
2421 if (deltaq_arg > NO_DELTA_Q) {
2422 ERROR("Delta Q mode can't be enabled in realtime only build.");
2423 }
2424 #endif
2425 extra_cfg.deltaq_mode = deltaq_arg;
2426 return update_extra_cfg(ctx, &extra_cfg);
2427 }
2428
ctrl_set_deltaq_strength(aom_codec_alg_priv_t * ctx,va_list args)2429 static aom_codec_err_t ctrl_set_deltaq_strength(aom_codec_alg_priv_t *ctx,
2430 va_list args) {
2431 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2432 extra_cfg.deltaq_strength = CAST(AV1E_SET_DELTAQ_STRENGTH, args);
2433 return update_extra_cfg(ctx, &extra_cfg);
2434 }
2435
ctrl_set_deltalf_mode(aom_codec_alg_priv_t * ctx,va_list args)2436 static aom_codec_err_t ctrl_set_deltalf_mode(aom_codec_alg_priv_t *ctx,
2437 va_list args) {
2438 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2439 extra_cfg.deltalf_mode = CAST(AV1E_SET_DELTALF_MODE, args);
2440 return update_extra_cfg(ctx, &extra_cfg);
2441 }
2442
ctrl_set_min_gf_interval(aom_codec_alg_priv_t * ctx,va_list args)2443 static aom_codec_err_t ctrl_set_min_gf_interval(aom_codec_alg_priv_t *ctx,
2444 va_list args) {
2445 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2446 extra_cfg.min_gf_interval = CAST(AV1E_SET_MIN_GF_INTERVAL, args);
2447 return update_extra_cfg(ctx, &extra_cfg);
2448 }
2449
ctrl_set_max_gf_interval(aom_codec_alg_priv_t * ctx,va_list args)2450 static aom_codec_err_t ctrl_set_max_gf_interval(aom_codec_alg_priv_t *ctx,
2451 va_list args) {
2452 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2453 extra_cfg.max_gf_interval = CAST(AV1E_SET_MAX_GF_INTERVAL, args);
2454 return update_extra_cfg(ctx, &extra_cfg);
2455 }
2456
ctrl_set_gf_min_pyr_height(aom_codec_alg_priv_t * ctx,va_list args)2457 static aom_codec_err_t ctrl_set_gf_min_pyr_height(aom_codec_alg_priv_t *ctx,
2458 va_list args) {
2459 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2460 extra_cfg.gf_min_pyr_height = CAST(AV1E_SET_GF_MIN_PYRAMID_HEIGHT, args);
2461 return update_extra_cfg(ctx, &extra_cfg);
2462 }
2463
ctrl_set_gf_max_pyr_height(aom_codec_alg_priv_t * ctx,va_list args)2464 static aom_codec_err_t ctrl_set_gf_max_pyr_height(aom_codec_alg_priv_t *ctx,
2465 va_list args) {
2466 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2467 extra_cfg.gf_max_pyr_height = CAST(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, args);
2468 return update_extra_cfg(ctx, &extra_cfg);
2469 }
2470
ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t * ctx,va_list args)2471 static aom_codec_err_t ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t *ctx,
2472 va_list args) {
2473 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2474 extra_cfg.frame_periodic_boost = CAST(AV1E_SET_FRAME_PERIODIC_BOOST, args);
2475 return update_extra_cfg(ctx, &extra_cfg);
2476 }
2477
ctrl_enable_motion_vector_unit_test(aom_codec_alg_priv_t * ctx,va_list args)2478 static aom_codec_err_t ctrl_enable_motion_vector_unit_test(
2479 aom_codec_alg_priv_t *ctx, va_list args) {
2480 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2481 extra_cfg.motion_vector_unit_test =
2482 CAST(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, args);
2483 return update_extra_cfg(ctx, &extra_cfg);
2484 }
2485
ctrl_enable_fpmt_unit_test(aom_codec_alg_priv_t * ctx,va_list args)2486 static aom_codec_err_t ctrl_enable_fpmt_unit_test(aom_codec_alg_priv_t *ctx,
2487 va_list args) {
2488 #if !CONFIG_FPMT_TEST
2489 (void)args;
2490 (void)ctx;
2491 return AOM_CODEC_INCAPABLE;
2492 #else
2493 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2494 extra_cfg.fpmt_unit_test = CAST(AV1E_SET_FP_MT_UNIT_TEST, args);
2495 ctx->ppi->fpmt_unit_test_cfg = (extra_cfg.fpmt_unit_test == 1)
2496 ? PARALLEL_ENCODE
2497 : PARALLEL_SIMULATION_ENCODE;
2498 return update_extra_cfg(ctx, &extra_cfg);
2499 #endif
2500 }
2501
ctrl_enable_ext_tile_debug(aom_codec_alg_priv_t * ctx,va_list args)2502 static aom_codec_err_t ctrl_enable_ext_tile_debug(aom_codec_alg_priv_t *ctx,
2503 va_list args) {
2504 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2505 extra_cfg.ext_tile_debug = CAST(AV1E_ENABLE_EXT_TILE_DEBUG, args);
2506 return update_extra_cfg(ctx, &extra_cfg);
2507 }
2508
ctrl_set_target_seq_level_idx(aom_codec_alg_priv_t * ctx,va_list args)2509 static aom_codec_err_t ctrl_set_target_seq_level_idx(aom_codec_alg_priv_t *ctx,
2510 va_list args) {
2511 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2512 const int val = CAST(AV1E_SET_TARGET_SEQ_LEVEL_IDX, args);
2513 const int level = val % 100;
2514 const int operating_point_idx = val / 100;
2515 if (operating_point_idx < 0 ||
2516 operating_point_idx >= MAX_NUM_OPERATING_POINTS) {
2517 char *const err_string = ctx->ppi->error.detail;
2518 snprintf(err_string, ARG_ERR_MSG_MAX_LEN,
2519 "Invalid operating point index: %d", operating_point_idx);
2520 ctx->base.err_detail = err_string;
2521 return AOM_CODEC_INVALID_PARAM;
2522 }
2523 extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
2524 return update_extra_cfg(ctx, &extra_cfg);
2525 }
2526
ctrl_set_tier_mask(aom_codec_alg_priv_t * ctx,va_list args)2527 static aom_codec_err_t ctrl_set_tier_mask(aom_codec_alg_priv_t *ctx,
2528 va_list args) {
2529 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2530 extra_cfg.tier_mask = CAST(AV1E_SET_TIER_MASK, args);
2531 return update_extra_cfg(ctx, &extra_cfg);
2532 }
2533
ctrl_set_min_cr(aom_codec_alg_priv_t * ctx,va_list args)2534 static aom_codec_err_t ctrl_set_min_cr(aom_codec_alg_priv_t *ctx,
2535 va_list args) {
2536 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2537 extra_cfg.min_cr = CAST(AV1E_SET_MIN_CR, args);
2538 return update_extra_cfg(ctx, &extra_cfg);
2539 }
2540
ctrl_enable_sb_multipass_unit_test(aom_codec_alg_priv_t * ctx,va_list args)2541 static aom_codec_err_t ctrl_enable_sb_multipass_unit_test(
2542 aom_codec_alg_priv_t *ctx, va_list args) {
2543 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2544 extra_cfg.sb_multipass_unit_test =
2545 CAST(AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST, args);
2546 return update_extra_cfg(ctx, &extra_cfg);
2547 }
2548
ctrl_enable_sb_qp_sweep(aom_codec_alg_priv_t * ctx,va_list args)2549 static aom_codec_err_t ctrl_enable_sb_qp_sweep(aom_codec_alg_priv_t *ctx,
2550 va_list args) {
2551 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2552 extra_cfg.sb_qp_sweep = CAST(AV1E_ENABLE_SB_QP_SWEEP, args);
2553 return update_extra_cfg(ctx, &extra_cfg);
2554 }
2555
ctrl_set_external_partition(aom_codec_alg_priv_t * ctx,va_list args)2556 static aom_codec_err_t ctrl_set_external_partition(aom_codec_alg_priv_t *ctx,
2557 va_list args) {
2558 AV1_COMP *const cpi = ctx->ppi->cpi;
2559 aom_ext_part_funcs_t funcs = *CAST(AV1E_SET_EXTERNAL_PARTITION, args);
2560 aom_ext_part_config_t config;
2561 // TODO(chengchen): verify the sb_size has been set at this point.
2562 config.superblock_size = cpi->common.seq_params->sb_size;
2563 const aom_codec_err_t status =
2564 av1_ext_part_create(funcs, config, &cpi->ext_part_controller);
2565 return status;
2566 }
2567
ctrl_set_loopfilter_control(aom_codec_alg_priv_t * ctx,va_list args)2568 static aom_codec_err_t ctrl_set_loopfilter_control(aom_codec_alg_priv_t *ctx,
2569 va_list args) {
2570 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2571 extra_cfg.loopfilter_control = CAST(AV1E_SET_LOOPFILTER_CONTROL, args);
2572 return update_extra_cfg(ctx, &extra_cfg);
2573 }
2574
ctrl_set_skip_postproc_filtering(aom_codec_alg_priv_t * ctx,va_list args)2575 static aom_codec_err_t ctrl_set_skip_postproc_filtering(
2576 aom_codec_alg_priv_t *ctx, va_list args) {
2577 // Skipping the application of post-processing filters is allowed only
2578 // for ALLINTRA mode.
2579 if (ctx->cfg.g_usage != AOM_USAGE_ALL_INTRA) return AOM_CODEC_INCAPABLE;
2580 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2581 extra_cfg.skip_postproc_filtering =
2582 CAST(AV1E_SET_SKIP_POSTPROC_FILTERING, args);
2583 return update_extra_cfg(ctx, &extra_cfg);
2584 }
2585
ctrl_set_rtc_external_rc(aom_codec_alg_priv_t * ctx,va_list args)2586 static aom_codec_err_t ctrl_set_rtc_external_rc(aom_codec_alg_priv_t *ctx,
2587 va_list args) {
2588 ctx->ppi->cpi->rc.rtc_external_ratectrl =
2589 CAST(AV1E_SET_RTC_EXTERNAL_RC, args);
2590 return AOM_CODEC_OK;
2591 }
2592
ctrl_set_quantizer_one_pass(aom_codec_alg_priv_t * ctx,va_list args)2593 static aom_codec_err_t ctrl_set_quantizer_one_pass(aom_codec_alg_priv_t *ctx,
2594 va_list args) {
2595 const int qp = CAST(AV1E_SET_QUANTIZER_ONE_PASS, args);
2596
2597 if (qp < 0 || qp > 63) return AOM_CODEC_INVALID_PARAM;
2598
2599 aom_codec_enc_cfg_t *cfg = &ctx->cfg;
2600 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2601 cfg->rc_min_quantizer = cfg->rc_max_quantizer = qp;
2602 extra_cfg.aq_mode = 0;
2603 ctx->ppi->cpi->rc.use_external_qp_one_pass = 1;
2604
2605 return update_extra_cfg(ctx, &extra_cfg);
2606 }
2607
ctrl_set_bitrate_one_pass_cbr(aom_codec_alg_priv_t * ctx,va_list args)2608 static aom_codec_err_t ctrl_set_bitrate_one_pass_cbr(aom_codec_alg_priv_t *ctx,
2609 va_list args) {
2610 AV1_PRIMARY *const ppi = ctx->ppi;
2611 AV1_COMP *const cpi = ppi->cpi;
2612 AV1EncoderConfig *oxcf = &cpi->oxcf;
2613 if (!is_one_pass_rt_params(cpi) || oxcf->rc_cfg.mode != AOM_CBR ||
2614 cpi->ppi->use_svc || ppi->num_fp_contexts != 1 || ppi->cpi_lap != NULL) {
2615 return AOM_CODEC_INVALID_PARAM;
2616 }
2617 const int new_bitrate = CAST(AV1E_SET_BITRATE_ONE_PASS_CBR, args);
2618 ctx->cfg.rc_target_bitrate = new_bitrate;
2619 oxcf->rc_cfg.target_bandwidth = new_bitrate * 1000;
2620 set_primary_rc_buffer_sizes(oxcf, ppi);
2621 av1_new_framerate(cpi, cpi->framerate);
2622 check_reset_rc_flag(cpi);
2623 return AOM_CODEC_OK;
2624 }
2625
ctrl_set_max_consec_frame_drop_cbr(aom_codec_alg_priv_t * ctx,va_list args)2626 static aom_codec_err_t ctrl_set_max_consec_frame_drop_cbr(
2627 aom_codec_alg_priv_t *ctx, va_list args) {
2628 AV1_PRIMARY *const ppi = ctx->ppi;
2629 AV1_COMP *const cpi = ppi->cpi;
2630 const int max_consec_drop = CAST(AV1E_SET_MAX_CONSEC_FRAME_DROP_CBR, args);
2631 if (max_consec_drop < 0) return AOM_CODEC_INVALID_PARAM;
2632 cpi->rc.max_consec_drop = max_consec_drop;
2633 cpi->rc.drop_count_consec = 0;
2634 return AOM_CODEC_OK;
2635 }
2636
ctrl_set_svc_frame_drop_mode(aom_codec_alg_priv_t * ctx,va_list args)2637 static aom_codec_err_t ctrl_set_svc_frame_drop_mode(aom_codec_alg_priv_t *ctx,
2638 va_list args) {
2639 AV1_PRIMARY *const ppi = ctx->ppi;
2640 AV1_COMP *const cpi = ppi->cpi;
2641 cpi->svc.framedrop_mode = CAST(AV1E_SET_SVC_FRAME_DROP_MODE, args);
2642 if (cpi->svc.framedrop_mode != AOM_LAYER_DROP &&
2643 cpi->svc.framedrop_mode != AOM_FULL_SUPERFRAME_DROP)
2644 return AOM_CODEC_INVALID_PARAM;
2645 else
2646 return AOM_CODEC_OK;
2647 }
2648
2649 #if !CONFIG_REALTIME_ONLY
create_stats_buffer(FIRSTPASS_STATS ** frame_stats_buffer,STATS_BUFFER_CTX * stats_buf_context,int num_lap_buffers)2650 static aom_codec_err_t create_stats_buffer(FIRSTPASS_STATS **frame_stats_buffer,
2651 STATS_BUFFER_CTX *stats_buf_context,
2652 int num_lap_buffers) {
2653 aom_codec_err_t res = AOM_CODEC_OK;
2654
2655 int size = get_stats_buf_size(num_lap_buffers, MAX_LAG_BUFFERS);
2656 *frame_stats_buffer =
2657 (FIRSTPASS_STATS *)aom_calloc(size, sizeof(FIRSTPASS_STATS));
2658 if (*frame_stats_buffer == NULL) return AOM_CODEC_MEM_ERROR;
2659
2660 stats_buf_context->stats_in_start = *frame_stats_buffer;
2661 stats_buf_context->stats_in_end = stats_buf_context->stats_in_start;
2662 stats_buf_context->stats_in_buf_end =
2663 stats_buf_context->stats_in_start + size;
2664
2665 stats_buf_context->total_left_stats = aom_calloc(1, sizeof(FIRSTPASS_STATS));
2666 if (stats_buf_context->total_left_stats == NULL) return AOM_CODEC_MEM_ERROR;
2667 av1_twopass_zero_stats(stats_buf_context->total_left_stats);
2668 stats_buf_context->total_stats = aom_calloc(1, sizeof(FIRSTPASS_STATS));
2669 if (stats_buf_context->total_stats == NULL) return AOM_CODEC_MEM_ERROR;
2670 av1_twopass_zero_stats(stats_buf_context->total_stats);
2671 return res;
2672 }
2673 #endif
2674
av1_create_context_and_bufferpool(AV1_PRIMARY * ppi,AV1_COMP ** p_cpi,BufferPool ** p_buffer_pool,const AV1EncoderConfig * oxcf,COMPRESSOR_STAGE stage,int lap_lag_in_frames)2675 aom_codec_err_t av1_create_context_and_bufferpool(AV1_PRIMARY *ppi,
2676 AV1_COMP **p_cpi,
2677 BufferPool **p_buffer_pool,
2678 const AV1EncoderConfig *oxcf,
2679 COMPRESSOR_STAGE stage,
2680 int lap_lag_in_frames) {
2681 aom_codec_err_t res = AOM_CODEC_OK;
2682 BufferPool *buffer_pool = *p_buffer_pool;
2683
2684 if (buffer_pool == NULL) {
2685 buffer_pool = (BufferPool *)aom_calloc(1, sizeof(BufferPool));
2686 if (buffer_pool == NULL) return AOM_CODEC_MEM_ERROR;
2687 buffer_pool->num_frame_bufs =
2688 (oxcf->mode == ALLINTRA) ? FRAME_BUFFERS_ALLINTRA : FRAME_BUFFERS;
2689 buffer_pool->frame_bufs = (RefCntBuffer *)aom_calloc(
2690 buffer_pool->num_frame_bufs, sizeof(*buffer_pool->frame_bufs));
2691 if (buffer_pool->frame_bufs == NULL) {
2692 buffer_pool->num_frame_bufs = 0;
2693 aom_free(buffer_pool);
2694 return AOM_CODEC_MEM_ERROR;
2695 }
2696 #if CONFIG_MULTITHREAD
2697 if (pthread_mutex_init(&buffer_pool->pool_mutex, NULL)) {
2698 aom_free(buffer_pool->frame_bufs);
2699 buffer_pool->frame_bufs = NULL;
2700 buffer_pool->num_frame_bufs = 0;
2701 aom_free(buffer_pool);
2702 return AOM_CODEC_MEM_ERROR;
2703 }
2704 #endif
2705 *p_buffer_pool = buffer_pool;
2706 }
2707 *p_cpi =
2708 av1_create_compressor(ppi, oxcf, buffer_pool, stage, lap_lag_in_frames);
2709 if (*p_cpi == NULL) res = AOM_CODEC_MEM_ERROR;
2710
2711 return res;
2712 }
2713
ctrl_set_fp_mt(aom_codec_alg_priv_t * ctx,va_list args)2714 static aom_codec_err_t ctrl_set_fp_mt(aom_codec_alg_priv_t *ctx, va_list args) {
2715 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2716 extra_cfg.fp_mt = CAST(AV1E_SET_FP_MT, args);
2717 const aom_codec_err_t result = update_extra_cfg(ctx, &extra_cfg);
2718 int num_fp_contexts = 1;
2719 if (ctx->ppi->num_fp_contexts == 1) {
2720 num_fp_contexts =
2721 av1_compute_num_fp_contexts(ctx->ppi, &ctx->ppi->parallel_cpi[0]->oxcf);
2722 if (num_fp_contexts > 1) {
2723 int i;
2724 for (i = 1; i < num_fp_contexts; i++) {
2725 int res = av1_create_context_and_bufferpool(
2726 ctx->ppi, &ctx->ppi->parallel_cpi[i], &ctx->buffer_pool, &ctx->oxcf,
2727 ENCODE_STAGE, -1);
2728 if (res != AOM_CODEC_OK) {
2729 return res;
2730 }
2731 #if !CONFIG_REALTIME_ONLY
2732 ctx->ppi->parallel_cpi[i]->twopass_frame.stats_in =
2733 ctx->ppi->twopass.stats_buf_ctx->stats_in_start;
2734 #endif
2735 }
2736 }
2737 }
2738 ctx->ppi->num_fp_contexts = num_fp_contexts;
2739 return result;
2740 }
2741
ctrl_set_auto_intra_tools_off(aom_codec_alg_priv_t * ctx,va_list args)2742 static aom_codec_err_t ctrl_set_auto_intra_tools_off(aom_codec_alg_priv_t *ctx,
2743 va_list args) {
2744 struct av1_extracfg extra_cfg = ctx->extra_cfg;
2745 extra_cfg.auto_intra_tools_off = CAST(AV1E_SET_AUTO_INTRA_TOOLS_OFF, args);
2746 return update_extra_cfg(ctx, &extra_cfg);
2747 }
2748
encoder_init(aom_codec_ctx_t * ctx)2749 static aom_codec_err_t encoder_init(aom_codec_ctx_t *ctx) {
2750 aom_codec_err_t res = AOM_CODEC_OK;
2751
2752 if (ctx->priv == NULL) {
2753 aom_codec_alg_priv_t *const priv = aom_calloc(1, sizeof(*priv));
2754 if (priv == NULL) return AOM_CODEC_MEM_ERROR;
2755
2756 ctx->priv = (aom_codec_priv_t *)priv;
2757 ctx->priv->init_flags = ctx->init_flags;
2758
2759 // Update the reference to the config structure to an internal copy.
2760 assert(ctx->config.enc);
2761 priv->cfg = *ctx->config.enc;
2762 ctx->config.enc = &priv->cfg;
2763
2764 priv->extra_cfg = default_extra_cfg;
2765 // Special handling:
2766 // By default, if omitted, --enable-cdef = 1.
2767 // Here we set its default value to 0 when --allintra is turned on.
2768 // However, if users set --enable-cdef = 1 from command line,
2769 // The encoder still respects it.
2770 if (priv->cfg.g_usage == ALLINTRA) {
2771 priv->extra_cfg.enable_cdef = 0;
2772 }
2773 av1_initialize_enc(priv->cfg.g_usage, priv->cfg.rc_end_usage);
2774
2775 res = validate_config(priv, &priv->cfg, &priv->extra_cfg);
2776
2777 if (res == AOM_CODEC_OK) {
2778 int *num_lap_buffers = &priv->num_lap_buffers;
2779 int lap_lag_in_frames = 0;
2780 *num_lap_buffers = 0;
2781 priv->timestamp_ratio.den = priv->cfg.g_timebase.den;
2782 priv->timestamp_ratio.num =
2783 (int64_t)priv->cfg.g_timebase.num * TICKS_PER_SEC;
2784 reduce_ratio(&priv->timestamp_ratio);
2785
2786 set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
2787 if (priv->oxcf.rc_cfg.mode != AOM_CBR &&
2788 priv->oxcf.pass == AOM_RC_ONE_PASS && priv->oxcf.mode == GOOD) {
2789 // Enable look ahead - enabled for AOM_Q, AOM_CQ, AOM_VBR
2790 *num_lap_buffers =
2791 AOMMIN((int)priv->cfg.g_lag_in_frames,
2792 AOMMIN(MAX_LAP_BUFFERS, priv->oxcf.kf_cfg.key_freq_max +
2793 SCENE_CUT_KEY_TEST_INTERVAL));
2794 if ((int)priv->cfg.g_lag_in_frames - (*num_lap_buffers) >=
2795 LAP_LAG_IN_FRAMES) {
2796 lap_lag_in_frames = LAP_LAG_IN_FRAMES;
2797 }
2798 }
2799 priv->oxcf.use_highbitdepth =
2800 (ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
2801
2802 priv->monochrome_on_init = priv->cfg.monochrome;
2803
2804 priv->ppi = av1_create_primary_compressor(&priv->pkt_list.head,
2805 *num_lap_buffers, &priv->oxcf);
2806 if (!priv->ppi) return AOM_CODEC_MEM_ERROR;
2807
2808 #if !CONFIG_REALTIME_ONLY
2809 res = create_stats_buffer(&priv->frame_stats_buffer,
2810 &priv->stats_buf_context, *num_lap_buffers);
2811 if (res != AOM_CODEC_OK) return AOM_CODEC_MEM_ERROR;
2812
2813 assert(MAX_LAP_BUFFERS >= MAX_LAG_BUFFERS);
2814 int size = get_stats_buf_size(*num_lap_buffers, MAX_LAG_BUFFERS);
2815 for (int i = 0; i < size; i++)
2816 priv->ppi->twopass.frame_stats_arr[i] = &priv->frame_stats_buffer[i];
2817
2818 priv->ppi->twopass.stats_buf_ctx = &priv->stats_buf_context;
2819 #endif
2820
2821 assert(priv->ppi->num_fp_contexts >= 1);
2822 res = av1_create_context_and_bufferpool(
2823 priv->ppi, &priv->ppi->parallel_cpi[0], &priv->buffer_pool,
2824 &priv->oxcf, ENCODE_STAGE, -1);
2825 if (res != AOM_CODEC_OK) {
2826 return res;
2827 }
2828 #if !CONFIG_REALTIME_ONLY
2829 priv->ppi->parallel_cpi[0]->twopass_frame.stats_in =
2830 priv->ppi->twopass.stats_buf_ctx->stats_in_start;
2831 #endif
2832 priv->ppi->cpi = priv->ppi->parallel_cpi[0];
2833
2834 // Create another compressor if look ahead is enabled
2835 if (res == AOM_CODEC_OK && *num_lap_buffers) {
2836 res = av1_create_context_and_bufferpool(
2837 priv->ppi, &priv->ppi->cpi_lap, &priv->buffer_pool_lap, &priv->oxcf,
2838 LAP_STAGE, clamp(lap_lag_in_frames, 0, MAX_LAG_BUFFERS));
2839 }
2840 }
2841 }
2842
2843 return res;
2844 }
2845
av1_destroy_context_and_bufferpool(AV1_COMP * cpi,BufferPool ** p_buffer_pool)2846 void av1_destroy_context_and_bufferpool(AV1_COMP *cpi,
2847 BufferPool **p_buffer_pool) {
2848 av1_remove_compressor(cpi);
2849 if (*p_buffer_pool) {
2850 av1_free_ref_frame_buffers(*p_buffer_pool);
2851 #if CONFIG_MULTITHREAD
2852 pthread_mutex_destroy(&(*p_buffer_pool)->pool_mutex);
2853 #endif
2854 aom_free(*p_buffer_pool);
2855 *p_buffer_pool = NULL;
2856 }
2857 }
2858
destroy_stats_buffer(STATS_BUFFER_CTX * stats_buf_context,FIRSTPASS_STATS * frame_stats_buffer)2859 static void destroy_stats_buffer(STATS_BUFFER_CTX *stats_buf_context,
2860 FIRSTPASS_STATS *frame_stats_buffer) {
2861 aom_free(stats_buf_context->total_left_stats);
2862 aom_free(stats_buf_context->total_stats);
2863 aom_free(frame_stats_buffer);
2864 }
2865
check_and_free_string(const char * default_str,const char ** ptr)2866 static void check_and_free_string(const char *default_str, const char **ptr) {
2867 if (*ptr == default_str) {
2868 // Default should be a literal. Do not free.
2869 return;
2870 }
2871 aom_free((void *)*ptr);
2872 *ptr = NULL;
2873 }
2874
destroy_extra_config(struct av1_extracfg * extra_cfg)2875 static void destroy_extra_config(struct av1_extracfg *extra_cfg) {
2876 #if CONFIG_TUNE_VMAF
2877 check_and_free_string(default_extra_cfg.vmaf_model_path,
2878 &extra_cfg->vmaf_model_path);
2879 #endif
2880 check_and_free_string(default_extra_cfg.two_pass_output,
2881 &extra_cfg->two_pass_output);
2882 check_and_free_string(default_extra_cfg.two_pass_output,
2883 &extra_cfg->second_pass_log);
2884 check_and_free_string(default_extra_cfg.partition_info_path,
2885 &extra_cfg->partition_info_path);
2886 check_and_free_string(default_extra_cfg.rate_distribution_info,
2887 &extra_cfg->rate_distribution_info);
2888 check_and_free_string(default_extra_cfg.film_grain_table_filename,
2889 &extra_cfg->film_grain_table_filename);
2890 }
2891
encoder_destroy(aom_codec_alg_priv_t * ctx)2892 static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) {
2893 free(ctx->cx_data);
2894 destroy_extra_config(&ctx->extra_cfg);
2895
2896 if (ctx->ppi) {
2897 AV1_PRIMARY *ppi = ctx->ppi;
2898 for (int i = 0; i < MAX_PARALLEL_FRAMES - 1; i++) {
2899 if (ppi->parallel_frames_data[i].cx_data) {
2900 free(ppi->parallel_frames_data[i].cx_data);
2901 }
2902 }
2903 #if CONFIG_ENTROPY_STATS
2904 print_entropy_stats(ppi);
2905 #endif
2906 #if CONFIG_INTERNAL_STATS
2907 print_internal_stats(ppi);
2908 #endif
2909
2910 for (int i = 0; i < MAX_PARALLEL_FRAMES; i++) {
2911 av1_destroy_context_and_bufferpool(ppi->parallel_cpi[i],
2912 &ctx->buffer_pool);
2913 }
2914 ppi->cpi = NULL;
2915
2916 if (ppi->cpi_lap) {
2917 av1_destroy_context_and_bufferpool(ppi->cpi_lap, &ctx->buffer_pool_lap);
2918 }
2919 av1_remove_primary_compressor(ppi);
2920 }
2921 destroy_stats_buffer(&ctx->stats_buf_context, ctx->frame_stats_buffer);
2922 aom_free(ctx);
2923 return AOM_CODEC_OK;
2924 }
2925
get_frame_pkt_flags(const AV1_COMP * cpi,unsigned int lib_flags)2926 static aom_codec_frame_flags_t get_frame_pkt_flags(const AV1_COMP *cpi,
2927 unsigned int lib_flags) {
2928 aom_codec_frame_flags_t flags = lib_flags << 16;
2929 if (lib_flags & FRAMEFLAGS_KEY) flags |= AOM_FRAME_IS_KEY;
2930 if (lib_flags & FRAMEFLAGS_INTRAONLY) flags |= AOM_FRAME_IS_INTRAONLY;
2931 if (lib_flags & FRAMEFLAGS_SWITCH) flags |= AOM_FRAME_IS_SWITCH;
2932 if (lib_flags & FRAMEFLAGS_ERROR_RESILIENT)
2933 flags |= AOM_FRAME_IS_ERROR_RESILIENT;
2934 if (cpi->droppable) flags |= AOM_FRAME_IS_DROPPABLE;
2935
2936 return flags;
2937 }
2938
get_src_border_in_pixels(AV1_COMP * cpi,BLOCK_SIZE sb_size)2939 static INLINE int get_src_border_in_pixels(AV1_COMP *cpi, BLOCK_SIZE sb_size) {
2940 if (cpi->oxcf.mode != REALTIME || av1_is_resize_needed(&cpi->oxcf))
2941 return cpi->oxcf.border_in_pixels;
2942
2943 const int sb_size_in_pixels_log2 = mi_size_wide_log2[sb_size] + MI_SIZE_LOG2;
2944 const int sb_aligned_width =
2945 ALIGN_POWER_OF_TWO(cpi->oxcf.frm_dim_cfg.width, sb_size_in_pixels_log2);
2946 const int sb_aligned_height =
2947 ALIGN_POWER_OF_TWO(cpi->oxcf.frm_dim_cfg.height, sb_size_in_pixels_log2);
2948 // Align the border pixels to a multiple of 32.
2949 const int border_pixels_width =
2950 ALIGN_POWER_OF_TWO(sb_aligned_width - cpi->oxcf.frm_dim_cfg.width, 5);
2951 const int border_pixels_height =
2952 ALIGN_POWER_OF_TWO(sb_aligned_height - cpi->oxcf.frm_dim_cfg.height, 5);
2953 const int border_in_pixels =
2954 AOMMAX(AOMMAX(border_pixels_width, border_pixels_height), 32);
2955 return border_in_pixels;
2956 }
2957
2958 // TODO(Mufaddal): Check feasibility of abstracting functions related to LAP
2959 // into a separate function.
encoder_encode(aom_codec_alg_priv_t * ctx,const aom_image_t * img,aom_codec_pts_t pts,unsigned long duration,aom_enc_frame_flags_t enc_flags)2960 static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
2961 const aom_image_t *img,
2962 aom_codec_pts_t pts,
2963 unsigned long duration,
2964 aom_enc_frame_flags_t enc_flags) {
2965 const size_t kMinCompressedSize = 8192;
2966 volatile aom_codec_err_t res = AOM_CODEC_OK;
2967 AV1_PRIMARY *const ppi = ctx->ppi;
2968 volatile aom_codec_pts_t ptsvol = pts;
2969 AV1_COMP_DATA cpi_data = { 0 };
2970
2971 cpi_data.timestamp_ratio = &ctx->timestamp_ratio;
2972 cpi_data.flush = !img;
2973 // LAP context
2974 AV1_COMP *cpi_lap = ppi->cpi_lap;
2975 if (ppi->cpi == NULL) return AOM_CODEC_INVALID_PARAM;
2976
2977 ppi->cpi->last_coded_width = ppi->cpi->oxcf.frm_dim_cfg.width;
2978 ppi->cpi->last_coded_height = ppi->cpi->oxcf.frm_dim_cfg.height;
2979
2980 if (ppi->lap_enabled && cpi_lap == NULL &&
2981 ppi->cpi->oxcf.pass == AOM_RC_ONE_PASS)
2982 return AOM_CODEC_INVALID_PARAM;
2983
2984 if (img != NULL) {
2985 res = validate_img(ctx, img);
2986 if (res == AOM_CODEC_OK) {
2987 const size_t uncompressed_frame_sz =
2988 ALIGN_POWER_OF_TWO_UNSIGNED(ctx->cfg.g_w, 5) *
2989 ALIGN_POWER_OF_TWO_UNSIGNED(ctx->cfg.g_h, 5) * get_image_bps(img) / 8;
2990
2991 // Due to the presence of no-show frames, the ctx->cx_data buffer holds
2992 // compressed data corresponding to multiple frames. As no-show frames are
2993 // not possible for all intra frame encoding with no forward key frames,
2994 // the buffer is allocated with a smaller size in this case.
2995 //
2996 // For pseudo random input, the compressed frame size is seen to exceed
2997 // the uncompressed frame size, but is less than 2 times the uncompressed
2998 // frame size. Hence the size of the buffer is chosen as 2 times the
2999 // uncompressed frame size.
3000 int multiplier = 8;
3001 if (ppi->cpi->oxcf.kf_cfg.key_freq_max == 0 &&
3002 !ppi->cpi->oxcf.kf_cfg.fwd_kf_enabled)
3003 multiplier = 2;
3004 size_t data_sz = uncompressed_frame_sz * multiplier;
3005 if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize;
3006 if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) {
3007 ctx->cx_data_sz = data_sz;
3008 free(ctx->cx_data);
3009 ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz);
3010 if (ctx->cx_data == NULL) {
3011 ctx->cx_data_sz = 0;
3012 return AOM_CODEC_MEM_ERROR;
3013 }
3014 }
3015 for (int i = 0; i < ppi->num_fp_contexts - 1; i++) {
3016 if (ppi->parallel_frames_data[i].cx_data == NULL) {
3017 ppi->parallel_frames_data[i].cx_data_sz = uncompressed_frame_sz;
3018 ppi->parallel_frames_data[i].frame_display_order_hint = -1;
3019 ppi->parallel_frames_data[i].frame_size = 0;
3020 ppi->parallel_frames_data[i].cx_data =
3021 (unsigned char *)malloc(ppi->parallel_frames_data[i].cx_data_sz);
3022 if (ppi->parallel_frames_data[i].cx_data == NULL) {
3023 ppi->parallel_frames_data[i].cx_data_sz = 0;
3024 return AOM_CODEC_MEM_ERROR;
3025 }
3026 }
3027 }
3028 }
3029 }
3030
3031 aom_codec_pkt_list_init(&ctx->pkt_list);
3032
3033 volatile aom_enc_frame_flags_t flags = enc_flags;
3034
3035 // The jmp_buf is valid only for the duration of the function that calls
3036 // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
3037 // before it returns.
3038 if (setjmp(ppi->error.jmp)) {
3039 ppi->error.setjmp = 0;
3040 res = update_error_state(ctx, &ppi->error);
3041 return res;
3042 }
3043 ppi->error.setjmp = 1;
3044
3045 if (ppi->use_svc && ppi->cpi->svc.use_flexible_mode == 0 && flags == 0)
3046 av1_set_svc_fixed_mode(ppi->cpi);
3047
3048 // Note(yunqing): While applying encoding flags, always start from enabling
3049 // all, and then modifying according to the flags. Previous frame's flags are
3050 // overwritten.
3051 av1_apply_encoding_flags(ppi->cpi, flags);
3052 if (cpi_lap != NULL) {
3053 av1_apply_encoding_flags(cpi_lap, flags);
3054 }
3055
3056 #if CONFIG_TUNE_VMAF
3057 if (ctx->extra_cfg.tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
3058 ctx->extra_cfg.tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
3059 aom_init_vmaf_model(&ppi->cpi->vmaf_info.vmaf_model,
3060 ppi->cpi->oxcf.tune_cfg.vmaf_model_path);
3061 }
3062 #endif
3063
3064 // Handle fixed keyframe intervals
3065 if (is_stat_generation_stage(ppi->cpi) || is_one_pass_rt_params(ppi->cpi)) {
3066 if (ctx->cfg.kf_mode == AOM_KF_AUTO &&
3067 ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
3068 if (ppi->cpi->common.spatial_layer_id == 0 &&
3069 ++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
3070 flags |= AOM_EFLAG_FORCE_KF;
3071 ctx->fixed_kf_cntr = 1;
3072 }
3073 }
3074 }
3075
3076 if (res == AOM_CODEC_OK) {
3077 AV1_COMP *cpi = ppi->cpi;
3078
3079 // Set up internal flags
3080 if (ctx->base.init_flags & AOM_CODEC_USE_PSNR) ppi->b_calculate_psnr = 1;
3081
3082 if (img != NULL) {
3083 if (!ctx->pts_offset_initialized) {
3084 ctx->pts_offset = ptsvol;
3085 ctx->pts_offset_initialized = 1;
3086 }
3087 if (ptsvol < ctx->pts_offset) {
3088 aom_internal_error(&ppi->error, AOM_CODEC_INVALID_PARAM,
3089 "pts is smaller than initial pts");
3090 }
3091 ptsvol -= ctx->pts_offset;
3092 if (ptsvol > INT64_MAX / cpi_data.timestamp_ratio->num) {
3093 aom_internal_error(
3094 &ppi->error, AOM_CODEC_INVALID_PARAM,
3095 "conversion of relative pts to ticks would overflow");
3096 }
3097 int64_t src_time_stamp =
3098 timebase_units_to_ticks(cpi_data.timestamp_ratio, ptsvol);
3099 #if ULONG_MAX > INT64_MAX
3100 if (duration > INT64_MAX) {
3101 aom_internal_error(&ppi->error, AOM_CODEC_INVALID_PARAM,
3102 "duration is too big");
3103 }
3104 #endif
3105 if (ptsvol > INT64_MAX - (int64_t)duration) {
3106 aom_internal_error(&ppi->error, AOM_CODEC_INVALID_PARAM,
3107 "relative pts + duration is too big");
3108 }
3109 aom_codec_pts_t pts_end = ptsvol + (int64_t)duration;
3110 if (pts_end > INT64_MAX / cpi_data.timestamp_ratio->num) {
3111 aom_internal_error(
3112 &ppi->error, AOM_CODEC_INVALID_PARAM,
3113 "conversion of relative pts + duration to ticks would overflow");
3114 }
3115 int64_t src_end_time_stamp =
3116 timebase_units_to_ticks(cpi_data.timestamp_ratio, pts_end);
3117
3118 YV12_BUFFER_CONFIG sd;
3119 res = image2yuvconfig(img, &sd);
3120 // When generating a monochrome stream, make |sd| a monochrome image.
3121 if (ctx->cfg.monochrome) {
3122 sd.u_buffer = sd.v_buffer = NULL;
3123 sd.uv_stride = 0;
3124 sd.monochrome = 1;
3125 }
3126 int use_highbitdepth = (sd.flags & YV12_FLAG_HIGHBITDEPTH) != 0;
3127 int subsampling_x = sd.subsampling_x;
3128 int subsampling_y = sd.subsampling_y;
3129
3130 if (!ppi->lookahead) {
3131 int lag_in_frames = cpi_lap != NULL ? cpi_lap->oxcf.gf_cfg.lag_in_frames
3132 : cpi->oxcf.gf_cfg.lag_in_frames;
3133 AV1EncoderConfig *oxcf = &cpi->oxcf;
3134 const BLOCK_SIZE sb_size = av1_select_sb_size(
3135 oxcf, oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height,
3136 ppi->number_spatial_layers);
3137 oxcf->border_in_pixels =
3138 av1_get_enc_border_size(av1_is_resize_needed(oxcf),
3139 oxcf->kf_cfg.key_freq_max == 0, sb_size);
3140 for (int i = 0; i < ppi->num_fp_contexts; i++) {
3141 ppi->parallel_cpi[i]->oxcf.border_in_pixels = oxcf->border_in_pixels;
3142 }
3143
3144 const int src_border_in_pixels = get_src_border_in_pixels(cpi, sb_size);
3145 ppi->lookahead = av1_lookahead_init(
3146 cpi->oxcf.frm_dim_cfg.width, cpi->oxcf.frm_dim_cfg.height,
3147 subsampling_x, subsampling_y, use_highbitdepth, lag_in_frames,
3148 src_border_in_pixels, cpi->common.features.byte_alignment,
3149 ctx->num_lap_buffers, (cpi->oxcf.kf_cfg.key_freq_max == 0),
3150 cpi->alloc_pyramid);
3151 }
3152 if (!ppi->lookahead)
3153 aom_internal_error(&ppi->error, AOM_CODEC_MEM_ERROR,
3154 "Failed to allocate lag buffers");
3155 for (int i = 0; i < ppi->num_fp_contexts; i++) {
3156 aom_codec_err_t err =
3157 av1_check_initial_width(ppi->parallel_cpi[i], use_highbitdepth,
3158 subsampling_x, subsampling_y);
3159 if (err != AOM_CODEC_OK) {
3160 aom_internal_error(&ppi->error, err,
3161 "av1_check_initial_width() failed");
3162 }
3163 }
3164 if (cpi_lap != NULL) {
3165 aom_codec_err_t err = av1_check_initial_width(
3166 cpi_lap, use_highbitdepth, subsampling_x, subsampling_y);
3167 if (err != AOM_CODEC_OK) {
3168 aom_internal_error(&ppi->error, err,
3169 "av1_check_initial_width() failed");
3170 }
3171 }
3172
3173 // Store the original flags in to the frame buffer. Will extract the
3174 // key frame flag when we actually encode this frame.
3175 if (av1_receive_raw_frame(cpi, flags | ctx->next_frame_flags, &sd,
3176 src_time_stamp, src_end_time_stamp)) {
3177 res = update_error_state(ctx, cpi->common.error);
3178 }
3179 ctx->next_frame_flags = 0;
3180 }
3181
3182 cpi_data.cx_data = ctx->cx_data;
3183 cpi_data.cx_data_sz = ctx->cx_data_sz;
3184
3185 /* Any pending invisible frames? */
3186 if (ctx->pending_cx_data_sz) {
3187 cpi_data.cx_data += ctx->pending_cx_data_sz;
3188 cpi_data.cx_data_sz -= ctx->pending_cx_data_sz;
3189
3190 /* TODO: this is a minimal check, the underlying codec doesn't respect
3191 * the buffer size anyway.
3192 */
3193 if (cpi_data.cx_data_sz < ctx->cx_data_sz / 2) {
3194 aom_internal_error(&ppi->error, AOM_CODEC_ERROR,
3195 "Compressed data buffer too small");
3196 }
3197 }
3198
3199 int is_frame_visible = 0;
3200 int has_no_show_keyframe = 0;
3201 int num_workers = 0;
3202
3203 if (cpi->oxcf.pass == AOM_RC_FIRST_PASS) {
3204 #if !CONFIG_REALTIME_ONLY
3205 num_workers = ppi->p_mt_info.num_mod_workers[MOD_FP] =
3206 av1_fp_compute_num_enc_workers(cpi);
3207 #endif
3208 } else {
3209 av1_compute_num_workers_for_mt(cpi);
3210 num_workers = av1_get_max_num_workers(cpi);
3211 }
3212 if (num_workers > 1 && ppi->p_mt_info.num_workers < num_workers) {
3213 // Obtain the maximum no. of frames that can be supported in a parallel
3214 // encode set.
3215 if (is_stat_consumption_stage(cpi)) {
3216 ppi->num_fp_contexts = av1_compute_num_fp_contexts(ppi, &cpi->oxcf);
3217 }
3218 if (ppi->p_mt_info.num_workers > 0) {
3219 av1_terminate_workers(ppi);
3220 free_thread_data(ppi);
3221 aom_free(ppi->p_mt_info.tile_thr_data);
3222 ppi->p_mt_info.tile_thr_data = NULL;
3223 aom_free(ppi->p_mt_info.workers);
3224 ppi->p_mt_info.workers = NULL;
3225 ppi->p_mt_info.num_workers = 0;
3226 for (int j = 0; j < ppi->num_fp_contexts; j++) {
3227 aom_free(ppi->parallel_cpi[j]->td.tctx);
3228 ppi->parallel_cpi[j]->td.tctx = NULL;
3229 }
3230 }
3231 av1_create_workers(ppi, num_workers);
3232 av1_init_tile_thread_data(ppi, cpi->oxcf.pass == AOM_RC_FIRST_PASS);
3233 }
3234
3235 // Re-allocate thread data if workers for encoder multi-threading stage
3236 // exceeds prev_num_enc_workers.
3237 const int num_enc_workers =
3238 av1_get_num_mod_workers_for_alloc(&ppi->p_mt_info, MOD_ENC);
3239 if (ppi->p_mt_info.prev_num_enc_workers < num_enc_workers &&
3240 num_enc_workers <= ppi->p_mt_info.num_workers) {
3241 free_thread_data(ppi);
3242 for (int j = 0; j < ppi->num_fp_contexts; j++) {
3243 aom_free(ppi->parallel_cpi[j]->td.tctx);
3244 ppi->parallel_cpi[j]->td.tctx = NULL;
3245 }
3246 av1_init_tile_thread_data(ppi, cpi->oxcf.pass == AOM_RC_FIRST_PASS);
3247 }
3248
3249 for (int i = 0; i < ppi->num_fp_contexts; i++) {
3250 av1_init_frame_mt(ppi, ppi->parallel_cpi[i]);
3251 }
3252 if (cpi_lap != NULL) {
3253 av1_init_frame_mt(ppi, cpi_lap);
3254 }
3255 #if CONFIG_MULTITHREAD
3256 if (ppi->p_mt_info.num_workers > 1) {
3257 for (int i = 0; i < ppi->num_fp_contexts; i++) {
3258 av1_init_mt_sync(ppi->parallel_cpi[i],
3259 ppi->parallel_cpi[i]->oxcf.pass == AOM_RC_FIRST_PASS);
3260 }
3261 if (cpi_lap != NULL) {
3262 av1_init_mt_sync(cpi_lap, 1);
3263 }
3264 }
3265 #endif // CONFIG_MULTITHREAD
3266
3267 // Call for LAP stage
3268 if (cpi_lap != NULL) {
3269 AV1_COMP_DATA cpi_lap_data = { 0 };
3270 cpi_lap_data.flush = !img;
3271 cpi_lap_data.timestamp_ratio = &ctx->timestamp_ratio;
3272 const int status = av1_get_compressed_data(cpi_lap, &cpi_lap_data);
3273 if (status > AOM_CODEC_OK) {
3274 aom_internal_error_copy(&ppi->error, cpi_lap->common.error);
3275 }
3276 av1_post_encode_updates(cpi_lap, &cpi_lap_data);
3277 }
3278
3279 // Recalculate the maximum number of frames that can be encoded in
3280 // parallel at the beginning of sub gop.
3281 if (is_stat_consumption_stage(cpi) && ppi->gf_group.size > 0 &&
3282 cpi->gf_frame_index == ppi->gf_group.size) {
3283 ppi->num_fp_contexts = av1_compute_num_fp_contexts(ppi, &cpi->oxcf);
3284 }
3285
3286 // Get the next visible frame. Invisible frames get packed with the next
3287 // visible frame.
3288 while (cpi_data.cx_data_sz >= ctx->cx_data_sz / 2 && !is_frame_visible) {
3289 int simulate_parallel_frame = 0;
3290 int status = -1;
3291 cpi->do_frame_data_update = true;
3292 cpi->ref_idx_to_skip = INVALID_IDX;
3293 cpi->ref_refresh_index = INVALID_IDX;
3294 cpi->refresh_idx_available = false;
3295
3296 #if CONFIG_FPMT_TEST
3297 simulate_parallel_frame =
3298 cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE ? 1 : 0;
3299 if (simulate_parallel_frame) {
3300 if (ppi->num_fp_contexts > 1 && ppi->gf_group.size > 1) {
3301 if (cpi->gf_frame_index < ppi->gf_group.size) {
3302 calc_frame_data_update_flag(&ppi->gf_group, cpi->gf_frame_index,
3303 &cpi->do_frame_data_update);
3304 }
3305 }
3306 status = av1_get_compressed_data(cpi, &cpi_data);
3307 }
3308
3309 #endif // CONFIG_FPMT_TEST
3310 if (!simulate_parallel_frame) {
3311 if (ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
3312 status = av1_get_compressed_data(cpi, &cpi_data);
3313 } else if (ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
3314 1) {
3315 // In case of an error, longjmp() would be invoked and hence "status"
3316 // is set to AOM_CODEC_OK here.
3317 av1_compress_parallel_frames(ppi, &cpi_data);
3318 status = AOM_CODEC_OK;
3319 } else {
3320 // No possibility of failures from this function and hence "status" is
3321 // set to AOM_CODEC_OK here.
3322 cpi = av1_get_parallel_frame_enc_data(ppi, &cpi_data);
3323 status = AOM_CODEC_OK;
3324 }
3325 }
3326 if (status == -1) break;
3327 if (status != AOM_CODEC_OK) {
3328 aom_internal_error_copy(&ppi->error, cpi->common.error);
3329 }
3330 if (ppi->num_fp_contexts > 0 && frame_is_intra_only(&cpi->common)) {
3331 av1_init_sc_decisions(ppi);
3332 }
3333
3334 ppi->seq_params_locked = 1;
3335 av1_post_encode_updates(cpi, &cpi_data);
3336
3337 #if CONFIG_ENTROPY_STATS
3338 if (ppi->cpi->oxcf.pass != 1 && !cpi->common.show_existing_frame)
3339 av1_accumulate_frame_counts(&ppi->aggregate_fc, &cpi->counts);
3340 #endif
3341 #if CONFIG_INTERNAL_STATS
3342 if (ppi->cpi->oxcf.pass != 1) {
3343 ppi->total_time_compress_data += cpi->time_compress_data;
3344 ppi->total_recode_hits += cpi->frame_recode_hits;
3345 ppi->total_bytes += cpi->bytes;
3346 for (int i = 0; i < MAX_MODES; i++) {
3347 ppi->total_mode_chosen_counts[i] += cpi->mode_chosen_counts[i];
3348 }
3349 }
3350 #endif // CONFIG_INTERNAL_STATS
3351
3352 if (!cpi_data.frame_size) continue;
3353 assert(cpi_data.cx_data != NULL && cpi_data.cx_data_sz != 0);
3354 const int write_temporal_delimiter =
3355 !cpi->common.spatial_layer_id && !ctx->pending_cx_data_sz;
3356
3357 if (write_temporal_delimiter) {
3358 uint32_t obu_header_size = 1;
3359 const uint32_t obu_payload_size = 0;
3360 const size_t length_field_size =
3361 aom_uleb_size_in_bytes(obu_payload_size);
3362
3363 const size_t move_offset = obu_header_size + length_field_size;
3364 memmove(ctx->cx_data + move_offset, ctx->cx_data, cpi_data.frame_size);
3365 obu_header_size =
3366 av1_write_obu_header(&ppi->level_params, &cpi->frame_header_count,
3367 OBU_TEMPORAL_DELIMITER, 0, ctx->cx_data);
3368
3369 // OBUs are preceded/succeeded by an unsigned leb128 coded integer.
3370 if (av1_write_uleb_obu_size(obu_header_size, obu_payload_size,
3371 ctx->cx_data) != AOM_CODEC_OK) {
3372 aom_internal_error(&ppi->error, AOM_CODEC_ERROR, NULL);
3373 }
3374
3375 cpi_data.frame_size +=
3376 obu_header_size + obu_payload_size + length_field_size;
3377 }
3378
3379 if (ctx->oxcf.save_as_annexb) {
3380 size_t curr_frame_size = cpi_data.frame_size;
3381 if (av1_convert_sect5obus_to_annexb(cpi_data.cx_data,
3382 &curr_frame_size) != AOM_CODEC_OK) {
3383 aom_internal_error(&ppi->error, AOM_CODEC_ERROR, NULL);
3384 }
3385 cpi_data.frame_size = curr_frame_size;
3386
3387 // B_PRIME (add frame size)
3388 const size_t length_field_size =
3389 aom_uleb_size_in_bytes(cpi_data.frame_size);
3390 memmove(cpi_data.cx_data + length_field_size, cpi_data.cx_data,
3391 cpi_data.frame_size);
3392 if (av1_write_uleb_obu_size(0, (uint32_t)cpi_data.frame_size,
3393 cpi_data.cx_data) != AOM_CODEC_OK) {
3394 aom_internal_error(&ppi->error, AOM_CODEC_ERROR, NULL);
3395 }
3396 cpi_data.frame_size += length_field_size;
3397 }
3398
3399 ctx->pending_cx_data_sz += cpi_data.frame_size;
3400
3401 cpi_data.cx_data += cpi_data.frame_size;
3402 cpi_data.cx_data_sz -= cpi_data.frame_size;
3403
3404 is_frame_visible = cpi->common.show_frame;
3405
3406 has_no_show_keyframe |=
3407 (!is_frame_visible &&
3408 cpi->common.current_frame.frame_type == KEY_FRAME);
3409 }
3410 if (is_frame_visible) {
3411 // Add the frame packet to the list of returned packets.
3412 aom_codec_cx_pkt_t pkt;
3413
3414 // decrement frames_left counter
3415 ppi->frames_left = AOMMAX(0, ppi->frames_left - 1);
3416 if (ctx->oxcf.save_as_annexb) {
3417 // B_PRIME (add TU size)
3418 size_t tu_size = ctx->pending_cx_data_sz;
3419 const size_t length_field_size = aom_uleb_size_in_bytes(tu_size);
3420 memmove(ctx->cx_data + length_field_size, ctx->cx_data, tu_size);
3421 if (av1_write_uleb_obu_size(0, (uint32_t)tu_size, ctx->cx_data) !=
3422 AOM_CODEC_OK) {
3423 aom_internal_error(&ppi->error, AOM_CODEC_ERROR, NULL);
3424 }
3425 ctx->pending_cx_data_sz += length_field_size;
3426 }
3427
3428 pkt.kind = AOM_CODEC_CX_FRAME_PKT;
3429
3430 pkt.data.frame.buf = ctx->cx_data;
3431 pkt.data.frame.sz = ctx->pending_cx_data_sz;
3432 pkt.data.frame.partition_id = -1;
3433 pkt.data.frame.vis_frame_size = cpi_data.frame_size;
3434
3435 pkt.data.frame.pts = ticks_to_timebase_units(cpi_data.timestamp_ratio,
3436 cpi_data.ts_frame_start) +
3437 ctx->pts_offset;
3438 pkt.data.frame.flags = get_frame_pkt_flags(cpi, cpi_data.lib_flags);
3439 if (has_no_show_keyframe) {
3440 // If one of the invisible frames in the packet is a keyframe, set
3441 // the delayed random access point flag.
3442 pkt.data.frame.flags |= AOM_FRAME_IS_DELAYED_RANDOM_ACCESS_POINT;
3443 }
3444 pkt.data.frame.duration = (uint32_t)ticks_to_timebase_units(
3445 cpi_data.timestamp_ratio,
3446 cpi_data.ts_frame_end - cpi_data.ts_frame_start);
3447
3448 aom_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
3449
3450 ctx->pending_cx_data_sz = 0;
3451 }
3452 }
3453
3454 ppi->error.setjmp = 0;
3455 return res;
3456 }
3457
encoder_get_cxdata(aom_codec_alg_priv_t * ctx,aom_codec_iter_t * iter)3458 static const aom_codec_cx_pkt_t *encoder_get_cxdata(aom_codec_alg_priv_t *ctx,
3459 aom_codec_iter_t *iter) {
3460 return aom_codec_pkt_list_get(&ctx->pkt_list.head, iter);
3461 }
3462
ctrl_set_reference(aom_codec_alg_priv_t * ctx,va_list args)3463 static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
3464 va_list args) {
3465 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
3466
3467 if (frame != NULL) {
3468 YV12_BUFFER_CONFIG sd;
3469
3470 image2yuvconfig(&frame->img, &sd);
3471 av1_set_reference_enc(ctx->ppi->cpi, frame->idx, &sd);
3472 return AOM_CODEC_OK;
3473 } else {
3474 return AOM_CODEC_INVALID_PARAM;
3475 }
3476 }
3477
ctrl_copy_reference(aom_codec_alg_priv_t * ctx,va_list args)3478 static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
3479 va_list args) {
3480 if (ctx->ppi->cpi->oxcf.algo_cfg.skip_postproc_filtering)
3481 return AOM_CODEC_INCAPABLE;
3482 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
3483
3484 if (frame != NULL) {
3485 YV12_BUFFER_CONFIG sd;
3486
3487 image2yuvconfig(&frame->img, &sd);
3488 av1_copy_reference_enc(ctx->ppi->cpi, frame->idx, &sd);
3489 return AOM_CODEC_OK;
3490 } else {
3491 return AOM_CODEC_INVALID_PARAM;
3492 }
3493 }
3494
ctrl_get_reference(aom_codec_alg_priv_t * ctx,va_list args)3495 static aom_codec_err_t ctrl_get_reference(aom_codec_alg_priv_t *ctx,
3496 va_list args) {
3497 if (ctx->ppi->cpi->oxcf.algo_cfg.skip_postproc_filtering)
3498 return AOM_CODEC_INCAPABLE;
3499 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
3500
3501 if (frame != NULL) {
3502 YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->ppi->cpi->common, frame->idx);
3503 if (fb == NULL) return AOM_CODEC_ERROR;
3504
3505 yuvconfig2image(&frame->img, fb, NULL);
3506 return AOM_CODEC_OK;
3507 } else {
3508 return AOM_CODEC_INVALID_PARAM;
3509 }
3510 }
3511
ctrl_get_new_frame_image(aom_codec_alg_priv_t * ctx,va_list args)3512 static aom_codec_err_t ctrl_get_new_frame_image(aom_codec_alg_priv_t *ctx,
3513 va_list args) {
3514 aom_image_t *const new_img = va_arg(args, aom_image_t *);
3515
3516 if (new_img != NULL) {
3517 YV12_BUFFER_CONFIG new_frame;
3518
3519 if (av1_get_last_show_frame(ctx->ppi->cpi, &new_frame) == 0) {
3520 yuvconfig2image(new_img, &new_frame, NULL);
3521 return AOM_CODEC_OK;
3522 } else {
3523 return AOM_CODEC_ERROR;
3524 }
3525 } else {
3526 return AOM_CODEC_INVALID_PARAM;
3527 }
3528 }
3529
ctrl_copy_new_frame_image(aom_codec_alg_priv_t * ctx,va_list args)3530 static aom_codec_err_t ctrl_copy_new_frame_image(aom_codec_alg_priv_t *ctx,
3531 va_list args) {
3532 aom_image_t *const new_img = va_arg(args, aom_image_t *);
3533
3534 if (new_img != NULL) {
3535 YV12_BUFFER_CONFIG new_frame;
3536
3537 if (av1_get_last_show_frame(ctx->ppi->cpi, &new_frame) == 0) {
3538 YV12_BUFFER_CONFIG sd;
3539 image2yuvconfig(new_img, &sd);
3540 return av1_copy_new_frame_enc(&ctx->ppi->cpi->common, &new_frame, &sd);
3541 } else {
3542 return AOM_CODEC_ERROR;
3543 }
3544 } else {
3545 return AOM_CODEC_INVALID_PARAM;
3546 }
3547 }
3548
encoder_get_preview(aom_codec_alg_priv_t * ctx)3549 static aom_image_t *encoder_get_preview(aom_codec_alg_priv_t *ctx) {
3550 YV12_BUFFER_CONFIG sd;
3551
3552 if (av1_get_preview_raw_frame(ctx->ppi->cpi, &sd) == 0) {
3553 yuvconfig2image(&ctx->preview_img, &sd, NULL);
3554 return &ctx->preview_img;
3555 } else {
3556 return NULL;
3557 }
3558 }
3559
ctrl_use_reference(aom_codec_alg_priv_t * ctx,va_list args)3560 static aom_codec_err_t ctrl_use_reference(aom_codec_alg_priv_t *ctx,
3561 va_list args) {
3562 const int reference_flag = va_arg(args, int);
3563
3564 av1_use_as_reference(&ctx->ppi->cpi->ext_flags.ref_frame_flags,
3565 reference_flag);
3566 return AOM_CODEC_OK;
3567 }
3568
ctrl_set_roi_map(aom_codec_alg_priv_t * ctx,va_list args)3569 static aom_codec_err_t ctrl_set_roi_map(aom_codec_alg_priv_t *ctx,
3570 va_list args) {
3571 (void)ctx;
3572 (void)args;
3573
3574 // TODO(yaowu): Need to re-implement and test for AV1.
3575 return AOM_CODEC_INVALID_PARAM;
3576 }
3577
ctrl_set_active_map(aom_codec_alg_priv_t * ctx,va_list args)3578 static aom_codec_err_t ctrl_set_active_map(aom_codec_alg_priv_t *ctx,
3579 va_list args) {
3580 aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
3581
3582 if (map) {
3583 if (!av1_set_active_map(ctx->ppi->cpi, map->active_map, (int)map->rows,
3584 (int)map->cols))
3585 return AOM_CODEC_OK;
3586 else
3587 return AOM_CODEC_INVALID_PARAM;
3588 } else {
3589 return AOM_CODEC_INVALID_PARAM;
3590 }
3591 }
3592
ctrl_get_active_map(aom_codec_alg_priv_t * ctx,va_list args)3593 static aom_codec_err_t ctrl_get_active_map(aom_codec_alg_priv_t *ctx,
3594 va_list args) {
3595 aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
3596
3597 if (map) {
3598 if (!av1_get_active_map(ctx->ppi->cpi, map->active_map, (int)map->rows,
3599 (int)map->cols))
3600 return AOM_CODEC_OK;
3601 else
3602 return AOM_CODEC_INVALID_PARAM;
3603 } else {
3604 return AOM_CODEC_INVALID_PARAM;
3605 }
3606 }
3607
ctrl_set_scale_mode(aom_codec_alg_priv_t * ctx,va_list args)3608 static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
3609 va_list args) {
3610 aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
3611
3612 if (mode) {
3613 const int res = av1_set_internal_size(
3614 &ctx->ppi->cpi->oxcf, &ctx->ppi->cpi->resize_pending_params,
3615 mode->h_scaling_mode, mode->v_scaling_mode);
3616 av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
3617 return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
3618 } else {
3619 return AOM_CODEC_INVALID_PARAM;
3620 }
3621 }
3622
ctrl_set_spatial_layer_id(aom_codec_alg_priv_t * ctx,va_list args)3623 static aom_codec_err_t ctrl_set_spatial_layer_id(aom_codec_alg_priv_t *ctx,
3624 va_list args) {
3625 const int spatial_layer_id = va_arg(args, int);
3626 if (spatial_layer_id >= MAX_NUM_SPATIAL_LAYERS)
3627 return AOM_CODEC_INVALID_PARAM;
3628 ctx->ppi->cpi->common.spatial_layer_id = spatial_layer_id;
3629 return AOM_CODEC_OK;
3630 }
3631
ctrl_set_number_spatial_layers(aom_codec_alg_priv_t * ctx,va_list args)3632 static aom_codec_err_t ctrl_set_number_spatial_layers(aom_codec_alg_priv_t *ctx,
3633 va_list args) {
3634 const int number_spatial_layers = va_arg(args, int);
3635 if (number_spatial_layers > MAX_NUM_SPATIAL_LAYERS)
3636 return AOM_CODEC_INVALID_PARAM;
3637 ctx->ppi->number_spatial_layers = number_spatial_layers;
3638 return AOM_CODEC_OK;
3639 }
3640
ctrl_set_layer_id(aom_codec_alg_priv_t * ctx,va_list args)3641 static aom_codec_err_t ctrl_set_layer_id(aom_codec_alg_priv_t *ctx,
3642 va_list args) {
3643 aom_svc_layer_id_t *const data = va_arg(args, aom_svc_layer_id_t *);
3644 ctx->ppi->cpi->common.spatial_layer_id = data->spatial_layer_id;
3645 ctx->ppi->cpi->common.temporal_layer_id = data->temporal_layer_id;
3646 ctx->ppi->cpi->svc.spatial_layer_id = data->spatial_layer_id;
3647 ctx->ppi->cpi->svc.temporal_layer_id = data->temporal_layer_id;
3648 return AOM_CODEC_OK;
3649 }
3650
ctrl_set_svc_params(aom_codec_alg_priv_t * ctx,va_list args)3651 static aom_codec_err_t ctrl_set_svc_params(aom_codec_alg_priv_t *ctx,
3652 va_list args) {
3653 AV1_PRIMARY *const ppi = ctx->ppi;
3654 AV1_COMP *const cpi = ppi->cpi;
3655 AV1_COMMON *const cm = &cpi->common;
3656 AV1EncoderConfig *oxcf = &cpi->oxcf;
3657 aom_svc_params_t *const params = va_arg(args, aom_svc_params_t *);
3658 int64_t target_bandwidth = 0;
3659 ppi->number_spatial_layers = params->number_spatial_layers;
3660 ppi->number_temporal_layers = params->number_temporal_layers;
3661 cpi->svc.number_spatial_layers = params->number_spatial_layers;
3662 cpi->svc.number_temporal_layers = params->number_temporal_layers;
3663 if (ppi->number_spatial_layers > 1 || ppi->number_temporal_layers > 1) {
3664 unsigned int sl, tl;
3665 ctx->ppi->use_svc = 1;
3666 const int num_layers =
3667 ppi->number_spatial_layers * ppi->number_temporal_layers;
3668 for (int layer = 0; layer < num_layers; ++layer) {
3669 if (params->max_quantizers[layer] > 63 ||
3670 params->min_quantizers[layer] < 0 ||
3671 params->min_quantizers[layer] > params->max_quantizers[layer]) {
3672 return AOM_CODEC_INVALID_PARAM;
3673 }
3674 }
3675 if (!av1_alloc_layer_context(cpi, num_layers)) return AOM_CODEC_MEM_ERROR;
3676
3677 for (sl = 0; sl < ppi->number_spatial_layers; ++sl) {
3678 for (tl = 0; tl < ppi->number_temporal_layers; ++tl) {
3679 const int layer = LAYER_IDS_TO_IDX(sl, tl, ppi->number_temporal_layers);
3680 LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
3681 lc->max_q = params->max_quantizers[layer];
3682 lc->min_q = params->min_quantizers[layer];
3683 lc->scaling_factor_num = AOMMAX(1, params->scaling_factor_num[sl]);
3684 lc->scaling_factor_den = AOMMAX(1, params->scaling_factor_den[sl]);
3685 const int layer_target_bitrate = params->layer_target_bitrate[layer];
3686 if (layer_target_bitrate > INT_MAX / 1000) {
3687 lc->layer_target_bitrate = INT_MAX;
3688 } else {
3689 lc->layer_target_bitrate = 1000 * layer_target_bitrate;
3690 }
3691 lc->framerate_factor = params->framerate_factor[tl];
3692 if (tl == ppi->number_temporal_layers - 1)
3693 target_bandwidth += lc->layer_target_bitrate;
3694 }
3695 }
3696 if (cm->current_frame.frame_number == 0) {
3697 if (!cpi->ppi->seq_params_locked) {
3698 SequenceHeader *const seq_params = &ppi->seq_params;
3699 seq_params->operating_points_cnt_minus_1 =
3700 ppi->number_spatial_layers * ppi->number_temporal_layers - 1;
3701 av1_init_seq_coding_tools(ppi, &cpi->oxcf, 1);
3702 }
3703 av1_init_layer_context(cpi);
3704 }
3705 oxcf->rc_cfg.target_bandwidth = target_bandwidth;
3706 set_primary_rc_buffer_sizes(oxcf, cpi->ppi);
3707 av1_update_layer_context_change_config(cpi, target_bandwidth);
3708 check_reset_rc_flag(cpi);
3709 }
3710 av1_check_fpmt_config(ctx->ppi, &ctx->ppi->cpi->oxcf);
3711 return AOM_CODEC_OK;
3712 }
3713
ctrl_set_svc_ref_frame_config(aom_codec_alg_priv_t * ctx,va_list args)3714 static aom_codec_err_t ctrl_set_svc_ref_frame_config(aom_codec_alg_priv_t *ctx,
3715 va_list args) {
3716 AV1_COMP *const cpi = ctx->ppi->cpi;
3717 aom_svc_ref_frame_config_t *const data =
3718 va_arg(args, aom_svc_ref_frame_config_t *);
3719 cpi->ppi->rtc_ref.set_ref_frame_config = 1;
3720 for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
3721 cpi->ppi->rtc_ref.reference[i] = data->reference[i];
3722 cpi->ppi->rtc_ref.ref_idx[i] = data->ref_idx[i];
3723 }
3724 for (unsigned int i = 0; i < REF_FRAMES; ++i)
3725 cpi->ppi->rtc_ref.refresh[i] = data->refresh[i];
3726 cpi->svc.use_flexible_mode = 1;
3727 cpi->svc.ksvc_fixed_mode = 0;
3728 return AOM_CODEC_OK;
3729 }
3730
ctrl_set_svc_ref_frame_comp_pred(aom_codec_alg_priv_t * ctx,va_list args)3731 static aom_codec_err_t ctrl_set_svc_ref_frame_comp_pred(
3732 aom_codec_alg_priv_t *ctx, va_list args) {
3733 AV1_COMP *const cpi = ctx->ppi->cpi;
3734 aom_svc_ref_frame_comp_pred_t *const data =
3735 va_arg(args, aom_svc_ref_frame_comp_pred_t *);
3736 cpi->ppi->rtc_ref.ref_frame_comp[0] = data->use_comp_pred[0];
3737 cpi->ppi->rtc_ref.ref_frame_comp[1] = data->use_comp_pred[1];
3738 cpi->ppi->rtc_ref.ref_frame_comp[2] = data->use_comp_pred[2];
3739 return AOM_CODEC_OK;
3740 }
3741
ctrl_set_tune_content(aom_codec_alg_priv_t * ctx,va_list args)3742 static aom_codec_err_t ctrl_set_tune_content(aom_codec_alg_priv_t *ctx,
3743 va_list args) {
3744 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3745 extra_cfg.content = CAST(AV1E_SET_TUNE_CONTENT, args);
3746 return update_extra_cfg(ctx, &extra_cfg);
3747 }
3748
ctrl_set_cdf_update_mode(aom_codec_alg_priv_t * ctx,va_list args)3749 static aom_codec_err_t ctrl_set_cdf_update_mode(aom_codec_alg_priv_t *ctx,
3750 va_list args) {
3751 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3752 extra_cfg.cdf_update_mode = CAST(AV1E_SET_CDF_UPDATE_MODE, args);
3753 return update_extra_cfg(ctx, &extra_cfg);
3754 }
3755
ctrl_set_color_primaries(aom_codec_alg_priv_t * ctx,va_list args)3756 static aom_codec_err_t ctrl_set_color_primaries(aom_codec_alg_priv_t *ctx,
3757 va_list args) {
3758 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3759 extra_cfg.color_primaries = CAST(AV1E_SET_COLOR_PRIMARIES, args);
3760 return update_extra_cfg(ctx, &extra_cfg);
3761 }
3762
ctrl_set_transfer_characteristics(aom_codec_alg_priv_t * ctx,va_list args)3763 static aom_codec_err_t ctrl_set_transfer_characteristics(
3764 aom_codec_alg_priv_t *ctx, va_list args) {
3765 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3766 extra_cfg.transfer_characteristics =
3767 CAST(AV1E_SET_TRANSFER_CHARACTERISTICS, args);
3768 return update_extra_cfg(ctx, &extra_cfg);
3769 }
3770
ctrl_set_matrix_coefficients(aom_codec_alg_priv_t * ctx,va_list args)3771 static aom_codec_err_t ctrl_set_matrix_coefficients(aom_codec_alg_priv_t *ctx,
3772 va_list args) {
3773 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3774 extra_cfg.matrix_coefficients = CAST(AV1E_SET_MATRIX_COEFFICIENTS, args);
3775 return update_extra_cfg(ctx, &extra_cfg);
3776 }
3777
ctrl_set_chroma_sample_position(aom_codec_alg_priv_t * ctx,va_list args)3778 static aom_codec_err_t ctrl_set_chroma_sample_position(
3779 aom_codec_alg_priv_t *ctx, va_list args) {
3780 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3781 extra_cfg.chroma_sample_position =
3782 CAST(AV1E_SET_CHROMA_SAMPLE_POSITION, args);
3783 return update_extra_cfg(ctx, &extra_cfg);
3784 }
3785
ctrl_set_color_range(aom_codec_alg_priv_t * ctx,va_list args)3786 static aom_codec_err_t ctrl_set_color_range(aom_codec_alg_priv_t *ctx,
3787 va_list args) {
3788 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3789 extra_cfg.color_range = CAST(AV1E_SET_COLOR_RANGE, args);
3790 return update_extra_cfg(ctx, &extra_cfg);
3791 }
3792
ctrl_set_render_size(aom_codec_alg_priv_t * ctx,va_list args)3793 static aom_codec_err_t ctrl_set_render_size(aom_codec_alg_priv_t *ctx,
3794 va_list args) {
3795 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3796 int *const render_size = va_arg(args, int *);
3797 extra_cfg.render_width = render_size[0];
3798 extra_cfg.render_height = render_size[1];
3799 return update_extra_cfg(ctx, &extra_cfg);
3800 }
3801
ctrl_set_superblock_size(aom_codec_alg_priv_t * ctx,va_list args)3802 static aom_codec_err_t ctrl_set_superblock_size(aom_codec_alg_priv_t *ctx,
3803 va_list args) {
3804 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3805 extra_cfg.superblock_size = CAST(AV1E_SET_SUPERBLOCK_SIZE, args);
3806 return update_extra_cfg(ctx, &extra_cfg);
3807 }
3808
ctrl_set_chroma_subsampling_x(aom_codec_alg_priv_t * ctx,va_list args)3809 static aom_codec_err_t ctrl_set_chroma_subsampling_x(aom_codec_alg_priv_t *ctx,
3810 va_list args) {
3811 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3812 extra_cfg.chroma_subsampling_x = CAST(AV1E_SET_CHROMA_SUBSAMPLING_X, args);
3813 return update_extra_cfg(ctx, &extra_cfg);
3814 }
3815
ctrl_set_chroma_subsampling_y(aom_codec_alg_priv_t * ctx,va_list args)3816 static aom_codec_err_t ctrl_set_chroma_subsampling_y(aom_codec_alg_priv_t *ctx,
3817 va_list args) {
3818 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3819 extra_cfg.chroma_subsampling_y = CAST(AV1E_SET_CHROMA_SUBSAMPLING_Y, args);
3820 return update_extra_cfg(ctx, &extra_cfg);
3821 }
3822
encoder_set_option(aom_codec_alg_priv_t * ctx,const char * name,const char * value)3823 static aom_codec_err_t encoder_set_option(aom_codec_alg_priv_t *ctx,
3824 const char *name, const char *value) {
3825 if (ctx == NULL || name == NULL || value == NULL)
3826 return AOM_CODEC_INVALID_PARAM;
3827 struct av1_extracfg extra_cfg = ctx->extra_cfg;
3828 // Used to mock the argv with just one string "--{name}={value}"
3829 char *argv[2] = { NULL, "" };
3830 size_t len = strlen(name) + strlen(value) + 4;
3831 char *const err_string = ctx->ppi->error.detail;
3832
3833 #if __STDC_VERSION__ >= 201112L
3834 // We use the keyword _Static_assert because clang-cl does not allow the
3835 // convenience macro static_assert to be used in function scope. See
3836 // https://bugs.llvm.org/show_bug.cgi?id=48904.
3837 _Static_assert(sizeof(ctx->ppi->error.detail) >= ARG_ERR_MSG_MAX_LEN,
3838 "The size of the err_msg buffer for arg_match_helper must be "
3839 "at least ARG_ERR_MSG_MAX_LEN");
3840 #else
3841 assert(sizeof(ctx->ppi->error.detail) >= ARG_ERR_MSG_MAX_LEN);
3842 #endif
3843
3844 argv[0] = aom_malloc(len * sizeof(argv[1][0]));
3845 if (!argv[0]) return AOM_CODEC_MEM_ERROR;
3846 snprintf(argv[0], len, "--%s=%s", name, value);
3847 struct arg arg;
3848 aom_codec_err_t err = AOM_CODEC_OK;
3849
3850 int match = 1;
3851 if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_keyframe_filtering,
3852 argv, err_string)) {
3853 extra_cfg.enable_keyframe_filtering =
3854 arg_parse_uint_helper(&arg, err_string);
3855 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.min_gf_interval, argv,
3856 err_string)) {
3857 extra_cfg.min_gf_interval = arg_parse_uint_helper(&arg, err_string);
3858 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.max_gf_interval, argv,
3859 err_string)) {
3860 extra_cfg.max_gf_interval = arg_parse_uint_helper(&arg, err_string);
3861 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.gf_min_pyr_height,
3862 argv, err_string)) {
3863 extra_cfg.gf_min_pyr_height = arg_parse_uint_helper(&arg, err_string);
3864 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.gf_max_pyr_height,
3865 argv, err_string)) {
3866 extra_cfg.gf_max_pyr_height = arg_parse_uint_helper(&arg, err_string);
3867 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.cpu_used_av1, argv,
3868 err_string)) {
3869 extra_cfg.cpu_used = arg_parse_uint_helper(&arg, err_string);
3870 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.auto_altref, argv,
3871 err_string)) {
3872 extra_cfg.enable_auto_alt_ref = arg_parse_uint_helper(&arg, err_string);
3873 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.noise_sens, argv,
3874 err_string)) {
3875 extra_cfg.noise_sensitivity = arg_parse_uint_helper(&arg, err_string);
3876 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.sharpness, argv,
3877 err_string)) {
3878 extra_cfg.sharpness = arg_parse_uint_helper(&arg, err_string);
3879 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.static_thresh, argv,
3880 err_string)) {
3881 extra_cfg.static_thresh = arg_parse_uint_helper(&arg, err_string);
3882 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.rowmtarg, argv,
3883 err_string)) {
3884 extra_cfg.row_mt = arg_parse_uint_helper(&arg, err_string);
3885 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.fpmtarg, argv,
3886 err_string)) {
3887 extra_cfg.fp_mt = arg_parse_uint_helper(&arg, err_string);
3888 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tile_cols, argv,
3889 err_string)) {
3890 extra_cfg.tile_columns = arg_parse_uint_helper(&arg, err_string);
3891 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tile_rows, argv,
3892 err_string)) {
3893 extra_cfg.tile_rows = arg_parse_uint_helper(&arg, err_string);
3894 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_tpl_model,
3895 argv, err_string)) {
3896 extra_cfg.enable_tpl_model = arg_parse_uint_helper(&arg, err_string);
3897 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.arnr_maxframes, argv,
3898 err_string)) {
3899 extra_cfg.arnr_max_frames = arg_parse_uint_helper(&arg, err_string);
3900 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.arnr_strength, argv,
3901 err_string)) {
3902 extra_cfg.arnr_strength = arg_parse_uint_helper(&arg, err_string);
3903 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tune_metric, argv,
3904 err_string)) {
3905 extra_cfg.tuning = arg_parse_enum_helper(&arg, err_string);
3906 }
3907 #if CONFIG_TUNE_VMAF
3908 else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.vmaf_model_path, argv,
3909 err_string)) {
3910 err = allocate_and_set_string(value, default_extra_cfg.vmaf_model_path,
3911 &extra_cfg.vmaf_model_path, err_string);
3912 }
3913 #endif
3914 else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.partition_info_path,
3915 argv, err_string)) {
3916 err = allocate_and_set_string(value, default_extra_cfg.partition_info_path,
3917 &extra_cfg.partition_info_path, err_string);
3918 } else if (arg_match_helper(&arg,
3919 &g_av1_codec_arg_defs.enable_rate_guide_deltaq,
3920 argv, err_string)) {
3921 extra_cfg.enable_rate_guide_deltaq =
3922 arg_parse_uint_helper(&arg, err_string);
3923 } else if (arg_match_helper(&arg,
3924 &g_av1_codec_arg_defs.rate_distribution_info,
3925 argv, err_string)) {
3926 err =
3927 allocate_and_set_string(value, default_extra_cfg.rate_distribution_info,
3928 &extra_cfg.rate_distribution_info, err_string);
3929 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.dist_metric, argv,
3930 err_string)) {
3931 extra_cfg.dist_metric = arg_parse_enum_helper(&arg, err_string);
3932 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.cq_level, argv,
3933 err_string)) {
3934 extra_cfg.cq_level = arg_parse_uint_helper(&arg, err_string);
3935 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.max_intra_rate_pct,
3936 argv, err_string)) {
3937 extra_cfg.rc_max_intra_bitrate_pct =
3938 arg_parse_uint_helper(&arg, err_string);
3939 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.max_inter_rate_pct,
3940 argv, err_string)) {
3941 extra_cfg.rc_max_inter_bitrate_pct =
3942 arg_parse_uint_helper(&arg, err_string);
3943 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.gf_cbr_boost_pct,
3944 argv, err_string)) {
3945 extra_cfg.gf_cbr_boost_pct = arg_parse_uint_helper(&arg, err_string);
3946 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.lossless, argv,
3947 err_string)) {
3948 extra_cfg.lossless = arg_parse_uint_helper(&arg, err_string);
3949 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_cdef, argv,
3950 err_string)) {
3951 extra_cfg.enable_cdef = arg_parse_uint_helper(&arg, err_string);
3952 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_restoration,
3953 argv, err_string)) {
3954 extra_cfg.enable_restoration = arg_parse_uint_helper(&arg, err_string);
3955 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.force_video_mode,
3956 argv, err_string)) {
3957 extra_cfg.force_video_mode = arg_parse_uint_helper(&arg, err_string);
3958 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_obmc, argv,
3959 err_string)) {
3960 extra_cfg.enable_obmc = arg_parse_uint_helper(&arg, err_string);
3961 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.disable_trellis_quant,
3962 argv, err_string)) {
3963 extra_cfg.disable_trellis_quant = arg_parse_uint_helper(&arg, err_string);
3964 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_qm, argv,
3965 err_string)) {
3966 extra_cfg.enable_qm = arg_parse_uint_helper(&arg, err_string);
3967 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.qm_max, argv,
3968 err_string)) {
3969 extra_cfg.qm_max = arg_parse_uint_helper(&arg, err_string);
3970 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.qm_min, argv,
3971 err_string)) {
3972 extra_cfg.qm_min = arg_parse_uint_helper(&arg, err_string);
3973 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.num_tg, argv,
3974 err_string)) {
3975 extra_cfg.num_tg = arg_parse_uint_helper(&arg, err_string);
3976 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.mtu_size, argv,
3977 err_string)) {
3978 extra_cfg.mtu_size = arg_parse_uint_helper(&arg, err_string);
3979 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.timing_info, argv,
3980 err_string)) {
3981 extra_cfg.timing_info_type = arg_parse_enum_helper(&arg, err_string);
3982 } else if (arg_match_helper(&arg,
3983 &g_av1_codec_arg_defs.frame_parallel_decoding,
3984 argv, err_string)) {
3985 extra_cfg.frame_parallel_decoding_mode =
3986 arg_parse_uint_helper(&arg, err_string);
3987 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_dual_filter,
3988 argv, err_string)) {
3989 extra_cfg.enable_dual_filter = arg_parse_uint_helper(&arg, err_string);
3990 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_chroma_deltaq,
3991 argv, err_string)) {
3992 extra_cfg.enable_chroma_deltaq = arg_parse_uint_helper(&arg, err_string);
3993 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.aq_mode, argv,
3994 err_string)) {
3995 extra_cfg.aq_mode = arg_parse_uint_helper(&arg, err_string);
3996 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.deltaq_mode, argv,
3997 err_string)) {
3998 extra_cfg.deltaq_mode = arg_parse_uint_helper(&arg, err_string);
3999 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.deltaq_strength, argv,
4000 err_string)) {
4001 extra_cfg.deltaq_strength = arg_parse_uint_helper(&arg, err_string);
4002 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.deltalf_mode, argv,
4003 err_string)) {
4004 extra_cfg.deltalf_mode = arg_parse_uint_helper(&arg, err_string);
4005 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.frame_periodic_boost,
4006 argv, err_string)) {
4007 extra_cfg.frame_periodic_boost = arg_parse_uint_helper(&arg, err_string);
4008 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tune_content, argv,
4009 err_string)) {
4010 extra_cfg.content = arg_parse_enum_helper(&arg, err_string);
4011 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.input_color_primaries,
4012 argv, err_string)) {
4013 extra_cfg.color_primaries = arg_parse_enum_helper(&arg, err_string);
4014 } else if (arg_match_helper(
4015 &arg, &g_av1_codec_arg_defs.input_transfer_characteristics,
4016 argv, err_string)) {
4017 extra_cfg.transfer_characteristics =
4018 arg_parse_enum_helper(&arg, err_string);
4019 } else if (arg_match_helper(&arg,
4020 &g_av1_codec_arg_defs.input_matrix_coefficients,
4021 argv, err_string)) {
4022 extra_cfg.matrix_coefficients = arg_parse_enum_helper(&arg, err_string);
4023 } else if (arg_match_helper(
4024 &arg, &g_av1_codec_arg_defs.input_chroma_sample_position, argv,
4025 err_string)) {
4026 extra_cfg.chroma_sample_position = arg_parse_enum_helper(&arg, err_string);
4027 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.superblock_size, argv,
4028 err_string)) {
4029 extra_cfg.superblock_size = arg_parse_enum_helper(&arg, err_string);
4030 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.error_resilient_mode,
4031 argv, err_string)) {
4032 extra_cfg.error_resilient_mode = arg_parse_int_helper(&arg, err_string);
4033 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.sframe_mode, argv,
4034 err_string)) {
4035 extra_cfg.s_frame_mode = arg_parse_int_helper(&arg, err_string);
4036 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.film_grain_test, argv,
4037 err_string)) {
4038 extra_cfg.film_grain_test_vector = arg_parse_int_helper(&arg, err_string);
4039 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.film_grain_table,
4040 argv, err_string)) {
4041 if (value == NULL) {
4042 // this parameter allows NULL as its value
4043 extra_cfg.film_grain_table_filename = value;
4044 } else {
4045 err = allocate_and_set_string(
4046 value, default_extra_cfg.film_grain_table_filename,
4047 &extra_cfg.film_grain_table_filename, err_string);
4048 }
4049 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.cdf_update_mode, argv,
4050 err_string)) {
4051 extra_cfg.cdf_update_mode = arg_parse_int_helper(&arg, err_string);
4052 } else if (arg_match_helper(&arg,
4053 &g_av1_codec_arg_defs.enable_rect_partitions,
4054 argv, err_string)) {
4055 extra_cfg.enable_rect_partitions = arg_parse_int_helper(&arg, err_string);
4056 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_ab_partitions,
4057 argv, err_string)) {
4058 extra_cfg.enable_ab_partitions = arg_parse_int_helper(&arg, err_string);
4059 } else if (arg_match_helper(&arg,
4060 &g_av1_codec_arg_defs.enable_1to4_partitions,
4061 argv, err_string)) {
4062 extra_cfg.enable_1to4_partitions = arg_parse_int_helper(&arg, err_string);
4063 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.min_partition_size,
4064 argv, err_string)) {
4065 extra_cfg.min_partition_size = arg_parse_int_helper(&arg, err_string);
4066 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.max_partition_size,
4067 argv, err_string)) {
4068 extra_cfg.max_partition_size = arg_parse_int_helper(&arg, err_string);
4069 } else if (arg_match_helper(&arg,
4070 &g_av1_codec_arg_defs.enable_intra_edge_filter,
4071 argv, err_string)) {
4072 extra_cfg.enable_intra_edge_filter =
4073 arg_parse_uint_helper(&arg, err_string);
4074 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_order_hint,
4075 argv, err_string)) {
4076 extra_cfg.enable_order_hint = arg_parse_int_helper(&arg, err_string);
4077 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_tx64, argv,
4078 err_string)) {
4079 extra_cfg.enable_tx64 = arg_parse_int_helper(&arg, err_string);
4080 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_flip_idtx,
4081 argv, err_string)) {
4082 extra_cfg.enable_flip_idtx = arg_parse_int_helper(&arg, err_string);
4083 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_rect_tx, argv,
4084 err_string)) {
4085 extra_cfg.enable_rect_tx = arg_parse_int_helper(&arg, err_string);
4086 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_dist_wtd_comp,
4087 argv, err_string)) {
4088 extra_cfg.enable_dist_wtd_comp = arg_parse_int_helper(&arg, err_string);
4089 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.max_reference_frames,
4090 argv, err_string)) {
4091 extra_cfg.max_reference_frames = arg_parse_int_helper(&arg, err_string);
4092 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.reduced_reference_set,
4093 argv, err_string)) {
4094 extra_cfg.enable_reduced_reference_set =
4095 arg_parse_int_helper(&arg, err_string);
4096 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_ref_frame_mvs,
4097 argv, err_string)) {
4098 extra_cfg.enable_ref_frame_mvs = arg_parse_int_helper(&arg, err_string);
4099 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_masked_comp,
4100 argv, err_string)) {
4101 extra_cfg.enable_masked_comp = arg_parse_int_helper(&arg, err_string);
4102 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_onesided_comp,
4103 argv, err_string)) {
4104 extra_cfg.enable_onesided_comp = arg_parse_int_helper(&arg, err_string);
4105 } else if (arg_match_helper(&arg,
4106 &g_av1_codec_arg_defs.enable_interintra_comp,
4107 argv, err_string)) {
4108 extra_cfg.enable_interintra_comp = arg_parse_int_helper(&arg, err_string);
4109 } else if (arg_match_helper(&arg,
4110 &g_av1_codec_arg_defs.enable_smooth_interintra,
4111 argv, err_string)) {
4112 extra_cfg.enable_smooth_interintra = arg_parse_int_helper(&arg, err_string);
4113 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_diff_wtd_comp,
4114 argv, err_string)) {
4115 extra_cfg.enable_diff_wtd_comp = arg_parse_int_helper(&arg, err_string);
4116 } else if (arg_match_helper(&arg,
4117 &g_av1_codec_arg_defs.enable_interinter_wedge,
4118 argv, err_string)) {
4119 extra_cfg.enable_interinter_wedge = arg_parse_int_helper(&arg, err_string);
4120 } else if (arg_match_helper(&arg,
4121 &g_av1_codec_arg_defs.enable_interintra_wedge,
4122 argv, err_string)) {
4123 extra_cfg.enable_interintra_wedge = arg_parse_int_helper(&arg, err_string);
4124 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_global_motion,
4125 argv, err_string)) {
4126 extra_cfg.enable_global_motion = arg_parse_int_helper(&arg, err_string);
4127 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_warped_motion,
4128 argv, err_string)) {
4129 extra_cfg.enable_warped_motion = arg_parse_int_helper(&arg, err_string);
4130 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_filter_intra,
4131 argv, err_string)) {
4132 extra_cfg.enable_filter_intra = arg_parse_int_helper(&arg, err_string);
4133 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_smooth_intra,
4134 argv, err_string)) {
4135 extra_cfg.enable_smooth_intra = arg_parse_int_helper(&arg, err_string);
4136 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_paeth_intra,
4137 argv, err_string)) {
4138 extra_cfg.enable_paeth_intra = arg_parse_int_helper(&arg, err_string);
4139 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_cfl_intra,
4140 argv, err_string)) {
4141 extra_cfg.enable_cfl_intra = arg_parse_int_helper(&arg, err_string);
4142 } else if (arg_match_helper(&arg,
4143 &g_av1_codec_arg_defs.enable_directional_intra,
4144 argv, err_string)) {
4145 extra_cfg.enable_directional_intra = arg_parse_int_helper(&arg, err_string);
4146 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_diagonal_intra,
4147 argv, err_string)) {
4148 extra_cfg.enable_diagonal_intra = arg_parse_int_helper(&arg, err_string);
4149 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_overlay, argv,
4150 err_string)) {
4151 extra_cfg.enable_overlay = arg_parse_int_helper(&arg, err_string);
4152 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_palette, argv,
4153 err_string)) {
4154 extra_cfg.enable_palette = arg_parse_int_helper(&arg, err_string);
4155 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_intrabc, argv,
4156 err_string)) {
4157 extra_cfg.enable_intrabc = arg_parse_int_helper(&arg, err_string);
4158 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_angle_delta,
4159 argv, err_string)) {
4160 extra_cfg.enable_angle_delta = arg_parse_int_helper(&arg, err_string);
4161 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.reduced_tx_type_set,
4162 argv, err_string)) {
4163 extra_cfg.reduced_tx_type_set = arg_parse_int_helper(&arg, err_string);
4164 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.use_intra_dct_only,
4165 argv, err_string)) {
4166 extra_cfg.use_intra_dct_only = arg_parse_int_helper(&arg, err_string);
4167 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.use_inter_dct_only,
4168 argv, err_string)) {
4169 extra_cfg.use_inter_dct_only = arg_parse_int_helper(&arg, err_string);
4170 } else if (arg_match_helper(&arg,
4171 &g_av1_codec_arg_defs.use_intra_default_tx_only,
4172 argv, err_string)) {
4173 extra_cfg.use_intra_default_tx_only =
4174 arg_parse_int_helper(&arg, err_string);
4175 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.quant_b_adapt, argv,
4176 err_string)) {
4177 extra_cfg.quant_b_adapt = arg_parse_int_helper(&arg, err_string);
4178 } else if (arg_match_helper(&arg,
4179 &g_av1_codec_arg_defs.vbr_corpus_complexity_lap,
4180 argv, err_string)) {
4181 extra_cfg.vbr_corpus_complexity_lap =
4182 arg_parse_uint_helper(&arg, err_string);
4183 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.set_tier_mask, argv,
4184 err_string)) {
4185 extra_cfg.tier_mask = arg_parse_uint_helper(&arg, err_string);
4186 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.set_min_cr, argv,
4187 err_string)) {
4188 extra_cfg.min_cr = arg_parse_uint_helper(&arg, err_string);
4189 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.coeff_cost_upd_freq,
4190 argv, err_string)) {
4191 extra_cfg.coeff_cost_upd_freq = arg_parse_uint_helper(&arg, err_string);
4192 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.mode_cost_upd_freq,
4193 argv, err_string)) {
4194 extra_cfg.mode_cost_upd_freq = arg_parse_uint_helper(&arg, err_string);
4195 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.mv_cost_upd_freq,
4196 argv, err_string)) {
4197 extra_cfg.mv_cost_upd_freq = arg_parse_uint_helper(&arg, err_string);
4198 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.dv_cost_upd_freq,
4199 argv, err_string)) {
4200 extra_cfg.dv_cost_upd_freq = arg_parse_uint_helper(&arg, err_string);
4201 }
4202 #if CONFIG_DENOISE
4203 else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.denoise_noise_level,
4204 argv, err_string)) {
4205 extra_cfg.noise_level =
4206 (float)arg_parse_int_helper(&arg, err_string) / 10.0f;
4207 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.denoise_block_size,
4208 argv, err_string)) {
4209 extra_cfg.noise_block_size = arg_parse_uint_helper(&arg, err_string);
4210 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_dnl_denoising,
4211 argv, err_string)) {
4212 extra_cfg.enable_dnl_denoising = arg_parse_uint_helper(&arg, err_string);
4213 }
4214 #endif
4215 else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.target_seq_level_idx,
4216 argv, err_string)) {
4217 const int val = arg_parse_int_helper(&arg, err_string);
4218 const int level = val % 100;
4219 const int operating_point_idx = val / 100;
4220 if (operating_point_idx < 0 ||
4221 operating_point_idx >= MAX_NUM_OPERATING_POINTS) {
4222 snprintf(err_string, ARG_ERR_MSG_MAX_LEN,
4223 "Invalid operating point index: %d", operating_point_idx);
4224 err = AOM_CODEC_INVALID_PARAM;
4225 } else {
4226 extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
4227 }
4228 } else if (arg_match_helper(&arg,
4229 &g_av1_codec_arg_defs.input_chroma_subsampling_x,
4230 argv, err_string)) {
4231 extra_cfg.chroma_subsampling_x = arg_parse_uint_helper(&arg, err_string);
4232 } else if (arg_match_helper(&arg,
4233 &g_av1_codec_arg_defs.input_chroma_subsampling_y,
4234 argv, err_string)) {
4235 extra_cfg.chroma_subsampling_y = arg_parse_uint_helper(&arg, err_string);
4236 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.passes, argv,
4237 err_string)) {
4238 extra_cfg.passes = arg_parse_int_helper(&arg, err_string);
4239 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.fwd_kf_dist, argv,
4240 err_string)) {
4241 extra_cfg.fwd_kf_dist = arg_parse_int_helper(&arg, err_string);
4242 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.two_pass_output, argv,
4243 err_string)) {
4244 err = allocate_and_set_string(value, default_extra_cfg.two_pass_output,
4245 &extra_cfg.two_pass_output, err_string);
4246 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.second_pass_log, argv,
4247 err_string)) {
4248 err = allocate_and_set_string(value, default_extra_cfg.second_pass_log,
4249 &extra_cfg.second_pass_log, err_string);
4250 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.loopfilter_control,
4251 argv, err_string)) {
4252 extra_cfg.loopfilter_control = arg_parse_int_helper(&arg, err_string);
4253 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.auto_intra_tools_off,
4254 argv, err_string)) {
4255 extra_cfg.auto_intra_tools_off = arg_parse_uint_helper(&arg, err_string);
4256 } else if (arg_match_helper(&arg,
4257 &g_av1_codec_arg_defs.strict_level_conformance,
4258 argv, err_string)) {
4259 extra_cfg.strict_level_conformance = arg_parse_int_helper(&arg, err_string);
4260 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.sb_qp_sweep, argv,
4261 err_string)) {
4262 extra_cfg.sb_qp_sweep = arg_parse_int_helper(&arg, err_string);
4263 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.kf_max_pyr_height,
4264 argv, err_string)) {
4265 extra_cfg.kf_max_pyr_height = arg_parse_int_helper(&arg, err_string);
4266 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tile_width, argv,
4267 err_string)) {
4268 ctx->cfg.tile_width_count = arg_parse_list_helper(
4269 &arg, ctx->cfg.tile_widths, MAX_TILE_WIDTHS, err_string);
4270 } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.tile_height, argv,
4271 err_string)) {
4272 ctx->cfg.tile_height_count = arg_parse_list_helper(
4273 &arg, ctx->cfg.tile_heights, MAX_TILE_HEIGHTS, err_string);
4274 } else {
4275 match = 0;
4276 snprintf(err_string, ARG_ERR_MSG_MAX_LEN, "Cannot find aom option %s",
4277 name);
4278 }
4279 aom_free(argv[0]);
4280
4281 if (err != AOM_CODEC_OK) {
4282 ctx->base.err_detail = err_string;
4283 return err;
4284 }
4285
4286 if (strlen(err_string) != 0) {
4287 ctx->base.err_detail = err_string;
4288 return AOM_CODEC_INVALID_PARAM;
4289 }
4290
4291 ctx->base.err_detail = NULL;
4292
4293 if (!match) {
4294 return AOM_CODEC_INVALID_PARAM;
4295 }
4296 return update_extra_cfg(ctx, &extra_cfg);
4297 }
4298
ctrl_get_seq_level_idx(aom_codec_alg_priv_t * ctx,va_list args)4299 static aom_codec_err_t ctrl_get_seq_level_idx(aom_codec_alg_priv_t *ctx,
4300 va_list args) {
4301 int *const arg = va_arg(args, int *);
4302 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
4303 return av1_get_seq_level_idx(&ctx->ppi->seq_params, &ctx->ppi->level_params,
4304 arg);
4305 }
4306
ctrl_get_target_seq_level_idx(aom_codec_alg_priv_t * ctx,va_list args)4307 static aom_codec_err_t ctrl_get_target_seq_level_idx(aom_codec_alg_priv_t *ctx,
4308 va_list args) {
4309 int *const arg = va_arg(args, int *);
4310 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
4311 return av1_get_target_seq_level_idx(&ctx->ppi->seq_params,
4312 &ctx->ppi->level_params, arg);
4313 }
4314
ctrl_get_num_operating_points(aom_codec_alg_priv_t * ctx,va_list args)4315 static aom_codec_err_t ctrl_get_num_operating_points(aom_codec_alg_priv_t *ctx,
4316 va_list args) {
4317 int *const arg = va_arg(args, int *);
4318 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
4319 *arg = ctx->ppi->seq_params.operating_points_cnt_minus_1 + 1;
4320 return AOM_CODEC_OK;
4321 }
4322
ctrl_get_luma_cdef_strength(aom_codec_alg_priv_t * ctx,va_list args)4323 static aom_codec_err_t ctrl_get_luma_cdef_strength(aom_codec_alg_priv_t *ctx,
4324 va_list args) {
4325 int *arg = va_arg(args, int *);
4326 AV1_COMMON const *cm = &ctx->ppi->cpi->common;
4327 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
4328 memcpy(arg, cm->cdef_info.cdef_strengths, CDEF_MAX_STRENGTHS * sizeof(*arg));
4329
4330 return AOM_CODEC_OK;
4331 }
4332
4333 static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
4334 { AV1_COPY_REFERENCE, ctrl_copy_reference },
4335 { AOME_USE_REFERENCE, ctrl_use_reference },
4336
4337 // Setters
4338 { AV1_SET_REFERENCE, ctrl_set_reference },
4339 { AOME_SET_ROI_MAP, ctrl_set_roi_map },
4340 { AOME_SET_ACTIVEMAP, ctrl_set_active_map },
4341 { AOME_SET_SCALEMODE, ctrl_set_scale_mode },
4342 { AOME_SET_SPATIAL_LAYER_ID, ctrl_set_spatial_layer_id },
4343 { AOME_SET_CPUUSED, ctrl_set_cpuused },
4344 { AOME_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref },
4345 { AOME_SET_ENABLEAUTOBWDREF, ctrl_set_enable_auto_bwd_ref },
4346 { AOME_SET_SHARPNESS, ctrl_set_sharpness },
4347 { AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
4348 { AV1E_SET_ROW_MT, ctrl_set_row_mt },
4349 { AV1E_SET_FP_MT, ctrl_set_fp_mt },
4350 { AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
4351 { AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
4352 { AV1E_SET_ENABLE_TPL_MODEL, ctrl_set_enable_tpl_model },
4353 { AV1E_SET_ENABLE_KEYFRAME_FILTERING, ctrl_set_enable_keyframe_filtering },
4354 { AOME_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
4355 { AOME_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
4356 { AOME_SET_TUNING, ctrl_set_tuning },
4357 { AOME_SET_CQ_LEVEL, ctrl_set_cq_level },
4358 { AOME_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct },
4359 { AOME_SET_NUMBER_SPATIAL_LAYERS, ctrl_set_number_spatial_layers },
4360 { AV1E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct },
4361 { AV1E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct },
4362 { AV1E_SET_LOSSLESS, ctrl_set_lossless },
4363 { AV1E_SET_ENABLE_CDEF, ctrl_set_enable_cdef },
4364 { AV1E_SET_ENABLE_RESTORATION, ctrl_set_enable_restoration },
4365 { AV1E_SET_FORCE_VIDEO_MODE, ctrl_set_force_video_mode },
4366 { AV1E_SET_ENABLE_OBMC, ctrl_set_enable_obmc },
4367 { AV1E_SET_DISABLE_TRELLIS_QUANT, ctrl_set_disable_trellis_quant },
4368 { AV1E_SET_ENABLE_QM, ctrl_set_enable_qm },
4369 { AV1E_SET_QM_Y, ctrl_set_qm_y },
4370 { AV1E_SET_QM_U, ctrl_set_qm_u },
4371 { AV1E_SET_QM_V, ctrl_set_qm_v },
4372 { AV1E_SET_QM_MIN, ctrl_set_qm_min },
4373 { AV1E_SET_QM_MAX, ctrl_set_qm_max },
4374 { AV1E_SET_NUM_TG, ctrl_set_num_tg },
4375 { AV1E_SET_MTU, ctrl_set_mtu },
4376 { AV1E_SET_TIMING_INFO_TYPE, ctrl_set_timing_info_type },
4377 { AV1E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode },
4378 { AV1E_SET_ERROR_RESILIENT_MODE, ctrl_set_error_resilient_mode },
4379 { AV1E_SET_S_FRAME_MODE, ctrl_set_s_frame_mode },
4380 { AV1E_SET_ENABLE_RECT_PARTITIONS, ctrl_set_enable_rect_partitions },
4381 { AV1E_SET_ENABLE_AB_PARTITIONS, ctrl_set_enable_ab_partitions },
4382 { AV1E_SET_ENABLE_1TO4_PARTITIONS, ctrl_set_enable_1to4_partitions },
4383 { AV1E_SET_MIN_PARTITION_SIZE, ctrl_set_min_partition_size },
4384 { AV1E_SET_MAX_PARTITION_SIZE, ctrl_set_max_partition_size },
4385 { AV1E_SET_ENABLE_DUAL_FILTER, ctrl_set_enable_dual_filter },
4386 { AV1E_SET_ENABLE_CHROMA_DELTAQ, ctrl_set_enable_chroma_deltaq },
4387 { AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctrl_set_enable_intra_edge_filter },
4388 { AV1E_SET_ENABLE_ORDER_HINT, ctrl_set_enable_order_hint },
4389 { AV1E_SET_ENABLE_TX64, ctrl_set_enable_tx64 },
4390 { AV1E_SET_ENABLE_FLIP_IDTX, ctrl_set_enable_flip_idtx },
4391 { AV1E_SET_ENABLE_RECT_TX, ctrl_set_enable_rect_tx },
4392 { AV1E_SET_ENABLE_DIST_WTD_COMP, ctrl_set_enable_dist_wtd_comp },
4393 { AV1E_SET_MAX_REFERENCE_FRAMES, ctrl_set_max_reference_frames },
4394 { AV1E_SET_REDUCED_REFERENCE_SET, ctrl_set_enable_reduced_reference_set },
4395 { AV1E_SET_ENABLE_REF_FRAME_MVS, ctrl_set_enable_ref_frame_mvs },
4396 { AV1E_SET_ALLOW_REF_FRAME_MVS, ctrl_set_allow_ref_frame_mvs },
4397 { AV1E_SET_ENABLE_MASKED_COMP, ctrl_set_enable_masked_comp },
4398 { AV1E_SET_ENABLE_ONESIDED_COMP, ctrl_set_enable_onesided_comp },
4399 { AV1E_SET_ENABLE_INTERINTRA_COMP, ctrl_set_enable_interintra_comp },
4400 { AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctrl_set_enable_smooth_interintra },
4401 { AV1E_SET_ENABLE_DIFF_WTD_COMP, ctrl_set_enable_diff_wtd_comp },
4402 { AV1E_SET_ENABLE_INTERINTER_WEDGE, ctrl_set_enable_interinter_wedge },
4403 { AV1E_SET_ENABLE_INTERINTRA_WEDGE, ctrl_set_enable_interintra_wedge },
4404 { AV1E_SET_ENABLE_GLOBAL_MOTION, ctrl_set_enable_global_motion },
4405 { AV1E_SET_ENABLE_WARPED_MOTION, ctrl_set_enable_warped_motion },
4406 { AV1E_SET_ALLOW_WARPED_MOTION, ctrl_set_allow_warped_motion },
4407 { AV1E_SET_ENABLE_FILTER_INTRA, ctrl_set_enable_filter_intra },
4408 { AV1E_SET_ENABLE_SMOOTH_INTRA, ctrl_set_enable_smooth_intra },
4409 { AV1E_SET_ENABLE_PAETH_INTRA, ctrl_set_enable_paeth_intra },
4410 { AV1E_SET_ENABLE_CFL_INTRA, ctrl_set_enable_cfl_intra },
4411 { AV1E_SET_ENABLE_DIRECTIONAL_INTRA, ctrl_set_enable_directional_intra },
4412 { AV1E_SET_ENABLE_DIAGONAL_INTRA, ctrl_set_enable_diagonal_intra },
4413 { AV1E_SET_ENABLE_SUPERRES, ctrl_set_enable_superres },
4414 { AV1E_SET_ENABLE_OVERLAY, ctrl_set_enable_overlay },
4415 { AV1E_SET_ENABLE_PALETTE, ctrl_set_enable_palette },
4416 { AV1E_SET_ENABLE_INTRABC, ctrl_set_enable_intrabc },
4417 { AV1E_SET_ENABLE_ANGLE_DELTA, ctrl_set_enable_angle_delta },
4418 { AV1E_SET_AQ_MODE, ctrl_set_aq_mode },
4419 { AV1E_SET_REDUCED_TX_TYPE_SET, ctrl_set_reduced_tx_type_set },
4420 { AV1E_SET_INTRA_DCT_ONLY, ctrl_set_intra_dct_only },
4421 { AV1E_SET_INTER_DCT_ONLY, ctrl_set_inter_dct_only },
4422 { AV1E_SET_INTRA_DEFAULT_TX_ONLY, ctrl_set_intra_default_tx_only },
4423 { AV1E_SET_QUANT_B_ADAPT, ctrl_set_quant_b_adapt },
4424 { AV1E_SET_COEFF_COST_UPD_FREQ, ctrl_set_coeff_cost_upd_freq },
4425 { AV1E_SET_MODE_COST_UPD_FREQ, ctrl_set_mode_cost_upd_freq },
4426 { AV1E_SET_MV_COST_UPD_FREQ, ctrl_set_mv_cost_upd_freq },
4427 { AV1E_SET_DELTAQ_MODE, ctrl_set_deltaq_mode },
4428 { AV1E_SET_DELTAQ_STRENGTH, ctrl_set_deltaq_strength },
4429 { AV1E_SET_DELTALF_MODE, ctrl_set_deltalf_mode },
4430 { AV1E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
4431 { AV1E_SET_TUNE_CONTENT, ctrl_set_tune_content },
4432 { AV1E_SET_CDF_UPDATE_MODE, ctrl_set_cdf_update_mode },
4433 { AV1E_SET_COLOR_PRIMARIES, ctrl_set_color_primaries },
4434 { AV1E_SET_TRANSFER_CHARACTERISTICS, ctrl_set_transfer_characteristics },
4435 { AV1E_SET_MATRIX_COEFFICIENTS, ctrl_set_matrix_coefficients },
4436 { AV1E_SET_CHROMA_SAMPLE_POSITION, ctrl_set_chroma_sample_position },
4437 { AV1E_SET_COLOR_RANGE, ctrl_set_color_range },
4438 { AV1E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity },
4439 { AV1E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval },
4440 { AV1E_SET_MAX_GF_INTERVAL, ctrl_set_max_gf_interval },
4441 { AV1E_SET_GF_MIN_PYRAMID_HEIGHT, ctrl_set_gf_min_pyr_height },
4442 { AV1E_SET_GF_MAX_PYRAMID_HEIGHT, ctrl_set_gf_max_pyr_height },
4443 { AV1E_SET_RENDER_SIZE, ctrl_set_render_size },
4444 { AV1E_SET_SUPERBLOCK_SIZE, ctrl_set_superblock_size },
4445 { AV1E_SET_SINGLE_TILE_DECODING, ctrl_set_single_tile_decoding },
4446 { AV1E_SET_VMAF_MODEL_PATH, ctrl_set_vmaf_model_path },
4447 { AV1E_SET_PARTITION_INFO_PATH, ctrl_set_partition_info_path },
4448 { AV1E_ENABLE_RATE_GUIDE_DELTAQ, ctrl_enable_rate_guide_deltaq },
4449 { AV1E_SET_RATE_DISTRIBUTION_INFO, ctrl_set_rate_distribution_info },
4450 { AV1E_SET_FILM_GRAIN_TEST_VECTOR, ctrl_set_film_grain_test_vector },
4451 { AV1E_SET_FILM_GRAIN_TABLE, ctrl_set_film_grain_table },
4452 { AV1E_SET_DENOISE_NOISE_LEVEL, ctrl_set_denoise_noise_level },
4453 { AV1E_SET_DENOISE_BLOCK_SIZE, ctrl_set_denoise_block_size },
4454 { AV1E_SET_ENABLE_DNL_DENOISING, ctrl_set_enable_dnl_denoising },
4455 { AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
4456 { AV1E_SET_FP_MT_UNIT_TEST, ctrl_enable_fpmt_unit_test },
4457 { AV1E_ENABLE_EXT_TILE_DEBUG, ctrl_enable_ext_tile_debug },
4458 { AV1E_SET_TARGET_SEQ_LEVEL_IDX, ctrl_set_target_seq_level_idx },
4459 { AV1E_SET_TIER_MASK, ctrl_set_tier_mask },
4460 { AV1E_SET_MIN_CR, ctrl_set_min_cr },
4461 { AV1E_SET_SVC_LAYER_ID, ctrl_set_layer_id },
4462 { AV1E_SET_SVC_PARAMS, ctrl_set_svc_params },
4463 { AV1E_SET_SVC_REF_FRAME_CONFIG, ctrl_set_svc_ref_frame_config },
4464 { AV1E_SET_SVC_REF_FRAME_COMP_PRED, ctrl_set_svc_ref_frame_comp_pred },
4465 { AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP, ctrl_set_vbr_corpus_complexity_lap },
4466 { AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST, ctrl_enable_sb_multipass_unit_test },
4467 { AV1E_ENABLE_SB_QP_SWEEP, ctrl_enable_sb_qp_sweep },
4468 { AV1E_SET_DV_COST_UPD_FREQ, ctrl_set_dv_cost_upd_freq },
4469 { AV1E_SET_EXTERNAL_PARTITION, ctrl_set_external_partition },
4470 { AV1E_SET_ENABLE_TX_SIZE_SEARCH, ctrl_set_enable_tx_size_search },
4471 { AV1E_SET_LOOPFILTER_CONTROL, ctrl_set_loopfilter_control },
4472 { AV1E_SET_SKIP_POSTPROC_FILTERING, ctrl_set_skip_postproc_filtering },
4473 { AV1E_SET_AUTO_INTRA_TOOLS_OFF, ctrl_set_auto_intra_tools_off },
4474 { AV1E_SET_RTC_EXTERNAL_RC, ctrl_set_rtc_external_rc },
4475 { AV1E_SET_QUANTIZER_ONE_PASS, ctrl_set_quantizer_one_pass },
4476 { AV1E_SET_BITRATE_ONE_PASS_CBR, ctrl_set_bitrate_one_pass_cbr },
4477 { AV1E_SET_MAX_CONSEC_FRAME_DROP_CBR, ctrl_set_max_consec_frame_drop_cbr },
4478 { AV1E_SET_SVC_FRAME_DROP_MODE, ctrl_set_svc_frame_drop_mode },
4479
4480 // Getters
4481 { AOME_GET_LAST_QUANTIZER, ctrl_get_quantizer },
4482 { AOME_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64 },
4483 { AOME_GET_LOOPFILTER_LEVEL, ctrl_get_loopfilter_level },
4484 { AV1_GET_REFERENCE, ctrl_get_reference },
4485 { AV1E_GET_ACTIVEMAP, ctrl_get_active_map },
4486 { AV1_GET_NEW_FRAME_IMAGE, ctrl_get_new_frame_image },
4487 { AV1_COPY_NEW_FRAME_IMAGE, ctrl_copy_new_frame_image },
4488 { AV1E_SET_CHROMA_SUBSAMPLING_X, ctrl_set_chroma_subsampling_x },
4489 { AV1E_SET_CHROMA_SUBSAMPLING_Y, ctrl_set_chroma_subsampling_y },
4490 { AV1E_GET_SEQ_LEVEL_IDX, ctrl_get_seq_level_idx },
4491 { AV1E_GET_BASELINE_GF_INTERVAL, ctrl_get_baseline_gf_interval },
4492 { AV1E_GET_TARGET_SEQ_LEVEL_IDX, ctrl_get_target_seq_level_idx },
4493 { AV1E_GET_NUM_OPERATING_POINTS, ctrl_get_num_operating_points },
4494 { AV1E_GET_LUMA_CDEF_STRENGTH, ctrl_get_luma_cdef_strength },
4495
4496 CTRL_MAP_END,
4497 };
4498
4499 static const aom_codec_enc_cfg_t encoder_usage_cfg[] = {
4500 #if !CONFIG_REALTIME_ONLY
4501 {
4502 // NOLINT
4503 AOM_USAGE_GOOD_QUALITY, // g_usage - non-realtime usage
4504 0, // g_threads
4505 0, // g_profile
4506
4507 320, // g_w
4508 240, // g_h
4509 0, // g_limit
4510 0, // g_forced_max_frame_width
4511 0, // g_forced_max_frame_height
4512 AOM_BITS_8, // g_bit_depth
4513 8, // g_input_bit_depth
4514
4515 { 1, 30 }, // g_timebase
4516
4517 0, // g_error_resilient
4518
4519 AOM_RC_ONE_PASS, // g_pass
4520
4521 35, // g_lag_in_frames
4522
4523 0, // rc_dropframe_thresh
4524 RESIZE_NONE, // rc_resize_mode
4525 SCALE_NUMERATOR, // rc_resize_denominator
4526 SCALE_NUMERATOR, // rc_resize_kf_denominator
4527
4528 AOM_SUPERRES_NONE, // rc_superres_mode
4529 SCALE_NUMERATOR, // rc_superres_denominator
4530 SCALE_NUMERATOR, // rc_superres_kf_denominator
4531 63, // rc_superres_qthresh
4532 32, // rc_superres_kf_qthresh
4533
4534 AOM_VBR, // rc_end_usage
4535 { NULL, 0 }, // rc_twopass_stats_in
4536 { NULL, 0 }, // rc_firstpass_mb_stats_in
4537 256, // rc_target_bitrate
4538 0, // rc_min_quantizer
4539 63, // rc_max_quantizer
4540 25, // rc_undershoot_pct
4541 25, // rc_overshoot_pct
4542
4543 6000, // rc_max_buffer_size
4544 4000, // rc_buffer_initial_size
4545 5000, // rc_buffer_optimal_size
4546
4547 50, // rc_two_pass_vbrbias
4548 0, // rc_two_pass_vbrmin_section
4549 2000, // rc_two_pass_vbrmax_section
4550
4551 // keyframing settings (kf)
4552 0, // fwd_kf_enabled
4553 AOM_KF_AUTO, // kf_mode
4554 0, // kf_min_dist
4555 9999, // kf_max_dist
4556 0, // sframe_dist
4557 1, // sframe_mode
4558 0, // large_scale_tile
4559 0, // monochrome
4560 0, // full_still_picture_hdr
4561 0, // save_as_annexb
4562 0, // tile_width_count
4563 0, // tile_height_count
4564 { 0 }, // tile_widths
4565 { 0 }, // tile_heights
4566 0, // use_fixed_qp_offsets
4567 { -1, -1, -1, -1, -1 }, // fixed_qp_offsets
4568 { 0, 128, 128, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4569 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // cfg
4570 },
4571 #endif // !CONFIG_REALTIME_ONLY
4572 {
4573 // NOLINT
4574 AOM_USAGE_REALTIME, // g_usage - real-time usage
4575 0, // g_threads
4576 0, // g_profile
4577
4578 320, // g_w
4579 240, // g_h
4580 0, // g_limit
4581 0, // g_forced_max_frame_width
4582 0, // g_forced_max_frame_height
4583 AOM_BITS_8, // g_bit_depth
4584 8, // g_input_bit_depth
4585
4586 { 1, 30 }, // g_timebase
4587
4588 0, // g_error_resilient
4589
4590 AOM_RC_ONE_PASS, // g_pass
4591
4592 0, // g_lag_in_frames
4593
4594 0, // rc_dropframe_thresh
4595 RESIZE_NONE, // rc_resize_mode
4596 SCALE_NUMERATOR, // rc_resize_denominator
4597 SCALE_NUMERATOR, // rc_resize_kf_denominator
4598
4599 AOM_SUPERRES_NONE, // rc_superres_mode
4600 SCALE_NUMERATOR, // rc_superres_denominator
4601 SCALE_NUMERATOR, // rc_superres_kf_denominator
4602 63, // rc_superres_qthresh
4603 32, // rc_superres_kf_qthresh
4604
4605 AOM_CBR, // rc_end_usage
4606 { NULL, 0 }, // rc_twopass_stats_in
4607 { NULL, 0 }, // rc_firstpass_mb_stats_in
4608 256, // rc_target_bitrate
4609 0, // rc_min_quantizer
4610 63, // rc_max_quantizer
4611 25, // rc_undershoot_pct
4612 25, // rc_overshoot_pct
4613
4614 6000, // rc_max_buffer_size
4615 4000, // rc_buffer_initial_size
4616 5000, // rc_buffer_optimal_size
4617
4618 50, // rc_two_pass_vbrbias
4619 0, // rc_two_pass_vbrmin_section
4620 2000, // rc_two_pass_vbrmax_section
4621
4622 // keyframing settings (kf)
4623 0, // fwd_kf_enabled
4624 AOM_KF_AUTO, // kf_mode
4625 0, // kf_min_dist
4626 9999, // kf_max_dist
4627 0, // sframe_dist
4628 1, // sframe_mode
4629 0, // large_scale_tile
4630 0, // monochrome
4631 0, // full_still_picture_hdr
4632 0, // save_as_annexb
4633 0, // tile_width_count
4634 0, // tile_height_count
4635 { 0 }, // tile_widths
4636 { 0 }, // tile_heights
4637 0, // use_fixed_qp_offsets
4638 { -1, -1, -1, -1, -1 }, // fixed_qp_offsets
4639 { 0, 128, 128, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // cfg
4641 },
4642 #if !CONFIG_REALTIME_ONLY
4643 {
4644 // NOLINT
4645 AOM_USAGE_ALL_INTRA, // g_usage - all intra usage
4646 0, // g_threads
4647 0, // g_profile
4648
4649 320, // g_w
4650 240, // g_h
4651 0, // g_limit
4652 0, // g_forced_max_frame_width
4653 0, // g_forced_max_frame_height
4654 AOM_BITS_8, // g_bit_depth
4655 8, // g_input_bit_depth
4656
4657 { 1, 30 }, // g_timebase
4658
4659 0, // g_error_resilient
4660
4661 AOM_RC_ONE_PASS, // g_pass
4662
4663 0, // g_lag_in_frames
4664
4665 0, // rc_dropframe_thresh
4666 RESIZE_NONE, // rc_resize_mode
4667 SCALE_NUMERATOR, // rc_resize_denominator
4668 SCALE_NUMERATOR, // rc_resize_kf_denominator
4669
4670 AOM_SUPERRES_NONE, // rc_superres_mode
4671 SCALE_NUMERATOR, // rc_superres_denominator
4672 SCALE_NUMERATOR, // rc_superres_kf_denominator
4673 63, // rc_superres_qthresh
4674 32, // rc_superres_kf_qthresh
4675
4676 AOM_Q, // rc_end_usage
4677 { NULL, 0 }, // rc_twopass_stats_in
4678 { NULL, 0 }, // rc_firstpass_mb_stats_in
4679 256, // rc_target_bitrate
4680 0, // rc_min_quantizer
4681 63, // rc_max_quantizer
4682 25, // rc_undershoot_pct
4683 25, // rc_overshoot_pct
4684
4685 6000, // rc_max_buffer_size
4686 4000, // rc_buffer_initial_size
4687 5000, // rc_buffer_optimal_size
4688
4689 50, // rc_two_pass_vbrbias
4690 0, // rc_two_pass_vbrmin_section
4691 2000, // rc_two_pass_vbrmax_section
4692
4693 // keyframing settings (kf)
4694 0, // fwd_kf_enabled
4695 AOM_KF_DISABLED, // kf_mode
4696 0, // kf_min_dist
4697 0, // kf_max_dist
4698 0, // sframe_dist
4699 1, // sframe_mode
4700 0, // large_scale_tile
4701 0, // monochrome
4702 0, // full_still_picture_hdr
4703 0, // save_as_annexb
4704 0, // tile_width_count
4705 0, // tile_height_count
4706 { 0 }, // tile_widths
4707 { 0 }, // tile_heights
4708 0, // use_fixed_qp_offsets
4709 { -1, -1, -1, -1, -1 }, // fixed_qp_offsets
4710 { 0, 128, 128, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4711 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // cfg
4712 },
4713 #endif // !CONFIG_REALTIME_ONLY
4714 };
4715
4716 // This data structure and function are exported in aom/aomcx.h
4717 #ifndef VERSION_STRING
4718 #define VERSION_STRING
4719 #endif
4720 aom_codec_iface_t aom_codec_av1_cx_algo = {
4721 "AOMedia Project AV1 Encoder" VERSION_STRING,
4722 AOM_CODEC_INTERNAL_ABI_VERSION,
4723 (CONFIG_AV1_HIGHBITDEPTH ? AOM_CODEC_CAP_HIGHBITDEPTH : 0) |
4724 AOM_CODEC_CAP_ENCODER | AOM_CODEC_CAP_PSNR, // aom_codec_caps_t
4725 encoder_init, // aom_codec_init_fn_t
4726 encoder_destroy, // aom_codec_destroy_fn_t
4727 encoder_ctrl_maps, // aom_codec_ctrl_fn_map_t
4728 {
4729 // NOLINT
4730 NULL, // aom_codec_peek_si_fn_t
4731 NULL, // aom_codec_get_si_fn_t
4732 NULL, // aom_codec_decode_fn_t
4733 NULL, // aom_codec_get_frame_fn_t
4734 NULL // aom_codec_set_fb_fn_t
4735 },
4736 {
4737 // NOLINT
4738 NELEMENTS(encoder_usage_cfg), // cfg_count
4739 encoder_usage_cfg, // aom_codec_enc_cfg_t
4740 encoder_encode, // aom_codec_encode_fn_t
4741 encoder_get_cxdata, // aom_codec_get_cx_data_fn_t
4742 encoder_set_config, // aom_codec_enc_config_set_fn_t
4743 encoder_get_global_headers, // aom_codec_get_global_headers_fn_t
4744 encoder_get_preview // aom_codec_get_preview_frame_fn_t
4745 },
4746 encoder_set_option // aom_codec_set_option_fn_t
4747 };
4748
aom_codec_av1_cx(void)4749 aom_codec_iface_t *aom_codec_av1_cx(void) { return &aom_codec_av1_cx_algo; }
4750