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

#include "config/aom_config.h"
#include "av1/common/av1_common_int.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/mathutils.h"
#include "av1/encoder/optical_flow.h"
#include "av1/encoder/sparse_linear_solver.h"
#include "av1/encoder/reconinter_enc.h"
#include "aom_mem/aom_mem.h"

#if CONFIG_OPTICAL_FLOW_API

void av1_init_opfl_params(OPFL_PARAMS *opfl_params) {
  opfl_params->pyramid_levels = OPFL_PYRAMID_LEVELS;
  opfl_params->warping_steps = OPFL_WARPING_STEPS;
  opfl_params->lk_params = NULL;
}

void av1_init_lk_params(LK_PARAMS *lk_params) {
  lk_params->window_size = OPFL_WINDOW_SIZE;
}

// Helper function to determine whether a frame is encoded with high bit-depth.
static INLINE int is_frame_high_bitdepth(const YV12_BUFFER_CONFIG *frame) {
  return (frame->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
}

// Helper function to determine whether optical flow method is sparse.
static INLINE int is_sparse(const OPFL_PARAMS *opfl_params) {
  return (opfl_params->flags & OPFL_FLAG_SPARSE) ? 1 : 0;
}

static void gradients_over_window(const YV12_BUFFER_CONFIG *frame,
                                  const YV12_BUFFER_CONFIG *ref_frame,
                                  const double x_coord, const double y_coord,
                                  const int window_size, const int bit_depth,
                                  double *ix, double *iy, double *it,
                                  LOCALMV *mv);

// coefficients for bilinear interpolation on unit square
static int pixel_interp(const double x, const double y, const double b00,
                        const double b01, const double b10, const double b11) {
  const int xint = (int)x;
  const int yint = (int)y;
  const double xdec = x - xint;
  const double ydec = y - yint;
  const double a = (1 - xdec) * (1 - ydec);
  const double b = xdec * (1 - ydec);
  const double c = (1 - xdec) * ydec;
  const double d = xdec * ydec;
  // if x, y are already integers, this results to b00
  int interp = (int)round(a * b00 + b * b01 + c * b10 + d * b11);
  return interp;
}

// bilinear interpolation to find subpixel values
static AOM_INLINE int get_subpixels(const YV12_BUFFER_CONFIG *frame, int *pred,
                                    const int w, const int h, LOCALMV mv,
                                    const double x_coord,
                                    const double y_coord) {
  double left = x_coord + mv.row;
  double top = y_coord + mv.col;
  const int fromedge = 2;
  const int height = frame->y_crop_height;
  const int width = frame->y_crop_width;
  if (left < 1) left = 1;
  if (top < 1) top = 1;
  // could use elements past boundary where stride > width
  if (top > height - fromedge) top = height - fromedge;
  if (left > width - fromedge) left = width - fromedge;
  const uint8_t *buf = frame->y_buffer;
  const int s = frame->y_stride;
  int prev = -1;

  int xint;
  int yint;
  int idx = 0;
  for (int y = prev; y < prev + h; y++) {
    for (int x = prev; x < prev + w; x++) {
      double xx = left + x;
      double yy = top + y;
      xint = (int)xx;
      yint = (int)yy;
      int interp = pixel_interp(
          xx, yy, buf[yint * s + xint], buf[yint * s + (xint + 1)],
          buf[(yint + 1) * s + xint], buf[(yint + 1) * s + (xint + 1)]);
      pred[idx++] = interp;
    }
  }
  return 0;
}

// Scharr filter to compute spatial gradient
static void spatial_gradient(const YV12_BUFFER_CONFIG *frame, const int x_coord,
                             const int y_coord, const int direction,
                             double *derivative) {
  double *filter;
  // Scharr filters
  double gx[9] = { -3, 0, 3, -10, 0, 10, -3, 0, 3 };
  double gy[9] = { -3, -10, -3, 0, 0, 0, 3, 10, 3 };
  if (direction == 0) {  // x direction
    filter = gx;
  } else {  // y direction
    filter = gy;
  }
  int idx = 0;
  double d = 0;
  for (int yy = -1; yy <= 1; yy++) {
    for (int xx = -1; xx <= 1; xx++) {
      d += filter[idx] *
           frame->y_buffer[(y_coord + yy) * frame->y_stride + (x_coord + xx)];
      idx++;
    }
  }
  // normalization scaling factor for scharr
  *derivative = d / 32.0;
}

// Determine the spatial gradient at subpixel locations
// For example, when reducing images for pyramidal LK,
// corners found in original image may be at subpixel locations.
static void gradient_interp(double *fullpel_deriv, const double x_coord,
                            const double y_coord, const int w, const int h,
                            double *derivative) {
  const int xint = (int)x_coord;
  const int yint = (int)y_coord;
  double interp;
  if (xint + 1 > w - 1 || yint + 1 > h - 1) {
    interp = fullpel_deriv[yint * w + xint];
  } else {
    interp = pixel_interp(x_coord, y_coord, fullpel_deriv[yint * w + xint],
                          fullpel_deriv[yint * w + (xint + 1)],
                          fullpel_deriv[(yint + 1) * w + xint],
                          fullpel_deriv[(yint + 1) * w + (xint + 1)]);
  }

  *derivative = interp;
}

static void temporal_gradient(const YV12_BUFFER_CONFIG *frame,
                              const YV12_BUFFER_CONFIG *frame2,
                              const double x_coord, const double y_coord,
                              const int bit_depth, double *derivative,
                              LOCALMV *mv) {
  const int w = 2;
  const int h = 2;
  uint8_t pred1[4];
  uint8_t pred2[4];

  const int y = (int)y_coord;
  const int x = (int)x_coord;
  const double ydec = y_coord - y;
  const double xdec = x_coord - x;
  const int is_intrabc = 0;  // Is intra-copied?
  const int is_high_bitdepth = is_frame_high_bitdepth(frame2);
  const int subsampling_x = 0, subsampling_y = 0;  // for y-buffer
  const int_interpfilters interp_filters =
      av1_broadcast_interp_filter(MULTITAP_SHARP);
  const int plane = 0;  // y-plane
  const struct buf_2d ref_buf2 = { NULL, frame2->y_buffer, frame2->y_crop_width,
                                   frame2->y_crop_height, frame2->y_stride };
  struct scale_factors scale;
  av1_setup_scale_factors_for_frame(&scale, frame->y_crop_width,
                                    frame->y_crop_height, frame->y_crop_width,
                                    frame->y_crop_height);
  InterPredParams inter_pred_params;
  av1_init_inter_params(&inter_pred_params, w, h, y, x, subsampling_x,
                        subsampling_y, bit_depth, is_high_bitdepth, is_intrabc,
                        &scale, &ref_buf2, interp_filters);
  inter_pred_params.interp_filter_params[0] =
      &av1_interp_filter_params_list[interp_filters.as_filters.x_filter];
  inter_pred_params.interp_filter_params[1] =
      &av1_interp_filter_params_list[interp_filters.as_filters.y_filter];
  inter_pred_params.conv_params = get_conv_params(0, plane, bit_depth);
  MV newmv = { .row = (int16_t)round((mv->row + xdec) * 8),
               .col = (int16_t)round((mv->col + ydec) * 8) };
  av1_enc_build_one_inter_predictor(pred2, w, &newmv, &inter_pred_params);
  const struct buf_2d ref_buf1 = { NULL, frame->y_buffer, frame->y_crop_width,
                                   frame->y_crop_height, frame->y_stride };
  av1_init_inter_params(&inter_pred_params, w, h, y, x, subsampling_x,
                        subsampling_y, bit_depth, is_high_bitdepth, is_intrabc,
                        &scale, &ref_buf1, interp_filters);
  inter_pred_params.interp_filter_params[0] =
      &av1_interp_filter_params_list[interp_filters.as_filters.x_filter];
  inter_pred_params.interp_filter_params[1] =
      &av1_interp_filter_params_list[interp_filters.as_filters.y_filter];
  inter_pred_params.conv_params = get_conv_params(0, plane, bit_depth);
  MV zeroMV = { .row = (int16_t)round(xdec * 8),
                .col = (int16_t)round(ydec * 8) };
  av1_enc_build_one_inter_predictor(pred1, w, &zeroMV, &inter_pred_params);

  *derivative = pred2[0] - pred1[0];
}

// Numerical differentiate over window_size x window_size surrounding (x,y)
// location. Alters ix, iy, it to contain numerical partial derivatives
static void gradients_over_window(const YV12_BUFFER_CONFIG *frame,
                                  const YV12_BUFFER_CONFIG *ref_frame,
                                  const double x_coord, const double y_coord,
                                  const int window_size, const int bit_depth,
                                  double *ix, double *iy, double *it,
                                  LOCALMV *mv) {
  const double left = x_coord - window_size / 2.0;
  const double top = y_coord - window_size / 2.0;
  // gradient operators need pixel before and after (start at 1)
  const double x_start = AOMMAX(1, left);
  const double y_start = AOMMAX(1, top);
  const int frame_height = frame->y_crop_height;
  const int frame_width = frame->y_crop_width;
  double deriv_x;
  double deriv_y;
  double deriv_t;

  const double x_end = AOMMIN(x_coord + window_size / 2.0, frame_width - 2);
  const double y_end = AOMMIN(y_coord + window_size / 2.0, frame_height - 2);
  const int xs = (int)AOMMAX(1, x_start - 1);
  const int ys = (int)AOMMAX(1, y_start - 1);
  const int xe = (int)AOMMIN(x_end + 2, frame_width - 2);
  const int ye = (int)AOMMIN(y_end + 2, frame_height - 2);
  // with normalization, gradients may be double values
  double *fullpel_dx = aom_malloc((ye - ys) * (xe - xs) * sizeof(deriv_x));
  double *fullpel_dy = aom_malloc((ye - ys) * (xe - xs) * sizeof(deriv_y));
  // TODO(any): This could be more efficient in the case that x_coord
  // and y_coord are integers.. but it may look more messy.

  // calculate spatial gradients at full pixel locations
  for (int j = ys; j < ye; j++) {
    for (int i = xs; i < xe; i++) {
      spatial_gradient(frame, i, j, 0, &deriv_x);
      spatial_gradient(frame, i, j, 1, &deriv_y);
      int idx = (j - ys) * (xe - xs) + (i - xs);
      fullpel_dx[idx] = deriv_x;
      fullpel_dy[idx] = deriv_y;
    }
  }
  // compute numerical differentiation for every pixel in window
  // (this potentially includes subpixels)
  for (double j = y_start; j < y_end; j++) {
    for (double i = x_start; i < x_end; i++) {
      temporal_gradient(frame, ref_frame, i, j, bit_depth, &deriv_t, mv);
      gradient_interp(fullpel_dx, i - xs, j - ys, xe - xs, ye - ys, &deriv_x);
      gradient_interp(fullpel_dy, i - xs, j - ys, xe - xs, ye - ys, &deriv_y);
      int idx = (int)(j - top) * window_size + (int)(i - left);
      ix[idx] = deriv_x;
      iy[idx] = deriv_y;
      it[idx] = deriv_t;
    }
  }
  // TODO(any): to avoid setting deriv arrays to zero for every iteration,
  // could instead pass these two values back through function call
  // int first_idx = (int)(y_start - top) * window_size + (int)(x_start - left);
  // int width = window_size - ((int)(x_start - left) + (int)(left + window_size
  // - x_end));

  aom_free(fullpel_dx);
  aom_free(fullpel_dy);
}

// To compute eigenvalues of 2x2 matrix: Solve for lambda where
// Determinant(matrix - lambda*identity) == 0
static void eigenvalues_2x2(const double *matrix, double *eig) {
  const double a = 1;
  const double b = -1 * matrix[0] - matrix[3];
  const double c = -1 * matrix[1] * matrix[2] + matrix[0] * matrix[3];
  // quadratic formula
  const double discriminant = b * b - 4 * a * c;
  eig[0] = (-b - sqrt(discriminant)) / (2.0 * a);
  eig[1] = (-b + sqrt(discriminant)) / (2.0 * a);
  // double check that eigenvalues are ordered by magnitude
  if (fabs(eig[0]) > fabs(eig[1])) {
    double tmp = eig[0];
    eig[0] = eig[1];
    eig[1] = tmp;
  }
}

// Shi-Tomasi corner detection criteria
static double corner_score(const YV12_BUFFER_CONFIG *frame_to_filter,
                           const YV12_BUFFER_CONFIG *ref_frame, const int x,
                           const int y, double *i_x, double *i_y, double *i_t,
                           const int n, const int bit_depth) {
  double eig[2];
  LOCALMV mv = { .row = 0, .col = 0 };
  // TODO(any): technically, ref_frame and i_t are not used by corner score
  // so these could be replaced by dummy variables,
  // or change this to spatial gradient function over window only
  gradients_over_window(frame_to_filter, ref_frame, x, y, n, bit_depth, i_x,
                        i_y, i_t, &mv);
  double Mres1[1] = { 0 }, Mres2[1] = { 0 }, Mres3[1] = { 0 };
  multiply_mat(i_x, i_x, Mres1, 1, n * n, 1);
  multiply_mat(i_x, i_y, Mres2, 1, n * n, 1);
  multiply_mat(i_y, i_y, Mres3, 1, n * n, 1);
  double M[4] = { Mres1[0], Mres2[0], Mres2[0], Mres3[0] };
  eigenvalues_2x2(M, eig);
  return fabs(eig[0]);
}

// Finds corners in frame_to_filter
// For less strict requirements (i.e. more corners), decrease threshold
static int detect_corners(const YV12_BUFFER_CONFIG *frame_to_filter,
                          const YV12_BUFFER_CONFIG *ref_frame,
                          const int maxcorners, int *ref_corners,
                          const int bit_depth) {
  const int frame_height = frame_to_filter->y_crop_height;
  const int frame_width = frame_to_filter->y_crop_width;
  // TODO(any): currently if maxcorners is decreased, then it only means
  // corners will be omited from bottom-right of image. if maxcorners
  // is actually used, then this algorithm would need to re-iterate
  // and choose threshold based on that
  assert(maxcorners == frame_height * frame_width);
  int countcorners = 0;
  const double threshold = 0.1;
  double score;
  const int n = 3;
  double i_x[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  double i_y[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  double i_t[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  const int fromedge = n;
  double max_score = corner_score(frame_to_filter, ref_frame, fromedge,
                                  fromedge, i_x, i_y, i_t, n, bit_depth);
  // rough estimate of max corner score in image
  for (int x = fromedge; x < frame_width - fromedge; x += 1) {
    for (int y = fromedge; y < frame_height - fromedge; y += frame_height / 5) {
      for (int i = 0; i < n * n; i++) {
        i_x[i] = 0;
        i_y[i] = 0;
        i_t[i] = 0;
      }
      score = corner_score(frame_to_filter, ref_frame, x, y, i_x, i_y, i_t, n,
                           bit_depth);
      if (score > max_score) {
        max_score = score;
      }
    }
  }
  // score all the points and choose corners over threshold
  for (int x = fromedge; x < frame_width - fromedge; x += 1) {
    for (int y = fromedge;
         (y < frame_height - fromedge) && countcorners < maxcorners; y += 1) {
      for (int i = 0; i < n * n; i++) {
        i_x[i] = 0;
        i_y[i] = 0;
        i_t[i] = 0;
      }
      score = corner_score(frame_to_filter, ref_frame, x, y, i_x, i_y, i_t, n,
                           bit_depth);
      if (score > threshold * max_score) {
        ref_corners[countcorners * 2] = x;
        ref_corners[countcorners * 2 + 1] = y;
        countcorners++;
      }
    }
  }
  return countcorners;
}

// weights is an nxn matrix. weights is filled with a gaussian function,
// with independent variable: distance from the center point.
static void gaussian(const double sigma, const int n, const int normalize,
                     double *weights) {
  double total_weight = 0;
  for (int j = 0; j < n; j++) {
    for (int i = 0; i < n; i++) {
      double distance = sqrt(pow(n / 2 - i, 2) + pow(n / 2 - j, 2));
      double weight = exp(-0.5 * pow(distance / sigma, 2));
      weights[j * n + i] = weight;
      total_weight += weight;
    }
  }
  if (normalize == 1) {
    for (int j = 0; j < n; j++) {
      weights[j] = weights[j] / total_weight;
    }
  }
}

static double convolve(const double *filter, const int *img, const int size) {
  double result = 0;
  for (int i = 0; i < size; i++) {
    result += filter[i] * img[i];
  }
  return result;
}

// Applies a Gaussian low-pass smoothing filter to produce
// a corresponding lower resolution image with halved dimensions
static void reduce(uint8_t *img, int height, int width, int stride,
                   uint8_t *reduced_img) {
  const int new_width = width / 2;
  const int window_size = 5;
  const double gaussian_filter[25] = {
    1. / 256, 1.0 / 64, 3. / 128, 1. / 64,  1. / 256, 1. / 64, 1. / 16,
    3. / 32,  1. / 16,  1. / 64,  3. / 128, 3. / 32,  9. / 64, 3. / 32,
    3. / 128, 1. / 64,  1. / 16,  3. / 32,  1. / 16,  1. / 64, 1. / 256,
    1. / 64,  3. / 128, 1. / 64,  1. / 256
  };
  // filter is 5x5 so need prev and forward 2 pixels
  int img_section[25];
  for (int y = 0; y < height - 1; y += 2) {
    for (int x = 0; x < width - 1; x += 2) {
      int i = 0;
      for (int yy = y - window_size / 2; yy <= y + window_size / 2; yy++) {
        for (int xx = x - window_size / 2; xx <= x + window_size / 2; xx++) {
          int yvalue = yy;
          int xvalue = xx;
          // copied pixels outside the boundary
          if (yvalue < 0) yvalue = 0;
          if (xvalue < 0) xvalue = 0;
          if (yvalue >= height) yvalue = height - 1;
          if (xvalue >= width) xvalue = width - 1;
          img_section[i++] = img[yvalue * stride + xvalue];
        }
      }
      reduced_img[(y / 2) * new_width + (x / 2)] = (uint8_t)convolve(
          gaussian_filter, img_section, window_size * window_size);
    }
  }
}

static int cmpfunc(const void *a, const void *b) {
  return (*(int *)a - *(int *)b);
}
static void filter_mvs(const MV_FILTER_TYPE mv_filter, const int frame_height,
                       const int frame_width, LOCALMV *localmvs, MV *mvs) {
  const int n = 5;  // window size
  // for smoothing filter
  const double gaussian_filter[25] = {
    1. / 256, 1. / 64,  3. / 128, 1. / 64,  1. / 256, 1. / 64, 1. / 16,
    3. / 32,  1. / 16,  1. / 64,  3. / 128, 3. / 32,  9. / 64, 3. / 32,
    3. / 128, 1. / 64,  1. / 16,  3. / 32,  1. / 16,  1. / 64, 1. / 256,
    1. / 64,  3. / 128, 1. / 64,  1. / 256
  };
  // for median filter
  int mvrows[25];
  int mvcols[25];
  if (mv_filter != MV_FILTER_NONE) {
    for (int y = 0; y < frame_height; y++) {
      for (int x = 0; x < frame_width; x++) {
        int center_idx = y * frame_width + x;
        int i = 0;
        double filtered_row = 0;
        double filtered_col = 0;
        for (int yy = y - n / 2; yy <= y + n / 2; yy++) {
          for (int xx = x - n / 2; xx <= x + n / 2; xx++) {
            int yvalue = yy;
            int xvalue = xx;
            // copied pixels outside the boundary
            if (yvalue < 0) yvalue = 0;
            if (xvalue < 0) xvalue = 0;
            if (yvalue >= frame_height) yvalue = frame_height - 1;
            if (xvalue >= frame_width) xvalue = frame_width - 1;
            int index = yvalue * frame_width + xvalue;
            if (mv_filter == MV_FILTER_SMOOTH) {
              filtered_row += mvs[index].row * gaussian_filter[i];
              filtered_col += mvs[index].col * gaussian_filter[i];
            } else if (mv_filter == MV_FILTER_MEDIAN) {
              mvrows[i] = mvs[index].row;
              mvcols[i] = mvs[index].col;
            }
            i++;
          }
        }

        MV mv = mvs[center_idx];
        if (mv_filter == MV_FILTER_SMOOTH) {
          mv.row = (int16_t)filtered_row;
          mv.col = (int16_t)filtered_col;
        } else if (mv_filter == MV_FILTER_MEDIAN) {
          qsort(mvrows, 25, sizeof(mv.row), cmpfunc);
          qsort(mvcols, 25, sizeof(mv.col), cmpfunc);
          mv.row = mvrows[25 / 2];
          mv.col = mvcols[25 / 2];
        }
        LOCALMV localmv = { .row = ((double)mv.row) / 8,
                            .col = ((double)mv.row) / 8 };
        localmvs[y * frame_width + x] = localmv;
        // if mvs array is immediately updated here, then the result may
        // propagate to other pixels.
      }
    }
    for (int i = 0; i < frame_height * frame_width; i++) {
      MV mv = { .row = (int16_t)round(8 * localmvs[i].row),
                .col = (int16_t)round(8 * localmvs[i].col) };
      mvs[i] = mv;
    }
  }
}

// Computes optical flow at a single pyramid level,
// using Lucas-Kanade algorithm.
// Modifies mvs array.
static void lucas_kanade(const YV12_BUFFER_CONFIG *from_frame,
                         const YV12_BUFFER_CONFIG *to_frame, const int level,
                         const LK_PARAMS *lk_params, const int num_ref_corners,
                         int *ref_corners, const int mv_stride,
                         const int bit_depth, LOCALMV *mvs) {
  assert(lk_params->window_size > 0 && lk_params->window_size % 2 == 0);
  const int n = lk_params->window_size;
  // algorithm is sensitive to window size
  double *i_x = (double *)aom_malloc(n * n * sizeof(*i_x));
  double *i_y = (double *)aom_malloc(n * n * sizeof(*i_y));
  double *i_t = (double *)aom_malloc(n * n * sizeof(*i_t));
  const int expand_multiplier = (int)pow(2, level);
  double sigma = 0.2 * n;
  double *weights = (double *)aom_malloc(n * n * sizeof(*weights));
  // normalizing doesn't really affect anything since it's applied
  // to every component of M and b
  gaussian(sigma, n, 0, weights);
  for (int i = 0; i < num_ref_corners; i++) {
    const double x_coord = 1.0 * ref_corners[i * 2] / expand_multiplier;
    const double y_coord = 1.0 * ref_corners[i * 2 + 1] / expand_multiplier;
    int highres_x = ref_corners[i * 2];
    int highres_y = ref_corners[i * 2 + 1];
    int mv_idx = highres_y * (mv_stride) + highres_x;
    LOCALMV mv_old = mvs[mv_idx];
    mv_old.row = mv_old.row / expand_multiplier;
    mv_old.col = mv_old.col / expand_multiplier;
    // using this instead of memset, since it's not completely
    // clear if zero memset works on double arrays
    for (int j = 0; j < n * n; j++) {
      i_x[j] = 0;
      i_y[j] = 0;
      i_t[j] = 0;
    }
    gradients_over_window(from_frame, to_frame, x_coord, y_coord, n, bit_depth,
                          i_x, i_y, i_t, &mv_old);
    double Mres1[1] = { 0 }, Mres2[1] = { 0 }, Mres3[1] = { 0 };
    double bres1[1] = { 0 }, bres2[1] = { 0 };
    for (int j = 0; j < n * n; j++) {
      Mres1[0] += weights[j] * i_x[j] * i_x[j];
      Mres2[0] += weights[j] * i_x[j] * i_y[j];
      Mres3[0] += weights[j] * i_y[j] * i_y[j];
      bres1[0] += weights[j] * i_x[j] * i_t[j];
      bres2[0] += weights[j] * i_y[j] * i_t[j];
    }
    double M[4] = { Mres1[0], Mres2[0], Mres2[0], Mres3[0] };
    double b[2] = { -1 * bres1[0], -1 * bres2[0] };
    double eig[2] = { 1, 1 };
    eigenvalues_2x2(M, eig);
    double threshold = 0.1;
    if (fabs(eig[0]) > threshold) {
      // if M is not invertible, then displacement
      // will default to zeros
      double u[2] = { 0, 0 };
      linsolve(2, M, 2, b, u);
      int mult = 1;
      if (level != 0)
        mult = expand_multiplier;  // mv doubles when resolution doubles
      LOCALMV mv = { .row = (mult * (u[0] + mv_old.row)),
                     .col = (mult * (u[1] + mv_old.col)) };
      mvs[mv_idx] = mv;
      mvs[mv_idx] = mv;
    }
  }
  aom_free(weights);
  aom_free(i_t);
  aom_free(i_x);
  aom_free(i_y);
}

// Warp the src_frame to warper_frame according to mvs.
// mvs point to src_frame
static void warp_back_frame(YV12_BUFFER_CONFIG *warped_frame,
                            const YV12_BUFFER_CONFIG *src_frame,
                            const LOCALMV *mvs, int mv_stride) {
  int w, h;
  const int fw = src_frame->y_crop_width;
  const int fh = src_frame->y_crop_height;
  const int src_fs = src_frame->y_stride, warped_fs = warped_frame->y_stride;
  const uint8_t *src_buf = src_frame->y_buffer;
  uint8_t *warped_buf = warped_frame->y_buffer;
  double temp;
  for (h = 0; h < fh; h++) {
    for (w = 0; w < fw; w++) {
      double cord_x = (double)w + mvs[h * mv_stride + w].col;
      double cord_y = (double)h + mvs[h * mv_stride + w].row;
      cord_x = fclamp(cord_x, 0, (double)(fw - 1));
      cord_y = fclamp(cord_y, 0, (double)(fh - 1));
      const int floorx = (int)floor(cord_x);
      const int floory = (int)floor(cord_y);
      const double fracx = cord_x - (double)floorx;
      const double fracy = cord_y - (double)floory;

      temp = 0;
      for (int hh = 0; hh < 2; hh++) {
        const double weighth = hh ? (fracy) : (1 - fracy);
        for (int ww = 0; ww < 2; ww++) {
          const double weightw = ww ? (fracx) : (1 - fracx);
          int y = floory + hh;
          int x = floorx + ww;
          y = clamp(y, 0, fh - 1);
          x = clamp(x, 0, fw - 1);
          temp += (double)src_buf[y * src_fs + x] * weightw * weighth;
        }
      }
      warped_buf[h * warped_fs + w] = (uint8_t)round(temp);
    }
  }
}

// Same as warp_back_frame, but using a better interpolation filter.
static void warp_back_frame_intp(YV12_BUFFER_CONFIG *warped_frame,
                                 const YV12_BUFFER_CONFIG *src_frame,
                                 const LOCALMV *mvs, int mv_stride) {
  int w, h;
  const int fw = src_frame->y_crop_width;
  const int fh = src_frame->y_crop_height;
  const int warped_fs = warped_frame->y_stride;
  uint8_t *warped_buf = warped_frame->y_buffer;
  const int blk = 2;
  uint8_t temp_blk[4];

  const int is_intrabc = 0;  // Is intra-copied?
  const int is_high_bitdepth = is_frame_high_bitdepth(src_frame);
  const int subsampling_x = 0, subsampling_y = 0;  // for y-buffer
  const int_interpfilters interp_filters =
      av1_broadcast_interp_filter(MULTITAP_SHARP2);
  const int plane = 0;  // y-plane
  const struct buf_2d ref_buf2 = { NULL, src_frame->y_buffer,
                                   src_frame->y_crop_width,
                                   src_frame->y_crop_height,
                                   src_frame->y_stride };
  const int bit_depth = src_frame->bit_depth;
  struct scale_factors scale;
  av1_setup_scale_factors_for_frame(
      &scale, src_frame->y_crop_width, src_frame->y_crop_height,
      src_frame->y_crop_width, src_frame->y_crop_height);

  for (h = 0; h < fh; h++) {
    for (w = 0; w < fw; w++) {
      InterPredParams inter_pred_params;
      av1_init_inter_params(&inter_pred_params, blk, blk, h, w, subsampling_x,
                            subsampling_y, bit_depth, is_high_bitdepth,
                            is_intrabc, &scale, &ref_buf2, interp_filters);
      inter_pred_params.interp_filter_params[0] =
          &av1_interp_filter_params_list[interp_filters.as_filters.x_filter];
      inter_pred_params.interp_filter_params[1] =
          &av1_interp_filter_params_list[interp_filters.as_filters.y_filter];
      inter_pred_params.conv_params = get_conv_params(0, plane, bit_depth);
      MV newmv = { .row = (int16_t)round((mvs[h * mv_stride + w].row) * 8),
                   .col = (int16_t)round((mvs[h * mv_stride + w].col) * 8) };
      av1_enc_build_one_inter_predictor(temp_blk, blk, &newmv,
                                        &inter_pred_params);
      warped_buf[h * warped_fs + w] = temp_blk[0];
    }
  }
}

#define DERIVATIVE_FILTER_LENGTH 7
double filter[DERIVATIVE_FILTER_LENGTH] = { -1.0 / 60, 9.0 / 60,  -45.0 / 60, 0,
                                            45.0 / 60, -9.0 / 60, 1.0 / 60 };

// Get gradient of the whole frame
static void get_frame_gradients(const YV12_BUFFER_CONFIG *from_frame,
                                const YV12_BUFFER_CONFIG *to_frame, double *ix,
                                double *iy, double *it, int grad_stride) {
  int w, h, k, idx;
  const int fw = from_frame->y_crop_width;
  const int fh = from_frame->y_crop_height;
  const int from_fs = from_frame->y_stride, to_fs = to_frame->y_stride;
  const uint8_t *from_buf = from_frame->y_buffer;
  const uint8_t *to_buf = to_frame->y_buffer;

  const int lh = DERIVATIVE_FILTER_LENGTH;
  const int hleft = (lh - 1) / 2;

  for (h = 0; h < fh; h++) {
    for (w = 0; w < fw; w++) {
      // x
      ix[h * grad_stride + w] = 0;
      for (k = 0; k < lh; k++) {
        // if we want to make this block dependent, need to extend the
        // boundaries using other initializations.
        idx = w + k - hleft;
        idx = clamp(idx, 0, fw - 1);
        ix[h * grad_stride + w] += filter[k] * 0.5 *
                                   ((double)from_buf[h * from_fs + idx] +
                                    (double)to_buf[h * to_fs + idx]);
      }
      // y
      iy[h * grad_stride + w] = 0;
      for (k = 0; k < lh; k++) {
        // if we want to make this block dependent, need to extend the
        // boundaries using other initializations.
        idx = h + k - hleft;
        idx = clamp(idx, 0, fh - 1);
        iy[h * grad_stride + w] += filter[k] * 0.5 *
                                   ((double)from_buf[idx * from_fs + w] +
                                    (double)to_buf[idx * to_fs + w]);
      }
      // t
      it[h * grad_stride + w] =
          (double)to_buf[h * to_fs + w] - (double)from_buf[h * from_fs + w];
    }
  }
}

// Solve for linear equations given by the H-S method
static void solve_horn_schunck(const double *ix, const double *iy,
                               const double *it, int grad_stride, int width,
                               int height, const LOCALMV *init_mvs,
                               int init_mv_stride, LOCALMV *mvs,
                               int mv_stride) {
  // TODO(bohanli): May just need to allocate the buffers once per optical flow
  // calculation
  int *row_pos = aom_calloc(width * height * 28, sizeof(*row_pos));
  int *col_pos = aom_calloc(width * height * 28, sizeof(*col_pos));
  double *values = aom_calloc(width * height * 28, sizeof(*values));
  double *mv_vec = aom_calloc(width * height * 2, sizeof(*mv_vec));
  double *mv_init_vec = aom_calloc(width * height * 2, sizeof(*mv_init_vec));
  double *temp_b = aom_calloc(width * height * 2, sizeof(*temp_b));
  double *b = aom_calloc(width * height * 2, sizeof(*b));

  // the location idx for neighboring pixels, k < 4 are the 4 direct neighbors
  const int check_locs_y[12] = { 0, 0, -1, 1, -1, -1, 1, 1, 0, 0, -2, 2 };
  const int check_locs_x[12] = { -1, 1, 0, 0, -1, 1, -1, 1, -2, 2, 0, 0 };

  int h, w, checkh, checkw, k;
  const int offset = height * width;
  SPARSE_MTX A;
  int c = 0;
  const double lambda = 100;

  for (w = 0; w < width; w++) {
    for (h = 0; h < height; h++) {
      mv_init_vec[w * height + h] = init_mvs[h * init_mv_stride + w].col;
      mv_init_vec[w * height + h + offset] =
          init_mvs[h * init_mv_stride + w].row;
    }
  }

  // get matrix A
  for (w = 0; w < width; w++) {
    for (h = 0; h < height; h++) {
      int center_num_direct = 4;
      const int center_idx = w * height + h;
      if (w == 0 || w == width - 1) center_num_direct--;
      if (h == 0 || h == height - 1) center_num_direct--;
      // diagonal entry for this row from the center pixel
      double cor_w = center_num_direct * center_num_direct + center_num_direct;
      row_pos[c] = center_idx;
      col_pos[c] = center_idx;
      values[c] = lambda * cor_w;
      c++;
      row_pos[c] = center_idx + offset;
      col_pos[c] = center_idx + offset;
      values[c] = lambda * cor_w;
      c++;
      // other entries from direct neighbors
      for (k = 0; k < 4; k++) {
        checkh = h + check_locs_y[k];
        checkw = w + check_locs_x[k];
        if (checkh < 0 || checkh >= height || checkw < 0 || checkw >= width) {
          continue;
        }
        int this_idx = checkw * height + checkh;
        int this_num_direct = 4;
        if (checkw == 0 || checkw == width - 1) this_num_direct--;
        if (checkh == 0 || checkh == height - 1) this_num_direct--;
        cor_w = -center_num_direct - this_num_direct;
        row_pos[c] = center_idx;
        col_pos[c] = this_idx;
        values[c] = lambda * cor_w;
        c++;
        row_pos[c] = center_idx + offset;
        col_pos[c] = this_idx + offset;
        values[c] = lambda * cor_w;
        c++;
      }
      // entries from neighbors on the diagonal corners
      for (k = 4; k < 8; k++) {
        checkh = h + check_locs_y[k];
        checkw = w + check_locs_x[k];
        if (checkh < 0 || checkh >= height || checkw < 0 || checkw >= width) {
          continue;
        }
        int this_idx = checkw * height + checkh;
        cor_w = 2;
        row_pos[c] = center_idx;
        col_pos[c] = this_idx;
        values[c] = lambda * cor_w;
        c++;
        row_pos[c] = center_idx + offset;
        col_pos[c] = this_idx + offset;
        values[c] = lambda * cor_w;
        c++;
      }
      // entries from neighbors with dist of 2
      for (k = 8; k < 12; k++) {
        checkh = h + check_locs_y[k];
        checkw = w + check_locs_x[k];
        if (checkh < 0 || checkh >= height || checkw < 0 || checkw >= width) {
          continue;
        }
        int this_idx = checkw * height + checkh;
        cor_w = 1;
        row_pos[c] = center_idx;
        col_pos[c] = this_idx;
        values[c] = lambda * cor_w;
        c++;
        row_pos[c] = center_idx + offset;
        col_pos[c] = this_idx + offset;
        values[c] = lambda * cor_w;
        c++;
      }
    }
  }
  av1_init_sparse_mtx(row_pos, col_pos, values, c, 2 * width * height,
                      2 * width * height, &A);
  // subtract init mv part from b
  av1_mtx_vect_multi_left(&A, mv_init_vec, temp_b, 2 * width * height);
  for (int i = 0; i < 2 * width * height; i++) {
    b[i] = -temp_b[i];
  }
  av1_free_sparse_mtx_elems(&A);

  // add cross terms to A and modify b with ExEt / EyEt
  for (w = 0; w < width; w++) {
    for (h = 0; h < height; h++) {
      int curidx = w * height + h;
      // modify b
      b[curidx] += -ix[h * grad_stride + w] * it[h * grad_stride + w];
      b[curidx + offset] += -iy[h * grad_stride + w] * it[h * grad_stride + w];
      // add cross terms to A
      row_pos[c] = curidx;
      col_pos[c] = curidx + offset;
      values[c] = ix[h * grad_stride + w] * iy[h * grad_stride + w];
      c++;
      row_pos[c] = curidx + offset;
      col_pos[c] = curidx;
      values[c] = ix[h * grad_stride + w] * iy[h * grad_stride + w];
      c++;
    }
  }
  // Add diagonal terms to A
  for (int i = 0; i < c; i++) {
    if (row_pos[i] == col_pos[i]) {
      if (row_pos[i] < offset) {
        w = row_pos[i] / height;
        h = row_pos[i] % height;
        values[i] += pow(ix[h * grad_stride + w], 2);
      } else {
        w = (row_pos[i] - offset) / height;
        h = (row_pos[i] - offset) % height;
        values[i] += pow(iy[h * grad_stride + w], 2);
      }
    }
  }

  av1_init_sparse_mtx(row_pos, col_pos, values, c, 2 * width * height,
                      2 * width * height, &A);

  // solve for the mvs
  av1_conjugate_gradient_sparse(&A, b, 2 * width * height, mv_vec);
  // copy mvs
  for (w = 0; w < width; w++) {
    for (h = 0; h < height; h++) {
      mvs[h * mv_stride + w].col = mv_vec[w * height + h];
      mvs[h * mv_stride + w].row = mv_vec[w * height + h + offset];
    }
  }
  aom_free(row_pos);
  aom_free(col_pos);
  aom_free(values);
  aom_free(mv_vec);
  aom_free(mv_init_vec);
  aom_free(b);
  aom_free(temp_b);
  av1_free_sparse_mtx_elems(&A);
}

// Calculate optical flow from from_frame to to_frame using the H-S method.
static void horn_schunck(const YV12_BUFFER_CONFIG *from_frame,
                         const YV12_BUFFER_CONFIG *to_frame, const int level,
                         const int mv_stride, const int mv_height,
                         const int mv_width, const OPFL_PARAMS *opfl_params,
                         LOCALMV *mvs) {
  // mvs are always on level 0, here we define two new mv arrays that is of size
  // of this level.
  const int fw = from_frame->y_crop_width;
  const int fh = from_frame->y_crop_height;
  const int factor = (int)pow(2, level);
  int w, h, k, init_mv_stride;
  LOCALMV *init_mvs;
  if (level == 0) {
    init_mvs = mvs;
    init_mv_stride = mv_stride;
  } else {
    init_mvs = aom_calloc(fw * fh, sizeof(*mvs));
    init_mv_stride = fw;
    for (h = 0; h < fh; h++) {
      for (w = 0; w < fw; w++) {
        init_mvs[h * init_mv_stride + w].row =
            mvs[h * factor * mv_stride + w * factor].row / (double)factor;
        init_mvs[h * init_mv_stride + w].col =
            mvs[h * factor * mv_stride + w * factor].col / (double)factor;
      }
    }
  }
  LOCALMV *refine_mvs = aom_calloc(fw * fh, sizeof(*mvs));
  // temp frame for warping
  YV12_BUFFER_CONFIG temp_frame;
  temp_frame.y_buffer =
      (uint8_t *)aom_calloc(fh * fw, sizeof(*temp_frame.y_buffer));
  temp_frame.y_crop_height = fh;
  temp_frame.y_crop_width = fw;
  temp_frame.y_stride = fw;
  // gradient buffers
  double *ix = aom_calloc(fw * fh, sizeof(*ix));
  double *iy = aom_calloc(fw * fh, sizeof(*iy));
  double *it = aom_calloc(fw * fh, sizeof(*it));
  // For each warping step
  for (k = 0; k < opfl_params->warping_steps; k++) {
    // warp from_frame with init_mv
    if (level == 0) {
      warp_back_frame_intp(&temp_frame, to_frame, init_mvs, init_mv_stride);
    } else {
      warp_back_frame(&temp_frame, to_frame, init_mvs, init_mv_stride);
    }
    // calculate frame gradients
    get_frame_gradients(from_frame, &temp_frame, ix, iy, it, fw);
    // form linear equations and solve mvs
    solve_horn_schunck(ix, iy, it, fw, fw, fh, init_mvs, init_mv_stride,
                       refine_mvs, fw);
    // update init_mvs
    for (h = 0; h < fh; h++) {
      for (w = 0; w < fw; w++) {
        init_mvs[h * init_mv_stride + w].col += refine_mvs[h * fw + w].col;
        init_mvs[h * init_mv_stride + w].row += refine_mvs[h * fw + w].row;
      }
    }
  }
  // copy back the mvs if needed
  if (level != 0) {
    for (h = 0; h < mv_height; h++) {
      for (w = 0; w < mv_width; w++) {
        mvs[h * mv_stride + w].row =
            init_mvs[h / factor * init_mv_stride + w / factor].row *
            (double)factor;
        mvs[h * mv_stride + w].col =
            init_mvs[h / factor * init_mv_stride + w / factor].col *
            (double)factor;
      }
    }
  }
  if (level != 0) aom_free(init_mvs);
  aom_free(refine_mvs);
  aom_free(temp_frame.y_buffer);
  aom_free(ix);
  aom_free(iy);
  aom_free(it);
}

// Apply optical flow iteratively at each pyramid level
static void pyramid_optical_flow(const YV12_BUFFER_CONFIG *from_frame,
                                 const YV12_BUFFER_CONFIG *to_frame,
                                 const int bit_depth,
                                 const OPFL_PARAMS *opfl_params,
                                 const OPTFLOW_METHOD method, LOCALMV *mvs) {
  assert(opfl_params->pyramid_levels > 0 &&
         opfl_params->pyramid_levels <= MAX_PYRAMID_LEVELS);
  int levels = opfl_params->pyramid_levels;
  const int frame_height = from_frame->y_crop_height;
  const int frame_width = from_frame->y_crop_width;
  if ((frame_height / pow(2.0, levels - 1) < 50 ||
       frame_height / pow(2.0, levels - 1) < 50) &&
      levels > 1)
    levels = levels - 1;
  uint8_t *images1[MAX_PYRAMID_LEVELS];
  uint8_t *images2[MAX_PYRAMID_LEVELS];
  images1[0] = from_frame->y_buffer;
  images2[0] = to_frame->y_buffer;
  YV12_BUFFER_CONFIG *buffers1 = aom_malloc(levels * sizeof(*buffers1));
  YV12_BUFFER_CONFIG *buffers2 = aom_malloc(levels * sizeof(*buffers2));
  buffers1[0] = *from_frame;
  buffers2[0] = *to_frame;
  int fw = frame_width;
  int fh = frame_height;
  for (int i = 1; i < levels; i++) {
    // TODO(bohanli): may need to extend buffers for better interpolation SIMD
    images1[i] = (uint8_t *)aom_calloc(fh / 2 * fw / 2, sizeof(*images1[i]));
    images2[i] = (uint8_t *)aom_calloc(fh / 2 * fw / 2, sizeof(*images2[i]));
    int stride;
    if (i == 1)
      stride = from_frame->y_stride;
    else
      stride = fw;
    reduce(images1[i - 1], fh, fw, stride, images1[i]);
    reduce(images2[i - 1], fh, fw, stride, images2[i]);
    fh /= 2;
    fw /= 2;
    YV12_BUFFER_CONFIG a = { .y_buffer = images1[i],
                             .y_crop_width = fw,
                             .y_crop_height = fh,
                             .y_stride = fw };
    YV12_BUFFER_CONFIG b = { .y_buffer = images2[i],
                             .y_crop_width = fw,
                             .y_crop_height = fh,
                             .y_stride = fw };
    buffers1[i] = a;
    buffers2[i] = b;
  }
  // Compute corners for specific frame
  int *ref_corners = NULL;
  int num_ref_corners = 0;
  if (is_sparse(opfl_params)) {
    int maxcorners = from_frame->y_crop_width * from_frame->y_crop_height;
    ref_corners = aom_malloc(maxcorners * 2 * sizeof(*ref_corners));
    num_ref_corners = detect_corners(from_frame, to_frame, maxcorners,
                                     ref_corners, bit_depth);
  }
  const int stop_level = 0;
  for (int i = levels - 1; i >= stop_level; i--) {
    if (method == LUCAS_KANADE) {
      assert(is_sparse(opfl_params));
      lucas_kanade(&buffers1[i], &buffers2[i], i, opfl_params->lk_params,
                   num_ref_corners, ref_corners, buffers1[0].y_crop_width,
                   bit_depth, mvs);
    } else if (method == HORN_SCHUNCK) {
      assert(!is_sparse(opfl_params));
      horn_schunck(&buffers1[i], &buffers2[i], i, buffers1[0].y_crop_width,
                   buffers1[0].y_crop_height, buffers1[0].y_crop_width,
                   opfl_params, mvs);
    }
  }
  for (int i = 1; i < levels; i++) {
    aom_free(images1[i]);
    aom_free(images2[i]);
  }
  aom_free(ref_corners);
  aom_free(buffers1);
  aom_free(buffers2);
}
// Computes optical flow by applying algorithm at
// multiple pyramid levels of images (lower-resolution, smoothed images)
// This accounts for larger motions.
// Inputs:
//   from_frame Frame buffer.
//   to_frame: Frame buffer. MVs point from_frame -> to_frame.
//   from_frame_idx: Index of from_frame.
//   to_frame_idx: Index of to_frame. Return all zero MVs when idx are equal.
//   bit_depth:
//   opfl_params: contains algorithm-specific parameters.
//   mv_filter: MV_FILTER_NONE, MV_FILTER_SMOOTH, or MV_FILTER_MEDIAN.
//   method: LUCAS_KANADE, HORN_SCHUNCK
//   mvs: pointer to MVs. Contains initialization, and modified
//   based on optical flow. Must have
//   dimensions = from_frame->y_crop_width * from_frame->y_crop_height
void av1_optical_flow(const YV12_BUFFER_CONFIG *from_frame,
                      const YV12_BUFFER_CONFIG *to_frame,
                      const int from_frame_idx, const int to_frame_idx,
                      const int bit_depth, const OPFL_PARAMS *opfl_params,
                      const MV_FILTER_TYPE mv_filter,
                      const OPTFLOW_METHOD method, MV *mvs) {
  const int frame_height = from_frame->y_crop_height;
  const int frame_width = from_frame->y_crop_width;
  // TODO(any): deal with the case where frames are not of the same dimensions
  assert(frame_height == to_frame->y_crop_height &&
         frame_width == to_frame->y_crop_width);
  if (from_frame_idx == to_frame_idx) {
    // immediately return all zero mvs when frame indices are equal
    for (int yy = 0; yy < frame_height; yy++) {
      for (int xx = 0; xx < frame_width; xx++) {
        MV mv = { .row = 0, .col = 0 };
        mvs[yy * frame_width + xx] = mv;
      }
    }
    return;
  }

  // Initialize double mvs based on input parameter mvs array
  LOCALMV *localmvs =
      aom_malloc(frame_height * frame_width * sizeof(*localmvs));

  filter_mvs(MV_FILTER_SMOOTH, frame_height, frame_width, localmvs, mvs);

  for (int i = 0; i < frame_width * frame_height; i++) {
    MV mv = mvs[i];
    LOCALMV localmv = { .row = ((double)mv.row) / 8,
                        .col = ((double)mv.col) / 8 };
    localmvs[i] = localmv;
  }
  // Apply optical flow algorithm
  pyramid_optical_flow(from_frame, to_frame, bit_depth, opfl_params, method,
                       localmvs);

  // Update original mvs array
  for (int j = 0; j < frame_height; j++) {
    for (int i = 0; i < frame_width; i++) {
      int idx = j * frame_width + i;
      if (j + localmvs[idx].row < 0 || j + localmvs[idx].row >= frame_height ||
          i + localmvs[idx].col < 0 || i + localmvs[idx].col >= frame_width) {
        continue;
      }
      MV mv = { .row = (int16_t)round(8 * localmvs[idx].row),
                .col = (int16_t)round(8 * localmvs[idx].col) };
      mvs[idx] = mv;
    }
  }

  filter_mvs(mv_filter, frame_height, frame_width, localmvs, mvs);

  aom_free(localmvs);
}
#endif
