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

#include "config/aom_dsp_rtcd.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_scale/yv12config.h"
#include "aom/aom_integer.h"
#include "av1/encoder/context_tree.h"
#include "av1/encoder/av1_noise_estimate.h"
#include "av1/encoder/encoder.h"

#if CONFIG_AV1_TEMPORAL_DENOISING
#if CONFIG_SVC_ENCODER
// For SVC: only do noise estimation on top spatial layer.
static INLINE int noise_est_svc(const struct AV1_COMP *const cpi) {
  return (!cpi->use_svc ||
          (cpi->use_svc &&
           cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1));
}
#endif  // CONFIG_SVC_ENCODER
#endif  // CONFIG_AV1_TEMPORAL_DENOISING

void av1_noise_estimate_init(NOISE_ESTIMATE *const ne, int width, int height) {
  ne->enabled = 0;
  ne->level = (width * height < 1280 * 720) ? kLowLow : kLow;
  ne->value = 0;
  ne->count = 0;
  ne->thresh = 90;
  ne->last_w = 0;
  ne->last_h = 0;
  if (width * height >= 1920 * 1080) {
    ne->thresh = 200;
  } else if (width * height >= 1280 * 720) {
    ne->thresh = 140;
  } else if (width * height >= 640 * 360) {
    ne->thresh = 115;
  }
  ne->num_frames_estimate = 15;
  ne->adapt_thresh = (3 * ne->thresh) >> 1;
}

static int enable_noise_estimation(AV1_COMP *const cpi) {
  ResizePendingParams *const resize_pending_params =
      &cpi->resize_pending_params;
  const int resize_pending =
      (resize_pending_params->width && resize_pending_params->height &&
       (cpi->common.width != resize_pending_params->width ||
        cpi->common.height != resize_pending_params->height));

  if (cpi->common.seq_params.use_highbitdepth) return 0;

// Enable noise estimation if denoising is on.
#if CONFIG_AV1_TEMPORAL_DENOISING
  if (cpi->oxcf.noise_sensitivity > 0 &&
#if CONFIG_SVC_ENCODER
      noise_est_svc(cpi) &&
#endif  // CONFIG_SVC_ENCODER
      cpi->common.width >= 320 && cpi->common.height >= 180)
    return 1;
#endif
  // Only allow noise estimate under certain encoding mode.
  // Enabled for 1 pass CBR, speed >=5, and if resolution is same as original.
  // Not enabled for SVC mode and screen_content_mode.
  // Not enabled for low resolutions.
  if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_cfg.mode == AOM_CBR &&
      cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.speed >= 5 &&
      resize_pending == 0 &&
#if CONFIG_SVC_ENCODER
      !cpi->use_svc &&
#endif  // CONFIG_SVC_ENCODER
      cpi->oxcf.tune_cfg.content != AOM_CONTENT_SCREEN &&
      cpi->common.width * cpi->common.height >= 640 * 360)
    return 1;
  else
    return 0;
}

#if CONFIG_AV1_TEMPORAL_DENOISING
static void copy_frame(YV12_BUFFER_CONFIG *const dest,
                       const YV12_BUFFER_CONFIG *const src) {
  const uint8_t *srcbuf = src->y_buffer;
  uint8_t *destbuf = dest->y_buffer;

  assert(dest->y_width == src->y_width);
  assert(dest->y_height == src->y_height);

  for (int r = 0; r < dest->y_height; ++r) {
    memcpy(destbuf, srcbuf, dest->y_width);
    destbuf += dest->y_stride;
    srcbuf += src->y_stride;
  }
}
#endif  // CONFIG_AV1_TEMPORAL_DENOISING

NOISE_LEVEL av1_noise_estimate_extract_level(NOISE_ESTIMATE *const ne) {
  int noise_level = kLowLow;
  if (ne->value > (ne->thresh << 1)) {
    noise_level = kHigh;
  } else {
    if (ne->value > ne->thresh)
      noise_level = kMedium;
    else if (ne->value > (ne->thresh >> 1))
      noise_level = kLow;
    else
      noise_level = kLowLow;
  }
  return noise_level;
}

