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

Quelle  encoder.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 <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 7

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

#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file = NULL;
#endif

static inline void Scale2Ratio(AOM_SCALING_MODE mode, int *hr, int *hs) {
  switch (mode) {
    case AOME_NORMAL:
      *hr = 1;
      *hs = 1;
      break;
    case AOME_FOURFIVE:
      *hr = 4;
      *hs = 5;
      break;
    case AOME_THREEFIVE:
      *hr = 3;
      *hs = 5;
      break;
    case AOME_THREEFOUR:
      *hr = 3;
      *hs = 4;
      break;
    case AOME_ONEFOUR:
      *hr = 1;
      *hs = 4;
      break;
    case AOME_ONEEIGHT:
      *hr = 1;
      *hs = 8;
      break;
    case AOME_ONETWO:
      *hr = 1;
      *hs = 2;
      break;
    case AOME_TWOTHREE:
      *hr = 2;
      *hs = 3;
      break;
    case AOME_ONETHREE:
      *hr = 1;
      *hs = 3;
      break;
    default:
      *hr = 1;
      *hs = 1;
      assert(0);
      break;
  }
}

int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
  if (rows == mi_params->mb_rows && cols == mi_params->mb_cols) {
    unsigned char *const active_map_4x4 = cpi->active_map.map;
    const int mi_rows = mi_params->mi_rows;
    const int mi_cols = mi_params->mi_cols;
    cpi->active_map.update = 0;
    cpi->rc.percent_blocks_inactive = 0;
    assert(mi_rows % 2 == 0 && mi_rows > 0);
    assert(mi_cols % 2 == 0 && mi_cols > 0);
    if (new_map_16x16) {
      int num_samples = 0;
      int num_blocks_inactive = 0;
      for (int r = 0; r < mi_rows; r += 4) {
        for (int c = 0; c < mi_cols; c += 4) {
          const uint8_t val = new_map_16x16[(r >> 2) * cols + (c >> 2)]
                                  ? AM_SEGMENT_ID_ACTIVE
                                  : AM_SEGMENT_ID_INACTIVE;
          num_samples++;
          if (val == AM_SEGMENT_ID_INACTIVE) num_blocks_inactive++;
          const int row_max = AOMMIN(4, mi_rows - r);
          const int col_max = AOMMIN(4, mi_cols - c);
          for (int x = 0; x < row_max; ++x) {
            for (int y = 0; y < col_max; ++y) {
              active_map_4x4[(r + x) * mi_cols + (c + y)] = val;
            }
          }
        }
      }
      cpi->active_map.enabled = 1;
      cpi->active_map.update = 1;
      assert(num_samples);
      cpi->rc.percent_blocks_inactive =
          (num_blocks_inactive * 100) / num_samples;
    }
    return 0;
  }

  return -1;
}

int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
  const CommonModeInfoParams *const mi_params = &cpi->common.mi_params;
  if (rows == mi_params->mb_rows && cols == mi_params->mb_cols &&
      new_map_16x16) {
    unsigned char *const seg_map_8x8 = cpi->enc_seg.map;
    const int mi_rows = mi_params->mi_rows;
    const int mi_cols = mi_params->mi_cols;
    const int row_scale = mi_size_high_log2[BLOCK_16X16];
    const int col_scale = mi_size_wide_log2[BLOCK_16X16];
    assert(mi_rows % 2 == 0);
    assert(mi_cols % 2 == 0);

    memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
    if (cpi->active_map.enabled) {
      for (int r = 0; r < (mi_rows >> row_scale); ++r) {
        for (int c = 0; c < (mi_cols >> col_scale); ++c) {
          // Cyclic refresh segments are considered active despite not having
          // AM_SEGMENT_ID_ACTIVE
          uint8_t temp = 0;
          temp |= seg_map_8x8[(2 * r + 0) * mi_cols + (2 * c + 0)] !=
                  AM_SEGMENT_ID_INACTIVE;
          temp |= seg_map_8x8[(2 * r + 0) * mi_cols + (2 * c + 1)] !=
                  AM_SEGMENT_ID_INACTIVE;
          temp |= seg_map_8x8[(2 * r + 1) * mi_cols + (2 * c + 0)] !=
                  AM_SEGMENT_ID_INACTIVE;
          temp |= seg_map_8x8[(2 * r + 1) * mi_cols + (2 * c + 1)] !=
                  AM_SEGMENT_ID_INACTIVE;
          new_map_16x16[r * cols + c] |= temp;
        }
      }
    }
    return 0;
  }

  return -1;
}

void av1_initialize_enc(unsigned int usage, enum aom_rc_mode end_usage) {
  bool is_allintra = usage == ALLINTRA;

  av1_rtcd();
  aom_dsp_rtcd();
  aom_scale_rtcd();
  av1_init_intra_predictors();
  av1_init_me_luts();
  if (!is_allintra) av1_init_wedge_masks();
  if (!is_allintra || end_usage != AOM_Q) av1_rc_init_minq_luts();
}

void av1_new_framerate(AV1_COMP *cpi, double framerate) {
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
  av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
}

double av1_get_compression_ratio(const AV1_COMMON *const cm,
                                 size_t encoded_frame_size) {
  const int upscaled_width = cm->superres_upscaled_width;
  const int height = cm->height;
  const int64_t luma_pic_size = (int64_t)upscaled_width * height;
  const SequenceHeader *const seq_params = cm->seq_params;
  const BITSTREAM_PROFILE profile = seq_params->profile;
  const int pic_size_profile_factor =
      profile == PROFILE_0 ? 15 : (profile == PROFILE_1 ? 30 : 36);
  encoded_frame_size =
      (encoded_frame_size > 129 ? encoded_frame_size - 128 : 1);
  const int64_t uncompressed_frame_size =
      (luma_pic_size * pic_size_profile_factor) >> 3;
  return (double)uncompressed_frame_size / encoded_frame_size;
}

static void auto_tile_size_balancing(AV1_COMMON *const cm, int num_sbs,
                                     int num_tiles_lg, int tile_col_row) {
  CommonTileParams *const tiles = &cm->tiles;
  int i, start_sb;
  int size_sb = num_sbs >> num_tiles_lg;
  int res_sbs = num_sbs - (size_sb << num_tiles_lg);
  int num_tiles = 1 << num_tiles_lg;
  int inc_index = num_tiles - res_sbs;

  tiles->uniform_spacing = 0;

  for (i = 0, start_sb = 0; start_sb < num_sbs && i < MAX_TILE_COLS; ++i) {
    if (i == inc_index) ++size_sb;
    if (tile_col_row)
      tiles->col_start_sb[i] = start_sb;
    else
      tiles->row_start_sb[i] = start_sb;

    start_sb += AOMMIN(size_sb, tiles->max_width_sb);
  }

  if (tile_col_row) {
    tiles->cols = i;
    tiles->col_start_sb[i] = num_sbs;
  } else {
    tiles->rows = i;
    tiles->row_start_sb[i] = num_sbs;
  }
}

static void set_tile_info(AV1_COMMON *const cm,
                          const TileConfig *const tile_cfg) {
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const SequenceHeader *const seq_params = cm->seq_params;
  CommonTileParams *const tiles = &cm->tiles;
  int i, start_sb;

  av1_get_tile_limits(cm);

  int sb_cols =
      CEIL_POWER_OF_TWO(mi_params->mi_cols, seq_params->mib_size_log2);
  // configure tile columns
  if (tile_cfg->tile_width_count == 0 || tile_cfg->tile_height_count == 0) {
    tiles->uniform_spacing = 1;
    tiles->log2_cols = AOMMAX(tile_cfg->tile_columns, tiles->min_log2_cols);
    // Add a special case to handle super resolution
    sb_cols = coded_to_superres_mi(sb_cols, cm->superres_scale_denominator);
    int min_log2_cols = 0;
    for (; (tiles->max_width_sb << min_log2_cols) <= sb_cols; ++min_log2_cols) {
    }
    tiles->log2_cols = AOMMAX(tiles->log2_cols, min_log2_cols);

    tiles->log2_cols = AOMMIN(tiles->log2_cols, tiles->max_log2_cols);
  } else if (tile_cfg->tile_widths[0] < 0) {
    auto_tile_size_balancing(cm, sb_cols, tile_cfg->tile_columns, 1);
  } else {
    int size_sb, j = 0;
    tiles->uniform_spacing = 0;
    for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
      tiles->col_start_sb[i] = start_sb;
      size_sb = tile_cfg->tile_widths[j++];
      if (j >= tile_cfg->tile_width_count) j = 0;
      start_sb += AOMMIN(size_sb, tiles->max_width_sb);
    }
    tiles->cols = i;
    tiles->col_start_sb[i] = sb_cols;
  }
  av1_calculate_tile_cols(seq_params, mi_params->mi_rows, mi_params->mi_cols,
                          tiles);

  // configure tile rows
  int sb_rows =
      CEIL_POWER_OF_TWO(mi_params->mi_rows, seq_params->mib_size_log2);
  if (tiles->uniform_spacing) {
    tiles->log2_rows = AOMMAX(tile_cfg->tile_rows, tiles->min_log2_rows);
    tiles->log2_rows = AOMMIN(tiles->log2_rows, tiles->max_log2_rows);
  } else if (tile_cfg->tile_heights[0] < 0) {
    auto_tile_size_balancing(cm, sb_rows, tile_cfg->tile_rows, 0);
  } else {
    int size_sb, j = 0;
    for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
      tiles->row_start_sb[i] = start_sb;
      size_sb = tile_cfg->tile_heights[j++];
      if (j >= tile_cfg->tile_height_count) j = 0;
      start_sb += AOMMIN(size_sb, tiles->max_height_sb);
    }
    tiles->rows = i;
    tiles->row_start_sb[i] = sb_rows;
  }
  av1_calculate_tile_rows(seq_params, mi_params->mi_rows, tiles);
}

