/*
 * Copyright (c) 2022, 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 "aom_dsp/pyramid.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/bitops.h"
#include "aom_util/aom_thread.h"

// TODO(rachelbarker): Move needed code from av1/ to aom_dsp/
#include "av1/common/resize.h"

#include <assert.h>
#include <string.h>

// Lifecycle:
// * Frame buffer alloc code calls aom_get_pyramid_alloc_size()
//   to work out how much space is needed for a given number of pyramid
//   levels. This is counted in the size checked against the max allocation
//   limit
// * Then calls aom_alloc_pyramid() to actually create the pyramid
// * Pyramid is initially marked as invalid (no data)
// * Whenever pyramid is needed, we check the valid flag. If set, use existing
//   data. If not set, compute full pyramid
// * Whenever frame buffer is reused, clear the valid flag
// * Whenever frame buffer is resized, reallocate pyramid

size_t aom_get_pyramid_alloc_size(int width, int height, int n_levels) {
  // Limit number of levels on small frames
  const int msb = get_msb(AOMMIN(width, height));
  const int max_levels = AOMMAX(msb - MIN_PYRAMID_SIZE_LOG2, 1);
  n_levels = AOMMIN(n_levels, max_levels);

  size_t alloc_size = 0;
  alloc_size += sizeof(ImagePyramid);
  alloc_size += n_levels * sizeof(PyramidLayer);

  // Calculate how much memory is needed for downscaled frame buffers
  size_t buffer_size = 0;

  // Work out if we need to allocate a few extra bytes for alignment.
  // aom_memalign() will ensure that the start of the allocation is aligned
  // to a multiple of PYRAMID_ALIGNMENT. But we want the first image pixel
  // to be aligned, not the first byte of the allocation.
  //
  // In the loop below, we ensure that the stride of every image is a multiple
  // of PYRAMID_ALIGNMENT. Thus the allocated size of each pyramid level will
  // also be a multiple of PYRAMID_ALIGNMENT. Thus, as long as we can get the
  // first pixel in the first pyramid layer aligned properly, that will
  // automatically mean that the first pixel of every row of every layer is
  // properly aligned too.
  //
  // Thus all we need to consider is the first pixel in the first layer.
  // This is located at offset
  //   extra_bytes + level_stride * PYRAMID_PADDING + PYRAMID_PADDING
  // bytes into the buffer. Since level_stride is a multiple of
  // PYRAMID_ALIGNMENT, we can ignore that. So we need
  //   extra_bytes + PYRAMID_PADDING = multiple of PYRAMID_ALIGNMENT
  //
  // To solve this, we can round PYRAMID_PADDING up to the next multiple
  // of PYRAMID_ALIGNMENT, then subtract the orginal value to calculate
  // how many extra bytes are needed.
  size_t first_px_offset =
      (PYRAMID_PADDING + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);
  size_t extra_bytes = first_px_offset - PYRAMID_PADDING;
  buffer_size += extra_bytes;

  for (int level = 0; level < n_levels; level++) {
    int level_width = width >> level;
    int level_height = height >> level;

    // Allocate padding for each layer
    int padded_width = level_width + 2 * PYRAMID_PADDING;
    int padded_height = level_height + 2 * PYRAMID_PADDING;

    // Align the layer stride to be a multiple of PYRAMID_ALIGNMENT
    // This ensures that, as long as the top-left pixel in this pyramid level is
    // properly aligned, then so will the leftmost pixel in every row of the
    // pyramid level.
    int level_stride =
        (padded_width + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);

    buffer_size += level_stride * padded_height;
  }

  alloc_size += buffer_size;

  return alloc_size;
}

ImagePyramid *aom_alloc_pyramid(int width, int height, int n_levels) {
  // Limit number of levels on small frames
  const int msb = get_msb(AOMMIN(width, height));
  const int max_levels = AOMMAX(msb - MIN_PYRAMID_SIZE_LOG2, 1);
  n_levels = AOMMIN(n_levels, max_levels);

  ImagePyramid *pyr = aom_calloc(1, sizeof(*pyr));
  if (!pyr) {
    return NULL;
  }

  pyr->layers = aom_calloc(n_levels, sizeof(PyramidLayer));
  if (!pyr->layers) {
    aom_free(pyr);
    return NULL;
  }

  pyr->valid = false;
  pyr->n_levels = n_levels;

  // Compute sizes and offsets for each pyramid level
  // These are gathered up first, so that we can allocate all pyramid levels
  // in a single buffer
  size_t buffer_size = 0;
  size_t *layer_offsets = aom_calloc(n_levels, sizeof(size_t));
  if (!layer_offsets) {
    aom_free(pyr);
    aom_free(pyr->layers);
    return NULL;
  }

  // Work out if we need to allocate a few extra bytes for alignment.
  // aom_memalign() will ensure that the start of the allocation is aligned
  // to a multiple of PYRAMID_ALIGNMENT. But we want the first image pixel
  // to be aligned, not the first byte of the allocation.
  //
  // In the loop below, we ensure that the stride of every image is a multiple
  // of PYRAMID_ALIGNMENT. Thus the allocated size of each pyramid level will
  // also be a multiple of PYRAMID_ALIGNMENT. Thus, as long as we can get the
  // first pixel in the first pyramid layer aligned properly, that will
  // automatically mean that the first pixel of every row of every layer is
  // properly aligned too.
  //
  // Thus all we need to consider is the first pixel in the first layer.
  // This is located at offset
  //   extra_bytes + level_stride * PYRAMID_PADDING + PYRAMID_PADDING
  // bytes into the buffer. Since level_stride is a multiple of
  // PYRAMID_ALIGNMENT, we can ignore that. So we need
  //   extra_bytes + PYRAMID_PADDING = multiple of PYRAMID_ALIGNMENT
  //
  // To solve this, we can round PYRAMID_PADDING up to the next multiple
  // of PYRAMID_ALIGNMENT, then subtract the orginal value to calculate
  // how many extra bytes are needed.
  size_t first_px_offset =
      (PYRAMID_PADDING + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);
  size_t extra_bytes = first_px_offset - PYRAMID_PADDING;
  buffer_size += extra_bytes;

  for (int level = 0; level < n_levels; level++) {
    PyramidLayer *layer = &pyr->layers[level];

    int level_width = width >> level;
    int level_height = height >> level;

    // Allocate padding for each layer
    int padded_width = level_width + 2 * PYRAMID_PADDING;
    int padded_height = level_height + 2 * PYRAMID_PADDING;

    // Align the layer stride to be a multiple of PYRAMID_ALIGNMENT
    // This ensures that, as long as the top-left pixel in this pyramid level is
    // properly aligned, then so will the leftmost pixel in every row of the
    // pyramid level.
    int level_stride =
        (padded_width + PYRAMID_ALIGNMENT - 1) & ~(PYRAMID_ALIGNMENT - 1);

    size_t level_alloc_start = buffer_size;
    size_t level_start =
        level_alloc_start + PYRAMID_PADDING * level_stride + PYRAMID_PADDING;

    buffer_size += level_stride * padded_height;

    layer_offsets[level] = level_start;
    layer->width = level_width;
    layer->height = level_height;
    layer->stride = level_stride;
  }

  pyr->buffer_alloc =
      aom_memalign(PYRAMID_ALIGNMENT, buffer_size * sizeof(*pyr->buffer_alloc));
  if (!pyr->buffer_alloc) {
    aom_free(pyr);
    aom_free(pyr->layers);
    aom_free(layer_offsets);
    return NULL;
  }

  // Fill in pointers for each level
  for (int level = 0; level < n_levels; level++) {
    PyramidLayer *layer = &pyr->layers[level];
    layer->buffer = pyr->buffer_alloc + layer_offsets[level];
  }

#if CONFIG_MULTITHREAD
  pthread_mutex_init(&pyr->mutex, NULL);
#endif  // CONFIG_MULTITHREAD

  aom_free(layer_offsets);
  return pyr;
}

// Fill the border region of a pyramid frame.
// This must be called after the main image area is filled out.
// `img_buf` should point to the first pixel in the image area,
// ie. it should be pyr->level_buffer + pyr->level_loc[level].
static INLINE void fill_border(uint8_t *img_buf, const int width,
                               const int height, const int stride) {
  // Fill left and right areas
  for (int row = 0; row < height; row++) {
    uint8_t *row_start = &img_buf[row * stride];
    uint8_t left_pixel = row_start[0];
    memset(row_start - PYRAMID_PADDING, left_pixel, PYRAMID_PADDING);
    uint8_t right_pixel = row_start[width - 1];
    memset(row_start + width, right_pixel, PYRAMID_PADDING);
  }

  // Fill top area
  for (int row = -PYRAMID_PADDING; row < 0; row++) {
    uint8_t *row_start = &img_buf[row * stride];
    memcpy(row_start - PYRAMID_PADDING, img_buf - PYRAMID_PADDING,
           width + 2 * PYRAMID_PADDING);
  }

  // Fill bottom area
  uint8_t *last_row_start = &img_buf[(height - 1) * stride];
  for (int row = height; row < height + PYRAMID_PADDING; row++) {
    uint8_t *row_start = &img_buf[row * stride];
    memcpy(row_start - PYRAMID_PADDING, last_row_start - PYRAMID_PADDING,
           width + 2 * PYRAMID_PADDING);
  }
}

// Compute coarse to fine pyramids for a frame
// This must only be called while holding frame_pyr->mutex
static INLINE void fill_pyramid(const YV12_BUFFER_CONFIG *frame, int bit_depth,
                                ImagePyramid *frame_pyr) {
  int n_levels = frame_pyr->n_levels;
  const int frame_width = frame->y_crop_width;
  const int frame_height = frame->y_crop_height;
  const int frame_stride = frame->y_stride;
  assert((frame_width >> n_levels) >= 0);
  assert((frame_height >> n_levels) >= 0);

  // Downconvert to 8 bits
  PyramidLayer *first_layer = &frame_pyr->layers[0];
  assert(first_layer->width == frame_width);
  assert(first_layer->height == frame_height);

  uint16_t *frame_buffer = frame->y_buffer;
  uint8_t *pyr_buffer = first_layer->buffer;
  int pyr_stride = first_layer->stride;
  for (int y = 0; y < frame_height; y++) {
    uint16_t *frame_row = frame_buffer + y * frame_stride;
    uint8_t *pyr_row = pyr_buffer + y * pyr_stride;
    for (int x = 0; x < frame_width; x++) {
      pyr_row[x] = frame_row[x] >> (bit_depth - 8);
    }
  }

  fill_border(pyr_buffer, frame_width, frame_height, pyr_stride);

  // Fill in the remaining levels through progressive downsampling
  for (int level = 1; level < n_levels; ++level) {
    PyramidLayer *prev_layer = &frame_pyr->layers[level - 1];
    uint8_t *prev_buffer = prev_layer->buffer;
    int prev_stride = prev_layer->stride;

    PyramidLayer *this_layer = &frame_pyr->layers[level];
    uint8_t *this_buffer = this_layer->buffer;
    int this_width = this_layer->width;
    int this_height = this_layer->height;
    int this_stride = this_layer->stride;

    // Compute the this pyramid level by downsampling the current level.
    //
    // We downsample by a factor of exactly 2, clipping the rightmost and
    // bottommost pixel off of the current level if needed. We do this for
    // two main reasons:
    //
    // 1) In the disflow code, when stepping from a higher pyramid level to a
    //    lower pyramid level, we need to not just interpolate the flow field
    //    but also to scale each flow vector by the upsampling ratio.
    //    So it is much more convenient if this ratio is simply 2.
    //
    // 2) Up/downsampling by a factor of 2 can be implemented much more
    //    efficiently than up/downsampling by a generic ratio.
    //    TODO(rachelbarker): Use optimized downsample-by-2 function
    av1_resize_plane(prev_buffer, this_height << 1, this_width << 1,
                     prev_stride, this_buffer, this_height, this_width,
                     this_stride);
    fill_border(this_buffer, this_width, this_height, this_stride);
  }
}

// Fill out a downsampling pyramid for a given frame.
//
// The top level (index 0) will always be an 8-bit copy of the input frame,
// regardless of the input bit depth. Additional levels are then downscaled
// by powers of 2.
//
// For small input frames, the number of levels actually constructed
// will be limited so that the smallest image is at least MIN_PYRAMID_SIZE
// pixels along each side.
//
// However, if the input frame has a side of length < MIN_PYRAMID_SIZE,
// we will still construct the top level.
void aom_compute_pyramid(const YV12_BUFFER_CONFIG *frame, int bit_depth,
                         ImagePyramid *pyr) {
  assert(pyr);

  // Per the comments in the ImagePyramid struct, we must take this mutex
  // before reading or writing the "valid" flag, and hold it while computing
  // the pyramid, to ensure proper behaviour if multiple threads call this
  // function simultaneously
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD

  if (!pyr->valid) {
    fill_pyramid(frame, bit_depth, pyr);
    pyr->valid = true;
  }

  // At this point, the pyramid is guaranteed to be valid, and can be safely
  // read from without holding the mutex any more

#if CONFIG_MULTITHREAD
  pthread_mutex_unlock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
}

#ifndef NDEBUG
// Check if a pyramid has already been computed.
// This is mostly a debug helper - as it is necessary to hold pyr->mutex
// while reading the valid flag, we cannot just write:
//   assert(pyr->valid);
// This function allows the check to be correctly written as:
//   assert(aom_is_pyramid_valid(pyr));
bool aom_is_pyramid_valid(ImagePyramid *pyr) {
  assert(pyr);

  // Per the comments in the ImagePyramid struct, we must take this mutex
  // before reading or writing the "valid" flag, and hold it while computing
  // the pyramid, to ensure proper behaviour if multiple threads call this
  // function simultaneously
#if CONFIG_MULTITHREAD
  pthread_mutex_lock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD

  bool valid = pyr->valid;

#if CONFIG_MULTITHREAD
  pthread_mutex_unlock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD

  return valid;
}
#endif

// Mark a pyramid as no longer containing valid data.
// This must be done whenever the corresponding frame buffer is reused
void aom_invalidate_pyramid(ImagePyramid *pyr) {
  if (pyr) {
#if CONFIG_MULTITHREAD
    pthread_mutex_lock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
    pyr->valid = false;
#if CONFIG_MULTITHREAD
    pthread_mutex_unlock(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
  }
}

// Release the memory associated with a pyramid
void aom_free_pyramid(ImagePyramid *pyr) {
  if (pyr) {
#if CONFIG_MULTITHREAD
    pthread_mutex_destroy(&pyr->mutex);
#endif  // CONFIG_MULTITHREAD
    aom_free(pyr->buffer_alloc);
    aom_free(pyr->layers);
    aom_free(pyr);
  }
}
