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