Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/aom/av1/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 209 kB image not shown  

Quelle  av1_cx_iface.c   Sprache: C

 
/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "config/aom_config.h"
#include "config/aom_version.h"

#include "aom/aomcx.h"
#include "aom/aom_encoder.h"
#include "aom/aom_external_partition.h"
#include "aom/aom_image.h"
#include "aom/internal/aom_codec_internal.h"
#include "aom_dsp/flow_estimation/flow_estimation.h"
#include "aom_mem/aom_mem.h"
#include "aom_scale/yv12config.h"
#include "aom_util/aom_pthread.h"

#include "av1/av1_cx_iface.h"
#include "av1/av1_iface_common.h"
#include "av1/common/av1_common_int.h"
#include "av1/common/enums.h"
#include "av1/common/scale.h"
#include "av1/encoder/bitstream.h"
#include "av1/encoder/enc_enums.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/encoder_alloc.h"
#include "av1/encoder/encoder_utils.h"
#include "av1/encoder/ethread.h"
#include "av1/encoder/external_partition.h"
#include "av1/encoder/firstpass.h"
#include "av1/encoder/lookahead.h"
#include "av1/encoder/rc_utils.h"
#include "av1/arg_defs.h"

#include "common/args_helper.h"

struct av1_extracfg {
  int cpu_used;
  unsigned int enable_auto_alt_ref;
  unsigned int enable_auto_bwd_ref;
  unsigned int noise_sensitivity;
  unsigned int sharpness;
  unsigned int static_thresh;
  unsigned int row_mt;
  unsigned int fp_mt;
  unsigned int tile_columns;  // log2 number of tile columns
  unsigned int tile_rows;     // log2 number of tile rows
  unsigned int auto_tiles;
  unsigned int enable_tpl_model;
  unsigned int enable_keyframe_filtering;
  unsigned int arnr_max_frames;
  unsigned int arnr_strength;
  unsigned int min_gf_interval;
  unsigned int max_gf_interval;
  unsigned int gf_min_pyr_height;
  unsigned int gf_max_pyr_height;
  aom_tune_metric tuning;
  const char *vmaf_model_path;
  const char *partition_info_path;
  unsigned int enable_rate_guide_deltaq;
  const char *rate_distribution_info;
  aom_dist_metric dist_metric;
  unsigned int cq_level;  // constrained quality level
  unsigned int rc_max_intra_bitrate_pct;
  unsigned int rc_max_inter_bitrate_pct;
  unsigned int gf_cbr_boost_pct;
  unsigned int lossless;
  unsigned int enable_cdef;
  unsigned int enable_restoration;
  unsigned int force_video_mode;
  unsigned int enable_obmc;
  unsigned int disable_trellis_quant;
  unsigned int enable_qm;
  unsigned int qm_y;
  unsigned int qm_u;
  unsigned int qm_v;
  unsigned int qm_min;
  unsigned int qm_max;
  unsigned int num_tg;
  unsigned int mtu_size;

  aom_timing_info_type_t timing_info_type;
  unsigned int frame_parallel_decoding_mode;
  int enable_dual_filter;
  unsigned int enable_chroma_deltaq;
  AQ_MODE aq_mode;
  DELTAQ_MODE deltaq_mode;
  int deltaq_strength;
  int deltalf_mode;
  unsigned int frame_periodic_boost;
  aom_tune_content content;
  aom_color_primaries_t color_primaries;
  aom_transfer_characteristics_t transfer_characteristics;
  aom_matrix_coefficients_t matrix_coefficients;
  aom_chroma_sample_position_t chroma_sample_position;
  int color_range;
  int render_width;
  int render_height;
  aom_superblock_size_t superblock_size;
  unsigned int single_tile_decoding;
  int error_resilient_mode;
  int s_frame_mode;

  int film_grain_test_vector;
  const char *film_grain_table_filename;
  unsigned int motion_vector_unit_test;
#if CONFIG_FPMT_TEST
  unsigned int fpmt_unit_test;
#endif
  unsigned int cdf_update_mode;
  int enable_rect_partitions;    // enable rectangular partitions for sequence
  int enable_ab_partitions;      // enable AB partitions for sequence
  int enable_1to4_partitions;    // enable 1:4 and 4:1 partitions for sequence
  int min_partition_size;        // min partition size [4,8,16,32,64,128]
  int max_partition_size;        // max partition size [4,8,16,32,64,128]
  int enable_intra_edge_filter;  // enable intra-edge filter for sequence
  int enable_order_hint;         // enable order hint for sequence
  int enable_tx64;               // enable 64-pt transform usage for sequence
  int enable_flip_idtx;          // enable flip and identity transform types
  int enable_rect_tx;        // enable rectangular transform usage for sequence
  int enable_dist_wtd_comp;  // enable dist wtd compound for sequence
  int max_reference_frames;  // maximum number of references per frame
  int enable_reduced_reference_set;  // enable reduced set of references
  int enable_ref_frame_mvs;          // sequence level
  int allow_ref_frame_mvs;           // frame level
  int enable_masked_comp;            // enable masked compound for sequence
  int enable_onesided_comp;          // enable one sided compound for sequence
  int enable_interintra_comp;        // enable interintra compound for sequence
  int enable_smooth_interintra;      // enable smooth interintra mode usage
  int enable_diff_wtd_comp;          // enable diff-wtd compound usage
  int enable_interinter_wedge;       // enable interinter-wedge compound usage
  int enable_interintra_wedge;       // enable interintra-wedge compound usage
  int enable_global_motion;          // enable global motion usage for sequence
  int enable_warped_motion;          // sequence level
  int allow_warped_motion;           // frame level
  int enable_filter_intra;           // enable filter intra for sequence
  int enable_smooth_intra;           // enable smooth intra modes for sequence
  int enable_paeth_intra;            // enable Paeth intra mode for sequence
  int enable_cfl_intra;              // enable CFL uv intra mode for sequence
  int enable_directional_intra;      // enable directional modes for sequence
  int enable_diagonal_intra;  // enable D45 to D203 intra modes for sequence
  int enable_superres;
  int enable_overlay;  // enable overlay for filtered arf frames
  int enable_palette;
  int enable_intrabc;
  int enable_angle_delta;
#if CONFIG_DENOISE
  float noise_level;
  int noise_block_size;
  int enable_dnl_denoising;
#endif

  unsigned int chroma_subsampling_x;
  unsigned int chroma_subsampling_y;
  int reduced_tx_type_set;
  int use_intra_dct_only;
  int use_inter_dct_only;
  int use_intra_default_tx_only;
  int enable_tx_size_search;
  int quant_b_adapt;
  unsigned int vbr_corpus_complexity_lap;
  AV1_LEVEL target_seq_level_idx[MAX_NUM_OPERATING_POINTS];
  // Bit mask to specify which tier each of the 32 possible operating points
  // conforms to.
  unsigned int tier_mask;
  // min_cr / 100 is the target minimum compression ratio for each frame.
  unsigned int min_cr;
  COST_UPDATE_TYPE coeff_cost_upd_freq;
  COST_UPDATE_TYPE mode_cost_upd_freq;
  COST_UPDATE_TYPE mv_cost_upd_freq;
  COST_UPDATE_TYPE dv_cost_upd_freq;
  unsigned int ext_tile_debug;
  unsigned int sb_multipass_unit_test;
  // Total number of passes. If this number is -1, then we assume passes = 1 or
  // 2 (passes = 1 if pass == AOM_RC_ONE_PASS and passes = 2 otherwise).
  int passes;
  int fwd_kf_dist;

  LOOPFILTER_CONTROL loopfilter_control;
  // Indicates if the application of post-processing filters should be skipped
  // on reconstructed frame.
  unsigned int skip_postproc_filtering;
  // the name of the second pass output file when passes > 2
  const char *two_pass_output;
  const char *second_pass_log;
  // Automatically determine whether to disable several intra tools
  // when "--deltaq-mode=3" is true.
  // Default as 0.
  // When set to 1, the encoder will analyze the reconstruction quality
  // as compared to the source image in the preprocessing pass.
  // If the recontruction quality is considered high enough, we disable
  // the following intra coding tools, for better encoding speed:
  // "--enable_smooth_intra",
  // "--enable_paeth_intra",
  // "--enable_cfl_intra",
  // "--enable_diagonal_intra".
  int auto_intra_tools_off;
  int strict_level_conformance;
  int kf_max_pyr_height;
  int sb_qp_sweep;
};

