/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  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
 * aomedia.org/license/patent-license/.
 */

#include <limits.h>

#include "aom_mem/aom_mem.h"

#include "av1/common/pred_common.h"
#include "av1/common/tile_common.h"

#include "av1/common/cost.h"
#include "av1/encoder/segmentation.h"

void av1_enable_segmentation(struct segmentation *seg) {
  seg->enabled = 1;
  seg->update_map = 1;
  seg->update_data = 1;
  seg->temporal_update = 0;
}

void av1_disable_segmentation(struct segmentation *seg) {
  seg->enabled = 0;
  seg->update_map = 0;
  seg->update_data = 0;
  seg->temporal_update = 0;
}

void av1_disable_segfeature(struct segmentation *seg, int segment_id,
                            SEG_LVL_FEATURES feature_id) {
  seg->feature_mask[segment_id] &= ~(1 << feature_id);
}

void av1_clear_segdata(struct segmentation *seg, int segment_id,
                       SEG_LVL_FEATURES feature_id) {
  seg->feature_data[segment_id][feature_id] = 0;
}

static void count_segs(const AV1_COMMON *cm, MACROBLOCKD *xd,
                       const TileInfo *tile, MB_MODE_INFO **mi,
                       unsigned *no_pred_segcounts,
                       unsigned (*temporal_predictor_count)[2],
                       unsigned *t_unpred_seg_counts, int bw, int bh,
                       int mi_row, int mi_col) {
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;

  xd->mi = mi;
  assert(xd->mi && xd->mi[0]);
  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
                 mi_params->mi_cols, &xd->mi[0]->chroma_ref_info);

  // Count the number of hits on each segment with no prediction
  const int segment_id = xd->mi[0]->segment_id;
  no_pred_segcounts[segment_id]++;

  // Temporal prediction not allowed on key frames
  if (cm->current_frame.frame_type != KEY_FRAME &&
      xd->mi[0]->region_type != INTRA_REGION) {
    const BLOCK_SIZE bsize = xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART];
    // Test to see if the segment id matches the predicted value.
    const int pred_segment_id =
        cm->last_frame_seg_map
            ? get_segment_id(mi_params, cm->last_frame_seg_map, bsize, mi_row,
                             mi_col)
            : 0;
    const int pred_flag = pred_segment_id == segment_id;
    const int pred_context = av1_get_pred_context_seg_id(xd);

    // Store the prediction status for this mb and update counts
    // as appropriate
    xd->mi[0]->seg_id_predicted = pred_flag;
    temporal_predictor_count[pred_context][pred_flag]++;

    // Update the "unpredicted" segment count
    if (!pred_flag) t_unpred_seg_counts[segment_id]++;
  }
}

