/*
 * 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 "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/encoder/thirdpass.h"
#include "av1/common/blockd.h"

#if CONFIG_THREE_PASS
#include "common/ivfdec.h"
#endif

#if CONFIG_THREE_PASS
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 CONFIG_AV1_DECODER
  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.");
    }
  }
#else
  aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                     "To utilize three-pass encoding, libaom must be built "
                     "with CONFIG_AV1_DECODER=1.");
#endif
}
#endif  // CONFIG_THREE_PASS

// 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 CONFIG_THREE_PASS
  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;
  }
#else
  aom_internal_error(ctx->err_info, AOM_CODEC_ERROR,
                     "Cannot parse bitstream without CONFIG_THREE_PASS.");
#endif
  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 CONFIG_THREE_PASS
  if (ctx->input_ctx && ctx->input_ctx->file) fclose(ctx->input_ctx->file);
  aom_free(ctx->input_ctx);
#endif
  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;
}