void av1_update_noise_estimate(AV1_COMP *const cpi) {
  const AV1_COMMON *const cm = &cpi->common;
  const CommonModeInfoParams *const mi_params = &cm->mi_params;

  NOISE_ESTIMATE *const ne = &cpi->noise_estimate;
#if CONFIG_SVC_ENCODER
  const int low_res = (cm->width <= 352 && cm->height <= 288);
#endif  // CONFIG_SVC_ENCODER
  // Estimate of noise level every frame_period frames.
  int frame_period = 8;
  int thresh_consec_zeromv = 6;
  int frame_counter = cm->current_frame.frame_number;
  // Estimate is between current source and last source.
  YV12_BUFFER_CONFIG *last_source = cpi->last_source;
#if CONFIG_AV1_TEMPORAL_DENOISING
  if (cpi->oxcf.noise_sensitivity > 0
#if CONFIG_SVC_ENCODER
      && noise_est_svc(cpi)
#endif  // CONFIG_SVC_ENCODER
  ) {
    last_source = &cpi->denoiser.last_source;
    // Tune these thresholds for different resolutions when denoising is
    // enabled.
    if (cm->width > 640 && cm->width <= 1920) {
      thresh_consec_zeromv = 2;
    }
  }
#endif
  ne->enabled = enable_noise_estimation(cpi);
#if CONFIG_SVC_ENCODER
  if (cpi->svc.number_spatial_layers > 1)
    frame_counter = cpi->svc.current_superframe;
#endif  // CONFIG_SVC_ENCODER
  if (!ne->enabled || frame_counter % frame_period != 0 ||
      last_source == NULL ||
      (
#if CONFIG_SVC_ENCODER
          cpi->svc.number_spatial_layers == 1 &&
#endif  // CONFIG_SVC_ENCODER
          (ne->last_w != cm->width || ne->last_h != cm->height))) {
#if CONFIG_AV1_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity > 0
#if CONFIG_SVC_ENCODER
        && noise_est_svc(cpi)
#endif  // CONFIG_SVC_ENCODER
    )
      copy_frame(&cpi->denoiser.last_source, cpi->source);
#endif
    if (last_source != NULL) {
      ne->last_w = cm->width;
      ne->last_h = cm->height;
    }
    return;
#if CONFIG_SVC_ENCODER
  } else if (frame_counter > 60 && cpi->svc.num_encoded_top_layer > 1 &&
             cpi->rc.frames_since_key > cpi->svc.number_spatial_layers &&
             cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1 &&
             cpi->rc.avg_frame_low_motion < (low_res ? 60 : 40)) {
    // Force noise estimation to 0 and denoiser off if content has high motion.
    ne->level = kLowLow;
    ne->count = 0;
    ne->num_frames_estimate = 10;
#if CONFIG_AV1_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity > 0 && noise_est_svc(cpi) &&
        cpi->svc.current_superframe > 1) {
      av1_denoiser_set_noise_level(cpi, ne->level);
      copy_frame(&cpi->denoiser.last_source, cpi->source);
    }
#endif
    return;
