restoration.h 9.4 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
#define RESTORATION_TILESIZE_MAX 256
28
#define RESTORATION_TILEPELS_MAX \
29
  (RESTORATION_TILESIZE_MAX * RESTORATION_TILESIZE_MAX * 9 / 4)
30

31
// 4 32-bit buffers needed for the filter:
32
// 2 for the restored versions of the frame and
33
// 2 for each restoration operation
David Barker's avatar
David Barker committed
34
#define SGRPROJ_OUTBUF_SIZE \
35
  ((RESTORATION_TILESIZE_MAX * 3 / 2) * (RESTORATION_TILESIZE_MAX * 3 / 2 + 16))
David Barker's avatar
David Barker committed
36
37
38
#define SGRPROJ_TMPBUF_SIZE                         \
  (RESTORATION_TILEPELS_MAX * 2 * sizeof(int32_t) + \
   SGRPROJ_OUTBUF_SIZE * 2 * sizeof(int32_t))
39
#define SGRPROJ_EXTBUF_SIZE (0)
40
#define SGRPROJ_PARAMS_BITS 4
41
#define SGRPROJ_PARAMS (1 << SGRPROJ_PARAMS_BITS)
42
#define USE_HIGHPASS_IN_SGRPROJ 0
43
44
45
46
47
48
49
50
51

// 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)

52
53
54
55
56
57
58
#if USE_HIGHPASS_IN_SGRPROJ
#define SGRPROJ_PRJ_MIN0 (-(1 << SGRPROJ_PRJ_BITS) / 8)
#define SGRPROJ_PRJ_MAX0 (SGRPROJ_PRJ_MIN0 + (1 << SGRPROJ_PRJ_BITS) - 1)
#define SGRPROJ_PRJ_MIN1 (-(1 << SGRPROJ_PRJ_BITS) / 2)
#define SGRPROJ_PRJ_MAX1 (SGRPROJ_PRJ_MIN1 + (1 << SGRPROJ_PRJ_BITS) - 1)
#else
#define SGRPROJ_PRJ_MIN0 (-(1 << SGRPROJ_PRJ_BITS) * 3 / 4)
59
60
61
#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)
62
#endif  // USE_HIGHPASS_IN_SGRPROJ
63

64
65
#define SGRPROJ_PRJ_SUBEXP_K 4

66
67
#define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)

David Barker's avatar
David Barker committed
68
69
70
71
72
73
#define MAX_RADIUS 3  // Only 1, 2, 3 allowed
#define MAX_EPS 80    // Max value of eps
#define MAX_NELEM ((2 * MAX_RADIUS + 1) * (2 * MAX_RADIUS + 1))
#define SGRPROJ_MTABLE_BITS 20
#define SGRPROJ_RECIP_BITS 12

74
75
76
77
78
#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)
79
#define WIENER_EXTBUF_SIZE (0)
80

81
82
#define WIENER_FILT_PREC_BITS 7
#define WIENER_FILT_STEP (1 << WIENER_FILT_PREC_BITS)
83

84
85
86
// Whether to use high intermediate precision filtering
#define USE_WIENER_HIGH_INTERMEDIATE_PRECISION 0

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

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

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

99
100
101
102
103
104
105
#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)

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

113
114
115
116
#define WIENER_FILT_TAP0_SUBEXP_K 1
#define WIENER_FILT_TAP1_SUBEXP_K 2
#define WIENER_FILT_TAP2_SUBEXP_K 3

117
118
// Max of SGRPROJ_TMPBUF_SIZE, DOMAINTXFMRF_TMPBUF_SIZE, WIENER_TMPBUF_SIZE
#define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)
119

120
// Max of SGRPROJ_EXTBUF_SIZE, WIENER_EXTBUF_SIZE
121
#define RESTORATION_EXTBUF_SIZE (WIENER_EXTBUF_SIZE)
122

123
124
125
126
127
128
129
130
131
132
133
// 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;
134

135
typedef struct {
136
137
138
139
#if USE_HIGHPASS_IN_SGRPROJ
  int corner;
  int edge;
#else
140
141
  int r1;
  int e1;
142
#endif  // USE_HIGHPASS_IN_SGRPROJ
143
144
145
146
147
148
149
150
151
  int r2;
  int e2;
} sgr_params_type;

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

