chromium/third_party/libaom/source/libaom/av1/encoder/encoder.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 <assert.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "av1/common/scale.h"
#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"

#include "aom/aomcx.h"

#if CONFIG_DENOISE
#include "aom_dsp/grain_table.h"
#include "aom_dsp/noise_util.h"
#include "aom_dsp/noise_model.h"
#endif
#include "aom_dsp/flow_estimation/corner_detect.h"
#include "aom_dsp/psnr.h"
#if CONFIG_INTERNAL_STATS
#include "aom_dsp/ssim.h"
#endif
#include "aom_ports/aom_timer.h"
#include "aom_ports/mem.h"
#include "aom_util/aom_pthread.h"
#if CONFIG_BITSTREAM_DEBUG
#include "aom_util/debug_util.h"
#endif  // CONFIG_BITSTREAM_DEBUG

#include "av1/common/alloccommon.h"
#include "av1/common/debugmodes.h"
#include "av1/common/filter.h"
#include "av1/common/idct.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
#include "av1/common/resize.h"
#include "av1/common/tile_common.h"

#include "av1/encoder/allintra_vis.h"
#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/aq_variance.h"
#include "av1/encoder/bitstream.h"
#if CONFIG_INTERNAL_STATS
#include "av1/encoder/blockiness.h"
#endif
#include "av1/encoder/context_tree.h"
#include "av1/encoder/dwt.h"
#include "av1/encoder/encodeframe.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/encode_strategy.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/encoder_alloc.h"
#include "av1/encoder/encoder_utils.h"
#include "av1/encoder/encodetxb.h"
#include "av1/encoder/ethread.h"
#include "av1/encoder/firstpass.h"
#include "av1/encoder/hash_motion.h"
#include "av1/encoder/hybrid_fwd_txfm.h"
#include "av1/encoder/intra_mode_search.h"
#include "av1/encoder/mv_prec.h"
#include "av1/encoder/pass2_strategy.h"
#include "av1/encoder/pickcdef.h"
#include "av1/encoder/picklpf.h"
#include "av1/encoder/pickrst.h"
#include "av1/encoder/random.h"
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/rc_utils.h"
#include "av1/encoder/rd.h"
#include "av1/encoder/rdopt.h"
#if CONFIG_SALIENCY_MAP
#include "av1/encoder/saliency_map.h"
#endif
#include "av1/encoder/segmentation.h"
#include "av1/encoder/speed_features.h"
#include "av1/encoder/superres_scale.h"
#if CONFIG_THREE_PASS
#include "av1/encoder/thirdpass.h"
#endif
#include "av1/encoder/tpl_model.h"
#include "av1/encoder/reconinter_enc.h"
#include "av1/encoder/var_based_part.h"

#define DEFAULT_EXPLICIT_ORDER_HINT_BITS

// #define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
#define FILE_NAME_LEN
#endif

#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file = NULL;
#endif

static inline void Scale2Ratio(AOM_SCALING_MODE mode, int *hr, int *hs) {}

int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {}

int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {}

void av1_initialize_enc(unsigned int usage, enum aom_rc_mode end_usage) {}

void av1_new_framerate(AV1_COMP *cpi, double framerate) {}

double av1_get_compression_ratio(const AV1_COMMON *const cm,
                                 size_t encoded_frame_size) {}

static void auto_tile_size_balancing(AV1_COMMON *const cm, int num_sbs,
                                     int num_tiles_lg, int tile_col_row) {}

static void set_tile_info(AV1_COMMON *const cm,
                          const TileConfig *const tile_cfg) {}

void av1_update_frame_size(AV1_COMP *cpi) {}

static inline int does_level_match(int width, int height, double fps,
                                   int lvl_width, int lvl_height,
                                   double lvl_fps, int lvl_dim_mult) {}

static void set_bitstream_level_tier(AV1_PRIMARY *const ppi, int width,
                                     int height, double init_framerate) {}

static void init_seq_coding_tools(AV1_PRIMARY *const ppi,
                                  const AV1EncoderConfig *oxcf,
                                  int disable_frame_id_numbers) {}

static void init_config_sequence(struct AV1_PRIMARY *ppi,
                                 const AV1EncoderConfig *oxcf) {}

static void init_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {}

void av1_change_config_seq(struct AV1_PRIMARY *ppi,
                           const AV1EncoderConfig *oxcf,
                           bool *is_sb_size_changed) {}

void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf,
                       bool is_sb_size_changed) {}

static inline void init_frame_info(FRAME_INFO *frame_info,
                                   const AV1_COMMON *const cm) {}

static inline void init_frame_index_set(FRAME_INDEX_SET *frame_index_set) {}

static inline void update_counters_for_show_frame(AV1_COMP *const cpi) {}

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

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

#if CONFIG_INTERNAL_STATS
#define SNPRINT

#define SNPRINT2
#endif  // CONFIG_INTERNAL_STATS

void av1_remove_primary_compressor(AV1_PRIMARY *ppi) {}

void av1_remove_compressor(AV1_COMP *cpi) {}

static void generate_psnr_packet(AV1_COMP *cpi) {}

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) {}