void av1_update_frame_size(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;

  // Setup mi_params here in case we need more mi's.
  CommonModeInfoParams *const mi_params = &cm->mi_params;
  mi_params->set_mb_mi(mi_params, cm->width, cm->height,
                       cpi->sf.part_sf.default_min_partition_size);

  av1_init_macroblockd(cm, xd);

  if (!cpi->ppi->seq_params_locked)
    set_sb_size(cm->seq_params,
                av1_select_sb_size(&cpi->oxcf, cm->width, cm->height,
                                   cpi->ppi->number_spatial_layers));

  set_tile_info(cm, &cpi->oxcf.tile_cfg);
}

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) {
  const int64_t lvl_luma_pels = (int64_t)lvl_width * lvl_height;
  const double lvl_display_sample_rate = lvl_luma_pels * lvl_fps;
  const int64_t luma_pels = (int64_t)width * height;
  const double display_sample_rate = luma_pels * fps;
  return luma_pels <= lvl_luma_pels &&
         display_sample_rate <= lvl_display_sample_rate &&
         width <= lvl_width * lvl_dim_mult &&
         height <= lvl_height * lvl_dim_mult;
}

static void set_bitstream_level_tier(AV1_PRIMARY *const ppi, int width,
                                     int height, double init_framerate) {
  SequenceHeader *const seq_params = &ppi->seq_params;
  const AV1LevelParams *const level_params = &ppi->level_params;
  // TODO(any): This is a placeholder function that only addresses dimensions
  // and max display sample rates.
  // Need to add checks for max bit rate, max decoded luma sample rate, header
  // rate, etc. that are not covered by this function.
  AV1_LEVEL level = SEQ_LEVEL_MAX;
  if (does_level_match(width, height, init_framerate, 512, 288, 30.0, 4)) {
    level = SEQ_LEVEL_2_0;
  } else if (does_level_match(width, height, init_framerate, 704, 396, 30.0,
                              4)) {
    level = SEQ_LEVEL_2_1;
  } else if (does_level_match(width, height, init_framerate, 1088, 612, 30.0,
                              4)) {
    level = SEQ_LEVEL_3_0;
  } else if (does_level_match(width, height, init_framerate, 1376, 774, 30.0,
                              4)) {
    level = SEQ_LEVEL_3_1;
  } else if (does_level_match(width, height, init_framerate, 2048, 1152, 30.0,
                              3)) {
    level = SEQ_LEVEL_4_0;
  } else if (does_level_match(width, height, init_framerate, 2048, 1152, 60.0,
                              3)) {
    level = SEQ_LEVEL_4_1;
  } else if (does_level_match(width, height, init_framerate, 4096, 2176, 30.0,
                              2)) {
    level = SEQ_LEVEL_5_0;
  } else if (does_level_match(width, height, init_framerate, 4096, 2176, 60.0,
                              2)) {
    level = SEQ_LEVEL_5_1;
  } else if (does_level_match(width, height, init_framerate, 4096, 2176, 120.0,
                              2)) {
    level = SEQ_LEVEL_5_2;
  } else if (does_level_match(width, height, init_framerate, 8192, 4352, 30.0,
                              2)) {
    level = SEQ_LEVEL_6_0;
  } else if (does_level_match(width, height, init_framerate, 8192, 4352, 60.0,
                              2)) {
    level = SEQ_LEVEL_6_1;
  } else if (does_level_match(width, height, init_framerate, 8192, 4352, 120.0,
                              2)) {
    level = SEQ_LEVEL_6_2;
  }
#if CONFIG_CWG_C013
  // TODO(bohanli): currently target level is only working for the 0th operating
  // point, so scalable coding is not supported.
  else if (level_params->target_seq_level_idx[0] >= SEQ_LEVEL_7_0 &&
           level_params->target_seq_level_idx[0] <= SEQ_LEVEL_8_3) {
    // Only use level 7.x to 8.x when explicitly asked to.
    if (does_level_match(width, height, init_framerate, 16384, 8704, 30.0, 2)) {
      level = SEQ_LEVEL_7_0;
    } else if (does_level_match(width, height, init_framerate, 16384, 8704,
                                60.0, 2)) {
      level = SEQ_LEVEL_7_1;
    } else if (does_level_match(width, height, init_framerate, 16384, 8704,
                                120.0, 2)) {
      level = SEQ_LEVEL_7_2;
    } else if (does_level_match(width, height, init_framerate, 32768, 17408,
                                30.0, 2)) {
      level = SEQ_LEVEL_8_0;
    } else if (does_level_match(width, height, init_framerate, 32768, 17408,
                                60.0, 2)) {
      level = SEQ_LEVEL_8_1;
    } else if (does_level_match(width, height, init_framerate, 32768, 17408,
                                120.0, 2)) {
      level = SEQ_LEVEL_8_2;
    }
  }
#endif

  for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
    assert(is_valid_seq_level_idx(level_params->target_seq_level_idx[i]) ||
           level_params->target_seq_level_idx[i] == SEQ_LEVEL_KEEP_STATS);
    // If a higher target level is specified, it is then used rather than the
    // inferred one from resolution and framerate.
    seq_params->seq_level_idx[i] =
        level_params->target_seq_level_idx[i] < SEQ_LEVELS &&
                level_params->target_seq_level_idx[i] > level
            ? level_params->target_seq_level_idx[i]
            : level;
    // Set the maximum parameters for bitrate and buffer size for this profile,
    // level, and tier
    seq_params->op_params[i].bitrate = av1_max_level_bitrate(
        seq_params->profile, seq_params->seq_level_idx[i], seq_params->tier[i]);
    // Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass the
    // check
    if (seq_params->op_params[i].bitrate == 0)
      aom_internal_error(
          &ppi->error, AOM_CODEC_UNSUP_BITSTREAM,
          "AV1 does not support this combination of profile, level, and tier.");
    // Buffer size in bits/s is bitrate in bits/s * 1 s
    seq_params->op_params[i].buffer_size = seq_params->op_params[i].bitrate;
  }
}