#if !CONFIG_REALTIME_ONLY
static const struct av1_extracfg default_extra_cfg = {
  0,              // cpu_used
  1,              // enable_auto_alt_ref
  0,              // enable_auto_bwd_ref
  0,              // noise_sensitivity
  0,              // sharpness
  0,              // static_thresh
  1,              // row_mt
  0,              // fp_mt
  0,              // tile_columns
  0,              // tile_rows
  0,              // auto_tiles
  1,              // enable_tpl_model
  1,              // enable_keyframe_filtering
  7,              // arnr_max_frames
  5,              // arnr_strength
  0,              // min_gf_interval; 0 -> default decision
  0,              // max_gf_interval; 0 -> default decision
  0,              // gf_min_pyr_height
  5,              // gf_max_pyr_height
  AOM_TUNE_PSNR,  // tuning
  "/usr/local/share/model/vmaf_v0.6.1.json",  // VMAF model path
  ".",                                        // partition info path
  0,                                          // enable rate guide deltaq
  "./rate_map.txt",                           // rate distribution input
  AOM_DIST_METRIC_PSNR,                       // dist_metric
  10,                                         // cq_level
  0,                                          // rc_max_intra_bitrate_pct
  0,                                          // rc_max_inter_bitrate_pct
  0,                                          // gf_cbr_boost_pct
  0,                                          // lossless
  1,                                          // enable_cdef
  1,                                          // enable_restoration
  0,                                          // force_video_mode
  1,                                          // enable_obmc
  3,                                          // disable_trellis_quant
  0,                                          // enable_qm
  DEFAULT_QM_Y,                               // qm_y
  DEFAULT_QM_U,                               // qm_u
  DEFAULT_QM_V,                               // qm_v
  DEFAULT_QM_FIRST,                           // qm_min
  DEFAULT_QM_LAST,                            // qm_max
  1,                                          // max number of tile groups
  0,                                          // mtu_size
  AOM_TIMING_UNSPECIFIED,       // No picture timing signaling in bitstream
  0,                            // frame_parallel_decoding_mode
  1,                            // enable dual filter
  0,                            // enable delta quant in chroma planes
  NO_AQ,                        // aq_mode
  DELTA_Q_OBJECTIVE,            // deltaq_mode
  100,                          // deltaq_strength
  0,                            // delta lf mode
  0,                            // frame_periodic_boost
  AOM_CONTENT_DEFAULT,          // content
  AOM_CICP_CP_UNSPECIFIED,      // CICP color primaries
  AOM_CICP_TC_UNSPECIFIED,      // CICP transfer characteristics
  AOM_CICP_MC_UNSPECIFIED,      // CICP matrix coefficients
  AOM_CSP_UNKNOWN,              // chroma sample position
  0,                            // color range
  0,                            // render width
  0,                            // render height
  AOM_SUPERBLOCK_SIZE_DYNAMIC,  // superblock_size
  1,                            // this depends on large_scale_tile.
  0,                            // error_resilient_mode off by default.
  0,                            // s_frame_mode off by default.
  0,                            // film_grain_test_vector
  NULL,                         // film_grain_table_filename
  0,                            // motion_vector_unit_test
#if CONFIG_FPMT_TEST
  0,  // fpmt_unit_test
#endif
  1,    // CDF update mode
  1,    // enable rectangular partitions
  1,    // enable ab shape partitions
  1,    // enable 1:4 and 4:1 partitions
  4,    // min_partition_size
  128,  // max_partition_size
  1,    // enable intra edge filter
  1,    // frame order hint
  1,    // enable 64-pt transform usage
  1,    // enable flip and identity transform
  1,    // enable rectangular transform usage
  1,    // dist-wtd compound
  7,    // max_reference_frames
  0,    // enable_reduced_reference_set
  1,    // enable_ref_frame_mvs sequence level
  1,    // allow ref_frame_mvs frame level
  1,    // enable masked compound at sequence level
  1,    // enable one sided compound at sequence level
  1,    // enable interintra compound at sequence level
  1,    // enable smooth interintra mode
  1,    // enable difference-weighted compound
  1,    // enable interinter wedge compound
  1,    // enable interintra wedge compound
  1,    // enable_global_motion usage
  1,    // enable_warped_motion at sequence level
  1,    // allow_warped_motion at frame level
  1,    // enable filter intra at sequence level
  1,    // enable smooth intra modes usage for sequence
  1,    // enable Paeth intra mode usage for sequence
  1,    // enable CFL uv intra mode usage for sequence
  1,    // enable directional intra mode usage for sequence
  1,    // enable D45 to D203 intra mode usage for sequence
  1,    // superres
  1,    // enable overlay
  1,    // enable palette
  1,    // enable intrabc
  1,    // enable angle delta
#if CONFIG_DENOISE
  0,   // noise_level
  32,  // noise_block_size
  1,   // enable_dnl_denoising
#endif
  0,  // chroma_subsampling_x
  0,  // chroma_subsampling_y
  0,  // reduced_tx_type_set
  0,  // use_intra_dct_only
  0,  // use_inter_dct_only
  0,  // use_intra_default_tx_only
  1,  // enable_tx_size_search
  0,  // quant_b_adapt
  0,  // vbr_corpus_complexity_lap
  {
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
  },               // target_seq_level_idx
  0,               // tier_mask
  0,               // min_cr
  COST_UPD_SB,     // coeff_cost_upd_freq
  COST_UPD_SB,     // mode_cost_upd_freq
  COST_UPD_SB,     // mv_cost_upd_freq
  COST_UPD_SB,     // dv_cost_upd_freq
  0,               // ext_tile_debug
  0,               // sb_multipass_unit_test
  -1,              // passes
  -1,              // fwd_kf_dist
  LOOPFILTER_ALL,  // loopfilter_control
  0,               // skip_postproc_filtering
  NULL,            // two_pass_output
  NULL,            // second_pass_log
  0,               // auto_intra_tools_off
  0,               // strict_level_conformance
  -1,              // kf_max_pyr_height
  0,               // sb_qp_sweep
};
#else
// Some settings are changed for realtime only build.
static const struct av1_extracfg default_extra_cfg = {
  10,             // cpu_used
  1,              // enable_auto_alt_ref
  0,              // enable_auto_bwd_ref
  0,              // noise_sensitivity
  0,              // sharpness
  0,              // static_thresh
  1,              // row_mt
  0,              // fp_mt
  0,              // tile_columns
  0,              // tile_rows
  0,              // auto_tiles
  0,              // enable_tpl_model
  0,              // enable_keyframe_filtering
  7,              // arnr_max_frames
  5,              // arnr_strength
  0,              // min_gf_interval; 0 -> default decision
  0,              // max_gf_interval; 0 -> default decision
  0,              // gf_min_pyr_height
  5,              // gf_max_pyr_height
  AOM_TUNE_PSNR,  // tuning
  "/usr/local/share/model/vmaf_v0.6.1.json",  // VMAF model path
  ".",                                        // partition info path
  0,                                          // enable rate guide deltaq
  "./rate_map.txt",                           // rate distribution input
  AOM_DIST_METRIC_PSNR,                       // dist_metric
  10,                                         // cq_level
  300,                                        // rc_max_intra_bitrate_pct
  0,                                          // rc_max_inter_bitrate_pct
  0,                                          // gf_cbr_boost_pct
  0,                                          // lossless
  1,                                          // enable_cdef
  0,                                          // enable_restoration
  0,                                          // force_video_mode
  0,                                          // enable_obmc
  3,                                          // disable_trellis_quant
  0,                                          // enable_qm
  DEFAULT_QM_Y,                               // qm_y
  DEFAULT_QM_U,                               // qm_u
  DEFAULT_QM_V,                               // qm_v
  DEFAULT_QM_FIRST,                           // qm_min
  DEFAULT_QM_LAST,                            // qm_max
  1,                                          // max number of tile groups
  0,                                          // mtu_size
  AOM_TIMING_UNSPECIFIED,       // No picture timing signaling in bitstream
  0,                            // frame_parallel_decoding_mode
  0,                            // enable dual filter
  0,                            // enable delta quant in chroma planes
  CYCLIC_REFRESH_AQ,            // aq_mode
  NO_DELTA_Q,                   // deltaq_mode
  100,                          // deltaq_strength
  0,                            // delta lf mode
  0,                            // frame_periodic_boost
  AOM_CONTENT_DEFAULT,          // content
  AOM_CICP_CP_UNSPECIFIED,      // CICP color primaries
  AOM_CICP_TC_UNSPECIFIED,      // CICP transfer characteristics
  AOM_CICP_MC_UNSPECIFIED,      // CICP matrix coefficients
  AOM_CSP_UNKNOWN,              // chroma sample position
  0,                            // color range
  0,                            // render width
  0,                            // render height
  AOM_SUPERBLOCK_SIZE_DYNAMIC,  // superblock_size
  1,                            // this depends on large_scale_tile.
  0,                            // error_resilient_mode off by default.
  0,                            // s_frame_mode off by default.
  0,                            // film_grain_test_vector
  NULL,                         // film_grain_table_filename
  0,                            // motion_vector_unit_test
#if CONFIG_FPMT_TEST
  0,                            // fpmt_unit_test
#endif
  1,                            // CDF update mode
  0,                            // enable rectangular partitions
  0,                            // enable ab shape partitions
  0,                            // enable 1:4 and 4:1 partitions
  4,                            // min_partition_size
  128,                          // max_partition_size
  0,                            // enable intra edge filter
  0,                            // frame order hint
  0,                            // enable 64-pt transform usage
  1,                            // enable flip and identity transform
  1,                            // enable rectangular transform usage
  0,                            // dist-wtd compound
  3,                            // max_reference_frames
  0,                            // enable_reduced_reference_set
  0,                            // enable_ref_frame_mvs sequence level
  0,                            // allow ref_frame_mvs frame level
  0,                            // enable masked compound at sequence level
  0,                            // enable one sided compound at sequence level
  0,                            // enable interintra compound at sequence level
  0,                            // enable smooth interintra mode
  0,                            // enable difference-weighted compound
  0,                            // enable interinter wedge compound
  0,                            // enable interintra wedge compound
  0,                            // enable_global_motion usage
  0,                            // enable_warped_motion at sequence level
  0,                            // allow_warped_motion at frame level
  0,                            // enable filter intra at sequence level
  0,                            // enable smooth intra modes usage for sequence
  0,                            // enable Paeth intra mode usage for sequence
  0,                            // enable CFL uv intra mode usage for sequence
  1,   // enable directional intra mode usage for sequence
  1,   // enable D45 to D203 intra mode usage for sequence
  0,   // superres
  0,   // enable overlay
  1,   // enable palette
  0,   // enable intrabc
  0,   // enable angle delta
#if CONFIG_DENOISE
  0,   // noise_level
  32,  // noise_block_size
  1,   // enable_dnl_denoising
#endif
  0,   // chroma_subsampling_x
  0,   // chroma_subsampling_y
  0,   // reduced_tx_type_set
  0,   // use_intra_dct_only
  0,   // use_inter_dct_only
  1,   // use_intra_default_tx_only
  1,   // enable_tx_size_search
  0,   // quant_b_adapt
  0,   // vbr_corpus_complexity_lap
  {
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
      SEQ_LEVEL_MAX, SEQ_LEVEL_MAX,
  },               // target_seq_level_idx
  0,               // tier_mask
  0,               // min_cr
  COST_UPD_OFF,    // coeff_cost_upd_freq
  COST_UPD_OFF,    // mode_cost_upd_freq
  COST_UPD_OFF,    // mv_cost_upd_freq
  COST_UPD_OFF,    // dv_cost_upd_freq
  0,               // ext_tile_debug
  0,               // sb_multipass_unit_test
  -1,              // passes
  -1,              // fwd_kf_dist
  LOOPFILTER_ALL,  // loopfilter_control
  0,               // skip_postproc_filtering
  NULL,            // two_pass_output
  NULL,            // second_pass_log
  0,               // auto_intra_tools_off
  0,               // strict_level_conformance
  -1,              // kf_max_pyr_height
  0,               // sb_qp_sweep
};
#endif

