chromium/third_party/libaom/source/libaom/av1/common/restoration.c

/*
 * 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 <stddef.h>

#include "config/aom_config.h"
#include "config/aom_scale_rtcd.h"

#include "aom/internal/aom_codec_internal.h"
#include "aom_mem/aom_mem.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/mem.h"
#include "aom_util/aom_pthread.h"

#include "av1/common/av1_common_int.h"
#include "av1/common/convolve.h"
#include "av1/common/enums.h"
#include "av1/common/resize.h"
#include "av1/common/restoration.h"
#include "av1/common/thread_common.h"

// The 's' values are calculated based on original 'r' and 'e' values in the
// spec using GenSgrprojVtable().
// Note: Setting r = 0 skips the filter; with corresponding s = -1 (invalid).
const sgr_params_type av1_sgr_params[SGRPROJ_PARAMS] =;

void av1_get_upsampled_plane_size(const AV1_COMMON *cm, int is_uv, int *plane_w,
                                  int *plane_h) {}

// Count horizontal or vertical units in a plane (use a width or height for
// plane_size, respectively). We basically want to divide the plane size by the
// size of a restoration unit. Rather than rounding up unconditionally as you
// might expect, we round to nearest, which models the way a right or bottom
// restoration unit can extend to up to 150% its normal width or height.
//
// The max with 1 is to deal with small frames, which may be smaller than
// half of an LR unit in size.
int av1_lr_count_units(int unit_size, int plane_size) {}

void av1_alloc_restoration_struct(AV1_COMMON *cm, RestorationInfo *rsi,
                                  int is_uv) {}

void av1_free_restoration_struct(RestorationInfo *rst_info) {}

#if 0
// Pair of values for each sgrproj parameter:
// Index 0 corresponds to r[0], e[0]
// Index 1 corresponds to r[1], e[1]
int sgrproj_mtable[SGRPROJ_PARAMS][2];

static void GenSgrprojVtable(void) {
  for (int i = 0; i < SGRPROJ_PARAMS; ++i) {
    const sgr_params_type *const params = &av1_sgr_params[i];
    for (int j = 0; j < 2; ++j) {
      const int e = params->e[j];
      const int r = params->r[j];
      if (r == 0) {                 // filter is disabled
        sgrproj_mtable[i][j] = -1;  // mark invalid
      } else {                      // filter is enabled
        const int n = (2 * r + 1) * (2 * r + 1);
        const int n2e = n * n * e;
        assert(n2e != 0);
        sgrproj_mtable[i][j] = (((1 << SGRPROJ_MTABLE_BITS) + n2e / 2) / n2e);
      }
    }
  }
}
#endif

void av1_loop_restoration_precal(void) {}

static void extend_frame_lowbd(uint8_t *data, int width, int height,
                               ptrdiff_t stride, int border_horz,
                               int border_vert) {}

#if CONFIG_AV1_HIGHBITDEPTH
static void extend_frame_highbd(uint16_t *data, int width, int height,
                                ptrdiff_t stride, int border_horz,
                                int border_vert) {
  uint16_t *data_p;
  int i, j;
  for (i = 0; i < height; ++i) {
    data_p = data + i * stride;
    for (j = -border_horz; j < 0; ++j) data_p[j] = data_p[0];
    for (j = width; j < width + border_horz; ++j) data_p[j] = data_p[width - 1];
  }
  data_p = data - border_horz;
  for (i = -border_vert; i < 0; ++i) {
    memcpy(data_p + i * stride, data_p,
           (width + 2 * border_horz) * sizeof(uint16_t));
  }
  for (i = height; i < height + border_vert; ++i) {
    memcpy(data_p + i * stride, data_p + (height - 1) * stride,
           (width + 2 * border_horz) * sizeof(uint16_t));
  }
}

static void copy_rest_unit_highbd(int width, int height, const uint16_t *src,
                                  int src_stride, uint16_t *dst,
                                  int dst_stride) {
  for (int i = 0; i < height; ++i)
    memcpy(dst + i * dst_stride, src + i * src_stride, width * sizeof(*dst));
}
#endif

void av1_extend_frame(uint8_t *data, int width, int height, int stride,
                      int border_horz, int border_vert, int highbd) {}

static void copy_rest_unit_lowbd(int width, int height, const uint8_t *src,
                                 int src_stride, uint8_t *dst, int dst_stride) {}

static void copy_rest_unit(int width, int height, const uint8_t *src,
                           int src_stride, uint8_t *dst, int dst_stride,
                           int highbd) {}

#define REAL_PTR(hbd, d)

// With striped loop restoration, the filtering for each 64-pixel stripe gets
// most of its input from the output of CDEF (stored in data8), but we need to
// fill out a border of 3 pixels above/below the stripe according to the
// following rules:
//
// * At the top and bottom of the frame, we copy the outermost row of CDEF
//   pixels three times. This extension is done by a call to av1_extend_frame()
//   at the start of the loop restoration process, so the value of
//   copy_above/copy_below doesn't strictly matter.
//
// * All other boundaries are stripe boundaries within the frame. In that case,
//   we take 2 rows of deblocked pixels and extend them to 3 rows of context.
static void get_stripe_boundary_info(const RestorationTileLimits *limits,
                                     int plane_w, int plane_h, int ss_y,
                                     int *copy_above, int *copy_below) {}

// Overwrite the border pixels around a processing stripe so that the conditions
// listed above get_stripe_boundary_info() are preserved.
// We save the pixels which get overwritten into a temporary buffer, so that
// they can be restored by restore_processing_stripe_boundary() after we've
// processed the stripe.
//
// limits gives the rectangular limits of the remaining stripes for the current
// restoration unit. rsb is the stored stripe boundaries (taken from either
// deblock or CDEF output as necessary).
static void setup_processing_stripe_boundary(
    const RestorationTileLimits *limits, const RestorationStripeBoundaries *rsb,
    int rsb_row, int use_highbd, int h, uint8_t *data8, int data_stride,
    RestorationLineBuffers *rlbs, int copy_above, int copy_below, int opt) {}

// Once a processing stripe is finished, this function sets the boundary
// pixels which were overwritten by setup_processing_stripe_boundary()
// back to their original values
static void restore_processing_stripe_boundary(
    const RestorationTileLimits *limits, const RestorationLineBuffers *rlbs,
    int use_highbd, int h, uint8_t *data8, int data_stride, int copy_above,
    int copy_below, int opt) {}

static void wiener_filter_stripe(const RestorationUnitInfo *rui,
                                 int stripe_width, int stripe_height,
                                 int procunit_width, const uint8_t *src,
                                 int src_stride, uint8_t *dst, int dst_stride,
                                 int32_t *tmpbuf, int bit_depth,
                                 struct aom_internal_error_info *error_info) {}

/* Calculate windowed sums (if sqr=0) or sums of squares (if sqr=1)
   over the input. The window is of size (2r + 1)x(2r + 1), and we
   specialize to r = 1, 2, 3. A default function is used for r > 3.

   Each loop follows the same format: We keep a window's worth of input
   in individual variables and select data out of that as appropriate.
*/
static void boxsum1(int32_t *src, int width, int height, int src_stride,
                    int sqr, int32_t *dst, int dst_stride) {}