static void init_seq_coding_tools(AV1_PRIMARY *const ppi,
                                  const AV1EncoderConfig *oxcf,
                                  int disable_frame_id_numbers) {
  SequenceHeader *const seq = &ppi->seq_params;
  const FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
  const ToolCfg *const tool_cfg = &oxcf->tool_cfg;

  seq->still_picture =
      !tool_cfg->force_video_mode && (oxcf->input_cfg.limit == 1);
  seq->reduced_still_picture_hdr =
      seq->still_picture && !tool_cfg->full_still_picture_hdr;
  seq->force_screen_content_tools = 2;
  seq->force_integer_mv = 2;
  seq->order_hint_info.enable_order_hint = tool_cfg->enable_order_hint;
  seq->frame_id_numbers_present_flag =
      !seq->reduced_still_picture_hdr &&
      !oxcf->tile_cfg.enable_large_scale_tile &&
      tool_cfg->error_resilient_mode && !disable_frame_id_numbers;
  if (seq->reduced_still_picture_hdr) {
    seq->order_hint_info.enable_order_hint = 0;
    seq->force_screen_content_tools = 2;
    seq->force_integer_mv = 2;
  }
  seq->order_hint_info.order_hint_bits_minus_1 =
      seq->order_hint_info.enable_order_hint
          ? DEFAULT_EXPLICIT_ORDER_HINT_BITS - 1
          : -1;

  seq->max_frame_width = frm_dim_cfg->forced_max_frame_width
                             ? frm_dim_cfg->forced_max_frame_width
                             : frm_dim_cfg->width;
  seq->max_frame_height = frm_dim_cfg->forced_max_frame_height
                              ? frm_dim_cfg->forced_max_frame_height
                              : frm_dim_cfg->height;
  seq->num_bits_width =
      (seq->max_frame_width > 1) ? get_msb(seq->max_frame_width - 1) + 1 : 1;
  seq->num_bits_height =
      (seq->max_frame_height > 1) ? get_msb(seq->max_frame_height - 1) + 1 : 1;
  assert(seq->num_bits_width <= 16);
  assert(seq->num_bits_height <= 16);

  seq->frame_id_length = FRAME_ID_LENGTH;
  seq->delta_frame_id_length = DELTA_FRAME_ID_LENGTH;

  seq->enable_dual_filter = tool_cfg->enable_dual_filter;
  seq->order_hint_info.enable_dist_wtd_comp =
      oxcf->comp_type_cfg.enable_dist_wtd_comp;
  seq->order_hint_info.enable_dist_wtd_comp &=
      seq->order_hint_info.enable_order_hint;
  seq->order_hint_info.enable_ref_frame_mvs = tool_cfg->ref_frame_mvs_present;
  seq->order_hint_info.enable_ref_frame_mvs &=
      seq->order_hint_info.enable_order_hint;
  seq->enable_superres = oxcf->superres_cfg.enable_superres;
  seq->enable_cdef = tool_cfg->cdef_control != CDEF_NONE ? 1 : 0;
  seq->enable_restoration = tool_cfg->enable_restoration;
  seq->enable_warped_motion = oxcf->motion_mode_cfg.enable_warped_motion;
  seq->enable_interintra_compound = tool_cfg->enable_interintra_comp;
  seq->enable_masked_compound = oxcf->comp_type_cfg.enable_masked_comp;
  seq->enable_intra_edge_filter = oxcf->intra_mode_cfg.enable_intra_edge_filter;
  seq->enable_filter_intra = oxcf->intra_mode_cfg.enable_filter_intra;

  set_bitstream_level_tier(ppi, frm_dim_cfg->width, frm_dim_cfg->height,
                           oxcf->input_cfg.init_framerate);

  if (seq->operating_points_cnt_minus_1 == 0) {
    seq->operating_point_idc[0] = 0;
    seq->has_nonzero_operating_point_idc = false;
  } else {
    // Set operating_point_idc[] such that the i=0 point corresponds to the
    // highest quality operating point (all layers), and subsequent
    // operarting points (i > 0) are lower quality corresponding to
    // skip decoding enhancement  layers (temporal first).
    int i = 0;
    assert(seq->operating_points_cnt_minus_1 ==
           (int)(ppi->number_spatial_layers * ppi->number_temporal_layers - 1));
    for (unsigned int sl = 0; sl < ppi->number_spatial_layers; sl++) {
      for (unsigned int tl = 0; tl < ppi->number_temporal_layers; tl++) {
        seq->operating_point_idc[i] =
            (~(~0u << (ppi->number_spatial_layers - sl)) << 8) |
            ~(~0u << (ppi->number_temporal_layers - tl));
        assert(seq->operating_point_idc[i] != 0);
        i++;
      }
    }
    seq->has_nonzero_operating_point_idc = true;
  }
}

static void init_config_sequence(struct AV1_PRIMARY *ppi,
                                 const AV1EncoderConfig *oxcf) {
  SequenceHeader *const seq_params = &ppi->seq_params;
  const DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
  const ColorCfg *const color_cfg = &oxcf->color_cfg;

  ppi->use_svc = 0;
  ppi->number_spatial_layers = 1;
  ppi->number_temporal_layers = 1;

  seq_params->profile = oxcf->profile;
  seq_params->bit_depth = oxcf->tool_cfg.bit_depth;
  seq_params->use_highbitdepth = oxcf->use_highbitdepth;
  seq_params->color_primaries = color_cfg->color_primaries;
  seq_params->transfer_characteristics = color_cfg->transfer_characteristics;
  seq_params->matrix_coefficients = color_cfg->matrix_coefficients;
  seq_params->monochrome = oxcf->tool_cfg.enable_monochrome;
  seq_params->chroma_sample_position = color_cfg->chroma_sample_position;
  seq_params->color_range = color_cfg->color_range;
  seq_params->timing_info_present = dec_model_cfg->timing_info_present;
  seq_params->timing_info.num_units_in_display_tick =
      dec_model_cfg->timing_info.num_units_in_display_tick;
  seq_params->timing_info.time_scale = dec_model_cfg->timing_info.time_scale;
  seq_params->timing_info.equal_picture_interval =
      dec_model_cfg->timing_info.equal_picture_interval;
  seq_params->timing_info.num_ticks_per_picture =
      dec_model_cfg->timing_info.num_ticks_per_picture;

  seq_params->display_model_info_present_flag =
      dec_model_cfg->display_model_info_present_flag;
  seq_params->decoder_model_info_present_flag =
      dec_model_cfg->decoder_model_info_present_flag;
  if (dec_model_cfg->decoder_model_info_present_flag) {
    // set the decoder model parameters in schedule mode
    seq_params->decoder_model_info.num_units_in_decoding_tick =
        dec_model_cfg->num_units_in_decoding_tick;
    ppi->buffer_removal_time_present = 1;
    av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
    av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
  } else if (seq_params->timing_info_present &&
             seq_params->timing_info.equal_picture_interval &&
             !seq_params->decoder_model_info_present_flag) {
    // set the decoder model parameters in resource availability mode
    av1_set_resource_availability_parameters(&seq_params->op_params[0]);
  } else {
    seq_params->op_params[0].initial_display_delay =
        10;  // Default value (not signaled)
  }

  if (seq_params->monochrome) {
    seq_params->subsampling_x = 1;
    seq_params->subsampling_y = 1;
  } else if (seq_params->color_primaries == AOM_CICP_CP_BT_709 &&
             seq_params->transfer_characteristics == AOM_CICP_TC_SRGB &&
             seq_params->matrix_coefficients == AOM_CICP_MC_IDENTITY) {
    seq_params->subsampling_x = 0;
    seq_params->subsampling_y = 0;
  } else {
    if (seq_params->profile == 0) {
      seq_params->subsampling_x = 1;
      seq_params->subsampling_y = 1;
    } else if (seq_params->profile == 1) {
      seq_params->subsampling_x = 0;
      seq_params->subsampling_y = 0;
    } else {
      if (seq_params->bit_depth == AOM_BITS_12) {
        seq_params->subsampling_x = oxcf->input_cfg.chroma_subsampling_x;
        seq_params->subsampling_y = oxcf->input_cfg.chroma_subsampling_y;
      } else {
        seq_params->subsampling_x = 1;
        seq_params->subsampling_y = 0;
      }
    }
  }
  av1_change_config_seq(ppi, oxcf, NULL);
}

static void init_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
  AV1_COMMON *const cm = &cpi->common;
  ResizePendingParams *resize_pending_params = &cpi->resize_pending_params;

  cpi->oxcf = *oxcf;
  cpi->framerate = oxcf->input_cfg.init_framerate;

  cm->width = oxcf->frm_dim_cfg.width;
  cm->height = oxcf->frm_dim_cfg.height;
  cpi->is_dropped_frame = false;

  alloc_compressor_data(cpi);

  cpi->data_alloc_width = cm->width;
  cpi->data_alloc_height = cm->height;
  cpi->frame_size_related_setup_done = false;

  // Single thread case: use counts in common.
  cpi->td.counts = &cpi->counts;

  // Init SVC parameters.
  cpi->svc.number_spatial_layers = 1;
  cpi->svc.number_temporal_layers = 1;
  cm->spatial_layer_id = 0;
  cm->temporal_layer_id = 0;
  // Init rtc_ref parameters.
  cpi->ppi->rtc_ref.set_ref_frame_config = 0;
  cpi->ppi->rtc_ref.non_reference_frame = 0;
  cpi->ppi->rtc_ref.ref_frame_comp[0] = 0;
  cpi->ppi->rtc_ref.ref_frame_comp[1] = 0;
  cpi->ppi->rtc_ref.ref_frame_comp[2] = 0;

  // change includes all joint functionality
  av1_change_config(cpi, oxcf, false);

  cpi->ref_frame_flags = 0;

  // Reset resize pending flags
  resize_pending_params->width = 0;
  resize_pending_params->height = 0;

  // Setup identity scale factor
  av1_setup_scale_factors_for_frame(&cm->sf_identity, 1, 1, 1, 1);

  init_buffer_indices(&cpi->force_intpel_info, cm->remapped_ref_idx);

  av1_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height);
}

