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

#include "config/aom_scale_rtcd.h"

#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/psnr.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/mem.h"

#include "av1/common/av1_common_int.h"
#include "av1/common/av1_loopfilter.h"
#include "av1/common/quant_common.h"

#include "av1/encoder/av1_quantize.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/picklpf.h"

// AV1 loop filter applies to the whole frame according to mi_rows and mi_cols,
// which are calculated based on aligned width and aligned height,
// In addition, if super res is enabled, it copies the whole frame
// according to the aligned width and height (av1_superres_upscale()).
// So we need to copy the whole filtered region, instead of the cropped region.
// For example, input image size is: 160x90.
// Then src->y_crop_width = 160, src->y_crop_height = 90.
// The aligned frame size is: src->y_width = 160, src->y_height = 96.
// AV1 aligns frame size to a multiple of 8, if there is
// chroma subsampling, it is able to ensure the chroma is also
// an integer number of mi units. mi unit is 4x4, 8 = 4 * 2, and 2 luma mi
// units correspond to 1 chroma mi unit if there is subsampling.
// See: aom_realloc_frame_buffer() in yv12config.c.
static void yv12_copy_plane(const YV12_BUFFER_CONFIG *src_bc,
                            YV12_BUFFER_CONFIG *dst_bc, int plane) {
  switch (plane) {
    case 0: aom_yv12_copy_y(src_bc, dst_bc, 0); break;
    case 1: aom_yv12_copy_u(src_bc, dst_bc, 0); break;
    case 2: aom_yv12_copy_v(src_bc, dst_bc, 0); break;
    default: assert(plane >= 0 && plane <= 2); break;
  }
}

static int get_max_filter_level(const AV1_COMP *cpi) {
  if (is_stat_consumption_stage_twopass(cpi)) {
    return cpi->ppi->twopass.section_intra_rating > 8 ? MAX_LOOP_FILTER * 3 / 4
                                                      : MAX_LOOP_FILTER;
  } else {
    return MAX_LOOP_FILTER;
  }
}

static int64_t try_filter_frame(const YV12_BUFFER_CONFIG *sd,
                                AV1_COMP *const cpi, int filt_level,
                                int partial_frame, int plane, int dir) {
  MultiThreadInfo *const mt_info = &cpi->mt_info;
  int num_workers = mt_info->num_mod_workers[MOD_LPF];
  AV1_COMMON *const cm = &cpi->common;
  int64_t filt_err;

  assert(plane >= 0 && plane <= 2);
  int filter_level[2] = { filt_level, filt_level };
  if (plane == 0 && dir == 0) filter_level[1] = cm->lf.filter_level[1];
  if (plane == 0 && dir == 1) filter_level[0] = cm->lf.filter_level[0];

  // set base filters for use of get_filter_level (av1_loopfilter.c) when in
  // DELTA_LF mode
  switch (plane) {
    case 0:
      cm->lf.filter_level[0] = filter_level[0];
      cm->lf.filter_level[1] = filter_level[1];
      break;
    case 1: cm->lf.filter_level_u = filter_level[0]; break;
    case 2: cm->lf.filter_level_v = filter_level[0]; break;
  }

  // lpf_opt_level = 1 : Enables dual/quad loop-filtering.
  int lpf_opt_level = is_inter_tx_size_search_level_one(&cpi->sf.tx_sf);

  av1_loop_filter_frame_mt(&cm->cur_frame->buf, cm, &cpi->td.mb.e_mbd, plane,
                           plane + 1, partial_frame, mt_info->workers,
                           num_workers, &mt_info->lf_row_sync, lpf_opt_level);

  filt_err = aom_get_sse_plane(sd, &cm->cur_frame->buf, plane,
                               cm->seq_params->use_highbitdepth);

  // Re-instate the unfiltered frame
  yv12_copy_plane(&cpi->last_frame_uf, &cm->cur_frame->buf, plane);

  return filt_err;
}