struct aom_codec_alg_priv {
  aom_codec_priv_t base;
  aom_codec_enc_cfg_t cfg;
  struct av1_extracfg extra_cfg;
  aom_rational64_t timestamp_ratio;
  aom_codec_pts_t pts_offset;
  unsigned char pts_offset_initialized;
  AV1EncoderConfig oxcf;
  AV1_PRIMARY *ppi;
  unsigned char *cx_data;
  size_t cx_data_sz;
  size_t pending_cx_data_sz;
  aom_image_t preview_img;
  aom_enc_frame_flags_t next_frame_flags;
  aom_codec_pkt_list_decl(256) pkt_list;
  unsigned int fixed_kf_cntr;
  // BufferPool that holds all reference frames.
  BufferPool *buffer_pool;

  // lookahead instance variables
  BufferPool *buffer_pool_lap;
  FIRSTPASS_STATS *frame_stats_buffer;
  // Number of stats buffers required for look ahead
  int num_lap_buffers;
  STATS_BUFFER_CTX stats_buf_context;
  bool monochrome_on_init;
};

static inline int gcd(int64_t a, int b) {
  int remainder;
  while (b > 0) {
    remainder = (int)(a % b);
    a = b;
    b = remainder;
  }

  return (int)a;
}

static void reduce_ratio(aom_rational64_t *ratio) {
  const int denom = gcd(ratio->num, ratio->den);
  ratio->num /= denom;
  ratio->den /= denom;
}

// Called by encoder_encode() only. Must not be called by encoder_init()
// because the `error` paramerer will be destroyed by aom_codec_enc_init_ver()
// after encoder_init() returns an error. See the "IMPORTANT" comment in
// aom_codec_enc_init_ver().
static aom_codec_err_t update_error_state(
    aom_codec_alg_priv_t *ctx, const struct aom_internal_error_info *error) {
  const aom_codec_err_t res = error->error_code;

  if (res != AOM_CODEC_OK)
    ctx->base.err_detail = error->has_detail ? error->detail : NULL;

  return res;
}

// This function deep copies a string src to *dst. For default string we will
// use a string literal, and otherwise we will allocate memory for the string.
static aom_codec_err_t allocate_and_set_string(const char *src,
                                               const char *default_src,
                                               const char **dst,
                                               char *err_detail) {
  if (!src) {
    snprintf(err_detail, ARG_ERR_MSG_MAX_LEN,
             "Null pointer given to a string parameter.");
    return AOM_CODEC_INVALID_PARAM;
  }
  if (*dst && strcmp(src, *dst) == 0) return AOM_CODEC_OK;
  // If the input is exactly the same as default, we will use the string
  // literal, so do not free here.
  if (*dst != default_src) {
    aom_free((void *)*dst);
  }

  if (default_src && strcmp(src, default_src) == 0) {
    // default_src should be a string literal
    *dst = default_src;
  } else {
    size_t len = strlen(src) + 1;
    char *tmp = aom_malloc(len * sizeof(*tmp));
    if (!tmp) {
      snprintf(err_detail, ARG_ERR_MSG_MAX_LEN,
               "Failed to allocate memory for copying parameters.");
      return AOM_CODEC_MEM_ERROR;
    }
    memcpy(tmp, src, len);
    *dst = tmp;
  }
  return 0;
}

#undef ERROR
#define ERROR(str)                  \
  do {                              \
    ctx->base.err_detail = str;     \
    return AOM_CODEC_INVALID_PARAM; \
  } while (0)

#define RANGE_CHECK(p, memb, lo, hi)                   \
  do {                                                 \
    if (!((p)->memb >= (lo) && (p)->memb <= (hi)))     \
      ERROR(#memb " out of range [" #lo ".." #hi "]"); \
  } while (0)

#define RANGE_CHECK_HI(p, memb, hi)                                     \
  do {                                                                  \
    if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
  } while (0)

#define RANGE_CHECK_BOOL(p, memb)                                     \
  do {                                                                \
    if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \
  } while (0)

static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
                                       const aom_codec_enc_cfg_t *cfg,
                                       const struct av1_extracfg *extra_cfg) {
  RANGE_CHECK(cfg, g_w, 1, 65536);                        // 16 bits available
  RANGE_CHECK(cfg, g_h, 1, 65536);                        // 16 bits available
  RANGE_CHECK_HI(cfg, g_forced_max_frame_width, 65536);   // 16 bits available
  RANGE_CHECK_HI(cfg, g_forced_max_frame_height, 65536);  // 16 bits available
  if (cfg->g_forced_max_frame_width) {
    RANGE_CHECK_HI(cfg, g_w, cfg->g_forced_max_frame_width);
  }
  if (cfg->g_forced_max_frame_height) {
    RANGE_CHECK_HI(cfg, g_h, cfg->g_forced_max_frame_height);
  }
  // To avoid integer overflows when multiplying width by height (or values
  // derived from width and height) using the int type, impose a maximum frame
  // area (width * height) of 2^30.
  const unsigned int max_frame_width =
      cfg->g_forced_max_frame_width ? cfg->g_forced_max_frame_width : cfg->g_w;
  const unsigned int max_frame_height = cfg->g_forced_max_frame_height
                                            ? cfg->g_forced_max_frame_height
                                            : cfg->g_h;
  const int64_t max_frame_area = (int64_t)max_frame_width * max_frame_height;
  if (max_frame_area > (1 << 30)) {
    ERROR("max_frame_area out of range [..2^30]");
  }
  RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
  RANGE_CHECK(cfg, g_timebase.num, 1, 1000000000);
  RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);

  RANGE_CHECK_HI(cfg, rc_target_bitrate, 2000000);
  RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
  RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
  RANGE_CHECK_BOOL(extra_cfg, lossless);
  RANGE_CHECK_HI(extra_cfg, aq_mode, AQ_MODE_COUNT - 1);
  RANGE_CHECK_HI(extra_cfg, deltaq_mode, DELTA_Q_MODE_COUNT - 1);

  if (cfg->g_usage != ALLINTRA &&
      extra_cfg->deltaq_mode == DELTA_Q_VARIANCE_BOOST) {
    ERROR("Variance Boost (deltaq_mode = 6) can only be set in all intra mode");
  }

  RANGE_CHECK_HI(extra_cfg, deltalf_mode, 1);
  RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