static void boxsum2(int32_t *src, int width, int height, int src_stride,
                    int sqr, int32_t *dst, int dst_stride) {}

static void boxsum(int32_t *src, int width, int height, int src_stride, int r,
                   int sqr, int32_t *dst, int dst_stride) {}

void av1_decode_xq(const int *xqd, int *xq, const sgr_params_type *params) {}

const int32_t av1_x_by_xplus1[256] =;

const int32_t av1_one_by_x[MAX_NELEM] =;

static void calculate_intermediate_result(int32_t *dgd, int width, int height,
                                          int dgd_stride, int bit_depth,
                                          int sgr_params_idx, int radius_idx,
                                          int pass, int32_t *A, int32_t *B) {}

static void selfguided_restoration_fast_internal(
    int32_t *dgd, int width, int height, int dgd_stride, int32_t *dst,
    int dst_stride, int bit_depth, int sgr_params_idx, int radius_idx) {}

static void selfguided_restoration_internal(int32_t *dgd, int width, int height,
                                            int dgd_stride, int32_t *dst,
                                            int dst_stride, int bit_depth,
                                            int sgr_params_idx,
                                            int radius_idx) {}

int av1_selfguided_restoration_c(const uint8_t *dgd8, int width, int height,
                                 int dgd_stride, int32_t *flt0, int32_t *flt1,
                                 int flt_stride, int sgr_params_idx,
                                 int bit_depth, int highbd) {}

