chromium/third_party/libaom/source/libaom/av1/encoder/encoder.h

/*
 * 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.
 */

/*!\file
 * \brief Declares top-level encoder structures and functions.
 */
#ifndef AOM_AV1_ENCODER_ENCODER_H_
#define AOM_AV1_ENCODER_ENCODER_H_

#include <stdbool.h>
#include <stdio.h>

#include "config/aom_config.h"

#include "aom/aomcx.h"
#include "aom_util/aom_pthread.h"

#include "av1/common/alloccommon.h"
#include "av1/common/av1_common_int.h"
#include "av1/common/blockd.h"
#include "av1/common/entropymode.h"
#include "av1/common/enums.h"
#include "av1/common/reconintra.h"
#include "av1/common/resize.h"
#include "av1/common/thread_common.h"
#include "av1/common/timing.h"

#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/av1_quantize.h"
#include "av1/encoder/block.h"
#include "av1/encoder/context_tree.h"
#include "av1/encoder/enc_enums.h"
#include "av1/encoder/encodemb.h"
#include "av1/encoder/external_partition.h"
#include "av1/encoder/firstpass.h"
#include "av1/encoder/global_motion.h"
#include "av1/encoder/level.h"
#include "av1/encoder/lookahead.h"
#include "av1/encoder/mcomp.h"
#include "av1/encoder/pickcdef.h"
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/rd.h"
#include "av1/encoder/speed_features.h"
#include "av1/encoder/svc_layercontext.h"
#include "av1/encoder/temporal_filter.h"
#if CONFIG_THREE_PASS
#include "av1/encoder/thirdpass.h"
#endif
#include "av1/encoder/tokenize.h"
#include "av1/encoder/tpl_model.h"
#include "av1/encoder/av1_noise_estimate.h"
#include "av1/encoder/bitstream.h"

#if CONFIG_INTERNAL_STATS
#include "aom_dsp/ssim.h"
#endif
#include "aom_dsp/variance.h"
#if CONFIG_DENOISE
#include "aom_dsp/noise_model.h"
#endif
#if CONFIG_TUNE_VMAF
#include "av1/encoder/tune_vmaf.h"
#endif
#if CONFIG_AV1_TEMPORAL_DENOISING
#include "av1/encoder/av1_temporal_denoiser.h"
#endif
#if CONFIG_TUNE_BUTTERAUGLI
#include "av1/encoder/tune_butteraugli.h"
#endif

#include "aom/internal/aom_codec_internal.h"

