• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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