Home | History | Annotate | Download | only in av1
      1 /*
      2  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
      3  *
      4  * This source code is subject to the terms of the BSD 2 Clause License and
      5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6  * was not distributed with this source code in the LICENSE file, you can
      7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8  * Media Patent License 1.0 was not distributed with this source code in the
      9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10  */
     11 #include <stdlib.h>
     12 #include <string.h>
     13 
     14 #include "config/aom_config.h"
     15 #include "config/aom_version.h"
     16 
     17 #include "aom_ports/aom_once.h"
     18 #include "aom_ports/mem_ops.h"
     19 #include "aom_ports/system_state.h"
     20 
     21 #include "aom/aom_encoder.h"
     22 #include "aom/internal/aom_codec_internal.h"
     23 
     24 #include "av1/av1_iface_common.h"
     25 #include "av1/encoder/bitstream.h"
     26 #include "av1/encoder/encoder.h"
     27 #include "av1/encoder/firstpass.h"
     28 
     29 #define MAG_SIZE (4)
     30 #define MAX_NUM_ENHANCEMENT_LAYERS 3
     31 
     32 struct av1_extracfg {
     33   int cpu_used;  // available cpu percentage in 1/16
     34   unsigned int enable_auto_alt_ref;
     35   unsigned int enable_auto_bwd_ref;
     36   unsigned int noise_sensitivity;
     37   unsigned int sharpness;
     38   unsigned int static_thresh;
     39   unsigned int row_mt;
     40   unsigned int tile_columns;  // log2 number of tile columns
     41   unsigned int tile_rows;     // log2 number of tile rows
     42   unsigned int enable_tpl_model;
     43   unsigned int arnr_max_frames;
     44   unsigned int arnr_strength;
     45   unsigned int min_gf_interval;
     46   unsigned int max_gf_interval;
     47   unsigned int gf_max_pyr_height;
     48   aom_tune_metric tuning;
     49   unsigned int cq_level;  // constrained quality level
     50   unsigned int rc_max_intra_bitrate_pct;
     51   unsigned int rc_max_inter_bitrate_pct;
     52   unsigned int gf_cbr_boost_pct;
     53   unsigned int lossless;
     54   unsigned int enable_cdef;
     55   unsigned int enable_restoration;
     56   unsigned int enable_obmc;
     57   unsigned int disable_trellis_quant;
     58   unsigned int enable_qm;
     59   unsigned int qm_y;
     60   unsigned int qm_u;
     61   unsigned int qm_v;
     62   unsigned int qm_min;
     63   unsigned int qm_max;
     64 #if CONFIG_DIST_8X8
     65   unsigned int enable_dist_8x8;
     66 #endif
     67   unsigned int num_tg;
     68   unsigned int mtu_size;
     69 
     70   aom_timing_info_type_t timing_info_type;
     71   unsigned int frame_parallel_decoding_mode;
     72   int enable_dual_filter;
     73   AQ_MODE aq_mode;
     74   DELTAQ_MODE deltaq_mode;
     75   unsigned int frame_periodic_boost;
     76   aom_bit_depth_t bit_depth;
     77   aom_tune_content content;
     78   aom_color_primaries_t color_primaries;
     79   aom_transfer_characteristics_t transfer_characteristics;
     80   aom_matrix_coefficients_t matrix_coefficients;
     81   aom_chroma_sample_position_t chroma_sample_position;
     82   int color_range;
     83   int render_width;
     84   int render_height;
     85   aom_superblock_size_t superblock_size;
     86   unsigned int single_tile_decoding;
     87   int error_resilient_mode;
     88   int s_frame_mode;
     89 
     90   int film_grain_test_vector;
     91   const char *film_grain_table_filename;
     92   unsigned int motion_vector_unit_test;
     93   unsigned int cdf_update_mode;
     94   int enable_rect_partitions;    // enable rectangular partitions for sequence
     95   int enable_ab_partitions;      // enable AB partitions for sequence
     96   int enable_1to4_partitions;    // enable 1:4 and 4:1 partitions for sequence
     97   int min_partition_size;        // min partition size [4,8,16,32,64,128]
     98   int max_partition_size;        // max partition size [4,8,16,32,64,128]
     99   int enable_intra_edge_filter;  // enable intra-edge filter for sequence
    100   int enable_order_hint;         // enable order hint for sequence
    101   int enable_tx64;               // enable 64-pt transform usage for sequence
    102   int tx_size_search_method;     // set transform block size search method
    103   int enable_flip_idtx;          // enable flip and identity transform types
    104   int enable_dist_wtd_comp;      // enable dist wtd compound for sequence
    105   int max_reference_frames;      // maximum number of references per frame
    106   int enable_reduced_reference_set;  // enable reduced set of references
    107   int enable_ref_frame_mvs;          // sequence level
    108   int allow_ref_frame_mvs;           // frame level
    109   int enable_masked_comp;            // enable masked compound for sequence
    110   int enable_onesided_comp;          // enable one sided compound for sequence
    111   int enable_interintra_comp;        // enable interintra compound for sequence
    112   int enable_smooth_interintra;      // enable smooth interintra mode usage
    113   int enable_diff_wtd_comp;          // enable diff-wtd compound usage
    114   int enable_interinter_wedge;       // enable interinter-wedge compound usage
    115   int enable_interintra_wedge;       // enable interintra-wedge compound usage
    116   int enable_global_motion;          // enable global motion usage for sequence
    117   int enable_warped_motion;          // sequence level
    118   int allow_warped_motion;           // frame level
    119   int enable_filter_intra;           // enable filter intra for sequence
    120   int enable_smooth_intra;           // enable smooth intra modes for sequence
    121   int enable_paeth_intra;            // enable Paeth intra mode for sequence
    122   int enable_cfl_intra;              // enable CFL uv intra mode for sequence
    123   int enable_superres;
    124   int enable_palette;
    125   int enable_intrabc;
    126   int enable_angle_delta;
    127 #if CONFIG_DENOISE
    128   float noise_level;
    129   int noise_block_size;
    130 #endif
    131 
    132   unsigned int chroma_subsampling_x;
    133   unsigned int chroma_subsampling_y;
    134   int reduced_tx_type_set;
    135   int use_intra_dct_only;
    136   int use_inter_dct_only;
    137   int use_intra_default_tx_only;
    138   int quant_b_adapt;
    139   AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
    140   // Bit mask to specify which tier each of the 32 possible operating points
    141   // conforms to.
    142   unsigned int tier_mask;
    143   COST_UPDATE_TYPE coeff_cost_upd_freq;
    144   COST_UPDATE_TYPE mode_cost_upd_freq;
    145 };
    146 
    147 static struct av1_extracfg default_extra_cfg = {
    148   0,                       // cpu_used
    149   1,                       // enable_auto_alt_ref
    150   0,                       // enable_auto_bwd_ref
    151   0,                       // noise_sensitivity
    152   CONFIG_SHARP_SETTINGS,   // sharpness
    153   0,                       // static_thresh
    154   1,                       // row_mt
    155   0,                       // tile_columns
    156   0,                       // tile_rows
    157   0,                       // enable_tpl_model
    158   7,                       // arnr_max_frames
    159   5,                       // arnr_strength
    160   0,                       // min_gf_interval; 0 -> default decision
    161   0,                       // max_gf_interval; 0 -> default decision
    162   4,                       // gf_max_pyr_height
    163   AOM_TUNE_PSNR,           // tuning
    164   10,                      // cq_level
    165   0,                       // rc_max_intra_bitrate_pct
    166   0,                       // rc_max_inter_bitrate_pct
    167   0,                       // gf_cbr_boost_pct
    168   0,                       // lossless
    169   !CONFIG_SHARP_SETTINGS,  // enable_cdef
    170   1,                       // enable_restoration
    171   1,                       // enable_obmc
    172   0,                       // disable_trellis_quant
    173   0,                       // enable_qm
    174   DEFAULT_QM_Y,            // qm_y
    175   DEFAULT_QM_U,            // qm_u
    176   DEFAULT_QM_V,            // qm_v
    177   DEFAULT_QM_FIRST,        // qm_min
    178   DEFAULT_QM_LAST,         // qm_max
    179 #if CONFIG_DIST_8X8
    180   0,
    181 #endif
    182   1,                            // max number of tile groups
    183   0,                            // mtu_size
    184   AOM_TIMING_UNSPECIFIED,       // No picture timing signaling in bitstream
    185   0,                            // frame_parallel_decoding_mode
    186   1,                            // enable dual filter
    187   NO_AQ,                        // aq_mode
    188   NO_DELTA_Q,                   // deltaq_mode
    189   0,                            // frame_periodic_delta_q
    190   AOM_BITS_8,                   // Bit depth
    191   AOM_CONTENT_DEFAULT,          // content
    192   AOM_CICP_CP_UNSPECIFIED,      // CICP color space
    193   AOM_CICP_TC_UNSPECIFIED,      // CICP transfer characteristics
    194   AOM_CICP_MC_UNSPECIFIED,      // CICP matrix coefficients
    195   AOM_CSP_UNKNOWN,              // chroma sample position
    196   0,                            // color range
    197   0,                            // render width
    198   0,                            // render height
    199   AOM_SUPERBLOCK_SIZE_DYNAMIC,  // superblock_size
    200   1,                            // this depends on large_scale_tile.
    201   0,                            // error_resilient_mode off by default.
    202   0,                            // s_frame_mode off by default.
    203   0,                            // film_grain_test_vector
    204   0,                            // film_grain_table_filename
    205   0,                            // motion_vector_unit_test
    206   1,                            // CDF update mode
    207   1,                            // enable rectangular partitions
    208   1,                            // enable ab shape partitions
    209   1,                            // enable 1:4 and 4:1 partitions
    210   4,                            // min_partition_size
    211   128,                          // max_partition_size
    212   1,                            // enable intra edge filter
    213   1,                            // frame order hint
    214   1,                            // enable 64-pt transform usage
    215   0,                            // transform block size search method
    216   1,                            // enable flip and identity transform
    217   1,                            // dist-wtd compound
    218   7,                            // max_reference_frames
    219   0,                            // enable_reduced_reference_set
    220   1,                            // enable_ref_frame_mvs sequence level
    221   1,                            // allow ref_frame_mvs frame level
    222   1,                            // enable masked compound at sequence level
    223   1,                            // enable one sided compound at sequence level
    224   1,                            // enable interintra compound at sequence level
    225   1,                            // enable smooth interintra mode
    226   1,                            // enable difference-weighted compound
    227   1,                            // enable interinter wedge compound
    228   1,                            // enable interintra wedge compound
    229   1,                            // enable_global_motion usage
    230   1,                            // enable_warped_motion at sequence level
    231   1,                            // allow_warped_motion at frame level
    232   1,                            // enable filter intra at sequence level
    233   1,                            // enable smooth intra modes usage for sequence
    234   1,                            // enable Paeth intra mode usage for sequence
    235   1,                            // enable CFL uv intra mode usage for sequence
    236   1,                            // superres
    237   1,                            // enable palette
    238   !CONFIG_SHARP_SETTINGS,       // enable intrabc
    239   1,                            // enable angle delta
    240 #if CONFIG_DENOISE
    241   0,   // noise_level
    242   32,  // noise_block_size
    243 #endif
    244   0,  // chroma_subsampling_x
    245   0,  // chroma_subsampling_y
    246   0,  // reduced_tx_type_set
    247   0,  // use_intra_dct_only
    248   0,  // use_inter_dct_only
    249   0,  // use_intra_default_tx_only
    250   0,  // quant_b_adapt
    251   {
    252       31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
    253       31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
    254   },            // target_seq_level_idx
    255   0,            // tier_mask
    256   COST_UPD_SB,  // coeff_cost_upd_freq
    257   COST_UPD_SB,  // mode_cost_upd_freq
    258 };
    259 
    260 struct aom_codec_alg_priv {
    261   aom_codec_priv_t base;
    262   aom_codec_enc_cfg_t cfg;
    263   struct av1_extracfg extra_cfg;
    264   AV1EncoderConfig oxcf;
    265   AV1_COMP *cpi;
    266   unsigned char *cx_data;
    267   size_t cx_data_sz;
    268   unsigned char *pending_cx_data;
    269   size_t pending_cx_data_sz;
    270   int pending_frame_count;
    271   size_t pending_frame_sizes[8];
    272   aom_image_t preview_img;
    273   aom_enc_frame_flags_t next_frame_flags;
    274   aom_postproc_cfg_t preview_ppcfg;
    275   aom_codec_pkt_list_decl(256) pkt_list;
    276   unsigned int fixed_kf_cntr;
    277   // BufferPool that holds all reference frames.
    278   BufferPool *buffer_pool;
    279 };
    280 
    281 static aom_codec_err_t update_error_state(
    282     aom_codec_alg_priv_t *ctx, const struct aom_internal_error_info *error) {
    283   const aom_codec_err_t res = error->error_code;
    284 
    285   if (res != AOM_CODEC_OK)
    286     ctx->base.err_detail = error->has_detail ? error->detail : NULL;
    287 
    288   return res;
    289 }
    290 
    291 #undef ERROR
    292 #define ERROR(str)                  \
    293   do {                              \
    294     ctx->base.err_detail = str;     \
    295     return AOM_CODEC_INVALID_PARAM; \
    296   } while (0)
    297 
    298 #define RANGE_CHECK(p, memb, lo, hi)                   \
    299   do {                                                 \
    300     if (!((p)->memb >= (lo) && (p)->memb <= (hi)))     \
    301       ERROR(#memb " out of range [" #lo ".." #hi "]"); \
    302   } while (0)
    303 
    304 #define RANGE_CHECK_HI(p, memb, hi)                                     \
    305   do {                                                                  \
    306     if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
    307   } while (0)
    308 
    309 #define RANGE_CHECK_BOOL(p, memb)                                     \
    310   do {                                                                \
    311     if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \
    312   } while (0)
    313 
    314 static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
    315                                        const aom_codec_enc_cfg_t *cfg,
    316                                        const struct av1_extracfg *extra_cfg) {
    317   RANGE_CHECK(cfg, g_w, 1, 65535);  // 16 bits available
    318   RANGE_CHECK(cfg, g_h, 1, 65535);  // 16 bits available
    319   RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
    320   RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
    321   RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);
    322 
    323   RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
    324   RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
    325   RANGE_CHECK_BOOL(extra_cfg, lossless);
    326   RANGE_CHECK_HI(extra_cfg, aq_mode, AQ_MODE_COUNT - 1);
    327   RANGE_CHECK_HI(extra_cfg, deltaq_mode, DELTAQ_MODE_COUNT - 1);
    328   RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
    329   RANGE_CHECK_HI(cfg, g_usage, 1);
    330   RANGE_CHECK_HI(cfg, g_threads, MAX_NUM_THREADS);
    331   RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
    332   RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
    333   RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
    334   RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
    335   RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
    336   RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
    337   RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
    338   RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_LAST_PASS);
    339   RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
    340   RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
    341   if (extra_cfg->max_gf_interval > 0) {
    342     RANGE_CHECK(extra_cfg, max_gf_interval, MAX(2, extra_cfg->min_gf_interval),
    343                 (MAX_LAG_BUFFERS - 1));
    344   }
    345   RANGE_CHECK_HI(extra_cfg, gf_max_pyr_height, 4);
    346 
    347   RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
    348   RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
    349               SCALE_NUMERATOR << 1);
    350   RANGE_CHECK(cfg, rc_resize_kf_denominator, SCALE_NUMERATOR,
    351               SCALE_NUMERATOR << 1);
    352   RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_MODES - 1);
    353   RANGE_CHECK(cfg, rc_superres_denominator, SCALE_NUMERATOR,
    354               SCALE_NUMERATOR << 1);
    355   RANGE_CHECK(cfg, rc_superres_kf_denominator, SCALE_NUMERATOR,
    356               SCALE_NUMERATOR << 1);
    357   RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63);
    358   RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
    359   RANGE_CHECK_HI(extra_cfg, cdf_update_mode, 2);
    360 
    361   // AV1 does not support a lower bound on the keyframe interval in
    362   // automatic keyframe placement mode.
    363   if (cfg->kf_mode != AOM_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist &&
    364       cfg->kf_min_dist > 0)
    365     ERROR(
    366         "kf_min_dist not supported in auto mode, use 0 "
    367         "or kf_max_dist instead.");
    368 
    369   RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
    370   RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 1);
    371   RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
    372   RANGE_CHECK(extra_cfg, cpu_used, 0, 8);
    373   RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
    374   RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
    375               AOM_SUPERBLOCK_SIZE_DYNAMIC);
    376   RANGE_CHECK_HI(cfg, large_scale_tile, 1);
    377   RANGE_CHECK_HI(extra_cfg, single_tile_decoding, 1);
    378 
    379   RANGE_CHECK_HI(extra_cfg, row_mt, 1);
    380 
    381   RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
    382   RANGE_CHECK_HI(extra_cfg, tile_rows, 6);
    383 
    384   RANGE_CHECK_HI(cfg, monochrome, 1);
    385 
    386   if (cfg->large_scale_tile && extra_cfg->aq_mode)
    387     ERROR(
    388         "Adaptive quantization are not supported in large scale tile "
    389         "coding.");
    390 
    391   RANGE_CHECK_HI(extra_cfg, sharpness, 7);
    392   RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
    393   RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
    394   RANGE_CHECK_HI(extra_cfg, cq_level, 63);
    395   RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
    396   RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
    397   RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);
    398 
    399   // TODO(yaowu): remove this when ssim tuning is implemented for av1
    400   if (extra_cfg->tuning == AOM_TUNE_SSIM)
    401     ERROR("Option --tune=ssim is not currently supported in AV1.");
    402 
    403   if (cfg->g_pass == AOM_RC_LAST_PASS) {
    404     const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    405     const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
    406     const FIRSTPASS_STATS *stats;
    407 
    408     if (cfg->rc_twopass_stats_in.buf == NULL)
    409       ERROR("rc_twopass_stats_in.buf not set.");
    410 
    411     if (cfg->rc_twopass_stats_in.sz % packet_sz)
    412       ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
    413 
    414     if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
    415       ERROR("rc_twopass_stats_in requires at least two packets.");
    416 
    417     stats =
    418         (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
    419 
    420     if ((int)(stats->count + 0.5) != n_packets - 1)
    421       ERROR("rc_twopass_stats_in missing EOS stats packet");
    422   }
    423 
    424   if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
    425       cfg->g_bit_depth > AOM_BITS_10) {
    426     ERROR("Codec bit-depth 12 not supported in profile < 2");
    427   }
    428   if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
    429       cfg->g_input_bit_depth > 10) {
    430     ERROR("Source bit-depth 12 not supported in profile < 2");
    431   }
    432 
    433   RANGE_CHECK(extra_cfg, color_primaries, AOM_CICP_CP_BT_709,
    434               AOM_CICP_CP_EBU_3213);  // Need to check range more precisely to
    435                                       // check for reserved values?
    436   RANGE_CHECK(extra_cfg, transfer_characteristics, AOM_CICP_TC_BT_709,
    437               AOM_CICP_TC_HLG);
    438   RANGE_CHECK(extra_cfg, matrix_coefficients, AOM_CICP_MC_IDENTITY,
    439               AOM_CICP_MC_ICTCP);
    440   RANGE_CHECK(extra_cfg, color_range, 0, 1);
    441 
    442 #if CONFIG_DIST_8X8
    443   RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_DAALA_DIST);
    444 #else
    445   RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_SSIM);
    446 #endif
    447 
    448   RANGE_CHECK(extra_cfg, timing_info_type, AOM_TIMING_UNSPECIFIED,
    449               AOM_TIMING_DEC_MODEL);
    450 
    451   RANGE_CHECK(extra_cfg, film_grain_test_vector, 0, 16);
    452 
    453   if (extra_cfg->lossless) {
    454     if (extra_cfg->aq_mode != 0)
    455       ERROR("Only --aq_mode=0 can be used with --lossless=1.");
    456 #if CONFIG_DIST_8X8
    457     if (extra_cfg->enable_dist_8x8)
    458       ERROR("dist-8x8 cannot be used with lossless compression.");
    459 #endif
    460   }
    461 
    462   RANGE_CHECK(extra_cfg, max_reference_frames, 3, 7);
    463   RANGE_CHECK(extra_cfg, enable_reduced_reference_set, 0, 1);
    464   RANGE_CHECK_HI(extra_cfg, chroma_subsampling_x, 1);
    465   RANGE_CHECK_HI(extra_cfg, chroma_subsampling_y, 1);
    466 
    467   RANGE_CHECK_HI(extra_cfg, disable_trellis_quant, 3);
    468   RANGE_CHECK(extra_cfg, coeff_cost_upd_freq, 0, 2);
    469   RANGE_CHECK(extra_cfg, mode_cost_upd_freq, 0, 2);
    470 
    471   RANGE_CHECK(extra_cfg, min_partition_size, 4, 128);
    472   RANGE_CHECK(extra_cfg, max_partition_size, 4, 128);
    473   RANGE_CHECK_HI(extra_cfg, min_partition_size, extra_cfg->max_partition_size);
    474 
    475   RANGE_CHECK(extra_cfg, tx_size_search_method, 0, 2);
    476 
    477   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
    478     if (!is_valid_seq_level_idx(extra_cfg->target_seq_level_idx[i]))
    479       ERROR("Target sequence level index is invalid");
    480   }
    481 
    482   return AOM_CODEC_OK;
    483 }
    484 
    485 static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
    486                                     const aom_image_t *img) {
    487   switch (img->fmt) {
    488     case AOM_IMG_FMT_YV12:
    489     case AOM_IMG_FMT_I420:
    490     case AOM_IMG_FMT_YV1216:
    491     case AOM_IMG_FMT_I42016: break;
    492     case AOM_IMG_FMT_I444:
    493     case AOM_IMG_FMT_I44416:
    494       if (ctx->cfg.g_profile == (unsigned int)PROFILE_0 &&
    495           !ctx->cfg.monochrome) {
    496         ERROR("Invalid image format. I444 images not supported in profile.");
    497       }
    498       break;
    499     case AOM_IMG_FMT_I422:
    500     case AOM_IMG_FMT_I42216:
    501       if (ctx->cfg.g_profile != (unsigned int)PROFILE_2) {
    502         ERROR("Invalid image format. I422 images not supported in profile.");
    503       }
    504       break;
    505     default:
    506       ERROR(
    507           "Invalid image format. Only YV12, I420, I422, I444 images are "
    508           "supported.");
    509       break;
    510   }
    511 
    512   if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
    513     ERROR("Image size must match encoder init configuration size");
    514 
    515   return AOM_CODEC_OK;
    516 }
    517 
    518 static int get_image_bps(const aom_image_t *img) {
    519   switch (img->fmt) {
    520     case AOM_IMG_FMT_YV12:
    521     case AOM_IMG_FMT_I420: return 12;
    522     case AOM_IMG_FMT_I422: return 16;
    523     case AOM_IMG_FMT_I444: return 24;
    524     case AOM_IMG_FMT_YV1216:
    525     case AOM_IMG_FMT_I42016: return 24;
    526     case AOM_IMG_FMT_I42216: return 32;
    527     case AOM_IMG_FMT_I44416: return 48;
    528     default: assert(0 && "Invalid image format"); break;
    529   }
    530   return 0;
    531 }
    532 
    533 // Set appropriate options to disable frame super-resolution.
    534 static void disable_superres(AV1EncoderConfig *const oxcf) {
    535   oxcf->superres_mode = SUPERRES_NONE;
    536   oxcf->superres_scale_denominator = SCALE_NUMERATOR;
    537   oxcf->superres_kf_scale_denominator = SCALE_NUMERATOR;
    538   oxcf->superres_qthresh = 255;
    539   oxcf->superres_kf_qthresh = 255;
    540 }
    541 
    542 static aom_codec_err_t set_encoder_config(
    543     AV1EncoderConfig *oxcf, const aom_codec_enc_cfg_t *cfg,
    544     const struct av1_extracfg *extra_cfg) {
    545   const int is_vbr = cfg->rc_end_usage == AOM_VBR;
    546   oxcf->profile = cfg->g_profile;
    547   oxcf->fwd_kf_enabled = cfg->fwd_kf_enabled;
    548   oxcf->max_threads = (int)cfg->g_threads;
    549   oxcf->mode = (cfg->g_usage == 1) ? REALTIME : GOOD;
    550   oxcf->width = cfg->g_w;
    551   oxcf->height = cfg->g_h;
    552   oxcf->forced_max_frame_width = cfg->g_forced_max_frame_width;
    553   oxcf->forced_max_frame_height = cfg->g_forced_max_frame_height;
    554   oxcf->bit_depth = cfg->g_bit_depth;
    555   oxcf->input_bit_depth = cfg->g_input_bit_depth;
    556   // guess a frame rate if out of whack, use 30
    557   oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
    558   if (extra_cfg->timing_info_type == AOM_TIMING_EQUAL ||
    559       extra_cfg->timing_info_type == AOM_TIMING_DEC_MODEL) {
    560     oxcf->timing_info_present = 1;
    561     oxcf->timing_info.num_units_in_display_tick = cfg->g_timebase.num;
    562     oxcf->timing_info.time_scale = cfg->g_timebase.den;
    563     oxcf->timing_info.num_ticks_per_picture = 1;
    564   } else {
    565     oxcf->timing_info_present = 0;
    566   }
    567   if (extra_cfg->timing_info_type == AOM_TIMING_EQUAL) {
    568     oxcf->timing_info.equal_picture_interval = 1;
    569     oxcf->decoder_model_info_present_flag = 0;
    570     oxcf->display_model_info_present_flag = 1;
    571   } else if (extra_cfg->timing_info_type == AOM_TIMING_DEC_MODEL) {
    572     //    if( extra_cfg->arnr_strength > 0 )
    573     //    {
    574     //      printf("Only --arnr-strength=0 can currently be used with
    575     //      --timing-info=model."); return AOM_CODEC_INVALID_PARAM;
    576     //    }
    577     //    if( extra_cfg->enable_superres)
    578     //    {
    579     //      printf("Only --superres-mode=0 can currently be used with
    580     //      --timing-info=model."); return AOM_CODEC_INVALID_PARAM;
    581     //    }
    582     oxcf->buffer_model.num_units_in_decoding_tick = cfg->g_timebase.num;
    583     oxcf->timing_info.equal_picture_interval = 0;
    584     oxcf->decoder_model_info_present_flag = 1;
    585     oxcf->buffer_removal_time_present = 1;
    586     oxcf->display_model_info_present_flag = 1;
    587   }
    588   if (oxcf->init_framerate > 180) {
    589     oxcf->init_framerate = 30;
    590     oxcf->timing_info_present = 0;
    591   }
    592   oxcf->cfg = &cfg->cfg;
    593 
    594   switch (cfg->g_pass) {
    595     case AOM_RC_ONE_PASS: oxcf->pass = 0; break;
    596     case AOM_RC_FIRST_PASS: oxcf->pass = 1; break;
    597     case AOM_RC_LAST_PASS: oxcf->pass = 2; break;
    598   }
    599 
    600   oxcf->lag_in_frames =
    601       cfg->g_pass == AOM_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
    602   oxcf->rc_mode = cfg->rc_end_usage;
    603 
    604   // Convert target bandwidth from Kbit/s to Bit/s
    605   oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
    606   oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
    607   oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
    608   oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
    609 
    610   oxcf->best_allowed_q =
    611       extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
    612   oxcf->worst_allowed_q =
    613       extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_max_quantizer);
    614   oxcf->cq_level = av1_quantizer_to_qindex(extra_cfg->cq_level);
    615   oxcf->fixed_q = -1;
    616 
    617   oxcf->enable_cdef = extra_cfg->enable_cdef;
    618   oxcf->enable_restoration = extra_cfg->enable_restoration;
    619   oxcf->enable_obmc = extra_cfg->enable_obmc;
    620   oxcf->enable_palette = extra_cfg->enable_palette;
    621   oxcf->enable_intrabc = extra_cfg->enable_intrabc;
    622   oxcf->enable_angle_delta = extra_cfg->enable_angle_delta;
    623   oxcf->disable_trellis_quant = extra_cfg->disable_trellis_quant;
    624   oxcf->using_qm = extra_cfg->enable_qm;
    625   oxcf->qm_y = extra_cfg->qm_y;
    626   oxcf->qm_u = extra_cfg->qm_u;
    627   oxcf->qm_v = extra_cfg->qm_v;
    628   oxcf->qm_minlevel = extra_cfg->qm_min;
    629   oxcf->qm_maxlevel = extra_cfg->qm_max;
    630   oxcf->reduced_tx_type_set = extra_cfg->reduced_tx_type_set;
    631   oxcf->use_intra_dct_only = extra_cfg->use_intra_dct_only;
    632   oxcf->use_inter_dct_only = extra_cfg->use_inter_dct_only;
    633   oxcf->use_intra_default_tx_only = extra_cfg->use_intra_default_tx_only;
    634   oxcf->quant_b_adapt = extra_cfg->quant_b_adapt;
    635   oxcf->coeff_cost_upd_freq = (COST_UPDATE_TYPE)extra_cfg->coeff_cost_upd_freq;
    636   oxcf->mode_cost_upd_freq = (COST_UPDATE_TYPE)extra_cfg->mode_cost_upd_freq;
    637 #if CONFIG_DIST_8X8
    638   oxcf->using_dist_8x8 = extra_cfg->enable_dist_8x8;
    639   if (extra_cfg->tuning == AOM_TUNE_CDEF_DIST ||
    640       extra_cfg->tuning == AOM_TUNE_DAALA_DIST)
    641     oxcf->using_dist_8x8 = 1;
    642 #endif
    643   oxcf->num_tile_groups = extra_cfg->num_tg;
    644   // In large-scale tile encoding mode, num_tile_groups is always 1.
    645   if (cfg->large_scale_tile) oxcf->num_tile_groups = 1;
    646   oxcf->mtu = extra_cfg->mtu_size;
    647 
    648   // FIXME(debargha): Should this be:
    649   // oxcf->allow_ref_frame_mvs = extra_cfg->allow_ref_frame_mvs &
    650   //                             extra_cfg->enable_order_hint ?
    651   // Disallow using temporal MVs while large_scale_tile = 1.
    652   oxcf->allow_ref_frame_mvs =
    653       extra_cfg->allow_ref_frame_mvs && !cfg->large_scale_tile;
    654   oxcf->under_shoot_pct = cfg->rc_undershoot_pct;
    655   oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
    656 
    657   oxcf->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
    658   oxcf->resize_scale_denominator = (uint8_t)cfg->rc_resize_denominator;
    659   oxcf->resize_kf_scale_denominator = (uint8_t)cfg->rc_resize_kf_denominator;
    660   if (oxcf->resize_mode == RESIZE_FIXED &&
    661       oxcf->resize_scale_denominator == SCALE_NUMERATOR &&
    662       oxcf->resize_kf_scale_denominator == SCALE_NUMERATOR)
    663     oxcf->resize_mode = RESIZE_NONE;
    664 
    665   if (extra_cfg->lossless || cfg->large_scale_tile) {
    666     disable_superres(oxcf);
    667   } else {
    668     oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode;
    669     oxcf->superres_scale_denominator = (uint8_t)cfg->rc_superres_denominator;
    670     oxcf->superres_kf_scale_denominator =
    671         (uint8_t)cfg->rc_superres_kf_denominator;
    672     oxcf->superres_qthresh = av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
    673     oxcf->superres_kf_qthresh =
    674         av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh);
    675     if (oxcf->superres_mode == SUPERRES_FIXED &&
    676         oxcf->superres_scale_denominator == SCALE_NUMERATOR &&
    677         oxcf->superres_kf_scale_denominator == SCALE_NUMERATOR) {
    678       disable_superres(oxcf);
    679     }
    680     if (oxcf->superres_mode == SUPERRES_QTHRESH &&
    681         oxcf->superres_qthresh == 255 && oxcf->superres_kf_qthresh == 255) {
    682       disable_superres(oxcf);
    683     }
    684   }
    685 
    686   oxcf->enable_tpl_model =
    687       extra_cfg->enable_tpl_model && (oxcf->superres_mode == SUPERRES_NONE);
    688 
    689   oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
    690   oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
    691   oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
    692 
    693   oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh;
    694 
    695   oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct;
    696   oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
    697   oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
    698 
    699   oxcf->auto_key =
    700       cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
    701 
    702   oxcf->key_freq = cfg->kf_max_dist;
    703   oxcf->sframe_dist = cfg->sframe_dist;
    704   oxcf->sframe_mode = cfg->sframe_mode;
    705   oxcf->sframe_enabled = cfg->sframe_dist != 0;
    706   oxcf->speed = extra_cfg->cpu_used;
    707   oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
    708   oxcf->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
    709   oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
    710   oxcf->sharpness = extra_cfg->sharpness;
    711 
    712   oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in;
    713 
    714   oxcf->color_primaries = extra_cfg->color_primaries;
    715   oxcf->transfer_characteristics = extra_cfg->transfer_characteristics;
    716   oxcf->matrix_coefficients = extra_cfg->matrix_coefficients;
    717   oxcf->chroma_sample_position = extra_cfg->chroma_sample_position;
    718 
    719   oxcf->color_range = extra_cfg->color_range;
    720   oxcf->render_width = extra_cfg->render_width;
    721   oxcf->render_height = extra_cfg->render_height;
    722   oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
    723   // Adjust g_lag_in_frames down if not needed
    724   oxcf->lag_in_frames =
    725       AOMMIN(MAX_GF_INTERVAL + oxcf->arnr_max_frames / 2, oxcf->lag_in_frames);
    726   oxcf->arnr_strength = extra_cfg->arnr_strength;
    727   oxcf->min_gf_interval = extra_cfg->min_gf_interval;
    728   oxcf->max_gf_interval = extra_cfg->max_gf_interval;
    729   oxcf->gf_max_pyr_height = extra_cfg->gf_max_pyr_height;
    730 
    731   oxcf->tuning = extra_cfg->tuning;
    732   oxcf->content = extra_cfg->content;
    733   oxcf->cdf_update_mode = (uint8_t)extra_cfg->cdf_update_mode;
    734   oxcf->superblock_size = extra_cfg->superblock_size;
    735   if (cfg->large_scale_tile) {
    736     oxcf->film_grain_test_vector = 0;
    737     oxcf->film_grain_table_filename = NULL;
    738   } else {
    739     oxcf->film_grain_test_vector = extra_cfg->film_grain_test_vector;
    740     oxcf->film_grain_table_filename = extra_cfg->film_grain_table_filename;
    741   }
    742 #if CONFIG_DENOISE
    743   oxcf->noise_level = extra_cfg->noise_level;
    744   oxcf->noise_block_size = extra_cfg->noise_block_size;
    745 #endif
    746   oxcf->large_scale_tile = cfg->large_scale_tile;
    747   oxcf->single_tile_decoding =
    748       (oxcf->large_scale_tile) ? extra_cfg->single_tile_decoding : 0;
    749   if (oxcf->large_scale_tile) {
    750     // The superblock_size can only be AOM_SUPERBLOCK_SIZE_64X64 or
    751     // AOM_SUPERBLOCK_SIZE_128X128 while oxcf->large_scale_tile = 1. If
    752     // superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC, hard set it to
    753     // AOM_SUPERBLOCK_SIZE_64X64(default value in large_scale_tile).
    754     if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64 &&
    755         extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_128X128)
    756       oxcf->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
    757   }
    758 
    759   oxcf->row_mt = extra_cfg->row_mt;
    760 
    761   oxcf->tile_columns = extra_cfg->tile_columns;
    762   oxcf->tile_rows = extra_cfg->tile_rows;
    763 
    764   oxcf->monochrome = cfg->monochrome;
    765   oxcf->full_still_picture_hdr = cfg->full_still_picture_hdr;
    766   oxcf->enable_dual_filter = extra_cfg->enable_dual_filter;
    767   oxcf->enable_rect_partitions = extra_cfg->enable_rect_partitions;
    768   oxcf->enable_ab_partitions = extra_cfg->enable_ab_partitions;
    769   oxcf->enable_1to4_partitions = extra_cfg->enable_1to4_partitions;
    770   oxcf->min_partition_size = extra_cfg->min_partition_size;
    771   oxcf->max_partition_size = extra_cfg->max_partition_size;
    772   oxcf->enable_intra_edge_filter = extra_cfg->enable_intra_edge_filter;
    773   oxcf->enable_tx64 = extra_cfg->enable_tx64;
    774   oxcf->tx_size_search_method = extra_cfg->tx_size_search_method;
    775   oxcf->enable_flip_idtx = extra_cfg->enable_flip_idtx;
    776   oxcf->enable_order_hint = extra_cfg->enable_order_hint;
    777   oxcf->enable_dist_wtd_comp =
    778       extra_cfg->enable_dist_wtd_comp & extra_cfg->enable_order_hint;
    779   oxcf->max_reference_frames = extra_cfg->max_reference_frames;
    780   oxcf->enable_reduced_reference_set = extra_cfg->enable_reduced_reference_set;
    781   oxcf->enable_masked_comp = extra_cfg->enable_masked_comp;
    782   oxcf->enable_onesided_comp = extra_cfg->enable_onesided_comp;
    783   oxcf->enable_diff_wtd_comp =
    784       extra_cfg->enable_masked_comp & extra_cfg->enable_diff_wtd_comp;
    785   oxcf->enable_interinter_wedge =
    786       extra_cfg->enable_masked_comp & extra_cfg->enable_interinter_wedge;
    787   oxcf->enable_interintra_comp = extra_cfg->enable_interintra_comp;
    788   oxcf->enable_smooth_interintra =
    789       extra_cfg->enable_interintra_comp && extra_cfg->enable_smooth_interintra;
    790   oxcf->enable_interintra_wedge =
    791       extra_cfg->enable_interintra_comp & extra_cfg->enable_interintra_wedge;
    792   oxcf->enable_ref_frame_mvs =
    793       extra_cfg->enable_ref_frame_mvs & extra_cfg->enable_order_hint;
    794 
    795   oxcf->enable_global_motion = extra_cfg->enable_global_motion;
    796   oxcf->enable_warped_motion = extra_cfg->enable_warped_motion;
    797   oxcf->allow_warped_motion =
    798       extra_cfg->allow_warped_motion & extra_cfg->enable_warped_motion;
    799   oxcf->enable_filter_intra = extra_cfg->enable_filter_intra;
    800   oxcf->enable_smooth_intra = extra_cfg->enable_smooth_intra;
    801   oxcf->enable_paeth_intra = extra_cfg->enable_paeth_intra;
    802   oxcf->enable_cfl_intra = extra_cfg->enable_cfl_intra;
    803 
    804   oxcf->enable_superres =
    805       (oxcf->superres_mode != SUPERRES_NONE) && extra_cfg->enable_superres;
    806   if (!oxcf->enable_superres) {
    807     disable_superres(oxcf);
    808   }
    809 
    810   oxcf->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS);
    811   oxcf->tile_height_count = AOMMIN(cfg->tile_height_count, MAX_TILE_ROWS);
    812   for (int i = 0; i < oxcf->tile_width_count; i++) {
    813     oxcf->tile_widths[i] = AOMMAX(cfg->tile_widths[i], 1);
    814   }
    815   for (int i = 0; i < oxcf->tile_height_count; i++) {
    816     oxcf->tile_heights[i] = AOMMAX(cfg->tile_heights[i], 1);
    817   }
    818   oxcf->error_resilient_mode =
    819       cfg->g_error_resilient | extra_cfg->error_resilient_mode;
    820   oxcf->s_frame_mode = extra_cfg->s_frame_mode;
    821   oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
    822   if (cfg->g_pass == AOM_RC_LAST_PASS) {
    823     const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    824     const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
    825     oxcf->limit = n_packets - 1;
    826   } else {
    827     oxcf->limit = cfg->g_limit;
    828   }
    829 
    830   if (oxcf->limit == 1) {
    831     // still picture mode, display model and timing is meaningless
    832     oxcf->display_model_info_present_flag = 0;
    833     oxcf->timing_info_present = 0;
    834   }
    835 
    836   oxcf->aq_mode = extra_cfg->aq_mode;
    837   oxcf->deltaq_mode = extra_cfg->deltaq_mode;
    838 
    839   oxcf->save_as_annexb = cfg->save_as_annexb;
    840 
    841   oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
    842   oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test;
    843 
    844   oxcf->chroma_subsampling_x = extra_cfg->chroma_subsampling_x;
    845   oxcf->chroma_subsampling_y = extra_cfg->chroma_subsampling_y;
    846   oxcf->border_in_pixels = (oxcf->resize_mode || oxcf->superres_mode)
    847                                ? AOM_BORDER_IN_PIXELS
    848                                : AOM_ENC_NO_SCALE_BORDER;
    849   memcpy(oxcf->target_seq_level_idx, extra_cfg->target_seq_level_idx,
    850          sizeof(oxcf->target_seq_level_idx));
    851   oxcf->tier_mask = extra_cfg->tier_mask;
    852   return AOM_CODEC_OK;
    853 }
    854 
    855 static aom_codec_err_t encoder_set_config(aom_codec_alg_priv_t *ctx,
    856                                           const aom_codec_enc_cfg_t *cfg) {
    857   aom_codec_err_t res;
    858   int force_key = 0;
    859 
    860   if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) {
    861     if (cfg->g_lag_in_frames > 1 || cfg->g_pass != AOM_RC_ONE_PASS)
    862       ERROR("Cannot change width or height after initialization");
    863     if (!valid_ref_frame_size(ctx->cfg.g_w, ctx->cfg.g_h, cfg->g_w, cfg->g_h) ||
    864         (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) ||
    865         (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height))
    866       force_key = 1;
    867   }
    868 
    869   // Prevent increasing lag_in_frames. This check is stricter than it needs
    870   // to be -- the limit is not increasing past the first lag_in_frames
    871   // value, but we don't track the initial config, only the last successful
    872   // config.
    873   if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
    874     ERROR("Cannot increase lag_in_frames");
    875 
    876   res = validate_config(ctx, cfg, &ctx->extra_cfg);
    877 
    878   if (res == AOM_CODEC_OK) {
    879     ctx->cfg = *cfg;
    880     set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
    881     // On profile change, request a key frame
    882     force_key |= ctx->cpi->common.seq_params.profile != ctx->oxcf.profile;
    883     av1_change_config(ctx->cpi, &ctx->oxcf);
    884   }
    885 
    886   if (force_key) ctx->next_frame_flags |= AOM_EFLAG_FORCE_KF;
    887 
    888   return res;
    889 }
    890 
    891 static aom_fixed_buf_t *encoder_get_global_headers(aom_codec_alg_priv_t *ctx) {
    892   return av1_get_global_headers(ctx->cpi);
    893 }
    894 
    895 static aom_codec_err_t ctrl_get_quantizer(aom_codec_alg_priv_t *ctx,
    896                                           va_list args) {
    897   int *const arg = va_arg(args, int *);
    898   if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
    899   *arg = av1_get_quantizer(ctx->cpi);
    900   return AOM_CODEC_OK;
    901 }
    902 
    903 static aom_codec_err_t ctrl_get_quantizer64(aom_codec_alg_priv_t *ctx,
    904                                             va_list args) {
    905   int *const arg = va_arg(args, int *);
    906   if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
    907   *arg = av1_qindex_to_quantizer(av1_get_quantizer(ctx->cpi));
    908   return AOM_CODEC_OK;
    909 }
    910 
    911 static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
    912                                         const struct av1_extracfg *extra_cfg) {
    913   const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
    914   if (res == AOM_CODEC_OK) {
    915     ctx->extra_cfg = *extra_cfg;
    916     set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
    917     av1_change_config(ctx->cpi, &ctx->oxcf);
    918   }
    919   return res;
    920 }
    921 
    922 static aom_codec_err_t ctrl_set_cpuused(aom_codec_alg_priv_t *ctx,
    923                                         va_list args) {
    924   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    925   extra_cfg.cpu_used = CAST(AOME_SET_CPUUSED, args);
    926   return update_extra_cfg(ctx, &extra_cfg);
    927 }
    928 
    929 static aom_codec_err_t ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t *ctx,
    930                                                     va_list args) {
    931   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    932   extra_cfg.enable_auto_alt_ref = CAST(AOME_SET_ENABLEAUTOALTREF, args);
    933   return update_extra_cfg(ctx, &extra_cfg);
    934 }
    935 
    936 static aom_codec_err_t ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t *ctx,
    937                                                     va_list args) {
    938   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    939   extra_cfg.enable_auto_bwd_ref = CAST(AOME_SET_ENABLEAUTOBWDREF, args);
    940   return update_extra_cfg(ctx, &extra_cfg);
    941 }
    942 
    943 static aom_codec_err_t ctrl_set_noise_sensitivity(aom_codec_alg_priv_t *ctx,
    944                                                   va_list args) {
    945   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    946   extra_cfg.noise_sensitivity = CAST(AV1E_SET_NOISE_SENSITIVITY, args);
    947   return update_extra_cfg(ctx, &extra_cfg);
    948 }
    949 
    950 static aom_codec_err_t ctrl_set_sharpness(aom_codec_alg_priv_t *ctx,
    951                                           va_list args) {
    952   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    953   extra_cfg.sharpness = CAST(AOME_SET_SHARPNESS, args);
    954   return update_extra_cfg(ctx, &extra_cfg);
    955 }
    956 
    957 static aom_codec_err_t ctrl_set_static_thresh(aom_codec_alg_priv_t *ctx,
    958                                               va_list args) {
    959   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    960   extra_cfg.static_thresh = CAST(AOME_SET_STATIC_THRESHOLD, args);
    961   return update_extra_cfg(ctx, &extra_cfg);
    962 }
    963 
    964 static aom_codec_err_t ctrl_set_row_mt(aom_codec_alg_priv_t *ctx,
    965                                        va_list args) {
    966   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    967   extra_cfg.row_mt = CAST(AV1E_SET_ROW_MT, args);
    968   return update_extra_cfg(ctx, &extra_cfg);
    969 }
    970 
    971 static aom_codec_err_t ctrl_set_tile_columns(aom_codec_alg_priv_t *ctx,
    972                                              va_list args) {
    973   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    974   extra_cfg.tile_columns = CAST(AV1E_SET_TILE_COLUMNS, args);
    975   return update_extra_cfg(ctx, &extra_cfg);
    976 }
    977 
    978 static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
    979                                           va_list args) {
    980   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    981   extra_cfg.tile_rows = CAST(AV1E_SET_TILE_ROWS, args);
    982   return update_extra_cfg(ctx, &extra_cfg);
    983 }
    984 
    985 static aom_codec_err_t ctrl_set_enable_tpl_model(aom_codec_alg_priv_t *ctx,
    986                                                  va_list args) {
    987   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    988   extra_cfg.enable_tpl_model = CAST(AV1E_SET_ENABLE_TPL_MODEL, args);
    989   return update_extra_cfg(ctx, &extra_cfg);
    990 }
    991 
    992 static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
    993                                                 va_list args) {
    994   struct av1_extracfg extra_cfg = ctx->extra_cfg;
    995   extra_cfg.arnr_max_frames = CAST(AOME_SET_ARNR_MAXFRAMES, args);
    996   return update_extra_cfg(ctx, &extra_cfg);
    997 }
    998 
    999 static aom_codec_err_t ctrl_set_arnr_strength(aom_codec_alg_priv_t *ctx,
   1000                                               va_list args) {
   1001   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1002   extra_cfg.arnr_strength = CAST(AOME_SET_ARNR_STRENGTH, args);
   1003   return update_extra_cfg(ctx, &extra_cfg);
   1004 }
   1005 
   1006 static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx,
   1007                                        va_list args) {
   1008   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1009   extra_cfg.tuning = CAST(AOME_SET_TUNING, args);
   1010   return update_extra_cfg(ctx, &extra_cfg);
   1011 }
   1012 
   1013 static aom_codec_err_t ctrl_set_cq_level(aom_codec_alg_priv_t *ctx,
   1014                                          va_list args) {
   1015   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1016   extra_cfg.cq_level = CAST(AOME_SET_CQ_LEVEL, args);
   1017   return update_extra_cfg(ctx, &extra_cfg);
   1018 }
   1019 
   1020 static aom_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
   1021     aom_codec_alg_priv_t *ctx, va_list args) {
   1022   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1023   extra_cfg.rc_max_intra_bitrate_pct =
   1024       CAST(AOME_SET_MAX_INTRA_BITRATE_PCT, args);
   1025   return update_extra_cfg(ctx, &extra_cfg);
   1026 }
   1027 
   1028 static aom_codec_err_t ctrl_set_rc_max_inter_bitrate_pct(
   1029     aom_codec_alg_priv_t *ctx, va_list args) {
   1030   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1031   extra_cfg.rc_max_inter_bitrate_pct =
   1032       CAST(AOME_SET_MAX_INTER_BITRATE_PCT, args);
   1033   return update_extra_cfg(ctx, &extra_cfg);
   1034 }
   1035 
   1036 static aom_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t *ctx,
   1037                                                     va_list args) {
   1038   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1039   extra_cfg.gf_cbr_boost_pct = CAST(AV1E_SET_GF_CBR_BOOST_PCT, args);
   1040   return update_extra_cfg(ctx, &extra_cfg);
   1041 }
   1042 
   1043 static aom_codec_err_t ctrl_set_lossless(aom_codec_alg_priv_t *ctx,
   1044                                          va_list args) {
   1045   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1046   extra_cfg.lossless = CAST(AV1E_SET_LOSSLESS, args);
   1047   return update_extra_cfg(ctx, &extra_cfg);
   1048 }
   1049 
   1050 static aom_codec_err_t ctrl_set_enable_cdef(aom_codec_alg_priv_t *ctx,
   1051                                             va_list args) {
   1052   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1053   extra_cfg.enable_cdef = CAST(AV1E_SET_ENABLE_CDEF, args);
   1054   return update_extra_cfg(ctx, &extra_cfg);
   1055 }
   1056 
   1057 static aom_codec_err_t ctrl_set_enable_restoration(aom_codec_alg_priv_t *ctx,
   1058                                                    va_list args) {
   1059   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1060   extra_cfg.enable_restoration = CAST(AV1E_SET_ENABLE_RESTORATION, args);
   1061   return update_extra_cfg(ctx, &extra_cfg);
   1062 }
   1063 
   1064 static aom_codec_err_t ctrl_set_enable_obmc(aom_codec_alg_priv_t *ctx,
   1065                                             va_list args) {
   1066   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1067   extra_cfg.enable_obmc = CAST(AV1E_SET_ENABLE_OBMC, args);
   1068   return update_extra_cfg(ctx, &extra_cfg);
   1069 }
   1070 
   1071 static aom_codec_err_t ctrl_set_disable_trellis_quant(aom_codec_alg_priv_t *ctx,
   1072                                                       va_list args) {
   1073   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1074   extra_cfg.disable_trellis_quant = CAST(AV1E_SET_DISABLE_TRELLIS_QUANT, args);
   1075   return update_extra_cfg(ctx, &extra_cfg);
   1076 }
   1077 
   1078 static aom_codec_err_t ctrl_set_enable_qm(aom_codec_alg_priv_t *ctx,
   1079                                           va_list args) {
   1080   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1081   extra_cfg.enable_qm = CAST(AV1E_SET_ENABLE_QM, args);
   1082   return update_extra_cfg(ctx, &extra_cfg);
   1083 }
   1084 static aom_codec_err_t ctrl_set_qm_y(aom_codec_alg_priv_t *ctx, va_list args) {
   1085   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1086   extra_cfg.qm_y = CAST(AV1E_SET_QM_Y, args);
   1087   return update_extra_cfg(ctx, &extra_cfg);
   1088 }
   1089 static aom_codec_err_t ctrl_set_qm_u(aom_codec_alg_priv_t *ctx, va_list args) {
   1090   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1091   extra_cfg.qm_u = CAST(AV1E_SET_QM_U, args);
   1092   return update_extra_cfg(ctx, &extra_cfg);
   1093 }
   1094 static aom_codec_err_t ctrl_set_qm_v(aom_codec_alg_priv_t *ctx, va_list args) {
   1095   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1096   extra_cfg.qm_v = CAST(AV1E_SET_QM_V, args);
   1097   return update_extra_cfg(ctx, &extra_cfg);
   1098 }
   1099 static aom_codec_err_t ctrl_set_qm_min(aom_codec_alg_priv_t *ctx,
   1100                                        va_list args) {
   1101   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1102   extra_cfg.qm_min = CAST(AV1E_SET_QM_MIN, args);
   1103   return update_extra_cfg(ctx, &extra_cfg);
   1104 }
   1105 
   1106 static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
   1107                                        va_list args) {
   1108   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1109   extra_cfg.qm_max = CAST(AV1E_SET_QM_MAX, args);
   1110   return update_extra_cfg(ctx, &extra_cfg);
   1111 }
   1112 #if CONFIG_DIST_8X8
   1113 static aom_codec_err_t ctrl_set_enable_dist_8x8(aom_codec_alg_priv_t *ctx,
   1114                                                 va_list args) {
   1115   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1116   extra_cfg.enable_dist_8x8 = CAST(AV1E_SET_ENABLE_DIST_8X8, args);
   1117   return update_extra_cfg(ctx, &extra_cfg);
   1118 }
   1119 #endif
   1120 static aom_codec_err_t ctrl_set_num_tg(aom_codec_alg_priv_t *ctx,
   1121                                        va_list args) {
   1122   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1123   extra_cfg.num_tg = CAST(AV1E_SET_NUM_TG, args);
   1124   return update_extra_cfg(ctx, &extra_cfg);
   1125 }
   1126 
   1127 static aom_codec_err_t ctrl_set_mtu(aom_codec_alg_priv_t *ctx, va_list args) {
   1128   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1129   extra_cfg.mtu_size = CAST(AV1E_SET_MTU, args);
   1130   return update_extra_cfg(ctx, &extra_cfg);
   1131 }
   1132 static aom_codec_err_t ctrl_set_timing_info_type(aom_codec_alg_priv_t *ctx,
   1133                                                  va_list args) {
   1134   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1135   extra_cfg.timing_info_type = CAST(AV1E_SET_TIMING_INFO_TYPE, args);
   1136   return update_extra_cfg(ctx, &extra_cfg);
   1137 }
   1138 
   1139 static aom_codec_err_t ctrl_set_enable_dual_filter(aom_codec_alg_priv_t *ctx,
   1140                                                    va_list args) {
   1141   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1142   extra_cfg.enable_dual_filter = CAST(AV1E_SET_ENABLE_DUAL_FILTER, args);
   1143   return update_extra_cfg(ctx, &extra_cfg);
   1144 }
   1145 
   1146 static aom_codec_err_t ctrl_set_enable_rect_partitions(
   1147     aom_codec_alg_priv_t *ctx, va_list args) {
   1148   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1149   extra_cfg.enable_rect_partitions =
   1150       CAST(AV1E_SET_ENABLE_RECT_PARTITIONS, args);
   1151   return update_extra_cfg(ctx, &extra_cfg);
   1152 }
   1153 
   1154 static aom_codec_err_t ctrl_set_enable_ab_partitions(aom_codec_alg_priv_t *ctx,
   1155                                                      va_list args) {
   1156   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1157   extra_cfg.enable_ab_partitions = CAST(AV1E_SET_ENABLE_AB_PARTITIONS, args);
   1158   return update_extra_cfg(ctx, &extra_cfg);
   1159 }
   1160 
   1161 static aom_codec_err_t ctrl_set_enable_1to4_partitions(
   1162     aom_codec_alg_priv_t *ctx, va_list args) {
   1163   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1164   extra_cfg.enable_1to4_partitions =
   1165       CAST(AV1E_SET_ENABLE_1TO4_PARTITIONS, args);
   1166   return update_extra_cfg(ctx, &extra_cfg);
   1167 }
   1168 
   1169 static aom_codec_err_t ctrl_set_min_partition_size(aom_codec_alg_priv_t *ctx,
   1170                                                    va_list args) {
   1171   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1172   extra_cfg.min_partition_size = CAST(AV1E_SET_MIN_PARTITION_SIZE, args);
   1173   return update_extra_cfg(ctx, &extra_cfg);
   1174 }
   1175 
   1176 static aom_codec_err_t ctrl_set_max_partition_size(aom_codec_alg_priv_t *ctx,
   1177                                                    va_list args) {
   1178   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1179   extra_cfg.max_partition_size = CAST(AV1E_SET_MAX_PARTITION_SIZE, args);
   1180   return update_extra_cfg(ctx, &extra_cfg);
   1181 }
   1182 
   1183 static aom_codec_err_t ctrl_set_enable_intra_edge_filter(
   1184     aom_codec_alg_priv_t *ctx, va_list args) {
   1185   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1186   extra_cfg.enable_intra_edge_filter =
   1187       CAST(AV1E_SET_ENABLE_INTRA_EDGE_FILTER, args);
   1188   return update_extra_cfg(ctx, &extra_cfg);
   1189 }
   1190 
   1191 static aom_codec_err_t ctrl_set_enable_order_hint(aom_codec_alg_priv_t *ctx,
   1192                                                   va_list args) {
   1193   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1194   extra_cfg.enable_order_hint = CAST(AV1E_SET_ENABLE_ORDER_HINT, args);
   1195   return update_extra_cfg(ctx, &extra_cfg);
   1196 }
   1197 
   1198 static aom_codec_err_t ctrl_set_enable_tx64(aom_codec_alg_priv_t *ctx,
   1199                                             va_list args) {
   1200   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1201   extra_cfg.enable_tx64 = CAST(AV1E_SET_ENABLE_TX64, args);
   1202   return update_extra_cfg(ctx, &extra_cfg);
   1203 }
   1204 
   1205 static aom_codec_err_t ctrl_set_tx_size_search_method(aom_codec_alg_priv_t *ctx,
   1206                                                       va_list args) {
   1207   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1208   extra_cfg.tx_size_search_method = CAST(AV1E_SET_TX_SIZE_SEARCH_METHOD, args);
   1209   return update_extra_cfg(ctx, &extra_cfg);
   1210 }
   1211 
   1212 static aom_codec_err_t ctrl_set_enable_flip_idtx(aom_codec_alg_priv_t *ctx,
   1213                                                  va_list args) {
   1214   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1215   extra_cfg.enable_flip_idtx = CAST(AV1E_SET_ENABLE_FLIP_IDTX, args);
   1216   return update_extra_cfg(ctx, &extra_cfg);
   1217 }
   1218 
   1219 static aom_codec_err_t ctrl_set_enable_dist_wtd_comp(aom_codec_alg_priv_t *ctx,
   1220                                                      va_list args) {
   1221   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1222   extra_cfg.enable_dist_wtd_comp = CAST(AV1E_SET_ENABLE_DIST_WTD_COMP, args);
   1223   return update_extra_cfg(ctx, &extra_cfg);
   1224 }
   1225 
   1226 static aom_codec_err_t ctrl_set_max_reference_frames(aom_codec_alg_priv_t *ctx,
   1227                                                      va_list args) {
   1228   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1229   extra_cfg.max_reference_frames = CAST(AV1E_SET_MAX_REFERENCE_FRAMES, args);
   1230   return update_extra_cfg(ctx, &extra_cfg);
   1231 }
   1232 
   1233 static aom_codec_err_t ctrl_set_enable_reduced_reference_set(
   1234     aom_codec_alg_priv_t *ctx, va_list args) {
   1235   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1236   extra_cfg.enable_reduced_reference_set =
   1237       CAST(AV1E_SET_REDUCED_REFERENCE_SET, args);
   1238   return update_extra_cfg(ctx, &extra_cfg);
   1239 }
   1240 
   1241 static aom_codec_err_t ctrl_set_enable_ref_frame_mvs(aom_codec_alg_priv_t *ctx,
   1242                                                      va_list args) {
   1243   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1244   extra_cfg.enable_ref_frame_mvs = CAST(AV1E_SET_ENABLE_REF_FRAME_MVS, args);
   1245   return update_extra_cfg(ctx, &extra_cfg);
   1246 }
   1247 
   1248 static aom_codec_err_t ctrl_set_allow_ref_frame_mvs(aom_codec_alg_priv_t *ctx,
   1249                                                     va_list args) {
   1250   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1251   extra_cfg.allow_ref_frame_mvs = CAST(AV1E_SET_ALLOW_REF_FRAME_MVS, args);
   1252   return update_extra_cfg(ctx, &extra_cfg);
   1253 }
   1254 
   1255 static aom_codec_err_t ctrl_set_enable_masked_comp(aom_codec_alg_priv_t *ctx,
   1256                                                    va_list args) {
   1257   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1258   extra_cfg.enable_masked_comp = CAST(AV1E_SET_ENABLE_MASKED_COMP, args);
   1259   return update_extra_cfg(ctx, &extra_cfg);
   1260 }
   1261 
   1262 static aom_codec_err_t ctrl_set_enable_onesided_comp(aom_codec_alg_priv_t *ctx,
   1263                                                      va_list args) {
   1264   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1265   extra_cfg.enable_onesided_comp = CAST(AV1E_SET_ENABLE_ONESIDED_COMP, args);
   1266   return update_extra_cfg(ctx, &extra_cfg);
   1267 }
   1268 
   1269 static aom_codec_err_t ctrl_set_enable_interintra_comp(
   1270     aom_codec_alg_priv_t *ctx, va_list args) {
   1271   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1272   extra_cfg.enable_interintra_comp =
   1273       CAST(AV1E_SET_ENABLE_INTERINTRA_COMP, args);
   1274   return update_extra_cfg(ctx, &extra_cfg);
   1275 }
   1276 
   1277 static aom_codec_err_t ctrl_set_enable_smooth_interintra(
   1278     aom_codec_alg_priv_t *ctx, va_list args) {
   1279   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1280   extra_cfg.enable_smooth_interintra =
   1281       CAST(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, args);
   1282   return update_extra_cfg(ctx, &extra_cfg);
   1283 }
   1284 
   1285 static aom_codec_err_t ctrl_set_enable_diff_wtd_comp(aom_codec_alg_priv_t *ctx,
   1286                                                      va_list args) {
   1287   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1288   extra_cfg.enable_diff_wtd_comp = CAST(AV1E_SET_ENABLE_DIFF_WTD_COMP, args);
   1289   return update_extra_cfg(ctx, &extra_cfg);
   1290 }
   1291 
   1292 static aom_codec_err_t ctrl_set_enable_interinter_wedge(
   1293     aom_codec_alg_priv_t *ctx, va_list args) {
   1294   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1295   extra_cfg.enable_interinter_wedge =
   1296       CAST(AV1E_SET_ENABLE_INTERINTER_WEDGE, args);
   1297   return update_extra_cfg(ctx, &extra_cfg);
   1298 }
   1299 
   1300 static aom_codec_err_t ctrl_set_enable_interintra_wedge(
   1301     aom_codec_alg_priv_t *ctx, va_list args) {
   1302   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1303   extra_cfg.enable_interintra_wedge =
   1304       CAST(AV1E_SET_ENABLE_INTERINTRA_WEDGE, args);
   1305   return update_extra_cfg(ctx, &extra_cfg);
   1306 }
   1307 
   1308 static aom_codec_err_t ctrl_set_enable_global_motion(aom_codec_alg_priv_t *ctx,
   1309                                                      va_list args) {
   1310   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1311   extra_cfg.enable_global_motion = CAST(AV1E_SET_ENABLE_GLOBAL_MOTION, args);
   1312   return update_extra_cfg(ctx, &extra_cfg);
   1313 }
   1314 
   1315 static aom_codec_err_t ctrl_set_enable_warped_motion(aom_codec_alg_priv_t *ctx,
   1316                                                      va_list args) {
   1317   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1318   extra_cfg.enable_warped_motion = CAST(AV1E_SET_ENABLE_WARPED_MOTION, args);
   1319   return update_extra_cfg(ctx, &extra_cfg);
   1320 }
   1321 
   1322 static aom_codec_err_t ctrl_set_allow_warped_motion(aom_codec_alg_priv_t *ctx,
   1323                                                     va_list args) {
   1324   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1325   extra_cfg.allow_warped_motion = CAST(AV1E_SET_ALLOW_WARPED_MOTION, args);
   1326   return update_extra_cfg(ctx, &extra_cfg);
   1327 }
   1328 
   1329 static aom_codec_err_t ctrl_set_enable_filter_intra(aom_codec_alg_priv_t *ctx,
   1330                                                     va_list args) {
   1331   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1332   extra_cfg.enable_filter_intra = CAST(AV1E_SET_ENABLE_FILTER_INTRA, args);
   1333   return update_extra_cfg(ctx, &extra_cfg);
   1334 }
   1335 
   1336 static aom_codec_err_t ctrl_set_enable_smooth_intra(aom_codec_alg_priv_t *ctx,
   1337                                                     va_list args) {
   1338   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1339   extra_cfg.enable_smooth_intra = CAST(AV1E_SET_ENABLE_SMOOTH_INTRA, args);
   1340   return update_extra_cfg(ctx, &extra_cfg);
   1341 }
   1342 
   1343 static aom_codec_err_t ctrl_set_enable_paeth_intra(aom_codec_alg_priv_t *ctx,
   1344                                                    va_list args) {
   1345   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1346   extra_cfg.enable_paeth_intra = CAST(AV1E_SET_ENABLE_PAETH_INTRA, args);
   1347   return update_extra_cfg(ctx, &extra_cfg);
   1348 }
   1349 
   1350 static aom_codec_err_t ctrl_set_enable_cfl_intra(aom_codec_alg_priv_t *ctx,
   1351                                                  va_list args) {
   1352   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1353   extra_cfg.enable_cfl_intra = CAST(AV1E_SET_ENABLE_CFL_INTRA, args);
   1354   return update_extra_cfg(ctx, &extra_cfg);
   1355 }
   1356 
   1357 static aom_codec_err_t ctrl_set_enable_superres(aom_codec_alg_priv_t *ctx,
   1358                                                 va_list args) {
   1359   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1360   extra_cfg.enable_superres = CAST(AV1E_SET_ENABLE_SUPERRES, args);
   1361   return update_extra_cfg(ctx, &extra_cfg);
   1362 }
   1363 
   1364 static aom_codec_err_t ctrl_set_enable_palette(aom_codec_alg_priv_t *ctx,
   1365                                                va_list args) {
   1366   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1367   extra_cfg.enable_palette = CAST(AV1E_SET_ENABLE_PALETTE, args);
   1368   return update_extra_cfg(ctx, &extra_cfg);
   1369 }
   1370 
   1371 static aom_codec_err_t ctrl_set_enable_intrabc(aom_codec_alg_priv_t *ctx,
   1372                                                va_list args) {
   1373   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1374   extra_cfg.enable_intrabc = CAST(AV1E_SET_ENABLE_INTRABC, args);
   1375   return update_extra_cfg(ctx, &extra_cfg);
   1376 }
   1377 
   1378 static aom_codec_err_t ctrl_set_enable_angle_delta(aom_codec_alg_priv_t *ctx,
   1379                                                    va_list args) {
   1380   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1381   extra_cfg.enable_angle_delta = CAST(AV1E_SET_ENABLE_ANGLE_DELTA, args);
   1382   return update_extra_cfg(ctx, &extra_cfg);
   1383 }
   1384 
   1385 static aom_codec_err_t ctrl_set_error_resilient_mode(aom_codec_alg_priv_t *ctx,
   1386                                                      va_list args) {
   1387   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1388   extra_cfg.error_resilient_mode = CAST(AV1E_SET_ERROR_RESILIENT_MODE, args);
   1389   return update_extra_cfg(ctx, &extra_cfg);
   1390 }
   1391 
   1392 static aom_codec_err_t ctrl_set_s_frame_mode(aom_codec_alg_priv_t *ctx,
   1393                                              va_list args) {
   1394   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1395   extra_cfg.s_frame_mode = CAST(AV1E_SET_S_FRAME_MODE, args);
   1396   return update_extra_cfg(ctx, &extra_cfg);
   1397 }
   1398 
   1399 static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
   1400     aom_codec_alg_priv_t *ctx, va_list args) {
   1401   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1402   extra_cfg.frame_parallel_decoding_mode =
   1403       CAST(AV1E_SET_FRAME_PARALLEL_DECODING, args);
   1404   return update_extra_cfg(ctx, &extra_cfg);
   1405 }
   1406 
   1407 static aom_codec_err_t ctrl_set_single_tile_decoding(aom_codec_alg_priv_t *ctx,
   1408                                                      va_list args) {
   1409   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1410   extra_cfg.single_tile_decoding = CAST(AV1E_SET_SINGLE_TILE_DECODING, args);
   1411   return update_extra_cfg(ctx, &extra_cfg);
   1412 }
   1413 
   1414 static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
   1415                                         va_list args) {
   1416   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1417   extra_cfg.aq_mode = CAST(AV1E_SET_AQ_MODE, args);
   1418   return update_extra_cfg(ctx, &extra_cfg);
   1419 }
   1420 
   1421 static aom_codec_err_t ctrl_set_reduced_tx_type_set(aom_codec_alg_priv_t *ctx,
   1422                                                     va_list args) {
   1423   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1424   extra_cfg.reduced_tx_type_set = CAST(AV1E_SET_REDUCED_TX_TYPE_SET, args);
   1425   return update_extra_cfg(ctx, &extra_cfg);
   1426 }
   1427 
   1428 static aom_codec_err_t ctrl_set_intra_dct_only(aom_codec_alg_priv_t *ctx,
   1429                                                va_list args) {
   1430   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1431   extra_cfg.use_intra_dct_only = CAST(AV1E_SET_INTRA_DCT_ONLY, args);
   1432   return update_extra_cfg(ctx, &extra_cfg);
   1433 }
   1434 
   1435 static aom_codec_err_t ctrl_set_inter_dct_only(aom_codec_alg_priv_t *ctx,
   1436                                                va_list args) {
   1437   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1438   extra_cfg.use_inter_dct_only = CAST(AV1E_SET_INTER_DCT_ONLY, args);
   1439   return update_extra_cfg(ctx, &extra_cfg);
   1440 }
   1441 
   1442 static aom_codec_err_t ctrl_set_intra_default_tx_only(aom_codec_alg_priv_t *ctx,
   1443                                                       va_list args) {
   1444   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1445   extra_cfg.use_intra_default_tx_only =
   1446       CAST(AV1E_SET_INTRA_DEFAULT_TX_ONLY, args);
   1447   return update_extra_cfg(ctx, &extra_cfg);
   1448 }
   1449 
   1450 static aom_codec_err_t ctrl_set_quant_b_adapt(aom_codec_alg_priv_t *ctx,
   1451                                               va_list args) {
   1452   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1453   extra_cfg.quant_b_adapt = CAST(AV1E_SET_QUANT_B_ADAPT, args);
   1454   return update_extra_cfg(ctx, &extra_cfg);
   1455 }
   1456 
   1457 static aom_codec_err_t ctrl_set_coeff_cost_upd_freq(aom_codec_alg_priv_t *ctx,
   1458                                                     va_list args) {
   1459   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1460   extra_cfg.coeff_cost_upd_freq = CAST(AV1E_SET_COEFF_COST_UPD_FREQ, args);
   1461   return update_extra_cfg(ctx, &extra_cfg);
   1462 }
   1463 
   1464 static aom_codec_err_t ctrl_set_mode_cost_upd_freq(aom_codec_alg_priv_t *ctx,
   1465                                                    va_list args) {
   1466   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1467   extra_cfg.mode_cost_upd_freq = CAST(AV1E_SET_MODE_COST_UPD_FREQ, args);
   1468   return update_extra_cfg(ctx, &extra_cfg);
   1469 }
   1470 
   1471 static aom_codec_err_t ctrl_set_film_grain_test_vector(
   1472     aom_codec_alg_priv_t *ctx, va_list args) {
   1473   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1474   extra_cfg.film_grain_test_vector =
   1475       CAST(AV1E_SET_FILM_GRAIN_TEST_VECTOR, args);
   1476   return update_extra_cfg(ctx, &extra_cfg);
   1477 }
   1478 
   1479 static aom_codec_err_t ctrl_set_film_grain_table(aom_codec_alg_priv_t *ctx,
   1480                                                  va_list args) {
   1481   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1482   extra_cfg.film_grain_table_filename = CAST(AV1E_SET_FILM_GRAIN_TABLE, args);
   1483   return update_extra_cfg(ctx, &extra_cfg);
   1484 }
   1485 
   1486 #if CONFIG_DENOISE
   1487 static aom_codec_err_t ctrl_set_denoise_noise_level(aom_codec_alg_priv_t *ctx,
   1488                                                     va_list args) {
   1489   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1490   extra_cfg.noise_level =
   1491       ((float)CAST(AV1E_SET_DENOISE_NOISE_LEVEL, args)) / 10.0f;
   1492   return update_extra_cfg(ctx, &extra_cfg);
   1493 }
   1494 
   1495 static aom_codec_err_t ctrl_set_denoise_block_size(aom_codec_alg_priv_t *ctx,
   1496                                                    va_list args) {
   1497   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1498   extra_cfg.noise_block_size = CAST(AV1E_SET_DENOISE_BLOCK_SIZE, args);
   1499   return update_extra_cfg(ctx, &extra_cfg);
   1500 }
   1501 #endif
   1502 
   1503 static aom_codec_err_t ctrl_set_deltaq_mode(aom_codec_alg_priv_t *ctx,
   1504                                             va_list args) {
   1505   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1506   extra_cfg.deltaq_mode = CAST(AV1E_SET_DELTAQ_MODE, args);
   1507   return update_extra_cfg(ctx, &extra_cfg);
   1508 }
   1509 
   1510 static aom_codec_err_t ctrl_set_min_gf_interval(aom_codec_alg_priv_t *ctx,
   1511                                                 va_list args) {
   1512   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1513   extra_cfg.min_gf_interval = CAST(AV1E_SET_MIN_GF_INTERVAL, args);
   1514   return update_extra_cfg(ctx, &extra_cfg);
   1515 }
   1516 
   1517 static aom_codec_err_t ctrl_set_max_gf_interval(aom_codec_alg_priv_t *ctx,
   1518                                                 va_list args) {
   1519   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1520   extra_cfg.max_gf_interval = CAST(AV1E_SET_MAX_GF_INTERVAL, args);
   1521   return update_extra_cfg(ctx, &extra_cfg);
   1522 }
   1523 
   1524 static aom_codec_err_t ctrl_set_gf_max_pyr_height(aom_codec_alg_priv_t *ctx,
   1525                                                   va_list args) {
   1526   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1527   extra_cfg.gf_max_pyr_height = CAST(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, args);
   1528   return update_extra_cfg(ctx, &extra_cfg);
   1529 }
   1530 
   1531 static aom_codec_err_t ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t *ctx,
   1532                                                      va_list args) {
   1533   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1534   extra_cfg.frame_periodic_boost = CAST(AV1E_SET_FRAME_PERIODIC_BOOST, args);
   1535   return update_extra_cfg(ctx, &extra_cfg);
   1536 }
   1537 
   1538 static aom_codec_err_t ctrl_enable_motion_vector_unit_test(
   1539     aom_codec_alg_priv_t *ctx, va_list args) {
   1540   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1541   extra_cfg.motion_vector_unit_test =
   1542       CAST(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, args);
   1543   return update_extra_cfg(ctx, &extra_cfg);
   1544 }
   1545 
   1546 static aom_codec_err_t ctrl_set_target_seq_level_idx(aom_codec_alg_priv_t *ctx,
   1547                                                      va_list args) {
   1548   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1549   const int val = CAST(AV1E_SET_TARGET_SEQ_LEVEL_IDX, args);
   1550   const int level = val % 100;
   1551   const int operating_point_idx = val / 100;
   1552   if (operating_point_idx >= 0 &&
   1553       operating_point_idx < MAX_NUM_OPERATING_POINTS) {
   1554     extra_cfg.target_seq_level_idx[operating_point_idx] = (AV1_LEVEL)level;
   1555   }
   1556   return update_extra_cfg(ctx, &extra_cfg);
   1557 }
   1558 
   1559 static aom_codec_err_t ctrl_set_tier_mask(aom_codec_alg_priv_t *ctx,
   1560                                           va_list args) {
   1561   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   1562   extra_cfg.tier_mask = CAST(AV1E_SET_TIER_MASK, args);
   1563   return update_extra_cfg(ctx, &extra_cfg);
   1564 }
   1565 
   1566 static aom_codec_err_t encoder_init(aom_codec_ctx_t *ctx,
   1567                                     aom_codec_priv_enc_mr_cfg_t *data) {
   1568   aom_codec_err_t res = AOM_CODEC_OK;
   1569   (void)data;
   1570 
   1571   if (ctx->priv == NULL) {
   1572     aom_codec_alg_priv_t *const priv = aom_calloc(1, sizeof(*priv));
   1573     if (priv == NULL) return AOM_CODEC_MEM_ERROR;
   1574 
   1575     ctx->priv = (aom_codec_priv_t *)priv;
   1576     ctx->priv->init_flags = ctx->init_flags;
   1577     ctx->priv->enc.total_encoders = 1;
   1578     priv->buffer_pool = (BufferPool *)aom_calloc(1, sizeof(BufferPool));
   1579     if (priv->buffer_pool == NULL) return AOM_CODEC_MEM_ERROR;
   1580 
   1581 #if CONFIG_MULTITHREAD
   1582     if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
   1583       return AOM_CODEC_MEM_ERROR;
   1584     }
   1585 #endif
   1586 
   1587     if (ctx->config.enc) {
   1588       // Update the reference to the config structure to an internal copy.
   1589       priv->cfg = *ctx->config.enc;
   1590       ctx->config.enc = &priv->cfg;
   1591     }
   1592 
   1593     priv->extra_cfg = default_extra_cfg;
   1594     aom_once(av1_initialize_enc);
   1595 
   1596     res = validate_config(priv, &priv->cfg, &priv->extra_cfg);
   1597 
   1598     if (res == AOM_CODEC_OK) {
   1599       set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
   1600       priv->oxcf.use_highbitdepth =
   1601           (ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
   1602       priv->cpi = av1_create_compressor(&priv->oxcf, priv->buffer_pool);
   1603       if (priv->cpi == NULL)
   1604         res = AOM_CODEC_MEM_ERROR;
   1605       else
   1606         priv->cpi->output_pkt_list = &priv->pkt_list.head;
   1607     }
   1608   }
   1609 
   1610   return res;
   1611 }
   1612 
   1613 static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) {
   1614   free(ctx->cx_data);
   1615   av1_remove_compressor(ctx->cpi);
   1616 #if CONFIG_MULTITHREAD
   1617   pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
   1618 #endif
   1619   aom_free(ctx->buffer_pool);
   1620   aom_free(ctx);
   1621   return AOM_CODEC_OK;
   1622 }
   1623 
   1624 static aom_codec_frame_flags_t get_frame_pkt_flags(const AV1_COMP *cpi,
   1625                                                    unsigned int lib_flags) {
   1626   aom_codec_frame_flags_t flags = lib_flags << 16;
   1627 
   1628   if (lib_flags & FRAMEFLAGS_KEY) flags |= AOM_FRAME_IS_KEY;
   1629   if (lib_flags & FRAMEFLAGS_INTRAONLY) flags |= AOM_FRAME_IS_INTRAONLY;
   1630   if (lib_flags & FRAMEFLAGS_SWITCH) flags |= AOM_FRAME_IS_SWITCH;
   1631   if (lib_flags & FRAMEFLAGS_ERROR_RESILIENT)
   1632     flags |= AOM_FRAME_IS_ERROR_RESILIENT;
   1633   if (cpi->droppable) flags |= AOM_FRAME_IS_DROPPABLE;
   1634 
   1635   return flags;
   1636 }
   1637 
   1638 static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
   1639                                       const aom_image_t *img,
   1640                                       aom_codec_pts_t pts,
   1641                                       unsigned long duration,
   1642                                       aom_enc_frame_flags_t enc_flags) {
   1643   const size_t kMinCompressedSize = 8192;
   1644   volatile aom_codec_err_t res = AOM_CODEC_OK;
   1645   AV1_COMP *const cpi = ctx->cpi;
   1646   const aom_rational_t *const timebase = &ctx->cfg.g_timebase;
   1647 
   1648   if (cpi == NULL) return AOM_CODEC_INVALID_PARAM;
   1649 
   1650   if (img != NULL) {
   1651     res = validate_img(ctx, img);
   1652     // TODO(jzern) the checks related to cpi's validity should be treated as a
   1653     // failure condition, encoder setup is done fully in init() currently.
   1654     if (res == AOM_CODEC_OK) {
   1655       size_t data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
   1656                        ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img);
   1657       if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize;
   1658       if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) {
   1659         ctx->cx_data_sz = data_sz;
   1660         free(ctx->cx_data);
   1661         ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz);
   1662         if (ctx->cx_data == NULL) {
   1663           return AOM_CODEC_MEM_ERROR;
   1664         }
   1665       }
   1666     }
   1667   }
   1668   if (ctx->oxcf.mode != GOOD && ctx->oxcf.mode != REALTIME) {
   1669     ctx->oxcf.mode = GOOD;
   1670     av1_change_config(ctx->cpi, &ctx->oxcf);
   1671   }
   1672 
   1673   aom_codec_pkt_list_init(&ctx->pkt_list);
   1674 
   1675   volatile aom_enc_frame_flags_t flags = enc_flags;
   1676 
   1677   // The jmp_buf is valid only for the duration of the function that calls
   1678   // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
   1679   // before it returns.
   1680   if (setjmp(cpi->common.error.jmp)) {
   1681     cpi->common.error.setjmp = 0;
   1682     res = update_error_state(ctx, &cpi->common.error);
   1683     aom_clear_system_state();
   1684     return res;
   1685   }
   1686   cpi->common.error.setjmp = 1;
   1687 
   1688   // Note(yunqing): While applying encoding flags, always start from enabling
   1689   // all, and then modifying according to the flags. Previous frame's flags are
   1690   // overwritten.
   1691   av1_apply_encoding_flags(cpi, flags);
   1692 
   1693   // Handle fixed keyframe intervals
   1694   if (ctx->cfg.kf_mode == AOM_KF_AUTO &&
   1695       ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
   1696     if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
   1697       flags |= AOM_EFLAG_FORCE_KF;
   1698       ctx->fixed_kf_cntr = 1;
   1699     }
   1700   }
   1701 
   1702   if (res == AOM_CODEC_OK) {
   1703     int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts);
   1704     int64_t dst_end_time_stamp =
   1705         timebase_units_to_ticks(timebase, pts + duration);
   1706 
   1707     // Set up internal flags
   1708     if (ctx->base.init_flags & AOM_CODEC_USE_PSNR) cpi->b_calculate_psnr = 1;
   1709 
   1710     if (img != NULL) {
   1711       YV12_BUFFER_CONFIG sd;
   1712       res = image2yuvconfig(img, &sd);
   1713 
   1714       // Store the original flags in to the frame buffer. Will extract the
   1715       // key frame flag when we actually encode this frame.
   1716       if (av1_receive_raw_frame(cpi, flags | ctx->next_frame_flags, &sd,
   1717                                 dst_time_stamp, dst_end_time_stamp)) {
   1718         res = update_error_state(ctx, &cpi->common.error);
   1719       }
   1720       ctx->next_frame_flags = 0;
   1721     }
   1722 
   1723     unsigned char *cx_data = ctx->cx_data;
   1724     size_t cx_data_sz = ctx->cx_data_sz;
   1725 
   1726     assert(!(cx_data == NULL && cx_data_sz != 0));
   1727 
   1728     /* Any pending invisible frames? */
   1729     if (ctx->pending_cx_data) {
   1730       memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
   1731       ctx->pending_cx_data = cx_data;
   1732       cx_data += ctx->pending_cx_data_sz;
   1733       cx_data_sz -= ctx->pending_cx_data_sz;
   1734 
   1735       /* TODO: this is a minimal check, the underlying codec doesn't respect
   1736        * the buffer size anyway.
   1737        */
   1738       if (cx_data_sz < ctx->cx_data_sz / 2) {
   1739         aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR,
   1740                            "Compressed data buffer too small");
   1741       }
   1742     }
   1743 
   1744     size_t frame_size = 0;
   1745     unsigned int lib_flags = 0;
   1746     int is_frame_visible = 0;
   1747     int index_size = 0;
   1748     int has_fwd_keyframe = 0;
   1749     // invisible frames get packed with the next visible frame
   1750     while (cx_data_sz - index_size >= ctx->cx_data_sz / 2 &&
   1751            !is_frame_visible &&
   1752            -1 != av1_get_compressed_data(cpi, &lib_flags, &frame_size, cx_data,
   1753                                          &dst_time_stamp, &dst_end_time_stamp,
   1754                                          !img, timebase)) {
   1755       cpi->seq_params_locked = 1;
   1756       if (frame_size) {
   1757         if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
   1758 
   1759         const int write_temporal_delimiter =
   1760             !cpi->common.spatial_layer_id && !ctx->pending_frame_count;
   1761 
   1762         if (write_temporal_delimiter) {
   1763           uint32_t obu_header_size = 1;
   1764           const uint32_t obu_payload_size = 0;
   1765           const size_t length_field_size =
   1766               aom_uleb_size_in_bytes(obu_payload_size);
   1767 
   1768           if (ctx->pending_cx_data) {
   1769             const size_t move_offset = length_field_size + 1;
   1770             memmove(ctx->pending_cx_data + move_offset, ctx->pending_cx_data,
   1771                     frame_size);
   1772           }
   1773           const uint32_t obu_header_offset = 0;
   1774           obu_header_size = av1_write_obu_header(
   1775               cpi, OBU_TEMPORAL_DELIMITER, 0,
   1776               (uint8_t *)(ctx->pending_cx_data + obu_header_offset));
   1777 
   1778           // OBUs are preceded/succeeded by an unsigned leb128 coded integer.
   1779           if (write_uleb_obu_size(obu_header_size, obu_payload_size,
   1780                                   ctx->pending_cx_data) != AOM_CODEC_OK) {
   1781             aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR, NULL);
   1782           }
   1783 
   1784           frame_size += obu_header_size + obu_payload_size + length_field_size;
   1785         }
   1786 
   1787         if (ctx->oxcf.save_as_annexb) {
   1788           size_t curr_frame_size = frame_size;
   1789           if (av1_convert_sect5obus_to_annexb(cx_data, &curr_frame_size) !=
   1790               AOM_CODEC_OK) {
   1791             aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR, NULL);
   1792           }
   1793           frame_size = curr_frame_size;
   1794 
   1795           // B_PRIME (add frame size)
   1796           const size_t length_field_size = aom_uleb_size_in_bytes(frame_size);
   1797           if (ctx->pending_cx_data) {
   1798             const size_t move_offset = length_field_size;
   1799             memmove(cx_data + move_offset, cx_data, frame_size);
   1800           }
   1801           if (write_uleb_obu_size(0, (uint32_t)frame_size, cx_data) !=
   1802               AOM_CODEC_OK) {
   1803             aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR, NULL);
   1804           }
   1805           frame_size += length_field_size;
   1806         }
   1807 
   1808         ctx->pending_frame_sizes[ctx->pending_frame_count++] = frame_size;
   1809         ctx->pending_cx_data_sz += frame_size;
   1810 
   1811         cx_data += frame_size;
   1812         cx_data_sz -= frame_size;
   1813 
   1814         index_size = MAG_SIZE * (ctx->pending_frame_count - 1) + 2;
   1815 
   1816         is_frame_visible = cpi->common.show_frame;
   1817 
   1818         has_fwd_keyframe |= (!is_frame_visible &&
   1819                              cpi->common.current_frame.frame_type == KEY_FRAME);
   1820       }
   1821     }
   1822     if (is_frame_visible) {
   1823       // Add the frame packet to the list of returned packets.
   1824       aom_codec_cx_pkt_t pkt;
   1825 
   1826       if (ctx->oxcf.save_as_annexb) {
   1827         //  B_PRIME (add TU size)
   1828         size_t tu_size = ctx->pending_cx_data_sz;
   1829         const size_t length_field_size = aom_uleb_size_in_bytes(tu_size);
   1830         if (ctx->pending_cx_data) {
   1831           const size_t move_offset = length_field_size;
   1832           memmove(ctx->pending_cx_data + move_offset, ctx->pending_cx_data,
   1833                   tu_size);
   1834         }
   1835         if (write_uleb_obu_size(0, (uint32_t)tu_size, ctx->pending_cx_data) !=
   1836             AOM_CODEC_OK) {
   1837           aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR, NULL);
   1838         }
   1839         ctx->pending_cx_data_sz += length_field_size;
   1840       }
   1841 
   1842       pkt.kind = AOM_CODEC_CX_FRAME_PKT;
   1843 
   1844       pkt.data.frame.buf = ctx->pending_cx_data;
   1845       pkt.data.frame.sz = ctx->pending_cx_data_sz;
   1846       pkt.data.frame.partition_id = -1;
   1847       pkt.data.frame.vis_frame_size = frame_size;
   1848 
   1849       pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
   1850       pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
   1851       if (has_fwd_keyframe) {
   1852         // If one of the invisible frames in the packet is a keyframe, set
   1853         // the delayed random access point flag.
   1854         pkt.data.frame.flags |= AOM_FRAME_IS_DELAYED_RANDOM_ACCESS_POINT;
   1855       }
   1856       pkt.data.frame.duration = (uint32_t)ticks_to_timebase_units(
   1857           timebase, dst_end_time_stamp - dst_time_stamp);
   1858 
   1859       aom_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
   1860 
   1861       ctx->pending_cx_data = NULL;
   1862       ctx->pending_cx_data_sz = 0;
   1863       ctx->pending_frame_count = 0;
   1864     }
   1865   }
   1866 
   1867   cpi->common.error.setjmp = 0;
   1868   return res;
   1869 }
   1870 
   1871 static const aom_codec_cx_pkt_t *encoder_get_cxdata(aom_codec_alg_priv_t *ctx,
   1872                                                     aom_codec_iter_t *iter) {
   1873   return aom_codec_pkt_list_get(&ctx->pkt_list.head, iter);
   1874 }
   1875 
   1876 static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
   1877                                           va_list args) {
   1878   av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
   1879 
   1880   if (frame != NULL) {
   1881     YV12_BUFFER_CONFIG sd;
   1882 
   1883     image2yuvconfig(&frame->img, &sd);
   1884     av1_set_reference_enc(ctx->cpi, frame->idx, &sd);
   1885     return AOM_CODEC_OK;
   1886   } else {
   1887     return AOM_CODEC_INVALID_PARAM;
   1888   }
   1889 }
   1890 
   1891 static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
   1892                                            va_list args) {
   1893   av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
   1894 
   1895   if (frame != NULL) {
   1896     YV12_BUFFER_CONFIG sd;
   1897 
   1898     image2yuvconfig(&frame->img, &sd);
   1899     av1_copy_reference_enc(ctx->cpi, frame->idx, &sd);
   1900     return AOM_CODEC_OK;
   1901   } else {
   1902     return AOM_CODEC_INVALID_PARAM;
   1903   }
   1904 }
   1905 
   1906 static aom_codec_err_t ctrl_get_reference(aom_codec_alg_priv_t *ctx,
   1907                                           va_list args) {
   1908   av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
   1909 
   1910   if (frame != NULL) {
   1911     YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->cpi->common, frame->idx);
   1912     if (fb == NULL) return AOM_CODEC_ERROR;
   1913 
   1914     yuvconfig2image(&frame->img, fb, NULL);
   1915     return AOM_CODEC_OK;
   1916   } else {
   1917     return AOM_CODEC_INVALID_PARAM;
   1918   }
   1919 }
   1920 
   1921 static aom_codec_err_t ctrl_get_new_frame_image(aom_codec_alg_priv_t *ctx,
   1922                                                 va_list args) {
   1923   aom_image_t *const new_img = va_arg(args, aom_image_t *);
   1924 
   1925   if (new_img != NULL) {
   1926     YV12_BUFFER_CONFIG new_frame;
   1927 
   1928     if (av1_get_last_show_frame(ctx->cpi, &new_frame) == 0) {
   1929       yuvconfig2image(new_img, &new_frame, NULL);
   1930       return AOM_CODEC_OK;
   1931     } else {
   1932       return AOM_CODEC_ERROR;
   1933     }
   1934   } else {
   1935     return AOM_CODEC_INVALID_PARAM;
   1936   }
   1937 }
   1938 
   1939 static aom_codec_err_t ctrl_copy_new_frame_image(aom_codec_alg_priv_t *ctx,
   1940                                                  va_list args) {
   1941   aom_image_t *const new_img = va_arg(args, aom_image_t *);
   1942 
   1943   if (new_img != NULL) {
   1944     YV12_BUFFER_CONFIG new_frame;
   1945 
   1946     if (av1_get_last_show_frame(ctx->cpi, &new_frame) == 0) {
   1947       YV12_BUFFER_CONFIG sd;
   1948       image2yuvconfig(new_img, &sd);
   1949       return av1_copy_new_frame_enc(&ctx->cpi->common, &new_frame, &sd);
   1950     } else {
   1951       return AOM_CODEC_ERROR;
   1952     }
   1953   } else {
   1954     return AOM_CODEC_INVALID_PARAM;
   1955   }
   1956 }
   1957 
   1958 static aom_codec_err_t ctrl_set_previewpp(aom_codec_alg_priv_t *ctx,
   1959                                           va_list args) {
   1960   (void)ctx;
   1961   (void)args;
   1962   return AOM_CODEC_INCAPABLE;
   1963 }
   1964 
   1965 static aom_image_t *encoder_get_preview(aom_codec_alg_priv_t *ctx) {
   1966   YV12_BUFFER_CONFIG sd;
   1967 
   1968   if (av1_get_preview_raw_frame(ctx->cpi, &sd) == 0) {
   1969     yuvconfig2image(&ctx->preview_img, &sd, NULL);
   1970     return &ctx->preview_img;
   1971   } else {
   1972     return NULL;
   1973   }
   1974 }
   1975 
   1976 static aom_codec_err_t ctrl_use_reference(aom_codec_alg_priv_t *ctx,
   1977                                           va_list args) {
   1978   const int reference_flag = va_arg(args, int);
   1979 
   1980   av1_use_as_reference(ctx->cpi, reference_flag);
   1981   return AOM_CODEC_OK;
   1982 }
   1983 
   1984 static aom_codec_err_t ctrl_set_roi_map(aom_codec_alg_priv_t *ctx,
   1985                                         va_list args) {
   1986   (void)ctx;
   1987   (void)args;
   1988 
   1989   // TODO(yaowu): Need to re-implement and test for AV1.
   1990   return AOM_CODEC_INVALID_PARAM;
   1991 }
   1992 
   1993 static aom_codec_err_t ctrl_set_active_map(aom_codec_alg_priv_t *ctx,
   1994                                            va_list args) {
   1995   aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
   1996 
   1997   if (map) {
   1998     if (!av1_set_active_map(ctx->cpi, map->active_map, (int)map->rows,
   1999                             (int)map->cols))
   2000       return AOM_CODEC_OK;
   2001     else
   2002       return AOM_CODEC_INVALID_PARAM;
   2003   } else {
   2004     return AOM_CODEC_INVALID_PARAM;
   2005   }
   2006 }
   2007 
   2008 static aom_codec_err_t ctrl_get_active_map(aom_codec_alg_priv_t *ctx,
   2009                                            va_list args) {
   2010   aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
   2011 
   2012   if (map) {
   2013     if (!av1_get_active_map(ctx->cpi, map->active_map, (int)map->rows,
   2014                             (int)map->cols))
   2015       return AOM_CODEC_OK;
   2016     else
   2017       return AOM_CODEC_INVALID_PARAM;
   2018   } else {
   2019     return AOM_CODEC_INVALID_PARAM;
   2020   }
   2021 }
   2022 
   2023 static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
   2024                                            va_list args) {
   2025   aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
   2026 
   2027   if (mode) {
   2028     const int res =
   2029         av1_set_internal_size(ctx->cpi, (AOM_SCALING)mode->h_scaling_mode,
   2030                               (AOM_SCALING)mode->v_scaling_mode);
   2031     return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
   2032   } else {
   2033     return AOM_CODEC_INVALID_PARAM;
   2034   }
   2035 }
   2036 
   2037 static aom_codec_err_t ctrl_set_spatial_layer_id(aom_codec_alg_priv_t *ctx,
   2038                                                  va_list args) {
   2039   const int spatial_layer_id = va_arg(args, int);
   2040   if (spatial_layer_id > MAX_NUM_ENHANCEMENT_LAYERS)
   2041     return AOM_CODEC_INVALID_PARAM;
   2042   ctx->cpi->common.spatial_layer_id = spatial_layer_id;
   2043   return AOM_CODEC_OK;
   2044 }
   2045 
   2046 static aom_codec_err_t ctrl_set_number_spatial_layers(aom_codec_alg_priv_t *ctx,
   2047                                                       va_list args) {
   2048   const int number_spatial_layers = va_arg(args, int);
   2049   if (number_spatial_layers > MAX_NUM_ENHANCEMENT_LAYERS)
   2050     return AOM_CODEC_INVALID_PARAM;
   2051   ctx->cpi->common.number_spatial_layers = number_spatial_layers;
   2052   return AOM_CODEC_OK;
   2053 }
   2054 
   2055 static aom_codec_err_t ctrl_set_tune_content(aom_codec_alg_priv_t *ctx,
   2056                                              va_list args) {
   2057   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2058   extra_cfg.content = CAST(AV1E_SET_TUNE_CONTENT, args);
   2059   return update_extra_cfg(ctx, &extra_cfg);
   2060 }
   2061 
   2062 static aom_codec_err_t ctrl_set_cdf_update_mode(aom_codec_alg_priv_t *ctx,
   2063                                                 va_list args) {
   2064   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2065   extra_cfg.cdf_update_mode = CAST(AV1E_SET_CDF_UPDATE_MODE, args);
   2066   return update_extra_cfg(ctx, &extra_cfg);
   2067 }
   2068 
   2069 static aom_codec_err_t ctrl_set_color_primaries(aom_codec_alg_priv_t *ctx,
   2070                                                 va_list args) {
   2071   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2072   extra_cfg.color_primaries = CAST(AV1E_SET_COLOR_PRIMARIES, args);
   2073   return update_extra_cfg(ctx, &extra_cfg);
   2074 }
   2075 
   2076 static aom_codec_err_t ctrl_set_transfer_characteristics(
   2077     aom_codec_alg_priv_t *ctx, va_list args) {
   2078   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2079   extra_cfg.transfer_characteristics =
   2080       CAST(AV1E_SET_TRANSFER_CHARACTERISTICS, args);
   2081   return update_extra_cfg(ctx, &extra_cfg);
   2082 }
   2083 
   2084 static aom_codec_err_t ctrl_set_matrix_coefficients(aom_codec_alg_priv_t *ctx,
   2085                                                     va_list args) {
   2086   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2087   extra_cfg.matrix_coefficients = CAST(AV1E_SET_MATRIX_COEFFICIENTS, args);
   2088   return update_extra_cfg(ctx, &extra_cfg);
   2089 }
   2090 
   2091 static aom_codec_err_t ctrl_set_chroma_sample_position(
   2092     aom_codec_alg_priv_t *ctx, va_list args) {
   2093   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2094   extra_cfg.chroma_sample_position =
   2095       CAST(AV1E_SET_CHROMA_SAMPLE_POSITION, args);
   2096   return update_extra_cfg(ctx, &extra_cfg);
   2097 }
   2098 
   2099 static aom_codec_err_t ctrl_set_color_range(aom_codec_alg_priv_t *ctx,
   2100                                             va_list args) {
   2101   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2102   extra_cfg.color_range = CAST(AV1E_SET_COLOR_RANGE, args);
   2103   return update_extra_cfg(ctx, &extra_cfg);
   2104 }
   2105 
   2106 static aom_codec_err_t ctrl_set_render_size(aom_codec_alg_priv_t *ctx,
   2107                                             va_list args) {
   2108   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2109   int *const render_size = va_arg(args, int *);
   2110   extra_cfg.render_width = render_size[0];
   2111   extra_cfg.render_height = render_size[1];
   2112   return update_extra_cfg(ctx, &extra_cfg);
   2113 }
   2114 
   2115 static aom_codec_err_t ctrl_set_superblock_size(aom_codec_alg_priv_t *ctx,
   2116                                                 va_list args) {
   2117   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2118   extra_cfg.superblock_size = CAST(AV1E_SET_SUPERBLOCK_SIZE, args);
   2119   return update_extra_cfg(ctx, &extra_cfg);
   2120 }
   2121 
   2122 static aom_codec_err_t ctrl_set_chroma_subsampling_x(aom_codec_alg_priv_t *ctx,
   2123                                                      va_list args) {
   2124   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2125   extra_cfg.chroma_subsampling_x = CAST(AV1E_SET_CHROMA_SUBSAMPLING_X, args);
   2126   return update_extra_cfg(ctx, &extra_cfg);
   2127 }
   2128 
   2129 static aom_codec_err_t ctrl_set_chroma_subsampling_y(aom_codec_alg_priv_t *ctx,
   2130                                                      va_list args) {
   2131   struct av1_extracfg extra_cfg = ctx->extra_cfg;
   2132   extra_cfg.chroma_subsampling_y = CAST(AV1E_SET_CHROMA_SUBSAMPLING_Y, args);
   2133   return update_extra_cfg(ctx, &extra_cfg);
   2134 }
   2135 
   2136 static aom_codec_err_t ctrl_get_seq_level_idx(aom_codec_alg_priv_t *ctx,
   2137                                               va_list args) {
   2138   int *const arg = va_arg(args, int *);
   2139   if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
   2140   return av1_get_seq_level_idx(ctx->cpi, arg);
   2141 }
   2142 
   2143 static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
   2144   { AV1_COPY_REFERENCE, ctrl_copy_reference },
   2145   { AOME_USE_REFERENCE, ctrl_use_reference },
   2146 
   2147   // Setters
   2148   { AV1_SET_REFERENCE, ctrl_set_reference },
   2149   { AOM_SET_POSTPROC, ctrl_set_previewpp },
   2150   { AOME_SET_ROI_MAP, ctrl_set_roi_map },
   2151   { AOME_SET_ACTIVEMAP, ctrl_set_active_map },
   2152   { AOME_SET_SCALEMODE, ctrl_set_scale_mode },
   2153   { AOME_SET_SPATIAL_LAYER_ID, ctrl_set_spatial_layer_id },
   2154   { AOME_SET_CPUUSED, ctrl_set_cpuused },
   2155   { AOME_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref },
   2156   { AOME_SET_ENABLEAUTOBWDREF, ctrl_set_enable_auto_bwd_ref },
   2157   { AOME_SET_SHARPNESS, ctrl_set_sharpness },
   2158   { AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
   2159   { AV1E_SET_ROW_MT, ctrl_set_row_mt },
   2160   { AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
   2161   { AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
   2162   { AV1E_SET_ENABLE_TPL_MODEL, ctrl_set_enable_tpl_model },
   2163   { AOME_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
   2164   { AOME_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
   2165   { AOME_SET_TUNING, ctrl_set_tuning },
   2166   { AOME_SET_CQ_LEVEL, ctrl_set_cq_level },
   2167   { AOME_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct },
   2168   { AOME_SET_NUMBER_SPATIAL_LAYERS, ctrl_set_number_spatial_layers },
   2169   { AV1E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct },
   2170   { AV1E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct },
   2171   { AV1E_SET_LOSSLESS, ctrl_set_lossless },
   2172   { AV1E_SET_ENABLE_CDEF, ctrl_set_enable_cdef },
   2173   { AV1E_SET_ENABLE_RESTORATION, ctrl_set_enable_restoration },
   2174   { AV1E_SET_ENABLE_OBMC, ctrl_set_enable_obmc },
   2175   { AV1E_SET_DISABLE_TRELLIS_QUANT, ctrl_set_disable_trellis_quant },
   2176   { AV1E_SET_ENABLE_QM, ctrl_set_enable_qm },
   2177   { AV1E_SET_QM_Y, ctrl_set_qm_y },
   2178   { AV1E_SET_QM_U, ctrl_set_qm_u },
   2179   { AV1E_SET_QM_V, ctrl_set_qm_v },
   2180   { AV1E_SET_QM_MIN, ctrl_set_qm_min },
   2181   { AV1E_SET_QM_MAX, ctrl_set_qm_max },
   2182 #if CONFIG_DIST_8X8
   2183   { AV1E_SET_ENABLE_DIST_8X8, ctrl_set_enable_dist_8x8 },
   2184 #endif
   2185   { AV1E_SET_NUM_TG, ctrl_set_num_tg },
   2186   { AV1E_SET_MTU, ctrl_set_mtu },
   2187   { AV1E_SET_TIMING_INFO_TYPE, ctrl_set_timing_info_type },
   2188   { AV1E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode },
   2189   { AV1E_SET_ERROR_RESILIENT_MODE, ctrl_set_error_resilient_mode },
   2190   { AV1E_SET_S_FRAME_MODE, ctrl_set_s_frame_mode },
   2191   { AV1E_SET_ENABLE_RECT_PARTITIONS, ctrl_set_enable_rect_partitions },
   2192   { AV1E_SET_ENABLE_AB_PARTITIONS, ctrl_set_enable_ab_partitions },
   2193   { AV1E_SET_ENABLE_1TO4_PARTITIONS, ctrl_set_enable_1to4_partitions },
   2194   { AV1E_SET_MIN_PARTITION_SIZE, ctrl_set_min_partition_size },
   2195   { AV1E_SET_MAX_PARTITION_SIZE, ctrl_set_max_partition_size },
   2196   { AV1E_SET_ENABLE_DUAL_FILTER, ctrl_set_enable_dual_filter },
   2197   { AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctrl_set_enable_intra_edge_filter },
   2198   { AV1E_SET_ENABLE_ORDER_HINT, ctrl_set_enable_order_hint },
   2199   { AV1E_SET_ENABLE_TX64, ctrl_set_enable_tx64 },
   2200   { AV1E_SET_TX_SIZE_SEARCH_METHOD, ctrl_set_tx_size_search_method },
   2201   { AV1E_SET_ENABLE_FLIP_IDTX, ctrl_set_enable_flip_idtx },
   2202   { AV1E_SET_ENABLE_DIST_WTD_COMP, ctrl_set_enable_dist_wtd_comp },
   2203   { AV1E_SET_MAX_REFERENCE_FRAMES, ctrl_set_max_reference_frames },
   2204   { AV1E_SET_REDUCED_REFERENCE_SET, ctrl_set_enable_reduced_reference_set },
   2205   { AV1E_SET_ENABLE_REF_FRAME_MVS, ctrl_set_enable_ref_frame_mvs },
   2206   { AV1E_SET_ALLOW_REF_FRAME_MVS, ctrl_set_allow_ref_frame_mvs },
   2207   { AV1E_SET_ENABLE_MASKED_COMP, ctrl_set_enable_masked_comp },
   2208   { AV1E_SET_ENABLE_ONESIDED_COMP, ctrl_set_enable_onesided_comp },
   2209   { AV1E_SET_ENABLE_INTERINTRA_COMP, ctrl_set_enable_interintra_comp },
   2210   { AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctrl_set_enable_smooth_interintra },
   2211   { AV1E_SET_ENABLE_DIFF_WTD_COMP, ctrl_set_enable_diff_wtd_comp },
   2212   { AV1E_SET_ENABLE_INTERINTER_WEDGE, ctrl_set_enable_interinter_wedge },
   2213   { AV1E_SET_ENABLE_INTERINTRA_WEDGE, ctrl_set_enable_interintra_wedge },
   2214   { AV1E_SET_ENABLE_GLOBAL_MOTION, ctrl_set_enable_global_motion },
   2215   { AV1E_SET_ENABLE_WARPED_MOTION, ctrl_set_enable_warped_motion },
   2216   { AV1E_SET_ALLOW_WARPED_MOTION, ctrl_set_allow_warped_motion },
   2217   { AV1E_SET_ENABLE_FILTER_INTRA, ctrl_set_enable_filter_intra },
   2218   { AV1E_SET_ENABLE_SMOOTH_INTRA, ctrl_set_enable_smooth_intra },
   2219   { AV1E_SET_ENABLE_PAETH_INTRA, ctrl_set_enable_paeth_intra },
   2220   { AV1E_SET_ENABLE_CFL_INTRA, ctrl_set_enable_cfl_intra },
   2221   { AV1E_SET_ENABLE_SUPERRES, ctrl_set_enable_superres },
   2222   { AV1E_SET_ENABLE_PALETTE, ctrl_set_enable_palette },
   2223   { AV1E_SET_ENABLE_INTRABC, ctrl_set_enable_intrabc },
   2224   { AV1E_SET_ENABLE_ANGLE_DELTA, ctrl_set_enable_angle_delta },
   2225   { AV1E_SET_AQ_MODE, ctrl_set_aq_mode },
   2226   { AV1E_SET_REDUCED_TX_TYPE_SET, ctrl_set_reduced_tx_type_set },
   2227   { AV1E_SET_INTRA_DCT_ONLY, ctrl_set_intra_dct_only },
   2228   { AV1E_SET_INTER_DCT_ONLY, ctrl_set_inter_dct_only },
   2229   { AV1E_SET_INTRA_DEFAULT_TX_ONLY, ctrl_set_intra_default_tx_only },
   2230   { AV1E_SET_QUANT_B_ADAPT, ctrl_set_quant_b_adapt },
   2231   { AV1E_SET_COEFF_COST_UPD_FREQ, ctrl_set_coeff_cost_upd_freq },
   2232   { AV1E_SET_MODE_COST_UPD_FREQ, ctrl_set_mode_cost_upd_freq },
   2233   { AV1E_SET_DELTAQ_MODE, ctrl_set_deltaq_mode },
   2234   { AV1E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
   2235   { AV1E_SET_TUNE_CONTENT, ctrl_set_tune_content },
   2236   { AV1E_SET_CDF_UPDATE_MODE, ctrl_set_cdf_update_mode },
   2237   { AV1E_SET_COLOR_PRIMARIES, ctrl_set_color_primaries },
   2238   { AV1E_SET_TRANSFER_CHARACTERISTICS, ctrl_set_transfer_characteristics },
   2239   { AV1E_SET_MATRIX_COEFFICIENTS, ctrl_set_matrix_coefficients },
   2240   { AV1E_SET_CHROMA_SAMPLE_POSITION, ctrl_set_chroma_sample_position },
   2241   { AV1E_SET_COLOR_RANGE, ctrl_set_color_range },
   2242   { AV1E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity },
   2243   { AV1E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval },
   2244   { AV1E_SET_MAX_GF_INTERVAL, ctrl_set_max_gf_interval },
   2245   { AV1E_SET_GF_MAX_PYRAMID_HEIGHT, ctrl_set_gf_max_pyr_height },
   2246   { AV1E_SET_RENDER_SIZE, ctrl_set_render_size },
   2247   { AV1E_SET_SUPERBLOCK_SIZE, ctrl_set_superblock_size },
   2248   { AV1E_SET_SINGLE_TILE_DECODING, ctrl_set_single_tile_decoding },
   2249   { AV1E_SET_FILM_GRAIN_TEST_VECTOR, ctrl_set_film_grain_test_vector },
   2250   { AV1E_SET_FILM_GRAIN_TABLE, ctrl_set_film_grain_table },
   2251 #if CONFIG_DENOISE
   2252   { AV1E_SET_DENOISE_NOISE_LEVEL, ctrl_set_denoise_noise_level },
   2253   { AV1E_SET_DENOISE_BLOCK_SIZE, ctrl_set_denoise_block_size },
   2254 #endif  // CONFIG_FILM_GRAIN
   2255   { AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
   2256   { AV1E_SET_TARGET_SEQ_LEVEL_IDX, ctrl_set_target_seq_level_idx },
   2257   { AV1E_SET_TIER_MASK, ctrl_set_tier_mask },
   2258 
   2259   // Getters
   2260   { AOME_GET_LAST_QUANTIZER, ctrl_get_quantizer },
   2261   { AOME_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64 },
   2262   { AV1_GET_REFERENCE, ctrl_get_reference },
   2263   { AV1E_GET_ACTIVEMAP, ctrl_get_active_map },
   2264   { AV1_GET_NEW_FRAME_IMAGE, ctrl_get_new_frame_image },
   2265   { AV1_COPY_NEW_FRAME_IMAGE, ctrl_copy_new_frame_image },
   2266   { AV1E_SET_CHROMA_SUBSAMPLING_X, ctrl_set_chroma_subsampling_x },
   2267   { AV1E_SET_CHROMA_SUBSAMPLING_Y, ctrl_set_chroma_subsampling_y },
   2268   { AV1E_GET_SEQ_LEVEL_IDX, ctrl_get_seq_level_idx },
   2269   { -1, NULL },
   2270 };
   2271 
   2272 static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
   2273   { 0,
   2274     {
   2275         // NOLINT
   2276         0,  // g_usage - non-realtime usage
   2277         0,  // g_threads
   2278         0,  // g_profile
   2279 
   2280         320,         // g_width
   2281         240,         // g_height
   2282         0,           // g_limit
   2283         0,           // g_forced_max_frame_width
   2284         0,           // g_forced_max_frame_height
   2285         AOM_BITS_8,  // g_bit_depth
   2286         8,           // g_input_bit_depth
   2287 
   2288         { 1, 30 },  // g_timebase
   2289 
   2290         0,  // g_error_resilient
   2291 
   2292         AOM_RC_ONE_PASS,  // g_pass
   2293 
   2294         19,  // g_lag_in_frames
   2295 
   2296         0,                // rc_dropframe_thresh
   2297         RESIZE_NONE,      // rc_resize_mode
   2298         SCALE_NUMERATOR,  // rc_resize_denominator
   2299         SCALE_NUMERATOR,  // rc_resize_kf_denominator
   2300 
   2301         SUPERRES_NONE,    // rc_superres_mode
   2302         SCALE_NUMERATOR,  // rc_superres_denominator
   2303         SCALE_NUMERATOR,  // rc_superres_kf_denominator
   2304         63,               // rc_superres_qthresh
   2305         32,               // rc_superres_kf_qthresh
   2306 
   2307         AOM_VBR,      // rc_end_usage
   2308         { NULL, 0 },  // rc_twopass_stats_in
   2309         { NULL, 0 },  // rc_firstpass_mb_stats_in
   2310         256,          // rc_target_bandwidth
   2311         0,            // rc_min_quantizer
   2312         63,           // rc_max_quantizer
   2313         25,           // rc_undershoot_pct
   2314         25,           // rc_overshoot_pct
   2315 
   2316         6000,  // rc_max_buffer_size
   2317         4000,  // rc_buffer_initial_size
   2318         5000,  // rc_buffer_optimal_size
   2319 
   2320         50,    // rc_two_pass_vbrbias
   2321         0,     // rc_two_pass_vbrmin_section
   2322         2000,  // rc_two_pass_vbrmax_section
   2323 
   2324         // keyframing settings (kf)
   2325         0,            // fwd_kf_enabled
   2326         AOM_KF_AUTO,  // g_kfmode
   2327         0,            // kf_min_dist
   2328         9999,         // kf_max_dist
   2329         0,            // sframe_dist
   2330         1,            // sframe_mode
   2331         0,            // large_scale_tile
   2332         0,            // monochrome
   2333         0,            // full_still_picture_hdr
   2334         0,            // save_as_annexb
   2335         0,            // tile_width_count
   2336         0,            // tile_height_count
   2337         { 0 },        // tile_widths
   2338         { 0 },        // tile_heights
   2339         { 1 },        // config file
   2340     } },
   2341   { 1,
   2342     {
   2343         // NOLINT
   2344         1,  // g_usage - real-time usage
   2345         0,  // g_threads
   2346         0,  // g_profile
   2347 
   2348         320,         // g_width
   2349         240,         // g_height
   2350         0,           // g_limit
   2351         0,           // g_forced_max_frame_width
   2352         0,           // g_forced_max_frame_height
   2353         AOM_BITS_8,  // g_bit_depth
   2354         8,           // g_input_bit_depth
   2355 
   2356         { 1, 30 },  // g_timebase
   2357 
   2358         0,  // g_error_resilient
   2359 
   2360         AOM_RC_ONE_PASS,  // g_pass
   2361 
   2362         1,  // g_lag_in_frames
   2363 
   2364         0,                // rc_dropframe_thresh
   2365         RESIZE_NONE,      // rc_resize_mode
   2366         SCALE_NUMERATOR,  // rc_resize_denominator
   2367         SCALE_NUMERATOR,  // rc_resize_kf_denominator
   2368 
   2369         0,                // rc_superres_mode
   2370         SCALE_NUMERATOR,  // rc_superres_denominator
   2371         SCALE_NUMERATOR,  // rc_superres_kf_denominator
   2372         63,               // rc_superres_qthresh
   2373         32,               // rc_superres_kf_qthresh
   2374 
   2375         AOM_CBR,      // rc_end_usage
   2376         { NULL, 0 },  // rc_twopass_stats_in
   2377         { NULL, 0 },  // rc_firstpass_mb_stats_in
   2378         256,          // rc_target_bandwidth
   2379         0,            // rc_min_quantizer
   2380         63,           // rc_max_quantizer
   2381         25,           // rc_undershoot_pct
   2382         25,           // rc_overshoot_pct
   2383 
   2384         6000,  // rc_max_buffer_size
   2385         4000,  // rc_buffer_initial_size
   2386         5000,  // rc_buffer_optimal_size
   2387 
   2388         50,    // rc_two_pass_vbrbias
   2389         0,     // rc_two_pass_vbrmin_section
   2390         2000,  // rc_two_pass_vbrmax_section
   2391 
   2392         // keyframing settings (kf)
   2393         0,            // fwd_kf_enabled
   2394         AOM_KF_AUTO,  // g_kfmode
   2395         0,            // kf_min_dist
   2396         9999,         // kf_max_dist
   2397         0,            // sframe_dist
   2398         1,            // sframe_mode
   2399         0,            // large_scale_tile
   2400         0,            // monochrome
   2401         0,            // full_still_picture_hdr
   2402         0,            // save_as_annexb
   2403         0,            // tile_width_count
   2404         0,            // tile_height_count
   2405         { 0 },        // tile_widths
   2406         { 0 },        // tile_heights
   2407         { 1 },        // config file
   2408     } },
   2409 };
   2410 
   2411 #ifndef VERSION_STRING
   2412 #define VERSION_STRING
   2413 #endif
   2414 CODEC_INTERFACE(aom_codec_av1_cx) = {
   2415   "AOMedia Project AV1 Encoder" VERSION_STRING,
   2416   AOM_CODEC_INTERNAL_ABI_VERSION,
   2417   AOM_CODEC_CAP_HIGHBITDEPTH | AOM_CODEC_CAP_ENCODER |
   2418       AOM_CODEC_CAP_PSNR,  // aom_codec_caps_t
   2419   encoder_init,            // aom_codec_init_fn_t
   2420   encoder_destroy,         // aom_codec_destroy_fn_t
   2421   encoder_ctrl_maps,       // aom_codec_ctrl_fn_map_t
   2422   {
   2423       // NOLINT
   2424       NULL,  // aom_codec_peek_si_fn_t
   2425       NULL,  // aom_codec_get_si_fn_t
   2426       NULL,  // aom_codec_decode_fn_t
   2427       NULL,  // aom_codec_get_frame_fn_t
   2428       NULL   // aom_codec_set_fb_fn_t
   2429   },
   2430   {
   2431       // NOLINT
   2432       2,                           // 2 cfg map
   2433       encoder_usage_cfg_map,       // aom_codec_enc_cfg_map_t
   2434       encoder_encode,              // aom_codec_encode_fn_t
   2435       encoder_get_cxdata,          // aom_codec_get_cx_data_fn_t
   2436       encoder_set_config,          // aom_codec_enc_config_set_fn_t
   2437       encoder_get_global_headers,  // aom_codec_get_global_headers_fn_t
   2438       encoder_get_preview,         // aom_codec_get_preview_frame_fn_t
   2439       NULL                         // aom_codec_enc_mr_get_mem_loc_fn_t
   2440   }
   2441 };
   2442