/*
 * 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);
  // substract 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.
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