#ifdef __cplusplus
extern "C" {
#endif

// TODO(yunqing, any): Added suppression tag to quiet Doxygen warnings. Need to
// adjust it while we work on documentation.
/*!\cond */
// Number of frames required to test for scene cut detection
#define SCENE_CUT_KEY_TEST_INTERVAL

// Lookahead index threshold to enable temporal filtering for second arf.
#define TF_LOOKAHEAD_IDX_THR

#define HDR_QP_LEVELS
#define CHROMA_CB_QP_SCALE
#define CHROMA_CR_QP_SCALE
#define CHROMA_QP_SCALE
#define CHROMA_QP_OFFSET
#define QP_SCALE_FACTOR
#define DISABLE_HDR_LUMA_DELTAQ

// Rational number with an int64 numerator
// This structure holds a fractional value
aom_rational64_t;  // alias for struct aom_rational

enum {} UENUM1BYTE();

enum {} UENUM1BYTE();

#if CONFIG_FPMT_TEST
enum {
  PARALLEL_ENCODE = 0,
  PARALLEL_SIMULATION_ENCODE,
  NUM_FPMT_TEST_ENCODES
} UENUM1BYTE(FPMT_TEST_ENC_CFG);
#endif  // CONFIG_FPMT_TEST
// 0 level frames are sometimes used for rate control purposes, but for
// reference mapping purposes, the minimum level should be 1.
#define MIN_PYR_LEVEL
static inline int get_true_pyr_level(int frame_level, int frame_order,
                                     int max_layer_depth) {}

enum {} UENUM1BYTE();
enum {} UENUM1BYTE();

enum {} UENUM1BYTE();

enum {} UENUM1BYTE();

enum {} UENUM1BYTE();

#define MAX_VBR_CORPUS_COMPLEXITY

MULTI_THREADED_MODULES;

/*!\endcond */

/*!\enum COST_UPDATE_TYPE
 * \brief    This enum controls how often the entropy costs should be updated.
 * \warning  In case of any modifications/additions done to the enum
 * COST_UPDATE_TYPE, the enum INTERNAL_COST_UPDATE_TYPE needs to be updated as
 * well.
 */
COST_UPDATE_TYPE;

/*!\enum LOOPFILTER_CONTROL
 * \brief This enum controls to which frames loopfilter is applied.
 */
LOOPFILTER_CONTROL;

/*!\enum SKIP_APPLY_POSTPROC_FILTER
 * \brief This enum controls the application of post-processing filters on a
 * reconstructed frame.
 */
SKIP_APPLY_POSTPROC_FILTER;

/*!
 * \brief Encoder config related to resize.
 */
ResizeCfg;

/*!
 * \brief Encoder config for coding block partitioning.
 */
PartitionCfg;

/*!
 * \brief Encoder flags for intra prediction.
 */
IntraModeCfg;

/*!
 * \brief Encoder flags for transform sizes and types.
 */
TxfmSizeTypeCfg;

/*!
 * \brief Encoder flags for compound prediction modes.
 */
CompoundTypeCfg;

/*!
 * \brief Encoder config related to frame super-resolution.
 */
SuperResCfg;

/*!
 * \brief Encoder config related to the coding of key frames.
 */
KeyFrameCfg;

/*!
 * \brief Encoder rate control configuration parameters
 */
RateControlCfg;

/*!\cond */
GFConfig;

TileConfig;

FrameDimensionCfg;

MotionModeCfg;

DecoderModelCfg;

CostUpdateFreq;

RefFrameCfg;

ColorCfg;

UnitTestCfg;

TuneCfg;

InputCfg;

QuantizationCfg;

/*!\endcond */
/*!
 * \brief Algorithm configuration parameters.
 */
AlgoCfg;
/*!\cond */

ToolCfg;

/*!\endcond */
/*!
 * \brief Main encoder configuration data structure.
 */
AV1EncoderConfig;

/*!\cond */
static inline int is_lossless_requested(const RateControlCfg *const rc_cfg) {}
/*!\endcond */

/*!
 * \brief Encoder-side probabilities for pruning of various AV1 tools
 */
FrameProbInfo;

/*!\cond */

FRAME_COUNTS;

#define INTER_MODE_RD_DATA_OVERALL_SIZE

InterModeRdModel;

RdIdxPair;
// TODO(angiebird): This is an estimated size. We still need to figure what is
// the maximum number of modes.
#define MAX_INTER_MODES
// TODO(any): rename this struct to something else. There is already another
// struct called inter_mode_info, which makes this terribly confusing.
/*!\endcond */
/*!
 * \brief Struct used to hold inter mode data for fast tx search.
 *
 * This struct is used to perform a full transform search only on winning
 * candidates searched with an estimate for transform coding RD.
 */
InterModesInfo;

/*!\cond */
VPartVar;

VPVariance;

VP4x4;

VP8x8;

VP16x16;

VP32x32;

VP64x64;

VP128x128;

/*!\endcond */

/*!
 * \brief Thresholds for variance based partitioning.
 */
VarBasedPartitionInfo;

/*!
 * \brief Encoder parameters for synchronization of row based multi-threading
 */
AV1EncRowMultiThreadSync;

/*!\cond */

// TODO(jingning) All spatially adaptive variables should go to TileDataEnc.
TileDataEnc;

RD_COUNTS;

ThreadData;

struct EncWorkerData;

/*!\endcond */

/*!
 * \brief Encoder data related to row-based multi-threading
 */
AV1EncRowMultiThreadInfo;

/*!
 * \brief Encoder data related to multi-threading for allintra deltaq-mode=3
 */
AV1EncAllIntraMultiThreadInfo;

/*!
 * \brief Max number of recodes used to track the frame probabilities.
 */
#define NUM_RECODES_PER_FRAME

/*!
 * \brief Max number of frames that can be encoded in a parallel encode set.
 */
#define MAX_PARALLEL_FRAMES

/*!
 * \brief Buffers to be backed up during parallel encode set to be restored
 * later.
 */
RestoreStateBuffers;

/*!
 * \brief Parameters related to restoration types.
 */
RestUnitSearchInfo;

/*!
 * \brief Structure to hold search parameter per restoration unit and
 * intermediate buffer of Wiener filter used in pick filter stage of Loop
 * restoration.
 */
AV1LrPickStruct;

/*!
 * \brief Primary Encoder parameters related to multi-threading.
 */
PrimaryMultiThreadInfo;

/*!
 * \brief Encoder parameters related to multi-threading.
 */
MultiThreadInfo;

/*!\cond */

ActiveMap;

/*!\endcond */

/*!
 * \brief Encoder info used for decision on forcing integer motion vectors.
 */
ForceIntegerMVInfo;

/*!\cond */

#if CONFIG_INTERNAL_STATS
// types of stats
enum {
  STAT_Y,
  STAT_U,
  STAT_V,
  STAT_ALL,
  NUM_STAT_TYPES  // This should always be the last member of the enum
} UENUM1BYTE(StatType);

typedef struct IMAGE_STAT {
  double stat[NUM_STAT_TYPES];
  double worst;
} ImageStat;
#endif  // CONFIG_INTERNAL_STATS

EncRefCntBuffer;

/*!\endcond */

/*!
 * \brief Buffer to store mode information at mi_alloc_bsize (4x4 or 8x8) level
 *
 * This is used for bitstream preparation.
 */
MBMIExtFrameBufferInfo;

/*!\cond */

#if CONFIG_COLLECT_PARTITION_STATS
typedef struct FramePartitionTimingStats {
  int partition_decisions[6][EXT_PARTITION_TYPES];
  int partition_attempts[6][EXT_PARTITION_TYPES];
  int64_t partition_times[6][EXT_PARTITION_TYPES];

  int partition_redo;
} FramePartitionTimingStats;
#endif  // CONFIG_COLLECT_PARTITION_STATS

#if CONFIG_COLLECT_COMPONENT_TIMING
#include "aom_ports/aom_timer.h"
// Adjust the following to add new components.
enum {
  av1_encode_strategy_time,
  av1_get_one_pass_rt_params_time,
  av1_get_second_pass_params_time,
  denoise_and_encode_time,
  apply_filtering_time,
  av1_tpl_setup_stats_time,
  encode_frame_to_data_rate_time,
  encode_with_or_without_recode_time,
  loop_filter_time,
  cdef_time,
  loop_restoration_time,
  av1_pack_bitstream_final_time,
  av1_encode_frame_time,
  av1_compute_global_motion_time,
  av1_setup_motion_field_time,
  encode_sb_row_time,

  rd_pick_partition_time,
  rd_use_partition_time,
  choose_var_based_partitioning_time,
  av1_prune_partitions_time,
  none_partition_search_time,
  split_partition_search_time,
  rectangular_partition_search_time,
  ab_partitions_search_time,
  rd_pick_4partition_time,
  encode_sb_time,

  rd_pick_sb_modes_time,
  av1_rd_pick_intra_mode_sb_time,
  av1_rd_pick_inter_mode_sb_time,
  set_params_rd_pick_inter_mode_time,
  skip_inter_mode_time,
  handle_inter_mode_time,
  evaluate_motion_mode_for_winner_candidates_time,
  do_tx_search_time,
  handle_intra_mode_time,
  refine_winner_mode_tx_time,
  av1_search_palette_mode_time,
  handle_newmv_time,
  compound_type_rd_time,
  interpolation_filter_search_time,
  motion_mode_rd_time,

  nonrd_use_partition_time,
  pick_sb_modes_nonrd_time,
  hybrid_intra_mode_search_time,
  nonrd_pick_inter_mode_sb_time,
  encode_b_nonrd_time,

  kTimingComponents,
} UENUM1BYTE(TIMING_COMPONENT);

static inline char const *get_component_name(int index) {
  switch (index) {
    case av1_encode_strategy_time: return "av1_encode_strategy_time";
    case av1_get_one_pass_rt_params_time:
      return "av1_get_one_pass_rt_params_time";
    case av1_get_second_pass_params_time:
      return "av1_get_second_pass_params_time";
    case denoise_and_encode_time: return "denoise_and_encode_time";
    case apply_filtering_time: return "apply_filtering_time";
    case av1_tpl_setup_stats_time: return "av1_tpl_setup_stats_time";
    case encode_frame_to_data_rate_time:
      return "encode_frame_to_data_rate_time";
    case encode_with_or_without_recode_time:
      return "encode_with_or_without_recode_time";
    case loop_filter_time: return "loop_filter_time";
    case cdef_time: return "cdef_time";
    case loop_restoration_time: return "loop_restoration_time";
    case av1_pack_bitstream_final_time: return "av1_pack_bitstream_final_time";
    case av1_encode_frame_time: return "av1_encode_frame_time";
    case av1_compute_global_motion_time:
      return "av1_compute_global_motion_time";
    case av1_setup_motion_field_time: return "av1_setup_motion_field_time";
    case encode_sb_row_time: return "encode_sb_row_time";

    case rd_pick_partition_time: return "rd_pick_partition_time";
    case rd_use_partition_time: return "rd_use_partition_time";
    case choose_var_based_partitioning_time:
      return "choose_var_based_partitioning_time";
    case av1_prune_partitions_time: return "av1_prune_partitions_time";
    case none_partition_search_time: return "none_partition_search_time";
    case split_partition_search_time: return "split_partition_search_time";
    case rectangular_partition_search_time:
      return "rectangular_partition_search_time";
    case ab_partitions_search_time: return "ab_partitions_search_time";
    case rd_pick_4partition_time: return "rd_pick_4partition_time";
    case encode_sb_time: return "encode_sb_time";

    case rd_pick_sb_modes_time: return "rd_pick_sb_modes_time";
    case av1_rd_pick_intra_mode_sb_time:
      return "av1_rd_pick_intra_mode_sb_time";
    case av1_rd_pick_inter_mode_sb_time:
      return "av1_rd_pick_inter_mode_sb_time";
    case set_params_rd_pick_inter_mode_time:
      return "set_params_rd_pick_inter_mode_time";
    case skip_inter_mode_time: return "skip_inter_mode_time";
    case handle_inter_mode_time: return "handle_inter_mode_time";
    case evaluate_motion_mode_for_winner_candidates_time:
      return "evaluate_motion_mode_for_winner_candidates_time";
    case do_tx_search_time: return "do_tx_search_time";
    case handle_intra_mode_time: return "handle_intra_mode_time";
    case refine_winner_mode_tx_time: return "refine_winner_mode_tx_time";
    case av1_search_palette_mode_time: return "av1_search_palette_mode_time";
    case handle_newmv_time: return "handle_newmv_time";
    case compound_type_rd_time: return "compound_type_rd_time";
    case interpolation_filter_search_time:
      return "interpolation_filter_search_time";
    case motion_mode_rd_time: return "motion_mode_rd_time";

    case nonrd_use_partition_time: return "nonrd_use_partition_time";
    case pick_sb_modes_nonrd_time: return "pick_sb_modes_nonrd_time";
    case hybrid_intra_mode_search_time: return "hybrid_intra_mode_search_time";
    case nonrd_pick_inter_mode_sb_time: return "nonrd_pick_inter_mode_sb_time";
    case encode_b_nonrd_time: return "encode_b_nonrd_time";

    default: assert(0);
  }
  return "error";
}
#endif

// The maximum number of internal ARFs except ALTREF_FRAME
#define MAX_INTERNAL_ARFS

/*!\endcond */

/*!
 * \brief Parameters related to global motion search
 */
GlobalMotionInfo;

/*!
 * \brief Flags related to interpolation filter search
 */
InterpSearchFlags;

/*!
 * \brief Parameters for motion vector search process
 */
MotionVectorSearchParams;

/*!
 * \brief Refresh frame flags for different type of frames.
 *
 * If the refresh flag is true for a particular reference frame, after the
 * current frame is encoded, the reference frame gets refreshed (updated) to
 * be the current frame. Note: Usually at most one flag will be set to true at
 * a time. But, for key-frames, all flags are set to true at once.
 */
RefreshFrameInfo;

/*!
 * \brief Desired dimensions for an externally triggered resize.
 *
 * When resize is triggered externally, the desired dimensions are stored in
 * this struct until used in the next frame to be coded. These values are
 * effective only for one frame and are reset after they are used.
 */
ResizePendingParams;

/*!
 * \brief Refrence frame distance related variables.
 */
RefFrameDistanceInfo;

/*!
 * \brief Parameters used for winner mode processing.
 *
 * This is a basic two pass approach: in the first pass, we reduce the number of
 * transform searches based on some thresholds during the rdopt process to find
 * the  "winner mode". In the second pass, we perform a more through tx search
 * on the winner mode.
 * There are some arrays in the struct, and their indices are used in the
 * following manner:
 * Index 0: Default mode evaluation, Winner mode processing is not applicable
 * (Eg : IntraBc).
 * Index 1: Mode evaluation.
 * Index 2: Winner mode evaluation
 * Index 1 and 2 are only used when the respective speed feature is on.
 */
WinnerModeParams;

/*!
 * \brief Frame refresh flags set by the external interface.
 *
 * Flags set by external interface to determine which reference buffers are
 * refreshed by this frame. When set, the encoder will update the particular
 * reference frame buffer with the contents of the current frame.
 */
ExtRefreshFrameFlagsInfo;

/*!
 * \brief Flags signalled by the external interface at frame level.
 */
ExternalFlags;

/*!\cond */

MV_STATS;

WeberStats;

CODING_CONTEXT;

FRAME_INFO;

/*!
 * \brief This structure stores different types of frame indices.
 */
FRAME_INDEX_SET;

/*!\endcond */

/*!
 * \brief Segmentation related information for the current frame.
 */
EncSegmentationInfo;

/*!
 * \brief Frame time stamps.
 */
TimeStamps;

/*!
 * Pointers to the memory allocated for frame level transform coeff related
 * info.
 */
CoeffBufferPool;

#if !CONFIG_REALTIME_ONLY
/*!\cond */
// DUCKY_ENCODE_FRAME_MODE is c version of EncodeFrameMode
enum {
  DUCKY_ENCODE_FRAME_MODE_NONE,  // Let native AV1 determine q index and rdmult
  DUCKY_ENCODE_FRAME_MODE_QINDEX,  // DuckyEncode determines q index and AV1
                                   // determines rdmult
  DUCKY_ENCODE_FRAME_MODE_QINDEX_RDMULT,  // DuckyEncode determines q index and
                                          // rdmult
} UENUM1BYTE(DUCKY_ENCODE_FRAME_MODE);

enum {
  DUCKY_ENCODE_GOP_MODE_NONE,  // native AV1 decides GOP
  DUCKY_ENCODE_GOP_MODE_RCL,   // rate control lib decides GOP
} UENUM1BYTE(DUCKY_ENCODE_GOP_MODE);

typedef struct DuckyEncodeFrameInfo {
  DUCKY_ENCODE_FRAME_MODE qp_mode;
  DUCKY_ENCODE_GOP_MODE gop_mode;
  int q_index;
  int rdmult;
  // These two arrays are equivalent to std::vector<SuperblockEncodeParameters>
  int *superblock_encode_qindex;
  int *superblock_encode_rdmult;
  int delta_q_enabled;
} DuckyEncodeFrameInfo;

typedef struct DuckyEncodeFrameResult {
  int global_order_idx;
  int q_index;
  int rdmult;
  int rate;
  int64_t dist;
  double psnr;
} DuckyEncodeFrameResult;

typedef struct DuckyEncodeInfo {
  DuckyEncodeFrameInfo frame_info;
  DuckyEncodeFrameResult frame_result;
} DuckyEncodeInfo;
/*!\endcond */
#endif

/*!\cond */
RTC_REF;
/*!\endcond */

/*!
 * \brief Structure to hold data corresponding to an encoded frame.
 */
AV1_COMP_DATA;

/*!
 * \brief Top level primary encoder structure
 */
AV1_PRIMARY;

/*!
 * \brief Top level encoder structure.
 */
AV1_COMP;

/*!
 * \brief Input frames and last input frame
 */
EncodeFrameInput;

/*!
 * \brief contains per-frame encoding parameters decided upon by
 * av1_encode_strategy() and passed down to av1_encode().
 */
EncodeFrameParams;

/*!\cond */

// EncodeFrameResults contains information about the result of encoding a
// single frame
EncodeFrameResults;

void av1_initialize_enc(unsigned int usage, enum aom_rc_mode end_usage);

struct AV1_COMP *av1_create_compressor(AV1_PRIMARY *ppi,
                                       const AV1EncoderConfig *oxcf,
                                       BufferPool *const pool,
                                       COMPRESSOR_STAGE stage,
                                       int lap_lag_in_frames);

struct AV1_PRIMARY *av1_create_primary_compressor(
    struct aom_codec_pkt_list *pkt_list_head, int num_lap_buffers,
    const AV1EncoderConfig *oxcf);

void av1_remove_compressor(AV1_COMP *cpi);

void av1_remove_primary_compressor(AV1_PRIMARY *ppi);

#if CONFIG_ENTROPY_STATS
void print_entropy_stats(AV1_PRIMARY *const ppi);
#endif
#if CONFIG_INTERNAL_STATS
void print_internal_stats(AV1_PRIMARY *ppi);
#endif

void av1_change_config_seq(AV1_PRIMARY *ppi, const AV1EncoderConfig *oxcf,
                           bool *sb_size_changed);

void av1_change_config(AV1_COMP *cpi, const AV1EncoderConfig *oxcf,
                       bool sb_size_changed);

aom_codec_err_t av1_check_initial_width(AV1_COMP *cpi, int use_highbitdepth,
                                        int subsampling_x, int subsampling_y);

void av1_post_encode_updates(AV1_COMP *const cpi,
                             const AV1_COMP_DATA *const cpi_data);

void av1_release_scaled_references_fpmt(AV1_COMP *cpi);

void av1_decrement_ref_counts_fpmt(BufferPool *buffer_pool,
                                   int ref_buffers_used_map);

void av1_init_sc_decisions(AV1_PRIMARY *const ppi);

AV1_COMP *av1_get_parallel_frame_enc_data(AV1_PRIMARY *const ppi,
                                          AV1_COMP_DATA *const first_cpi_data);

int av1_init_parallel_frame_context(const AV1_COMP_DATA *const first_cpi_data,
                                    AV1_PRIMARY *const ppi,
                                    int *ref_buffers_used_map);

/*!\endcond */

/*!\brief Obtain the raw frame data
 *
 * \ingroup high_level_algo
 * This function receives the raw frame data from input.
 *
 * \param[in]     cpi            Top-level encoder structure
 * \param[in]     frame_flags    Flags to decide how to encoding the frame
 * \param[in,out] sd             Contain raw frame data
 * \param[in]     time_stamp     Time stamp of the frame
 * \param[in]     end_time_stamp End time stamp
 *
 * \return Returns a value to indicate if the frame data is received
 * successfully.
 * \note The caller can assume that a copy of this frame is made and not just a
 * copy of the pointer.
 */
int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags,
                          const YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
                          int64_t end_time_stamp);

