restoration.h 9.19 KB
Newer Older
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
4 5 6 7 8 9
 * 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.
10 11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12 13
#ifndef AV1_COMMON_RESTORATION_H_
#define AV1_COMMON_RESTORATION_H_
14

15
#include "aom_ports/mem.h"
Yaowu Xu's avatar
Yaowu Xu committed
16
#include "./aom_config.h"
17

18
#include "av1/common/blockd.h"
19 20 21 22 23

#ifdef __cplusplus
extern "C" {
#endif

24 25 26
#define CLIP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
#define RINT(x) ((x) < 0 ? (int)((x)-0.5) : (int)((x) + 0.5))

27 28 29 30 31
#define RESTORATION_TILESIZE_SML 128
#define RESTORATION_TILESIZE_BIG 256
#define RESTORATION_TILEPELS_MAX \
  (RESTORATION_TILESIZE_BIG * RESTORATION_TILESIZE_BIG * 9 / 4)

32 33 34 35 36 37 38 39 40
#define DOMAINTXFMRF_PARAMS_BITS 6
#define DOMAINTXFMRF_PARAMS (1 << DOMAINTXFMRF_PARAMS_BITS)
#define DOMAINTXFMRF_SIGMA_SCALEBITS 4
#define DOMAINTXFMRF_SIGMA_SCALE (1 << DOMAINTXFMRF_SIGMA_SCALEBITS)
#define DOMAINTXFMRF_ITERS 3
#define DOMAINTXFMRF_VTABLE_PRECBITS 8
#define DOMAINTXFMRF_VTABLE_PREC (1 << DOMAINTXFMRF_VTABLE_PRECBITS)
#define DOMAINTXFMRF_MULT \
  sqrt(((1 << (DOMAINTXFMRF_ITERS * 2)) - 1) * 2.0 / 3.0)
41 42 43
// 1 32-bit and 2 8-bit buffers needed for the filter
#define DOMAINTXFMRF_TMPBUF_SIZE \
  (RESTORATION_TILEPELS_MAX * (sizeof(int32_t) + 2 * sizeof(uint8_t)))
44 45 46 47 48 49 50
// One extra buffer needed in encoder, which is either 8-bit or 16-bit
// depending on the video bit depth.
#if CONFIG_AOM_HIGHBITDEPTH
#define DOMAINTXFMRF_EXTBUF_SIZE (RESTORATION_TILEPELS_MAX * sizeof(uint16_t))
#else
#define DOMAINTXFMRF_EXTBUF_SIZE (RESTORATION_TILEPELS_MAX * sizeof(uint8_t))
#endif
51 52
#define DOMAINTXFMRF_BITS (DOMAINTXFMRF_PARAMS_BITS)

53
// 4 32-bit buffers needed for the filter:
54
// 2 for the restored versions of the frame and
55 56
// 2 for each restoration operation
#define SGRPROJ_TMPBUF_SIZE (RESTORATION_TILEPELS_MAX * 4 * sizeof(int32_t))
57
#define SGRPROJ_EXTBUF_SIZE (0)
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#define SGRPROJ_PARAMS_BITS 3
#define SGRPROJ_PARAMS (1 << SGRPROJ_PARAMS_BITS)

// Precision bits for projection
#define SGRPROJ_PRJ_BITS 7
// Restoration precision bits generated higher than source before projection
#define SGRPROJ_RST_BITS 4
// Internal precision bits for core selfguided_restoration
#define SGRPROJ_SGR_BITS 8
#define SGRPROJ_SGR (1 << SGRPROJ_SGR_BITS)

#define SGRPROJ_PRJ_MIN0 (-(1 << SGRPROJ_PRJ_BITS) / 4)
#define SGRPROJ_PRJ_MAX0 (SGRPROJ_PRJ_MIN0 + (1 << SGRPROJ_PRJ_BITS) - 1)
#define SGRPROJ_PRJ_MIN1 (-(1 << SGRPROJ_PRJ_BITS) / 4)
#define SGRPROJ_PRJ_MAX1 (SGRPROJ_PRJ_MIN1 + (1 << SGRPROJ_PRJ_BITS) - 1)

#define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)

76 77 78 79 80
#define WIENER_HALFWIN 3
#define WIENER_HALFWIN1 (WIENER_HALFWIN + 1)
#define WIENER_WIN (2 * WIENER_HALFWIN + 1)
#define WIENER_WIN2 ((WIENER_WIN) * (WIENER_WIN))
#define WIENER_TMPBUF_SIZE (0)
81
#define WIENER_EXTBUF_SIZE (0)
82

83 84
#define WIENER_FILT_PREC_BITS 7
#define WIENER_FILT_STEP (1 << WIENER_FILT_PREC_BITS)
85

86 87 88 89
// Central values for the taps
#define WIENER_FILT_TAP0_MIDV (3)
#define WIENER_FILT_TAP1_MIDV (-7)
#define WIENER_FILT_TAP2_MIDV (16)
90

clang-format's avatar
clang-format committed
91 92 93
#define WIENER_FILT_TAP0_BITS 4
#define WIENER_FILT_TAP1_BITS 5
#define WIENER_FILT_TAP2_BITS 6
94

95 96 97
#define WIENER_FILT_BITS \
  ((WIENER_FILT_TAP0_BITS + WIENER_FILT_TAP1_BITS + WIENER_FILT_TAP2_BITS) * 2)

98 99 100 101 102 103 104
#define WIENER_FILT_TAP0_MINV \
  (WIENER_FILT_TAP0_MIDV - (1 << WIENER_FILT_TAP0_BITS) / 2)
#define WIENER_FILT_TAP1_MINV \
  (WIENER_FILT_TAP1_MIDV - (1 << WIENER_FILT_TAP1_BITS) / 2)
#define WIENER_FILT_TAP2_MINV \
  (WIENER_FILT_TAP2_MIDV - (1 << WIENER_FILT_TAP2_BITS) / 2)

105
#define WIENER_FILT_TAP0_MAXV \
106
  (WIENER_FILT_TAP0_MIDV - 1 + (1 << WIENER_FILT_TAP0_BITS) / 2)
107
#define WIENER_FILT_TAP1_MAXV \
108
  (WIENER_FILT_TAP1_MIDV - 1 + (1 << WIENER_FILT_TAP1_BITS) / 2)
109
#define WIENER_FILT_TAP2_MAXV \
110 111 112 113
  (WIENER_FILT_TAP2_MIDV - 1 + (1 << WIENER_FILT_TAP2_BITS) / 2)

// Max of SGRPROJ_TMPBUF_SIZE, DOMAINTXFMRF_TMPBUF_SIZE, WIENER_TMPBUF_SIZE
#define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)
114 115
// Max of SGRPROJ_EXTBUF_SIZE, DOMAINTXFMRF_EXTBUF_SIZE, WIENER_EXTBUF_SIZE
#define RESTORATION_EXTBUF_SIZE (DOMAINTXFMRF_EXTBUF_SIZE)
116

117 118 119 120 121 122 123 124 125 126 127
// Check the assumptions of the existing code
#if SUBPEL_TAPS != WIENER_WIN + 1
#error "Wiener filter currently only works if SUBPEL_TAPS == WIENER_WIN + 1"
#endif
#if WIENER_FILT_PREC_BITS != 7
#error "Wiener filter currently only works if WIENER_FILT_PREC_BITS == 7"
#endif
typedef struct {
  DECLARE_ALIGNED(16, InterpKernel, vfilter);
  DECLARE_ALIGNED(16, InterpKernel, hfilter);
} WienerInfo;
128

129 130 131 132 133 134 135 136 137 138 139 140
typedef struct {
  int r1;
  int e1;
  int r2;
  int e2;
} sgr_params_type;

typedef struct {
  int ep;
  int xqd[2];
} SgrprojInfo;

141
typedef struct { int sigma_r; } DomaintxfmrfInfo;
142

143
typedef struct {
144 145
  RestorationType frame_restoration_type;
  RestorationType *restoration_type;
146
  // Wiener filter
147
  WienerInfo *wiener_info;
148 149
  // Selfguided proj filter
  SgrprojInfo *sgrproj_info;
150 151
  // Domain transform filter
  DomaintxfmrfInfo *domaintxfmrf_info;
152
} RestorationInfo;
153

154
typedef struct {
155 156
  RestorationInfo *rsi;
  int keyframe;
157 158 159
  int ntiles;
  int tile_width, tile_height;
  int nhtiles, nvtiles;
160
  int32_t *tmpbuf;
161
} RestorationInternal;
162

163 164 165 166 167 168 169
static INLINE int get_rest_tilesize(int width, int height) {
  if (width * height <= 352 * 288)
    return RESTORATION_TILESIZE_SML;
  else
    return RESTORATION_TILESIZE_BIG;
}

170 171 172
static INLINE int av1_get_rest_ntiles(int width, int height, int *tile_width,
                                      int *tile_height, int *nhtiles,
                                      int *nvtiles) {
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
  int nhtiles_, nvtiles_;
  int tile_width_, tile_height_;
  int tilesize = get_rest_tilesize(width, height);
  tile_width_ = (tilesize < 0) ? width : AOMMIN(tilesize, width);
  tile_height_ = (tilesize < 0) ? height : AOMMIN(tilesize, height);
  nhtiles_ = (width + (tile_width_ >> 1)) / tile_width_;
  nvtiles_ = (height + (tile_height_ >> 1)) / tile_height_;
  if (tile_width) *tile_width = tile_width_;
  if (tile_height) *tile_height = tile_height_;
  if (nhtiles) *nhtiles = nhtiles_;
  if (nvtiles) *nvtiles = nvtiles_;
  return (nhtiles_ * nvtiles_);
}

static INLINE void av1_get_rest_tile_limits(
    int tile_idx, int subtile_idx, int subtile_bits, int nhtiles, int nvtiles,
    int tile_width, int tile_height, int im_width, int im_height, int clamp_h,
    int clamp_v, int *h_start, int *h_end, int *v_start, int *v_end) {
  const int htile_idx = tile_idx % nhtiles;
  const int vtile_idx = tile_idx / nhtiles;
  *h_start = htile_idx * tile_width;
  *v_start = vtile_idx * tile_height;
  *h_end = (htile_idx < nhtiles - 1) ? *h_start + tile_width : im_width;
  *v_end = (vtile_idx < nvtiles - 1) ? *v_start + tile_height : im_height;
  if (subtile_bits) {
    const int num_subtiles_1d = (1 << subtile_bits);
    const int subtile_width = (*h_end - *h_start) >> subtile_bits;
    const int subtile_height = (*v_end - *v_start) >> subtile_bits;
    const int subtile_idx_h = subtile_idx & (num_subtiles_1d - 1);
    const int subtile_idx_v = subtile_idx >> subtile_bits;
    *h_start += subtile_idx_h * subtile_width;
    *v_start += subtile_idx_v * subtile_height;
    *h_end = subtile_idx_h == num_subtiles_1d - 1 ? *h_end
                                                  : *h_start + subtile_width;
    *v_end = subtile_idx_v == num_subtiles_1d - 1 ? *v_end
                                                  : *v_start + subtile_height;
  }
  if (clamp_h) {
211 212
    *h_start = AOMMAX(*h_start, clamp_h);
    *h_end = AOMMIN(*h_end, im_width - clamp_h);
213 214
  }
  if (clamp_v) {
215 216
    *v_start = AOMMAX(*v_start, clamp_v);
    *v_end = AOMMIN(*v_end, im_height - clamp_v);
217 218 219
  }
}

220 221
extern const sgr_params_type sgr_params[SGRPROJ_PARAMS];

222 223 224 225
int av1_alloc_restoration_struct(RestorationInfo *rst_info, int width,
                                 int height);
void av1_free_restoration_struct(RestorationInfo *rst_info);

226
void extend_frame(uint8_t *data, int width, int height, int stride);
227
void av1_selfguided_restoration(int32_t *dgd, int width, int height, int stride,
228
                                int bit_depth, int r, int eps, int32_t *tmpbuf);
229
void av1_domaintxfmrf_restoration(uint8_t *dgd, int width, int height,
230
                                  int stride, int param, uint8_t *dst,
231
                                  int dst_stride, int32_t *tmpbuf);
232
#if CONFIG_AOM_HIGHBITDEPTH
233
void extend_frame_highbd(uint16_t *data, int width, int height, int stride);
234
void av1_domaintxfmrf_restoration_highbd(uint16_t *dgd, int width, int height,
235
                                         int stride, int param, int bit_depth,
236 237
                                         uint16_t *dst, int dst_stride,
                                         int32_t *tmpbuf);
238
#endif  // CONFIG_AOM_HIGHBITDEPTH
239
void decode_xq(int *xqd, int *xq);
Yaowu Xu's avatar
Yaowu Xu committed
240
void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
241
                                RestorationInfo *rsi, int components_pattern,
242
                                int partial_frame, YV12_BUFFER_CONFIG *dst);
Yaowu Xu's avatar
Yaowu Xu committed
243
void av1_loop_restoration_precal();
244 245 246 247
#ifdef __cplusplus
}  // extern "C"
#endif

Yaowu Xu's avatar
Yaowu Xu committed
248
#endif  // AV1_COMMON_RESTORATION_H_