/src/dav1d/src/lr_apply_tmpl.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright © 2018, VideoLAN and dav1d authors |
3 | | * Copyright © 2018, Two Orioles, LLC |
4 | | * All rights reserved. |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following conditions are met: |
8 | | * |
9 | | * 1. Redistributions of source code must retain the above copyright notice, this |
10 | | * list of conditions and the following disclaimer. |
11 | | * |
12 | | * 2. Redistributions in binary form must reproduce the above copyright notice, |
13 | | * this list of conditions and the following disclaimer in the documentation |
14 | | * and/or other materials provided with the distribution. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
20 | | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | */ |
27 | | |
28 | | #include "config.h" |
29 | | |
30 | | #include <stdio.h> |
31 | | |
32 | | #include "common/intops.h" |
33 | | |
34 | | #include "src/lr_apply.h" |
35 | | |
36 | | static void lr_stripe(const Dav1dFrameContext *const f, pixel *p, |
37 | | const pixel (*left)[4], int x, int y, |
38 | | const int plane, const int unit_w, const int row_h, |
39 | | const Av1RestorationUnit *const lr, enum LrEdgeFlags edges) |
40 | 74.5k | { |
41 | 74.5k | const Dav1dDSPContext *const dsp = f->dsp; |
42 | 74.5k | const int chroma = !!plane; |
43 | 74.5k | const int ss_ver = chroma & (f->sr_cur.p.p.layout == DAV1D_PIXEL_LAYOUT_I420); |
44 | 74.5k | const ptrdiff_t stride = f->sr_cur.p.stride[chroma]; |
45 | 74.5k | const int sby = (y + (y ? 8 << ss_ver : 0)) >> (6 - ss_ver + f->seq_hdr->sb128); |
46 | 74.5k | const int have_tt = f->c->n_tc > 1; |
47 | 74.5k | const pixel *lpf = f->lf.lr_lpf_line[plane] + |
48 | 74.5k | have_tt * (sby * (4 << f->seq_hdr->sb128) - 4) * PXSTRIDE(stride) + x; |
49 | | |
50 | | // The first stripe of the frame is shorter by 8 luma pixel rows. |
51 | 74.5k | int stripe_h = imin((64 - 8 * !y) >> ss_ver, row_h - y); |
52 | | |
53 | 74.5k | looprestorationfilter_fn lr_fn; |
54 | 74.5k | LooprestorationParams params; |
55 | 74.5k | if (lr->type == DAV1D_RESTORATION_WIENER) { |
56 | 31.2k | int16_t (*const filter)[8] = params.filter; |
57 | 31.2k | filter[0][0] = filter[0][6] = lr->filter_h[0]; |
58 | 31.2k | filter[0][1] = filter[0][5] = lr->filter_h[1]; |
59 | 31.2k | filter[0][2] = filter[0][4] = lr->filter_h[2]; |
60 | 31.2k | filter[0][3] = -(filter[0][0] + filter[0][1] + filter[0][2]) * 2; |
61 | | #if BITDEPTH != 8 |
62 | | /* For 8-bit SIMD it's beneficial to handle the +128 separately |
63 | | * in order to avoid overflows. */ |
64 | | filter[0][3] += 128; |
65 | | #endif |
66 | | |
67 | 31.2k | filter[1][0] = filter[1][6] = lr->filter_v[0]; |
68 | 31.2k | filter[1][1] = filter[1][5] = lr->filter_v[1]; |
69 | 31.2k | filter[1][2] = filter[1][4] = lr->filter_v[2]; |
70 | 31.2k | filter[1][3] = 128 - (filter[1][0] + filter[1][1] + filter[1][2]) * 2; |
71 | | |
72 | 31.2k | lr_fn = dsp->lr.wiener[!(filter[0][0] | filter[1][0])]; |
73 | 43.3k | } else { |
74 | 43.3k | assert(lr->type >= DAV1D_RESTORATION_SGRPROJ); |
75 | 43.3k | const int sgr_idx = lr->type - DAV1D_RESTORATION_SGRPROJ; |
76 | 43.3k | const uint16_t *const sgr_params = dav1d_sgr_params[sgr_idx]; |
77 | 43.3k | params.sgr.s0 = sgr_params[0]; |
78 | 43.3k | params.sgr.s1 = sgr_params[1]; |
79 | 43.3k | params.sgr.w0 = lr->sgr_weights[0]; |
80 | 43.3k | params.sgr.w1 = 128 - (lr->sgr_weights[0] + lr->sgr_weights[1]); |
81 | | |
82 | 43.3k | lr_fn = dsp->lr.sgr[!!sgr_params[0] + !!sgr_params[1] * 2 - 1]; |
83 | 43.3k | } |
84 | | |
85 | 127k | while (y + stripe_h <= row_h) { |
86 | | // Change the HAVE_BOTTOM bit in edges to (sby + 1 != f->sbh || y + stripe_h != row_h) |
87 | 127k | edges ^= (-(sby + 1 != f->sbh || y + stripe_h != row_h) ^ edges) & LR_HAVE_BOTTOM; |
88 | 127k | lr_fn(p, stride, left, lpf, unit_w, stripe_h, ¶ms, edges HIGHBD_CALL_SUFFIX); |
89 | | |
90 | 127k | left += stripe_h; |
91 | 127k | y += stripe_h; |
92 | 127k | p += stripe_h * PXSTRIDE(stride); |
93 | 127k | edges |= LR_HAVE_TOP; |
94 | 127k | stripe_h = imin(64 >> ss_ver, row_h - y); |
95 | 127k | if (stripe_h == 0) break; |
96 | 52.5k | lpf += 4 * PXSTRIDE(stride); |
97 | 52.5k | } |
98 | 74.5k | } |
99 | | |
100 | | static void backup4xU(pixel (*dst)[4], const pixel *src, const ptrdiff_t src_stride, |
101 | | int u) |
102 | 42.5k | { |
103 | 3.51M | for (; u > 0; u--, dst++, src += PXSTRIDE(src_stride)) |
104 | 3.47M | pixel_copy(dst, src, 4); |
105 | 42.5k | } |
106 | | |
107 | | static void lr_sbrow(const Dav1dFrameContext *const f, pixel *p, const int y, |
108 | | const int w, const int h, const int row_h, const int plane) |
109 | 248k | { |
110 | 248k | const int chroma = !!plane; |
111 | 248k | const int ss_ver = chroma & (f->sr_cur.p.p.layout == DAV1D_PIXEL_LAYOUT_I420); |
112 | 248k | const int ss_hor = chroma & (f->sr_cur.p.p.layout != DAV1D_PIXEL_LAYOUT_I444); |
113 | 248k | const ptrdiff_t p_stride = f->sr_cur.p.stride[chroma]; |
114 | | |
115 | 248k | const int unit_size_log2 = f->frame_hdr->restoration.unit_size[!!plane]; |
116 | 248k | const int unit_size = 1 << unit_size_log2; |
117 | 248k | const int half_unit_size = unit_size >> 1; |
118 | 248k | const int max_unit_size = unit_size + half_unit_size; |
119 | | |
120 | | // Y coordinate of the sbrow (y is 8 luma pixel rows above row_y) |
121 | 248k | const int row_y = y + ((8 >> ss_ver) * !!y); |
122 | | |
123 | | // FIXME This is an ugly hack to lookup the proper AV1Filter unit for |
124 | | // chroma planes. Question: For Multithreaded decoding, is it better |
125 | | // to store the chroma LR information with collocated Luma information? |
126 | | // In other words. For a chroma restoration unit locate at 128,128 and |
127 | | // with a 4:2:0 chroma subsampling, do we store the filter information at |
128 | | // the AV1Filter unit located at (128,128) or (256,256) |
129 | | // TODO Support chroma subsampling. |
130 | 248k | const int shift_hor = 7 - ss_hor; |
131 | | |
132 | | /* maximum sbrow height is 128 + 8 rows offset */ |
133 | 248k | ALIGN_STK_16(pixel, pre_lr_border, 2, [128 + 8][4]); |
134 | 248k | const Av1RestorationUnit *lr[2]; |
135 | | |
136 | 248k | enum LrEdgeFlags edges = (y > 0 ? LR_HAVE_TOP : 0) | LR_HAVE_RIGHT; |
137 | | |
138 | 248k | int aligned_unit_pos = row_y & ~(unit_size - 1); |
139 | 248k | if (aligned_unit_pos && aligned_unit_pos + half_unit_size > h) |
140 | 5.99k | aligned_unit_pos -= unit_size; |
141 | 248k | aligned_unit_pos <<= ss_ver; |
142 | 248k | const int sb_idx = (aligned_unit_pos >> 7) * f->sr_sb128w; |
143 | 248k | const int unit_idx = ((aligned_unit_pos >> 6) & 1) << 1; |
144 | 248k | lr[0] = &f->lf.lr_mask[sb_idx].lr[plane][unit_idx]; |
145 | 248k | int restore = lr[0]->type != DAV1D_RESTORATION_NONE; |
146 | 248k | int x = 0, bit = 0; |
147 | 319k | for (; x + max_unit_size <= w; p += unit_size, edges |= LR_HAVE_LEFT, bit ^= 1) { |
148 | 70.9k | const int next_x = x + unit_size; |
149 | 70.9k | const int next_u_idx = unit_idx + ((next_x >> (shift_hor - 1)) & 1); |
150 | 70.9k | lr[!bit] = |
151 | 70.9k | &f->lf.lr_mask[sb_idx + (next_x >> shift_hor)].lr[plane][next_u_idx]; |
152 | 70.9k | const int restore_next = lr[!bit]->type != DAV1D_RESTORATION_NONE; |
153 | 70.9k | if (restore_next) |
154 | 42.5k | backup4xU(pre_lr_border[bit], p + unit_size - 4, p_stride, row_h - y); |
155 | 70.9k | if (restore) |
156 | 42.6k | lr_stripe(f, p, pre_lr_border[!bit], x, y, plane, unit_size, row_h, |
157 | 42.6k | lr[bit], edges); |
158 | 70.9k | x = next_x; |
159 | 70.9k | restore = restore_next; |
160 | 70.9k | } |
161 | 248k | if (restore) { |
162 | 31.8k | edges &= ~LR_HAVE_RIGHT; |
163 | 31.8k | const int unit_w = w - x; |
164 | 31.8k | lr_stripe(f, p, pre_lr_border[!bit], x, y, plane, unit_w, row_h, lr[bit], edges); |
165 | 31.8k | } |
166 | 248k | } |
167 | | |
168 | | void bytefn(dav1d_lr_sbrow)(Dav1dFrameContext *const f, pixel *const dst[3], |
169 | | const int sby) |
170 | 218k | { |
171 | 218k | const int offset_y = 8 * !!sby; |
172 | 218k | const ptrdiff_t *const dst_stride = f->sr_cur.p.stride; |
173 | 218k | const int restore_planes = f->lf.restore_planes; |
174 | 218k | const int not_last = sby + 1 < f->sbh; |
175 | | |
176 | 218k | if (restore_planes & LR_RESTORE_Y) { |
177 | 209k | const int h = f->sr_cur.p.p.h; |
178 | 209k | const int w = f->sr_cur.p.p.w; |
179 | 209k | const int next_row_y = (sby + 1) << (6 + f->seq_hdr->sb128); |
180 | 209k | const int row_h = imin(next_row_y - 8 * not_last, h); |
181 | 209k | const int y_stripe = (sby << (6 + f->seq_hdr->sb128)) - offset_y; |
182 | 209k | lr_sbrow(f, dst[0] - offset_y * PXSTRIDE(dst_stride[0]), y_stripe, w, |
183 | 209k | h, row_h, 0); |
184 | 209k | } |
185 | 218k | if (restore_planes & (LR_RESTORE_U | LR_RESTORE_V)) { |
186 | 26.8k | const int ss_ver = f->sr_cur.p.p.layout == DAV1D_PIXEL_LAYOUT_I420; |
187 | 26.8k | const int ss_hor = f->sr_cur.p.p.layout != DAV1D_PIXEL_LAYOUT_I444; |
188 | 26.8k | const int h = (f->sr_cur.p.p.h + ss_ver) >> ss_ver; |
189 | 26.8k | const int w = (f->sr_cur.p.p.w + ss_hor) >> ss_hor; |
190 | 26.8k | const int next_row_y = (sby + 1) << ((6 - ss_ver) + f->seq_hdr->sb128); |
191 | 26.8k | const int row_h = imin(next_row_y - (8 >> ss_ver) * not_last, h); |
192 | 26.8k | const int offset_uv = offset_y >> ss_ver; |
193 | 26.8k | const int y_stripe = (sby << ((6 - ss_ver) + f->seq_hdr->sb128)) - offset_uv; |
194 | 26.8k | if (restore_planes & LR_RESTORE_U) |
195 | 16.7k | lr_sbrow(f, dst[1] - offset_uv * PXSTRIDE(dst_stride[1]), y_stripe, |
196 | 16.7k | w, h, row_h, 1); |
197 | | |
198 | 26.8k | if (restore_planes & LR_RESTORE_V) |
199 | 22.2k | lr_sbrow(f, dst[2] - offset_uv * PXSTRIDE(dst_stride[1]), y_stripe, |
200 | 22.2k | w, h, row_h, 2); |
201 | 26.8k | } |
202 | 218k | } Line | Count | Source | 170 | 150k | { | 171 | 150k | const int offset_y = 8 * !!sby; | 172 | 150k | const ptrdiff_t *const dst_stride = f->sr_cur.p.stride; | 173 | 150k | const int restore_planes = f->lf.restore_planes; | 174 | 150k | const int not_last = sby + 1 < f->sbh; | 175 | | | 176 | 150k | if (restore_planes & LR_RESTORE_Y) { | 177 | 143k | const int h = f->sr_cur.p.p.h; | 178 | 143k | const int w = f->sr_cur.p.p.w; | 179 | 143k | const int next_row_y = (sby + 1) << (6 + f->seq_hdr->sb128); | 180 | 143k | const int row_h = imin(next_row_y - 8 * not_last, h); | 181 | 143k | const int y_stripe = (sby << (6 + f->seq_hdr->sb128)) - offset_y; | 182 | 143k | lr_sbrow(f, dst[0] - offset_y * PXSTRIDE(dst_stride[0]), y_stripe, w, | 183 | 143k | h, row_h, 0); | 184 | 143k | } | 185 | 150k | if (restore_planes & (LR_RESTORE_U | LR_RESTORE_V)) { | 186 | 12.9k | const int ss_ver = f->sr_cur.p.p.layout == DAV1D_PIXEL_LAYOUT_I420; | 187 | 12.9k | const int ss_hor = f->sr_cur.p.p.layout != DAV1D_PIXEL_LAYOUT_I444; | 188 | 12.9k | const int h = (f->sr_cur.p.p.h + ss_ver) >> ss_ver; | 189 | 12.9k | const int w = (f->sr_cur.p.p.w + ss_hor) >> ss_hor; | 190 | 12.9k | const int next_row_y = (sby + 1) << ((6 - ss_ver) + f->seq_hdr->sb128); | 191 | 12.9k | const int row_h = imin(next_row_y - (8 >> ss_ver) * not_last, h); | 192 | 12.9k | const int offset_uv = offset_y >> ss_ver; | 193 | 12.9k | const int y_stripe = (sby << ((6 - ss_ver) + f->seq_hdr->sb128)) - offset_uv; | 194 | 12.9k | if (restore_planes & LR_RESTORE_U) | 195 | 5.96k | lr_sbrow(f, dst[1] - offset_uv * PXSTRIDE(dst_stride[1]), y_stripe, | 196 | 5.96k | w, h, row_h, 1); | 197 | | | 198 | 12.9k | if (restore_planes & LR_RESTORE_V) | 199 | 10.6k | lr_sbrow(f, dst[2] - offset_uv * PXSTRIDE(dst_stride[1]), y_stripe, | 200 | 10.6k | w, h, row_h, 2); | 201 | 12.9k | } | 202 | 150k | } |
Line | Count | Source | 170 | 68.5k | { | 171 | 68.5k | const int offset_y = 8 * !!sby; | 172 | 68.5k | const ptrdiff_t *const dst_stride = f->sr_cur.p.stride; | 173 | 68.5k | const int restore_planes = f->lf.restore_planes; | 174 | 68.5k | const int not_last = sby + 1 < f->sbh; | 175 | | | 176 | 68.5k | if (restore_planes & LR_RESTORE_Y) { | 177 | 65.6k | const int h = f->sr_cur.p.p.h; | 178 | 65.6k | const int w = f->sr_cur.p.p.w; | 179 | 65.6k | const int next_row_y = (sby + 1) << (6 + f->seq_hdr->sb128); | 180 | 65.6k | const int row_h = imin(next_row_y - 8 * not_last, h); | 181 | 65.6k | const int y_stripe = (sby << (6 + f->seq_hdr->sb128)) - offset_y; | 182 | 65.6k | lr_sbrow(f, dst[0] - offset_y * PXSTRIDE(dst_stride[0]), y_stripe, w, | 183 | 65.6k | h, row_h, 0); | 184 | 65.6k | } | 185 | 68.5k | if (restore_planes & (LR_RESTORE_U | LR_RESTORE_V)) { | 186 | 13.9k | const int ss_ver = f->sr_cur.p.p.layout == DAV1D_PIXEL_LAYOUT_I420; | 187 | 13.9k | const int ss_hor = f->sr_cur.p.p.layout != DAV1D_PIXEL_LAYOUT_I444; | 188 | 13.9k | const int h = (f->sr_cur.p.p.h + ss_ver) >> ss_ver; | 189 | 13.9k | const int w = (f->sr_cur.p.p.w + ss_hor) >> ss_hor; | 190 | 13.9k | const int next_row_y = (sby + 1) << ((6 - ss_ver) + f->seq_hdr->sb128); | 191 | 13.9k | const int row_h = imin(next_row_y - (8 >> ss_ver) * not_last, h); | 192 | 13.9k | const int offset_uv = offset_y >> ss_ver; | 193 | 13.9k | const int y_stripe = (sby << ((6 - ss_ver) + f->seq_hdr->sb128)) - offset_uv; | 194 | 13.9k | if (restore_planes & LR_RESTORE_U) | 195 | 10.8k | lr_sbrow(f, dst[1] - offset_uv * PXSTRIDE(dst_stride[1]), y_stripe, | 196 | 10.8k | w, h, row_h, 1); | 197 | | | 198 | 13.9k | if (restore_planes & LR_RESTORE_V) | 199 | 11.6k | lr_sbrow(f, dst[2] - offset_uv * PXSTRIDE(dst_stride[1]), y_stripe, | 200 | 11.6k | w, h, row_h, 2); | 201 | 13.9k | } | 202 | 68.5k | } |
|