static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
                          const TileInfo *tile, MB_MODE_INFO **mi,
                          unsigned *no_pred_segcounts,
                          unsigned (*temporal_predictor_count)[2],
                          unsigned *t_unpred_seg_counts, int mi_row, int mi_col,
                          const PARTITION_TREE *ptree) {
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int mis = mi_params->mi_stride;
  BLOCK_SIZE bsize = ptree->bsize;
  const int bw = mi_size_wide[bsize], bh = mi_size_high[bsize];
  const int hbw = bw / 2, hbh = bh / 2;
  const int qbw = bw / 4, qbh = bh / 4;
  const int ebw = bw / 8, ebh = bh / 8;

  if (mi_row >= mi_params->mi_rows || mi_col >= mi_params->mi_cols) return;

#define CSEGS(cs_bw, cs_bh, cs_rowoff, cs_coloff)                              \
  count_segs(cm, xd, tile, mi + mis * (cs_rowoff) + (cs_coloff),               \
             no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts, \
             (cs_bw), (cs_bh), mi_row + (cs_rowoff), mi_col + (cs_coloff));
#define CSEGS_RECURSIVE(cs_rowoff, cs_coloff, subtree)              \
  count_segs_sb(cm, xd, tile, mi + mis * (cs_rowoff) + (cs_coloff), \
                no_pred_segcounts, temporal_predictor_count,        \
                t_unpred_seg_counts, mi_row + (cs_rowoff),          \
                mi_col + (cs_coloff), subtree);

  int tree_idx = 0;
  const PARTITION_TYPE partition = ptree->partition;
  switch (partition) {
    case PARTITION_NONE: CSEGS(bw, bh, 0, 0); break;
    case PARTITION_HORZ:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      CSEGS_RECURSIVE(hbh, 0, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_VERT:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      CSEGS_RECURSIVE(0, hbw, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_HORZ_3:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      CSEGS_RECURSIVE(qbh, 0, ptree->sub_tree[tree_idx++]);
      CSEGS_RECURSIVE(qbh, hbw, ptree->sub_tree[tree_idx++]);
      if (mi_row + 3 * qbh < mi_params->mi_rows)
        CSEGS_RECURSIVE(3 * qbh, 0, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_VERT_3:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      CSEGS_RECURSIVE(0, qbw, ptree->sub_tree[tree_idx++]);
      CSEGS_RECURSIVE(hbh, qbw, ptree->sub_tree[tree_idx++]);
      if (mi_col + 3 * qbw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, 3 * qbw, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_HORZ_4A:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      if (mi_row + ebh < mi_params->mi_rows)
        CSEGS_RECURSIVE(ebh, 0, ptree->sub_tree[tree_idx++]);
      if (mi_row + 3 * ebh < mi_params->mi_rows)
        CSEGS_RECURSIVE(3 * ebh, 0, ptree->sub_tree[tree_idx++]);
      if (mi_row + 7 * ebh < mi_params->mi_rows)
        CSEGS_RECURSIVE(7 * ebh, 0, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_HORZ_4B:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      if (mi_row + ebh < mi_params->mi_rows)
        CSEGS_RECURSIVE(ebh, 0, ptree->sub_tree[tree_idx++]);
      if (mi_row + 5 * ebh < mi_params->mi_rows)
        CSEGS_RECURSIVE(5 * ebh, 0, ptree->sub_tree[tree_idx++]);
      if (mi_row + 7 * ebh < mi_params->mi_rows)
        CSEGS_RECURSIVE(7 * ebh, 0, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_VERT_4A:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      if (mi_col + ebw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, ebw, ptree->sub_tree[tree_idx++]);
      if (mi_col + 3 * ebw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, 3 * ebw, ptree->sub_tree[tree_idx++]);
      if (mi_col + 7 * ebw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, 7 * ebw, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_VERT_4B:
      CSEGS_RECURSIVE(0, 0, ptree->sub_tree[tree_idx++]);
      if (mi_col + ebw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, ebw, ptree->sub_tree[tree_idx++]);
      if (mi_col + 5 * ebw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, 5 * ebw, ptree->sub_tree[tree_idx++]);
      if (mi_col + 7 * ebw < mi_params->mi_cols)
        CSEGS_RECURSIVE(0, 7 * ebw, ptree->sub_tree[tree_idx++]);
      break;
    case PARTITION_SPLIT: {
      for (int n = 0; n < 4; n++) {
        const int mi_dc = hbw * (n & 1);
        const int mi_dr = hbh * (n >> 1);
        count_segs_sb(cm, xd, tile, &mi[mi_dr * mis + mi_dc], no_pred_segcounts,
                      temporal_predictor_count, t_unpred_seg_counts,
                      mi_row + mi_dr, mi_col + mi_dc, ptree->sub_tree[n]);
      }
    } break;
    default: assert(0);
  }

#undef CSEGS
}

void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
  struct segmentation *seg = &cm->seg;
  struct segmentation_probs *segp = &cm->fc->seg;
  int no_pred_cost;
  int t_pred_cost = INT_MAX;
  int tile_col, tile_row, mi_row, mi_col;
  unsigned temporal_predictor_count[SEG_TEMPORAL_PRED_CTXS][2] = { { 0 } };
  unsigned no_pred_segcounts[MAX_SEGMENTS] = { 0 };
  unsigned t_unpred_seg_counts[MAX_SEGMENTS] = { 0 };
  (void)xd;
  int scale_up = cm->prev_frame && (cm->width > cm->prev_frame->width ||
                                    cm->height > cm->prev_frame->height);
  // First of all generate stats regarding how well the last segment map
  // predicts this one
  if (!scale_up) {
    for (tile_row = 0; tile_row < cm->tiles.rows; tile_row++) {
      TileInfo tile_info;
      av1_tile_set_row(&tile_info, cm, tile_row);
      for (tile_col = 0; tile_col < cm->tiles.cols; tile_col++) {
        MB_MODE_INFO **mi_ptr;
        av1_tile_set_col(&tile_info, cm, tile_col);
        mi_ptr = cm->mi_params.mi_grid_base +
                 tile_info.mi_row_start * cm->mi_params.mi_stride +
                 tile_info.mi_col_start;
        for (mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
             mi_row += cm->mib_size,
            mi_ptr += cm->mib_size * cm->mi_params.mi_stride) {
          MB_MODE_INFO **mi = mi_ptr;
          for (mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
               mi_col += cm->mib_size, mi += cm->mib_size) {
            const SB_INFO *sbi = av1_get_sb_info(cm, mi_row, mi_col);
            const PARTITION_TREE *ptree = sbi->ptree_root[AOM_PLANE_Y];
            count_segs_sb(cm, xd, &tile_info, mi, no_pred_segcounts,
                          temporal_predictor_count, t_unpred_seg_counts, mi_row,
                          mi_col, ptree);
          }
        }
      }
    }
  }

  int seg_id_cost[MAX_SEGMENTS];
  av1_cost_tokens_from_cdf(seg_id_cost, segp->tree_cdf, NULL);
  no_pred_cost = 0;
  for (int i = 0; i < MAX_SEGMENTS; ++i)
    no_pred_cost += no_pred_segcounts[i] * seg_id_cost[i];

  // Frames without past dependency cannot use temporal prediction
  if (cm->features.primary_ref_frame != PRIMARY_REF_NONE) {
    int pred_flag_cost[SEG_TEMPORAL_PRED_CTXS][2];
    for (int i = 0; i < SEG_TEMPORAL_PRED_CTXS; ++i)
      av1_cost_tokens_from_cdf(pred_flag_cost[i], segp->pred_cdf[i], NULL);
    t_pred_cost = 0;
    // Cost for signaling the prediction flag.
    for (int i = 0; i < SEG_TEMPORAL_PRED_CTXS; ++i) {
      for (int j = 0; j < 2; ++j)
        t_pred_cost += temporal_predictor_count[i][j] * pred_flag_cost[i][j];
    }
    // Cost for signaling the unpredicted segment id.
    for (int i = 0; i < MAX_SEGMENTS; ++i)
      t_pred_cost += t_unpred_seg_counts[i] * seg_id_cost[i];
  }

  // Now choose which coding method to use.
  if (t_pred_cost < no_pred_cost) {
    assert(!cm->features.error_resilient_mode);
    seg->temporal_update = 1;
  } else {
    seg->temporal_update = 0;
  }
}

void av1_reset_segment_features(AV1_COMMON *cm) {
  struct segmentation *seg = &cm->seg;

  // Set up default state for MB feature flags
  seg->enabled = 0;
  seg->update_map = 0;
  seg->update_data = 0;
  av1_clearall_segfeatures(seg);
#if CONFIG_EXT_SEG
  seg->enable_ext_seg = cm->seq_params.enable_ext_seg;
#endif  // CONFIG_EXT_SEG
}