#ifdef OUTPUT_YUV_REC
void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
  uint8_t *src = s->y_buffer;
  int h = cm->height;
  if (yuv_rec_file == NULL) return;
  if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
    uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);

    do {
      fwrite(src16, s->y_width, 2, yuv_rec_file);
      src16 += s->y_stride;
    } while (--h);

    src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
    h = s->uv_height;

    do {
      fwrite(src16, s->uv_width, 2, yuv_rec_file);
      src16 += s->uv_stride;
    } while (--h);

    src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
    h = s->uv_height;

    do {
      fwrite(src16, s->uv_width, 2, yuv_rec_file);
      src16 += s->uv_stride;
    } while (--h);

    fflush(yuv_rec_file);
    return;
  }

  do {
    fwrite(src, s->y_width, 1, yuv_rec_file);
    src += s->y_stride;
  } while (--h);

  src = s->u_buffer;
  h = s->uv_height;

  do {
    fwrite(src, s->uv_width, 1, yuv_rec_file);
    src += s->uv_stride;
  } while (--h);

  src = s->v_buffer;
  h = s->uv_height;

  do {
    fwrite(src, s->uv_width, 1, yuv_rec_file);
    src += s->uv_stride;
  } while (--h);

  fflush(yuv_rec_file);
}
#endif  // OUTPUT_YUV_REC

void av1_set_mv_search_params(AV1_COMP *cpi) {}

void av1_set_screen_content_options(AV1_COMP *cpi, FeatureFlags *features) {}

static void init_motion_estimation(AV1_COMP *cpi) {}

static void init_ref_frame_bufs(AV1_COMP *cpi) {}

// TODO(chengchen): consider renaming this function as it is necessary
// for the encoder to setup critical parameters, and it does not
// deal with initial width any longer.
aom_codec_err_t av1_check_initial_width(AV1_COMP *cpi, int use_highbitdepth,
                                        int subsampling_x, int subsampling_y) {}

#if CONFIG_AV1_TEMPORAL_DENOISING
static void setup_denoiser_buffer(AV1_COMP *cpi) {}
#endif

// Returns 1 if the assigned width or height was <= 0.
static int set_size_literal(AV1_COMP *cpi, int width, int height) {}

void av1_set_frame_size(AV1_COMP *cpi, int width, int height) {}

static inline int extend_borders_mt(const AV1_COMP *cpi,
                                    MULTI_THREADED_MODULES stage, int plane) {}

/*!\brief Select and apply cdef filters and switchable restoration filters
 *
 * \ingroup high_level_algo
 */
static void cdef_restoration_frame(AV1_COMP *cpi, AV1_COMMON *cm,
                                   MACROBLOCKD *xd, int use_restoration,
                                   int use_cdef,
                                   unsigned int skip_apply_postproc_filters) {}

static void extend_frame_borders(AV1_COMP *cpi) {}

/*!\brief Select and apply deblocking filters, cdef filters, and restoration
 * filters.
 *
 * \ingroup high_level_algo
 */
static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {}

static void update_motion_stat(AV1_COMP *const cpi) {}

/*!\brief Encode a frame without the recode loop, usually used in one-pass
 * encoding and realtime coding.
 *
 * \ingroup high_level_algo
 *
 * \param[in]    cpi             Top-level encoder structure
 *
 * \return Returns a value to indicate if the encoding is done successfully.
 * \retval #AOM_CODEC_OK
 * \retval #AOM_CODEC_ERROR
 */
static int encode_without_recode(AV1_COMP *cpi) {}

#if !CONFIG_REALTIME_ONLY

/*!\brief Recode loop for encoding one frame. the purpose of encoding one frame
 * for multiple times can be approaching a target bitrate or adjusting the usage
 * of global motions.
 *
 * \ingroup high_level_algo
 *
 * \param[in]    cpi             Top-level encoder structure
 * \param[in]    size            Bitstream size
 * \param[out]   dest            Bitstream output buffer
 * \param[in]    dest_size       Bitstream output buffer size
 *
 * \return Returns a value to indicate if the encoding is done successfully.
 * \retval #AOM_CODEC_OK
 * \retval -1
 * \retval #AOM_CODEC_ERROR
 */
