Line data Source code
1 : /*
2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 : *
4 : * This source code is subject to the terms of the BSD 2 Clause License and
5 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 : * was not distributed with this source code in the LICENSE file, you can
7 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 : * Media Patent License 1.0 was not distributed with this source code in the
9 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 : */
11 :
12 : #ifndef AV1_COMMON_RESTORATION_H_
13 : #define AV1_COMMON_RESTORATION_H_
14 :
15 : #include <math.h>
16 : #include "EbDefinitions.h"
17 : #include "EbPictureBufferDesc.h"
18 : #include "EbAv1Structs.h"
19 :
20 : #ifdef __cplusplus
21 : extern "C" {
22 : #endif
23 :
24 : void eb_apply_selfguided_restoration_c(const uint8_t *dat8, int32_t width, int32_t height,
25 : int32_t stride, int32_t eps, const int32_t *xqd,
26 : uint8_t *dst8, int32_t dst_stride,
27 : int32_t *tmpbuf, int32_t bit_depth,
28 : int32_t highbd);
29 :
30 : #define CLIP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
31 : #define RINT(x) ((x) < 0 ? (int32_t)((x)-0.5) : (int32_t)((x) + 0.5))
32 :
33 : #define REAL_PTR(hbd, d) ((hbd) ? (uint8_t *)CONVERT_TO_SHORTPTR(d) : (d))
34 :
35 : #define RESTORATION_PROC_UNIT_SIZE 64
36 :
37 : // Filter tile grid offset upwards compared to the superblock grid
38 : #define RESTORATION_UNIT_OFFSET 8
39 :
40 : #define SGRPROJ_BORDER_VERT 3 // Vertical border used for Sgr
41 : #define SGRPROJ_BORDER_HORZ 3 // Horizontal border used for Sgr
42 :
43 : #define WIENER_BORDER_VERT 2 // Vertical border used for Wiener
44 : #define WIENER_HALFWIN 3
45 : #define WIENER_BORDER_HORZ (WIENER_HALFWIN) // Horizontal border for Wiener
46 :
47 : // RESTORATION_BORDER_VERT determines line buffer requirement for LR.
48 : // Should be set at the max of SGRPROJ_BORDER_VERT and WIENER_BORDER_VERT.
49 : // Note the line buffer needed is twice the value of this macro.
50 : #if SGRPROJ_BORDER_VERT >= WIENER_BORDER_VERT
51 : #define RESTORATION_BORDER_VERT (SGRPROJ_BORDER_VERT)
52 : #else
53 : #define RESTORATION_BORDER_VERT (WIENER_BORDER_VERT)
54 : #endif // SGRPROJ_BORDER_VERT >= WIENER_BORDER_VERT
55 :
56 : #if SGRPROJ_BORDER_HORZ >= WIENER_BORDER_HORZ
57 : #define RESTORATION_BORDER_HORZ (SGRPROJ_BORDER_HORZ)
58 : #else
59 : #define RESTORATION_BORDER_HORZ (WIENER_BORDER_HORZ)
60 : #endif // SGRPROJ_BORDER_VERT >= WIENER_BORDER_VERT
61 :
62 : // How many border pixels do we need for each processing unit?
63 : #define RESTORATION_BORDER 3
64 :
65 : // How many rows of deblocked pixels do we save above/below each processing
66 : // stripe?
67 : #define RESTORATION_CTX_VERT 2
68 :
69 : // Additional pixels to the left and right in above/below buffers
70 : // It is RESTORATION_BORDER_HORZ rounded up to get nicer buffer alignment
71 : #define RESTORATION_EXTRA_HORZ 4
72 :
73 : // Pad up to 20 more (may be much less is needed)
74 : #define RESTORATION_PADDING 20
75 : #define RESTORATION_PROC_UNIT_PELS \
76 : ((RESTORATION_PROC_UNIT_SIZE + RESTORATION_BORDER_HORZ * 2 + \
77 : RESTORATION_PADDING) * \
78 : (RESTORATION_PROC_UNIT_SIZE + RESTORATION_BORDER_VERT * 2 + \
79 : RESTORATION_PADDING))
80 :
81 : #define RESTORATION_UNITSIZE_MAX 256
82 : #define RESTORATION_UNITPELS_HORZ_MAX \
83 : (RESTORATION_UNITSIZE_MAX * 3 / 2 + 2 * RESTORATION_BORDER_HORZ + 16)
84 : #define RESTORATION_UNITPELS_VERT_MAX \
85 : ((RESTORATION_UNITSIZE_MAX * 3 / 2 + 2 * RESTORATION_BORDER_VERT + \
86 : RESTORATION_UNIT_OFFSET))
87 : #define RESTORATION_UNITPELS_MAX \
88 : (RESTORATION_UNITPELS_HORZ_MAX * RESTORATION_UNITPELS_VERT_MAX)
89 :
90 : // Two 32-bit buffers needed for the restored versions from two filters
91 : // TODO(debargha, rupert): Refactor to not need the large tilesize to be stored
92 : // on the decoder side.
93 : #define SGRPROJ_TMPBUF_SIZE (RESTORATION_UNITPELS_MAX * 2 * sizeof(int32_t))
94 :
95 : #define SGRPROJ_EXTBUF_SIZE (0)
96 : #define SGRPROJ_PARAMS_BITS 4
97 : #define SGRPROJ_PARAMS (1 << SGRPROJ_PARAMS_BITS)
98 :
99 : // Precision bits for projection
100 : #define SGRPROJ_PRJ_BITS 7
101 : // Restoration precision bits generated higher than source before projection
102 : #define SGRPROJ_RST_BITS 4
103 : // Internal precision bits for core selfguided_restoration
104 : #define SGRPROJ_SGR_BITS 8
105 : #define SGRPROJ_SGR (1 << SGRPROJ_SGR_BITS)
106 :
107 : #define SGRPROJ_PRJ_MIN0 (-(1 << SGRPROJ_PRJ_BITS) * 3 / 4)
108 : #define SGRPROJ_PRJ_MAX0 (SGRPROJ_PRJ_MIN0 + (1 << SGRPROJ_PRJ_BITS) - 1)
109 : #define SGRPROJ_PRJ_MIN1 (-(1 << SGRPROJ_PRJ_BITS) / 4)
110 : #define SGRPROJ_PRJ_MAX1 (SGRPROJ_PRJ_MIN1 + (1 << SGRPROJ_PRJ_BITS) - 1)
111 :
112 : #define SGRPROJ_PRJ_SUBEXP_K 4
113 :
114 : #define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)
115 :
116 : #define MAX_RADIUS 2 // Only 1, 2, 3 allowed
117 : #define MAX_NELEM ((2 * MAX_RADIUS + 1) * (2 * MAX_RADIUS + 1))
118 : #define SGRPROJ_MTABLE_BITS 20
119 : #define SGRPROJ_RECIP_BITS 12
120 :
121 : #define WIENER_HALFWIN1 (WIENER_HALFWIN + 1)
122 : #define WIENER_WIN (2 * WIENER_HALFWIN + 1)
123 : #define WIENER_WIN2 ((WIENER_WIN) * (WIENER_WIN))
124 : #define WIENER_TMPBUF_SIZE (0)
125 : #define WIENER_EXTBUF_SIZE (0)
126 :
127 : // If WIENER_WIN_CHROMA == WIENER_WIN - 2, that implies 5x5 filters are used for
128 : // chroma. To use 7x7 for chroma set WIENER_WIN_CHROMA to WIENER_WIN.
129 : #define WIENER_WIN_CHROMA (WIENER_WIN - 2)
130 : #define WIENER_WIN2_CHROMA ((WIENER_WIN_CHROMA) * (WIENER_WIN_CHROMA))
131 : #define WIENER_FILT_PREC_BITS 7
132 : #define WIENER_FILT_STEP (1 << WIENER_FILT_PREC_BITS)
133 : #define WIENER_WIN_3TAP (WIENER_WIN - 4)
134 : #define WIENER_WIN2_3TAP ((WIENER_WIN_3TAP) * (WIENER_WIN_3TAP))
135 :
136 : // Central values for the taps
137 : #define WIENER_FILT_TAP0_MIDV (3)
138 : #define WIENER_FILT_TAP1_MIDV (-7)
139 : #define WIENER_FILT_TAP2_MIDV (15)
140 : #define WIENER_FILT_TAP3_MIDV \
141 : (WIENER_FILT_STEP - 2 * (WIENER_FILT_TAP0_MIDV + WIENER_FILT_TAP1_MIDV + \
142 : WIENER_FILT_TAP2_MIDV))
143 :
144 : #define WIENER_FILT_TAP0_BITS 4
145 : #define WIENER_FILT_TAP1_BITS 5
146 : #define WIENER_FILT_TAP2_BITS 6
147 :
148 : #define WIENER_FILT_BITS \
149 : ((WIENER_FILT_TAP0_BITS + WIENER_FILT_TAP1_BITS + WIENER_FILT_TAP2_BITS) * 2)
150 :
151 : #define WIENER_FILT_TAP0_MINV \
152 : (WIENER_FILT_TAP0_MIDV - (1 << WIENER_FILT_TAP0_BITS) / 2)
153 : #define WIENER_FILT_TAP1_MINV \
154 : (WIENER_FILT_TAP1_MIDV - (1 << WIENER_FILT_TAP1_BITS) / 2)
155 : #define WIENER_FILT_TAP2_MINV \
156 : (WIENER_FILT_TAP2_MIDV - (1 << WIENER_FILT_TAP2_BITS) / 2)
157 :
158 : #define WIENER_FILT_TAP0_MAXV \
159 : (WIENER_FILT_TAP0_MIDV - 1 + (1 << WIENER_FILT_TAP0_BITS) / 2)
160 : #define WIENER_FILT_TAP1_MAXV \
161 : (WIENER_FILT_TAP1_MIDV - 1 + (1 << WIENER_FILT_TAP1_BITS) / 2)
162 : #define WIENER_FILT_TAP2_MAXV \
163 : (WIENER_FILT_TAP2_MIDV - 1 + (1 << WIENER_FILT_TAP2_BITS) / 2)
164 :
165 : #define WIENER_FILT_TAP0_SUBEXP_K 1
166 : #define WIENER_FILT_TAP1_SUBEXP_K 2
167 : #define WIENER_FILT_TAP2_SUBEXP_K 3
168 :
169 : // Max of SGRPROJ_TMPBUF_SIZE, DOMAINTXFMRF_TMPBUF_SIZE, WIENER_TMPBUF_SIZE
170 : #define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)
171 :
172 : // Max of SGRPROJ_EXTBUF_SIZE, WIENER_EXTBUF_SIZE
173 : #define RESTORATION_EXTBUF_SIZE (WIENER_EXTBUF_SIZE)
174 :
175 : // Check the assumptions of the existing code
176 : #if SUBPEL_TAPS != WIENER_WIN + 1
177 : //#error "Wiener filter currently only works if SUBPEL_TAPS == WIENER_WIN + 1"
178 : #endif
179 : #if WIENER_FILT_PREC_BITS != 7
180 : #error "Wiener filter currently only works if WIENER_FILT_PREC_BITS == 7"
181 : #endif
182 :
183 : typedef struct WienerInfo
184 : {
185 : DECLARE_ALIGNED(16, InterpKernel, vfilter);
186 : DECLARE_ALIGNED(16, InterpKernel, hfilter);
187 : } WienerInfo;
188 :
189 : typedef struct SgrprojInfo
190 : {
191 : int32_t ep;
192 : int32_t xqd[2];
193 : } SgrprojInfo;
194 :
195 : typedef struct RestorationUnitInfo
196 : {
197 : RestorationType restoration_type;
198 : WienerInfo wiener_info;
199 : SgrprojInfo sgrproj_info;
200 : } RestorationUnitInfo;
201 :
202 : typedef struct AV1PixelRect {
203 : int32_t left, top, right, bottom;
204 : } AV1PixelRect;
205 :
206 : // A restoration line buffer needs space for two lines plus a horizontal filter
207 : // margin of RESTORATION_EXTRA_HORZ on each side.
208 : #define RESTORATION_LINEBUFFER_WIDTH \
209 : (RESTORATION_UNITSIZE_MAX * 3 / 2 + 2 * RESTORATION_EXTRA_HORZ)
210 :
211 : // Similarly, the column buffers (used when we're at a vertical tile edge
212 : // that we can't filter across) need space for one processing unit's worth
213 : // of pixels, plus the top/bottom border width
214 : #define RESTORATION_COLBUFFER_HEIGHT \
215 : (RESTORATION_PROC_UNIT_SIZE + 2 * RESTORATION_BORDER)
216 :
217 : typedef struct RestorationLineBuffers
218 : {
219 : // Temporary buffers to save/restore 3 lines above/below the restoration
220 : // stripe.
221 : uint16_t tmp_save_above[RESTORATION_BORDER][RESTORATION_LINEBUFFER_WIDTH];
222 : uint16_t tmp_save_below[RESTORATION_BORDER][RESTORATION_LINEBUFFER_WIDTH];
223 : } RestorationLineBuffers;
224 :
225 : typedef struct RestorationStripeBoundaries
226 : {
227 : uint8_t *stripe_boundary_above;
228 : uint8_t *stripe_boundary_below;
229 : int32_t stripe_boundary_stride;
230 : int32_t stripe_boundary_size;
231 : } RestorationStripeBoundaries;
232 :
233 : typedef struct RestorationInfo
234 : {
235 : RestorationType frame_restoration_type;
236 : int32_t restoration_unit_size;
237 :
238 : // Fields below here are allocated and initialised by
239 : // eb_av1_alloc_restoration_struct. (horz_)units_per_tile give the number of
240 : // restoration units in (one row of) the largest tile in the frame. The data
241 : // in unit_info is laid out with units_per_tile entries for each tile, which
242 : // have stride horz_units_per_tile.
243 : //
244 : // Even if there are tiles of different sizes, the data in unit_info is laid
245 : // out as if all tiles are of full size.
246 : int32_t units_per_tile;
247 : int32_t vert_units_per_tile, horz_units_per_tile;
248 : RestorationUnitInfo *unit_info;
249 : RestorationStripeBoundaries boundaries;
250 : int32_t optimized_lr;
251 : } RestorationInfo;
252 :
253 1680 : static INLINE void set_default_sgrproj(SgrprojInfo *sgrproj_info) {
254 1680 : sgrproj_info->xqd[0] = (SGRPROJ_PRJ_MIN0 + SGRPROJ_PRJ_MAX0) / 2;
255 1680 : sgrproj_info->xqd[1] = (SGRPROJ_PRJ_MIN1 + SGRPROJ_PRJ_MAX1) / 2;
256 1680 : }
257 :
258 1680 : static INLINE void set_default_wiener(WienerInfo *wiener_info) {
259 1680 : wiener_info->vfilter[0] = wiener_info->hfilter[0] = WIENER_FILT_TAP0_MIDV;
260 1680 : wiener_info->vfilter[1] = wiener_info->hfilter[1] = WIENER_FILT_TAP1_MIDV;
261 1680 : wiener_info->vfilter[2] = wiener_info->hfilter[2] = WIENER_FILT_TAP2_MIDV;
262 1680 : wiener_info->vfilter[WIENER_HALFWIN] = wiener_info->hfilter[WIENER_HALFWIN] =
263 : -2 *
264 : (WIENER_FILT_TAP2_MIDV + WIENER_FILT_TAP1_MIDV + WIENER_FILT_TAP0_MIDV);
265 1680 : wiener_info->vfilter[4] = wiener_info->hfilter[4] = WIENER_FILT_TAP2_MIDV;
266 1680 : wiener_info->vfilter[5] = wiener_info->hfilter[5] = WIENER_FILT_TAP1_MIDV;
267 1680 : wiener_info->vfilter[6] = wiener_info->hfilter[6] = WIENER_FILT_TAP0_MIDV;
268 1680 : }
269 :
270 : typedef struct RestorationTileLimits {
271 : int32_t h_start, h_end, v_start, v_end;
272 : } RestorationTileLimits;
273 :
274 : extern const SgrParamsType eb_sgr_params[SGRPROJ_PARAMS];
275 : extern int32_t sgrproj_mtable[SGRPROJ_PARAMS][2];
276 : extern const int32_t eb_x_by_xplus1[256];
277 : extern const int32_t eb_one_by_x[MAX_NELEM];
278 :
279 : //void eb_av1_alloc_restoration_struct(struct Av1Common *cm, RestorationInfo *rsi,
280 : // int32_t is_uv);
281 : void eb_extend_frame(uint8_t *data, int32_t width, int32_t height, int32_t stride,
282 : int32_t border_horz, int32_t border_vert, int32_t highbd);
283 : void eb_decode_xq(const int32_t *xqd, int32_t *xq, const SgrParamsType *params);
284 :
285 : // Filter a single loop restoration unit.
286 : //
287 : // limits is the limits of the unit. rui gives the mode to use for this unit
288 : // and its coefficients. If striped loop restoration is enabled, rsb contains
289 : // deblocked pixels to use for stripe boundaries; rlbs is just some space to
290 : // use as a scratch buffer. tile_rect gives the limits of the tile containing
291 : // this unit. tile_stripe0 is the index of the first stripe in this tile.
292 : //
293 : // ss_x and ss_y are flags which should be 1 if this is a plane with
294 : // horizontal/vertical subsampling, respectively. highbd is a flag which should
295 : // be 1 in high bit depth mode, in which case bit_depth is the bit depth.
296 : //
297 : // data8 is the frame data (pointing at the top-left corner of the frame, not
298 : // the restoration unit) and stride is its stride. dst8 is the buffer where the
299 : // results will be written and has stride dst_stride. Like data8, dst8 should
300 : // point at the top-left corner of the frame.
301 : //
302 : // Finally tmpbuf is a scratch buffer used by the sgrproj filter which should
303 : // be at least SGRPROJ_TMPBUF_SIZE big.
304 : void eb_av1_loop_restoration_filter_unit(
305 : uint8_t need_bounadaries,
306 : const RestorationTileLimits *limits, const RestorationUnitInfo *rui,
307 : const RestorationStripeBoundaries *rsb, RestorationLineBuffers *rlbs,
308 : const AV1PixelRect *tile_rect, int32_t tile_stripe0, int32_t ss_x, int32_t ss_y,
309 : int32_t highbd, int32_t bit_depth, uint8_t *data8, int32_t stride, uint8_t *dst8,
310 : int32_t dst_stride, int32_t *tmpbuf, int32_t optimized_lr);
311 :
312 : void extend_lines(uint8_t *buf, int32_t width, int32_t height, int32_t stride,
313 : int32_t extend, int32_t use_highbitdepth);
314 :
315 : //void eb_av1_loop_restoration_filter_frame(Yv12BufferConfig *frame,
316 : // Av1Common *cm, int32_t optimized_lr);
317 : typedef void(*RestUnitVisitor)(const RestorationTileLimits *limits,
318 : const AV1PixelRect *tile_rect,
319 : int32_t rest_unit_idx, void *priv);
320 :
321 : typedef void(*RestTileStartVisitor)(int32_t tile_row, int32_t tile_col,
322 : void *priv);
323 :
324 : // Call on_rest_unit for each loop restoration unit in the frame. At the start
325 : // of each tile, call on_tile.
326 : //void av1_foreach_rest_unit_in_frame(Av1Common *cm, int32_t plane,
327 : // RestTileStartVisitor on_tile,
328 : // RestUnitVisitor on_rest_unit,
329 : // void *priv);
330 :
331 : // Return 1 iff the block at mi_row, mi_col with size bsize is a
332 : // top-level superblock containing the top-left corner of at least one
333 : // loop restoration unit.
334 : //
335 : // If the block is a top-level superblock, the function writes to
336 : // *rcol0, *rcol1, *rrow0, *rrow1. The rectangle of restoration unit
337 : // indices given by [*rcol0, *rcol1) x [*rrow0, *rrow1) are relative
338 : // to the current tile, whose starting index is returned as
339 : // *tile_tl_idx.
340 : //int32_t eb_av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int32_t plane,
341 : // int32_t mi_row, int32_t mi_col, BlockSize bsize,
342 : // int32_t *rcol0, int32_t *rcol1, int32_t *rrow0,
343 : // int32_t *rrow1, int32_t *tile_tl_idx);
344 :
345 : //void eb_av1_loop_restoration_save_boundary_lines(const Yv12BufferConfig *frame,
346 : // struct AV1Common *cm,
347 : // int32_t after_cdef);
348 :
349 : static const double TINY_NEAR_ZERO = 1.0E-16;
350 :
351 : // Solves Ax = b, where x and b are column vectors of size nx1 and A is nxn
352 : static INLINE int32_t linsolve(int32_t n, double *A, int32_t stride, double *b, double *x) {
353 : int32_t i, j, k;
354 : double c;
355 : // Forward elimination
356 : for (k = 0; k < n - 1; k++) {
357 : // Bring the largest magitude to the diagonal position
358 : for (i = n - 1; i > k; i--) {
359 : if (fabs(A[(i - 1) * stride + k]) < fabs(A[i * stride + k])) {
360 : for (j = 0; j < n; j++) {
361 : c = A[i * stride + j];
362 : A[i * stride + j] = A[(i - 1) * stride + j];
363 : A[(i - 1) * stride + j] = c;
364 : }
365 : c = b[i];
366 : b[i] = b[i - 1];
367 : b[i - 1] = c;
368 : }
369 : }
370 : for (i = k; i < n - 1; i++) {
371 : if (fabs(A[k * stride + k]) < TINY_NEAR_ZERO) return 0;
372 : c = A[(i + 1) * stride + k] / A[k * stride + k];
373 : for (j = 0; j < n; j++) A[(i + 1) * stride + j] -= c * A[k * stride + j];
374 : b[i + 1] -= c * b[k];
375 : }
376 : }
377 : // Backward substitution
378 : for (i = n - 1; i >= 0; i--) {
379 : if (fabs(A[i * stride + i]) < TINY_NEAR_ZERO) return 0;
380 : c = 0;
381 : for (j = i + 1; j <= n - 1; j++) c += A[i * stride + j] * x[j];
382 : x[i] = (b[i] - c) / A[i * stride + i];
383 : }
384 :
385 : return 1;
386 : }
387 :
388 : // Returns 1 if a superres upscaled frame is unscaled and 0 otherwise.
389 4272 : static INLINE int32_t av1_superres_unscaled(const FrameSize *frm_size) {
390 : // Note: for some corner cases (e.g. cm->width of 1), there may be no scaling
391 : // required even though cm->superres_scale_denominator != SCALE_NUMERATOR.
392 : // So, the following check is more accurate.
393 4272 : return (frm_size->frame_width == frm_size->superres_upscaled_width);
394 : }
395 :
396 : AV1PixelRect whole_frame_rect(FrameSize *frm_size, int32_t sub_x,
397 : int32_t sub_y, int32_t is_uv);
398 :
399 : #define RDDIV_BITS 7
400 : #define RD_EPB_SHIFT 6
401 :
402 : #define RDCOST_DBL(RM, R, D) \
403 : (((((double)(R)) * (RM)) / (double)(1 << AV1_PROB_COST_SHIFT)) + \
404 : ((double)(D) * (1 << RDDIV_BITS)))
405 :
406 : typedef struct RestUnitSearchInfo
407 : {
408 : // The best coefficients for Wiener or Sgrproj restoration
409 : WienerInfo wiener;
410 : SgrprojInfo sgrproj;
411 :
412 : // The sum of squared errors for this rtype.
413 : int64_t sse[RESTORE_SWITCHABLE_TYPES];
414 :
415 : // The rtype to use for this unit given a frame rtype as
416 : // index. Indices: WIENER, SGRPROJ, SWITCHABLE.
417 : RestorationType best_rtype[RESTORE_TYPES - 1];
418 : } RestUnitSearchInfo;
419 :
420 : #ifdef __cplusplus
421 : } // extern "C"
422 : #endif
423 :
424 : #endif // AV1_COMMON_RESTORATION_H_
|