#if CONFIG_REALTIME_ONLY
  RANGE_CHECK(cfg, g_usage, AOM_USAGE_REALTIME, AOM_USAGE_REALTIME);
#else
  RANGE_CHECK_HI(cfg, g_usage, AOM_USAGE_ALL_INTRA);
#endif
  RANGE_CHECK_HI(cfg, g_threads, MAX_NUM_THREADS);
  RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
  RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
  RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
  RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
  RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
  RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
  RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_THIRD_PASS);
  RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
  if (cfg->g_usage == AOM_USAGE_ALL_INTRA) {
    RANGE_CHECK_HI(cfg, g_lag_in_frames, 0);
    RANGE_CHECK_HI(cfg, kf_max_dist, 0);
  }
  RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
  RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
  if (extra_cfg->max_gf_interval > 0) {
    RANGE_CHECK(extra_cfg, max_gf_interval,
                AOMMAX(2, extra_cfg->min_gf_interval), (MAX_LAG_BUFFERS - 1));
  }
  RANGE_CHECK_HI(extra_cfg, gf_min_pyr_height, 5);
  RANGE_CHECK_HI(extra_cfg, gf_max_pyr_height, 5);
  if (extra_cfg->gf_min_pyr_height > extra_cfg->gf_max_pyr_height) {
    ERROR(
        "gf_min_pyr_height must be less than or equal to "
        "gf_max_pyramid_height");
  }

  RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
  RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
              SCALE_NUMERATOR << 1);
  RANGE_CHECK(cfg, rc_resize_kf_denominator, SCALE_NUMERATOR,
              SCALE_NUMERATOR << 1);
  RANGE_CHECK_HI(cfg, rc_superres_mode, AOM_SUPERRES_AUTO);
  RANGE_CHECK(cfg, rc_superres_denominator, SCALE_NUMERATOR,
              SCALE_NUMERATOR << 1);
  RANGE_CHECK(cfg, rc_superres_kf_denominator, SCALE_NUMERATOR,
              SCALE_NUMERATOR << 1);
  RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63);
  RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
  RANGE_CHECK_HI(extra_cfg, cdf_update_mode, 2);

  RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
#if CONFIG_FPMT_TEST
  RANGE_CHECK_HI(extra_cfg, fpmt_unit_test, 1);
#endif
  RANGE_CHECK_HI(extra_cfg, sb_multipass_unit_test, 1);
  RANGE_CHECK_HI(extra_cfg, ext_tile_debug, 1);
  RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 1);
  RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
  RANGE_CHECK(extra_cfg, cpu_used, 0,
              (cfg->g_usage == AOM_USAGE_REALTIME) ? 11 : 9);
  RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
  RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
              AOM_SUPERBLOCK_SIZE_DYNAMIC);
  RANGE_CHECK_HI(cfg, large_scale_tile, 1);
  RANGE_CHECK_HI(extra_cfg, single_tile_decoding, 1);
  RANGE_CHECK_HI(extra_cfg, enable_rate_guide_deltaq, 1);

  RANGE_CHECK_HI(extra_cfg, row_mt, 1);
  RANGE_CHECK_HI(extra_cfg, fp_mt, 1);

  RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
  RANGE_CHECK_HI(extra_cfg, tile_rows, 6);
  RANGE_CHECK_HI(extra_cfg, auto_tiles, 1);

  RANGE_CHECK_HI(cfg, monochrome, 1);

  if (cfg->large_scale_tile && extra_cfg->aq_mode)
    ERROR(
        "Adaptive quantization are not supported in large scale tile "
        "coding.");

  RANGE_CHECK_HI(extra_cfg, sharpness, 7);
  RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
  RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
  RANGE_CHECK_HI(extra_cfg, cq_level, 63);
  RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
  RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
  RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);

  if (cfg->g_pass >= AOM_RC_SECOND_PASS) {
    const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
    const FIRSTPASS_STATS *stats;

    if (cfg->rc_twopass_stats_in.buf == NULL)
      ERROR("rc_twopass_stats_in.buf not set.");

    if (cfg->rc_twopass_stats_in.sz % packet_sz)
      ERROR("rc_twopass_stats_in.sz indicates truncated packet.");

    if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
      ERROR("rc_twopass_stats_in requires at least two packets.");

    stats =
        (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;

    if ((int)(stats->count + 0.5) != n_packets - 1)
      ERROR("rc_twopass_stats_in missing EOS stats packet");
  }

  if (extra_cfg->passes != -1 && cfg->g_pass == AOM_RC_ONE_PASS &&
      extra_cfg->passes != 1) {
    ERROR("One pass encoding but passes != 1.");
  }

  if (extra_cfg->passes != -1 && (int)cfg->g_pass > extra_cfg->passes) {
    ERROR("Current pass is larger than total number of passes.");
  }

  if (cfg->g_profile == (unsigned int)PROFILE_1 && cfg->monochrome) {
    ERROR("Monochrome is not supported in profile 1");
  }

  if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
      cfg->g_bit_depth > AOM_BITS_10) {
    ERROR("Codec bit-depth 12 not supported in profile < 2");
  }
  if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
      cfg->g_input_bit_depth > 10) {
    ERROR("Source bit-depth 12 not supported in profile < 2");
  }

  if (cfg->rc_end_usage == AOM_Q) {
    RANGE_CHECK_HI(cfg, use_fixed_qp_offsets, 1);
  } else {
    if (cfg->use_fixed_qp_offsets > 0) {
      ERROR("--use_fixed_qp_offsets can only be used with --end-usage=q");
    }
  }

  RANGE_CHECK(extra_cfg, color_primaries, AOM_CICP_CP_BT_709,
              AOM_CICP_CP_EBU_3213);  // Need to check range more precisely to
                                      // check for reserved values?
  RANGE_CHECK(extra_cfg, transfer_characteristics, AOM_CICP_TC_BT_709,
              AOM_CICP_TC_HLG);
  RANGE_CHECK(extra_cfg, matrix_coefficients, AOM_CICP_MC_IDENTITY,
              AOM_CICP_MC_ICTCP);
  RANGE_CHECK(extra_cfg, color_range, 0, 1);

  /* Average corpus complexity is supported only in the case of single pass
   * VBR*/

  if (cfg->g_pass == AOM_RC_ONE_PASS && cfg->rc_end_usage == AOM_VBR)
    RANGE_CHECK_HI(extra_cfg, vbr_corpus_complexity_lap,
                   MAX_VBR_CORPUS_COMPLEXITY);
  else if (extra_cfg->vbr_corpus_complexity_lap != 0)
    ERROR(
        "VBR corpus complexity is supported only in the case of single pass "
        "VBR mode.");

#if !CONFIG_TUNE_BUTTERAUGLI
  if (extra_cfg->tuning == AOM_TUNE_BUTTERAUGLI) {
    ERROR(
        "This error may be related to the wrong configuration options: try to "
        "set -DCONFIG_TUNE_BUTTERAUGLI=1 at the time CMake is run.");
  }
#endif

#if !CONFIG_TUNE_VMAF
  if (extra_cfg->tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
      extra_cfg->tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
    ERROR(
        "This error may be related to the wrong configuration options: try to "
        "set -DCONFIG_TUNE_VMAF=1 at the time CMake is run.");
  }