static int encode_with_recode_loop(AV1_COMP *cpi, size_t *size, uint8_t *dest,
                                   size_t dest_size) {
  AV1_COMMON *const cm = &cpi->common;
  RATE_CONTROL *const rc = &cpi->rc;
  GlobalMotionInfo *const gm_info = &cpi->gm_info;
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
  const QuantizationCfg *const q_cfg = &oxcf->q_cfg;
  const int allow_recode = (cpi->sf.hl_sf.recode_loop != DISALLOW_RECODE);
  // Must allow recode if minimum compression ratio is set.
  assert(IMPLIES(oxcf->rc_cfg.min_cr > 0, allow_recode));

  set_size_independent_vars(cpi);
  if (is_stat_consumption_stage_twopass(cpi) &&
      cpi->sf.interp_sf.adaptive_interp_filter_search)
    cpi->interp_search_flags.interp_filter_search_mask =
        av1_setup_interp_filter_search_mask(cpi);

  av1_setup_frame_size(cpi);

  if (av1_superres_in_recode_allowed(cpi) &&
      cpi->superres_mode != AOM_SUPERRES_NONE &&
      cm->superres_scale_denominator == SCALE_NUMERATOR) {
    // Superres mode is currently enabled, but the denominator selected will
    // disable superres. So no need to continue, as we will go through another
    // recode loop for full-resolution after this anyway.
    return -1;
  }

  int top_index = 0, bottom_index = 0;
  int q = 0, q_low = 0, q_high = 0;
  av1_set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
  q_low = bottom_index;
  q_high = top_index;

  av1_set_mv_search_params(cpi);

  allocate_gradient_info_for_hog(cpi);

  allocate_src_var_of_4x4_sub_block_buf(cpi);

  if (cpi->sf.part_sf.partition_search_type == VAR_BASED_PARTITION)
    variance_partition_alloc(cpi);

  if (cm->current_frame.frame_type == KEY_FRAME) copy_frame_prob_info(cpi);

#if CONFIG_COLLECT_COMPONENT_TIMING
  printf("\n Encoding a frame: \n");
#endif

#if !CONFIG_RD_COMMAND
  // Determine whether to use screen content tools using two fast encoding.
  if (!cpi->sf.hl_sf.disable_extra_sc_testing && !cpi->use_ducky_encode)
    av1_determine_sc_tools_with_encoding(cpi, q);
#endif  // !CONFIG_RD_COMMAND

#if CONFIG_TUNE_VMAF
  if (oxcf->tune_cfg.tuning == AOM_TUNE_VMAF_NEG_MAX_GAIN) {
    av1_vmaf_neg_preprocessing(cpi, cpi->unscaled_source);
  }
#endif

#if CONFIG_TUNE_BUTTERAUGLI
  cpi->butteraugli_info.recon_set = false;
  int original_q = 0;
#endif

  cpi->num_frame_recode = 0;

  // Loop variables
  int loop = 0;
  int loop_count = 0;
  int overshoot_seen = 0;
  int undershoot_seen = 0;
  int low_cr_seen = 0;
  int last_loop_allow_hp = 0;

  do {
    loop = 0;
    int do_mv_stats_collection = 1;

    // if frame was scaled calculate global_motion_search again if already
    // done
    if (loop_count > 0 && cpi->source && gm_info->search_done) {
      if (cpi->source->y_crop_width != cm->width ||
          cpi->source->y_crop_height != cm->height) {
        gm_info->search_done = 0;
      }
    }
    cpi->source = av1_realloc_and_scale_if_required(
        cm, cpi->unscaled_source, &cpi->scaled_source, EIGHTTAP_REGULAR, 0,
        false, false, cpi->oxcf.border_in_pixels, cpi->alloc_pyramid);

#if CONFIG_TUNE_BUTTERAUGLI
    if (oxcf->tune_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
      if (loop_count == 0) {
        original_q = q;
        // TODO(sdeng): different q here does not make big difference. Use a
        // faster pass instead.
        q = 96;
        av1_setup_butteraugli_source(cpi);
      } else {
        q = original_q;
      }
    }
#endif

    if (cpi->unscaled_last_source != NULL) {
      cpi->last_source = av1_realloc_and_scale_if_required(
          cm, cpi->unscaled_last_source, &cpi->scaled_last_source,
          EIGHTTAP_REGULAR, 0, false, false, cpi->oxcf.border_in_pixels,
          cpi->alloc_pyramid);
    }

    int scale_references = 0;
#if CONFIG_FPMT_TEST
    scale_references =
        cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE ? 1 : 0;
#endif  // CONFIG_FPMT_TEST
    if (scale_references ||
        cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
      if (!frame_is_intra_only(cm)) {
        if (loop_count > 0) {
          release_scaled_references(cpi);
        }
        av1_scale_references(cpi, EIGHTTAP_REGULAR, 0, 0);
      }
    }

#if CONFIG_TUNE_VMAF
    if (oxcf->tune_cfg.tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
        oxcf->tune_cfg.tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
      cpi->vmaf_info.original_qindex = q;
      q = av1_get_vmaf_base_qindex(cpi, q);
    }
#endif

#if CONFIG_RD_COMMAND
    RD_COMMAND *rd_command = &cpi->rd_command;
    RD_OPTION option = rd_command->option_ls[rd_command->frame_index];
    if (option == RD_OPTION_SET_Q || option == RD_OPTION_SET_Q_RDMULT) {
      q = rd_command->q_index_ls[rd_command->frame_index];
    }
#endif  // CONFIG_RD_COMMAND

#if CONFIG_BITRATE_ACCURACY
#if CONFIG_THREE_PASS
    if (oxcf->pass == AOM_RC_THIRD_PASS && cpi->vbr_rc_info.ready == 1) {
      int frame_coding_idx =
          av1_vbr_rc_frame_coding_idx(&cpi->vbr_rc_info, cpi->gf_frame_index);
      if (frame_coding_idx < cpi->vbr_rc_info.total_frame_count) {
        q = cpi->vbr_rc_info.q_index_list[frame_coding_idx];
      } else {
        // TODO(angiebird): Investigate why sometimes there is an extra frame
        // after the last GOP.
        q = cpi->vbr_rc_info.base_q_index;
      }
    }
#else
    if (cpi->vbr_rc_info.q_index_list_ready) {
      q = cpi->vbr_rc_info.q_index_list[cpi->gf_frame_index];
    }
#endif  // CONFIG_THREE_PASS
#endif  // CONFIG_BITRATE_ACCURACY

#if CONFIG_RATECTRL_LOG && CONFIG_THREE_PASS && CONFIG_BITRATE_ACCURACY
    // TODO(angiebird): Move this into a function.
    if (oxcf->pass == AOM_RC_THIRD_PASS) {
      int frame_coding_idx =
          av1_vbr_rc_frame_coding_idx(&cpi->vbr_rc_info, cpi->gf_frame_index);
      double qstep_ratio = cpi->vbr_rc_info.qstep_ratio_list[frame_coding_idx];
      FRAME_UPDATE_TYPE update_type =
          cpi->vbr_rc_info.update_type_list[frame_coding_idx];
      rc_log_frame_encode_param(&cpi->rc_log, frame_coding_idx, qstep_ratio, q,
                                update_type);
    }
#endif  // CONFIG_RATECTRL_LOG && CONFIG_THREE_PASS && CONFIG_BITRATE_ACCURACY

    if (cpi->use_ducky_encode) {
      const DuckyEncodeFrameInfo *frame_info =
          &cpi->ducky_encode_info.frame_info;
      if (frame_info->qp_mode == DUCKY_ENCODE_FRAME_MODE_QINDEX) {
        q = frame_info->q_index;
        cm->delta_q_info.delta_q_present_flag = frame_info->delta_q_enabled;
      }
    }

    av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q,
                      q_cfg->enable_chroma_deltaq, q_cfg->enable_hdr_deltaq);
    av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
    av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
                       cm->seq_params->bit_depth);

    av1_set_variance_partition_thresholds(cpi, q, 0);

    // printf("Frame %d/%d: q = %d, frame_type = %d superres_denom = %d\n",
    //        cm->current_frame.frame_number, cm->show_frame, q,
    //        cm->current_frame.frame_type, cm->superres_scale_denominator);

    if (loop_count == 0) {
      av1_setup_frame(cpi);
    } else if (get_primary_ref_frame_buf(cm) == NULL) {
      // Base q-index may have changed, so we need to assign proper default coef
      // probs before every iteration.
      av1_default_coef_probs(cm);
      av1_setup_frame_contexts(cm);
    }

    if (q_cfg->aq_mode == VARIANCE_AQ) {
      av1_vaq_frame_setup(cpi);
    } else if (q_cfg->aq_mode == COMPLEXITY_AQ) {
      av1_setup_in_frame_q_adj(cpi);
    }

    if (cm->seg.enabled) {
      if (!cm->seg.update_data && cm->prev_frame) {
        segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
        cm->seg.enabled = cm->prev_frame->seg.enabled;
      } else {
        av1_calculate_segdata(&cm->seg);
      }
    } else {
      memset(&cm->seg, 0, sizeof(cm->seg));
    }
    segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
    cm->cur_frame->seg.enabled = cm->seg.enabled;

