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 https://www.aomedia.org/license/software-license. 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 https://www.aomedia.org/license/patent-license.
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 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 void svt_apply_selfguided_restoration_c(const uint8_t *dat8, int32_t width, int32_t height,
26                                         int32_t stride, int32_t eps, const int32_t *xqd,
27                                         uint8_t *dst8, int32_t dst_stride, int32_t *tmpbuf,
28                                         int32_t bit_depth, 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 + RESTORATION_PADDING) * \
77      (RESTORATION_PROC_UNIT_SIZE + RESTORATION_BORDER_VERT * 2 + RESTORATION_PADDING))
78 
79 #define RESTORATION_UNITSIZE_MAX 256
80 #define RESTORATION_UNITPELS_HORZ_MAX \
81     (RESTORATION_UNITSIZE_MAX * 3 / 2 + 2 * RESTORATION_BORDER_HORZ + 16)
82 #define RESTORATION_UNITPELS_VERT_MAX \
83     ((RESTORATION_UNITSIZE_MAX * 3 / 2 + 2 * RESTORATION_BORDER_VERT + RESTORATION_UNIT_OFFSET))
84 #define RESTORATION_UNITPELS_MAX (RESTORATION_UNITPELS_HORZ_MAX * RESTORATION_UNITPELS_VERT_MAX)
85 
86 // Two 32-bit buffers needed for the restored versions from two filters
87 #define SGRPROJ_TMPBUF_SIZE (RESTORATION_UNITPELS_MAX * 2 * sizeof(int32_t))
88 
89 #define SGRPROJ_EXTBUF_SIZE (0)
90 #define SGRPROJ_PARAMS_BITS 4
91 #define SGRPROJ_PARAMS (1 << SGRPROJ_PARAMS_BITS)
92 
93 // Precision bits for projection
94 #define SGRPROJ_PRJ_BITS 7
95 // Restoration precision bits generated higher than source before projection
96 #define SGRPROJ_RST_BITS 4
97 // Internal precision bits for core selfguided_restoration
98 #define SGRPROJ_SGR_BITS 8
99 #define SGRPROJ_SGR (1 << SGRPROJ_SGR_BITS)
100 
101 #define SGRPROJ_PRJ_MIN0 (-(1 << SGRPROJ_PRJ_BITS) * 3 / 4)
102 #define SGRPROJ_PRJ_MAX0 (SGRPROJ_PRJ_MIN0 + (1 << SGRPROJ_PRJ_BITS) - 1)
103 #define SGRPROJ_PRJ_MIN1 (-(1 << SGRPROJ_PRJ_BITS) / 4)
104 #define SGRPROJ_PRJ_MAX1 (SGRPROJ_PRJ_MIN1 + (1 << SGRPROJ_PRJ_BITS) - 1)
105 
106 #define SGRPROJ_PRJ_SUBEXP_K 4
107 
108 #define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)
109 
110 #define MAX_RADIUS 2 // Only 1, 2, 3 allowed
111 #define MAX_NELEM ((2 * MAX_RADIUS + 1) * (2 * MAX_RADIUS + 1))
112 #define SGRPROJ_MTABLE_BITS 20
113 #define SGRPROJ_RECIP_BITS 12
114 
115 #define WIENER_HALFWIN1 (WIENER_HALFWIN + 1)
116 #define WIENER_WIN (2 * WIENER_HALFWIN + 1)
117 #define WIENER_WIN2 ((WIENER_WIN) * (WIENER_WIN))
118 #define WIENER_TMPBUF_SIZE (0)
119 #define WIENER_EXTBUF_SIZE (0)
120 
121 // If WIENER_WIN_CHROMA == WIENER_WIN - 2, that implies 5x5 filters are used for
122 // chroma. To use 7x7 for chroma set WIENER_WIN_CHROMA to WIENER_WIN.
123 #define WIENER_WIN_CHROMA (WIENER_WIN - 2)
124 #define WIENER_WIN2_CHROMA ((WIENER_WIN_CHROMA) * (WIENER_WIN_CHROMA))
125 #define WIENER_FILT_PREC_BITS 7
126 #define WIENER_FILT_STEP (1 << WIENER_FILT_PREC_BITS)
127 #define WIENER_WIN_3TAP (WIENER_WIN - 4)
128 #define WIENER_WIN2_3TAP ((WIENER_WIN_3TAP) * (WIENER_WIN_3TAP))
129 
130 // Central values for the taps
131 #define WIENER_FILT_TAP0_MIDV (3)
132 #define WIENER_FILT_TAP1_MIDV (-7)
133 #define WIENER_FILT_TAP2_MIDV (15)
134 #define WIENER_FILT_TAP3_MIDV \
135     (WIENER_FILT_STEP - 2 * (WIENER_FILT_TAP0_MIDV + WIENER_FILT_TAP1_MIDV + WIENER_FILT_TAP2_MIDV))
136 
137 #define WIENER_FILT_TAP0_BITS 4
138 #define WIENER_FILT_TAP1_BITS 5
139 #define WIENER_FILT_TAP2_BITS 6
140 
141 #define WIENER_FILT_BITS \
142     ((WIENER_FILT_TAP0_BITS + WIENER_FILT_TAP1_BITS + WIENER_FILT_TAP2_BITS) * 2)
143 
144 #define WIENER_FILT_TAP0_MINV (WIENER_FILT_TAP0_MIDV - (1 << WIENER_FILT_TAP0_BITS) / 2)
145 #define WIENER_FILT_TAP1_MINV (WIENER_FILT_TAP1_MIDV - (1 << WIENER_FILT_TAP1_BITS) / 2)
146 #define WIENER_FILT_TAP2_MINV (WIENER_FILT_TAP2_MIDV - (1 << WIENER_FILT_TAP2_BITS) / 2)
147 
148 #define WIENER_FILT_TAP0_MAXV (WIENER_FILT_TAP0_MIDV - 1 + (1 << WIENER_FILT_TAP0_BITS) / 2)
149 #define WIENER_FILT_TAP1_MAXV (WIENER_FILT_TAP1_MIDV - 1 + (1 << WIENER_FILT_TAP1_BITS) / 2)
150 #define WIENER_FILT_TAP2_MAXV (WIENER_FILT_TAP2_MIDV - 1 + (1 << WIENER_FILT_TAP2_BITS) / 2)
151 
152 #define WIENER_FILT_TAP0_SUBEXP_K 1
153 #define WIENER_FILT_TAP1_SUBEXP_K 2
154 #define WIENER_FILT_TAP2_SUBEXP_K 3
155 
156 // Max of SGRPROJ_TMPBUF_SIZE, DOMAINTXFMRF_TMPBUF_SIZE, WIENER_TMPBUF_SIZE
157 #define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)
158 
159 // Max of SGRPROJ_EXTBUF_SIZE, WIENER_EXTBUF_SIZE
160 #define RESTORATION_EXTBUF_SIZE (WIENER_EXTBUF_SIZE)
161 
162 // Check the assumptions of the existing code
163 #if SUBPEL_TAPS != WIENER_WIN + 1
164 //#error "Wiener filter currently only works if SUBPEL_TAPS == WIENER_WIN + 1"
165 #endif
166 #if WIENER_FILT_PREC_BITS != 7
167 #error "Wiener filter currently only works if WIENER_FILT_PREC_BITS == 7"
168 #endif
169 
170 typedef struct WienerInfo {
171     DECLARE_ALIGNED(16, InterpKernel, vfilter);
172     DECLARE_ALIGNED(16, InterpKernel, hfilter);
173 } WienerInfo;
174 
175 typedef struct SgrprojInfo {
176     int32_t ep;
177     int32_t xqd[2];
178 } SgrprojInfo;
179 
180 // Similarly, the column buffers (used when we're at a vertical tile edge
181 // that we can't filter across) need space for one processing unit's worth
182 // of pixels, plus the top/bottom border width
183 #define RESTORATION_COLBUFFER_HEIGHT (RESTORATION_PROC_UNIT_SIZE + 2 * RESTORATION_BORDER)
184 
185 typedef struct RestorationUnitInfo {
186     RestorationType restoration_type;
187     WienerInfo      wiener_info;
188     SgrprojInfo     sgrproj_info;
189 } RestorationUnitInfo;
190 
191 typedef struct Av1PixelRect {
192     int32_t left, top, right, bottom;
193 } Av1PixelRect;
194 
195 // A restoration line buffer needs space for two lines plus a horizontal filter
196 // margin of RESTORATION_EXTRA_HORZ on each side.
197 #define RESTORATION_LINEBUFFER_WIDTH (RESTORATION_UNITSIZE_MAX * 3 / 2 + 2 * RESTORATION_EXTRA_HORZ)
198 
199 // Similarly, the column buffers (used when we're at a vertical tile edge
200 // that we can't filter across) need space for one processing unit's worth
201 // of pixels, plus the top/bottom border width
202 #define RESTORATION_COLBUFFER_HEIGHT (RESTORATION_PROC_UNIT_SIZE + 2 * RESTORATION_BORDER)
203 
204 typedef struct RestorationLineBuffers {
205     // Temporary buffers to save/restore 3 lines above/below the restoration
206     // stripe.
207     uint16_t tmp_save_above[RESTORATION_BORDER][RESTORATION_LINEBUFFER_WIDTH];
208     uint16_t tmp_save_below[RESTORATION_BORDER][RESTORATION_LINEBUFFER_WIDTH];
209 
210     // Temporary buffers to save/restore 4 column left/right of a processing unit.
211     uint16_t tmp_save_cdef[MAX_SB_SIZE + RESTORATION_UNIT_OFFSET][RESTORATION_EXTRA_HORZ];
212     uint16_t tmp_save_lr[MAX_SB_SIZE + RESTORATION_UNIT_OFFSET][RESTORATION_EXTRA_HORZ];
213 } RestorationLineBuffers;
214 
215 typedef struct RestorationStripeBoundaries {
216     uint8_t *stripe_boundary_above;
217     uint8_t *stripe_boundary_below;
218     int32_t  stripe_boundary_stride;
219     int32_t  stripe_boundary_size;
220 } RestorationStripeBoundaries;
221 
222 typedef struct RestorationInfo {
223     RestorationType frame_restoration_type;
224     int32_t         restoration_unit_size;
225 
226     // Fields below here are allocated and initialised by
227     // svt_av1_alloc_restoration_struct. (horz_)units_per_tile give the number of
228     // restoration units in (one row of) the largest tile in the frame. The data
229     // in unit_info is laid out with units_per_tile entries for each tile, which
230     // have stride horz_units_per_tile.
231     //
232     // Even if there are tiles of different sizes, the data in unit_info is laid
233     // out as if all tiles are of full size.
234     int32_t                     units_per_tile;
235     int32_t                     vert_units_per_tile, horz_units_per_tile;
236     RestorationUnitInfo *       unit_info;
237     RestorationStripeBoundaries boundaries;
238     int32_t                     optimized_lr;
239 } RestorationInfo;
240 
set_default_sgrproj(SgrprojInfo * sgrproj_info)241 static INLINE void set_default_sgrproj(SgrprojInfo *sgrproj_info) {
242     sgrproj_info->xqd[0] = (SGRPROJ_PRJ_MIN0 + SGRPROJ_PRJ_MAX0) / 2;
243     sgrproj_info->xqd[1] = (SGRPROJ_PRJ_MIN1 + SGRPROJ_PRJ_MAX1) / 2;
244 }
245 
set_default_wiener(WienerInfo * wiener_info)246 static INLINE void set_default_wiener(WienerInfo *wiener_info) {
247     wiener_info->vfilter[0] = wiener_info->hfilter[0] = WIENER_FILT_TAP0_MIDV;
248     wiener_info->vfilter[1] = wiener_info->hfilter[1] = WIENER_FILT_TAP1_MIDV;
249     wiener_info->vfilter[2] = wiener_info->hfilter[2] = WIENER_FILT_TAP2_MIDV;
250     wiener_info->vfilter[WIENER_HALFWIN] = wiener_info->hfilter[WIENER_HALFWIN] = -2 *
251         (WIENER_FILT_TAP2_MIDV + WIENER_FILT_TAP1_MIDV + WIENER_FILT_TAP0_MIDV);
252     wiener_info->vfilter[4] = wiener_info->hfilter[4] = WIENER_FILT_TAP2_MIDV;
253     wiener_info->vfilter[5] = wiener_info->hfilter[5] = WIENER_FILT_TAP1_MIDV;
254     wiener_info->vfilter[6] = wiener_info->hfilter[6] = WIENER_FILT_TAP0_MIDV;
255 }
256 
257 typedef struct RestorationTileLimits {
258     int32_t h_start, h_end, v_start, v_end;
259 } RestorationTileLimits;
260 
261 extern const SgrParamsType eb_sgr_params[SGRPROJ_PARAMS];
262 extern int32_t             sgrproj_mtable[SGRPROJ_PARAMS][2];
263 extern const int32_t       eb_x_by_xplus1[256];
264 extern const int32_t       eb_one_by_x[MAX_NELEM];
265 
266 //void svt_av1_alloc_restoration_struct(struct Av1Common *cm, RestorationInfo *rsi,
267 //                                      int32_t is_uv);
268 void svt_extend_frame(uint8_t *data, int32_t width, int32_t height, int32_t stride,
269                       int32_t border_horz, int32_t border_vert, int32_t highbd);
270 void svt_decode_xq(const int32_t *xqd, int32_t *xq, const SgrParamsType *params);
271 
272 // Filter a single loop restoration unit.
273 //
274 // limits is the limits of the unit. rui gives the mode to use for this unit
275 // and its coefficients. If striped loop restoration is enabled, rsb contains
276 // deblocked pixels to use for stripe boundaries; rlbs is just some space to
277 // use as a scratch buffer. tile_rect gives the limits of the tile containing
278 // this unit. tile_stripe0 is the index of the first stripe in this tile.
279 //
280 // ss_x and ss_y are flags which should be 1 if this is a plane with
281 // horizontal/vertical subsampling, respectively. highbd is a flag which should
282 // be 1 in high bit depth mode, in which case bit_depth is the bit depth.
283 //
284 // data8 is the frame data (pointing at the top-left corner of the frame, not
285 // the restoration unit) and stride is its stride. dst8 is the buffer where the
286 // results will be written and has stride dst_stride. Like data8, dst8 should
287 // point at the top-left corner of the frame.
288 //
289 // Finally tmpbuf is a scratch buffer used by the sgrproj filter which should
290 // be at least SGRPROJ_TMPBUF_SIZE big.
291 void svt_av1_loop_restoration_filter_unit(
292     uint8_t need_bounadaries, const RestorationTileLimits *limits, const RestorationUnitInfo *rui,
293     const RestorationStripeBoundaries *rsb, RestorationLineBuffers *rlbs,
294     const Av1PixelRect *tile_rect, int32_t tile_stripe0, int32_t ss_x, int32_t ss_y, int32_t highbd,
295     int32_t bit_depth, uint8_t *data8, int32_t stride, uint8_t *dst8, int32_t dst_stride,
296     int32_t *tmpbuf, int32_t optimized_lr);
297 
298 void extend_lines(uint8_t *buf, int32_t width, int32_t height, int32_t stride, int32_t extend,
299                   int32_t use_highbitdepth);
300 
301 //void svt_av1_loop_restoration_filter_frame(Yv12BufferConfig *frame,
302 //                                           Av1Common *cm, int32_t optimized_lr);
303 typedef void (*RestUnitVisitor)(const RestorationTileLimits *limits, const Av1PixelRect *tile_rect,
304                                 int32_t rest_unit_idx, void *priv);
305 
306 typedef void (*RestTileStartVisitor)(int32_t tile_row, int32_t tile_col, void *priv);
307 
308 // Call on_rest_unit for each loop restoration unit in the frame. At the start
309 // of each tile, call on_tile.
310 //void av1_foreach_rest_unit_in_frame(Av1Common *cm, int32_t plane,
311 //                                    RestTileStartVisitor on_tile,
312 //                                    RestUnitVisitor on_rest_unit,
313 //                                    void *priv);
314 
315 // Return 1 iff the block at mi_row, mi_col with size bsize is a
316 // top-level superblock containing the top-left corner of at least one
317 // loop restoration unit.
318 //
319 // If the block is a top-level superblock, the function writes to
320 // *rcol0, *rcol1, *rrow0, *rrow1. The rectangle of restoration unit
321 // indices given by [*rcol0, *rcol1) x [*rrow0, *rrow1) are relative
322 // to the current tile, whose starting index is returned as
323 // *tile_tl_idx.
324 //int32_t svt_av1_loop_restoration_corners_in_sb(const struct AV1Common *cm, int32_t plane,
325 //                                       int32_t mi_row, int32_t mi_col, BlockSize bsize,
326 //                                       int32_t *rcol0, int32_t *rcol1, int32_t *rrow0,
327 //                                       int32_t *rrow1, int32_t *tile_tl_idx);
328 
329 //void svt_av1_loop_restoration_save_boundary_lines(const Yv12BufferConfig *frame,
330 //                                                  struct AV1Common *cm,
331 //                                                  int32_t after_cdef);
332 
333 static const double tiny_near_zero = 1.0E-16;
334 
335 // Solves Ax = b, where x and b are column vectors of size nx1 and A is nxn
linsolve(int32_t n,double * A,int32_t stride,double * b,double * x)336 static INLINE int32_t linsolve(int32_t n, double *A, int32_t stride, double *b, double *x) {
337     int32_t i, j, k;
338     double  c;
339     // Forward elimination
340     for (k = 0; k < n - 1; k++) {
341         // Bring the largest magitude to the diagonal position
342         for (i = n - 1; i > k; i--) {
343             if (fabs(A[(i - 1) * stride + k]) < fabs(A[i * stride + k])) {
344                 for (j = 0; j < n; j++) {
345                     c                       = A[i * stride + j];
346                     A[i * stride + j]       = A[(i - 1) * stride + j];
347                     A[(i - 1) * stride + j] = c;
348                 }
349                 c        = b[i];
350                 b[i]     = b[i - 1];
351                 b[i - 1] = c;
352             }
353         }
354         for (i = k; i < n - 1; i++) {
355             if (fabs(A[k * stride + k]) < tiny_near_zero)
356                 return 0;
357             c = A[(i + 1) * stride + k] / A[k * stride + k];
358             for (j = 0; j < n; j++) A[(i + 1) * stride + j] -= c * A[k * stride + j];
359             b[i + 1] -= c * b[k];
360         }
361     }
362     // Backward substitution
363     for (i = n - 1; i >= 0; i--) {
364         if (fabs(A[i * stride + i]) < tiny_near_zero)
365             return 0;
366         c = 0;
367         for (j = i + 1; j <= n - 1; j++) c += A[i * stride + j] * x[j];
368         x[i] = (b[i] - c) / A[i * stride + i];
369     }
370 
371     return 1;
372 }
373 
374 // Returns 1 if a superres upscaled frame is unscaled and 0 otherwise.
av1_superres_unscaled(const FrameSize * frm_size)375 static INLINE int32_t av1_superres_unscaled(const FrameSize *frm_size) {
376     return (frm_size->frame_width == frm_size->superres_upscaled_width);
377 }
378 
379 Av1PixelRect whole_frame_rect(FrameSize *frm_size, int32_t sub_x, int32_t sub_y, int32_t is_uv);
380 
381 #define RDDIV_BITS 7
382 #define RD_EPB_SHIFT 6
383 
384 #define RDCOST_DBL(RM, R, D)                                         \
385     (((((double)(R)) * (RM)) / (double)(1 << AV1_PROB_COST_SHIFT)) + \
386      ((double)(D) * (1 << RDDIV_BITS)))
387 
388 typedef struct RestUnitSearchInfo {
389     // The best coefficients for Wiener or Sgrproj restoration
390     WienerInfo  wiener;
391     SgrprojInfo sgrproj;
392 
393     // The sum of squared errors for this rtype.
394     int64_t sse[RESTORE_SWITCHABLE_TYPES];
395 
396     // The rtype to use for this unit given a frame rtype as
397     // index. Indices: WIENER, SGRPROJ, SWITCHABLE.
398     RestorationType best_rtype[RESTORE_TYPES - 1];
399 } RestUnitSearchInfo;
400 
401 #define NUM_STRIPE_FILTERS 4
402 
403 void wiener_filter_stripe(const RestorationUnitInfo *rui, int32_t stripe_width,
404                           int32_t stripe_height, int32_t procunit_width, const uint8_t *src,
405                           int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t *tmpbuf,
406                           int32_t bit_depth);
407 void sgrproj_filter_stripe(const RestorationUnitInfo *rui, int32_t stripe_width,
408                            int32_t stripe_height, int32_t procunit_width, const uint8_t *src,
409                            int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t *tmpbuf,
410                            int32_t bit_depth);
411 void wiener_filter_stripe_highbd(const RestorationUnitInfo *rui, int32_t stripe_width,
412                                  int32_t stripe_height, int32_t procunit_width, const uint8_t *src8,
413                                  int32_t src_stride, uint8_t *dst8, int32_t dst_stride,
414                                  int32_t *tmpbuf, int32_t bit_depth);
415 void sgrproj_filter_stripe_highbd(const RestorationUnitInfo *rui, int32_t stripe_width,
416                                   int32_t stripe_height, int32_t procunit_width,
417                                   const uint8_t *src8, int32_t src_stride, uint8_t *dst8,
418                                   int32_t dst_stride, int32_t *tmpbuf, int32_t bit_depth);
419 
420 void get_stripe_boundary_info(const RestorationTileLimits *limits, const Av1PixelRect *tile_rect,
421                               int32_t ss_y, int32_t *copy_above, int32_t *copy_below);
422 void setup_processing_stripe_boundary(const RestorationTileLimits *      limits,
423                                       const RestorationStripeBoundaries *rsb, int32_t rsb_row,
424                                       int32_t use_highbd, int32_t h, uint8_t *data8,
425                                       int32_t data_stride, RestorationLineBuffers *rlbs,
426                                       int32_t copy_above, int32_t copy_below, int32_t opt);
427 void restore_processing_stripe_boundary(const RestorationTileLimits * limits,
428                                         const RestorationLineBuffers *rlbs, int32_t use_highbd,
429                                         int32_t h, uint8_t *data8, int32_t data_stride,
430                                         int32_t copy_above, int32_t copy_below, int32_t opt);
431 
432 typedef void (*StripeFilterFun)(const RestorationUnitInfo *rui, int32_t stripe_width,
433                                 int32_t stripe_height, int32_t procunit_width, const uint8_t *src,
434                                 int32_t src_stride, uint8_t *dst, int32_t dst_stride,
435                                 int32_t *tmpbuf, int32_t bit_depth);
436 
437 void copy_tile(int32_t width, int32_t height, const uint8_t *src, int32_t src_stride, uint8_t *dst,
438                int32_t dst_stride, int32_t highbd);
439 #ifdef __cplusplus
440 } // extern "C"
441 #endif
442 
443 #endif // AV1_COMMON_RESTORATION_H_
444