#endif  // CONFIG_SVC_ENCODER
  } else {
    unsigned int bin_size = 100;
    unsigned int hist[MAX_VAR_HIST_BINS] = { 0 };
    unsigned int hist_avg[MAX_VAR_HIST_BINS];
    unsigned int max_bin = 0;
    unsigned int max_bin_count = 0;
    unsigned int bin_cnt;
    int bsize = BLOCK_16X16;
    // Loop over sub-sample of 16x16 blocks of frame, and for blocks that have
    // been encoded as zero/small mv at least x consecutive frames, compute
    // the variance to update estimate of noise in the source.
    const uint8_t *src_y = cpi->source->y_buffer;
    const int src_ystride = cpi->source->y_stride;
    const uint8_t *last_src_y = last_source->y_buffer;
    const int last_src_ystride = last_source->y_stride;
    const uint8_t *src_u = cpi->source->u_buffer;
    const uint8_t *src_v = cpi->source->v_buffer;
    const int src_uvstride = cpi->source->uv_stride;
    int mi_row, mi_col;
    int num_low_motion = 0;
    int frame_low_motion = 1;
    for (mi_row = 0; mi_row < mi_params->mi_rows; mi_row += 2) {
      for (mi_col = 0; mi_col < mi_params->mi_cols; mi_col += 2) {
        int bl_index =
            (mi_row >> 1) * (mi_params->mi_cols >> 1) + (mi_col >> 1);
        if (cpi->consec_zero_mv[bl_index] > thresh_consec_zeromv)
          num_low_motion++;
      }
    }
    if (num_low_motion <
        (((3 * (mi_params->mi_rows * mi_params->mi_cols) >> 2)) >> 3))
      frame_low_motion = 0;
    for (mi_row = 0; mi_row < mi_params->mi_rows; mi_row++) {
      for (mi_col = 0; mi_col < mi_params->mi_cols; mi_col++) {
        // 16x16 blocks, 1/4 sample of frame.
        if (mi_row % 8 == 0 && mi_col % 8 == 0 &&
            mi_row < mi_params->mi_rows - 3 &&
            mi_col < mi_params->mi_cols - 3) {
          int bl_index =
              (mi_row >> 1) * (mi_params->mi_cols >> 1) + (mi_col >> 1);
          int bl_index1 = bl_index + 1;
          int bl_index2 = bl_index + (mi_params->mi_cols >> 1);
          int bl_index3 = bl_index2 + 1;
          int consec_zeromv =
              AOMMIN(cpi->consec_zero_mv[bl_index],
                     AOMMIN(cpi->consec_zero_mv[bl_index1],
                            AOMMIN(cpi->consec_zero_mv[bl_index2],
                                   cpi->consec_zero_mv[bl_index3])));
          // Only consider blocks that are likely steady background. i.e, have
          // been encoded as zero/low motion x (= thresh_consec_zeromv) frames
          // in a row. consec_zero_mv[] defined for 8x8 blocks, so consider all
          // 4 sub-blocks for 16x16 block. And exclude this frame if
          // high_source_sad is true (i.e., scene/content change).
          if (frame_low_motion && consec_zeromv > thresh_consec_zeromv &&
              !cpi->rc.high_source_sad) {
            unsigned int sse;
            // Compute variance between co-located blocks from current and
            // last input frames.
            unsigned int variance = cpi->fn_ptr[bsize].vf(
                src_y, src_ystride, last_src_y, last_src_ystride, &sse);
            unsigned int hist_index = variance / bin_size;
            if (hist_index < MAX_VAR_HIST_BINS)
              hist[hist_index]++;
            else if (hist_index < 3 * (MAX_VAR_HIST_BINS >> 1))
              hist[MAX_VAR_HIST_BINS - 1]++;  // Account for the tail
          }
        }
        src_y += 4;
        last_src_y += 4;
        src_u += 2;
        src_v += 2;
      }
      src_y += (src_ystride << 2) - (mi_params->mi_cols << 2);
      last_src_y += (last_src_ystride << 2) - (mi_params->mi_cols << 2);
      src_u += (src_uvstride << 1) - (mi_params->mi_cols << 1);
      src_v += (src_uvstride << 1) - (mi_params->mi_cols << 1);
    }
    ne->last_w = cm->width;
    ne->last_h = cm->height;
    // Adjust histogram to account for effect that histogram flattens
    // and shifts to zero as scene darkens.
    if (hist[0] > 10 && (hist[MAX_VAR_HIST_BINS - 1] > hist[0] >> 2)) {
      hist[0] = 0;
      hist[1] >>= 2;
      hist[2] >>= 2;
      hist[3] >>= 2;
      hist[4] >>= 1;
      hist[5] >>= 1;
      hist[6] = 3 * hist[6] >> 1;
      hist[MAX_VAR_HIST_BINS - 1] >>= 1;
    }

    // Average hist[] and find largest bin
    for (bin_cnt = 0; bin_cnt < MAX_VAR_HIST_BINS; bin_cnt++) {
      if (bin_cnt == 0)
        hist_avg[bin_cnt] = (hist[0] + hist[1] + hist[2]) / 3;
      else if (bin_cnt == MAX_VAR_HIST_BINS - 1)
        hist_avg[bin_cnt] = hist[MAX_VAR_HIST_BINS - 1] >> 2;
      else if (bin_cnt == MAX_VAR_HIST_BINS - 2)
        hist_avg[bin_cnt] = (hist[bin_cnt - 1] + 2 * hist[bin_cnt] +
                             (hist[bin_cnt + 1] >> 1) + 2) >>
                            2;
      else
        hist_avg[bin_cnt] =
            (hist[bin_cnt - 1] + 2 * hist[bin_cnt] + hist[bin_cnt + 1] + 2) >>
            2;

      if (hist_avg[bin_cnt] > max_bin_count) {
        max_bin_count = hist_avg[bin_cnt];
        max_bin = bin_cnt;
      }
    }

    // Scale by 40 to work with existing thresholds
    ne->value = (int)((3 * ne->value + max_bin * 40) >> 2);
    // Quickly increase VNR strength when the noise level increases suddenly.
    if (ne->level < kMedium && ne->value > ne->adapt_thresh) {
      ne->count = ne->num_frames_estimate;
    } else {
      ne->count++;
    }
    if (ne->count == ne->num_frames_estimate) {
      // Reset counter and check noise level condition.
      ne->num_frames_estimate = 30;
      ne->count = 0;
      ne->level = av1_noise_estimate_extract_level(ne);
#if CONFIG_AV1_TEMPORAL_DENOISING
      if (cpi->oxcf.noise_sensitivity > 0
#if CONFIG_SVC_ENCODER
          && noise_est_svc(cpi)
#endif  // CONFIG_SVC_ENCODER
      )
        av1_denoiser_set_noise_level(cpi, ne->level);
#endif
    }
  }
#if CONFIG_AV1_TEMPORAL_DENOISING
  if (cpi->oxcf.noise_sensitivity > 0
#if CONFIG_SVC_ENCODER
      && noise_est_svc(cpi)
#endif  // CONFIG_SVC_ENCODER
  )
    copy_frame(&cpi->denoiser.last_source, cpi->source);
#endif
}
