/*
 * 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 <limits.h>
#include <math.h>

#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_variance.h"
#include "av1/encoder/encodeframe.h"
#include "av1/common/seg_common.h"
#include "av1/encoder/segmentation.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_ports/system_state.h"

#define AQ_C_SEGMENTS 5
#define DEFAULT_AQ2_SEG 3  // Neutral Q segment
#define AQ_C_STRENGTHS 3
static const double aq_c_q_adj_factor[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = {
  { 1.75, 1.25, 1.05, 1.00, 0.90 },
  { 2.00, 1.50, 1.15, 1.00, 0.85 },
  { 2.50, 1.75, 1.25, 1.00, 0.80 }
};
static const double aq_c_transitions[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = {
  { 0.15, 0.30, 0.55, 2.00, 100.0 },
  { 0.20, 0.40, 0.65, 2.00, 100.0 },
  { 0.25, 0.50, 0.75, 2.00, 100.0 }
};
static const double aq_c_var_thresholds[AQ_C_STRENGTHS][AQ_C_SEGMENTS] = {
  { -4.0, -3.0, -2.0, 100.00, 100.0 },
  { -3.5, -2.5, -1.5, 100.00, 100.0 },
  { -3.0, -2.0, -1.0, 100.00, 100.0 }
};

static int get_aq_c_strength(int q_index, aom_bit_depth_t bit_depth) {
  // Approximate base quatizer (truncated to int)
  const int base_quant = av1_ac_quant_QTX(q_index, 0, bit_depth) / 4;
  return (base_quant > 10) + (base_quant > 25);
}

static bool is_frame_aq_enabled(const AV1_COMP *const cpi) {
  const AV1_COMMON *const cm = &cpi->common;
  const RefreshFrameFlagsInfo *const refresh_frame_flags = &cpi->refresh_frame;

  return frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
         refresh_frame_flags->alt_ref_frame ||
         (refresh_frame_flags->golden_frame && !cpi->rc.is_src_frame_alt_ref);
}

// Segmentation only makes sense if the target bits per SB is above a threshold.
// Below this the overheads will usually outweigh any benefit.
static bool is_sb_aq_enabled(const AV1_COMP *const cpi) {
  return cpi->rc.sb64_target_rate >= 256;
}

void av1_setup_in_frame_q_adj(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const int base_qindex = cm->quant_params.base_qindex;
  struct segmentation *const seg = &cm->seg;
  const int resolution_change =
      cm->prev_frame && (cm->width != cm->prev_frame->width ||
                         cm->height != cm->prev_frame->height);

  // Make SURE use of floating point in this function is safe.
  aom_clear_system_state();

  if (resolution_change) {
    memset(cpi->enc_seg.map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
    av1_clearall_segfeatures(seg);
    av1_disable_segmentation(seg);
    return;
  }

  if (is_frame_aq_enabled(cpi)) {
    int segment;
    const int aq_strength =
        get_aq_c_strength(base_qindex, cm->seq_params.bit_depth);

    // Clear down the segment map.
    memset(cpi->enc_seg.map, DEFAULT_AQ2_SEG,
           cm->mi_params.mi_rows * cm->mi_params.mi_cols);

    av1_clearall_segfeatures(seg);

    if (!is_sb_aq_enabled(cpi)) {
      av1_disable_segmentation(seg);
      return;
    }

    av1_enable_segmentation(seg);

    // Default segment "Q" feature is disabled so it defaults to the baseline Q.
    av1_disable_segfeature(seg, DEFAULT_AQ2_SEG, SEG_LVL_ALT_Q);

    // Use some of the segments for in frame Q adjustment.
    for (segment = 0; segment < AQ_C_SEGMENTS; ++segment) {
      int qindex_delta;

      if (segment == DEFAULT_AQ2_SEG) continue;

      qindex_delta = av1_compute_qdelta_by_rate(
          &cpi->rc, cm->current_frame.frame_type, base_qindex,
          aq_c_q_adj_factor[aq_strength][segment], cpi->is_screen_content_type,
          cm->seq_params.bit_depth);

      // For AQ complexity mode, we dont allow Q0 in a segment if the base
      // Q is not 0. Q0 (lossless) implies 4x4 only and in AQ mode 2 a segment
      // Q delta is sometimes applied without going back around the rd loop.
      // This could lead to an illegal combination of partition size and q.
      if ((base_qindex != 0) && ((base_qindex + qindex_delta) == 0)) {
        qindex_delta = -base_qindex + 1;
      }
      if ((base_qindex + qindex_delta) > 0) {
        av1_enable_segfeature(seg, segment, SEG_LVL_ALT_Q);
        av1_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta);
      }
    }
  }
}

#define DEFAULT_LV_THRESH 10.0
#define MIN_DEFAULT_LV_THRESH 8.0
// Select a segment for the current block.
// The choice of segment for a block depends on the ratio of the projected
// bits for the block vs a target average and its spatial complexity.
void av1_caq_select_segment(const AV1_COMP *cpi, MACROBLOCK *mb, BLOCK_SIZE bs,
                            int mi_row, int mi_col, int projected_rate) {
  if ((!is_frame_aq_enabled(cpi)) || (!is_sb_aq_enabled(cpi))) return;
  const AV1_COMMON *const cm = &cpi->common;
  const int num_planes = av1_num_planes(cm);

  const int mi_offset = mi_row * cm->mi_params.mi_cols + mi_col;
  const int xmis = AOMMIN(cm->mi_params.mi_cols - mi_col, mi_size_wide[bs]);
  const int ymis = AOMMIN(cm->mi_params.mi_rows - mi_row, mi_size_high[bs]);
  int x, y;
  int i;
  unsigned char segment;

  if (0) {
    segment = DEFAULT_AQ2_SEG;
  } else {
    // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh).
    // It is converted to bits << AV1_PROB_COST_SHIFT units.
    const int64_t num = (int64_t)(cpi->rc.sb64_target_rate * xmis * ymis)
                        << AV1_PROB_COST_SHIFT;
    const int denom = cm->seq_params.mib_size * cm->seq_params.mib_size;
    const int target_rate = (int)(num / denom);
    double logvar;
    double low_var_thresh;
    const int aq_strength = get_aq_c_strength(cm->quant_params.base_qindex,
                                              cm->seq_params.bit_depth);

    aom_clear_system_state();
    low_var_thresh =
        (is_stat_consumption_stage_twopass(cpi))
            ? AOMMAX(exp(cpi->twopass.mb_av_energy), MIN_DEFAULT_LV_THRESH)
            : DEFAULT_LV_THRESH;

    av1_setup_src_planes(mb, cpi->source, mi_row, mi_col, num_planes, bs);
    logvar = av1_log_block_var(cpi, mb, bs);

    segment = AQ_C_SEGMENTS - 1;  // Just in case no break out below.
    for (i = 0; i < AQ_C_SEGMENTS; ++i) {
      // Test rate against a threshold value and variance against a threshold.
      // Increasing segment number (higher variance and complexity) = higher Q.
      if ((projected_rate < target_rate * aq_c_transitions[aq_strength][i]) &&
          (logvar < (low_var_thresh + aq_c_var_thresholds[aq_strength][i]))) {
        segment = i;
        break;
      }
    }
  }

  // Fill in the entires in the segment map corresponding to this SB64.
  for (y = 0; y < ymis; y++) {
    for (x = 0; x < xmis; x++) {
      cpi->enc_seg.map[mi_offset + y * cm->mi_params.mi_cols + x] = segment;
    }
  }
}