/*!\brief Encode a frame
 *
 * \ingroup high_level_algo
 * \callgraph
 * \callergraph
 * This function encodes the raw frame data, and outputs the frame bit stream
 * to the designated buffer. The caller should use the output parameters
 * cpi_data->ts_frame_start and cpi_data->ts_frame_end only when this function
 * returns AOM_CODEC_OK.
 *
 * \param[in]     cpi         Top-level encoder structure
 * \param[in,out] cpi_data    Data corresponding to a frame encode
 *
 * \return Returns a value to indicate if the encoding is done successfully.
 * \retval #AOM_CODEC_OK
 * \retval -1
 *     No frame encoded; more input is required.
 * \retval "A nonzero (positive) aom_codec_err_t code"
 *     The encoding failed with the error. Sets the error code and error message
 * in \c cpi->common.error.
 */
int av1_get_compressed_data(AV1_COMP *cpi, AV1_COMP_DATA *const cpi_data);

/*!\brief Run 1-pass/2-pass encoding
 *
 * \ingroup high_level_algo
 * \callgraph
 * \callergraph
 */
int av1_encode(AV1_COMP *const cpi, uint8_t *const dest, size_t dest_size,
               const EncodeFrameInput *const frame_input,
               const EncodeFrameParams *const frame_params,
               EncodeFrameResults *const frame_results);

