/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"
#include "vp8/common/onyxc_int.h"
#include "onyx_int.h"
#include "vp8/encoder/quantize.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
#include "vp8/common/alloccommon.h"
#include "vp8/common/loopfilter.h"
#if ARCH_ARM
#include "vpx_ports/arm.h"
#endif

extern int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source,
                           YV12_BUFFER_CONFIG *dest);

static void yv12_copy_partial_frame(YV12_BUFFER_CONFIG *src_ybc,
                                    YV12_BUFFER_CONFIG *dst_ybc) {
  unsigned char *src_y, *dst_y;
  int yheight;
  int ystride;
  int yoffset;
  int linestocopy;

  yheight = src_ybc->y_height;
  ystride = src_ybc->y_stride;

  /* number of MB rows to use in partial filtering */
  linestocopy = (yheight >> 4) / PARTIAL_FRAME_FRACTION;
  linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */

  /* Copy extra 4 so that full filter context is available if filtering done
   * on the copied partial frame and not original. Partial filter does mb
   * filtering for top row also, which can modify3 pixels above.
   */
  linestocopy += 4;
  /* partial image starts at ~middle of frame (macroblock border)*/
  yoffset = ystride * (((yheight >> 5) * 16) - 4);
  src_y = src_ybc->y_buffer + yoffset;
  dst_y = dst_ybc->y_buffer + yoffset;

  memcpy(dst_y, src_y, ystride * linestocopy);
}

static int calc_partial_ssl_err(YV12_BUFFER_CONFIG *source,
                                YV12_BUFFER_CONFIG *dest) {
  int i, j;
  int Total = 0;
  int srcoffset, dstoffset;
  unsigned char *src = source->y_buffer;
  unsigned char *dst = dest->y_buffer;

  int linestocopy;

  /* number of MB rows to use in partial filtering */
  linestocopy = (source->y_height >> 4) / PARTIAL_FRAME_FRACTION;
  linestocopy = linestocopy ? linestocopy << 4 : 16; /* 16 lines per MB */

  /* partial image starts at ~middle of frame (macroblock border)*/
  srcoffset = source->y_stride * ((dest->y_height >> 5) * 16);
  dstoffset = dest->y_stride * ((dest->y_height >> 5) * 16);

  src += srcoffset;
  dst += dstoffset;

  /* Loop through the Y plane raw and reconstruction data summing
   * (square differences)
   */
  for (i = 0; i < linestocopy; i += 16) {
    for (j = 0; j < source->y_width; j += 16) {
      unsigned int sse;
      Total += vpx_mse16x16(src + j, source->y_stride, dst + j, dest->y_stride,
                            &sse);
    }

    src += 16 * source->y_stride;
    dst += 16 * dest->y_stride;
  }

  return Total;
}

/* Enforce a minimum filter level based upon baseline Q */
static int get_min_filter_level(VP8_COMP *cpi, int base_qindex) {
  int min_filter_level;

  if (cpi->source_alt_ref_active && cpi->common.refresh_golden_frame &&
      !cpi->common.refresh_alt_ref_frame) {
    min_filter_level = 0;
  } else {
    if (base_qindex <= 6) {
      min_filter_level = 0;
    } else if (base_qindex <= 16) {
      min_filter_level = 1;
    } else {
      min_filter_level = (base_qindex / 8);
    }
  }

  return min_filter_level;
}

/* Enforce a maximum filter level based upon baseline Q */
static int get_max_filter_level(VP8_COMP *cpi, int base_qindex) {
  /* PGW August 2006: Highest filter values almost always a bad idea */

  /* jbb chg: 20100118 - not so any more with this overquant stuff allow
   * high values with lots of intra coming in.
   */
  int max_filter_level = MAX_LOOP_FILTER;
  (void)base_qindex;

  if (cpi->twopass.section_intra_rating > 8) {
    max_filter_level = MAX_LOOP_FILTER * 3 / 4;
  }

  return max_filter_level;
}