static int search_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
                               int partial_frame,
                               const int *last_frame_filter_level, int plane,
                               int dir, int64_t *best_filter_sse) {
  const AV1_COMMON *const cm = &cpi->common;
  const int min_filter_level = 0;
  const int max_filter_level = get_max_filter_level(cpi);
  int filt_direction = 0;
  int64_t best_err;
  int filt_best;

  // Start the search at the previous frame filter level unless it is now out of
  // range.
  int lvl;
  switch (plane) {
    case 0:
      switch (dir) {
        case 2:
          lvl = (last_frame_filter_level[0] + last_frame_filter_level[1] + 1) >>
                1;
          break;
        case 0:
        case 1: lvl = last_frame_filter_level[dir]; break;
        default: assert(dir >= 0 && dir <= 2); return 0;
      }
      break;
    case 1: lvl = last_frame_filter_level[2]; break;
    case 2: lvl = last_frame_filter_level[3]; break;
    default: assert(plane >= 0 && plane <= 2); return 0;
  }
  int filt_mid = clamp(lvl, min_filter_level, max_filter_level);
  int filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
  // Sum squared error at each filter level
  int64_t ss_err[MAX_LOOP_FILTER + 1];

  const int use_coarse_search = cpi->sf.lpf_sf.use_coarse_filter_level_search;
  assert(use_coarse_search <= 1);
  static const int min_filter_step_lookup[2] = { 0, 2 };
  // min_filter_step_thesh determines the stopping criteria for the search.
  // The search is terminated when filter_step equals min_filter_step_thesh.
  const int min_filter_step_thesh = min_filter_step_lookup[use_coarse_search];

  // Set each entry to -1
  memset(ss_err, 0xFF, sizeof(ss_err));
  yv12_copy_plane(&cm->cur_frame->buf, &cpi->last_frame_uf, plane);
  best_err = try_filter_frame(sd, cpi, filt_mid, partial_frame, plane, dir);
  filt_best = filt_mid;
  ss_err[filt_mid] = best_err;

  while (filter_step > min_filter_step_thesh) {
    const int filt_high = AOMMIN(filt_mid + filter_step, max_filter_level);
    const int filt_low = AOMMAX(filt_mid - filter_step, min_filter_level);

    // Bias against raising loop filter in favor of lowering it.
    int64_t bias = (best_err >> (15 - (filt_mid / 8))) * filter_step;

    if ((is_stat_consumption_stage_twopass(cpi)) &&
        (cpi->ppi->twopass.section_intra_rating < 20))
      bias = (bias * cpi->ppi->twopass.section_intra_rating) / 20;

    // yx, bias less for large block size
    if (cm->features.tx_mode != ONLY_4X4) bias >>= 1;

    if (filt_direction <= 0 && filt_low != filt_mid) {
      // Get Low filter error score
      if (ss_err[filt_low] < 0) {
        ss_err[filt_low] =
            try_filter_frame(sd, cpi, filt_low, partial_frame, plane, dir);
      }
      // If value is close to the best so far then bias towards a lower loop
      // filter value.
      if (ss_err[filt_low] < (best_err + bias)) {
        // Was it actually better than the previous best?
        if (ss_err[filt_low] < best_err) {
          best_err = ss_err[filt_low];
        }
        filt_best = filt_low;
      }
    }

    // Now look at filt_high
    if (filt_direction >= 0 && filt_high != filt_mid) {
      if (ss_err[filt_high] < 0) {
        ss_err[filt_high] =
            try_filter_frame(sd, cpi, filt_high, partial_frame, plane, dir);
      }
      // If value is significantly better than previous best, bias added against
      // raising filter value
      if (ss_err[filt_high] < (best_err - bias)) {
        best_err = ss_err[filt_high];
        filt_best = filt_high;
      }
    }

    // Half the step distance if the best filter value was the same as last time
    if (filt_best == filt_mid) {
      filter_step /= 2;
      filt_direction = 0;
    } else {
      filt_direction = (filt_best < filt_mid) ? -1 : 1;
      filt_mid = filt_best;
    }
  }

  *best_filter_sse = ss_err[filt_best];

  return filt_best;
}