/*!\cond */
int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest);

int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame);

aom_codec_err_t av1_copy_new_frame_enc(AV1_COMMON *cm,
                                       YV12_BUFFER_CONFIG *new_frame,
                                       YV12_BUFFER_CONFIG *sd);

int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags);

int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);

int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);

void av1_set_frame_size(AV1_COMP *cpi, int width, int height);

void av1_set_mv_search_params(AV1_COMP *cpi);

int av1_set_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);

int av1_get_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);

int av1_set_internal_size(AV1EncoderConfig *const oxcf,
                          ResizePendingParams *resize_pending_params,
                          AOM_SCALING_MODE horiz_mode,
                          AOM_SCALING_MODE vert_mode);

int av1_get_quantizer(struct AV1_COMP *cpi);

int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *input_size);

void av1_alloc_mb_wiener_var_pred_buf(AV1_COMMON *cm, ThreadData *td);

void av1_dealloc_mb_wiener_var_pred_buf(ThreadData *td);

// Set screen content options.
// This function estimates whether to use screen content tools, by counting
// the portion of blocks that have few luma colors.
// Modifies:
//   cpi->commom.features.allow_screen_content_tools
//   cpi->common.features.allow_intrabc
//   cpi->use_screen_content_tools
//   cpi->is_screen_content_type
// However, the estimation is not accurate and may misclassify videos.
// A slower but more accurate approach that determines whether to use screen
// content tools is employed later. See av1_determine_sc_tools_with_encoding().
void av1_set_screen_content_options(struct AV1_COMP *cpi,
                                    FeatureFlags *features);