void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) {
  VP8_COMMON *cm = &cpi->common;

  int best_err = 0;
  int filt_err = 0;
  int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
  int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
  int filt_val;
  int best_filt_val;
  YV12_BUFFER_CONFIG *saved_frame = cm->frame_to_show;

  /* Replace unfiltered frame buffer with a new one */
  cm->frame_to_show = &cpi->pick_lf_lvl_frame;

  if (cm->frame_type == KEY_FRAME) {
    cm->sharpness_level = 0;
  } else {
    cm->sharpness_level = cpi->oxcf.Sharpness;
  }

  if (cm->sharpness_level != cm->last_sharpness_level) {
    vp8_loop_filter_update_sharpness(&cm->lf_info, cm->sharpness_level);
    cm->last_sharpness_level = cm->sharpness_level;
  }

  /* Start the search at the previous frame filter level unless it is
   * now out of range.
   */
  if (cm->filter_level < min_filter_level) {
    cm->filter_level = min_filter_level;
  } else if (cm->filter_level > max_filter_level) {
    cm->filter_level = max_filter_level;
  }

  filt_val = cm->filter_level;
  best_filt_val = filt_val;

  /* Get the err using the previous frame's filter value. */

  /* Copy the unfiltered / processed recon buffer to the new buffer */
  yv12_copy_partial_frame(saved_frame, cm->frame_to_show);
  vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);

  best_err = calc_partial_ssl_err(sd, cm->frame_to_show);

  filt_val -= 1 + (filt_val > 10);

  /* Search lower filter levels */
  while (filt_val >= min_filter_level) {
    /* Apply the loop filter */
    yv12_copy_partial_frame(saved_frame, cm->frame_to_show);
    vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);

    /* Get the err for filtered frame */
    filt_err = calc_partial_ssl_err(sd, cm->frame_to_show);

    /* Update the best case record or exit loop. */
    if (filt_err < best_err) {
      best_err = filt_err;
      best_filt_val = filt_val;
    } else {
      break;
    }

    /* Adjust filter level */
    filt_val -= 1 + (filt_val > 10);
  }

  /* Search up (note that we have already done filt_val = cm->filter_level) */
  filt_val = cm->filter_level + 1 + (filt_val > 10);

  if (best_filt_val == cm->filter_level) {
    /* Resist raising filter level for very small gains */
    best_err -= (best_err >> 10);

    while (filt_val < max_filter_level) {
      /* Apply the loop filter */
      yv12_copy_partial_frame(saved_frame, cm->frame_to_show);

      vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);

      /* Get the err for filtered frame */
      filt_err = calc_partial_ssl_err(sd, cm->frame_to_show);

      /* Update the best case record or exit loop. */
      if (filt_err < best_err) {
        /* Do not raise filter level if improvement is < 1 part
         * in 4096
         */
        best_err = filt_err - (filt_err >> 10);

        best_filt_val = filt_val;
      } else {
        break;
      }

      /* Adjust filter level */
      filt_val += 1 + (filt_val > 10);
    }
  }

  cm->filter_level = best_filt_val;

  if (cm->filter_level < min_filter_level) cm->filter_level = min_filter_level;

  if (cm->filter_level > max_filter_level) cm->filter_level = max_filter_level;

  /* restore unfiltered frame pointer */
  cm->frame_to_show = saved_frame;
}

/* Stub function for now Alt LF not used */
void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val) {
  MACROBLOCKD *mbd = &cpi->mb.e_mbd;
  (void)filt_val;

  mbd->segment_feature_data[MB_LVL_ALT_LF][0] =
      cpi->segment_feature_data[MB_LVL_ALT_LF][0];
  mbd->segment_feature_data[MB_LVL_ALT_LF][1] =
      cpi->segment_feature_data[MB_LVL_ALT_LF][1];
  mbd->segment_feature_data[MB_LVL_ALT_LF][2] =
      cpi->segment_feature_data[MB_LVL_ALT_LF][2];
  mbd->segment_feature_data[MB_LVL_ALT_LF][3] =
      cpi->segment_feature_data[MB_LVL_ALT_LF][3];
}