#endif

  RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_SSIMULACRA2);

  RANGE_CHECK(extra_cfg, dist_metric, AOM_DIST_METRIC_PSNR,
              AOM_DIST_METRIC_QM_PSNR);

  RANGE_CHECK(extra_cfg, timing_info_type, AOM_TIMING_UNSPECIFIED,
              AOM_TIMING_DEC_MODEL);

  RANGE_CHECK(extra_cfg, film_grain_test_vector, 0, 16);

  if (extra_cfg->lossless) {
    if (extra_cfg->aq_mode != 0)
      ERROR("Only --aq_mode=0 can be used with --lossless=1.");
    if (extra_cfg->enable_chroma_deltaq)
      ERROR("Only --enable_chroma_deltaq=0 can be used with --lossless=1.");
  }

  RANGE_CHECK(extra_cfg, max_reference_frames, 3, 7);
  RANGE_CHECK(extra_cfg, enable_reduced_reference_set, 0, 1);
  RANGE_CHECK_HI(extra_cfg, chroma_subsampling_x, 1);
  RANGE_CHECK_HI(extra_cfg, chroma_subsampling_y, 1);

  RANGE_CHECK_HI(extra_cfg, disable_trellis_quant, 3);
  RANGE_CHECK(extra_cfg, coeff_cost_upd_freq, 0, 3);
  RANGE_CHECK(extra_cfg, mode_cost_upd_freq, 0, 3);
  RANGE_CHECK(extra_cfg, mv_cost_upd_freq, 0, 3);
  RANGE_CHECK(extra_cfg, dv_cost_upd_freq, 0, 3);

  RANGE_CHECK(extra_cfg, min_partition_size, 4, 128);
  RANGE_CHECK(extra_cfg, max_partition_size, 4, 128);
  RANGE_CHECK_HI(extra_cfg, min_partition_size, extra_cfg->max_partition_size);

  for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
    const int level_idx = extra_cfg->target_seq_level_idx[i];
    if (!is_valid_seq_level_idx(level_idx) &&
        level_idx != SEQ_LEVEL_KEEP_STATS) {
      ERROR("Target sequence level index is invalid");
    }
  }

  RANGE_CHECK(extra_cfg, deltaq_strength, 0, 1000);
  RANGE_CHECK_HI(extra_cfg, loopfilter_control, 3);
  RANGE_CHECK_BOOL(extra_cfg, skip_postproc_filtering);
  RANGE_CHECK_HI(extra_cfg, enable_cdef, 3);
  RANGE_CHECK_BOOL(extra_cfg, auto_intra_tools_off);
  RANGE_CHECK_BOOL(extra_cfg, strict_level_conformance);
  RANGE_CHECK_BOOL(extra_cfg, sb_qp_sweep);

  RANGE_CHECK(extra_cfg, kf_max_pyr_height, -1, 5);
  if (extra_cfg->kf_max_pyr_height != -1 &&
      extra_cfg->kf_max_pyr_height < (int)extra_cfg->gf_min_pyr_height) {
    ERROR(
        "The value of kf-max-pyr-height should not be smaller than "
        "gf-min-pyr-height");
  }

  return AOM_CODEC_OK;
}

static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
                                    const aom_image_t *img) {
  switch (img->fmt) {
    case AOM_IMG_FMT_YV12:
    case AOM_IMG_FMT_NV12:
    case AOM_IMG_FMT_I420:
    case AOM_IMG_FMT_YV1216:
    case AOM_IMG_FMT_I42016: break;
    case AOM_IMG_FMT_I444:
    case AOM_IMG_FMT_I44416:
      if (ctx->cfg.g_profile == (unsigned int)PROFILE_0 &&
          !ctx->cfg.monochrome) {
        ERROR("Invalid image format. I444 images not supported in profile.");
      }
      break;
    case AOM_IMG_FMT_I422:
    case AOM_IMG_FMT_I42216:
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_2) {
        ERROR("Invalid image format. I422 images not supported in profile.");
      }
      break;
    default:
      ERROR(
          "Invalid image format. Only YV12, NV12, I420, I422, I444 images are "
          "supported.");
      break;
  }

  if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
    ERROR("Image size must match encoder init configuration size");

#if CONFIG_TUNE_BUTTERAUGLI
  if (ctx->extra_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
    if (img->bit_depth > 8) {
      ERROR("Only 8 bit depth images supported in tune=butteraugli mode.");
    }
    if (img->mc != 0 && img->mc != AOM_CICP_MC_BT_709 &&
        img->mc != AOM_CICP_MC_BT_601 && img->mc != AOM_CICP_MC_BT_470_B_G) {
      ERROR(
          "Only BT.709 and BT.601 matrix coefficients supported in "
          "tune=butteraugli mode. Identity matrix is treated as BT.601.");
    }
  }
#endif

  return AOM_CODEC_OK;
}

static int get_image_bps(const aom_image_t *img) {
  switch (img->fmt) {
    case AOM_IMG_FMT_YV12:
    case AOM_IMG_FMT_NV12:
    case AOM_IMG_FMT_I420: return 12;
    case AOM_IMG_FMT_I422: return 16;
    case AOM_IMG_FMT_I444: return 24;
    case AOM_IMG_FMT_YV1216:
    case AOM_IMG_FMT_I42016: return 24;
    case AOM_IMG_FMT_I42216: return 32;
    case AOM_IMG_FMT_I44416: return 48;
    default: assert(0 && "Invalid image format"); break;
  }
  return 0;
}

// Set appropriate options to disable frame super-resolution.
static void disable_superres(SuperResCfg *const superres_cfg) {
  superres_cfg->superres_mode = AOM_SUPERRES_NONE;
  superres_cfg->superres_scale_denominator = SCALE_NUMERATOR;
  superres_cfg->superres_kf_scale_denominator = SCALE_NUMERATOR;
  superres_cfg->superres_qthresh = 255;
  superres_cfg->superres_kf_qthresh = 255;
}

static void set_auto_tiles(TileConfig *const tile_cfg, unsigned int width,
                           unsigned int height, unsigned int threads) {
  int tile_cols_log2 = 0;
  int tile_rows_log2 = 0;
  if (threads < 2) return;
  // Avoid small tiles because they are particularly bad for coding.
  // Use no more tiles than the number of threads. Aim for one tile per
  // thread. Using more than one thread inside one tile could be less
  // efficient. Using more tiles than the number of threads would result
  // in a compression penalty without much benefit.
  const uint32_t kMinTileArea = 128 * 128;
  const uint32_t kMaxTiles = 32;
  uint32_t frame_area = width * height;
  uint32_t tiles = (frame_area + kMinTileArea - 1) / kMinTileArea;
  if (tiles > kMaxTiles) {
    tiles = kMaxTiles;
  }
  if (tiles > threads) {
    tiles = threads;
  }
  int tiles_log2 = (int)log2(tiles);
  // If the frame width is equal or greater than the height, use more tile
  // columns than tile rows.
  if (width >= height) {
    tile_cols_log2 = (tiles_log2 + 1) / 2;
    tile_rows_log2 = tiles_log2 - tile_cols_log2;
  } else {
    tile_rows_log2 = (tiles_log2 + 1) / 2;
    tile_cols_log2 = tiles_log2 - tile_rows_log2;
  }
  tile_cfg->tile_columns = tile_cols_log2;
  tile_cfg->tile_rows = tile_rows_log2;
}

static void update_default_encoder_config(const cfg_options_t *cfg,
                                          struct av1_extracfg *extra_cfg) {
  extra_cfg->enable_cdef = (cfg->disable_cdef == 0) ? 1 : 0;
  extra_cfg->enable_restoration = (cfg->disable_lr == 0);
  extra_cfg->superblock_size =
      (cfg->super_block_size == 64)    ? AOM_SUPERBLOCK_SIZE_64X64
      : (cfg->super_block_size == 128) ? AOM_SUPERBLOCK_SIZE_128X128
                                       : AOM_SUPERBLOCK_SIZE_DYNAMIC;
  extra_cfg->enable_warped_motion = (cfg->disable_warp_motion == 0);
  extra_cfg->enable_dist_wtd_comp = (cfg->disable_dist_wtd_comp == 0);
  extra_cfg->enable_diff_wtd_comp = (cfg->disable_diff_wtd_comp == 0);
  extra_cfg->enable_dual_filter = (cfg->disable_dual_filter == 0);
  extra_cfg->enable_angle_delta = (cfg->disable_intra_angle_delta == 0);
  extra_cfg->enable_rect_partitions = (cfg->disable_rect_partition_type == 0);
  extra_cfg->enable_ab_partitions = (cfg->disable_ab_partition_type == 0);
  extra_cfg->enable_1to4_partitions = (cfg->disable_1to4_partition_type == 0);
  extra_cfg->max_partition_size = cfg->max_partition_size;
  extra_cfg->min_partition_size = cfg->min_partition_size;
  extra_cfg->enable_intra_edge_filter = (cfg->disable_intra_edge_filter == 0);
  extra_cfg->enable_tx64 = (cfg->disable_tx_64x64 == 0);
  extra_cfg->enable_flip_idtx = (cfg->disable_flip_idtx == 0);
  extra_cfg->enable_masked_comp = (cfg->disable_masked_comp == 0);
  extra_cfg->enable_interintra_comp = (cfg->disable_inter_intra_comp == 0);
  extra_cfg->enable_smooth_interintra = (cfg->disable_smooth_inter_intra == 0);
  extra_cfg->enable_interinter_wedge = (cfg->disable_inter_inter_wedge == 0);
  extra_cfg->enable_interintra_wedge = (cfg->disable_inter_intra_wedge == 0);
  extra_cfg->enable_global_motion = (cfg->disable_global_motion == 0);
  extra_cfg->enable_filter_intra = (cfg->disable_filter_intra == 0);
  extra_cfg->enable_smooth_intra = (cfg->disable_smooth_intra == 0);
  extra_cfg->enable_paeth_intra = (cfg->disable_paeth_intra == 0);
  extra_cfg->enable_cfl_intra = (cfg->disable_cfl == 0);
  extra_cfg->enable_obmc = (cfg->disable_obmc == 0);
  extra_cfg->enable_palette = (cfg->disable_palette == 0);
  extra_cfg->enable_intrabc = (cfg->disable_intrabc == 0);
  extra_cfg->disable_trellis_quant = cfg->disable_trellis_quant;
  extra_cfg->allow_ref_frame_mvs = (cfg->disable_ref_frame_mv == 0);
  extra_cfg->enable_ref_frame_mvs = (cfg->disable_ref_frame_mv == 0);
  extra_cfg->enable_onesided_comp = (cfg->disable_one_sided_comp == 0);
  extra_cfg->enable_reduced_reference_set = cfg->reduced_reference_set;
  extra_cfg->reduced_tx_type_set = cfg->reduced_tx_type_set;
}