void av1_change_config_seq(struct AV1_PRIMARY *ppi,
                           const AV1EncoderConfig *oxcf,
                           bool *is_sb_size_changed) {
  SequenceHeader *const seq_params = &ppi->seq_params;
  const FrameDimensionCfg *const frm_dim_cfg = &oxcf->frm_dim_cfg;
  const DecoderModelCfg *const dec_model_cfg = &oxcf->dec_model_cfg;
  const ColorCfg *const color_cfg = &oxcf->color_cfg;

  if (seq_params->profile != oxcf->profile) seq_params->profile = oxcf->profile;
  seq_params->bit_depth = oxcf->tool_cfg.bit_depth;
  seq_params->color_primaries = color_cfg->color_primaries;
  seq_params->transfer_characteristics = color_cfg->transfer_characteristics;
  seq_params->matrix_coefficients = color_cfg->matrix_coefficients;
  seq_params->monochrome = oxcf->tool_cfg.enable_monochrome;
  seq_params->chroma_sample_position = color_cfg->chroma_sample_position;
  seq_params->color_range = color_cfg->color_range;

  assert(IMPLIES(seq_params->profile <= PROFILE_1,
                 seq_params->bit_depth <= AOM_BITS_10));

  seq_params->timing_info_present = dec_model_cfg->timing_info_present;
  seq_params->timing_info.num_units_in_display_tick =
      dec_model_cfg->timing_info.num_units_in_display_tick;
  seq_params->timing_info.time_scale = dec_model_cfg->timing_info.time_scale;
  seq_params->timing_info.equal_picture_interval =
      dec_model_cfg->timing_info.equal_picture_interval;
  seq_params->timing_info.num_ticks_per_picture =
      dec_model_cfg->timing_info.num_ticks_per_picture;

  seq_params->display_model_info_present_flag =
      dec_model_cfg->display_model_info_present_flag;
  seq_params->decoder_model_info_present_flag =
      dec_model_cfg->decoder_model_info_present_flag;
  if (dec_model_cfg->decoder_model_info_present_flag) {
    // set the decoder model parameters in schedule mode
    seq_params->decoder_model_info.num_units_in_decoding_tick =
        dec_model_cfg->num_units_in_decoding_tick;
    ppi->buffer_removal_time_present = 1;
    av1_set_aom_dec_model_info(&seq_params->decoder_model_info);
    av1_set_dec_model_op_parameters(&seq_params->op_params[0]);
  } else if (seq_params->timing_info_present &&
             seq_params->timing_info.equal_picture_interval &&
             !seq_params->decoder_model_info_present_flag) {
    // set the decoder model parameters in resource availability mode
    av1_set_resource_availability_parameters(&seq_params->op_params[0]);
  } else {
    seq_params->op_params[0].initial_display_delay =
        10;  // Default value (not signaled)
  }

#if !CONFIG_REALTIME_ONLY
  av1_update_film_grain_parameters_seq(ppi, oxcf);
#endif

  int sb_size = seq_params->sb_size;
  // Superblock size should not be updated after the first key frame.
  if (!ppi->seq_params_locked) {
    set_sb_size(seq_params, av1_select_sb_size(oxcf, frm_dim_cfg->width,
                                               frm_dim_cfg->height,
                                               ppi->number_spatial_layers));
    for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i)
      seq_params->tier[i] = (oxcf->tier_mask >> i) & 1;
  }
  if (is_sb_size_changed != NULL && sb_size != seq_params->sb_size)
    *is_sb_size_changed = true;

  // Init sequence level coding tools
  // This should not be called after the first key frame.
  if (!ppi->seq_params_locked) {
    seq_params->operating_points_cnt_minus_1 =
        (ppi->number_spatial_layers > 1 || ppi->number_temporal_layers > 1)
            ? ppi->number_spatial_layers * ppi->number_temporal_layers - 1
            : 0;
    init_seq_coding_tools(ppi, oxcf,
                          ppi->use_svc || ppi->rtc_ref.set_ref_frame_config);
  }
  seq_params->timing_info_present &= !seq_params->reduced_still_picture_hdr;

#if CONFIG_AV1_HIGHBITDEPTH
  highbd_set_var_fns(ppi);
#endif

  set_primary_rc_buffer_sizes(oxcf, ppi);
}

void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf,
                       bool is_sb_size_changed) {
  AV1_COMMON *const cm = &cpi->common;
  SequenceHeader *const seq_params = cm->seq_params;
  RATE_CONTROL *const rc = &cpi->rc;
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
  MACROBLOCK *const x = &cpi->td.mb;
  AV1LevelParams *const level_params = &cpi->ppi->level_params;
  RefreshFrameInfo *const refresh_frame = &cpi->refresh_frame;
  const FrameDimensionCfg *const frm_dim_cfg = &cpi->oxcf.frm_dim_cfg;
  const RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
  FeatureFlags *const features = &cm->features;

  // in case of LAP, lag in frames is set according to number of lap buffers
  // calculated at init time. This stores and restores LAP's lag in frames to
  // prevent override by new cfg.
  int lap_lag_in_frames = -1;
  if (cpi->ppi->lap_enabled && cpi->compressor_stage == LAP_STAGE) {
    lap_lag_in_frames = cpi->oxcf.gf_cfg.lag_in_frames;
  }

  cpi->oxcf = *oxcf;

#if !CONFIG_REALTIME_ONLY
  av1_update_film_grain_parameters(cpi, oxcf);
#endif

  // When user provides superres_mode = AOM_SUPERRES_AUTO, we still initialize
  // superres mode for current encoding = AOM_SUPERRES_NONE. This is to ensure
  // that any analysis (e.g. TPL) happening outside the main encoding loop still
  // happens at full resolution.
  // This value will later be set appropriately just before main encoding loop.
  cpi->superres_mode = oxcf->superres_cfg.superres_mode == AOM_SUPERRES_AUTO
                           ? AOM_SUPERRES_NONE
                           : oxcf->superres_cfg.superres_mode;  // default
  x->e_mbd.bd = (int)seq_params->bit_depth;
  x->e_mbd.global_motion = cm->global_motion;

  memcpy(level_params->target_seq_level_idx, cpi->oxcf.target_seq_level_idx,
         sizeof(level_params->target_seq_level_idx));
  level_params->keep_level_stats = 0;
  for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
    if (level_params->target_seq_level_idx[i] < SEQ_LEVELS ||
        level_params->target_seq_level_idx[i] == SEQ_LEVEL_KEEP_STATS) {
      level_params->keep_level_stats |= 1u << i;
      if (!level_params->level_info[i]) {
        CHECK_MEM_ERROR(cm, level_params->level_info[i],
                        aom_calloc(1, sizeof(*level_params->level_info[i])));
      }
    }
  }

  // TODO(huisu@): level targeting currently only works for the 0th operating
  // point, so scalable coding is not supported yet.
  if (level_params->target_seq_level_idx[0] < SEQ_LEVELS) {
    // Adjust encoder config in order to meet target level.
    config_target_level(cpi, level_params->target_seq_level_idx[0],
                        seq_params->tier[0]);
  }

  if (has_no_stats_stage(cpi) && (rc_cfg->mode == AOM_Q)) {
    p_rc->baseline_gf_interval = FIXED_GF_INTERVAL;
  } else if (!is_one_pass_rt_params(cpi) ||
             cm->current_frame.frame_number == 0) {
    // For rtc mode: logic for setting the baseline_gf_interval is done
    // in av1_get_one_pass_rt_params(), and it should not be reset here in
    // change_config(), unless after init_config (first frame).
    p_rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
  }

  refresh_frame->golden_frame = false;
  refresh_frame->bwd_ref_frame = false;

  features->refresh_frame_context =
      (oxcf->tool_cfg.frame_parallel_decoding_mode)
          ? REFRESH_FRAME_CONTEXT_DISABLED
          : REFRESH_FRAME_CONTEXT_BACKWARD;
  if (oxcf->tile_cfg.enable_large_scale_tile)
    features->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;

  if (x->palette_buffer == NULL) {
    CHECK_MEM_ERROR(cm, x->palette_buffer,
                    aom_memalign(16, sizeof(*x->palette_buffer)));
  }

  if (x->tmp_conv_dst == NULL) {
    CHECK_MEM_ERROR(
        cm, x->tmp_conv_dst,
        aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(*x->tmp_conv_dst)));
    x->e_mbd.tmp_conv_dst = x->tmp_conv_dst;
  }
  // The buffers 'tmp_pred_bufs[]' and 'comp_rd_buffer' are used in inter frames
  // to store intermediate inter mode prediction results and are not required
  // for allintra encoding mode. Hence, the memory allocations for these buffers
  // are avoided for allintra encoding mode.
  if (cpi->oxcf.kf_cfg.key_freq_max != 0) {
    if (x->comp_rd_buffer.pred0 == NULL)
      alloc_compound_type_rd_buffers(cm->error, &x->comp_rd_buffer);

    for (int i = 0; i < 2; ++i) {
      if (x->tmp_pred_bufs[i] == NULL) {
        CHECK_MEM_ERROR(cm, x->tmp_pred_bufs[i],
                        aom_memalign(32, 2 * MAX_MB_PLANE * MAX_SB_SQUARE *
                                             sizeof(*x->tmp_pred_bufs[i])));
        x->e_mbd.tmp_obmc_bufs[i] = x->tmp_pred_bufs[i];
      }
    }
  }

  av1_reset_segment_features(cm);

  av1_set_high_precision_mv(cpi, 1, 0);

  // Under a configuration change, where maximum_buffer_size may change,
  // keep buffer level clipped to the maximum allowed buffer size.
  p_rc->bits_off_target =
      AOMMIN(p_rc->bits_off_target, p_rc->maximum_buffer_size);
  p_rc->buffer_level = AOMMIN(p_rc->buffer_level, p_rc->maximum_buffer_size);

  // Set up frame rate and related parameters rate control values.
  av1_new_framerate(cpi, cpi->framerate);

  // Set absolute upper and lower quality limits
  rc->worst_quality = rc_cfg->worst_allowed_q;
  rc->best_quality = rc_cfg->best_allowed_q;

  // If lossless has been requested make sure average Q accumulators are reset.
  if (is_lossless_requested(&cpi->oxcf.rc_cfg)) {
    int i;
    for (i = 0; i < FRAME_TYPES; ++i) {
      p_rc->avg_frame_qindex[i] = 0;
    }
  }

  features->interp_filter =
      oxcf->tile_cfg.enable_large_scale_tile ? EIGHTTAP_REGULAR : SWITCHABLE;
  features->switchable_motion_mode = is_switchable_motion_mode_allowed(
      features->allow_warped_motion, oxcf->motion_mode_cfg.enable_obmc);

  if (frm_dim_cfg->render_width > 0 && frm_dim_cfg->render_height > 0) {
    cm->render_width = frm_dim_cfg->render_width;
    cm->render_height = frm_dim_cfg->render_height;
  } else {
    cm->render_width = frm_dim_cfg->width;
    cm->render_height = frm_dim_cfg->height;
  }
  cm->width = frm_dim_cfg->width;
  cm->height = frm_dim_cfg->height;

  if (cm->width > cpi->data_alloc_width ||
      cm->height > cpi->data_alloc_height || is_sb_size_changed) {
    av1_free_context_buffers(cm);
    av1_free_shared_coeff_buffer(&cpi->td.shared_coeff_buf);
    av1_free_sms_tree(&cpi->td);
    av1_free_pmc(cpi->td.firstpass_ctx, av1_num_planes(cm));
    cpi->td.firstpass_ctx = NULL;
    alloc_compressor_data(cpi);
    realloc_segmentation_maps(cpi);
    cpi->data_alloc_width = cm->width;
    cpi->data_alloc_height = cm->height;
    cpi->frame_size_related_setup_done = false;
  }
  av1_update_frame_size(cpi);

  rc->is_src_frame_alt_ref = 0;

  if (!cpi->ppi->rtc_ref.set_ref_frame_config)
    cpi->ext_flags.refresh_frame.update_pending = 0;
  cpi->ext_flags.refresh_frame_context_pending = 0;

  if (cpi->ppi->use_svc)
    av1_update_layer_context_change_config(cpi, rc_cfg->target_bandwidth);

  check_reset_rc_flag(cpi);

  // restore the value of lag_in_frame for LAP stage.
  if (lap_lag_in_frames != -1) {
    cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames;
  }