#if CONFIG_COLLECT_COMPONENT_TIMING
    start_timing(cpi, av1_encode_frame_time);
#endif
    // Set the motion vector precision based on mv stats from the last coded
    // frame.
    if (!frame_is_intra_only(cm)) {
      av1_pick_and_set_high_precision_mv(cpi, q);

      // If the precision has changed during different iteration of the loop,
      // then we need to reset the global motion vectors
      if (loop_count > 0 &&
          cm->features.allow_high_precision_mv != last_loop_allow_hp) {
        gm_info->search_done = 0;
      }
      last_loop_allow_hp = cm->features.allow_high_precision_mv;
    }

    // transform / motion compensation build reconstruction frame
    av1_encode_frame(cpi);

    // Disable mv_stats collection for parallel frames based on update flag.
    if (!cpi->do_frame_data_update) do_mv_stats_collection = 0;

    // Reset the mv_stats in case we are interrupted by an intraframe or an
    // overlay frame.
    if (cpi->mv_stats.valid && do_mv_stats_collection) av1_zero(cpi->mv_stats);

    // Gather the mv_stats for the next frame
    if (cpi->sf.hl_sf.high_precision_mv_usage == LAST_MV_DATA &&
        av1_frame_allows_smart_mv(cpi) && do_mv_stats_collection) {
      av1_collect_mv_stats(cpi, q);
    }

#if CONFIG_COLLECT_COMPONENT_TIMING
    end_timing(cpi, av1_encode_frame_time);
#endif

#if CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
    const int do_dummy_pack = 1;
#else   // CONFIG_BITRATE_ACCURACY
    // Dummy pack of the bitstream using up to date stats to get an
    // accurate estimate of output frame size to determine if we need
    // to recode.
    const int do_dummy_pack =
        (cpi->sf.hl_sf.recode_loop >= ALLOW_RECODE_KFARFGF &&
         oxcf->rc_cfg.mode != AOM_Q) ||
        oxcf->rc_cfg.min_cr > 0;
#endif  // CONFIG_BITRATE_ACCURACY
    if (do_dummy_pack) {
      av1_finalize_encoded_frame(cpi);
      int largest_tile_id = 0;  // Output from bitstream: unused here
      rc->coefficient_size = 0;
      if (av1_pack_bitstream(cpi, dest, dest_size, size, &largest_tile_id) !=
          AOM_CODEC_OK) {
        return AOM_CODEC_ERROR;
      }

      // bits used for this frame
      rc->projected_frame_size = (int)(*size) << 3;
#if CONFIG_RD_COMMAND
      PSNR_STATS psnr;
      aom_calc_psnr(cpi->source, &cpi->common.cur_frame->buf, &psnr);
      printf("q %d rdmult %d rate %d dist %" PRIu64 "\n", q, cpi->rd.RDMULT,
             rc->projected_frame_size, psnr.sse[0]);
      ++rd_command->frame_index;
      if (rd_command->frame_index == rd_command->frame_count) {
        return AOM_CODEC_ERROR;
      }
#endif  // CONFIG_RD_COMMAND

#if CONFIG_RATECTRL_LOG && CONFIG_THREE_PASS && CONFIG_BITRATE_ACCURACY
      if (oxcf->pass == AOM_RC_THIRD_PASS) {
        int frame_coding_idx =
            av1_vbr_rc_frame_coding_idx(&cpi->vbr_rc_info, cpi->gf_frame_index);
        rc_log_frame_entropy(&cpi->rc_log, frame_coding_idx,
                             rc->projected_frame_size, rc->coefficient_size);
      }
#endif  // CONFIG_RATECTRL_LOG && CONFIG_THREE_PASS && CONFIG_BITRATE_ACCURACY
    }