int av1_apply_selfguided_restoration_c(const uint8_t *dat8, int width,
                                       int height, int stride, int eps,
                                       const int *xqd, uint8_t *dst8,
                                       int dst_stride, int32_t *tmpbuf,
                                       int bit_depth, int highbd) {}

static void sgrproj_filter_stripe(const RestorationUnitInfo *rui,
                                  int stripe_width, int stripe_height,
                                  int procunit_width, const uint8_t *src,
                                  int src_stride, uint8_t *dst, int dst_stride,
                                  int32_t *tmpbuf, int bit_depth,
                                  struct aom_internal_error_info *error_info) {}

#if CONFIG_AV1_HIGHBITDEPTH
static void wiener_filter_stripe_highbd(
    const RestorationUnitInfo *rui, int stripe_width, int stripe_height,
    int procunit_width, const uint8_t *src8, int src_stride, uint8_t *dst8,
    int dst_stride, int32_t *tmpbuf, int bit_depth,
    struct aom_internal_error_info *error_info) {
  (void)tmpbuf;
  (void)error_info;
  const WienerConvolveParams conv_params = get_conv_params_wiener(bit_depth);

  for (int j = 0; j < stripe_width; j += procunit_width) {
    int w = AOMMIN(procunit_width, (stripe_width - j + 15) & ~15);
    const uint8_t *src8_p = src8 + j;
    uint8_t *dst8_p = dst8 + j;
    av1_highbd_wiener_convolve_add_src(src8_p, src_stride, dst8_p, dst_stride,
                                       rui->wiener_info.hfilter, 16,
                                       rui->wiener_info.vfilter, 16, w,
                                       stripe_height, &conv_params, bit_depth);
  }
}

static void sgrproj_filter_stripe_highbd(
    const RestorationUnitInfo *rui, int stripe_width, int stripe_height,
    int procunit_width, const uint8_t *src8, int src_stride, uint8_t *dst8,
    int dst_stride, int32_t *tmpbuf, int bit_depth,
    struct aom_internal_error_info *error_info) {
  for (int j = 0; j < stripe_width; j += procunit_width) {
    int w = AOMMIN(procunit_width, stripe_width - j);
    if (av1_apply_selfguided_restoration(
            src8 + j, w, stripe_height, src_stride, rui->sgrproj_info.ep,
            rui->sgrproj_info.xqd, dst8 + j, dst_stride, tmpbuf, bit_depth,
            1) != 0) {
      aom_internal_error(
          error_info, AOM_CODEC_MEM_ERROR,
          "Error allocating buffer in av1_apply_selfguided_restoration");
    }
  }
}
#endif  // CONFIG_AV1_HIGHBITDEPTH

stripe_filter_fun;

#if CONFIG_AV1_HIGHBITDEPTH
#define NUM_STRIPE_FILTERS
static const stripe_filter_fun stripe_filters[NUM_STRIPE_FILTERS] = {
  wiener_filter_stripe, sgrproj_filter_stripe, wiener_filter_stripe_highbd,
  sgrproj_filter_stripe_highbd
};
#else
#define NUM_STRIPE_FILTERS
static const stripe_filter_fun stripe_filters[NUM_STRIPE_FILTERS] =;
#endif  // CONFIG_AV1_HIGHBITDEPTH