#if CONFIG_REALTIME_ONLY
  assert(!oxcf->tool_cfg.enable_global_motion);
  cpi->alloc_pyramid = false;
#else
  cpi->alloc_pyramid = oxcf->tool_cfg.enable_global_motion;
#endif  // CONFIG_REALTIME_ONLY
}

static inline void init_frame_info(FRAME_INFO *frame_info,
                                   const AV1_COMMON *const cm) {
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const SequenceHeader *const seq_params = cm->seq_params;
  frame_info->frame_width = cm->width;
  frame_info->frame_height = cm->height;
  frame_info->mi_cols = mi_params->mi_cols;
  frame_info->mi_rows = mi_params->mi_rows;
  frame_info->mb_cols = mi_params->mb_cols;
  frame_info->mb_rows = mi_params->mb_rows;
  frame_info->num_mbs = mi_params->MBs;
  frame_info->bit_depth = seq_params->bit_depth;
  frame_info->subsampling_x = seq_params->subsampling_x;
  frame_info->subsampling_y = seq_params->subsampling_y;
}

static inline void init_frame_index_set(FRAME_INDEX_SET *frame_index_set) {
  frame_index_set->show_frame_count = 0;
}

static inline void update_counters_for_show_frame(AV1_COMP *const cpi) {
  assert(cpi->common.show_frame);
  cpi->frame_index_set.show_frame_count++;
  cpi->common.current_frame.frame_number++;
}

AV1_PRIMARY *av1_create_primary_compressor(
    struct aom_codec_pkt_list *pkt_list_head, int num_lap_buffers,
    const AV1EncoderConfig *oxcf) {
  AV1_PRIMARY *volatile const ppi = aom_memalign(32, sizeof(AV1_PRIMARY));
  if (!ppi) return NULL;
  av1_zero(*ppi);

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(ppi->error.jmp)) {
    ppi->error.setjmp = 0;
    av1_remove_primary_compressor(ppi);
    return 0;
  }
  ppi->error.setjmp = 1;

  ppi->seq_params_locked = 0;
  ppi->lap_enabled = num_lap_buffers > 0;
  ppi->output_pkt_list = pkt_list_head;
  ppi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
  ppi->frames_left = oxcf->input_cfg.limit;
  ppi->num_fp_contexts = 1;

  init_config_sequence(ppi, oxcf);

#if CONFIG_ENTROPY_STATS
  av1_zero(ppi->aggregate_fc);
#endif  // CONFIG_ENTROPY_STATS

  av1_primary_rc_init(oxcf, &ppi->p_rc);

  // For two pass and lag_in_frames > 33 in LAP.
  ppi->p_rc.enable_scenecut_detection = ENABLE_SCENECUT_MODE_2;
  if (ppi->lap_enabled) {
    if ((num_lap_buffers <
         (MAX_GF_LENGTH_LAP + SCENE_CUT_KEY_TEST_INTERVAL + 1)) &&
        num_lap_buffers >= (MAX_GF_LENGTH_LAP + 3)) {
      /*
       * For lag in frames >= 19 and <33, enable scenecut
       * with limited future frame prediction.
       */

      ppi->p_rc.enable_scenecut_detection = ENABLE_SCENECUT_MODE_1;
    } else if (num_lap_buffers < (MAX_GF_LENGTH_LAP + 3)) {
      // Disable scenecut when lag_in_frames < 19.
      ppi->p_rc.enable_scenecut_detection = DISABLE_SCENECUT;
    }
  }

#define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX4DF, SDX3DF) \
  ppi->fn_ptr[BT].sdf = SDF;                              \
  ppi->fn_ptr[BT].sdaf = SDAF;                            \
  ppi->fn_ptr[BT].vf = VF;                                \
  ppi->fn_ptr[BT].svf = SVF;                              \
  ppi->fn_ptr[BT].svaf = SVAF;                            \
  ppi->fn_ptr[BT].sdx4df = SDX4DF;                        \
  ppi->fn_ptr[BT].sdx3df = SDX3DF;

// Realtime mode doesn't use 4x rectangular blocks.
#if !CONFIG_REALTIME_ONLY
  // sdaf (used in compound prediction, get_mvpred_compound_sad()) is unused
  // for 4xN and Nx4 blocks.
  BFP(BLOCK_4X16, aom_sad4x16, /*SDAF=*/NULL, aom_variance4x16,
      aom_sub_pixel_variance4x16, aom_sub_pixel_avg_variance4x16,
      aom_sad4x16x4d, aom_sad4x16x3d)

  // sdaf (used in compound prediction, get_mvpred_compound_sad()) is unused
  // for 4xN and Nx4 blocks.
  BFP(BLOCK_16X4, aom_sad16x4, /*SDAF=*/NULL, aom_variance16x4,
      aom_sub_pixel_variance16x4, aom_sub_pixel_avg_variance16x4,
      aom_sad16x4x4d, aom_sad16x4x3d)

  BFP(BLOCK_8X32, aom_sad8x32, aom_sad8x32_avg, aom_variance8x32,
      aom_sub_pixel_variance8x32, aom_sub_pixel_avg_variance8x32,
      aom_sad8x32x4d, aom_sad8x32x3d)

  BFP(BLOCK_32X8, aom_sad32x8, aom_sad32x8_avg, aom_variance32x8,
      aom_sub_pixel_variance32x8, aom_sub_pixel_avg_variance32x8,
      aom_sad32x8x4d, aom_sad32x8x3d)

  BFP(BLOCK_16X64, aom_sad16x64, aom_sad16x64_avg, aom_variance16x64,
      aom_sub_pixel_variance16x64, aom_sub_pixel_avg_variance16x64,
      aom_sad16x64x4d, aom_sad16x64x3d)

  BFP(BLOCK_64X16, aom_sad64x16, aom_sad64x16_avg, aom_variance64x16,
      aom_sub_pixel_variance64x16, aom_sub_pixel_avg_variance64x16,
      aom_sad64x16x4d, aom_sad64x16x3d)