void av1_pick_filter_level(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi,
                           LPF_PICK_METHOD method) {
  AV1_COMMON *const cm = &cpi->common;
  const SequenceHeader *const seq_params = cm->seq_params;
  const int num_planes = av1_num_planes(cm);
  struct loopfilter *const lf = &cm->lf;
  int disable_filter_rt_screen = 0;
  (void)sd;

  // Enable loop filter sharpness only for all-intra encoding mode,
  // or tune IQ or SSIMULACRA2. This is because:
  // - All-intra: frames do not have to serve as references to others
  // - Tune IQ/SSIMULACRA2: enabling loop filter sharpness has been found to
  //   be beneficial for sharpness perception
  if (cpi->oxcf.mode == ALLINTRA || cpi->oxcf.tune_cfg.tuning == AOM_TUNE_IQ ||
      cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2) {
    lf->sharpness_level = cpi->oxcf.algo_cfg.sharpness;
  } else {
    lf->sharpness_level = 0;
  }

  if (cpi->oxcf.algo_cfg.enable_adaptive_sharpness) {
    // Loop filter sharpness levels are highly nonlinear. Visually, lf sharpness
    // 1 is closer to 7 than it is to 0, so in practice adaptive sharpness is
    // written to pick levels 0, 1 and 7 to keep it simple.
    int max_lf_sharpness;

    if (cm->quant_params.base_qindex <= 112) {
      max_lf_sharpness = 7;
    } else if (cm->quant_params.base_qindex <= 160) {
      max_lf_sharpness = 1;
    } else {
      max_lf_sharpness = 0;
    }

    lf->sharpness_level = AOMMIN(lf->sharpness_level, max_lf_sharpness);
  }

  if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
      cpi->sf.rt_sf.skip_lf_screen) {
    // Skip the filter when most of the frame is inactive, for any aq mode.
    if (cpi->active_map.enabled &&
        cpi->rc.percent_blocks_inactive >
            cpi->sf.rt_sf.thresh_active_maps_skip_lf_cdef)
      disable_filter_rt_screen = 1;
    else if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ)
      disable_filter_rt_screen = av1_cyclic_refresh_disable_lf(cpi);
  }

  if (disable_filter_rt_screen ||
      cpi->oxcf.algo_cfg.loopfilter_control == LOOPFILTER_NONE ||
      (cpi->oxcf.algo_cfg.loopfilter_control == LOOPFILTER_REFERENCE &&
       cpi->ppi->rtc_ref.non_reference_frame)) {
    lf->filter_level[0] = 0;
    lf->filter_level[1] = 0;
    return;
  }

  if (method == LPF_PICK_MINIMAL_LPF) {
    lf->filter_level[0] = 0;
    lf->filter_level[1] = 0;
  } else if (method >= LPF_PICK_FROM_Q) {
    const int min_filter_level = 0;
    const int max_filter_level = get_max_filter_level(cpi);
    const int q = av1_ac_quant_QTX(cm->quant_params.base_qindex, 0,
                                   seq_params->bit_depth);
    // based on tests result for rtc test set
    // 0.04590 boosted or 0.02295 non-booseted in 18-bit fixed point
    const int strength_boost_q_treshold = 0;
    int inter_frame_multiplier =
        (q > strength_boost_q_treshold ||
         (cpi->sf.rt_sf.use_nonrd_pick_mode &&
          cpi->common.width * cpi->common.height > 352 * 288))
            ? 12034
            : 6017;
    // Increase strength on base TL0 for temporal layers, for low-resoln,
    // based on frame source_sad.
    if (cpi->svc.number_temporal_layers > 1 &&
        cpi->svc.temporal_layer_id == 0 &&
        cpi->common.width * cpi->common.height <= 352 * 288 &&
        cpi->sf.rt_sf.use_nonrd_pick_mode) {
      if (cpi->rc.frame_source_sad > 100000)
        inter_frame_multiplier = inter_frame_multiplier << 1;
      else if (cpi->rc.frame_source_sad > 50000)
        inter_frame_multiplier = 3 * (inter_frame_multiplier >> 1);
    } else if (cpi->sf.rt_sf.use_fast_fixed_part) {
      inter_frame_multiplier = inter_frame_multiplier << 1;
    }
    // These values were determined by linear fitting the result of the
    // searched level for 8 bit depth:
    // Keyframes: filt_guess = q * 0.06699 - 1.60817
    // Other frames: filt_guess = q * inter_frame_multiplier + 2.48225
    //
    // 10 bit depth:
    // filt_guess = q * 0.01976 + 3.87252
    //
    // 12 bit depth:
    // filt_guess = q * 0.00494 + 3.87252
    int filt_guess;
    switch (seq_params->bit_depth) {
      case AOM_BITS_8:
        filt_guess =
            (cm->current_frame.frame_type == KEY_FRAME)
                ? ROUND_POWER_OF_TWO(q * 17563 - 421574, 18)
                : ROUND_POWER_OF_TWO(q * inter_frame_multiplier + 650707, 18);
        break;
      case AOM_BITS_10:
        filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 4060632, 20);
        break;
      case AOM_BITS_12:
        filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 16242526, 22);
        break;
      default:
        assert(0 &&
               "bit_depth should be AOM_BITS_8, AOM_BITS_10 "
               "or AOM_BITS_12");
        return;
    }
    if (seq_params->bit_depth != AOM_BITS_8 &&
        cm->current_frame.frame_type == KEY_FRAME)
      filt_guess -= 4;
    // TODO(chengchen): retrain the model for Y, U, V filter levels
    lf->filter_level[0] = clamp(filt_guess, min_filter_level, max_filter_level);
    lf->filter_level[1] = clamp(filt_guess, min_filter_level, max_filter_level);
    lf->filter_level_u = clamp(filt_guess, min_filter_level, max_filter_level);
    lf->filter_level_v = clamp(filt_guess, min_filter_level, max_filter_level);
    if (cpi->oxcf.algo_cfg.loopfilter_control == LOOPFILTER_SELECTIVELY &&
        !frame_is_intra_only(cm) && !cpi->rc.high_source_sad) {
      if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN) {
        lf->filter_level[0] = 0;
        lf->filter_level[1] = 0;
      } else {
        const int num4x4 = (cm->width >> 2) * (cm->height >> 2);
        const int newmv_thresh = 7;
        const int distance_since_key_thresh = 5;
        if ((cpi->td.rd_counts.newmv_or_intra_blocks * 100 / num4x4) <
                newmv_thresh &&
            cpi->rc.frames_since_key > distance_since_key_thresh) {
          lf->filter_level[0] = 0;
          lf->filter_level[1] = 0;
        }
      }
    }
  } else {
    int last_frame_filter_level[4] = { 0 };
    if (!frame_is_intra_only(cm)) {
      last_frame_filter_level[0] = cpi->ppi->filter_level[0];
      last_frame_filter_level[1] = cpi->ppi->filter_level[1];
      last_frame_filter_level[2] = cpi->ppi->filter_level_u;
      last_frame_filter_level[3] = cpi->ppi->filter_level_v;
    }
    // The frame buffer last_frame_uf is used to store the non-loop filtered
    // reconstructed frame in search_filter_level().
    if (aom_realloc_frame_buffer(
            &cpi->last_frame_uf, cm->width, cm->height,
            seq_params->subsampling_x, seq_params->subsampling_y,
            seq_params->use_highbitdepth, cpi->oxcf.border_in_pixels,
            cm->features.byte_alignment, NULL, NULL, NULL, false, 0))
      aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
                         "Failed to allocate last frame buffer");

    int64_t zero_filter_sse[MAX_MB_PLANE] = { 0 };
    int64_t best_filter_sse[MAX_MB_PLANE] = { 0 };

    if (cpi->sf.lpf_sf.skip_loop_filter_using_filt_error >= 1) {
      for (int plane = 0; plane < num_planes; plane++) {
        zero_filter_sse[plane] = aom_get_sse_plane(
            sd, &cm->cur_frame->buf, plane, cm->seq_params->use_highbitdepth);
      }
    }

    lf->filter_level[0] = lf->filter_level[1] =
        search_filter_level(sd, cpi, method == LPF_PICK_FROM_SUBIMAGE,
                            last_frame_filter_level, 0, 2, &best_filter_sse[0]);
    if (method != LPF_PICK_FROM_FULL_IMAGE_NON_DUAL) {
      lf->filter_level[0] = search_filter_level(
          sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, last_frame_filter_level, 0,
          0, &best_filter_sse[0]);
      lf->filter_level[1] = search_filter_level(
          sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, last_frame_filter_level, 0,
          1, &best_filter_sse[0]);
    }

    if (num_planes > 1) {
      lf->filter_level_u = search_filter_level(
          sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, last_frame_filter_level, 1,
          0, &best_filter_sse[1]);
      lf->filter_level_v = search_filter_level(
          sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, last_frame_filter_level, 2,
          0, &best_filter_sse[2]);
    }

    lf->backup_filter_level[0] = lf->filter_level[0];
    lf->backup_filter_level[1] = lf->filter_level[1];
    lf->backup_filter_level_u = lf->filter_level_u;
    lf->backup_filter_level_v = lf->filter_level_v;

    if (cpi->sf.lpf_sf.adaptive_luma_loop_filter_skip >= 1) {
      int32_t min_ref_filter_level[2] = { MAX_LOOP_FILTER, MAX_LOOP_FILTER };
      // Find the minimum luma filter levels across all reference frames.
      for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
        const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
        if (buf == NULL) continue;

        if (buf->filter_level[0] != -1)
          min_ref_filter_level[0] =
              AOMMIN(min_ref_filter_level[0], buf->filter_level[0]);
        if (buf->filter_level[1] != -1)
          min_ref_filter_level[1] =
              AOMMIN(min_ref_filter_level[1], buf->filter_level[1]);
      }

      // Reset luma filter levels to zero based on minimum filter levels of
      // reference frames and current frame's pyramid level.
      unsigned int pyramid_level = cm->current_frame.pyramid_level;
      if (pyramid_level > 1) {
        int filter_threshold;
        if (pyramid_level >= 4)
          filter_threshold = 16;
        else
          filter_threshold = 8;

        const bool reset_filter_level_y =
            lf->filter_level[0] < filter_threshold &&
            lf->filter_level[1] < filter_threshold &&
            lf->filter_level_u < filter_threshold &&
            lf->filter_level_v < filter_threshold &&
            min_ref_filter_level[0] == 0 && min_ref_filter_level[1] == 0;
        if (reset_filter_level_y) {
          lf->filter_level[0] = 0;
          lf->filter_level[1] = 0;
        }
      }
    }

    if (lf->filter_level[0] != 0 && lf->filter_level[1] != 0 &&
        cpi->sf.lpf_sf.skip_loop_filter_using_filt_error >= 1) {
      const double pct_improvement_thresh = 2.0;
      bool reset_filter_level_y = true;

      // Calculate the percentage improvement in SSE for each plane. This
      // measures the relative reduction in error when applying the filter
      // compared to no filtering.
      for (int plane = 0; plane < num_planes; plane++) {
        const double pct_improvement_sse =
            ((zero_filter_sse[plane] - best_filter_sse[plane]) * 100.0) /
            zero_filter_sse[plane];
        reset_filter_level_y &= pct_improvement_sse < pct_improvement_thresh;
      }

      if (reset_filter_level_y) {
        lf->filter_level[0] = 0;
        lf->filter_level[1] = 0;
      }
    }

    // Store the current frame's filter levels to be referenced
    // while determining the minimum filter level from reference frames.
    cm->cur_frame->filter_level[0] = lf->filter_level[0];
    cm->cur_frame->filter_level[1] = lf->filter_level[1];
  }
}