// Filter one restoration unit
void av1_loop_restoration_filter_unit(
    const RestorationTileLimits *limits, const RestorationUnitInfo *rui,
    const RestorationStripeBoundaries *rsb, RestorationLineBuffers *rlbs,
    int plane_w, int plane_h, int ss_x, int ss_y, int highbd, int bit_depth,
    uint8_t *data8, int stride, uint8_t *dst8, int dst_stride, int32_t *tmpbuf,
    int optimized_lr, struct aom_internal_error_info *error_info) {}

static void filter_frame_on_unit(const RestorationTileLimits *limits,
                                 int rest_unit_idx, void *priv, int32_t *tmpbuf,
                                 RestorationLineBuffers *rlbs,
                                 struct aom_internal_error_info *error_info) {}

void av1_loop_restoration_filter_frame_init(AV1LrStruct *lr_ctxt,
                                            YV12_BUFFER_CONFIG *frame,
                                            AV1_COMMON *cm, int optimized_lr,
                                            int num_planes) {}

void av1_loop_restoration_copy_planes(AV1LrStruct *loop_rest_ctxt,
                                      AV1_COMMON *cm, int num_planes) {}

// Call on_rest_unit for each loop restoration unit in the plane.
static void foreach_rest_unit_in_plane(const struct AV1Common *cm, int plane,
                                       rest_unit_visitor_t on_rest_unit,
                                       void *priv, int32_t *tmpbuf,
                                       RestorationLineBuffers *rlbs) {}

static void foreach_rest_unit_in_planes(AV1LrStruct *lr_ctxt, AV1_COMMON *cm,
                                        int num_planes) {}

void av1_loop_restoration_filter_frame(YV12_BUFFER_CONFIG *frame,
                                       AV1_COMMON *cm, int optimized_lr,
                                       void *lr_ctxt) {}

void av1_foreach_rest_unit_in_row(
    RestorationTileLimits *limits, int plane_w,
    rest_unit_visitor_t on_rest_unit, int row_number, int unit_size,
    int hnum_rest_units, int vnum_rest_units, int plane, void *priv,
    int32_t *tmpbuf, RestorationLineBuffers *rlbs, sync_read_fn_t on_sync_read,
    sync_write_fn_t on_sync_write, struct AV1LrSyncData *const lr_sync,
    struct aom_internal_error_info *error_info) {}

void av1_lr_sync_read_dummy(void *const lr_sync, int r, int c, int plane) {}

void av1_lr_sync_write_dummy(void *const lr_sync, int r, int c,
                             const int sb_cols, int plane) {}

int av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int plane,
                                       int mi_row, int mi_col, BLOCK_SIZE bsize,
                                       int *rcol0, int *rcol1, int *rrow0,
                                       int *rrow1) {}

// Extend to left and right
static void extend_lines(uint8_t *buf, int width, int height, int stride,
                         int extend, int use_highbitdepth) {}

static void save_deblock_boundary_lines(
    const YV12_BUFFER_CONFIG *frame, const AV1_COMMON *cm, int plane, int row,
    int stripe, int use_highbd, int is_above,
    RestorationStripeBoundaries *boundaries) {}

static void save_cdef_boundary_lines(const YV12_BUFFER_CONFIG *frame,
                                     const AV1_COMMON *cm, int plane, int row,
                                     int stripe, int use_highbd, int is_above,
                                     RestorationStripeBoundaries *boundaries) {}

static void save_boundary_lines(const YV12_BUFFER_CONFIG *frame, int use_highbd,
                                int plane, AV1_COMMON *cm, int after_cdef) {}

// For each RESTORATION_PROC_UNIT_SIZE pixel high stripe, save 4 scan
// lines to be used as boundary in the loop restoration process. The
// lines are saved in rst_internal.stripe_boundary_lines
void av1_loop_restoration_save_boundary_lines(const YV12_BUFFER_CONFIG *frame,
                                              AV1_COMMON *cm, int after_cdef) {}