#if CONFIG_TUNE_VMAF
    if (oxcf->tune_cfg.tuning >= AOM_TUNE_VMAF_WITH_PREPROCESSING &&
        oxcf->tune_cfg.tuning <= AOM_TUNE_VMAF_NEG_MAX_GAIN) {
      q = cpi->vmaf_info.original_qindex;
    }
#endif
    if (allow_recode) {
      // Update q and decide whether to do a recode loop
      recode_loop_update_q(cpi, &loop, &q, &q_low, &q_high, top_index,
                           bottom_index, &undershoot_seen, &overshoot_seen,
                           &low_cr_seen, loop_count);
    }

#if CONFIG_TUNE_BUTTERAUGLI
    if (loop_count == 0 && oxcf->tune_cfg.tuning == AOM_TUNE_BUTTERAUGLI) {
      loop = 1;
      av1_setup_butteraugli_rdmult_and_restore_source(cpi, 0.4);
    }
#endif

    if (cpi->use_ducky_encode) {
      // Ducky encode currently does not support recode loop.
      loop = 0;
    }
#if CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND
    loop = 0;  // turn off recode loop when CONFIG_BITRATE_ACCURACY is on
#endif         // CONFIG_BITRATE_ACCURACY || CONFIG_RD_COMMAND

    if (loop) {
      ++loop_count;
      cpi->num_frame_recode =
          (cpi->num_frame_recode < (NUM_RECODES_PER_FRAME - 1))
              ? (cpi->num_frame_recode + 1)
              : (NUM_RECODES_PER_FRAME - 1);
#if CONFIG_INTERNAL_STATS
      ++cpi->frame_recode_hits;
#endif
    }
#if CONFIG_COLLECT_COMPONENT_TIMING
    if (loop) printf("\n Recoding:");
#endif
  } while (loop);

  return AOM_CODEC_OK;
}
#endif  // !CONFIG_REALTIME_ONLY

// TODO(jingning, paulwilkins): Set up high grain level to test
// hardware decoders. Need to adapt the actual noise variance
// according to the difference between reconstructed frame and the
// source signal.
static void set_grain_syn_params(AV1_COMMON *cm) {}

/*!\brief Recode loop or a single loop for encoding one frame, followed by
 * in-loop deblocking filters, CDEF filters, and restoration filters.
 *
 * \ingroup high_level_algo
 * \callgraph
 * \callergraph
 *
 * \param[in]    cpi             Top-level encoder structure
 * \param[in]    size            Bitstream size
 * \param[out]   dest            Bitstream output buffer
 * \param[in]    dest_size       Bitstream output buffer size
 * \param[in]    sse             Total distortion of the frame
 * \param[in]    rate            Total rate of the frame
 * \param[in]    largest_tile_id Tile id of the last tile
 *
 * \return Returns a value to indicate if the encoding is done successfully.
 * \retval #AOM_CODEC_OK
 * \retval #AOM_CODEC_ERROR
 */
static int encode_with_recode_loop_and_filter(AV1_COMP *cpi, size_t *size,
                                              uint8_t *dest, size_t dest_size,
                                              int64_t *sse, int64_t *rate,
                                              int *largest_tile_id) {}

static int encode_with_and_without_superres(AV1_COMP *cpi, size_t *size,
                                            uint8_t *dest, size_t dest_size,
                                            int *largest_tile_id) {}

// Conditions to disable cdf_update mode in selective mode for real-time.
// Handle case for layers, scene change, and resizing.
static inline int selective_disable_cdf_rtc(const AV1_COMP *cpi) {}

#if !CONFIG_REALTIME_ONLY
static void subtract_stats(FIRSTPASS_STATS *section,
                           const FIRSTPASS_STATS *frame) {
  section->frame -= frame->frame;
  section->weight -= frame->weight;
  section->intra_error -= frame->intra_error;
  section->frame_avg_wavelet_energy -= frame->frame_avg_wavelet_energy;
  section->coded_error -= frame->coded_error;
  section->sr_coded_error -= frame->sr_coded_error;
  section->pcnt_inter -= frame->pcnt_inter;
  section->pcnt_motion -= frame->pcnt_motion;
  section->pcnt_second_ref -= frame->pcnt_second_ref;
  section->pcnt_neutral -= frame->pcnt_neutral;
  section->intra_skip_pct -= frame->intra_skip_pct;
  section->inactive_zone_rows -= frame->inactive_zone_rows;
  section->inactive_zone_cols -= frame->inactive_zone_cols;
  section->MVr -= frame->MVr;
  section->mvr_abs -= frame->mvr_abs;
  section->MVc -= frame->MVc;
  section->mvc_abs -= frame->mvc_abs;
  section->MVrv -= frame->MVrv;
  section->MVcv -= frame->MVcv;
  section->mv_in_out_count -= frame->mv_in_out_count;
  section->new_mv_count -= frame->new_mv_count;
  section->count -= frame->count;
  section->duration -= frame->duration;
}