static void set_encoder_config(AV1EncoderConfig *oxcf,
                               const aom_codec_enc_cfg_t *cfg,
                               struct av1_extracfg *extra_cfg) {
  if (cfg->encoder_cfg.init_by_cfg_file) {
    update_default_encoder_config(&cfg->encoder_cfg, extra_cfg);
  }

  TuneCfg *const tune_cfg = &oxcf->tune_cfg;
  FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
  TileConfig *const tile_cfg = &oxcf->tile_cfg;
  ResizeCfg *const resize_cfg = &oxcf->resize_cfg;
  GFConfig *const gf_cfg = &oxcf->gf_cfg;
  PartitionCfg *const part_cfg = &oxcf->part_cfg;
  IntraModeCfg *const intra_mode_cfg = &oxcf->intra_mode_cfg;
  TxfmSizeTypeCfg *const txfm_cfg = &oxcf->txfm_cfg;
  CompoundTypeCfg *const comp_type_cfg = &oxcf->comp_type_cfg;
  SuperResCfg *const superres_cfg = &oxcf->superres_cfg;
  KeyFrameCfg *const kf_cfg = &oxcf->kf_cfg;
  DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
  RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
  QuantizationCfg *const q_cfg = &oxcf->q_cfg;
  ColorCfg *const color_cfg = &oxcf->color_cfg;
  InputCfg *const input_cfg = &oxcf->input_cfg;
  AlgoCfg *const algo_cfg = &oxcf->algo_cfg;
  ToolCfg *const tool_cfg = &oxcf->tool_cfg;

  const int is_vbr = cfg->rc_end_usage == AOM_VBR;
  oxcf->profile = cfg->g_profile;
  oxcf->max_threads = (int)cfg->g_threads;

  switch (cfg->g_usage) {
    case AOM_USAGE_REALTIME: oxcf->mode = REALTIME; break;
    case AOM_USAGE_ALL_INTRA: oxcf->mode = ALLINTRA; break;
    default: oxcf->mode = GOOD; break;
  }

  // Set frame-dimension related configuration.
  frm_dim_cfg->width = cfg->g_w;
  frm_dim_cfg->height = cfg->g_h;
  frm_dim_cfg->forced_max_frame_width = cfg->g_forced_max_frame_width;
  frm_dim_cfg->forced_max_frame_height = cfg->g_forced_max_frame_height;
  frm_dim_cfg->render_width = extra_cfg->render_width;
  frm_dim_cfg->render_height = extra_cfg->render_height;

  // Set input video related configuration.
  input_cfg->input_bit_depth = cfg->g_input_bit_depth;
  // guess a frame rate if out of whack, use 30
  input_cfg->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
  if (cfg->g_pass >= AOM_RC_SECOND_PASS) {
    const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
    input_cfg->limit = n_packets - 1;
  } else {
    input_cfg->limit = cfg->g_limit;
  }
  input_cfg->chroma_subsampling_x = extra_cfg->chroma_subsampling_x;
  input_cfg->chroma_subsampling_y = extra_cfg->chroma_subsampling_y;
  if (input_cfg->init_framerate > 180) {
    input_cfg->init_framerate = 30;
    dec_model_cfg->timing_info_present = 0;
  }

  // Set Decoder model configuration.
  if (extra_cfg->timing_info_type == AOM_TIMING_EQUAL ||
      extra_cfg->timing_info_type == AOM_TIMING_DEC_MODEL) {
    dec_model_cfg->timing_info_present = 1;
    dec_model_cfg->timing_info.num_units_in_display_tick = cfg->g_timebase.num;
    dec_model_cfg->timing_info.time_scale = cfg->g_timebase.den;
    dec_model_cfg->timing_info.num_ticks_per_picture = 1;
  } else {
    dec_model_cfg->timing_info_present = 0;
  }
  if (extra_cfg->timing_info_type == AOM_TIMING_EQUAL) {
    dec_model_cfg->timing_info.equal_picture_interval = 1;
    dec_model_cfg->decoder_model_info_present_flag = 0;
    dec_model_cfg->display_model_info_present_flag = 1;
  } else if (extra_cfg->timing_info_type == AOM_TIMING_DEC_MODEL) {
    dec_model_cfg->num_units_in_decoding_tick = cfg->g_timebase.num;
    dec_model_cfg->timing_info.equal_picture_interval = 0;
    dec_model_cfg->decoder_model_info_present_flag = 1;
    dec_model_cfg->display_model_info_present_flag = 1;
  }

  oxcf->pass = cfg->g_pass;
  // For backward compatibility, assume that if extra_cfg->passes==-1, then
  // passes = 1 or 2.
  if (extra_cfg->passes == -1) {
    if (cfg->g_pass == AOM_RC_ONE_PASS) {
      oxcf->passes = 1;
    } else {
      oxcf->passes = 2;
    }
  } else {
    oxcf->passes = extra_cfg->passes;
  }

  // Set Rate Control configuration.
  rc_cfg->max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
  rc_cfg->max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
  rc_cfg->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
  rc_cfg->mode = cfg->rc_end_usage;
  rc_cfg->min_cr = extra_cfg->min_cr;
  rc_cfg->best_allowed_q =
      extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
  rc_cfg->worst_allowed_q =
      extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_max_quantizer);
  rc_cfg->cq_level = av1_quantizer_to_qindex(extra_cfg->cq_level);
  rc_cfg->under_shoot_pct = cfg->rc_undershoot_pct;
  rc_cfg->over_shoot_pct = cfg->rc_overshoot_pct;
  rc_cfg->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
  rc_cfg->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
  rc_cfg->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
  // Convert target bandwidth from Kbit/s to Bit/s
  rc_cfg->target_bandwidth = 1000 * cfg->rc_target_bitrate;
  rc_cfg->drop_frames_water_mark = cfg->rc_dropframe_thresh;
  rc_cfg->vbr_corpus_complexity_lap = extra_cfg->vbr_corpus_complexity_lap;
  rc_cfg->vbrbias = cfg->rc_2pass_vbr_bias_pct;
  rc_cfg->vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
  rc_cfg->vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;

  // Set Toolset related configuration.
  tool_cfg->bit_depth = cfg->g_bit_depth;
  tool_cfg->cdef_control = (CDEF_CONTROL)extra_cfg->enable_cdef;
  tool_cfg->enable_restoration =
      (cfg->g_usage == AOM_USAGE_REALTIME) ? 0 : extra_cfg->enable_restoration;
  tool_cfg->force_video_mode = extra_cfg->force_video_mode;
  tool_cfg->enable_palette = extra_cfg->enable_palette;
  // FIXME(debargha): Should this be:
  // tool_cfg->enable_ref_frame_mvs  = extra_cfg->allow_ref_frame_mvs &
  //                                         extra_cfg->enable_order_hint ?
  // Disallow using temporal MVs while large_scale_tile = 1.
  tool_cfg->enable_ref_frame_mvs =
      extra_cfg->allow_ref_frame_mvs && !cfg->large_scale_tile;
  tool_cfg->superblock_size = extra_cfg->superblock_size;
  tool_cfg->enable_monochrome = cfg->monochrome;
  tool_cfg->full_still_picture_hdr = cfg->full_still_picture_hdr != 0;
  tool_cfg->enable_dual_filter = extra_cfg->enable_dual_filter;
  tool_cfg->enable_order_hint = extra_cfg->enable_order_hint;
  tool_cfg->enable_interintra_comp = extra_cfg->enable_interintra_comp;
  tool_cfg->ref_frame_mvs_present =
      extra_cfg->enable_ref_frame_mvs & extra_cfg->enable_order_hint;

  // Explicitly disable global motion in a few cases:
  // * For realtime mode, we never search global motion, and disabling
  //   it here prevents later code from allocating buffers we don't need
  // * For large scale tile mode, some of the intended use cases expect
  //   all frame headers to be identical. This breaks if global motion is
  //   used, since global motion data is stored in the frame header.
  //   eg, see test/lightfield_test.sh, which checks that all frame headers
  //   are the same.
  tool_cfg->enable_global_motion = extra_cfg->enable_global_motion &&
                                   cfg->g_usage != AOM_USAGE_REALTIME &&
                                   !cfg->large_scale_tile;

  tool_cfg->error_resilient_mode =
      cfg->g_error_resilient | extra_cfg->error_resilient_mode;
  tool_cfg->frame_parallel_decoding_mode =
      extra_cfg->frame_parallel_decoding_mode;

  // Set Quantization related configuration.
  q_cfg->using_qm = extra_cfg->enable_qm;
  q_cfg->qm_minlevel = extra_cfg->qm_min;
  q_cfg->qm_maxlevel = extra_cfg->qm_max;
  q_cfg->quant_b_adapt = extra_cfg->quant_b_adapt;
  q_cfg->enable_chroma_deltaq = extra_cfg->enable_chroma_deltaq;
  q_cfg->aq_mode = extra_cfg->aq_mode;
  q_cfg->deltaq_mode = extra_cfg->deltaq_mode;
  q_cfg->deltaq_strength = extra_cfg->deltaq_strength;
  q_cfg->use_fixed_qp_offsets =
      cfg->use_fixed_qp_offsets && (rc_cfg->mode == AOM_Q);
  q_cfg->enable_hdr_deltaq =
      (q_cfg->deltaq_mode == DELTA_Q_HDR) &&
      (cfg->g_bit_depth == AOM_BITS_10) &&
      (extra_cfg->color_primaries == AOM_CICP_CP_BT_2020);

  tool_cfg->enable_deltalf_mode =
      (q_cfg->deltaq_mode != NO_DELTA_Q) && extra_cfg->deltalf_mode;

  // Set cost update frequency configuration.
  oxcf->cost_upd_freq.coeff = (COST_UPDATE_TYPE)extra_cfg->coeff_cost_upd_freq;
  oxcf->cost_upd_freq.mode = (COST_UPDATE_TYPE)extra_cfg->mode_cost_upd_freq;
  // Avoid MV cost update for allintra encoding mode.
  oxcf->cost_upd_freq.mv = (cfg->kf_max_dist != 0)
                               ? (COST_UPDATE_TYPE)extra_cfg->mv_cost_upd_freq
                               : COST_UPD_OFF;
  oxcf->cost_upd_freq.dv = (COST_UPDATE_TYPE)extra_cfg->dv_cost_upd_freq;

  // Set frame resize mode configuration.
  resize_cfg->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
  resize_cfg->resize_scale_denominator = (uint8_t)cfg->rc_resize_denominator;
  resize_cfg->resize_kf_scale_denominator =
      (uint8_t)cfg->rc_resize_kf_denominator;
  if (resize_cfg->resize_mode == RESIZE_FIXED &&
      resize_cfg->resize_scale_denominator == SCALE_NUMERATOR &&
      resize_cfg->resize_kf_scale_denominator == SCALE_NUMERATOR)
    resize_cfg->resize_mode = RESIZE_NONE;

  // Set encoder algorithm related configuration.
  algo_cfg->enable_overlay = extra_cfg->enable_overlay;
  algo_cfg->disable_trellis_quant = extra_cfg->disable_trellis_quant;
  algo_cfg->sharpness = extra_cfg->sharpness;
  algo_cfg->arnr_max_frames = extra_cfg->arnr_max_frames;
  algo_cfg->arnr_strength = extra_cfg->arnr_strength;
  algo_cfg->cdf_update_mode = (uint8_t)extra_cfg->cdf_update_mode;
  // TODO(any): Fix and Enable TPL for resize-mode > 0
  algo_cfg->enable_tpl_model =
      resize_cfg->resize_mode ? 0 : extra_cfg->enable_tpl_model;
  algo_cfg->loopfilter_control = extra_cfg->loopfilter_control;
  algo_cfg->skip_postproc_filtering = extra_cfg->skip_postproc_filtering;

  // Set two-pass stats configuration.
  oxcf->twopass_stats_in = cfg->rc_twopass_stats_in;

  if (extra_cfg->two_pass_output)
    oxcf->two_pass_output = extra_cfg->two_pass_output;

  oxcf->second_pass_log = extra_cfg->second_pass_log;

  // Set Key frame configuration.
  kf_cfg->fwd_kf_enabled = cfg->fwd_kf_enabled;
  kf_cfg->auto_key =
      cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
  kf_cfg->key_freq_min = cfg->kf_min_dist;
  kf_cfg->key_freq_max = cfg->kf_max_dist;
  kf_cfg->sframe_dist = cfg->sframe_dist;
  kf_cfg->sframe_mode = cfg->sframe_mode;
  kf_cfg->enable_sframe = extra_cfg->s_frame_mode;
  kf_cfg->enable_keyframe_filtering = extra_cfg->enable_keyframe_filtering;
  kf_cfg->fwd_kf_dist = extra_cfg->fwd_kf_dist;
  // Disable key frame filtering in all intra mode.
  if (cfg->kf_max_dist == 0) {
    kf_cfg->enable_keyframe_filtering = 0;
  }
  kf_cfg->enable_intrabc = extra_cfg->enable_intrabc;

  oxcf->speed = extra_cfg->cpu_used;
  // TODO(yunqingwang, any) In REALTIME mode, 1080p performance at speed 5 & 6
  // is quite bad. Force to use speed 7 for now. Will investigate it when we
  // work on rd path optimization later.
  if (oxcf->mode == REALTIME && AOMMIN(cfg->g_w, cfg->g_h) >= 1080 &&
      oxcf->speed < 7)
    oxcf->speed = 7;

  // Set Color related configuration.
  color_cfg->color_primaries = extra_cfg->color_primaries;
  color_cfg->transfer_characteristics = extra_cfg->transfer_characteristics;
  color_cfg->matrix_coefficients = extra_cfg->matrix_coefficients;
  color_cfg->color_range = extra_cfg->color_range;
  color_cfg->chroma_sample_position = extra_cfg->chroma_sample_position;

  // Set Group of frames configuration.
  // Force lag_in_frames to 0 for REALTIME mode
  gf_cfg->lag_in_frames = (oxcf->mode == REALTIME)
                              ? 0
                              : clamp(cfg->g_lag_in_frames, 0, MAX_LAG_BUFFERS);
  gf_cfg->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
  gf_cfg->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
  gf_cfg->min_gf_interval = extra_cfg->min_gf_interval;
  gf_cfg->max_gf_interval = extra_cfg->max_gf_interval;
  gf_cfg->gf_min_pyr_height = extra_cfg->gf_min_pyr_height;
  gf_cfg->gf_max_pyr_height = extra_cfg->gf_max_pyr_height;

  // Set tune related configuration.
  tune_cfg->tuning = extra_cfg->tuning;
  tune_cfg->vmaf_model_path = extra_cfg->vmaf_model_path;
  tune_cfg->content = extra_cfg->content;
  if (cfg->large_scale_tile) {
    tune_cfg->film_grain_test_vector = 0;
    tune_cfg->film_grain_table_filename = NULL;
  } else {
    tune_cfg->film_grain_test_vector = extra_cfg->film_grain_test_vector;
    tune_cfg->film_grain_table_filename = extra_cfg->film_grain_table_filename;
  }
  tune_cfg->dist_metric = extra_cfg->dist_metric;