void av1_update_frame_size(AV1_COMP *cpi);

RefFrameMapPair;

static inline void init_ref_map_pair(
    AV1_COMP *cpi, RefFrameMapPair ref_frame_map_pairs[REF_FRAMES]) {}

#if CONFIG_FPMT_TEST
static inline void calc_frame_data_update_flag(
    GF_GROUP *const gf_group, int gf_frame_index,
    bool *const do_frame_data_update) {
  *do_frame_data_update = true;
  // Set the flag to false for all frames in a given parallel encode set except
  // the last frame in the set with frame_parallel_level = 2.
  if (gf_group->frame_parallel_level[gf_frame_index] == 1) {
    *do_frame_data_update = false;
  } else if (gf_group->frame_parallel_level[gf_frame_index] == 2) {
    // Check if this is the last frame in the set with frame_parallel_level = 2.
    for (int i = gf_frame_index + 1; i < gf_group->size; i++) {
      if ((gf_group->frame_parallel_level[i] == 0 &&
           (gf_group->update_type[i] == ARF_UPDATE ||
            gf_group->update_type[i] == INTNL_ARF_UPDATE)) ||
          gf_group->frame_parallel_level[i] == 1) {
        break;
      } else if (gf_group->frame_parallel_level[i] == 2) {
        *do_frame_data_update = false;
        break;
      }
    }
  }
}
#endif