static void calculate_frame_avg_haar_energy(AV1_COMP *cpi) {
  TWO_PASS *const twopass = &cpi->ppi->twopass;
  const FIRSTPASS_STATS *const total_stats =
      twopass->stats_buf_ctx->total_stats;

  if (is_one_pass_rt_params(cpi) ||
      (cpi->oxcf.q_cfg.deltaq_mode != DELTA_Q_PERCEPTUAL) ||
      (is_fp_wavelet_energy_invalid(total_stats) == 0))
    return;

  const int num_mbs = (cpi->oxcf.resize_cfg.resize_mode != RESIZE_NONE)
                          ? cpi->initial_mbs
                          : cpi->common.mi_params.MBs;
  const YV12_BUFFER_CONFIG *const unfiltered_source = cpi->unfiltered_source;
  const uint8_t *const src = unfiltered_source->y_buffer;
  const int hbd = unfiltered_source->flags & YV12_FLAG_HIGHBITDEPTH;
  const int stride = unfiltered_source->y_stride;
  const BLOCK_SIZE fp_block_size =
      get_fp_block_size(cpi->is_screen_content_type);
  const int fp_block_size_width = block_size_wide[fp_block_size];
  const int fp_block_size_height = block_size_high[fp_block_size];
  const int num_unit_cols =
      get_num_blocks(unfiltered_source->y_crop_width, fp_block_size_width);
  const int num_unit_rows =
      get_num_blocks(unfiltered_source->y_crop_height, fp_block_size_height);
  const int num_8x8_cols = num_unit_cols * (fp_block_size_width / 8);
  const int num_8x8_rows = num_unit_rows * (fp_block_size_height / 8);
  int64_t frame_avg_wavelet_energy = av1_haar_ac_sad_mxn_uint8_input(
      src, stride, hbd, num_8x8_rows, num_8x8_cols);

  cpi->twopass_frame.frame_avg_haar_energy =
      log1p((double)frame_avg_wavelet_energy / num_mbs);
}
#endif

/*!\brief Run the final pass encoding for 1-pass/2-pass encoding mode, and pack
 * the bitstream
 *
 * \ingroup high_level_algo
 * \callgraph
 * \callergraph
 *
 * \param[in]    cpi             Top-level encoder structure
 * \param[in]    size            Bitstream size
 * \param[out]   dest            Bitstream output buffer
 * \param[in]    dest_size       Bitstream output buffer size
 *
 * \return Returns a value to indicate if the encoding is done successfully.
 * \retval #AOM_CODEC_OK
 * \retval #AOM_CODEC_ERROR
 */
static int encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size, uint8_t *dest,
                                     size_t dest_size) {}

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) {}

#if CONFIG_DENOISE
static int apply_denoise_2d(AV1_COMP *cpi, const YV12_BUFFER_CONFIG *sd,
                            int block_size, float noise_level,
                            int64_t time_stamp, int64_t end_time) {}
#endif

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) {}

#if CONFIG_ENTROPY_STATS
void print_entropy_stats(AV1_PRIMARY *const ppi) {
  if (!ppi->cpi) return;

  if (ppi->cpi->oxcf.pass != 1 &&
      ppi->cpi->common.current_frame.frame_number > 0) {
    fprintf(stderr, "Writing counts.stt\n");
    FILE *f = fopen("counts.stt", "wb");
    fwrite(&ppi->aggregate_fc, sizeof(ppi->aggregate_fc), 1, f);
    fclose(f);
  }
}
#endif  // CONFIG_ENTROPY_STATS

#if CONFIG_INTERNAL_STATS
static void adjust_image_stat(double y, double u, double v, double all,
                              ImageStat *s) {
  s->stat[STAT_Y] += y;
  s->stat[STAT_U] += u;
  s->stat[STAT_V] += v;
  s->stat[STAT_ALL] += all;
  s->worst = AOMMIN(s->worst, all);
}

static void compute_internal_stats(AV1_COMP *cpi, int frame_bytes) {
  AV1_PRIMARY *const ppi = cpi->ppi;
  AV1_COMMON *const cm = &cpi->common;
  double samples = 0.0;
  const uint32_t in_bit_depth = cpi->oxcf.input_cfg.input_bit_depth;
  const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;

  if (cpi->ppi->use_svc &&
      cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)
    return;

#if CONFIG_INTER_STATS_ONLY
  if (cm->current_frame.frame_type == KEY_FRAME) return;  // skip key frame
#endif
  cpi->bytes += frame_bytes;
  if (cm->show_frame) {
    const YV12_BUFFER_CONFIG *orig = cpi->source;
    const YV12_BUFFER_CONFIG *recon = &cpi->common.cur_frame->buf;
    double y, u, v, frame_all;

    ppi->count[0]++;
    ppi->count[1]++;
    if (cpi->ppi->b_calculate_psnr) {
      PSNR_STATS psnr;
      double weight[2] = { 0.0, 0.0 };
      double frame_ssim2[2] = { 0.0, 0.0 };
#if CONFIG_AV1_HIGHBITDEPTH
      aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
#else
      aom_calc_psnr(orig, recon, &psnr);
#endif
      adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], psnr.psnr[0],
                        &(ppi->psnr[0]));
      ppi->total_sq_error[0] += psnr.sse[0];
      ppi->total_samples[0] += psnr.samples[0];
      samples = psnr.samples[0];

      aom_calc_ssim(orig, recon, bit_depth, in_bit_depth,
                    cm->seq_params->use_highbitdepth, weight, frame_ssim2);

      ppi->worst_ssim = AOMMIN(ppi->worst_ssim, frame_ssim2[0]);
      ppi->summed_quality += frame_ssim2[0] * weight[0];
      ppi->summed_weights += weight[0];

#if CONFIG_AV1_HIGHBITDEPTH
      // Compute PSNR based on stream bit depth
      if ((cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) &&
          (in_bit_depth < bit_depth)) {
        adjust_image_stat(psnr.psnr_hbd[1], psnr.psnr_hbd[2], psnr.psnr_hbd[3],
                          psnr.psnr_hbd[0], &ppi->psnr[1]);
        ppi->total_sq_error[1] += psnr.sse_hbd[0];
        ppi->total_samples[1] += psnr.samples_hbd[0];

        ppi->worst_ssim_hbd = AOMMIN(ppi->worst_ssim_hbd, frame_ssim2[1]);
        ppi->summed_quality_hbd += frame_ssim2[1] * weight[1];
        ppi->summed_weights_hbd += weight[1];
      }
#endif

#if 0
      {
        FILE *f = fopen("q_used.stt", "a");
        double y2 = psnr.psnr[1];
        double u2 = psnr.psnr[2];
        double v2 = psnr.psnr[3];
        double frame_psnr2 = psnr.psnr[0];
        fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
                cm->current_frame.frame_number, y2, u2, v2,
                frame_psnr2, frame_ssim2);
        fclose(f);
      }