#endif  // !CONFIG_REALTIME_ONLY

  BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
      aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
      aom_sad128x128x4d, aom_sad128x128x3d)

  BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
      aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64,
      aom_sad128x64x4d, aom_sad128x64x3d)

  BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
      aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128,
      aom_sad64x128x4d, aom_sad64x128x3d)

  BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
      aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16,
      aom_sad32x16x4d, aom_sad32x16x3d)

  BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
      aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32,
      aom_sad16x32x4d, aom_sad16x32x3d)

  BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
      aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32,
      aom_sad64x32x4d, aom_sad64x32x3d)

  BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
      aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64,
      aom_sad32x64x4d, aom_sad32x64x3d)

  BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
      aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
      aom_sad32x32x4d, aom_sad32x32x3d)

  BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
      aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
      aom_sad64x64x4d, aom_sad64x64x3d)

  BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
      aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
      aom_sad16x16x4d, aom_sad16x16x3d)

  BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
      aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8,
      aom_sad16x8x4d, aom_sad16x8x3d)

  BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
      aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16,
      aom_sad8x16x4d, aom_sad8x16x3d)

  BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
      aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x4d,
      aom_sad8x8x3d)

  // sdaf (used in compound prediction, get_mvpred_compound_sad()) is unused
  // for 4xN and Nx4 blocks.
  BFP(BLOCK_8X4, aom_sad8x4, /*SDAF=*/NULL, aom_variance8x4,
      aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, aom_sad8x4x4d,
      aom_sad8x4x3d)

  // sdaf (used in compound prediction, get_mvpred_compound_sad()) is unused
  // for 4xN and Nx4 blocks.
  BFP(BLOCK_4X8, aom_sad4x8, /*SDAF=*/NULL, aom_variance4x8,
      aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, aom_sad4x8x4d,
      aom_sad4x8x3d)

  // sdaf (used in compound prediction, get_mvpred_compound_sad()) is unused
  // for 4xN and Nx4 blocks.
  BFP(BLOCK_4X4, aom_sad4x4, /*SDAF=*/NULL, aom_variance4x4,
      aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x4d,
      aom_sad4x4x3d)

#if !CONFIG_REALTIME_ONLY
#define OBFP(BT, OSDF, OVF, OSVF) \
  ppi->fn_ptr[BT].osdf = OSDF;    \
  ppi->fn_ptr[BT].ovf = OVF;      \
  ppi->fn_ptr[BT].osvf = OSVF;

  OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
       aom_obmc_sub_pixel_variance128x128)
  OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
       aom_obmc_sub_pixel_variance128x64)
  OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
       aom_obmc_sub_pixel_variance64x128)
  OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
       aom_obmc_sub_pixel_variance64x64)
  OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
       aom_obmc_sub_pixel_variance64x32)
  OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
       aom_obmc_sub_pixel_variance32x64)
  OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
       aom_obmc_sub_pixel_variance32x32)
  OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
       aom_obmc_sub_pixel_variance32x16)
  OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
       aom_obmc_sub_pixel_variance16x32)
  OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
       aom_obmc_sub_pixel_variance16x16)
  OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
       aom_obmc_sub_pixel_variance16x8)
  OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
       aom_obmc_sub_pixel_variance8x16)
  OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
       aom_obmc_sub_pixel_variance8x8)
  OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
       aom_obmc_sub_pixel_variance4x8)
  OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
       aom_obmc_sub_pixel_variance8x4)
  OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
       aom_obmc_sub_pixel_variance4x4)
  OBFP(BLOCK_4X16, aom_obmc_sad4x16, aom_obmc_variance4x16,
       aom_obmc_sub_pixel_variance4x16)
  OBFP(BLOCK_16X4, aom_obmc_sad16x4, aom_obmc_variance16x4,
       aom_obmc_sub_pixel_variance16x4)
  OBFP(BLOCK_8X32, aom_obmc_sad8x32, aom_obmc_variance8x32,
       aom_obmc_sub_pixel_variance8x32)
  OBFP(BLOCK_32X8, aom_obmc_sad32x8, aom_obmc_variance32x8,
       aom_obmc_sub_pixel_variance32x8)
  OBFP(BLOCK_16X64, aom_obmc_sad16x64, aom_obmc_variance16x64,
       aom_obmc_sub_pixel_variance16x64)
  OBFP(BLOCK_64X16, aom_obmc_sad64x16, aom_obmc_variance64x16,
       aom_obmc_sub_pixel_variance64x16)
#endif  // !CONFIG_REALTIME_ONLY

#define MBFP(BT, MCSDF, MCSVF)  \
  ppi->fn_ptr[BT].msdf = MCSDF; \
  ppi->fn_ptr[BT].msvf = MCSVF;

  MBFP(BLOCK_128X128, aom_masked_sad128x128,
       aom_masked_sub_pixel_variance128x128)
  MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_sub_pixel_variance128x64)
  MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_sub_pixel_variance64x128)
  MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_sub_pixel_variance64x64)
  MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_sub_pixel_variance64x32)
  MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_sub_pixel_variance32x64)
  MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_sub_pixel_variance32x32)
  MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_sub_pixel_variance32x16)
  MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_sub_pixel_variance16x32)
  MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_sub_pixel_variance16x16)
  MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_sub_pixel_variance16x8)
  MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_sub_pixel_variance8x16)
  MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_sub_pixel_variance8x8)
  MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_sub_pixel_variance4x8)
  MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_sub_pixel_variance8x4)
  MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_sub_pixel_variance4x4)

#if !CONFIG_REALTIME_ONLY
  MBFP(BLOCK_4X16, aom_masked_sad4x16, aom_masked_sub_pixel_variance4x16)
  MBFP(BLOCK_16X4, aom_masked_sad16x4, aom_masked_sub_pixel_variance16x4)
  MBFP(BLOCK_8X32, aom_masked_sad8x32, aom_masked_sub_pixel_variance8x32)
  MBFP(BLOCK_32X8, aom_masked_sad32x8, aom_masked_sub_pixel_variance32x8)
  MBFP(BLOCK_16X64, aom_masked_sad16x64, aom_masked_sub_pixel_variance16x64)
  MBFP(BLOCK_64X16, aom_masked_sad64x16, aom_masked_sub_pixel_variance64x16)
#endif

#define SDSFP(BT, SDSF, SDSX4DF) \
  ppi->fn_ptr[BT].sdsf = SDSF;   \
  ppi->fn_ptr[BT].sdsx4df = SDSX4DF;

  SDSFP(BLOCK_128X128, aom_sad_skip_128x128, aom_sad_skip_128x128x4d)
  SDSFP(BLOCK_128X64, aom_sad_skip_128x64, aom_sad_skip_128x64x4d)
  SDSFP(BLOCK_64X128, aom_sad_skip_64x128, aom_sad_skip_64x128x4d)
  SDSFP(BLOCK_64X64, aom_sad_skip_64x64, aom_sad_skip_64x64x4d)
  SDSFP(BLOCK_64X32, aom_sad_skip_64x32, aom_sad_skip_64x32x4d)

  SDSFP(BLOCK_32X64, aom_sad_skip_32x64, aom_sad_skip_32x64x4d)
  SDSFP(BLOCK_32X32, aom_sad_skip_32x32, aom_sad_skip_32x32x4d)
  SDSFP(BLOCK_32X16, aom_sad_skip_32x16, aom_sad_skip_32x16x4d)

  SDSFP(BLOCK_16X32, aom_sad_skip_16x32, aom_sad_skip_16x32x4d)
  SDSFP(BLOCK_16X16, aom_sad_skip_16x16, aom_sad_skip_16x16x4d)
  SDSFP(BLOCK_8X16, aom_sad_skip_8x16, aom_sad_skip_8x16x4d)

#if !CONFIG_REALTIME_ONLY
  SDSFP(BLOCK_64X16, aom_sad_skip_64x16, aom_sad_skip_64x16x4d)
  SDSFP(BLOCK_16X64, aom_sad_skip_16x64, aom_sad_skip_16x64x4d)
  SDSFP(BLOCK_8X32, aom_sad_skip_8x32, aom_sad_skip_8x32x4d)
  SDSFP(BLOCK_4X16, aom_sad_skip_4x16, aom_sad_skip_4x16x4d)
#endif
#undef SDSFP

#if CONFIG_AV1_HIGHBITDEPTH
  highbd_set_var_fns(ppi);
