/*
 * Copyright (c) 2021, 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 "av1/encoder/thirdpass.h"

#if CONFIG_THREE_PASS && CONFIG_AV1_DECODER
#include "aom/aom_codec.h"
#include "aom/aomdx.h"
#include "aom_dsp/psnr.h"
#include "aom_mem/aom_mem.h"
#include "av1/av1_iface_common.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/firstpass.h"
#include "av1/common/blockd.h"
#include "common/ivfdec.h"

static void setup_two_pass_stream_input(
    struct AvxInputContext **input_ctx_ptr, const char *input_file_name,
    struct aom_internal_error_info *err_info) {
  FILE *infile;
  infile = fopen(input_file_name, "rb");
  if (!infile) {
    aom_internal_error(err_info, AOM_CODEC_INVALID_PARAM,
                       "Failed to open input file '%s'.", input_file_name);
  }
  struct AvxInputContext *aom_input_ctx = aom_malloc(sizeof(*aom_input_ctx));
  if (!aom_input_ctx) {
    fclose(infile);
    aom_internal_error(err_info, AOM_CODEC_MEM_ERROR,
                       "Failed to allocate memory for third-pass context.");
  }
  memset(aom_input_ctx, 0, sizeof(*aom_input_ctx));
  aom_input_ctx->filename = input_file_name;
  aom_input_ctx->file = infile;

  if (file_is_ivf(aom_input_ctx)) {
    aom_input_ctx->file_type = FILE_TYPE_IVF;
  } else {
    fclose(infile);
    aom_free(aom_input_ctx);
    aom_internal_error(err_info, AOM_CODEC_INVALID_PARAM,
                       "Unrecognized input file type.");
  }
  *input_ctx_ptr = aom_input_ctx;
}

static void init_third_pass(THIRD_PASS_DEC_CTX *ctx) {
  if (!ctx->input_ctx) {
    if (ctx->input_file_name == NULL) {
      aom_internal_error(ctx->err_info, AOM_CODEC_INVALID_PARAM,
                         "No third pass input specified.");
    }
    setup_two_pass_stream_input(&ctx->input_ctx, ctx->input_file_name,
                                ctx->err_info);
  }

  if (!ctx->decoder.iface) {
    aom_codec_iface_t *decoder_iface = &aom_codec_av1_inspect_algo;
    if (aom_codec_dec_init(&ctx->decoder, decoder_iface, NULL, 0)) {
      aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                         "Failed to initialize decoder.");
    }
  }
}

// Return 0: success
//        1: cannot read because this is end of file
//       -1: failure to read the frame
static int read_frame(THIRD_PASS_DEC_CTX *ctx) {
  if (!ctx->input_ctx || !ctx->decoder.iface) {
    init_third_pass(ctx);
  }
  if (!ctx->have_frame) {
    if (ivf_read_frame(ctx->input_ctx->file, &ctx->buf, &ctx->bytes_in_buffer,
                       &ctx->buffer_size, NULL) != 0) {
      if (feof(ctx->input_ctx->file)) {
        return 1;
      } else {
        return -1;
      }
    }
    ctx->frame = ctx->buf;
    ctx->end_frame = ctx->frame + ctx->bytes_in_buffer;
    ctx->have_frame = 1;
  }

  Av1DecodeReturn adr;
  if (aom_codec_decode(&ctx->decoder, ctx->frame,
                       (unsigned int)ctx->bytes_in_buffer,
                       &adr) != AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to decode frame for third pass.");
  }
  ctx->this_frame_bits = (int)(adr.buf - ctx->frame) << 3;
  ctx->frame = adr.buf;
  ctx->bytes_in_buffer = ctx->end_frame - ctx->frame;
  if (ctx->frame == ctx->end_frame) ctx->have_frame = 0;
  return 0;
}

static void free_frame_info(THIRD_PASS_FRAME_INFO *frame_info) {
  if (!frame_info) return;
  aom_free(frame_info->mi_info);
  frame_info->mi_info = NULL;
}

// This function gets the information needed from the recently decoded frame,
// via various decoder APIs, and saves the info into ctx->frame_info.
// Return 0: success
//        1: cannot read because this is end of file
//       -1: failure to read the frame
static int get_frame_info(THIRD_PASS_DEC_CTX *ctx) {
  int ret = read_frame(ctx);
  if (ret != 0) return ret;
  int cur = ctx->frame_info_count;

  ctx->frame_info[cur].actual_bits = ctx->this_frame_bits;

  if (cur >= MAX_THIRD_PASS_BUF) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Third pass frame info ran out of available slots.");
  }
  int frame_type_flags = 0;
  if (aom_codec_control(&ctx->decoder, AOMD_GET_FRAME_FLAGS,
                        &frame_type_flags) != AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to read frame flags.");
  }
  if (frame_type_flags & AOM_FRAME_IS_KEY) {
    ctx->frame_info[cur].frame_type = KEY_FRAME;
  } else if (frame_type_flags & AOM_FRAME_IS_INTRAONLY) {
    ctx->frame_info[cur].frame_type = INTRA_ONLY_FRAME;
  } else if (frame_type_flags & AOM_FRAME_IS_SWITCH) {
    ctx->frame_info[cur].frame_type = S_FRAME;
  } else {
    ctx->frame_info[cur].frame_type = INTER_FRAME;
  }

  // Get frame width and height
  int frame_size[2];
  if (aom_codec_control(&ctx->decoder, AV1D_GET_FRAME_SIZE, frame_size) !=
      AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to read frame size.");
  }

  // Check if we need to re-alloc the mi fields.
  const int mi_cols = (frame_size[0] + 3) >> 2;
  const int mi_rows = (frame_size[1] + 3) >> 2;
  ctx->frame_info[cur].mi_stride = mi_cols;
  ctx->frame_info[cur].mi_rows = mi_rows;
  ctx->frame_info[cur].mi_cols = mi_cols;

  if (ctx->frame_info[cur].width != frame_size[0] ||
      ctx->frame_info[cur].height != frame_size[1] ||
      !ctx->frame_info[cur].mi_info) {
    free_frame_info(&ctx->frame_info[cur]);

    ctx->frame_info[cur].mi_info =
        aom_malloc(mi_cols * mi_rows * sizeof(*ctx->frame_info[cur].mi_info));

    if (!ctx->frame_info[cur].mi_info) {
      aom_internal_error(ctx->err_info, AOM_CODEC_MEM_ERROR,
                         "Failed to allocate mi buffer for the third pass.");
    }
  }

  ctx->frame_info[cur].width = frame_size[0];
  ctx->frame_info[cur].height = frame_size[1];

  // Get frame base q idx
  if (aom_codec_control(&ctx->decoder, AOMD_GET_BASE_Q_IDX,
                        &ctx->frame_info[cur].base_q_idx) != AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to read base q index.");
  }

  // Get show existing frame flag
  if (aom_codec_control(&ctx->decoder, AOMD_GET_SHOW_EXISTING_FRAME_FLAG,
                        &ctx->frame_info[cur].is_show_existing_frame) !=
      AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to read show existing frame flag.");
  }

  // Get show frame flag
  if (aom_codec_control(&ctx->decoder, AOMD_GET_SHOW_FRAME_FLAG,
                        &ctx->frame_info[cur].is_show_frame) != AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to read show frame flag.");
  }

  // Get order hint
  if (aom_codec_control(&ctx->decoder, AOMD_GET_ORDER_HINT,
                        &ctx->frame_info[cur].order_hint) != AOM_CODEC_OK) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Failed to read order hint.");
  }

  // Clear MI info
  for (int mi_row = 0; mi_row < mi_rows; mi_row++) {
    for (int mi_col = 0; mi_col < mi_cols; mi_col++) {
      ctx->frame_info[cur].mi_info[mi_row * mi_cols + mi_col].bsize =
          BLOCK_INVALID;
    }
  }

  // Get relevant information regarding each 4x4 MI
  MB_MODE_INFO cur_mi_info;
  THIRD_PASS_MI_INFO *const this_mi = ctx->frame_info[cur].mi_info;
  for (int mi_row = 0; mi_row < mi_rows; mi_row++) {
    for (int mi_col = 0; mi_col < mi_cols; mi_col++) {
      const int offset = mi_row * mi_cols + mi_col;
      if (this_mi[offset].bsize != BLOCK_INVALID) {
        continue;
      }
      // Get info of this MI
      if (aom_codec_control(&ctx->decoder, AV1D_GET_MI_INFO, mi_row, mi_col,
                            &cur_mi_info) != AOM_CODEC_OK) {
        aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                           "Failed to read mi info.");
      }
      const int blk_mi_rows = mi_size_high[cur_mi_info.bsize];
      const int blk_mi_cols = mi_size_wide[cur_mi_info.bsize];

      for (int h = 0; h < blk_mi_rows; h++) {
        for (int w = 0; w < blk_mi_cols; w++) {
          if (h + mi_row >= mi_rows || w + mi_col >= mi_cols) {
            continue;
          }
          const int this_offset = offset + h * mi_cols + w;
          this_mi[this_offset].bsize = cur_mi_info.bsize;
          this_mi[this_offset].partition = cur_mi_info.partition;
          this_mi[this_offset].mi_row_start = mi_row;
          this_mi[this_offset].mi_col_start = mi_col;
          this_mi[this_offset].mv[0] = cur_mi_info.mv[0];
          this_mi[this_offset].mv[1] = cur_mi_info.mv[1];
          this_mi[this_offset].ref_frame[0] = cur_mi_info.ref_frame[0];
          this_mi[this_offset].ref_frame[1] = cur_mi_info.ref_frame[1];
          this_mi[this_offset].pred_mode = cur_mi_info.mode;
        }
      }
    }
  }

  ctx->frame_info_count++;

  return 0;
}

#define USE_SECOND_PASS_FILE 1

#if !USE_SECOND_PASS_FILE
// Parse the frames in the gop and determine the last frame of the current GOP.
// Decode more frames if necessary. The variable max_num is the maximum static
// GOP length if we detect an IPPP structure, and it is expected that max_mum >=
// MAX_GF_INTERVAL.
static void get_current_gop_end(THIRD_PASS_DEC_CTX *ctx, int max_num,
                                int *last_idx) {
  assert(max_num >= MAX_GF_INTERVAL);
  *last_idx = 0;
  int cur_idx = 0;
  int arf_order_hint = -1;
  int num_show_frames = 0;
  while (num_show_frames < max_num) {
    assert(cur_idx < MAX_THIRD_PASS_BUF);
    // Read in from bitstream if needed.
    if (cur_idx >= ctx->frame_info_count) {
      int ret = get_frame_info(ctx);
      if (ret == 1) {
        // At the end of the file, GOP ends in the prev frame.
        if (arf_order_hint >= 0) {
          aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                             "Failed to derive GOP length.");
        }
        *last_idx = cur_idx - 1;
        return;
      }
      if (ret < 0) {
        aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                           "Failed to read frame for third pass.");
      }
    }

    // TODO(bohanli): verify that fwd_kf works here.
    if (ctx->frame_info[cur_idx].frame_type == KEY_FRAME &&
        ctx->frame_info[cur_idx].is_show_frame) {
      if (cur_idx != 0) {
        // If this is a key frame and is not the first kf in this kf group, we
        // have reached the next key frame. Stop here.
        *last_idx = cur_idx - 1;
        return;
      }
    } else if (!ctx->frame_info[cur_idx].is_show_frame &&
               arf_order_hint == -1) {
      // If this is an arf (the first no show)
      if (num_show_frames <= 1) {
        // This is an arf and we should end the GOP with its overlay.
        arf_order_hint = ctx->frame_info[cur_idx].order_hint;
      } else {
        // There are multiple show frames before the this arf, so we treat the
        // frames previous to this arf as a GOP.
        *last_idx = cur_idx - 1;
        return;
      }
    } else if (arf_order_hint >= 0 && ctx->frame_info[cur_idx].order_hint ==
                                          (unsigned int)arf_order_hint) {
      // If this is the overlay/show existing of the arf
      assert(ctx->frame_info[cur_idx].is_show_frame);
      *last_idx = cur_idx;
      return;
    } else {
      // This frame is part of the GOP.
      if (ctx->frame_info[cur_idx].is_show_frame) num_show_frames++;
    }
    cur_idx++;
  }
  // This is a long IPPP GOP and we will use a length of max_num here.
  assert(arf_order_hint < 0);
  *last_idx = max_num - 1;
  return;
}
#endif

static AOM_INLINE void read_gop_frames(THIRD_PASS_DEC_CTX *ctx) {
  int cur_idx = 0;
  while (cur_idx < ctx->gop_info.num_frames) {
    assert(cur_idx < MAX_THIRD_PASS_BUF);
    // Read in from bitstream if needed.
    if (cur_idx >= ctx->frame_info_count) {
      int ret = get_frame_info(ctx);
      if (ret != 0) {
        aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                           "Failed to read frame for third pass.");
      }
    }
    cur_idx++;
  }
  return;
}

void av1_set_gop_third_pass(THIRD_PASS_DEC_CTX *ctx) {
  // Read in future frames in the current GOP.
  read_gop_frames(ctx);

  int gf_len = 0;
  // Check the GOP length against the value read from second_pass_file
  for (int i = 0; i < ctx->gop_info.num_frames; i++) {
    if (ctx->frame_info[i].is_show_frame) gf_len++;
  }

  if (gf_len != ctx->gop_info.gf_length) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Mismatch in third pass GOP length!");
  }
}

void av1_pop_third_pass_info(THIRD_PASS_DEC_CTX *ctx) {
  if (ctx->frame_info_count == 0) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "No available frame info for third pass.");
  }
  ctx->frame_info_count--;
  free_frame_info(&ctx->frame_info[0]);
  for (int i = 0; i < ctx->frame_info_count; i++) {
    ctx->frame_info[i] = ctx->frame_info[i + 1];
  }
  ctx->frame_info[ctx->frame_info_count].mi_info = NULL;
}

void av1_init_thirdpass_ctx(AV1_COMMON *cm, THIRD_PASS_DEC_CTX **ctx,
                            const char *file) {
  av1_free_thirdpass_ctx(*ctx);
  CHECK_MEM_ERROR(cm, *ctx, aom_calloc(1, sizeof(**ctx)));
  THIRD_PASS_DEC_CTX *ctx_ptr = *ctx;
  ctx_ptr->input_file_name = file;
  ctx_ptr->prev_gop_end = -1;
  ctx_ptr->err_info = cm->error;
}

void av1_free_thirdpass_ctx(THIRD_PASS_DEC_CTX *ctx) {
  if (ctx == NULL) return;
  if (ctx->decoder.iface) {
    aom_codec_destroy(&ctx->decoder);
  }
  if (ctx->input_ctx && ctx->input_ctx->file) fclose(ctx->input_ctx->file);
  aom_free(ctx->input_ctx);
  if (ctx->buf) free(ctx->buf);
  for (int i = 0; i < MAX_THIRD_PASS_BUF; i++) {
    free_frame_info(&ctx->frame_info[i]);
  }
  aom_free(ctx);
}

void av1_write_second_pass_gop_info(AV1_COMP *cpi) {
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
  const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
  const PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;

  if (oxcf->pass == AOM_RC_SECOND_PASS && oxcf->second_pass_log) {
    // Write the GOP length to a log file.
    av1_open_second_pass_log(cpi, 0);

    THIRD_PASS_GOP_INFO gop_info;

    gop_info.num_frames = gf_group->size;
    gop_info.use_arf = (gf_group->arf_index >= 0);
    gop_info.gf_length = p_rc->baseline_gf_interval;

    size_t count =
        fwrite(&gop_info, sizeof(gop_info), 1, cpi->second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
                         "Could not write to second pass log file!");
    }
  }
}

void av1_write_second_pass_per_frame_info(AV1_COMP *cpi, int gf_index) {
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
  const GF_GROUP *const gf_group = &cpi->ppi->gf_group;

  if (oxcf->pass == AOM_RC_SECOND_PASS && oxcf->second_pass_log) {
    // write target bitrate
    int bits = gf_group->bit_allocation[gf_index];
    size_t count = fwrite(&bits, sizeof(bits), 1, cpi->second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
                         "Could not write to second pass log file!");
    }

    // write sse
    uint64_t sse = 0;
    int pkt_idx = cpi->ppi->output_pkt_list->cnt - 1;
    if (pkt_idx >= 0 &&
        cpi->ppi->output_pkt_list->pkts[pkt_idx].kind == AOM_CODEC_PSNR_PKT) {
      sse = cpi->ppi->output_pkt_list->pkts[pkt_idx].data.psnr.sse[0];
#if CONFIG_INTERNAL_STATS
    } else if (cpi->ppi->b_calculate_psnr) {
      sse = cpi->ppi->total_sq_error[0];
#endif
    } else {
      const YV12_BUFFER_CONFIG *orig = cpi->source;
      const YV12_BUFFER_CONFIG *recon = &cpi->common.cur_frame->buf;
      PSNR_STATS psnr;
#if CONFIG_AV1_HIGHBITDEPTH
      const uint32_t in_bit_depth = cpi->oxcf.input_cfg.input_bit_depth;
      const uint32_t bit_depth = cpi->td.mb.e_mbd.bd;
      aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
#else
      aom_calc_psnr(orig, recon, &psnr);
#endif
      sse = psnr.sse[0];
    }

    count = fwrite(&sse, sizeof(sse), 1, cpi->second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
                         "Could not write to second pass log file!");
    }

    // write bpm_factor
    double factor = cpi->ppi->twopass.bpm_factor;
    count = fwrite(&factor, sizeof(factor), 1, cpi->second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
                         "Could not write to second pass log file!");
    }
  }
}
void av1_open_second_pass_log(AV1_COMP *cpi, int is_read) {
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
  if (oxcf->second_pass_log == NULL) {
    aom_internal_error(cpi->common.error, AOM_CODEC_INVALID_PARAM,
                       "No second pass log file specified for the third pass!");
  }
  // Read the GOP length from a file.
  if (!cpi->second_pass_log_stream) {
    if (is_read) {
      cpi->second_pass_log_stream = fopen(cpi->oxcf.second_pass_log, "rb");
    } else {
      cpi->second_pass_log_stream = fopen(cpi->oxcf.second_pass_log, "wb");
    }
    if (!cpi->second_pass_log_stream) {
      aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
                         "Could not open second pass log file!");
    }
  }
}

void av1_close_second_pass_log(AV1_COMP *cpi) {
  if (cpi->second_pass_log_stream) {
    int ret = fclose(cpi->second_pass_log_stream);
    if (ret != 0) {
      aom_internal_error(cpi->common.error, AOM_CODEC_ERROR,
                         "Could not close second pass log file!");
    }
    cpi->second_pass_log_stream = 0;
  }
}

void av1_read_second_pass_gop_info(FILE *second_pass_log_stream,
                                   THIRD_PASS_GOP_INFO *gop_info,
                                   struct aom_internal_error_info *error) {
  size_t count = fread(gop_info, sizeof(*gop_info), 1, second_pass_log_stream);
  if (count < 1) {
    aom_internal_error(error, AOM_CODEC_ERROR,
                       "Could not read from second pass log file!");
  }
}

void av1_read_second_pass_per_frame_info(
    FILE *second_pass_log_stream, THIRD_PASS_FRAME_INFO *frame_info_arr,
    int frame_info_count, struct aom_internal_error_info *error) {
  for (int i = 0; i < frame_info_count; i++) {
    // read target bits
    int bits = 0;
    size_t count = fread(&bits, sizeof(bits), 1, second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(error, AOM_CODEC_ERROR,
                         "Could not read from second pass log file!");
    }
    frame_info_arr[i].bits_allocated = bits;

    // read distortion
    uint64_t sse;
    count = fread(&sse, sizeof(sse), 1, second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(error, AOM_CODEC_ERROR,
                         "Could not read from second pass log file!");
    }
    frame_info_arr[i].sse = sse;

    // read bpm factor
    double factor;
    count = fread(&factor, sizeof(factor), 1, second_pass_log_stream);
    if (count < 1) {
      aom_internal_error(error, AOM_CODEC_ERROR,
                         "Could not read from second pass log file!");
    }
    frame_info_arr[i].bpm_factor = factor;
  }
}

int av1_check_use_arf(THIRD_PASS_DEC_CTX *ctx) {
  if (ctx == NULL) return -1;
  int use_arf = 0;
  for (int i = 0; i < ctx->gop_info.gf_length; i++) {
    if (ctx->frame_info[i].order_hint != 0 &&
        ctx->frame_info[i].is_show_frame == 0) {
      use_arf = 1;
    }
  }
  if (use_arf != ctx->gop_info.use_arf) {
    aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                       "Mismatch in third pass GOP length!");
  }
  return use_arf;
}

void av1_get_third_pass_ratio(THIRD_PASS_DEC_CTX *ctx, int fidx, int fheight,
                              int fwidth, double *ratio_h, double *ratio_w) {
  assert(ctx);
  assert(fidx < ctx->frame_info_count);
  const int fheight_second_pass = ctx->frame_info[fidx].height;
  const int fwidth_second_pass = ctx->frame_info[fidx].width;
  assert(fheight_second_pass <= fheight && fwidth_second_pass <= fwidth);

  *ratio_h = (double)fheight / fheight_second_pass;
  *ratio_w = (double)fwidth / fwidth_second_pass;
}

THIRD_PASS_MI_INFO *av1_get_third_pass_mi(THIRD_PASS_DEC_CTX *ctx, int fidx,
                                          int mi_row, int mi_col,
                                          double ratio_h, double ratio_w) {
  assert(ctx);
  assert(fidx < ctx->frame_info_count);

  const int mi_rows_second_pass = ctx->frame_info[fidx].mi_rows;
  const int mi_cols_second_pass = ctx->frame_info[fidx].mi_cols;

  const int mi_row_second_pass =
      clamp((int)round(mi_row / ratio_h), 0, mi_rows_second_pass - 1);
  const int mi_col_second_pass =
      clamp((int)round(mi_col / ratio_w), 0, mi_cols_second_pass - 1);

  const int mi_stride_second_pass = ctx->frame_info[fidx].mi_stride;
  THIRD_PASS_MI_INFO *this_mi = ctx->frame_info[fidx].mi_info +
                                mi_row_second_pass * mi_stride_second_pass +
                                mi_col_second_pass;
  return this_mi;
}

void av1_third_pass_get_adjusted_mi(THIRD_PASS_MI_INFO *third_pass_mi,
                                    double ratio_h, double ratio_w, int *mi_row,
                                    int *mi_col) {
  *mi_row = (int)round(third_pass_mi->mi_row_start * ratio_h);
  *mi_col = (int)round(third_pass_mi->mi_col_start * ratio_w);
}

int_mv av1_get_third_pass_adjusted_mv(THIRD_PASS_MI_INFO *this_mi,
                                      double ratio_h, double ratio_w,
                                      MV_REFERENCE_FRAME frame) {
  assert(this_mi != NULL);
  int_mv cur_mv;
  cur_mv.as_int = INVALID_MV;

  if (frame < LAST_FRAME || frame > ALTREF_FRAME) return cur_mv;

  for (int r = 0; r < 2; r++) {
    if (this_mi->ref_frame[r] == frame) {
      cur_mv.as_mv.row = (int16_t)round(this_mi->mv[r].as_mv.row * ratio_h);
      cur_mv.as_mv.col = (int16_t)round(this_mi->mv[r].as_mv.col * ratio_w);
    }
  }

  return cur_mv;
}

BLOCK_SIZE av1_get_third_pass_adjusted_blk_size(THIRD_PASS_MI_INFO *this_mi,
                                                double ratio_h,
                                                double ratio_w) {
  assert(this_mi != NULL);
  BLOCK_SIZE bsize = BLOCK_INVALID;

  const BLOCK_SIZE bsize_second_pass = this_mi->bsize;
  assert(bsize_second_pass != BLOCK_INVALID);

  const int w_second_pass = block_size_wide[bsize_second_pass];
  const int h_second_pass = block_size_high[bsize_second_pass];

  int part_type;

  if (w_second_pass == h_second_pass) {
    part_type = PARTITION_NONE;
  } else if (w_second_pass / h_second_pass == 2) {
    part_type = PARTITION_HORZ;
  } else if (w_second_pass / h_second_pass == 4) {
    part_type = PARTITION_HORZ_4;
  } else if (h_second_pass / w_second_pass == 2) {
    part_type = PARTITION_VERT;
  } else if (h_second_pass / w_second_pass == 4) {
    part_type = PARTITION_VERT_4;
  } else {
    part_type = PARTITION_INVALID;
  }
  assert(part_type != PARTITION_INVALID);

  const int w = (int)(round(w_second_pass * ratio_w));
  const int h = (int)(round(h_second_pass * ratio_h));

  for (int i = 0; i < SQR_BLOCK_SIZES; i++) {
    const BLOCK_SIZE this_bsize = subsize_lookup[part_type][i];
    if (this_bsize == BLOCK_INVALID) continue;

    const int this_w = block_size_wide[this_bsize];
    const int this_h = block_size_high[this_bsize];

    if (this_w >= w && this_h >= h) {
      // find the smallest block size that contains the mapped block
      bsize = this_bsize;
      break;
    }
  }
  if (bsize == BLOCK_INVALID) {
    // could not find a proper one, just use the largest then.
    bsize = BLOCK_128X128;
  }

  return bsize;
}

PARTITION_TYPE av1_third_pass_get_sb_part_type(THIRD_PASS_DEC_CTX *ctx,
                                               THIRD_PASS_MI_INFO *this_mi) {
  int mi_stride = ctx->frame_info[0].mi_stride;

  int mi_row = this_mi->mi_row_start;
  int mi_col = this_mi->mi_col_start;

  THIRD_PASS_MI_INFO *corner_mi =
      &ctx->frame_info[0].mi_info[mi_row * mi_stride + mi_col];

  return corner_mi->partition;
}

#else   // !(CONFIG_THREE_PASS && CONFIG_AV1_DECODER)
void av1_init_thirdpass_ctx(AV1_COMMON *cm, THIRD_PASS_DEC_CTX **ctx,
                            const char *file) {
  (void)ctx;
  (void)file;
  aom_internal_error(cm->error, AOM_CODEC_ERROR,
                     "To utilize three-pass encoding, libaom must be built "
                     "with CONFIG_THREE_PASS=1 & CONFIG_AV1_DECODER=1.");
}

void av1_free_thirdpass_ctx(THIRD_PASS_DEC_CTX *ctx) { (void)ctx; }

void av1_set_gop_third_pass(THIRD_PASS_DEC_CTX *ctx) { (void)ctx; }

void av1_pop_third_pass_info(THIRD_PASS_DEC_CTX *ctx) { (void)ctx; }

void av1_open_second_pass_log(struct AV1_COMP *cpi, int is_read) {
  (void)cpi;
  (void)is_read;
}

void av1_close_second_pass_log(struct AV1_COMP *cpi) { (void)cpi; }

void av1_write_second_pass_gop_info(struct AV1_COMP *cpi) { (void)cpi; }

void av1_write_second_pass_per_frame_info(struct AV1_COMP *cpi, int gf_index) {
  (void)cpi;
  (void)gf_index;
}

void av1_read_second_pass_gop_info(FILE *second_pass_log_stream,
                                   THIRD_PASS_GOP_INFO *gop_info,
                                   struct aom_internal_error_info *error) {
  (void)second_pass_log_stream;
  (void)gop_info;
  (void)error;
}

void av1_read_second_pass_per_frame_info(
    FILE *second_pass_log_stream, THIRD_PASS_FRAME_INFO *frame_info_arr,
    int frame_info_count, struct aom_internal_error_info *error) {
  (void)second_pass_log_stream;
  (void)frame_info_arr;
  (void)frame_info_count;
  (void)error;
}

int av1_check_use_arf(THIRD_PASS_DEC_CTX *ctx) {
  (void)ctx;
  return 1;
}

void av1_get_third_pass_ratio(THIRD_PASS_DEC_CTX *ctx, int fidx, int fheight,
                              int fwidth, double *ratio_h, double *ratio_w) {
  (void)ctx;
  (void)fidx;
  (void)fheight;
  (void)fwidth;
  (void)ratio_h;
  (void)ratio_w;
}

THIRD_PASS_MI_INFO *av1_get_third_pass_mi(THIRD_PASS_DEC_CTX *ctx, int fidx,
                                          int mi_row, int mi_col,
                                          double ratio_h, double ratio_w) {
  (void)ctx;
  (void)fidx;
  (void)mi_row;
  (void)mi_col;
  (void)ratio_h;
  (void)ratio_w;
  return NULL;
}

int_mv av1_get_third_pass_adjusted_mv(THIRD_PASS_MI_INFO *this_mi,
                                      double ratio_h, double ratio_w,
                                      MV_REFERENCE_FRAME frame) {
  (void)this_mi;
  (void)ratio_h;
  (void)ratio_w;
  (void)frame;
  int_mv mv;
  mv.as_int = INVALID_MV;
  return mv;
}

BLOCK_SIZE av1_get_third_pass_adjusted_blk_size(THIRD_PASS_MI_INFO *this_mi,
                                                double ratio_h,
                                                double ratio_w) {
  (void)this_mi;
  (void)ratio_h;
  (void)ratio_w;
  return BLOCK_INVALID;
}

void av1_third_pass_get_adjusted_mi(THIRD_PASS_MI_INFO *third_pass_mi,
                                    double ratio_h, double ratio_w, int *mi_row,
                                    int *mi_col) {
  (void)third_pass_mi;
  (void)ratio_h;
  (void)ratio_w;
  (void)mi_row;
  (void)mi_col;
}

PARTITION_TYPE av1_third_pass_get_sb_part_type(THIRD_PASS_DEC_CTX *ctx,
                                               THIRD_PASS_MI_INFO *this_mi) {
  (void)ctx;
  (void)this_mi;
  return PARTITION_INVALID;
}
#endif  // CONFIG_THREE_PASS && CONFIG_AV1_DECODER

#if CONFIG_BITRATE_ACCURACY
static void fwrite_and_check(const void *ptr, size_t size, size_t nmemb,
                             FILE *stream,
                             struct aom_internal_error_info *error) {
  size_t count = fwrite(ptr, size, nmemb, stream);
  if (count < nmemb) {
    aom_internal_error(error, AOM_CODEC_ERROR, "fwrite_and_check failed\n");
  }
}

static void fread_and_check(void *ptr, size_t size, size_t nmemb, FILE *stream,
                            struct aom_internal_error_info *error) {
  size_t count = fread(ptr, size, nmemb, stream);
  if (count < nmemb) {
    aom_internal_error(error, AOM_CODEC_ERROR, "fread_and_check failed\n");
  }
}

void av1_pack_tpl_info(TPL_INFO *tpl_info, const GF_GROUP *gf_group,
                       const TplParams *tpl_data) {
  tpl_info->tpl_ready = tpl_data->ready;
  if (tpl_info->tpl_ready) {
    tpl_info->gf_length = gf_group->size;
    for (int i = 0; i < tpl_info->gf_length; ++i) {
      tpl_info->txfm_stats_list[i] = tpl_data->txfm_stats_list[i];
      tpl_info->qstep_ratio_ls[i] = av1_tpl_get_qstep_ratio(tpl_data, i);
      tpl_info->update_type_list[i] = gf_group->update_type[i];
    }
  }
}

void av1_write_tpl_info(const TPL_INFO *tpl_info, FILE *log_stream,
                        struct aom_internal_error_info *error) {
  fwrite_and_check(&tpl_info->tpl_ready, sizeof(tpl_info->tpl_ready), 1,
                   log_stream, error);
  if (tpl_info->tpl_ready) {
    fwrite_and_check(&tpl_info->gf_length, sizeof(tpl_info->gf_length), 1,
                     log_stream, error);
    assert(tpl_info->gf_length <= MAX_LENGTH_TPL_FRAME_STATS);
    fwrite_and_check(&tpl_info->txfm_stats_list,
                     sizeof(tpl_info->txfm_stats_list[0]), tpl_info->gf_length,
                     log_stream, error);
    fwrite_and_check(&tpl_info->qstep_ratio_ls,
                     sizeof(tpl_info->qstep_ratio_ls[0]), tpl_info->gf_length,
                     log_stream, error);
    fwrite_and_check(&tpl_info->update_type_list,
                     sizeof(tpl_info->update_type_list[0]), tpl_info->gf_length,
                     log_stream, error);
  }
}

void av1_read_tpl_info(TPL_INFO *tpl_info, FILE *log_stream,
                       struct aom_internal_error_info *error) {
  av1_zero(*tpl_info);
  fread_and_check(&tpl_info->tpl_ready, sizeof(tpl_info->tpl_ready), 1,
                  log_stream, error);
  if (tpl_info->tpl_ready) {
    fread_and_check(&tpl_info->gf_length, sizeof(tpl_info->gf_length), 1,
                    log_stream, error);
    assert(tpl_info->gf_length <= MAX_LENGTH_TPL_FRAME_STATS);
    fread_and_check(&tpl_info->txfm_stats_list,
                    sizeof(tpl_info->txfm_stats_list[0]), tpl_info->gf_length,
                    log_stream, error);
    fread_and_check(&tpl_info->qstep_ratio_ls,
                    sizeof(tpl_info->qstep_ratio_ls[0]), tpl_info->gf_length,
                    log_stream, error);
    fread_and_check(&tpl_info->update_type_list,
                    sizeof(tpl_info->update_type_list[0]), tpl_info->gf_length,
                    log_stream, error);
  }
}
#endif  // CONFIG_BITRATE_ACCURACY