// av1 uses 10,000,000 ticks/second as time stamp
#define TICKS_PER_SEC

static inline int64_t timebase_units_to_ticks(
    const aom_rational64_t *timestamp_ratio, int64_t n) {}

static inline int64_t ticks_to_timebase_units(
    const aom_rational64_t *timestamp_ratio, int64_t n) {}

static inline int frame_is_kf_gf_arf(const AV1_COMP *cpi) {}

// TODO([email protected], [email protected]): enable hash-me for HBD.
static inline int av1_use_hash_me(const AV1_COMP *const cpi) {}

static inline const YV12_BUFFER_CONFIG *get_ref_frame_yv12_buf(
    const AV1_COMMON *const cm, MV_REFERENCE_FRAME ref_frame) {}

static inline void alloc_frame_mvs(AV1_COMMON *const cm, RefCntBuffer *buf) {}

// Get the allocated token size for a tile. It does the same calculation as in
// the frame token allocation.
static inline unsigned int allocated_tokens(const TileInfo *tile,
                                            int sb_size_log2, int num_planes) {}

static inline void get_start_tok(AV1_COMP *cpi, int tile_row, int tile_col,
                                 int mi_row, TokenExtra **tok, int sb_size_log2,
                                 int num_planes) {}

void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags);

#define ALT_MIN_LAG
static inline int is_altref_enabled(int lag_in_frames, bool enable_auto_arf) {}

static inline int can_disable_altref(const GFConfig *gf_cfg) {}

// Helper function to compute number of blocks on either side of the frame.
static inline int get_num_blocks(const int frame_length, const int mb_length) {}