#if CONFIG_DENOISE
  oxcf->noise_level = extra_cfg->noise_level;
  oxcf->noise_block_size = extra_cfg->noise_block_size;
  oxcf->enable_dnl_denoising = extra_cfg->enable_dnl_denoising;
#endif

#if CONFIG_AV1_TEMPORAL_DENOISING
  // Temporal denoiser is for nonrd pickmode so disable it for speed < 7.
  // Also disable it for speed 7 for now since it needs to be modified for
  // the check_partition_merge_mode feature.
  if (cfg->g_bit_depth == AOM_BITS_8 && oxcf->speed > 7) {
    oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
  } else {
    oxcf->noise_sensitivity = 0;
  }
#endif
  // Set Tile related configuration.
  tile_cfg->num_tile_groups = extra_cfg->num_tg;
  // In large-scale tile encoding mode, num_tile_groups is always 1.
  if (cfg->large_scale_tile) tile_cfg->num_tile_groups = 1;
  tile_cfg->mtu = extra_cfg->mtu_size;
  tile_cfg->enable_large_scale_tile = cfg->large_scale_tile;
  tile_cfg->enable_single_tile_decoding =
      (tile_cfg->enable_large_scale_tile) ? extra_cfg->single_tile_decoding : 0;
  if (extra_cfg->auto_tiles) {
    set_auto_tiles(tile_cfg, cfg->g_w, cfg->g_h, cfg->g_threads);
    extra_cfg->tile_columns = tile_cfg->tile_columns;
    extra_cfg->tile_rows = tile_cfg->tile_rows;
  } else {
    tile_cfg->tile_columns = extra_cfg->tile_columns;
    tile_cfg->tile_rows = extra_cfg->tile_rows;
  }
  tile_cfg->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS);
  tile_cfg->tile_height_count = AOMMIN(cfg->tile_height_count, MAX_TILE_ROWS);
  for (int i = 0; i < tile_cfg->tile_width_count; i++) {
    tile_cfg->tile_widths[i] = cfg->tile_widths[i];
  }
  for (int i = 0; i < tile_cfg->tile_height_count; i++) {
    tile_cfg->tile_heights[i] = cfg->tile_heights[i];
  }
  tile_cfg->enable_ext_tile_debug = extra_cfg->ext_tile_debug;

  if (tile_cfg->enable_large_scale_tile) {
    // The superblock_size can only be AOM_SUPERBLOCK_SIZE_64X64 or
    // AOM_SUPERBLOCK_SIZE_128X128 while tile_cfg->enable_large_scale_tile = 1.
    // If superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC, hard set it to
    // AOM_SUPERBLOCK_SIZE_64X64(default value in large_scale_tile).
    if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64 &&
        extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_128X128)
      tool_cfg->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
  }

  // Set reference frame related configuration.
  oxcf->ref_frm_cfg.max_reference_frames = extra_cfg->max_reference_frames;
  oxcf->ref_frm_cfg.enable_reduced_reference_set =
      extra_cfg->enable_reduced_reference_set;
  oxcf->ref_frm_cfg.enable_onesided_comp = extra_cfg->enable_onesided_comp;

  oxcf->row_mt = extra_cfg->row_mt;
  oxcf->fp_mt = extra_cfg->fp_mt;

  // Set motion mode related configuration.
  oxcf->motion_mode_cfg.enable_obmc = extra_cfg->enable_obmc;
  oxcf->motion_mode_cfg.enable_warped_motion = extra_cfg->enable_warped_motion;
