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