#endif

  {
    // As cm->mi_params is a part of the frame level context (cpi), it is
    // unavailable at this point. mi_params is created as a local temporary
    // variable, to be passed into the functions used for allocating tpl
    // buffers. The values in this variable are populated according to initial
    // width and height of the frame.
    CommonModeInfoParams mi_params;
    enc_set_mb_mi(&mi_params, oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height,
                  BLOCK_4X4);

    const BLOCK_SIZE bsize = BLOCK_16X16;
    const int w = mi_size_wide[bsize];
    const int h = mi_size_high[bsize];
    const int num_cols = (mi_params.mi_cols + w - 1) / w;
    const int num_rows = (mi_params.mi_rows + h - 1) / h;
    AOM_CHECK_MEM_ERROR(
        &ppi->error, ppi->tpl_sb_rdmult_scaling_factors,
        aom_calloc(num_rows * num_cols,
                   sizeof(*ppi->tpl_sb_rdmult_scaling_factors)));

#if CONFIG_INTERNAL_STATS
    ppi->b_calculate_blockiness = 1;
    ppi->b_calculate_consistency = 1;

    for (int i = 0; i <= STAT_ALL; i++) {
      ppi->psnr[0].stat[i] = 0;
      ppi->psnr[1].stat[i] = 0;

      ppi->fastssim.stat[i] = 0;
      ppi->psnrhvs.stat[i] = 0;
    }

    ppi->psnr[0].worst = 100.0;
    ppi->psnr[1].worst = 100.0;
    ppi->worst_ssim = 100.0;
    ppi->worst_ssim_hbd = 100.0;

    ppi->count[0] = 0;
    ppi->count[1] = 0;
    ppi->total_bytes = 0;

    if (ppi->b_calculate_psnr) {
      ppi->total_sq_error[0] = 0;
      ppi->total_samples[0] = 0;
      ppi->total_sq_error[1] = 0;
      ppi->total_samples[1] = 0;
      ppi->total_recode_hits = 0;
      ppi->summed_quality = 0;
      ppi->summed_weights = 0;
      ppi->summed_quality_hbd = 0;
      ppi->summed_weights_hbd = 0;
    }

    ppi->fastssim.worst = 100.0;
    ppi->psnrhvs.worst = 100.0;

    if (ppi->b_calculate_blockiness) {
      ppi->total_blockiness = 0;
      ppi->worst_blockiness = 0.0;
    }

    ppi->total_inconsistency = 0;
    ppi->worst_consistency = 100.0;
    if (ppi->b_calculate_consistency) {
      AOM_CHECK_MEM_ERROR(&ppi->error, ppi->ssim_vars,
                          aom_malloc(sizeof(*ppi->ssim_vars) * 4 *
                                     mi_params.mi_rows * mi_params.mi_cols));
    }
#endif
  }

  ppi->error.setjmp = 0;
  return ppi;
}

AV1_COMP *av1_create_compressor(AV1_PRIMARY *ppi, const AV1EncoderConfig *oxcf,
                                BufferPool *const pool, COMPRESSOR_STAGE stage,
                                int lap_lag_in_frames) {
  AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));

  if (!cpi) return NULL;

  av1_zero(*cpi);

  cpi->ppi = ppi;

  AV1_COMMON *volatile const cm = &cpi->common;
  cm->seq_params = &ppi->seq_params;
  cm->error =
      (struct aom_internal_error_info *)aom_calloc(1, sizeof(*cm->error));
  if (!cm->error) {
    aom_free(cpi);
    return NULL;
  }

  // The jmp_buf is valid only for the duration of the function that calls
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
  // before it returns.
  if (setjmp(cm->error->jmp)) {
    cm->error->setjmp = 0;
    av1_remove_compressor(cpi);
    return NULL;
  }

  cm->error->setjmp = 1;
  cpi->compressor_stage = stage;

  cpi->do_frame_data_update = true;

  CommonModeInfoParams *const mi_params = &cm->mi_params;
  mi_params->free_mi = enc_free_mi;
  mi_params->setup_mi = enc_setup_mi;
  mi_params->set_mb_mi =
      (oxcf->pass == AOM_RC_FIRST_PASS || cpi->compressor_stage == LAP_STAGE)
          ? stat_stage_set_mb_mi
          : enc_set_mb_mi;

  mi_params->mi_alloc_bsize = BLOCK_4X4;

  CHECK_MEM_ERROR(cm, cm->fc,
                  (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
  CHECK_MEM_ERROR(
      cm, cm->default_frame_context,
      (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->default_frame_context)));
  memset(cm->fc, 0, sizeof(*cm->fc));
  memset(cm->default_frame_context, 0, sizeof(*cm->default_frame_context));

  cpi->common.buffer_pool = pool;

  init_config(cpi, oxcf);
  if (cpi->compressor_stage == LAP_STAGE) {
    cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames;
  }

  av1_rc_init(&cpi->oxcf, &cpi->rc);

  init_frame_info(&cpi->frame_info, cm);
  init_frame_index_set(&cpi->frame_index_set);

  cm->current_frame.frame_number = 0;
  cpi->rc.frame_number_encoded = 0;
  cpi->rc.prev_frame_is_dropped = 0;
  cpi->rc.max_consec_drop = INT_MAX;
  cpi->rc.drop_count_consec = 0;
  cm->current_frame_id = -1;
  cpi->tile_data = NULL;
  cpi->last_show_frame_buf = NULL;
  realloc_segmentation_maps(cpi);

  cpi->refresh_frame.alt_ref_frame = false;

#if CONFIG_SPEED_STATS
  cpi->tx_search_count = 0;
#endif  // CONFIG_SPEED_STATS

  cpi->time_stamps.first_ts_start = INT64_MAX;

#ifdef OUTPUT_YUV_REC
  yuv_rec_file = fopen("rec.yuv""wb");
#endif
#ifdef OUTPUT_YUV_DENOISED
  yuv_denoised_file = fopen("denoised.yuv""wb");
#endif

#if !CONFIG_REALTIME_ONLY
  if (is_stat_consumption_stage(cpi)) {
    const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    const int packets = (int)(oxcf->twopass_stats_in.sz / packet_sz);

    if (!cpi->ppi->lap_enabled) {
      /*Re-initialize to stats buffer, populated by application in the case of
       * two pass*/

      cpi->ppi->twopass.stats_buf_ctx->stats_in_start =
          oxcf->twopass_stats_in.buf;
      cpi->twopass_frame.stats_in =
          cpi->ppi->twopass.stats_buf_ctx->stats_in_start;
      cpi->ppi->twopass.stats_buf_ctx->stats_in_end =
          &cpi->ppi->twopass.stats_buf_ctx->stats_in_start[packets - 1];

      // The buffer size is packets - 1 because the last packet is total_stats.
      av1_firstpass_info_init(&cpi->ppi->twopass.firstpass_info,
                              oxcf->twopass_stats_in.buf, packets - 1);
      av1_init_second_pass(cpi);
    } else {
      av1_firstpass_info_init(&cpi->ppi->twopass.firstpass_info, NULL, 0);
      av1_init_single_pass_lap(cpi);
    }
  }
#endif

  // The buffer "obmc_buffer" is used in inter frames for fast obmc search.
  // Hence, the memory allocation for the same is avoided for allintra encoding
  // mode.
  if (cpi->oxcf.kf_cfg.key_freq_max != 0)
    alloc_obmc_buffers(&cpi->td.mb.obmc_buffer, cm->error);

  for (int x = 0; x < 2; x++)
    for (int y = 0; y < 2; y++)
      CHECK_MEM_ERROR(
          cm, cpi->td.mb.intrabc_hash_info.hash_value_buffer[x][y],
          (uint32_t *)aom_malloc(
              AOM_BUFFER_SIZE_FOR_BLOCK_HASH *
              sizeof(*cpi->td.mb.intrabc_hash_info.hash_value_buffer[0][0])));

  cpi->td.mb.intrabc_hash_info.g_crc_initialized = 0;

  av1_set_speed_features_framesize_independent(cpi, oxcf->speed);
  av1_set_speed_features_framesize_dependent(cpi, oxcf->speed);

  int max_mi_cols = mi_params->mi_cols;
  int max_mi_rows = mi_params->mi_rows;
  if (oxcf->frm_dim_cfg.forced_max_frame_width) {
    max_mi_cols = size_in_mi(oxcf->frm_dim_cfg.forced_max_frame_width);
  }
  if (oxcf->frm_dim_cfg.forced_max_frame_height) {
    max_mi_rows = size_in_mi(oxcf->frm_dim_cfg.forced_max_frame_height);
  }

  const int consec_zero_mv_alloc_size = (max_mi_rows * max_mi_cols) >> 2;
  CHECK_MEM_ERROR(
      cm, cpi->consec_zero_mv,
      aom_calloc(consec_zero_mv_alloc_size, sizeof(*cpi->consec_zero_mv)));
  cpi->consec_zero_mv_alloc_size = consec_zero_mv_alloc_size;

  cpi->mb_weber_stats = NULL;
  cpi->mb_delta_q = NULL;
  cpi->palette_pixel_num = 0;
  cpi->scaled_last_source_available = 0;

  {
    const BLOCK_SIZE bsize = BLOCK_16X16;
    const int w = mi_size_wide[bsize];
    const int h = mi_size_high[bsize];
    const int num_cols = (max_mi_cols + w - 1) / w;
    const int num_rows = (max_mi_rows + h - 1) / h;
    CHECK_MEM_ERROR(cm, cpi->ssim_rdmult_scaling_factors,
                    aom_calloc(num_rows * num_cols,
                               sizeof(*cpi->ssim_rdmult_scaling_factors)));
    CHECK_MEM_ERROR(cm, cpi->tpl_rdmult_scaling_factors,
                    aom_calloc(num_rows * num_cols,
                               sizeof(*cpi->tpl_rdmult_scaling_factors)));
  }

#if CONFIG_TUNE_VMAF
  {
    const BLOCK_SIZE bsize = BLOCK_64X64;
    const int w = mi_size_wide[bsize];
    const int h = mi_size_high[bsize];
    const int num_cols = (mi_params->mi_cols + w - 1) / w;
    const int num_rows = (mi_params->mi_rows + h - 1) / h;
    CHECK_MEM_ERROR(cm, cpi->vmaf_info.rdmult_scaling_factors,
                    aom_calloc(num_rows * num_cols,
                               sizeof(*cpi->vmaf_info.rdmult_scaling_factors)));
    for (int i = 0; i < MAX_ARF_LAYERS; i++) {
      cpi->vmaf_info.last_frame_unsharp_amount[i] = -1.0;
      cpi->vmaf_info.last_frame_ysse[i] = -1.0;
      cpi->vmaf_info.last_frame_vmaf[i] = -1.0;
    }
    cpi->vmaf_info.original_qindex = -1;
    cpi->vmaf_info.vmaf_model = NULL;
  }
#endif

#if CONFIG_TUNE_BUTTERAUGLI
  {
    const int w = mi_size_wide[butteraugli_rdo_bsize];
    const int h = mi_size_high[butteraugli_rdo_bsize];
    const int num_cols = (mi_params->mi_cols + w - 1) / w;
    const int num_rows = (mi_params->mi_rows + h - 1) / h;
    CHECK_MEM_ERROR(
        cm, cpi->butteraugli_info.rdmult_scaling_factors,
        aom_malloc(num_rows * num_cols *
                   sizeof(*cpi->butteraugli_info.rdmult_scaling_factors)));
    memset(&cpi->butteraugli_info.source, 0,
           sizeof(cpi->butteraugli_info.source));
    memset(&cpi->butteraugli_info.resized_source, 0,
           sizeof(cpi->butteraugli_info.resized_source));
    cpi->butteraugli_info.recon_set = false;
  }
#endif

#if CONFIG_SALIENCY_MAP
  {
    CHECK_MEM_ERROR(cm, cpi->saliency_map,
                    (uint8_t *)aom_calloc(cm->height * cm->width,
                                          sizeof(*cpi->saliency_map)));
    // Buffer initialization based on MIN_MIB_SIZE_LOG2 to ensure that
    // cpi->sm_scaling_factor buffer is allocated big enough, since we have no
    // idea of the actual superblock size we are going to use yet.
    const int min_mi_w_sb = (1 << MIN_MIB_SIZE_LOG2);
    const int min_mi_h_sb = (1 << MIN_MIB_SIZE_LOG2);
    const int max_sb_cols =
        (cm->mi_params.mi_cols + min_mi_w_sb - 1) / min_mi_w_sb;
    const int max_sb_rows =
        (cm->mi_params.mi_rows + min_mi_h_sb - 1) / min_mi_h_sb;
    CHECK_MEM_ERROR(cm, cpi->sm_scaling_factor,
                    (double *)aom_calloc(max_sb_rows * max_sb_cols,
                                         sizeof(*cpi->sm_scaling_factor)));
  }
#endif

#if CONFIG_COLLECT_PARTITION_STATS
  av1_zero(cpi->partition_stats);
#endif  // CONFIG_COLLECT_PARTITION_STATS

  // Initialize the members of DeltaQuantParams with INT_MAX to ensure that
  // the quantizer tables are correctly initialized using the default deltaq
  // parameters when av1_init_quantizer is called for the first time.
  DeltaQuantParams *const prev_deltaq_params =
      &cpi->enc_quant_dequant_params.prev_deltaq_params;
  prev_deltaq_params->y_dc_delta_q = INT_MAX;
  prev_deltaq_params->u_dc_delta_q = INT_MAX;
  prev_deltaq_params->v_dc_delta_q = INT_MAX;
  prev_deltaq_params->u_ac_delta_q = INT_MAX;
  prev_deltaq_params->v_ac_delta_q = INT_MAX;

  av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
                     cm->seq_params->bit_depth);
  av1_qm_init(&cm->quant_params, av1_num_planes(cm));

  av1_loop_filter_init(cm);
  cm->superres_scale_denominator = SCALE_NUMERATOR;
  cm->superres_upscaled_width = oxcf->frm_dim_cfg.width;
  cm->superres_upscaled_height = oxcf->frm_dim_cfg.height;