152
typedef struct {
153
  int restoration_tilesize;
154
155
  RestorationType frame_restoration_type;
  RestorationType *restoration_type;
156
  // Wiener filter
157
  WienerInfo *wiener_info;
158
159
  // Selfguided proj filter
  SgrprojInfo *sgrproj_info;
160
} RestorationInfo;
161

162
typedef struct {
163
164
  RestorationInfo *rsi;
  int keyframe;
165
166
167
  int ntiles;
  int tile_width, tile_height;
  int nhtiles, nvtiles;
168
  int32_t *tmpbuf;
169
} RestorationInternal;
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
static INLINE void set_default_sgrproj(SgrprojInfo *sgrproj_info) {
  sgrproj_info->xqd[0] = (SGRPROJ_PRJ_MIN0 + SGRPROJ_PRJ_MAX0) / 2;
  sgrproj_info->xqd[1] = (SGRPROJ_PRJ_MIN1 + SGRPROJ_PRJ_MAX1) / 2;
}

static INLINE void set_default_wiener(WienerInfo *wiener_info) {
  wiener_info->vfilter[0] = wiener_info->hfilter[0] = WIENER_FILT_TAP0_MIDV;
  wiener_info->vfilter[1] = wiener_info->hfilter[1] = WIENER_FILT_TAP1_MIDV;
  wiener_info->vfilter[2] = wiener_info->hfilter[2] = WIENER_FILT_TAP2_MIDV;
  wiener_info->vfilter[WIENER_HALFWIN] = wiener_info->hfilter[WIENER_HALFWIN] =
      -2 *
      (WIENER_FILT_TAP2_MIDV + WIENER_FILT_TAP1_MIDV + WIENER_FILT_TAP0_MIDV);
  wiener_info->vfilter[4] = wiener_info->hfilter[4] = WIENER_FILT_TAP2_MIDV;
  wiener_info->vfilter[5] = wiener_info->hfilter[5] = WIENER_FILT_TAP1_MIDV;
  wiener_info->vfilter[6] = wiener_info->hfilter[6] = WIENER_FILT_TAP0_MIDV;
}

188
189
190
static INLINE int av1_get_rest_ntiles(int width, int height, int tilesize,
                                      int *tile_width, int *tile_height,
                                      int *nhtiles, int *nvtiles) {
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  int nhtiles_, nvtiles_;
  int tile_width_, tile_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) {
228
229
    *h_start = AOMMAX(*h_start, clamp_h);
    *h_end = AOMMIN(*h_end, im_width - clamp_h);
230
231
  }
  if (clamp_v) {
232
233
    *v_start = AOMMAX(*v_start, clamp_v);
    *v_end = AOMMIN(*v_end, im_height - clamp_v);
234
235
236
  }
}

237
extern const sgr_params_type sgr_params[SGRPROJ_PARAMS];
David Barker's avatar
David Barker committed
238
239
240
extern int sgrproj_mtable[MAX_EPS][MAX_NELEM];
extern const int32_t x_by_xplus1[256];
extern const int32_t one_by_x[MAX_NELEM];
241

242
243
int av1_alloc_restoration_struct(struct AV1Common *cm,
                                 RestorationInfo *rst_info, int width,
244
245
246
                                 int height);
void av1_free_restoration_struct(RestorationInfo *rst_info);

247
void extend_frame(uint8_t *data, int width, int height, int stride);
248
#if CONFIG_HIGHBITDEPTH
249
void extend_frame_highbd(uint16_t *data, int width, int height, int stride);
250
#endif  // CONFIG_HIGHBITDEPTH
251
void decode_xq(int *xqd, int *xq);
Yaowu Xu's avatar
Yaowu Xu committed
252
void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
253
                                RestorationInfo *rsi, int components_pattern,
254
                                int partial_frame, YV12_BUFFER_CONFIG *dst);
Yaowu Xu's avatar
Yaowu Xu committed
255
void av1_loop_restoration_precal();
256
257
258
259
#ifdef __cplusplus
}  // extern "C"
#endif

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