#endif
    }
    if (ppi->b_calculate_blockiness) {
      if (!cm->seq_params->use_highbitdepth) {
        const double frame_blockiness =
            av1_get_blockiness(orig->y_buffer, orig->y_stride, recon->y_buffer,
                               recon->y_stride, orig->y_width, orig->y_height);
        ppi->worst_blockiness = AOMMAX(ppi->worst_blockiness, frame_blockiness);
        ppi->total_blockiness += frame_blockiness;
      }

      if (ppi->b_calculate_consistency) {
        if (!cm->seq_params->use_highbitdepth) {
          const double this_inconsistency = aom_get_ssim_metrics(
              orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride,
              orig->y_width, orig->y_height, ppi->ssim_vars, &ppi->metrics, 1);

          const double peak = (double)((1 << in_bit_depth) - 1);
          const double consistency =
              aom_sse_to_psnr(samples, peak, ppi->total_inconsistency);
          if (consistency > 0.0)
            ppi->worst_consistency =
                AOMMIN(ppi->worst_consistency, consistency);
          ppi->total_inconsistency += this_inconsistency;
        }
      }
    }

    frame_all =
        aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
    adjust_image_stat(y, u, v, frame_all, &ppi->fastssim);
    frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
    adjust_image_stat(y, u, v, frame_all, &ppi->psnrhvs);
  }
}

void print_internal_stats(AV1_PRIMARY *ppi) {
  if (!ppi->cpi) return;
  AV1_COMP *const cpi = ppi->cpi;

  if (ppi->cpi->oxcf.pass != 1 &&
      ppi->cpi->common.current_frame.frame_number > 0) {
    char headings[512] = { 0 };
    char results[512] = { 0 };
    FILE *f = fopen("opsnr.stt", "a");
    double time_encoded =
        (cpi->time_stamps.prev_ts_end - cpi->time_stamps.first_ts_start) /
        10000000.000;
    double total_encode_time =
        (ppi->total_time_receive_data + ppi->total_time_compress_data) /
        1000.000;
    const double dr =
        (double)ppi->total_bytes * (double)8 / (double)1000 / time_encoded;
    const double peak =
        (double)((1 << ppi->cpi->oxcf.input_cfg.input_bit_depth) - 1);
    const double target_rate =
        (double)ppi->cpi->oxcf.rc_cfg.target_bandwidth / 1000;
    const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);

    if (ppi->b_calculate_psnr) {
      const double total_psnr = aom_sse_to_psnr(
          (double)ppi->total_samples[0], peak, (double)ppi->total_sq_error[0]);
      const double total_ssim =
          100 * pow(ppi->summed_quality / ppi->summed_weights, 8.0);
      snprintf(headings, sizeof(headings),
               "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
               "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
               "WstPsnr\tWstSsim\tWstFast\tWstHVS\t"
               "AVPsrnY\tAPsnrCb\tAPsnrCr");
      snprintf(results, sizeof(results),
               "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
               "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
               "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
               "%7.3f\t%7.3f\t%7.3f",
               dr, ppi->psnr[0].stat[STAT_ALL] / ppi->count[0], total_psnr,
               ppi->psnr[0].stat[STAT_ALL] / ppi->count[0], total_psnr,
               total_ssim, total_ssim,
               ppi->fastssim.stat[STAT_ALL] / ppi->count[0],
               ppi->psnrhvs.stat[STAT_ALL] / ppi->count[0], ppi->psnr[0].worst,
               ppi->worst_ssim, ppi->fastssim.worst, ppi->psnrhvs.worst,
               ppi->psnr[0].stat[STAT_Y] / ppi->count[0],
               ppi->psnr[0].stat[STAT_U] / ppi->count[0],
               ppi->psnr[0].stat[STAT_V] / ppi->count[0]);

      if (ppi->b_calculate_blockiness) {
        SNPRINT(headings, "\t  Block\tWstBlck");
        SNPRINT2(results, "\t%7.3f", ppi->total_blockiness / ppi->count[0]);
        SNPRINT2(results, "\t%7.3f", ppi->worst_blockiness);
      }

      if (ppi->b_calculate_consistency) {
        double consistency =
            aom_sse_to_psnr((double)ppi->total_samples[0], peak,
                            (double)ppi->total_inconsistency);

        SNPRINT(headings, "\tConsist\tWstCons");
        SNPRINT2(results, "\t%7.3f", consistency);
        SNPRINT2(results, "\t%7.3f", ppi->worst_consistency);
      }

      SNPRINT(headings, "\t   Time\tRcErr\tAbsErr");
      SNPRINT2(results, "\t%8.0f", total_encode_time);
      SNPRINT2(results, " %7.2f", rate_err);
      SNPRINT2(results, " %7.2f", fabs(rate_err));

      SNPRINT(headings, "\tAPsnr611");
      SNPRINT2(results, " %7.3f",
               (6 * ppi->psnr[0].stat[STAT_Y] + ppi->psnr[0].stat[STAT_U] +
                ppi->psnr[0].stat[STAT_V]) /
                   (ppi->count[0] * 8));

#if CONFIG_AV1_HIGHBITDEPTH
      const uint32_t in_bit_depth = ppi->cpi->oxcf.input_cfg.input_bit_depth;
      const uint32_t bit_depth = ppi->seq_params.bit_depth;
      // Since cpi->source->flags is not available here, but total_samples[1]
      // will be non-zero if cpi->source->flags & YV12_FLAG_HIGHBITDEPTH was
      // true in compute_internal_stats
      if ((ppi->total_samples[1] > 0) && (in_bit_depth < bit_depth)) {
        const double peak_hbd = (double)((1 << bit_depth) - 1);
        const double total_psnr_hbd =
            aom_sse_to_psnr((double)ppi->total_samples[1], peak_hbd,
                            (double)ppi->total_sq_error[1]);
        const double total_ssim_hbd =
            100 * pow(ppi->summed_quality_hbd / ppi->summed_weights_hbd, 8.0);
        SNPRINT(headings,
                "\t AVGPsnrH GLBPsnrH AVPsnrPH GLPsnrPH"
                " AVPsnrYH APsnrCbH APsnrCrH WstPsnrH"
                " AOMSSIMH VPSSIMPH WstSsimH");
        SNPRINT2(results, "\t%7.3f",
                 ppi->psnr[1].stat[STAT_ALL] / ppi->count[1]);
        SNPRINT2(results, "  %7.3f", total_psnr_hbd);
        SNPRINT2(results, "  %7.3f",
                 ppi->psnr[1].stat[STAT_ALL] / ppi->count[1]);
        SNPRINT2(results, "  %7.3f", total_psnr_hbd);
        SNPRINT2(results, "  %7.3f", ppi->psnr[1].stat[STAT_Y] / ppi->count[1]);
        SNPRINT2(results, "  %7.3f", ppi->psnr[1].stat[STAT_U] / ppi->count[1]);
        SNPRINT2(results, "  %7.3f", ppi->psnr[1].stat[STAT_V] / ppi->count[1]);
        SNPRINT2(results, "  %7.3f", ppi->psnr[1].worst);
        SNPRINT2(results, "  %7.3f", total_ssim_hbd);
        SNPRINT2(results, "  %7.3f", total_ssim_hbd);
        SNPRINT2(results, "  %7.3f", ppi->worst_ssim_hbd);
      }
#endif
      fprintf(f, "%s\n", headings);
      fprintf(f, "%s\n", results);
    }

    fclose(f);

    aom_free(ppi->ssim_vars);
    ppi->ssim_vars = NULL;
  }
}
#endif  // CONFIG_INTERNAL_STATS