#if !CONFIG_REALTIME_ONLY
  if (cfg->g_usage == AOM_USAGE_REALTIME && oxcf->speed >= 7 &&
      oxcf->tune_cfg.content == AOM_CONTENT_SCREEN) {
    // TODO(marpan): warped motion is causing a crash for RT mode with screen
    // in nonrd (speed >= 7), for non-realtime build.
    // Re-enable/allow when the issue is fixed.
    oxcf->motion_mode_cfg.enable_warped_motion = 0;
    oxcf->motion_mode_cfg.allow_warped_motion = 0;
  } else {
    oxcf->motion_mode_cfg.allow_warped_motion =
        (extra_cfg->allow_warped_motion & extra_cfg->enable_warped_motion);
  }
#else
  oxcf->motion_mode_cfg.allow_warped_motion =
      (cfg->g_usage == AOM_USAGE_REALTIME && oxcf->speed >= 7)
          ? false
          : (extra_cfg->allow_warped_motion & extra_cfg->enable_warped_motion);
#endif

  // Set partition related configuration.
  part_cfg->enable_rect_partitions = extra_cfg->enable_rect_partitions;
  part_cfg->enable_ab_partitions = extra_cfg->enable_ab_partitions;
  part_cfg->enable_1to4_partitions = extra_cfg->enable_1to4_partitions;
  part_cfg->min_partition_size = extra_cfg->min_partition_size;
  part_cfg->max_partition_size = extra_cfg->max_partition_size;

  // Set intra mode configuration.
  intra_mode_cfg->enable_angle_delta = extra_cfg->enable_angle_delta;
  intra_mode_cfg->enable_intra_edge_filter =
      extra_cfg->enable_intra_edge_filter;
  intra_mode_cfg->enable_filter_intra = extra_cfg->enable_filter_intra;
  intra_mode_cfg->enable_smooth_intra = extra_cfg->enable_smooth_intra;
  intra_mode_cfg->enable_paeth_intra = extra_cfg->enable_paeth_intra;
  intra_mode_cfg->enable_cfl_intra = extra_cfg->enable_cfl_intra;
  intra_mode_cfg->enable_directional_intra =
      extra_cfg->enable_directional_intra;
  intra_mode_cfg->enable_diagonal_intra = extra_cfg->enable_diagonal_intra;
  intra_mode_cfg->auto_intra_tools_off = extra_cfg->auto_intra_tools_off;

  // Set transform size/type configuration.
  txfm_cfg->enable_tx64 = extra_cfg->enable_tx64;
  txfm_cfg->enable_flip_idtx = extra_cfg->enable_flip_idtx;
  txfm_cfg->enable_rect_tx = extra_cfg->enable_rect_tx;
  txfm_cfg->reduced_tx_type_set = extra_cfg->reduced_tx_type_set;
  txfm_cfg->use_intra_dct_only = extra_cfg->use_intra_dct_only;
  txfm_cfg->use_inter_dct_only = extra_cfg->use_inter_dct_only;
  txfm_cfg->use_intra_default_tx_only = extra_cfg->use_intra_default_tx_only;
  txfm_cfg->enable_tx_size_search = extra_cfg->enable_tx_size_search;

  // Set compound type configuration.
  comp_type_cfg->enable_dist_wtd_comp =
      extra_cfg->enable_dist_wtd_comp & extra_cfg->enable_order_hint;
  comp_type_cfg->enable_masked_comp = extra_cfg->enable_masked_comp;
  comp_type_cfg->enable_diff_wtd_comp =
      extra_cfg->enable_masked_comp & extra_cfg->enable_diff_wtd_comp;
  comp_type_cfg->enable_interinter_wedge =
      extra_cfg->enable_masked_comp & extra_cfg->enable_interinter_wedge;
  comp_type_cfg->enable_smooth_interintra =
      extra_cfg->enable_interintra_comp && extra_cfg->enable_smooth_interintra;
  comp_type_cfg->enable_interintra_wedge =
      extra_cfg->enable_interintra_comp & extra_cfg->enable_interintra_wedge;

  // Set Super-resolution mode configuration.
  if (extra_cfg->lossless || cfg->large_scale_tile) {
    disable_superres(superres_cfg);
  } else {
    superres_cfg->superres_mode = cfg->rc_superres_mode;
    superres_cfg->superres_scale_denominator =
        (uint8_t)cfg->rc_superres_denominator;
    superres_cfg->superres_kf_scale_denominator =
        (uint8_t)cfg->rc_superres_kf_denominator;
    superres_cfg->superres_qthresh =
        av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
    superres_cfg->superres_kf_qthresh =
        av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh);
    if (superres_cfg->superres_mode == AOM_SUPERRES_FIXED &&
        superres_cfg->superres_scale_denominator == SCALE_NUMERATOR &&
        superres_cfg->superres_kf_scale_denominator == SCALE_NUMERATOR) {
      disable_superres(superres_cfg);
    }
    if (superres_cfg->superres_mode == AOM_SUPERRES_QTHRESH &&
        superres_cfg->superres_qthresh == 255 &&
        superres_cfg->superres_kf_qthresh == 255) {
      disable_superres(superres_cfg);
    }
  }

  superres_cfg->enable_superres =
      (superres_cfg->superres_mode != AOM_SUPERRES_NONE) &&
      extra_cfg->enable_superres;
  if (!superres_cfg->enable_superres) {
    disable_superres(superres_cfg);
  }

  if (input_cfg->limit == 1) {
    // still picture mode, display model and timing is meaningless
    dec_model_cfg->display_model_info_present_flag = 0;
    dec_model_cfg->timing_info_present = 0;
  }

  oxcf->save_as_annexb = cfg->save_as_annexb;

  // Set unit test related configuration.
  oxcf->unit_test_cfg.motion_vector_unit_test =
      extra_cfg->motion_vector_unit_test;
  oxcf->unit_test_cfg.sb_multipass_unit_test =
      extra_cfg->sb_multipass_unit_test;

  oxcf->border_in_pixels =
      av1_get_enc_border_size(av1_is_resize_needed(oxcf),
                              (oxcf->kf_cfg.key_freq_max == 0), BLOCK_128X128);
  memcpy(oxcf->target_seq_level_idx, extra_cfg->target_seq_level_idx,
         sizeof(oxcf->target_seq_level_idx));
  oxcf->tier_mask = extra_cfg->tier_mask;

  oxcf->partition_info_path = extra_cfg->partition_info_path;

  oxcf->enable_rate_guide_deltaq = extra_cfg->enable_rate_guide_deltaq;
  oxcf->rate_distribution_info = extra_cfg->rate_distribution_info;

  oxcf->strict_level_conformance = extra_cfg->strict_level_conformance;

  oxcf->kf_max_pyr_height = extra_cfg->kf_max_pyr_height;

  oxcf->sb_qp_sweep = extra_cfg->sb_qp_sweep;
}

AV1EncoderConfig av1_get_encoder_config(const aom_codec_enc_cfg_t *cfg) {
  AV1EncoderConfig oxcf;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=81 H=89 G=84

¤ Dauer der Verarbeitung: 0.21 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.