// Check if statistics generation stage
static inline int is_stat_generation_stage(const AV1_COMP *const cpi) {}
// Check if statistics consumption stage
static inline int is_stat_consumption_stage_twopass(const AV1_COMP *const cpi) {}

// Check if statistics consumption stage
static inline int is_stat_consumption_stage(const AV1_COMP *const cpi) {}

// Decide whether 'dv_costs' need to be allocated/stored during the encoding.
static inline bool av1_need_dv_costs(const AV1_COMP *const cpi) {}

/*!\endcond */
/*!\brief Check if the current stage has statistics
 *
 *\ingroup two_pass_algo
 *
 * \param[in]    cpi     Top - level encoder instance structure
 *
 * \return 0 if no stats for current stage else 1
 */
static inline int has_no_stats_stage(const AV1_COMP *const cpi) {}

/*!\cond */

static inline int is_one_pass_rt_params(const AV1_COMP *cpi) {}

// Use default/internal reference structure for single-layer RTC.
static inline int use_rtc_reference_structure_one_layer(const AV1_COMP *cpi) {}

// Check if postencode drop is allowed.
static inline int allow_postencode_drop_rtc(const AV1_COMP *cpi) {}

// Function return size of frame stats buffer
static inline int get_stats_buf_size(int num_lap_buffer, int num_lag_buffer) {}

// TODO(zoeliu): To set up cpi->oxcf.gf_cfg.enable_auto_brf

static inline void set_ref_ptrs(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                MV_REFERENCE_FRAME ref0,
                                MV_REFERENCE_FRAME ref1) {}

static inline int get_chessboard_index(int frame_index) {}

static inline const int *cond_cost_list_const(const struct AV1_COMP *cpi,
                                              const int *cost_list) {}

static inline int *cond_cost_list(const struct AV1_COMP *cpi, int *cost_list) {}

// Compression ratio of current frame.
double av1_get_compression_ratio(const AV1_COMMON *const cm,
                                 size_t encoded_frame_size);

void av1_new_framerate(AV1_COMP *cpi, double framerate);

void av1_setup_frame_size(AV1_COMP *cpi);

#define LAYER_IDS_TO_IDX(sl, tl, num_tl)

// Returns 1 if a frame is scaled and 0 otherwise.
static inline int av1_resize_scaled(const AV1_COMMON *cm) {}

static inline int av1_frame_scaled(const AV1_COMMON *cm) {}

// Don't allow a show_existing_frame to coincide with an error resilient
// frame. An exception can be made for a forward keyframe since it has no
// previous dependencies.
static inline int encode_show_existing_frame(const AV1_COMMON *cm) {}

// Get index into the 'cpi->mbmi_ext_info.frame_base' array for the given
// 'mi_row' and 'mi_col'.
static inline int get_mi_ext_idx(const int mi_row, const int mi_col,
                                 const BLOCK_SIZE mi_alloc_bsize,
                                 const int mbmi_ext_stride) {}

// Lighter version of set_offsets that only sets the mode info
// pointers.
static inline void set_mode_info_offsets(
    const CommonModeInfoParams *const mi_params,
    const MBMIExtFrameBufferInfo *const mbmi_ext_info, MACROBLOCK *const x,
    MACROBLOCKD *const xd, int mi_row, int mi_col) {}

// Check to see if the given partition size is allowed for a specified number
// of mi block rows and columns remaining in the image.
// If not then return the largest allowed partition size
static inline BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
                                             int cols_left, int *bh, int *bw) {}

static const uint8_t av1_ref_frame_flag_list[REF_FRAMES] =;

// When more than 'max_allowed_refs' are available, we reduce the number of
// reference frames one at a time based on this order.
static const MV_REFERENCE_FRAME disable_order[] =;

static const MV_REFERENCE_FRAME
    ref_frame_priority_order[INTER_REFS_PER_FRAME] =;

static inline int get_ref_frame_flags(const SPEED_FEATURES *const sf,
                                      const int use_one_pass_rt_params,
                                      const YV12_BUFFER_CONFIG **ref_frames,
                                      const int ext_ref_frame_flags) {}

// Returns a Sequence Header OBU stored in an aom_fixed_buf_t, or NULL upon
// failure. When a non-NULL aom_fixed_buf_t pointer is returned by this
// function, the memory must be freed by the caller. Both the buf member of the
// aom_fixed_buf_t, and the aom_fixed_buf_t pointer itself must be freed. Memory
// returned must be freed via call to free().
//
// Note: The OBU returned is in Low Overhead Bitstream Format. Specifically,
// the obu_has_size_field bit is set, and the buffer contains the obu_size
// field.
aom_fixed_buf_t *av1_get_global_headers(AV1_PRIMARY *ppi);

#define MAX_GFUBOOST_FACTOR
#define MIN_GFUBOOST_FACTOR

static inline int is_frame_tpl_eligible(const GF_GROUP *const gf_group,
                                        uint8_t index) {}