#if !CONFIG_REALTIME_ONLY
  av1_loop_restoration_precal();
#endif

#if CONFIG_THREE_PASS
  cpi->third_pass_ctx = NULL;
  if (cpi->oxcf.pass == AOM_RC_THIRD_PASS) {
    av1_init_thirdpass_ctx(cm, &cpi->third_pass_ctx, NULL);
  }
#endif

  cpi->second_pass_log_stream = NULL;
  cpi->use_ducky_encode = 0;

  cm->error->setjmp = 0;
  return cpi;
}

#if CONFIG_INTERNAL_STATS
#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))

#define SNPRINT2(H, T, V) \
  snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
#endif  // CONFIG_INTERNAL_STATS

void av1_remove_primary_compressor(AV1_PRIMARY *ppi) {
  if (!ppi) return;
#if !CONFIG_REALTIME_ONLY
  av1_tf_info_free(&ppi->tf_info);
#endif  // !CONFIG_REALTIME_ONLY

  for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
    aom_free(ppi->level_params.level_info[i]);
  }
  av1_lookahead_destroy(ppi->lookahead);

  aom_free(ppi->tpl_sb_rdmult_scaling_factors);
  ppi->tpl_sb_rdmult_scaling_factors = NULL;

  TplParams *const tpl_data = &ppi->tpl_data;
  aom_free(tpl_data->txfm_stats_list);

  for (int frame = 0; frame < MAX_LAG_BUFFERS; ++frame) {
    aom_free(tpl_data->tpl_stats_pool[frame]);
    aom_free_frame_buffer(&tpl_data->tpl_rec_pool[frame]);
    tpl_data->tpl_stats_pool[frame] = NULL;
  }

#if !CONFIG_REALTIME_ONLY
  av1_tpl_dealloc(&tpl_data->tpl_mt_sync);
#endif

  av1_terminate_workers(ppi);
  free_thread_data(ppi);

  aom_free(ppi->p_mt_info.tile_thr_data);
  ppi->p_mt_info.tile_thr_data = NULL;
  aom_free(ppi->p_mt_info.workers);
  ppi->p_mt_info.workers = NULL;
  ppi->p_mt_info.num_workers = 0;

  aom_free(ppi);
}

void av1_remove_compressor(AV1_COMP *cpi) {
  if (!cpi) return;
#if CONFIG_RATECTRL_LOG
  if (cpi->oxcf.pass == 3) {
    rc_log_show(&cpi->rc_log);
  }
#endif  // CONFIG_RATECTRL_LOG

  AV1_COMMON *cm = &cpi->common;
  if (cm->current_frame.frame_number > 0) {
#if CONFIG_SPEED_STATS
    if (!is_stat_generation_stage(cpi)) {
      fprintf(stdout, "tx_search_count = %d\n", cpi->tx_search_count);
    }
#endif  // CONFIG_SPEED_STATS

#if CONFIG_COLLECT_PARTITION_STATS == 2
    if (!is_stat_generation_stage(cpi)) {
      av1_print_fr_partition_timing_stats(&cpi->partition_stats,
                                          "fr_part_timing_data.csv");
    }
#endif
  }

#if CONFIG_AV1_TEMPORAL_DENOISING
  av1_denoiser_free(&(cpi->denoiser));
#endif

  if (cm->error) {
    // Help detect use after free of the error detail string.
    memset(cm->error->detail, 'A'sizeof(cm->error->detail) - 1);
    cm->error->detail[sizeof(cm->error->detail) - 1] = '\0';
    aom_free(cm->error);
  }
  aom_free(cpi->td.tctx);
  MultiThreadInfo *const mt_info = &cpi->mt_info;
#if CONFIG_MULTITHREAD
  pthread_mutex_t *const enc_row_mt_mutex_ = mt_info->enc_row_mt.mutex_;
  pthread_cond_t *const enc_row_mt_cond_ = mt_info->enc_row_mt.cond_;
  pthread_mutex_t *const gm_mt_mutex_ = mt_info->gm_sync.mutex_;
  pthread_mutex_t *const tpl_error_mutex_ = mt_info->tpl_row_mt.mutex_;
  pthread_mutex_t *const pack_bs_mt_mutex_ = mt_info->pack_bs_sync.mutex_;
--> --------------------

--> maximum size reached

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

Messung V0.5
C=94 H=92 G=92

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ¤

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