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

#ifndef AOM_AV1_ENCODER_RDOPT_H_
#define AOM_AV1_ENCODER_RDOPT_H_

#include <stdbool.h>

#include "av1/common/blockd.h"
#include "av1/common/txb_common.h"

#include "av1/encoder/block.h"
#include "av1/encoder/context_tree.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/encodetxb.h"

#ifdef __cplusplus
extern "C" {
#endif

#define MAX_REF_MV_SEARCH 3
#define INTER_INTRA_RD_THRESH_SCALE 9
#define INTER_INTRA_RD_THRESH_SHIFT 4
#define COMP_TYPE_RD_THRESH_SCALE 11
#define COMP_TYPE_RD_THRESH_SHIFT 4
#define MAX_WINNER_MOTION_MODES 10

struct TileInfo;
struct macroblock;
struct RD_STATS;

#if CONFIG_RD_DEBUG
static INLINE void av1_update_txb_coeff_cost(RD_STATS *rd_stats, int plane,
                                             TX_SIZE tx_size, int blk_row,
                                             int blk_col, int txb_coeff_cost) {
  (void)blk_row;
  (void)blk_col;
  (void)tx_size;
  rd_stats->txb_coeff_cost[plane] += txb_coeff_cost;

  {
    const int txb_h = tx_size_high_unit[tx_size];
    const int txb_w = tx_size_wide_unit[tx_size];
    int idx, idy;
    for (idy = 0; idy < txb_h; ++idy)
      for (idx = 0; idx < txb_w; ++idx)
        rd_stats->txb_coeff_cost_map[plane][blk_row + idy][blk_col + idx] = 0;

    rd_stats->txb_coeff_cost_map[plane][blk_row][blk_col] = txb_coeff_cost;
  }
  assert(blk_row < TXB_COEFF_COST_MAP_SIZE);
  assert(blk_col < TXB_COEFF_COST_MAP_SIZE);
}
#endif

// Returns the number of colors in 'src'.
int av1_count_colors(const uint8_t *src, int stride, int rows, int cols,
                     int *val_count);
// Same as av1_count_colors(), but for high-bitdepth mode.
int av1_count_colors_highbd(const uint8_t *src8, int stride, int rows, int cols,
                            int bit_depth, int *val_count);

#if CONFIG_DIST_8X8
int64_t av1_dist_8x8(const struct AV1_COMP *const cpi, const MACROBLOCK *x,
                     const uint8_t *src, int src_stride, const uint8_t *dst,
                     int dst_stride, const BLOCK_SIZE tx_bsize, int bsw,
                     int bsh, int visible_w, int visible_h, int qindex);
#endif

static INLINE int av1_cost_skip_txb(MACROBLOCK *x, const TXB_CTX *const txb_ctx,
                                    int plane, TX_SIZE tx_size) {
  const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
  const PLANE_TYPE plane_type = get_plane_type(plane);
  const LV_MAP_COEFF_COST *const coeff_costs =
      &x->coeff_costs[txs_ctx][plane_type];
  return coeff_costs->txb_skip_cost[txb_ctx->txb_skip_ctx][1];
}

static INLINE int av1_cost_coeffs(MACROBLOCK *x, int plane, int block,
                                  TX_SIZE tx_size, const TX_TYPE tx_type,
                                  const TXB_CTX *const txb_ctx,
                                  int use_fast_coef_costing,
                                  int reduced_tx_set_used) {
#if TXCOEFF_COST_TIMER
  struct aom_usec_timer timer;
  aom_usec_timer_start(&timer);
#endif
  (void)use_fast_coef_costing;
  const int cost = av1_cost_coeffs_txb(x, plane, block, tx_size, tx_type,
                                       txb_ctx, reduced_tx_set_used);
#if TXCOEFF_COST_TIMER
  AV1_COMMON *tmp_cm = (AV1_COMMON *)&cpi->common;
  aom_usec_timer_mark(&timer);
  const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
  tmp_cm->txcoeff_cost_timer += elapsed_time;
  ++tmp_cm->txcoeff_cost_count;
#endif
  return cost;
}

void av1_rd_pick_intra_mode_sb(const struct AV1_COMP *cpi, struct macroblock *x,
                               struct RD_STATS *rd_cost, BLOCK_SIZE bsize,
                               PICK_MODE_CONTEXT *ctx, int64_t best_rd);

unsigned int av1_get_sby_perpixel_variance(const struct AV1_COMP *cpi,
                                           const struct buf_2d *ref,
                                           BLOCK_SIZE bs);
unsigned int av1_high_get_sby_perpixel_variance(const struct AV1_COMP *cpi,
                                                const struct buf_2d *ref,
                                                BLOCK_SIZE bs, int bd);

void av1_rd_pick_inter_mode_sb(struct AV1_COMP *cpi,
                               struct TileDataEnc *tile_data,
                               struct macroblock *x, struct RD_STATS *rd_cost,
                               BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                               int64_t best_rd_so_far);

void av1_nonrd_pick_inter_mode_sb(struct AV1_COMP *cpi,
                                  struct TileDataEnc *tile_data,
                                  struct macroblock *x,
                                  struct RD_STATS *rd_cost, BLOCK_SIZE bsize,
                                  PICK_MODE_CONTEXT *ctx,
                                  int64_t best_rd_so_far);

void av1_rd_pick_inter_mode_sb_seg_skip(
    const struct AV1_COMP *cpi, struct TileDataEnc *tile_data,
    struct macroblock *x, int mi_row, int mi_col, struct RD_STATS *rd_cost,
    BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd_so_far);

// The best edge strength seen in the block, as well as the best x and y
// components of edge strength seen.
typedef struct {
  uint16_t magnitude;
  uint16_t x;
  uint16_t y;
} EdgeInfo;

/** Returns an integer indicating the strength of the edge.
 * 0 means no edge found, 556 is the strength of a solid black/white edge,
 * and the number may range higher if the signal is even stronger (e.g., on a
 * corner). high_bd is a bool indicating the source should be treated
 * as a 16-bit array. bd is the bit depth.
 */
EdgeInfo av1_edge_exists(const uint8_t *src, int src_stride, int w, int h,
                         bool high_bd, int bd);

/** Applies a Gaussian blur with sigma = 1.3. Used by av1_edge_exists and
 * tests.
 */
void av1_gaussian_blur(const uint8_t *src, int src_stride, int w, int h,
                       uint8_t *dst, bool high_bd, int bd);

/* Applies standard 3x3 Sobel matrix. */
typedef struct {
  int16_t x;
  int16_t y;
} sobel_xy;

sobel_xy av1_sobel(const uint8_t *input, int stride, int i, int j,
                   bool high_bd);

void av1_inter_mode_data_init(struct TileDataEnc *tile_data);
void av1_inter_mode_data_fit(TileDataEnc *tile_data, int rdmult);

typedef int64_t (*pick_interinter_mask_type)(
    const AV1_COMP *const cpi, MACROBLOCK *x, const BLOCK_SIZE bsize,
    const uint8_t *const p0, const uint8_t *const p1,
    const int16_t *const residual1, const int16_t *const diff10);

static INLINE int av1_encoder_get_relative_dist(const OrderHintInfo *oh, int a,
                                                int b) {
  if (!oh->enable_order_hint) return 0;

  assert(a >= 0 && b >= 0);
  return (a - b);
}

// This function will return number of mi's in a superblock.
static INLINE int av1_get_sb_mi_size(const AV1_COMMON *const cm) {
  const int mi_alloc_size_1d = mi_size_wide[cm->mi_alloc_bsize];
  int sb_mi_rows =
      (mi_size_wide[cm->seq_params.sb_size] + mi_alloc_size_1d - 1) /
      mi_alloc_size_1d;
  assert(mi_size_wide[cm->seq_params.sb_size] ==
         mi_size_high[cm->seq_params.sb_size]);
  int sb_mi_size = sb_mi_rows * sb_mi_rows;

  return sb_mi_size;
}

// This function will copy usable ref_mv_stack[ref_frame][4] and
// weight[ref_frame][4] information from ref_mv_stack[ref_frame][8] and
// weight[ref_frame][8].
static INLINE void av1_copy_usable_ref_mv_stack_and_weight(
    const MACROBLOCKD *xd, MB_MODE_INFO_EXT *const mbmi_ext,
    MV_REFERENCE_FRAME ref_frame) {
  memcpy(mbmi_ext->weight[ref_frame], xd->weight[ref_frame],
         USABLE_REF_MV_STACK_SIZE * sizeof(xd->weight[0][0]));
  memcpy(mbmi_ext->ref_mv_stack[ref_frame], xd->ref_mv_stack[ref_frame],
         USABLE_REF_MV_STACK_SIZE * sizeof(xd->ref_mv_stack[0][0]));
}

static TX_MODE select_tx_mode(
    const AV1_COMP *cpi, const TX_SIZE_SEARCH_METHOD tx_size_search_method) {
  if (cpi->common.coded_lossless) return ONLY_4X4;
  if (tx_size_search_method == USE_LARGESTALL) {
    return TX_MODE_LARGEST;
  } else {
    assert(tx_size_search_method == USE_FULL_RD ||
           tx_size_search_method == USE_FAST_RD);
    return TX_MODE_SELECT;
  }
}

static INLINE void set_tx_size_search_method(
    const struct AV1_COMP *cpi, MACROBLOCK *x,
    int enable_winner_mode_for_tx_size_srch, int is_winner_mode) {
  // Populate transform size search method/transform mode appropriately
  x->tx_size_search_method = cpi->tx_size_search_methods[DEFAULT_EVAL];
  if (enable_winner_mode_for_tx_size_srch) {
    if (is_winner_mode)
      x->tx_size_search_method = cpi->tx_size_search_methods[WINNER_MODE_EVAL];
    else
      x->tx_size_search_method = cpi->tx_size_search_methods[MODE_EVAL];
  }
  x->tx_mode_search_type = select_tx_mode(cpi, x->tx_size_search_method);
}

static INLINE void set_tx_type_prune(const SPEED_FEATURES *sf, MACROBLOCK *x,
                                     int enable_winner_mode_tx_type_pruning,
                                     int is_winner_mode) {
  // Populate prune transform mode appropriately
  x->prune_mode = sf->tx_type_search.prune_mode;
  if (enable_winner_mode_tx_type_pruning) {
    if (is_winner_mode)
      x->prune_mode = NO_PRUNE;
    else
      x->prune_mode = PRUNE_2D_AGGRESSIVE;
  }
}

static INLINE void set_tx_domain_dist_params(
    const struct AV1_COMP *cpi, MACROBLOCK *x,
    int enable_winner_mode_for_tx_domain_dist, int is_winner_mode) {
  if (!enable_winner_mode_for_tx_domain_dist) {
    x->use_transform_domain_distortion =
        cpi->use_transform_domain_distortion[DEFAULT_EVAL];
    x->tx_domain_dist_threshold = cpi->tx_domain_dist_threshold[DEFAULT_EVAL];
    return;
  }

  if (is_winner_mode) {
    x->use_transform_domain_distortion =
        cpi->use_transform_domain_distortion[WINNER_MODE_EVAL];
    x->tx_domain_dist_threshold =
        cpi->tx_domain_dist_threshold[WINNER_MODE_EVAL];
  } else {
    x->use_transform_domain_distortion =
        cpi->use_transform_domain_distortion[MODE_EVAL];
    x->tx_domain_dist_threshold = cpi->tx_domain_dist_threshold[MODE_EVAL];
  }
}

// Checks the conditions to enable winner mode processing
static INLINE int is_winner_mode_processing_enabled(
    const struct AV1_COMP *cpi, MB_MODE_INFO *const mbmi,
    const PREDICTION_MODE best_mode) {
  const SPEED_FEATURES *sf = &cpi->sf;

  // TODO(any): Move block independent condition checks to frame level
  if (is_inter_block(mbmi)) {
    if (is_inter_mode(best_mode) &&
        sf->tx_type_search.fast_inter_tx_type_search &&
        !cpi->oxcf.use_inter_dct_only)
      return 1;
  } else {
    if (sf->tx_type_search.fast_intra_tx_type_search &&
        !cpi->oxcf.use_intra_default_tx_only && !cpi->oxcf.use_intra_dct_only)
      return 1;
  }

  // Check speed feature related to winner mode processing
  if (sf->enable_winner_mode_for_coeff_opt &&
      cpi->optimize_seg_arr[mbmi->segment_id] != NO_TRELLIS_OPT &&
      cpi->optimize_seg_arr[mbmi->segment_id] != FINAL_PASS_TRELLIS_OPT)
    return 1;
  if (sf->enable_winner_mode_for_tx_size_srch) return 1;

  return 0;
}

// This function sets mode parameters for different mode evaluation stages
static INLINE void set_mode_eval_params(const struct AV1_COMP *cpi,
                                        MACROBLOCK *x,
                                        MODE_EVAL_TYPE mode_eval_type) {
  const SPEED_FEATURES *sf = &cpi->sf;

  switch (mode_eval_type) {
    case DEFAULT_EVAL:
      x->use_default_inter_tx_type = 0;
      x->use_default_intra_tx_type = 0;
      x->predict_skip_level = cpi->predict_skip_level[DEFAULT_EVAL];
      // Set default transform domain distortion type
      set_tx_domain_dist_params(cpi, x, 0, 0);

      // Get default threshold for R-D optimization of coefficients
      x->coeff_opt_dist_threshold =
          get_rd_opt_coeff_thresh(cpi->coeff_opt_dist_threshold, 0, 0);
      // Set default transform size search method
      set_tx_size_search_method(cpi, x, 0, 0);
      // Set default transform type prune
      set_tx_type_prune(sf, x, 0, 0);
      break;
    case MODE_EVAL:
      x->use_default_intra_tx_type =
          (cpi->sf.tx_type_search.fast_intra_tx_type_search ||
           cpi->oxcf.use_intra_default_tx_only);
      x->use_default_inter_tx_type =
          cpi->sf.tx_type_search.fast_inter_tx_type_search;
      x->predict_skip_level = cpi->predict_skip_level[MODE_EVAL];

      // Set transform domain distortion type for mode evaluation
      set_tx_domain_dist_params(
          cpi, x, sf->enable_winner_mode_for_use_tx_domain_dist, 0);

      // Get threshold for R-D optimization of coefficients during mode
      // evaluation
      x->coeff_opt_dist_threshold =
          get_rd_opt_coeff_thresh(cpi->coeff_opt_dist_threshold,
                                  sf->enable_winner_mode_for_coeff_opt, 0);
      // Set the transform size search method for mode evaluation
      set_tx_size_search_method(cpi, x, sf->enable_winner_mode_for_tx_size_srch,
                                0);
      // Set transform type prune for mode evaluation
      set_tx_type_prune(
          sf, x, sf->tx_type_search.enable_winner_mode_tx_type_pruning, 0);
      break;
    case WINNER_MODE_EVAL:
      x->use_default_inter_tx_type = 0;
      x->use_default_intra_tx_type = 0;
      x->predict_skip_level = cpi->predict_skip_level[WINNER_MODE_EVAL];

      // Set transform domain distortion type for winner mode evaluation
      set_tx_domain_dist_params(
          cpi, x, sf->enable_winner_mode_for_use_tx_domain_dist, 1);

      // Get threshold for R-D optimization of coefficients for winner mode
      // evaluation
      x->coeff_opt_dist_threshold =
          get_rd_opt_coeff_thresh(cpi->coeff_opt_dist_threshold,
                                  sf->enable_winner_mode_for_coeff_opt, 1);
      // Set the transform size search method for winner mode evaluation
      set_tx_size_search_method(cpi, x, sf->enable_winner_mode_for_tx_size_srch,
                                1);
      // Set default transform type prune mode for winner mode evaluation
      set_tx_type_prune(
          sf, x, sf->tx_type_search.enable_winner_mode_tx_type_pruning, 1);

      // Reset hash state for winner mode processing. Winner mode and subsequent
      // transform/mode evaluations (palette/IntraBC) cann't reuse old data as
      // the decisions would have been sub-optimal
      // TODO(any): Move the evaluation of palette/IntraBC modes before winner
      // mode is processed and clean-up the code below
      reset_hash_records(x, cpi->sf.use_inter_txb_hash);

      break;
    default: assert(0);
  }
}

static INLINE int prune_ref_by_selective_ref_frame(
    const AV1_COMP *const cpi, const MV_REFERENCE_FRAME *const ref_frame,
    const unsigned int *const ref_display_order_hint,
    const unsigned int cur_frame_display_order_hint) {
  const SPEED_FEATURES *const sf = &cpi->sf;
  if (sf->selective_ref_frame) {
    const AV1_COMMON *const cm = &cpi->common;
    const OrderHintInfo *const order_hint_info =
        &cm->seq_params.order_hint_info;
    const int comp_pred = ref_frame[1] > INTRA_FRAME;
    if (sf->selective_ref_frame >= 2 ||
        (sf->selective_ref_frame == 1 && comp_pred)) {
      if (ref_frame[0] == LAST3_FRAME || ref_frame[1] == LAST3_FRAME) {
        if (av1_encoder_get_relative_dist(
                order_hint_info,
                ref_display_order_hint[LAST3_FRAME - LAST_FRAME],
                ref_display_order_hint[GOLDEN_FRAME - LAST_FRAME]) <= 0)
          return 1;
      }
      if (ref_frame[0] == LAST2_FRAME || ref_frame[1] == LAST2_FRAME) {
        if (av1_encoder_get_relative_dist(
                order_hint_info,
                ref_display_order_hint[LAST2_FRAME - LAST_FRAME],
                ref_display_order_hint[GOLDEN_FRAME - LAST_FRAME]) <= 0)
          return 1;
      }
    }

    // One-sided compound is used only when all reference frames are one-sided.
    if (sf->selective_ref_frame >= 2 && comp_pred && !cpi->all_one_sided_refs) {
      unsigned int ref_offsets[2];
      for (int i = 0; i < 2; ++i) {
        const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame[i]);
        assert(buf != NULL);
        ref_offsets[i] = buf->display_order_hint;
      }
      const int ref0_dist = av1_encoder_get_relative_dist(
          order_hint_info, ref_offsets[0], cur_frame_display_order_hint);
      const int ref1_dist = av1_encoder_get_relative_dist(
          order_hint_info, ref_offsets[1], cur_frame_display_order_hint);
      if ((ref0_dist <= 0 && ref1_dist <= 0) ||
          (ref0_dist > 0 && ref1_dist > 0)) {
        return 1;
      }
    }

    if (sf->selective_ref_frame >= 3) {
      if (ref_frame[0] == ALTREF2_FRAME || ref_frame[1] == ALTREF2_FRAME)
        if (av1_encoder_get_relative_dist(
                order_hint_info,
                ref_display_order_hint[ALTREF2_FRAME - LAST_FRAME],
                cur_frame_display_order_hint) < 0)
          return 1;
      if (ref_frame[0] == BWDREF_FRAME || ref_frame[1] == BWDREF_FRAME)
        if (av1_encoder_get_relative_dist(
                order_hint_info,
                ref_display_order_hint[BWDREF_FRAME - LAST_FRAME],
                cur_frame_display_order_hint) < 0)
          return 1;
    }

    if (sf->selective_ref_frame >= 4 && comp_pred) {
      // Check if one of the reference is ALTREF2_FRAME and BWDREF_FRAME is a
      // valid reference.
      if ((ref_frame[0] == ALTREF2_FRAME || ref_frame[1] == ALTREF2_FRAME) &&
          (cpi->ref_frame_flags & av1_ref_frame_flag_list[BWDREF_FRAME])) {
        // Check if both ALTREF2_FRAME and BWDREF_FRAME are future references.
        const int arf2_dist = av1_encoder_get_relative_dist(
            order_hint_info, ref_display_order_hint[ALTREF2_FRAME - LAST_FRAME],
            cur_frame_display_order_hint);
        const int bwd_dist = av1_encoder_get_relative_dist(
            order_hint_info, ref_display_order_hint[BWDREF_FRAME - LAST_FRAME],
            cur_frame_display_order_hint);
        if (arf2_dist > 0 && bwd_dist > 0 && bwd_dist <= arf2_dist) {
          // Drop ALTREF2_FRAME as a reference if BWDREF_FRAME is a closer
          // reference to the current frame than ALTREF2_FRAME
          assert(get_ref_frame_buf(cm, ALTREF2_FRAME) != NULL);
          assert(get_ref_frame_buf(cm, BWDREF_FRAME) != NULL);
          return 1;
        }
      }
    }
  }
  return 0;
}
#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // AOM_AV1_ENCODER_RDOPT_H_
