/*
 * 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 "av1/encoder/context_tree.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/rd.h"
#include <assert.h>

void av1_copy_tree_context(PICK_MODE_CONTEXT *dst_ctx,
                           PICK_MODE_CONTEXT *src_ctx) {
  dst_ctx->mic = src_ctx->mic;
  dst_ctx->mbmi_ext_best = src_ctx->mbmi_ext_best;

  dst_ctx->num_4x4_blk = src_ctx->num_4x4_blk;
  dst_ctx->skippable = src_ctx->skippable;
#if CONFIG_INTERNAL_STATS
  dst_ctx->best_mode_index = src_ctx->best_mode_index;
#endif  // CONFIG_INTERNAL_STATS

  memcpy(dst_ctx->blk_skip, src_ctx->blk_skip,
         sizeof(uint8_t) * src_ctx->num_4x4_blk);
  av1_copy_array(dst_ctx->tx_type_map, src_ctx->tx_type_map,
                 src_ctx->num_4x4_blk);

  dst_ctx->rd_stats = src_ctx->rd_stats;
  dst_ctx->rd_mode_is_ready = src_ctx->rd_mode_is_ready;
}

void av1_setup_shared_coeff_buffer(const SequenceHeader *const seq_params,
                                   PC_TREE_SHARED_BUFFERS *shared_bufs,
                                   struct aom_internal_error_info *error) {
  const int num_planes = seq_params->monochrome ? 1 : MAX_MB_PLANE;
  const int max_sb_square_y = 1 << num_pels_log2_lookup[seq_params->sb_size];
  const int max_sb_square_uv = max_sb_square_y >> (seq_params->subsampling_x +
                                                   seq_params->subsampling_y);
  for (int i = 0; i < num_planes; i++) {
    const int max_num_pix =
        (i == AOM_PLANE_Y) ? max_sb_square_y : max_sb_square_uv;
    AOM_CHECK_MEM_ERROR(error, shared_bufs->coeff_buf[i],
                        aom_memalign(32, max_num_pix * sizeof(tran_low_t)));
    AOM_CHECK_MEM_ERROR(error, shared_bufs->qcoeff_buf[i],
                        aom_memalign(32, max_num_pix * sizeof(tran_low_t)));
    AOM_CHECK_MEM_ERROR(error, shared_bufs->dqcoeff_buf[i],
                        aom_memalign(32, max_num_pix * sizeof(tran_low_t)));
  }
}

void av1_free_shared_coeff_buffer(PC_TREE_SHARED_BUFFERS *shared_bufs) {
  for (int i = 0; i < 3; i++) {
    aom_free(shared_bufs->coeff_buf[i]);
    aom_free(shared_bufs->qcoeff_buf[i]);
    aom_free(shared_bufs->dqcoeff_buf[i]);
    shared_bufs->coeff_buf[i] = NULL;
    shared_bufs->qcoeff_buf[i] = NULL;
    shared_bufs->dqcoeff_buf[i] = NULL;
  }
}

PICK_MODE_CONTEXT *av1_alloc_pmc(const struct AV1_COMP *const cpi,
                                 BLOCK_SIZE bsize,
                                 PC_TREE_SHARED_BUFFERS *shared_bufs) {
  PICK_MODE_CONTEXT *volatile ctx = NULL;
  const AV1_COMMON *const cm = &cpi->common;
  struct aom_internal_error_info error;

  if (setjmp(error.jmp)) {
    av1_free_pmc(ctx, av1_num_planes(cm));
    return NULL;
  }
  error.setjmp = 1;

  AOM_CHECK_MEM_ERROR(&error, ctx, aom_calloc(1, sizeof(*ctx)));
  ctx->rd_mode_is_ready = 0;

  const int num_planes = av1_num_planes(cm);
  const int num_pix = block_size_wide[bsize] * block_size_high[bsize];
  const int num_blk = num_pix / 16;

  AOM_CHECK_MEM_ERROR(&error, ctx->blk_skip,
                      aom_calloc(num_blk, sizeof(*ctx->blk_skip)));
  AOM_CHECK_MEM_ERROR(&error, ctx->tx_type_map,
                      aom_calloc(num_blk, sizeof(*ctx->tx_type_map)));
  ctx->num_4x4_blk = num_blk;

  for (int i = 0; i < num_planes; ++i) {
    ctx->coeff[i] = shared_bufs->coeff_buf[i];
    ctx->qcoeff[i] = shared_bufs->qcoeff_buf[i];
    ctx->dqcoeff[i] = shared_bufs->dqcoeff_buf[i];
    AOM_CHECK_MEM_ERROR(&error, ctx->eobs[i],
                        aom_memalign(32, num_blk * sizeof(*ctx->eobs[i])));
    AOM_CHECK_MEM_ERROR(
        &error, ctx->txb_entropy_ctx[i],
        aom_memalign(32, num_blk * sizeof(*ctx->txb_entropy_ctx[i])));
  }

  if (num_pix <= MAX_PALETTE_SQUARE) {
    for (int i = 0; i < 2; ++i) {
      if (cm->features.allow_screen_content_tools) {
        AOM_CHECK_MEM_ERROR(
            &error, ctx->color_index_map[i],
            aom_memalign(32, num_pix * sizeof(*ctx->color_index_map[i])));
      } else {
        ctx->color_index_map[i] = NULL;
      }
    }
  }

  av1_invalid_rd_stats(&ctx->rd_stats);

  return ctx;
}

void av1_reset_pmc(PICK_MODE_CONTEXT *ctx) {
  av1_zero_array(ctx->blk_skip, ctx->num_4x4_blk);
  av1_zero_array(ctx->tx_type_map, ctx->num_4x4_blk);
  av1_invalid_rd_stats(&ctx->rd_stats);
}

void av1_free_pmc(PICK_MODE_CONTEXT *ctx, int num_planes) {
  if (ctx == NULL) return;

  aom_free(ctx->blk_skip);
  ctx->blk_skip = NULL;
  aom_free(ctx->tx_type_map);
  for (int i = 0; i < num_planes; ++i) {
    ctx->coeff[i] = NULL;
    ctx->qcoeff[i] = NULL;
    ctx->dqcoeff[i] = NULL;
    aom_free(ctx->eobs[i]);
    ctx->eobs[i] = NULL;
    aom_free(ctx->txb_entropy_ctx[i]);
    ctx->txb_entropy_ctx[i] = NULL;
  }

  for (int i = 0; i < 2; ++i) {
    if (ctx->color_index_map[i]) {
      aom_free(ctx->color_index_map[i]);
      ctx->color_index_map[i] = NULL;
    }
  }

  aom_free(ctx);
}

PC_TREE *av1_alloc_pc_tree_node(BLOCK_SIZE bsize) {
  PC_TREE *pc_tree = aom_calloc(1, sizeof(*pc_tree));
  if (pc_tree == NULL) return NULL;

  pc_tree->partitioning = PARTITION_NONE;
  pc_tree->block_size = bsize;

  return pc_tree;
}

#define FREE_PMC_NODE(CTX)         \
  do {                             \
    av1_free_pmc(CTX, num_planes); \
    CTX = NULL;                    \
  } while (0)

void av1_free_pc_tree_recursive(PC_TREE *pc_tree, int num_planes, int keep_best,
                                int keep_none,
                                PARTITION_SEARCH_TYPE partition_search_type) {
  if (pc_tree == NULL) return;

  // Avoid freeing of extended partitions as they are not supported when
  // partition_search_type is VAR_BASED_PARTITION.
  if (partition_search_type == VAR_BASED_PARTITION && !keep_best &&
      !keep_none) {
    FREE_PMC_NODE(pc_tree->none);

    for (int i = 0; i < 2; ++i) {
      FREE_PMC_NODE(pc_tree->horizontal[i]);
      FREE_PMC_NODE(pc_tree->vertical[i]);
    }

#if !defined(NDEBUG) && !CONFIG_REALTIME_ONLY
    for (int i = 0; i < 3; ++i) {
      assert(pc_tree->horizontala[i] == NULL);
      assert(pc_tree->horizontalb[i] == NULL);
      assert(pc_tree->verticala[i] == NULL);
      assert(pc_tree->verticalb[i] == NULL);
    }
    for (int i = 0; i < 4; ++i) {
      assert(pc_tree->horizontal4[i] == NULL);
      assert(pc_tree->vertical4[i] == NULL);
    }
#endif

    for (int i = 0; i < 4; ++i) {
      if (pc_tree->split[i] != NULL) {
        av1_free_pc_tree_recursive(pc_tree->split[i], num_planes, 0, 0,
                                   partition_search_type);
        pc_tree->split[i] = NULL;
      }
    }
    aom_free(pc_tree);
    return;
  }

  const PARTITION_TYPE partition = pc_tree->partitioning;

  if (!keep_none && (!keep_best || (partition != PARTITION_NONE)))
    FREE_PMC_NODE(pc_tree->none);

  for (int i = 0; i < 2; ++i) {
    if (!keep_best || (partition != PARTITION_HORZ))
      FREE_PMC_NODE(pc_tree->horizontal[i]);
    if (!keep_best || (partition != PARTITION_VERT))
      FREE_PMC_NODE(pc_tree->vertical[i]);
  }
#if !CONFIG_REALTIME_ONLY
  for (int i = 0; i < 3; ++i) {
    if (!keep_best || (partition != PARTITION_HORZ_A))
      FREE_PMC_NODE(pc_tree->horizontala[i]);
    if (!keep_best || (partition != PARTITION_HORZ_B))
      FREE_PMC_NODE(pc_tree->horizontalb[i]);
    if (!keep_best || (partition != PARTITION_VERT_A))
      FREE_PMC_NODE(pc_tree->verticala[i]);
    if (!keep_best || (partition != PARTITION_VERT_B))
      FREE_PMC_NODE(pc_tree->verticalb[i]);
  }
  for (int i = 0; i < 4; ++i) {
    if (!keep_best || (partition != PARTITION_HORZ_4))
      FREE_PMC_NODE(pc_tree->horizontal4[i]);
    if (!keep_best || (partition != PARTITION_VERT_4))
      FREE_PMC_NODE(pc_tree->vertical4[i]);
  }
#endif
  if (!keep_best || (partition != PARTITION_SPLIT)) {
    for (int i = 0; i < 4; ++i) {
      if (pc_tree->split[i] != NULL) {
        av1_free_pc_tree_recursive(pc_tree->split[i], num_planes, 0, 0,
                                   partition_search_type);
        pc_tree->split[i] = NULL;
      }
    }
  }

  if (!keep_best && !keep_none) aom_free(pc_tree);
}

void av1_setup_sms_tree(AV1_COMP *const cpi, ThreadData *td) {
  // The structure 'sms_tree' is used to store the simple motion search data for
  // partition pruning in inter frames. Hence, the memory allocations and
  // initializations related to it are avoided for allintra encoding mode.
  if (cpi->oxcf.kf_cfg.key_freq_max == 0) return;

  AV1_COMMON *const cm = &cpi->common;
  const int stat_generation_stage = is_stat_generation_stage(cpi);
  const int is_sb_size_128 = cm->seq_params->sb_size == BLOCK_128X128;
  const int tree_nodes =
      av1_get_pc_tree_nodes(is_sb_size_128, stat_generation_stage);
  int sms_tree_index = 0;
  SIMPLE_MOTION_DATA_TREE *this_sms;
  int square_index = 1;
  int nodes;

  aom_free(td->sms_tree);
  CHECK_MEM_ERROR(cm, td->sms_tree,
                  aom_calloc(tree_nodes, sizeof(*td->sms_tree)));
  this_sms = &td->sms_tree[0];

  if (!stat_generation_stage) {
    const int leaf_factor = is_sb_size_128 ? 4 : 1;
    const int leaf_nodes = 256 * leaf_factor;

    // Sets up all the leaf nodes in the tree.
    for (sms_tree_index = 0; sms_tree_index < leaf_nodes; ++sms_tree_index) {
      SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
      tree->block_size = square[0];
    }

    // Each node has 4 leaf nodes, fill each block_size level of the tree
    // from leafs to the root.
    for (nodes = leaf_nodes >> 2; nodes > 0; nodes >>= 2) {
      for (int i = 0; i < nodes; ++i) {
        SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
        tree->block_size = square[square_index];
        for (int j = 0; j < 4; j++) tree->split[j] = this_sms++;
        ++sms_tree_index;
      }
      ++square_index;
    }
  } else {
    // Allocation for firstpass/LAP stage
    // TODO(Mufaddal): refactor square_index to use a common block_size macro
    // from firstpass.c
    SIMPLE_MOTION_DATA_TREE *const tree = &td->sms_tree[sms_tree_index];
    square_index = 2;
    tree->block_size = square[square_index];
  }

  // Set up the root node for the largest superblock size
  td->sms_root = &td->sms_tree[tree_nodes - 1];
}

void av1_free_sms_tree(ThreadData *td) {
  if (td->sms_tree != NULL) {
    aom_free(td->sms_tree);
    td->sms_tree = NULL;
  }
}