static inline void update_keyframe_counters(AV1_COMP *cpi) {}

static inline void update_frames_till_gf_update(AV1_COMP *cpi) {}

static inline void update_gf_group_index(AV1_COMP *cpi) {}

static void update_fb_of_context_type(const AV1_COMP *const cpi,
                                      int *const fb_of_context_type) {}

static void update_rc_counts(AV1_COMP *cpi) {}

static void update_end_of_frame_stats(AV1_COMP *cpi) {}

// Updates frame level stats related to global motion
static inline void update_gm_stats(AV1_COMP *cpi) {}

void av1_post_encode_updates(AV1_COMP *const cpi,
                             const AV1_COMP_DATA *const cpi_data) {}

int av1_get_compressed_data(AV1_COMP *cpi, AV1_COMP_DATA *const cpi_data) {}

// Populates cpi->scaled_ref_buf corresponding to frames in a parallel encode
// set. Also sets the bitmask 'ref_buffers_used_map'.
static void scale_references_fpmt(AV1_COMP *cpi, int *ref_buffers_used_map) {}

// Increments the ref_count of frame buffers referenced by cpi->scaled_ref_buf
// corresponding to frames in a parallel encode set.
static void increment_scaled_ref_counts_fpmt(BufferPool *buffer_pool,
                                             int ref_buffers_used_map) {}

// Releases cpi->scaled_ref_buf corresponding to frames in a parallel encode
// set.
void av1_release_scaled_references_fpmt(AV1_COMP *cpi) {}

// Decrements the ref_count of frame buffers referenced by cpi->scaled_ref_buf
// corresponding to frames in a parallel encode set.
void av1_decrement_ref_counts_fpmt(BufferPool *buffer_pool,
                                   int ref_buffers_used_map) {}

// Initialize parallel frame contexts with screen content decisions.
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) {}

// Initialises frames belonging to a parallel encode set.
int av1_init_parallel_frame_context(const AV1_COMP_DATA *const first_cpi_data,
                                    AV1_PRIMARY *const ppi,
                                    int *ref_buffers_used_map) {}

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_set_internal_size(AV1EncoderConfig *const oxcf,
                          ResizePendingParams *resize_pending_params,
                          AOM_SCALING_MODE horiz_mode,
                          AOM_SCALING_MODE vert_mode) {}

int av1_get_quantizer(AV1_COMP *cpi) {}

int av1_convert_sect5obus_to_annexb(uint8_t *buffer, size_t *frame_size) {}

static void rtc_set_updates_ref_frame_config(
    ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags,
    RTC_REF *const rtc_ref) {}

static int rtc_set_references_external_ref_frame_config(AV1_COMP *cpi) {}

void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {}

aom_fixed_buf_t *av1_get_global_headers(AV1_PRIMARY *ppi) {}