static inline int is_frame_eligible_for_ref_pruning(const GF_GROUP *gf_group,
                                                    int selective_ref_frame,
                                                    int prune_ref_frames,
                                                    int gf_index) {}

// Get update type of the current frame.
static inline FRAME_UPDATE_TYPE get_frame_update_type(const GF_GROUP *gf_group,
                                                      int gf_frame_index) {}

static inline int av1_pixels_to_mi(int pixels) {}

static inline int is_psnr_calc_enabled(const AV1_COMP *cpi) {}

static inline int is_frame_resize_pending(const AV1_COMP *const cpi) {}

// Check if loop filter is used.
static inline int is_loopfilter_used(const AV1_COMMON *const cm) {}

// Check if CDEF is used.
static inline int is_cdef_used(const AV1_COMMON *const cm) {}

// Check if loop restoration filter is used.
static inline int is_restoration_used(const AV1_COMMON *const cm) {}

// Checks if post-processing filters need to be applied.
// NOTE: This function decides if the application of different post-processing
// filters on the reconstructed frame can be skipped at the encoder side.
// However the computation of different filter parameters that are signaled in
// the bitstream is still required.
static inline unsigned int derive_skip_apply_postproc_filters(
    const AV1_COMP *cpi, int use_loopfilter, int use_cdef, int use_superres,
    int use_restoration) {}

static inline void set_postproc_filter_default_params(AV1_COMMON *cm) {}

static inline int is_inter_tx_size_search_level_one(
    const TX_SPEED_FEATURES *tx_sf) {}

static inline int get_lpf_opt_level(const SPEED_FEATURES *sf) {}

// Enable switchable motion mode only if warp and OBMC tools are allowed
static inline bool is_switchable_motion_mode_allowed(bool allow_warped_motion,
                                                     bool enable_obmc) {}

#if CONFIG_AV1_TEMPORAL_DENOISING
static inline int denoise_svc(const struct AV1_COMP *const cpi) {}
#endif

#if CONFIG_COLLECT_PARTITION_STATS == 2
static inline void av1_print_fr_partition_timing_stats(
    const FramePartitionTimingStats *part_stats, const char *filename) {
  FILE *f = fopen(filename, "w");
  if (!f) {
    return;
  }

  fprintf(f, "bsize,redo,");
  for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
    fprintf(f, "decision_%d,", part);
  }
  for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
    fprintf(f, "attempt_%d,", part);
  }
  for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
    fprintf(f, "time_%d,", part);
  }
  fprintf(f, "\n");

  static const int bsizes[6] = { 128, 64, 32, 16, 8, 4 };

  for (int bsize_idx = 0; bsize_idx < 6; bsize_idx++) {
    fprintf(f, "%d,%d,", bsizes[bsize_idx], part_stats->partition_redo);
    for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
      fprintf(f, "%d,", part_stats->partition_decisions[bsize_idx][part]);
    }
    for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
      fprintf(f, "%d,", part_stats->partition_attempts[bsize_idx][part]);
    }
    for (int part = 0; part < EXT_PARTITION_TYPES; part++) {
      fprintf(f, "%ld,", part_stats->partition_times[bsize_idx][part]);
    }
    fprintf(f, "\n");
  }
  fclose(f);
}
#endif  // CONFIG_COLLECT_PARTITION_STATS == 2

#if CONFIG_COLLECT_PARTITION_STATS
static inline int av1_get_bsize_idx_for_part_stats(BLOCK_SIZE bsize) {
  assert(bsize == BLOCK_128X128 || bsize == BLOCK_64X64 ||
         bsize == BLOCK_32X32 || bsize == BLOCK_16X16 || bsize == BLOCK_8X8 ||
         bsize == BLOCK_4X4);
  switch (bsize) {
    case BLOCK_128X128: return 0;
    case BLOCK_64X64: return 1;
    case BLOCK_32X32: return 2;
    case BLOCK_16X16: return 3;
    case BLOCK_8X8: return 4;
    case BLOCK_4X4: return 5;
    default: assert(0 && "Invalid bsize for partition_stats."); return -1;
  }
}
#endif  // CONFIG_COLLECT_PARTITION_STATS

#if CONFIG_COLLECT_COMPONENT_TIMING
static inline void start_timing(AV1_COMP *cpi, int component) {
  aom_usec_timer_start(&cpi->component_timer[component]);
}
static inline void end_timing(AV1_COMP *cpi, int component) {
  aom_usec_timer_mark(&cpi->component_timer[component]);
  cpi->frame_component_time[component] +=
      aom_usec_timer_elapsed(&cpi->component_timer[component]);
}
static inline char const *get_frame_type_enum(int type) {
  switch (type) {
    case 0: return "KEY_FRAME";
    case 1: return "INTER_FRAME";
    case 2: return "INTRA_ONLY_FRAME";
    case 3: return "S_FRAME";
    default: assert(0);
  }
  return "error";
}
#endif

/*!\endcond */

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // AOM_AV1_ENCODER_ENCODER_H_