void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi) {
  VP8_COMMON *cm = &cpi->common;

  int best_err = 0;
  int filt_err = 0;
  int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
  int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);

  int filter_step;
  int filt_high = 0;
  int filt_mid;
  int filt_low = 0;
  int filt_best;
  int filt_direction = 0;

  /* Bias against raising loop filter and in favor of lowering it */
  int Bias = 0;

  int ss_err[MAX_LOOP_FILTER + 1];

  YV12_BUFFER_CONFIG *saved_frame = cm->frame_to_show;

  memset(ss_err, 0, sizeof(ss_err));

  /* Replace unfiltered frame buffer with a new one */
  cm->frame_to_show = &cpi->pick_lf_lvl_frame;

  if (cm->frame_type == KEY_FRAME) {
    cm->sharpness_level = 0;
  } else {
    cm->sharpness_level = cpi->oxcf.Sharpness;
  }

  /* Start the search at the previous frame filter level unless it is
   * now out of range.
   */
  filt_mid = cm->filter_level;

  if (filt_mid < min_filter_level) {
    filt_mid = min_filter_level;
  } else if (filt_mid > max_filter_level) {
    filt_mid = max_filter_level;
  }

  /* Define the initial step size */
  filter_step = (filt_mid < 16) ? 4 : filt_mid / 4;

  /* Get baseline error score */

  /* Copy the unfiltered / processed recon buffer to the new buffer */
  vpx_yv12_copy_y(saved_frame, cm->frame_to_show);

  vp8cx_set_alt_lf_level(cpi, filt_mid);
  vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid);

  best_err = vp8_calc_ss_err(sd, cm->frame_to_show);

  ss_err[filt_mid] = best_err;

  filt_best = filt_mid;

  while (filter_step > 0) {
    Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step;

    if (cpi->twopass.section_intra_rating < 20) {
      Bias = Bias * cpi->twopass.section_intra_rating / 20;
    }

    filt_high = ((filt_mid + filter_step) > max_filter_level)
                    ? max_filter_level
                    : (filt_mid + filter_step);
    filt_low = ((filt_mid - filter_step) < min_filter_level)
                   ? min_filter_level
                   : (filt_mid - filter_step);

    if ((filt_direction <= 0) && (filt_low != filt_mid)) {
      if (ss_err[filt_low] == 0) {
        /* Get Low filter error score */
        vpx_yv12_copy_y(saved_frame, cm->frame_to_show);
        vp8cx_set_alt_lf_level(cpi, filt_low);
        vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low);

        filt_err = vp8_calc_ss_err(sd, cm->frame_to_show);
        ss_err[filt_low] = filt_err;
      } else {
        filt_err = ss_err[filt_low];
      }

      /* If value is close to the best so far then bias towards a
       * lower loop filter value.
       */
      if ((filt_err - Bias) < best_err) {
        /* Was it actually better than the previous best? */
        if (filt_err < best_err) best_err = filt_err;

        filt_best = filt_low;
      }
    }

    /* Now look at filt_high */
    if ((filt_direction >= 0) && (filt_high != filt_mid)) {
      if (ss_err[filt_high] == 0) {
        vpx_yv12_copy_y(saved_frame, cm->frame_to_show);
        vp8cx_set_alt_lf_level(cpi, filt_high);
        vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high);

        filt_err = vp8_calc_ss_err(sd, cm->frame_to_show);
        ss_err[filt_high] = filt_err;
      } else {
        filt_err = ss_err[filt_high];
      }

      /* Was it better than the previous best? */
      if (filt_err < (best_err - Bias)) {
        best_err = filt_err;
        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 = filter_step / 2;
      filt_direction = 0;
    } else {
      filt_direction = (filt_best < filt_mid) ? -1 : 1;
      filt_mid = filt_best;
    }
  }

  cm->filter_level = filt_best;

  /* restore unfiltered frame pointer */
  cm->frame_to_show = saved_frame;
}
