Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * VVC filters | ||
3 | * | ||
4 | * Copyright (C) 2021 Nuo Mi | ||
5 | * | ||
6 | * This file is part of FFmpeg. | ||
7 | * | ||
8 | * FFmpeg is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2.1 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * FFmpeg is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with FFmpeg; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | #include "libavutil/frame.h" | ||
23 | |||
24 | #include "ctu.h" | ||
25 | #include "data.h" | ||
26 | #include "filter.h" | ||
27 | #include "refs.h" | ||
28 | |||
29 | #define LEFT 0 | ||
30 | #define TOP 1 | ||
31 | #define RIGHT 2 | ||
32 | #define BOTTOM 3 | ||
33 | #define MAX_EDGES 4 | ||
34 | |||
35 | #define DEFAULT_INTRA_TC_OFFSET 2 | ||
36 | |||
37 | //Table 43 Derivation of threshold variables beta' and tc' from input Q | ||
38 | static const uint16_t tctable[66] = { | ||
39 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
40 | 0, 0, 3, 4, 4, 4, 4, 5, 5, 5, 5, 7, 7, 8, 9, 10, | ||
41 | 10, 11, 13, 14, 15, 17, 19, 21, 24, 25, 29, 33, 36, 41, 45, 51, | ||
42 | 57, 64, 71, 80, 89, 100, 112, 125, 141, 157, 177, 198, 222, 250, 280, 314, | ||
43 | 352, 395, | ||
44 | }; | ||
45 | |||
46 | //Table 43 Derivation of threshold variables beta' and tc' from input Q | ||
47 | static const uint8_t betatable[64] = { | ||
48 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
49 | 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, | ||
50 | 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, | ||
51 | 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, | ||
52 | }; | ||
53 | |||
54 | 6283108 | static int get_qPc(const VVCFrameContext *fc, const int x0, const int y0, const int chroma) | |
55 | { | ||
56 | 6283108 | const int x = x0 >> MIN_TU_LOG2; | |
57 | 6283108 | const int y = y0 >> MIN_TU_LOG2; | |
58 | 6283108 | const int min_tu_width = fc->ps.pps->min_tu_width; | |
59 | 6283108 | return fc->tab.qp[chroma][x + y * min_tu_width]; | |
60 | } | ||
61 | |||
62 | 44864 | static void copy_ctb(uint8_t *dst, const uint8_t *src, const int width, const int height, | |
63 | const ptrdiff_t dst_stride, const ptrdiff_t src_stride) | ||
64 | { | ||
65 |
2/2✓ Branch 0 taken 4426884 times.
✓ Branch 1 taken 44864 times.
|
4471748 | for (int y = 0; y < height; y++) { |
66 | 4426884 | memcpy(dst, src, width); | |
67 | |||
68 | 4426884 | dst += dst_stride; | |
69 | 4426884 | src += src_stride; | |
70 | } | ||
71 | 44864 | } | |
72 | |||
73 | 19272 | static void copy_pixel(uint8_t *dst, const uint8_t *src, const int pixel_shift) | |
74 | { | ||
75 |
1/2✓ Branch 0 taken 19272 times.
✗ Branch 1 not taken.
|
19272 | if (pixel_shift) |
76 | 19272 | *(uint16_t *)dst = *(uint16_t *)src; | |
77 | else | ||
78 | ✗ | *dst = *src; | |
79 | 19272 | } | |
80 | |||
81 | 264958 | static void copy_vert(uint8_t *dst, const uint8_t *src, const int pixel_shift, const int height, | |
82 | const ptrdiff_t dst_stride, const ptrdiff_t src_stride) | ||
83 | { | ||
84 | int i; | ||
85 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 264958 times.
|
264958 | if (pixel_shift == 0) { |
86 | ✗ | for (i = 0; i < height; i++) { | |
87 | ✗ | *dst = *src; | |
88 | ✗ | dst += dst_stride; | |
89 | ✗ | src += src_stride; | |
90 | } | ||
91 | } else { | ||
92 |
2/2✓ Branch 0 taken 24802416 times.
✓ Branch 1 taken 264958 times.
|
25067374 | for (i = 0; i < height; i++) { |
93 | 24802416 | *(uint16_t *)dst = *(uint16_t *)src; | |
94 | 24802416 | dst += dst_stride; | |
95 | 24802416 | src += src_stride; | |
96 | } | ||
97 | } | ||
98 | 264958 | } | |
99 | |||
100 | 253394 | static void copy_ctb_to_hv(VVCFrameContext *fc, const uint8_t *src, | |
101 | const ptrdiff_t src_stride, const int x, const int y, const int width, const int height, | ||
102 | const int c_idx, const int rx, const int ry, const int top) | ||
103 | { | ||
104 | 253394 | const int ps = fc->ps.sps->pixel_shift; | |
105 | 253394 | const int w = fc->ps.pps->width >> fc->ps.sps->hshift[c_idx]; | |
106 | 253394 | const int h = fc->ps.pps->height >> fc->ps.sps->vshift[c_idx]; | |
107 | |||
108 |
2/2✓ Branch 0 taken 126697 times.
✓ Branch 1 taken 126697 times.
|
253394 | if (top) { |
109 | /* top */ | ||
110 | 126697 | memcpy(fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry) * w + x) << ps), | |
111 | 126697 | src, width << ps); | |
112 | } else { | ||
113 | /* bottom */ | ||
114 | 126697 | memcpy(fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry + 1) * w + x) << ps), | |
115 | 126697 | src + src_stride * (height - 1), width << ps); | |
116 | |||
117 | /* copy vertical edges */ | ||
118 | 126697 | copy_vert(fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx) * h + y) << ps), src, ps, height, 1 << ps, src_stride); | |
119 | 126697 | copy_vert(fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx + 1) * h + y) << ps), src + ((width - 1) << ps), ps, height, 1 << ps, src_stride); | |
120 | } | ||
121 | 253394 | } | |
122 | |||
123 | 85158 | static void sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int top) | |
124 | { | ||
125 | 85158 | VVCFrameContext *fc = lc->fc; | |
126 | 85158 | const int ctb_size_y = fc->ps.sps->ctb_size_y; | |
127 | 85158 | const int x0 = rx << fc->ps.sps->ctb_log2_size_y; | |
128 | 85158 | const int y0 = ry << fc->ps.sps->ctb_log2_size_y; | |
129 | |||
130 |
4/4✓ Branch 0 taken 336472 times.
✓ Branch 1 taken 2080 times.
✓ Branch 2 taken 253394 times.
✓ Branch 3 taken 85158 times.
|
338552 | for (int c_idx = 0; c_idx < (fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) { |
131 | 253394 | const int x = x0 >> fc->ps.sps->hshift[c_idx]; | |
132 | 253394 | const int y = y0 >> fc->ps.sps->vshift[c_idx]; | |
133 | 253394 | const ptrdiff_t src_stride = fc->frame->linesize[c_idx]; | |
134 | 253394 | const int ctb_size_h = ctb_size_y >> fc->ps.sps->hshift[c_idx]; | |
135 | 253394 | const int ctb_size_v = ctb_size_y >> fc->ps.sps->vshift[c_idx]; | |
136 | 253394 | const int width = FFMIN(ctb_size_h, (fc->ps.pps->width >> fc->ps.sps->hshift[c_idx]) - x); | |
137 | 253394 | const int height = FFMIN(ctb_size_v, (fc->ps.pps->height >> fc->ps.sps->vshift[c_idx]) - y); | |
138 | 253394 | const uint8_t *src = &fc->frame->data[c_idx][y * src_stride + (x << fc->ps.sps->pixel_shift)]; | |
139 | 253394 | copy_ctb_to_hv(fc, src, src_stride, x, y, width, height, c_idx, rx, ry, top); | |
140 | } | ||
141 | 85158 | } | |
142 | |||
143 | 42579 | void ff_vvc_sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int last_row) | |
144 | { | ||
145 |
2/2✓ Branch 0 taken 35879 times.
✓ Branch 1 taken 6700 times.
|
42579 | if (ry) |
146 | 35879 | sao_copy_ctb_to_hv(lc, rx, ry - 1, 0); | |
147 | |||
148 | 42579 | sao_copy_ctb_to_hv(lc, rx, ry, 1); | |
149 | |||
150 |
2/2✓ Branch 0 taken 6700 times.
✓ Branch 1 taken 35879 times.
|
42579 | if (last_row) |
151 | 6700 | sao_copy_ctb_to_hv(lc, rx, ry, 0); | |
152 | 42579 | } | |
153 | |||
154 | 42579 | void ff_vvc_sao_filter(VVCLocalContext *lc, int x, int y) | |
155 | { | ||
156 | 42579 | VVCFrameContext *fc = lc->fc; | |
157 | 42579 | const int ctb_size_y = fc->ps.sps->ctb_size_y; | |
158 | static const uint8_t sao_tab[16] = { 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 }; | ||
159 | int c_idx; | ||
160 | 42579 | const int rx = x >> fc->ps.sps->ctb_log2_size_y; | |
161 | 42579 | const int ry = y >> fc->ps.sps->ctb_log2_size_y; | |
162 | 42579 | int edges[4] = { !rx, !ry, rx == fc->ps.pps->ctb_width - 1, ry == fc->ps.pps->ctb_height - 1 }; | |
163 | 42579 | const SAOParams *sao = &CTB(fc->tab.sao, rx, ry); | |
164 | // flags indicating unfilterable edges | ||
165 | 42579 | uint8_t vert_edge[] = { 0, 0 }; | |
166 | 42579 | uint8_t horiz_edge[] = { 0, 0 }; | |
167 | 42579 | uint8_t diag_edge[] = { 0, 0, 0, 0 }; | |
168 | 42579 | uint8_t tile_edge[] = { 0, 0, 0, 0 }; | |
169 | 42579 | uint8_t subpic_edge[] = { 0, 0, 0, 0 }; | |
170 | 42579 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
171 | 42579 | const uint8_t lfase = fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag; | |
172 |
2/2✓ Branch 0 taken 3774 times.
✓ Branch 1 taken 38805 times.
|
46353 | const uint8_t no_tile_filter = fc->ps.pps->r->num_tiles_in_pic > 1 && |
173 |
2/2✓ Branch 0 taken 939 times.
✓ Branch 1 taken 2835 times.
|
3774 | !fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag; |
174 |
2/2✓ Branch 0 taken 939 times.
✓ Branch 1 taken 41640 times.
|
43518 | const uint8_t no_subpic_filter = fc->ps.sps->r->sps_num_subpics_minus1 && |
175 |
1/2✓ Branch 0 taken 939 times.
✗ Branch 1 not taken.
|
939 | !fc->ps.sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx]; |
176 |
5/6✓ Branch 0 taken 41640 times.
✓ Branch 1 taken 939 times.
✓ Branch 2 taken 41640 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 38805 times.
✓ Branch 5 taken 2835 times.
|
42579 | const uint8_t restore = no_subpic_filter || no_tile_filter || !lfase; |
177 | |||
178 |
2/2✓ Branch 0 taken 39744 times.
✓ Branch 1 taken 2835 times.
|
42579 | if (restore) { |
179 |
2/2✓ Branch 0 taken 36148 times.
✓ Branch 1 taken 3596 times.
|
39744 | if (!edges[LEFT]) { |
180 |
4/4✓ Branch 0 taken 828 times.
✓ Branch 1 taken 35320 times.
✓ Branch 2 taken 333 times.
✓ Branch 3 taken 495 times.
|
36148 | tile_edge[LEFT] = no_tile_filter && fc->ps.pps->ctb_to_col_bd[rx] == rx; |
181 |
4/4✓ Branch 0 taken 828 times.
✓ Branch 1 taken 35320 times.
✓ Branch 2 taken 273 times.
✓ Branch 3 taken 555 times.
|
36148 | subpic_edge[LEFT] = no_subpic_filter && fc->ps.sps->r->sps_subpic_ctu_top_left_x[subpic_idx] == rx; |
182 |
6/8✓ Branch 0 taken 36148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35875 times.
✓ Branch 3 taken 273 times.
✓ Branch 4 taken 35815 times.
✓ Branch 5 taken 60 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 35815 times.
|
36148 | vert_edge[0] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx - 1, ry)) || tile_edge[LEFT] || subpic_edge[LEFT]; |
183 | } | ||
184 |
2/2✓ Branch 0 taken 36148 times.
✓ Branch 1 taken 3596 times.
|
39744 | if (!edges[RIGHT]) { |
185 |
4/4✓ Branch 0 taken 828 times.
✓ Branch 1 taken 35320 times.
✓ Branch 2 taken 333 times.
✓ Branch 3 taken 495 times.
|
36148 | tile_edge[RIGHT] = no_tile_filter && fc->ps.pps->ctb_to_col_bd[rx] != fc->ps.pps->ctb_to_col_bd[rx + 1]; |
186 |
2/2✓ Branch 0 taken 828 times.
✓ Branch 1 taken 35320 times.
|
36976 | subpic_edge[RIGHT] = no_subpic_filter && |
187 |
2/2✓ Branch 0 taken 273 times.
✓ Branch 1 taken 555 times.
|
828 | fc->ps.sps->r->sps_subpic_ctu_top_left_x[subpic_idx] + fc->ps.sps->r->sps_subpic_width_minus1[subpic_idx] == rx; |
188 |
6/8✓ Branch 0 taken 36148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35875 times.
✓ Branch 3 taken 273 times.
✓ Branch 4 taken 35815 times.
✓ Branch 5 taken 60 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 35815 times.
|
36148 | vert_edge[1] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx + 1, ry)) || tile_edge[RIGHT] || subpic_edge[RIGHT]; |
189 | } | ||
190 |
2/2✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 6385 times.
|
39744 | if (!edges[TOP]) { |
191 |
4/4✓ Branch 0 taken 732 times.
✓ Branch 1 taken 32627 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 450 times.
|
33359 | tile_edge[TOP] = no_tile_filter && fc->ps.pps->ctb_to_row_bd[ry] == ry; |
192 |
4/4✓ Branch 0 taken 732 times.
✓ Branch 1 taken 32627 times.
✓ Branch 2 taken 207 times.
✓ Branch 3 taken 525 times.
|
33359 | subpic_edge[TOP] = no_subpic_filter && fc->ps.sps->r->sps_subpic_ctu_top_left_y[subpic_idx] == ry; |
193 |
6/8✓ Branch 0 taken 33359 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33107 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 33047 times.
✓ Branch 5 taken 60 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 33047 times.
|
33359 | horiz_edge[0] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx, ry - 1)) || tile_edge[TOP] || subpic_edge[TOP]; |
194 | } | ||
195 |
2/2✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 6385 times.
|
39744 | if (!edges[BOTTOM]) { |
196 |
4/4✓ Branch 0 taken 732 times.
✓ Branch 1 taken 32627 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 450 times.
|
33359 | tile_edge[BOTTOM] = no_tile_filter && fc->ps.pps->ctb_to_row_bd[ry] != fc->ps.pps->ctb_to_row_bd[ry + 1]; |
197 |
2/2✓ Branch 0 taken 732 times.
✓ Branch 1 taken 32627 times.
|
34091 | subpic_edge[BOTTOM] = no_subpic_filter && |
198 |
2/2✓ Branch 0 taken 207 times.
✓ Branch 1 taken 525 times.
|
732 | fc->ps.sps->r->sps_subpic_ctu_top_left_y[subpic_idx] + fc->ps.sps->r->sps_subpic_height_minus1[subpic_idx] == ry; |
199 |
6/8✓ Branch 0 taken 33359 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33107 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 33047 times.
✓ Branch 5 taken 60 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 33047 times.
|
33359 | horiz_edge[1] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx, ry + 1)) || tile_edge[BOTTOM] || subpic_edge[BOTTOM]; |
200 | } | ||
201 |
4/4✓ Branch 0 taken 36148 times.
✓ Branch 1 taken 3596 times.
✓ Branch 2 taken 30611 times.
✓ Branch 3 taken 5537 times.
|
39744 | if (!edges[LEFT] && !edges[TOP]) { |
202 |
2/2✓ Branch 0 taken 30352 times.
✓ Branch 1 taken 259 times.
|
61222 | diag_edge[0] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx - 1, ry - 1)) || |
203 |
7/10✓ Branch 0 taken 30611 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30307 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 30262 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 30262 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 30262 times.
|
61222 | tile_edge[LEFT] || tile_edge[TOP] || subpic_edge[LEFT] || subpic_edge[TOP]; |
204 | } | ||
205 |
4/4✓ Branch 0 taken 33359 times.
✓ Branch 1 taken 6385 times.
✓ Branch 2 taken 30611 times.
✓ Branch 3 taken 2748 times.
|
39744 | if (!edges[TOP] && !edges[RIGHT]) { |
206 |
2/2✓ Branch 0 taken 30352 times.
✓ Branch 1 taken 259 times.
|
61222 | diag_edge[1] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx + 1, ry - 1)) || |
207 |
7/10✓ Branch 0 taken 30611 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30307 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 30262 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 30262 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 30262 times.
|
61222 | tile_edge[RIGHT] || tile_edge[TOP] || subpic_edge[TOP] || subpic_edge[RIGHT]; |
208 | } | ||
209 |
4/4✓ Branch 0 taken 36148 times.
✓ Branch 1 taken 3596 times.
✓ Branch 2 taken 30611 times.
✓ Branch 3 taken 5537 times.
|
39744 | if (!edges[RIGHT] && !edges[BOTTOM]) { |
210 |
2/2✓ Branch 0 taken 30352 times.
✓ Branch 1 taken 259 times.
|
61222 | diag_edge[2] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx + 1, ry + 1)) || |
211 |
7/10✓ Branch 0 taken 30611 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30307 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 30262 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 30262 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 30262 times.
|
61222 | tile_edge[RIGHT] || tile_edge[BOTTOM] || subpic_edge[RIGHT] || subpic_edge[BOTTOM]; |
212 | } | ||
213 |
4/4✓ Branch 0 taken 36148 times.
✓ Branch 1 taken 3596 times.
✓ Branch 2 taken 30611 times.
✓ Branch 3 taken 5537 times.
|
39744 | if (!edges[LEFT] && !edges[BOTTOM]) { |
214 |
2/2✓ Branch 0 taken 30352 times.
✓ Branch 1 taken 259 times.
|
61222 | diag_edge[3] = (!lfase && CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx - 1, ry + 1)) || |
215 |
7/10✓ Branch 0 taken 30611 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30307 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 30262 times.
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 30262 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 30262 times.
|
61222 | tile_edge[LEFT] || tile_edge[BOTTOM] || subpic_edge[LEFT] || subpic_edge[BOTTOM]; |
216 | } | ||
217 | } | ||
218 | |||
219 |
4/4✓ Branch 0 taken 168236 times.
✓ Branch 1 taken 1040 times.
✓ Branch 2 taken 126697 times.
✓ Branch 3 taken 42579 times.
|
169276 | for (c_idx = 0; c_idx < (fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) { |
220 | 126697 | int x0 = x >> fc->ps.sps->hshift[c_idx]; | |
221 | 126697 | int y0 = y >> fc->ps.sps->vshift[c_idx]; | |
222 | 126697 | ptrdiff_t src_stride = fc->frame->linesize[c_idx]; | |
223 | 126697 | int ctb_size_h = ctb_size_y >> fc->ps.sps->hshift[c_idx]; | |
224 | 126697 | int ctb_size_v = ctb_size_y >> fc->ps.sps->vshift[c_idx]; | |
225 | 126697 | int width = FFMIN(ctb_size_h, (fc->ps.pps->width >> fc->ps.sps->hshift[c_idx]) - x0); | |
226 | 126697 | int height = FFMIN(ctb_size_v, (fc->ps.pps->height >> fc->ps.sps->vshift[c_idx]) - y0); | |
227 | 126697 | int tab = sao_tab[(FFALIGN(width, 8) >> 3) - 1]; | |
228 | 126697 | uint8_t *src = &fc->frame->data[c_idx][y0 * src_stride + (x0 << fc->ps.sps->pixel_shift)]; | |
229 | ptrdiff_t dst_stride; | ||
230 | uint8_t *dst; | ||
231 | |||
232 |
3/3✓ Branch 0 taken 4599 times.
✓ Branch 1 taken 6324 times.
✓ Branch 2 taken 115774 times.
|
126697 | switch (sao->type_idx[c_idx]) { |
233 | 4599 | case SAO_BAND: | |
234 | 4599 | fc->vvcdsp.sao.band_filter[tab](src, src, src_stride, src_stride, | |
235 | 4599 | sao->offset_val[c_idx], sao->band_position[c_idx], width, height); | |
236 | 4599 | break; | |
237 | 6324 | case SAO_EDGE: | |
238 | { | ||
239 | 6324 | const int w = fc->ps.pps->width >> fc->ps.sps->hshift[c_idx]; | |
240 | 6324 | const int h = fc->ps.pps->height >> fc->ps.sps->vshift[c_idx]; | |
241 | 6324 | const int sh = fc->ps.sps->pixel_shift; | |
242 | |||
243 | 6324 | dst_stride = 2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE; | |
244 | 6324 | dst = lc->sao_buffer + dst_stride + AV_INPUT_BUFFER_PADDING_SIZE; | |
245 | |||
246 |
2/2✓ Branch 0 taken 5208 times.
✓ Branch 1 taken 1116 times.
|
6324 | if (!edges[TOP]) { |
247 | 5208 | const int left = 1 - edges[LEFT]; | |
248 | 5208 | const int right = 1 - edges[RIGHT]; | |
249 | const uint8_t *src1; | ||
250 | uint8_t *dst1; | ||
251 | 5208 | int pos = 0; | |
252 | |||
253 | 5208 | dst1 = dst - dst_stride - (left << sh); | |
254 | 5208 | src1 = fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry - 1) * w + x0 - left) << sh); | |
255 |
2/2✓ Branch 0 taken 4826 times.
✓ Branch 1 taken 382 times.
|
5208 | if (left) { |
256 | 4826 | copy_pixel(dst1, src1, sh); | |
257 | 4826 | pos += (1 << sh); | |
258 | } | ||
259 | 5208 | memcpy(dst1 + pos, src1 + pos, width << sh); | |
260 |
2/2✓ Branch 0 taken 4820 times.
✓ Branch 1 taken 388 times.
|
5208 | if (right) { |
261 | 4820 | pos += width << sh; | |
262 | 4820 | copy_pixel(dst1 + pos, src1 + pos, sh); | |
263 | } | ||
264 | } | ||
265 |
2/2✓ Branch 0 taken 5183 times.
✓ Branch 1 taken 1141 times.
|
6324 | if (!edges[BOTTOM]) { |
266 | 5183 | const int left = 1 - edges[LEFT]; | |
267 | 5183 | const int right = 1 - edges[RIGHT]; | |
268 | const uint8_t *src1; | ||
269 | uint8_t *dst1; | ||
270 | 5183 | int pos = 0; | |
271 | |||
272 | 5183 | dst1 = dst + height * dst_stride - (left << sh); | |
273 | 5183 | src1 = fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry + 2) * w + x0 - left) << sh); | |
274 |
2/2✓ Branch 0 taken 4807 times.
✓ Branch 1 taken 376 times.
|
5183 | if (left) { |
275 | 4807 | copy_pixel(dst1, src1, sh); | |
276 | 4807 | pos += (1 << sh); | |
277 | } | ||
278 | 5183 | memcpy(dst1 + pos, src1 + pos, width << sh); | |
279 |
2/2✓ Branch 0 taken 4819 times.
✓ Branch 1 taken 364 times.
|
5183 | if (right) { |
280 | 4819 | pos += width << sh; | |
281 | 4819 | copy_pixel(dst1 + pos, src1 + pos, sh); | |
282 | } | ||
283 | } | ||
284 |
2/2✓ Branch 0 taken 5782 times.
✓ Branch 1 taken 542 times.
|
6324 | if (!edges[LEFT]) { |
285 | 5782 | copy_vert(dst - (1 << sh), | |
286 | 5782 | fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx - 1) * h + y0) << sh), | |
287 | 5782 | sh, height, dst_stride, 1 << sh); | |
288 | } | ||
289 |
2/2✓ Branch 0 taken 5782 times.
✓ Branch 1 taken 542 times.
|
6324 | if (!edges[RIGHT]) { |
290 | 5782 | copy_vert(dst + (width << sh), | |
291 | 5782 | fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx + 2) * h + y0) << sh), | |
292 | 5782 | sh, height, dst_stride, 1 << sh); | |
293 | } | ||
294 | |||
295 | 6324 | copy_ctb(dst, src, width << sh, height, dst_stride, src_stride); | |
296 | 6324 | fc->vvcdsp.sao.edge_filter[tab](src, dst, src_stride, sao->offset_val[c_idx], | |
297 | 6324 | sao->eo_class[c_idx], width, height); | |
298 | 6324 | fc->vvcdsp.sao.edge_restore[restore](src, dst, src_stride, dst_stride, | |
299 | sao, edges, width, height, c_idx, vert_edge, horiz_edge, diag_edge); | ||
300 | 6324 | break; | |
301 | } | ||
302 | } | ||
303 | } | ||
304 | 42579 | } | |
305 | |||
306 | #define TAB_BS(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)] | ||
307 | #define TAB_MAX_LEN(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)] | ||
308 | |||
309 | //8 samples a time | ||
310 | #define DEBLOCK_STEP 8 | ||
311 | #define LUMA_GRID 4 | ||
312 | #define CHROMA_GRID 8 | ||
313 | |||
314 | 9323463 | static int boundary_strength(const VVCLocalContext *lc, const MvField *curr, const MvField *neigh, | |
315 | const RefPicList *neigh_rpl) | ||
316 | { | ||
317 | 9323463 | RefPicList *rpl = lc->sc->rpl; | |
318 | |||
319 |
2/2✓ Branch 0 taken 1752 times.
✓ Branch 1 taken 9321711 times.
|
9323463 | if (curr->pred_flag == PF_IBC) |
320 |
4/4✓ Branch 0 taken 685 times.
✓ Branch 1 taken 1067 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 665 times.
|
1752 | return FFABS(neigh->mv[0].x - curr->mv[0].x) >= 8 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 8; |
321 | |||
322 |
4/4✓ Branch 0 taken 4509283 times.
✓ Branch 1 taken 4812428 times.
✓ Branch 2 taken 4203581 times.
✓ Branch 3 taken 305702 times.
|
9321711 | if (curr->pred_flag == PF_BI && neigh->pred_flag == PF_BI) { |
323 | // same L0 and L1 | ||
324 |
2/2✓ Branch 0 taken 4128603 times.
✓ Branch 1 taken 74978 times.
|
4203581 | if (rpl[0].list[curr->ref_idx[0]] == neigh_rpl[0].list[neigh->ref_idx[0]] && |
325 |
2/2✓ Branch 0 taken 431371 times.
✓ Branch 1 taken 3697232 times.
|
4128603 | rpl[0].list[curr->ref_idx[0]] == rpl[1].list[curr->ref_idx[1]] && |
326 |
2/2✓ Branch 0 taken 428033 times.
✓ Branch 1 taken 3338 times.
|
431371 | neigh_rpl[0].list[neigh->ref_idx[0]] == neigh_rpl[1].list[neigh->ref_idx[1]]) { |
327 |
4/4✓ Branch 0 taken 383240 times.
✓ Branch 1 taken 44793 times.
✓ Branch 2 taken 358323 times.
✓ Branch 3 taken 24917 times.
|
428033 | if ((FFABS(neigh->mv[0].x - curr->mv[0].x) >= 8 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 8 || |
328 |
4/4✓ Branch 0 taken 354799 times.
✓ Branch 1 taken 3524 times.
✓ Branch 2 taken 3009 times.
✓ Branch 3 taken 351790 times.
|
358323 | FFABS(neigh->mv[1].x - curr->mv[1].x) >= 8 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 8) && |
329 |
4/4✓ Branch 0 taken 18868 times.
✓ Branch 1 taken 57375 times.
✓ Branch 2 taken 4635 times.
✓ Branch 3 taken 14233 times.
|
76243 | (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 8 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 8 || |
330 |
4/4✓ Branch 0 taken 2401 times.
✓ Branch 1 taken 2234 times.
✓ Branch 2 taken 1894 times.
✓ Branch 3 taken 507 times.
|
4635 | FFABS(neigh->mv[0].x - curr->mv[1].x) >= 8 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 8)) |
331 | 75736 | return 1; | |
332 | else | ||
333 | 352297 | return 0; | |
334 |
2/2✓ Branch 0 taken 3700570 times.
✓ Branch 1 taken 74978 times.
|
3775548 | } else if (neigh_rpl[0].list[neigh->ref_idx[0]] == rpl[0].list[curr->ref_idx[0]] && |
335 |
2/2✓ Branch 0 taken 3681992 times.
✓ Branch 1 taken 18578 times.
|
3700570 | neigh_rpl[1].list[neigh->ref_idx[1]] == rpl[1].list[curr->ref_idx[1]]) { |
336 |
4/4✓ Branch 0 taken 3159342 times.
✓ Branch 1 taken 522650 times.
✓ Branch 2 taken 3006471 times.
✓ Branch 3 taken 152871 times.
|
3681992 | if (FFABS(neigh->mv[0].x - curr->mv[0].x) >= 8 || FFABS(neigh->mv[0].y - curr->mv[0].y) >= 8 || |
337 |
4/4✓ Branch 0 taken 2974651 times.
✓ Branch 1 taken 31820 times.
✓ Branch 2 taken 20306 times.
✓ Branch 3 taken 2954345 times.
|
3006471 | FFABS(neigh->mv[1].x - curr->mv[1].x) >= 8 || FFABS(neigh->mv[1].y - curr->mv[1].y) >= 8) |
338 | 727647 | return 1; | |
339 | else | ||
340 | 2954345 | return 0; | |
341 |
2/2✓ Branch 0 taken 26177 times.
✓ Branch 1 taken 67379 times.
|
93556 | } else if (neigh_rpl[1].list[neigh->ref_idx[1]] == rpl[0].list[curr->ref_idx[0]] && |
342 |
2/2✓ Branch 0 taken 8232 times.
✓ Branch 1 taken 17945 times.
|
26177 | neigh_rpl[0].list[neigh->ref_idx[0]] == rpl[1].list[curr->ref_idx[1]]) { |
343 |
4/4✓ Branch 0 taken 2920 times.
✓ Branch 1 taken 5312 times.
✓ Branch 2 taken 1133 times.
✓ Branch 3 taken 1787 times.
|
8232 | if (FFABS(neigh->mv[1].x - curr->mv[0].x) >= 8 || FFABS(neigh->mv[1].y - curr->mv[0].y) >= 8 || |
344 |
4/4✓ Branch 0 taken 824 times.
✓ Branch 1 taken 309 times.
✓ Branch 2 taken 180 times.
✓ Branch 3 taken 644 times.
|
1133 | FFABS(neigh->mv[0].x - curr->mv[1].x) >= 8 || FFABS(neigh->mv[0].y - curr->mv[1].y) >= 8) |
345 | 7588 | return 1; | |
346 | else | ||
347 | 644 | return 0; | |
348 | } else { | ||
349 | 85324 | return 1; | |
350 | } | ||
351 |
4/4✓ Branch 0 taken 4812428 times.
✓ Branch 1 taken 305702 times.
✓ Branch 2 taken 4510464 times.
✓ Branch 3 taken 301964 times.
|
5118130 | } else if ((curr->pred_flag != PF_BI) && (neigh->pred_flag != PF_BI)){ // 1 MV |
352 | Mv A, B; | ||
353 | int ref_A, ref_B; | ||
354 | |||
355 |
2/2✓ Branch 0 taken 3686814 times.
✓ Branch 1 taken 823650 times.
|
4510464 | if (curr->pred_flag & 1) { |
356 | 3686814 | A = curr->mv[0]; | |
357 | 3686814 | ref_A = rpl[0].list[curr->ref_idx[0]]; | |
358 | } else { | ||
359 | 823650 | A = curr->mv[1]; | |
360 | 823650 | ref_A = rpl[1].list[curr->ref_idx[1]]; | |
361 | } | ||
362 | |||
363 |
2/2✓ Branch 0 taken 3684827 times.
✓ Branch 1 taken 825637 times.
|
4510464 | if (neigh->pred_flag & 1) { |
364 | 3684827 | B = neigh->mv[0]; | |
365 | 3684827 | ref_B = neigh_rpl[0].list[neigh->ref_idx[0]]; | |
366 | } else { | ||
367 | 825637 | B = neigh->mv[1]; | |
368 | 825637 | ref_B = neigh_rpl[1].list[neigh->ref_idx[1]]; | |
369 | } | ||
370 | |||
371 |
2/2✓ Branch 0 taken 4403396 times.
✓ Branch 1 taken 107068 times.
|
4510464 | if (ref_A == ref_B) { |
372 |
4/4✓ Branch 0 taken 4076034 times.
✓ Branch 1 taken 327362 times.
✓ Branch 2 taken 147003 times.
✓ Branch 3 taken 3929031 times.
|
4403396 | if (FFABS(A.x - B.x) >= 8 || FFABS(A.y - B.y) >= 8) |
373 | 474365 | return 1; | |
374 | else | ||
375 | 3929031 | return 0; | |
376 | } else | ||
377 | 107068 | return 1; | |
378 | } | ||
379 | |||
380 | 607666 | return 1; | |
381 | } | ||
382 | |||
383 | //part of 8.8.3.3 Derivation process of transform block boundary | ||
384 | 9170446 | static void derive_max_filter_length_luma(const VVCFrameContext *fc, const int qx, const int qy, | |
385 | const int is_intra, const int has_subblock, const int vertical, uint8_t *max_len_p, uint8_t *max_len_q) | ||
386 | { | ||
387 |
2/2✓ Branch 0 taken 4406482 times.
✓ Branch 1 taken 4763964 times.
|
9170446 | const int px = vertical ? qx - 1 : qx; |
388 |
2/2✓ Branch 0 taken 4763964 times.
✓ Branch 1 taken 4406482 times.
|
9170446 | const int py = !vertical ? qy - 1 : qy; |
389 |
2/2✓ Branch 0 taken 4406482 times.
✓ Branch 1 taken 4763964 times.
|
9170446 | const uint8_t *tb_size = vertical ? fc->tab.tb_width[LUMA] : fc->tab.tb_height[LUMA]; |
390 | 9170446 | const int size_p = tb_size[(py >> MIN_TU_LOG2) * fc->ps.pps->min_tu_width + (px >> MIN_TU_LOG2)]; | |
391 | 9170446 | const int size_q = tb_size[(qy >> MIN_TU_LOG2) * fc->ps.pps->min_tu_width + (qx >> MIN_TU_LOG2)]; | |
392 | 9170446 | const int min_cb_log2 = fc->ps.sps->min_cb_log2_size_y; | |
393 | 9170446 | const int off_p = (py >> min_cb_log2) * fc->ps.pps->min_cb_width + (px >> min_cb_log2); | |
394 |
4/4✓ Branch 0 taken 7917014 times.
✓ Branch 1 taken 1253432 times.
✓ Branch 2 taken 583387 times.
✓ Branch 3 taken 7333627 times.
|
9170446 | if (size_p <= 4 || size_q <= 4) { |
395 | 1836819 | *max_len_p = *max_len_q = 1; | |
396 | } else { | ||
397 | 7333627 | *max_len_p = *max_len_q = 3; | |
398 |
2/2✓ Branch 0 taken 4794602 times.
✓ Branch 1 taken 2539025 times.
|
7333627 | if (size_p >= 32) |
399 | 4794602 | *max_len_p = 7; | |
400 |
2/2✓ Branch 0 taken 4654197 times.
✓ Branch 1 taken 2679430 times.
|
7333627 | if (size_q >= 32) |
401 | 4654197 | *max_len_q = 7; | |
402 | } | ||
403 |
2/2✓ Branch 0 taken 1036516 times.
✓ Branch 1 taken 8133930 times.
|
9170446 | if (has_subblock) |
404 | 1036516 | *max_len_q = FFMIN(5, *max_len_q); | |
405 |
4/4✓ Branch 0 taken 8234848 times.
✓ Branch 1 taken 935598 times.
✓ Branch 2 taken 217688 times.
✓ Branch 3 taken 8017160 times.
|
9170446 | if (fc->tab.msf[off_p] || fc->tab.iaf[off_p]) |
406 | 1153286 | *max_len_p = FFMIN(5, *max_len_p); | |
407 | 9170446 | } | |
408 | |||
409 | 71955 | static void vvc_deblock_subblock_bs_vertical(const VVCLocalContext *lc, | |
410 | const int cb_x, const int cb_y, const int x0, const int y0, const int width, const int height) | ||
411 | { | ||
412 | 71955 | const VVCFrameContext *fc = lc->fc; | |
413 | 71955 | const MvField *tab_mvf = fc->tab.mvf; | |
414 | 71955 | const RefPicList *rpl = lc->sc->rpl; | |
415 | 71955 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
416 | 71955 | const int log2_min_pu_size = MIN_PU_LOG2; | |
417 | |||
418 | // bs for TU internal vertical PU boundaries | ||
419 |
2/2✓ Branch 0 taken 591870 times.
✓ Branch 1 taken 71955 times.
|
663825 | for (int j = 0; j < height; j += 4) { |
420 | 591870 | const int y_pu = (y0 + j) >> log2_min_pu_size; | |
421 | |||
422 |
2/2✓ Branch 0 taken 2659964 times.
✓ Branch 1 taken 591870 times.
|
3251834 | for (int i = 8 - ((x0 - cb_x) % 8); i < width; i += 8) { |
423 | 2659964 | const int xp_pu = (x0 + i - 1) >> log2_min_pu_size; | |
424 | 2659964 | const int xq_pu = (x0 + i) >> log2_min_pu_size; | |
425 | 2659964 | const MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu]; | |
426 | 2659964 | const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu]; | |
427 | 2659964 | const int x = x0 + i; | |
428 | 2659964 | const int y = y0 + j; | |
429 | 2659964 | const int bs = boundary_strength(lc, curr, left, rpl); | |
430 | 2659964 | uint8_t max_len_p = 0, max_len_q = 0; | |
431 | |||
432 | 2659964 | TAB_BS(fc->tab.vertical_bs[LUMA], x, y) = bs; | |
433 | |||
434 |
4/4✓ Branch 0 taken 2659300 times.
✓ Branch 1 taken 664 times.
✓ Branch 2 taken 888 times.
✓ Branch 3 taken 2658412 times.
|
2659964 | if (i == 4 || i == width - 4) |
435 | 1552 | max_len_p = max_len_q = 1; | |
436 |
4/4✓ Branch 0 taken 2134740 times.
✓ Branch 1 taken 523672 times.
✓ Branch 2 taken 424712 times.
✓ Branch 3 taken 1710028 times.
|
2658412 | else if (i == 8 || i == width - 8) |
437 | 948384 | max_len_p = max_len_q = 2; | |
438 | else | ||
439 | 1710028 | max_len_p = max_len_q = 3; | |
440 | |||
441 | 2659964 | TAB_MAX_LEN(fc->tab.vertical_p, x, y) = max_len_p; | |
442 | 2659964 | TAB_MAX_LEN(fc->tab.vertical_q, x, y) = max_len_q; | |
443 | } | ||
444 | } | ||
445 | 71955 | } | |
446 | |||
447 | 71955 | static void vvc_deblock_subblock_bs_horizontal(const VVCLocalContext *lc, | |
448 | const int cb_x, const int cb_y, const int x0, const int y0, const int width, const int height) | ||
449 | { | ||
450 | 71955 | const VVCFrameContext *fc = lc->fc; | |
451 | 71955 | const MvField* tab_mvf = fc->tab.mvf; | |
452 | 71955 | const RefPicList* rpl = lc->sc->rpl; | |
453 | 71955 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
454 | 71955 | const int log2_min_pu_size = MIN_PU_LOG2; | |
455 | |||
456 | // bs for TU internal horizontal PU boundaries | ||
457 |
2/2✓ Branch 0 taken 224646 times.
✓ Branch 1 taken 71955 times.
|
296601 | for (int j = 8 - ((y0 - cb_y) % 8); j < height; j += 8) { |
458 | 224646 | int yp_pu = (y0 + j - 1) >> log2_min_pu_size; | |
459 | 224646 | int yq_pu = (y0 + j) >> log2_min_pu_size; | |
460 | |||
461 |
2/2✓ Branch 0 taken 2635628 times.
✓ Branch 1 taken 224646 times.
|
2860274 | for (int i = 0; i < width; i += 4) { |
462 | 2635628 | const int x_pu = (x0 + i) >> log2_min_pu_size; | |
463 | 2635628 | const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu]; | |
464 | 2635628 | const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu]; | |
465 | 2635628 | const int x = x0 + i; | |
466 | 2635628 | const int y = y0 + j; | |
467 | 2635628 | const int bs = boundary_strength(lc, curr, top, rpl); | |
468 | 2635628 | uint8_t max_len_p = 0, max_len_q = 0; | |
469 | |||
470 | 2635628 | TAB_BS(fc->tab.horizontal_bs[LUMA], x, y) = bs; | |
471 | |||
472 | //fixme: | ||
473 | //edgeTbFlags[ x − sbW ][ y ] is equal to 1 | ||
474 | //edgeTbFlags[ x + sbW ][ y ] is equal to 1 | ||
475 |
4/4✓ Branch 0 taken 2635114 times.
✓ Branch 1 taken 514 times.
✓ Branch 2 taken 592 times.
✓ Branch 3 taken 2634522 times.
|
2635628 | if (j == 4 || j == height - 4) |
476 | 1106 | max_len_p = max_len_q = 1; | |
477 |
4/4✓ Branch 0 taken 2090408 times.
✓ Branch 1 taken 544114 times.
✓ Branch 2 taken 432126 times.
✓ Branch 3 taken 1658282 times.
|
2634522 | else if (j == 8 || j == height - 8) |
478 | 976240 | max_len_p = max_len_q = 2; | |
479 | else | ||
480 | 1658282 | max_len_p = max_len_q = 3; | |
481 | 2635628 | TAB_MAX_LEN(fc->tab.horizontal_p, x, y) = max_len_p; | |
482 | 2635628 | TAB_MAX_LEN(fc->tab.horizontal_q, x, y) = max_len_q; | |
483 | } | ||
484 | } | ||
485 | 71955 | } | |
486 | |||
487 | 36436026 | static av_always_inline int deblock_bs(const VVCLocalContext *lc, | |
488 | const int x_p, const int y_p, const int x_q, const int y_q, | ||
489 | const RefPicList *rpl_p, const int c_idx, const int off_to_cb, const uint8_t has_sub_block) | ||
490 | { | ||
491 | 36436026 | const VVCFrameContext *fc = lc->fc; | |
492 | 36436026 | const MvField *tab_mvf = fc->tab.mvf; | |
493 | 36436026 | const int log2_min_pu_size = MIN_PU_LOG2; | |
494 | 36436026 | const int log2_min_tu_size = MIN_TU_LOG2; | |
495 | 36436026 | const int log2_min_cb_size = fc->ps.sps->min_cb_log2_size_y; | |
496 | 36436026 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
497 | 36436026 | const int min_tu_width = fc->ps.pps->min_tu_width; | |
498 | 36436026 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
499 | 36436026 | const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size); | |
500 | 36436026 | const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size); | |
501 | 36436026 | const MvField *mvf_p = &tab_mvf[pu_p]; | |
502 | 36436026 | const MvField *mvf_q = &tab_mvf[pu_q]; | |
503 | 36436026 | const uint8_t chroma = !!c_idx; | |
504 | 36436026 | const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size); | |
505 | 36436026 | const int tu_q = (y_q >> log2_min_tu_size) * min_tu_width + (x_q >> log2_min_tu_size); | |
506 |
4/4✓ Branch 0 taken 178 times.
✓ Branch 1 taken 36435848 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 167 times.
|
36436026 | const uint8_t pcmf = fc->tab.pcmf[chroma][tu_p] && fc->tab.pcmf[chroma][tu_q]; |
507 | 36436026 | const int cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size); | |
508 | 36436026 | const int cb_q = (y_q >> log2_min_cb_size) * min_cb_width + (x_q >> log2_min_cb_size); | |
509 |
4/4✓ Branch 0 taken 28973425 times.
✓ Branch 1 taken 7462601 times.
✓ Branch 2 taken 602083 times.
✓ Branch 3 taken 28371342 times.
|
36436026 | const uint8_t intra = fc->tab.cpm[chroma][cb_p] == MODE_INTRA || fc->tab.cpm[chroma][cb_q] == MODE_INTRA; |
510 | 36436026 | const uint8_t same_mode = fc->tab.cpm[chroma][cb_p] == fc->tab.cpm[chroma][cb_q]; | |
511 | |||
512 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 36436015 times.
|
36436026 | if (pcmf) |
513 | 11 | return 0; | |
514 | |||
515 |
6/6✓ Branch 0 taken 28371342 times.
✓ Branch 1 taken 8064673 times.
✓ Branch 2 taken 28017246 times.
✓ Branch 3 taken 354096 times.
✓ Branch 4 taken 280852 times.
✓ Branch 5 taken 27736394 times.
|
36436015 | if (intra || mvf_p->ciip_flag || mvf_q->ciip_flag) |
516 | 8699621 | return 2; | |
517 | |||
518 |
2/2✓ Branch 0 taken 21559344 times.
✓ Branch 1 taken 6177050 times.
|
27736394 | if (chroma) { |
519 | 42746460 | return fc->tab.tu_coded_flag[c_idx][tu_p] || | |
520 |
2/2✓ Branch 0 taken 21022990 times.
✓ Branch 1 taken 164126 times.
|
21187116 | fc->tab.tu_coded_flag[c_idx][tu_q] || |
521 |
4/4✓ Branch 0 taken 21187116 times.
✓ Branch 1 taken 372228 times.
✓ Branch 2 taken 21001392 times.
✓ Branch 3 taken 21598 times.
|
63747852 | fc->tab.tu_joint_cbcr_residual_flag[tu_p] || |
522 |
2/2✓ Branch 0 taken 18920 times.
✓ Branch 1 taken 20982472 times.
|
21001392 | fc->tab.tu_joint_cbcr_residual_flag[tu_q]; |
523 | } | ||
524 | |||
525 |
4/4✓ Branch 0 taken 5496641 times.
✓ Branch 1 taken 680409 times.
✓ Branch 2 taken 337132 times.
✓ Branch 3 taken 5159509 times.
|
6177050 | if (fc->tab.tu_coded_flag[LUMA][tu_p] || fc->tab.tu_coded_flag[LUMA][tu_q]) |
526 | 1017541 | return 1; | |
527 | |||
528 |
6/6✓ Branch 0 taken 1324457 times.
✓ Branch 1 taken 3835052 times.
✓ Branch 2 taken 1316418 times.
✓ Branch 3 taken 8039 times.
✓ Branch 4 taken 1123464 times.
✓ Branch 5 taken 192954 times.
|
5159509 | if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block))) |
529 | 1131503 | return 0; // inside a cu, not aligned to 8 or with no subblocks | |
530 | |||
531 |
2/2✓ Branch 0 taken 135 times.
✓ Branch 1 taken 4027871 times.
|
4028006 | if (!same_mode) |
532 | 135 | return 1; | |
533 | |||
534 | 4027871 | return boundary_strength(lc, mvf_q, mvf_p, rpl_p); | |
535 | } | ||
536 | |||
537 | 3199998 | static int deblock_is_boundary(const VVCLocalContext *lc, const int boundary, | |
538 | const int pos, const int rs, const int vertical) | ||
539 | { | ||
540 | 3199998 | const VVCFrameContext *fc = lc->fc; | |
541 | 3199998 | const H266RawSPS *rsps = fc->ps.sps->r; | |
542 | 3199998 | const H266RawPPS *rpps = fc->ps.pps->r; | |
543 | int flag; | ||
544 |
4/4✓ Branch 0 taken 2844139 times.
✓ Branch 1 taken 355859 times.
✓ Branch 2 taken 502647 times.
✓ Branch 3 taken 2341492 times.
|
3199998 | if (boundary && (pos % fc->ps.sps->ctb_size_y) == 0) { |
545 |
2/2✓ Branch 0 taken 269406 times.
✓ Branch 1 taken 233241 times.
|
502647 | flag = vertical ? BOUNDARY_LEFT_SLICE : BOUNDARY_UPPER_SLICE; |
546 |
2/2✓ Branch 0 taken 17213 times.
✓ Branch 1 taken 485434 times.
|
502647 | if (lc->boundary_flags & flag && |
547 |
2/2✓ Branch 0 taken 6215 times.
✓ Branch 1 taken 10998 times.
|
17213 | !rpps->pps_loop_filter_across_slices_enabled_flag) |
548 | 6215 | return 0; | |
549 | |||
550 |
2/2✓ Branch 0 taken 266108 times.
✓ Branch 1 taken 230324 times.
|
496432 | flag = vertical ? BOUNDARY_LEFT_TILE : BOUNDARY_UPPER_TILE; |
551 |
2/2✓ Branch 0 taken 14396 times.
✓ Branch 1 taken 482036 times.
|
496432 | if (lc->boundary_flags & flag && |
552 |
2/2✓ Branch 0 taken 1295 times.
✓ Branch 1 taken 13101 times.
|
14396 | !rpps->pps_loop_filter_across_tiles_enabled_flag) |
553 | 1295 | return 0; | |
554 | |||
555 |
2/2✓ Branch 0 taken 265243 times.
✓ Branch 1 taken 229894 times.
|
495137 | flag = vertical ? BOUNDARY_LEFT_SUBPIC : BOUNDARY_UPPER_SUBPIC; |
556 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 495137 times.
|
495137 | if (lc->boundary_flags & flag) { |
557 | ✗ | const int q_rs = rs - (vertical ? 1 : fc->ps.pps->ctb_width); | |
558 | ✗ | const SliceContext *q_slice = lc->fc->slices[lc->fc->tab.slice_idx[q_rs]]; | |
559 | |||
560 | ✗ | if (!rsps->sps_loop_filter_across_subpic_enabled_flag[q_slice->sh.r->curr_subpic_idx] || | |
561 | ✗ | !rsps->sps_loop_filter_across_subpic_enabled_flag[lc->sc->sh.r->curr_subpic_idx]) | |
562 | ✗ | return 0; | |
563 | } | ||
564 | } | ||
565 | 3192488 | return boundary; | |
566 | } | ||
567 | |||
568 | 971013 | static void vvc_deblock_bs_luma_vertical(const VVCLocalContext *lc, | |
569 | const int x0, const int y0, const int width, const int height, const int rs) | ||
570 | { | ||
571 | 971013 | const VVCFrameContext *fc = lc->fc; | |
572 | 971013 | const MvField *tab_mvf = fc->tab.mvf; | |
573 | 971013 | const int log2_min_pu_size = MIN_PU_LOG2; | |
574 | 971013 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
575 | 971013 | const int min_cb_log2 = fc->ps.sps->min_cb_log2_size_y; | |
576 | 971013 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
577 | 971013 | const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width + | |
578 | 971013 | (x0 >> log2_min_pu_size)].pred_flag == PF_INTRA; | |
579 | int boundary_left; | ||
580 | 971013 | int has_vertical_sb = 0; | |
581 | |||
582 | 971013 | const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2); | |
583 | 971013 | const int cb_x = fc->tab.cb_pos_x[LUMA][off_q]; | |
584 | 971013 | const int cb_y = fc->tab.cb_pos_y[LUMA][off_q]; | |
585 | 971013 | const int cb_width = fc->tab.cb_width[LUMA][off_q]; | |
586 | 971013 | const int off_x = cb_x - x0; | |
587 | |||
588 |
2/2✓ Branch 0 taken 496575 times.
✓ Branch 1 taken 474438 times.
|
971013 | if (!is_intra) { |
589 |
4/4✓ Branch 0 taken 436406 times.
✓ Branch 1 taken 60169 times.
✓ Branch 2 taken 11786 times.
✓ Branch 3 taken 424620 times.
|
496575 | if (fc->tab.msf[off_q] || fc->tab.iaf[off_q]) |
590 | 71955 | has_vertical_sb = cb_width > 8; | |
591 | } | ||
592 | |||
593 | // bs for vertical TU boundaries | ||
594 |
3/4✓ Branch 0 taken 954452 times.
✓ Branch 1 taken 16561 times.
✓ Branch 2 taken 954452 times.
✗ Branch 3 not taken.
|
971013 | boundary_left = deblock_is_boundary(lc, x0 > 0 && !(x0 & 3), x0, rs, 1); |
595 | |||
596 |
2/2✓ Branch 0 taken 951950 times.
✓ Branch 1 taken 19063 times.
|
971013 | if (boundary_left) { |
597 | 951950 | const RefPicList *rpl_left = | |
598 |
2/2✓ Branch 0 taken 18544 times.
✓ Branch 1 taken 933406 times.
|
951950 | (lc->boundary_flags & BOUNDARY_LEFT_SLICE) ? ff_vvc_get_ref_list(fc, fc->ref, x0 - 1, y0) : lc->sc->rpl; |
599 |
2/2✓ Branch 0 taken 4406482 times.
✓ Branch 1 taken 951950 times.
|
5358432 | for (int i = 0; i < height; i += 4) { |
600 | uint8_t max_len_p, max_len_q; | ||
601 | 4406482 | const int bs = deblock_bs(lc, x0 - 1, y0 + i, x0, y0 + i, rpl_left, 0, off_x, has_vertical_sb); | |
602 | |||
603 | 4406482 | TAB_BS(fc->tab.vertical_bs[LUMA], x0, (y0 + i)) = bs; | |
604 | |||
605 | 4406482 | derive_max_filter_length_luma(fc, x0, y0 + i, is_intra, has_vertical_sb, 1, &max_len_p, &max_len_q); | |
606 | 4406482 | TAB_MAX_LEN(fc->tab.vertical_p, x0, y0 + i) = max_len_p; | |
607 | 4406482 | TAB_MAX_LEN(fc->tab.vertical_q, x0, y0 + i) = max_len_q; | |
608 | } | ||
609 | } | ||
610 | |||
611 |
2/2✓ Branch 0 taken 496575 times.
✓ Branch 1 taken 474438 times.
|
971013 | if (!is_intra) { |
612 |
4/4✓ Branch 0 taken 436406 times.
✓ Branch 1 taken 60169 times.
✓ Branch 2 taken 11786 times.
✓ Branch 3 taken 424620 times.
|
496575 | if (fc->tab.msf[off_q] || fc->tab.iaf[off_q]) |
613 | 71955 | vvc_deblock_subblock_bs_vertical(lc, cb_x, cb_y, x0, y0, width, height); | |
614 | } | ||
615 | 971013 | } | |
616 | |||
617 | 971013 | static void vvc_deblock_bs_luma_horizontal(const VVCLocalContext *lc, | |
618 | const int x0, const int y0, const int width, const int height, const int rs) | ||
619 | { | ||
620 | 971013 | const VVCFrameContext *fc = lc->fc; | |
621 | 971013 | const MvField *tab_mvf = fc->tab.mvf; | |
622 | 971013 | const int log2_min_pu_size = MIN_PU_LOG2; | |
623 | 971013 | const int min_pu_width = fc->ps.pps->min_pu_width; | |
624 | 971013 | const int min_cb_log2 = fc->ps.sps->min_cb_log2_size_y; | |
625 | 971013 | const int min_cb_width = fc->ps.pps->min_cb_width; | |
626 | 971013 | const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width + | |
627 | 971013 | (x0 >> log2_min_pu_size)].pred_flag == PF_INTRA; | |
628 | int boundary_upper; | ||
629 | 971013 | int has_horizontal_sb = 0; | |
630 | |||
631 | 971013 | const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2); | |
632 | 971013 | const int cb_x = fc->tab.cb_pos_x[LUMA][off_q]; | |
633 | 971013 | const int cb_y = fc->tab.cb_pos_y[LUMA][off_q]; | |
634 | 971013 | const int cb_height = fc->tab.cb_height[LUMA][off_q]; | |
635 | 971013 | const int off_y = y0 - cb_y; | |
636 | |||
637 |
2/2✓ Branch 0 taken 496575 times.
✓ Branch 1 taken 474438 times.
|
971013 | if (!is_intra) { |
638 |
4/4✓ Branch 0 taken 436406 times.
✓ Branch 1 taken 60169 times.
✓ Branch 2 taken 11786 times.
✓ Branch 3 taken 424620 times.
|
496575 | if (fc->tab.msf[off_q] || fc->tab.iaf[off_q]) |
639 | 71955 | has_horizontal_sb = cb_height > 8; | |
640 | } | ||
641 | |||
642 |
3/4✓ Branch 0 taken 944629 times.
✓ Branch 1 taken 26384 times.
✓ Branch 2 taken 944629 times.
✗ Branch 3 not taken.
|
971013 | boundary_upper = deblock_is_boundary(lc, y0 > 0 && !(y0 & 3), y0, rs, 0); |
643 | |||
644 |
2/2✓ Branch 0 taken 942726 times.
✓ Branch 1 taken 28287 times.
|
971013 | if (boundary_upper) { |
645 | 942726 | const RefPicList *rpl_top = | |
646 |
2/2✓ Branch 0 taken 33002 times.
✓ Branch 1 taken 909724 times.
|
942726 | (lc->boundary_flags & BOUNDARY_UPPER_SLICE) ? ff_vvc_get_ref_list(fc, fc->ref, x0, y0 - 1) : lc->sc->rpl; |
647 | |||
648 |
2/2✓ Branch 0 taken 4763964 times.
✓ Branch 1 taken 942726 times.
|
5706690 | for (int i = 0; i < width; i += 4) { |
649 | uint8_t max_len_p, max_len_q; | ||
650 | 4763964 | const int bs = deblock_bs(lc, x0 + i, y0 - 1, x0 + i, y0, rpl_top, 0, off_y, has_horizontal_sb); | |
651 | |||
652 | 4763964 | TAB_BS(fc->tab.horizontal_bs[LUMA], x0 + i, y0) = bs; | |
653 | |||
654 | 4763964 | derive_max_filter_length_luma(fc, x0 + i, y0, is_intra, has_horizontal_sb, 0, &max_len_p, &max_len_q); | |
655 | 4763964 | TAB_MAX_LEN(fc->tab.horizontal_p, x0 + i, y0) = max_len_p; | |
656 | 4763964 | TAB_MAX_LEN(fc->tab.horizontal_q, x0 + i, y0) = max_len_q; | |
657 | } | ||
658 | } | ||
659 | |||
660 |
2/2✓ Branch 0 taken 496575 times.
✓ Branch 1 taken 474438 times.
|
971013 | if (!is_intra) { |
661 |
4/4✓ Branch 0 taken 436406 times.
✓ Branch 1 taken 60169 times.
✓ Branch 2 taken 11786 times.
✓ Branch 3 taken 424620 times.
|
496575 | if (fc->tab.msf[off_q] || fc->tab.iaf[off_q]) |
662 | 71955 | vvc_deblock_subblock_bs_horizontal(lc, cb_x, cb_y, x0, y0, width, height); | |
663 | } | ||
664 | 971013 | } | |
665 | |||
666 | 628986 | static void vvc_deblock_bs_chroma_vertical(const VVCLocalContext *lc, | |
667 | const int x0, const int y0, const int width, const int height, const int rs) | ||
668 | { | ||
669 | 628986 | const VVCFrameContext *fc = lc->fc; | |
670 |
2/2✓ Branch 0 taken 615520 times.
✓ Branch 1 taken 13466 times.
|
1244506 | const int boundary_left = deblock_is_boundary(lc, |
671 |
2/2✓ Branch 0 taken 471835 times.
✓ Branch 1 taken 143685 times.
|
615520 | x0 > 0 && !(x0 & ((CHROMA_GRID << fc->ps.sps->hshift[CHROMA]) - 1)), x0, rs, 1); |
672 | |||
673 |
2/2✓ Branch 0 taken 470174 times.
✓ Branch 1 taken 158812 times.
|
628986 | if (boundary_left) { |
674 |
2/2✓ Branch 0 taken 6635628 times.
✓ Branch 1 taken 470174 times.
|
7105802 | for (int i = 0; i < height; i += 2) { |
675 |
2/2✓ Branch 0 taken 13271256 times.
✓ Branch 1 taken 6635628 times.
|
19906884 | for (int c_idx = CB; c_idx <= CR; c_idx++) { |
676 | 13271256 | const int bs = deblock_bs(lc, x0 - 1, y0 + i, x0, y0 + i, NULL, c_idx, 0, 0); | |
677 | |||
678 | 13271256 | TAB_BS(fc->tab.vertical_bs[c_idx], x0, (y0 + i)) = bs; | |
679 | } | ||
680 | } | ||
681 | } | ||
682 | 628986 | } | |
683 | |||
684 | 628986 | static void vvc_deblock_bs_chroma_horizontal(const VVCLocalContext *lc, | |
685 | const int x0, const int y0, const int width, const int height, const int rs) | ||
686 | { | ||
687 | 628986 | const VVCFrameContext *fc = lc->fc; | |
688 |
2/2✓ Branch 0 taken 606785 times.
✓ Branch 1 taken 22201 times.
|
1235771 | const int boundary_upper = deblock_is_boundary(lc, |
689 |
2/2✓ Branch 0 taken 473223 times.
✓ Branch 1 taken 133562 times.
|
606785 | y0 > 0 && !(y0 & ((CHROMA_GRID << fc->ps.sps->vshift[CHROMA]) - 1)), y0, rs, 0); |
690 | |||
691 |
2/2✓ Branch 0 taken 471779 times.
✓ Branch 1 taken 157207 times.
|
628986 | if (boundary_upper) { |
692 |
2/2✓ Branch 0 taken 6997162 times.
✓ Branch 1 taken 471779 times.
|
7468941 | for (int i = 0; i < width; i += 2) { |
693 |
2/2✓ Branch 0 taken 13994324 times.
✓ Branch 1 taken 6997162 times.
|
20991486 | for (int c_idx = CB; c_idx <= CR; c_idx++) { |
694 | 13994324 | const int bs = deblock_bs(lc, x0 + i, y0 - 1, x0 + i, y0, NULL, c_idx, 0, 0); | |
695 | |||
696 | 13994324 | TAB_BS(fc->tab.horizontal_bs[c_idx], x0 + i, y0) = bs; | |
697 | } | ||
698 | } | ||
699 | } | ||
700 | 628986 | } | |
701 | |||
702 | typedef void (*deblock_bs_fn)(const VVCLocalContext *lc, const int x0, const int y0, | ||
703 | const int width, const int height, const int rs); | ||
704 | |||
705 | 85782 | static void vvc_deblock_bs(const VVCLocalContext *lc, const int x0, const int y0, const int rs, const int vertical) | |
706 | { | ||
707 | 85782 | const VVCFrameContext *fc = lc->fc; | |
708 | 85782 | const VVCSPS *sps = fc->ps.sps; | |
709 | 85782 | const VVCPPS *pps = fc->ps.pps; | |
710 | 85782 | const int ctb_size = sps->ctb_size_y; | |
711 | 85782 | const int x_end = FFMIN(x0 + ctb_size, pps->width) >> MIN_TU_LOG2; | |
712 | 85782 | const int y_end = FFMIN(y0 + ctb_size, pps->height) >> MIN_TU_LOG2; | |
713 | 85782 | deblock_bs_fn deblock_bs[2][2] = { | |
714 | { vvc_deblock_bs_luma_horizontal, vvc_deblock_bs_chroma_horizontal }, | ||
715 | { vvc_deblock_bs_luma_vertical, vvc_deblock_bs_chroma_vertical } | ||
716 | }; | ||
717 | |||
718 |
2/2✓ Branch 0 taken 171564 times.
✓ Branch 1 taken 85782 times.
|
257346 | for (int is_chroma = 0; is_chroma <= 1; is_chroma++) { |
719 | 171564 | const int hs = sps->hshift[is_chroma]; | |
720 | 171564 | const int vs = sps->vshift[is_chroma]; | |
721 |
2/2✓ Branch 0 taken 5117720 times.
✓ Branch 1 taken 171564 times.
|
5289284 | for (int y = y0 >> MIN_TU_LOG2; y < y_end; y++) { |
722 |
2/2✓ Branch 0 taken 159738240 times.
✓ Branch 1 taken 5117720 times.
|
164855960 | for (int x = x0 >> MIN_TU_LOG2; x < x_end; x++) { |
723 | 159738240 | const int off = y * fc->ps.pps->min_tu_width + x; | |
724 |
4/4✓ Branch 0 taken 17007344 times.
✓ Branch 1 taken 142730896 times.
✓ Branch 2 taken 3199998 times.
✓ Branch 3 taken 13807346 times.
|
159738240 | if ((fc->tab.tb_pos_x0[is_chroma][off] >> MIN_TU_LOG2) == x && (fc->tab.tb_pos_y0[is_chroma][off] >> MIN_TU_LOG2) == y) { |
725 | 3199998 | deblock_bs[vertical][is_chroma](lc, x << MIN_TU_LOG2, y << MIN_TU_LOG2, | |
726 | 3199998 | fc->tab.tb_width[is_chroma][off] << hs, fc->tab.tb_height[is_chroma][off] << vs, rs); | |
727 | } | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | 85782 | } | |
732 | |||
733 | //part of 8.8.3.3 Derivation process of transform block boundary | ||
734 | 6097542 | static void max_filter_length_luma(const VVCFrameContext *fc, const int qx, const int qy, | |
735 | const int vertical, uint8_t *max_len_p, uint8_t *max_len_q) | ||
736 | { | ||
737 |
2/2✓ Branch 0 taken 2966669 times.
✓ Branch 1 taken 3130873 times.
|
6097542 | const uint8_t *tab_len_p = vertical ? fc->tab.vertical_p : fc->tab.horizontal_p; |
738 |
2/2✓ Branch 0 taken 2966669 times.
✓ Branch 1 taken 3130873 times.
|
6097542 | const uint8_t *tab_len_q = vertical ? fc->tab.vertical_q : fc->tab.horizontal_q; |
739 | 6097542 | *max_len_p = TAB_MAX_LEN(tab_len_p, qx, qy); | |
740 | 6097542 | *max_len_q = TAB_MAX_LEN(tab_len_q, qx, qy); | |
741 | 6097542 | } | |
742 | |||
743 | //part of 8.8.3.3 Derivation process of transform block boundary | ||
744 | 3141554 | static void max_filter_length_chroma(const VVCFrameContext *fc, const int qx, const int qy, | |
745 | const int vertical, const int horizontal_ctu_edge, const int bs, uint8_t *max_len_p, uint8_t *max_len_q) | ||
746 | { | ||
747 |
2/2✓ Branch 0 taken 1520188 times.
✓ Branch 1 taken 1621366 times.
|
3141554 | const int px = vertical ? qx - 1 : qx; |
748 |
2/2✓ Branch 0 taken 1621366 times.
✓ Branch 1 taken 1520188 times.
|
3141554 | const int py = !vertical ? qy - 1 : qy; |
749 |
2/2✓ Branch 0 taken 1520188 times.
✓ Branch 1 taken 1621366 times.
|
3141554 | const uint8_t *tb_size = vertical ? fc->tab.tb_width[CHROMA] : fc->tab.tb_height[CHROMA]; |
750 | |||
751 | 3141554 | const int size_p = tb_size[(py >> MIN_TU_LOG2) * fc->ps.pps->min_tu_width + (px >> MIN_TU_LOG2)]; | |
752 | 3141554 | const int size_q = tb_size[(qy >> MIN_TU_LOG2) * fc->ps.pps->min_tu_width + (qx >> MIN_TU_LOG2)]; | |
753 |
4/4✓ Branch 0 taken 2600245 times.
✓ Branch 1 taken 541309 times.
✓ Branch 2 taken 2248349 times.
✓ Branch 3 taken 351896 times.
|
3141554 | if (size_p >= 8 && size_q >= 8) { |
754 | 2248349 | *max_len_p = *max_len_q = 3; | |
755 |
2/2✓ Branch 0 taken 282115 times.
✓ Branch 1 taken 1966234 times.
|
2248349 | if (horizontal_ctu_edge) |
756 | 282115 | *max_len_p = 1; | |
757 | } else { | ||
758 | //part of 8.8.3.6.4 Decision process for chroma block edges | ||
759 | 893205 | *max_len_p = *max_len_q = (bs == 2); | |
760 | } | ||
761 | 3141554 | } | |
762 | |||
763 | 9239096 | static void max_filter_length(const VVCFrameContext *fc, const int qx, const int qy, | |
764 | const int c_idx, const int vertical, const int horizontal_ctu_edge, const int bs, uint8_t *max_len_p, uint8_t *max_len_q) | ||
765 | { | ||
766 |
2/2✓ Branch 0 taken 6097542 times.
✓ Branch 1 taken 3141554 times.
|
9239096 | if (!c_idx) |
767 | 6097542 | max_filter_length_luma(fc, qx, qy, vertical, max_len_p, max_len_q); | |
768 | else | ||
769 | 3141554 | max_filter_length_chroma(fc, qx, qy, vertical, horizontal_ctu_edge, bs, max_len_p, max_len_q); | |
770 | 9239096 | } | |
771 | |||
772 | #define TC_CALC(qp, bs) \ | ||
773 | tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \ | ||
774 | (tc_offset & -2), \ | ||
775 | 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)] | ||
776 | |||
777 | // part of 8.8.3.6.2 Decision process for luma block edges | ||
778 | 6097542 | static int get_qp_y(const VVCFrameContext *fc, const uint8_t *src, const int x, const int y, const int vertical) | |
779 | { | ||
780 | 6097542 | const VVCSPS *sps = fc->ps.sps; | |
781 | 6097542 | const int qp = (ff_vvc_get_qPy(fc, x - vertical, y - !vertical) + ff_vvc_get_qPy(fc, x, y) + 1) >> 1; | |
782 | 6097542 | int qp_offset = 0; | |
783 | int level; | ||
784 | |||
785 |
1/2✓ Branch 0 taken 6097542 times.
✗ Branch 1 not taken.
|
6097542 | if (!sps->r->sps_ladf_enabled_flag) |
786 | 6097542 | return qp; | |
787 | |||
788 | ✗ | level = fc->vvcdsp.lf.ladf_level[vertical](src, fc->frame->linesize[LUMA]); | |
789 | ✗ | qp_offset = sps->r->sps_ladf_lowest_interval_qp_offset; | |
790 | ✗ | for (int i = 0; i < sps->num_ladf_intervals - 1 && level > sps->ladf_interval_lower_bound[i + 1]; i++) | |
791 | ✗ | qp_offset = sps->r->sps_ladf_qp_offset[i]; | |
792 | |||
793 | ✗ | return qp + qp_offset; | |
794 | } | ||
795 | |||
796 | // part of 8.8.3.6.2 Decision process for luma block edges | ||
797 | 3141554 | static int get_qp_c(const VVCFrameContext *fc, const int x, const int y, const int c_idx, const int vertical) | |
798 | { | ||
799 | 3141554 | const VVCSPS *sps = fc->ps.sps; | |
800 | 3141554 | return (get_qPc(fc, x - vertical, y - !vertical, c_idx) + get_qPc(fc, x, y, c_idx) - 2 * sps->qp_bd_offset + 1) >> 1; | |
801 | } | ||
802 | |||
803 | 9239096 | static int get_qp(const VVCFrameContext *fc, const uint8_t *src, const int x, const int y, const int c_idx, const int vertical) | |
804 | { | ||
805 |
2/2✓ Branch 0 taken 6097542 times.
✓ Branch 1 taken 3141554 times.
|
9239096 | if (!c_idx) |
806 | 6097542 | return get_qp_y(fc, src, x, y, vertical); | |
807 | 3141554 | return get_qp_c(fc, x, y, c_idx, vertical); | |
808 | } | ||
809 | |||
810 | 42891 | void ff_vvc_deblock_vertical(const VVCLocalContext *lc, const int x0, const int y0, const int rs) | |
811 | { | ||
812 | 42891 | VVCFrameContext *fc = lc->fc; | |
813 | 42891 | const VVCSPS *sps = fc->ps.sps; | |
814 |
2/2✓ Branch 0 taken 42371 times.
✓ Branch 1 taken 520 times.
|
42891 | const int c_end = sps->r->sps_chroma_format_idc ? VVC_MAX_SAMPLE_ARRAYS : 1; |
815 | uint8_t *src; | ||
816 | int x, y, qp; | ||
817 | |||
818 | //not use this yet, may needed by plt. | ||
819 | 42891 | const uint8_t no_p[4] = { 0 }; | |
820 | 42891 | const uint8_t no_q[4] = { 0 } ; | |
821 | |||
822 | 42891 | const int ctb_log2_size_y = fc->ps.sps->ctb_log2_size_y; | |
823 | int x_end, y_end; | ||
824 | 42891 | const int ctb_size = 1 << ctb_log2_size_y; | |
825 | 42891 | const DBParams *params = fc->tab.deblock + rs; | |
826 | |||
827 | 42891 | vvc_deblock_bs(lc, x0, y0, rs, 1); | |
828 | |||
829 | 42891 | x_end = x0 + ctb_size; | |
830 |
2/2✓ Branch 0 taken 1418 times.
✓ Branch 1 taken 41473 times.
|
42891 | if (x_end > fc->ps.pps->width) |
831 | 1418 | x_end = fc->ps.pps->width; | |
832 | 42891 | y_end = y0 + ctb_size; | |
833 |
2/2✓ Branch 0 taken 6739 times.
✓ Branch 1 taken 36152 times.
|
42891 | if (y_end > fc->ps.pps->height) |
834 | 6739 | y_end = fc->ps.pps->height; | |
835 | |||
836 |
2/2✓ Branch 0 taken 127633 times.
✓ Branch 1 taken 42891 times.
|
170524 | for (int c_idx = 0; c_idx < c_end; c_idx++) { |
837 | 127633 | const int hs = sps->hshift[c_idx]; | |
838 | 127633 | const int vs = sps->vshift[c_idx]; | |
839 |
2/2✓ Branch 0 taken 84742 times.
✓ Branch 1 taken 42891 times.
|
127633 | const int grid = c_idx ? (CHROMA_GRID << hs) : LUMA_GRID; |
840 | 127633 | const int tc_offset = params->tc_offset[c_idx]; | |
841 | 127633 | const int beta_offset = params->beta_offset[c_idx]; | |
842 | |||
843 |
2/2✓ Branch 0 taken 1478495 times.
✓ Branch 1 taken 127633 times.
|
1606128 | for (y = y0; y < y_end; y += (DEBLOCK_STEP << vs)) { |
844 |
4/4✓ Branch 0 taken 1352944 times.
✓ Branch 1 taken 125551 times.
✓ Branch 2 taken 29710169 times.
✓ Branch 3 taken 1478495 times.
|
31188664 | for (x = x0 ? x0 : grid; x < x_end; x += grid) { |
845 | 29710169 | int32_t bs[4], beta[4], tc[4], all_zero_bs = 1; | |
846 | uint8_t max_len_p[4], max_len_q[4]; | ||
847 | |||
848 |
2/2✓ Branch 0 taken 65984766 times.
✓ Branch 1 taken 29710169 times.
|
95694935 | for (int i = 0; i < DEBLOCK_STEP >> (2 - vs); i++) { |
849 | 65984766 | const int dy = i << 2; | |
850 |
2/2✓ Branch 0 taken 65910510 times.
✓ Branch 1 taken 74256 times.
|
65984766 | bs[i] = (y + dy < y_end) ? TAB_BS(fc->tab.vertical_bs[c_idx], x, y + dy) : 0; |
851 |
2/2✓ Branch 0 taken 4486857 times.
✓ Branch 1 taken 61497909 times.
|
65984766 | if (bs[i]) { |
852 | 4486857 | src = &fc->frame->data[c_idx][((y + dy) >> vs) * fc->frame->linesize[c_idx] + ((x >> hs) << fc->ps.sps->pixel_shift)]; | |
853 | 4486857 | qp = get_qp(fc, src, x, y + dy, c_idx, 1); | |
854 | |||
855 | 4486857 | beta[i] = betatable[av_clip(qp + beta_offset, 0, MAX_QP)]; | |
856 | |||
857 | 4486857 | max_filter_length(fc, x, y + dy, c_idx, 1, 0, bs[i], &max_len_p[i], &max_len_q[i]); | |
858 | 4486857 | all_zero_bs = 0; | |
859 | } | ||
860 |
2/2✓ Branch 0 taken 4486857 times.
✓ Branch 1 taken 61497909 times.
|
65984766 | tc[i] = bs[i] ? TC_CALC(qp, bs[i]) : 0; |
861 | } | ||
862 | |||
863 |
2/2✓ Branch 0 taken 1976979 times.
✓ Branch 1 taken 27733190 times.
|
29710169 | if (!all_zero_bs) { |
864 | 1976979 | src = &fc->frame->data[c_idx][(y >> vs) * fc->frame->linesize[c_idx] + ((x >> hs) << fc->ps.sps->pixel_shift)]; | |
865 |
2/2✓ Branch 0 taken 1513224 times.
✓ Branch 1 taken 463755 times.
|
1976979 | if (!c_idx) { |
866 | 1513224 | fc->vvcdsp.lf.filter_luma[1](src, fc->frame->linesize[c_idx], | |
867 | beta, tc, no_p, no_q, max_len_p, max_len_q, 0); | ||
868 | } else { | ||
869 | 463755 | fc->vvcdsp.lf.filter_chroma[1](src, fc->frame->linesize[c_idx], | |
870 | beta, tc, no_p, no_q, max_len_p, max_len_q, vs); | ||
871 | } | ||
872 | } | ||
873 | } | ||
874 | } | ||
875 | } | ||
876 | 42891 | } | |
877 | |||
878 | 42891 | void ff_vvc_deblock_horizontal(const VVCLocalContext *lc, const int x0, const int y0, const int rs) | |
879 | { | ||
880 | 42891 | VVCFrameContext *fc = lc->fc; | |
881 | 42891 | const VVCSPS *sps = fc->ps.sps; | |
882 |
2/2✓ Branch 0 taken 42371 times.
✓ Branch 1 taken 520 times.
|
42891 | const int c_end = fc->ps.sps->r->sps_chroma_format_idc ? VVC_MAX_SAMPLE_ARRAYS : 1; |
883 | uint8_t* src; | ||
884 | int x, y, qp; | ||
885 | |||
886 | //not use this yet, may needed by plt. | ||
887 | 42891 | const uint8_t no_p[4] = { 0 }; | |
888 | 42891 | const uint8_t no_q[4] = { 0 } ; | |
889 | |||
890 | 42891 | const int ctb_log2_size_y = fc->ps.sps->ctb_log2_size_y; | |
891 | int x_end, y_end; | ||
892 | 42891 | const int ctb_size = 1 << ctb_log2_size_y; | |
893 | 42891 | const DBParams *params = fc->tab.deblock + rs; | |
894 | |||
895 | 42891 | vvc_deblock_bs(lc, x0, y0, rs, 0); | |
896 | |||
897 | 42891 | x_end = x0 + ctb_size; | |
898 |
2/2✓ Branch 0 taken 1418 times.
✓ Branch 1 taken 41473 times.
|
42891 | if (x_end > fc->ps.pps->width) |
899 | 1418 | x_end = fc->ps.pps->width; | |
900 | 42891 | y_end = y0 + ctb_size; | |
901 |
2/2✓ Branch 0 taken 6739 times.
✓ Branch 1 taken 36152 times.
|
42891 | if (y_end > fc->ps.pps->height) |
902 | 6739 | y_end = fc->ps.pps->height; | |
903 | |||
904 |
2/2✓ Branch 0 taken 127633 times.
✓ Branch 1 taken 42891 times.
|
170524 | for (int c_idx = 0; c_idx < c_end; c_idx++) { |
905 | 127633 | const int hs = sps->hshift[c_idx]; | |
906 | 127633 | const int vs = sps->vshift[c_idx]; | |
907 |
2/2✓ Branch 0 taken 84742 times.
✓ Branch 1 taken 42891 times.
|
127633 | const int grid = c_idx ? (CHROMA_GRID << vs) : LUMA_GRID; |
908 | 127633 | const int beta_offset = params->beta_offset[c_idx]; | |
909 | 127633 | const int tc_offset = params->tc_offset[c_idx]; | |
910 | |||
911 |
2/2✓ Branch 0 taken 2118210 times.
✓ Branch 1 taken 127633 times.
|
2245843 | for (y = y0; y < y_end; y += grid) { |
912 | 2118210 | const uint8_t horizontal_ctu_edge = !(y % fc->ps.sps->ctb_size_y); | |
913 |
2/2✓ Branch 0 taken 19697 times.
✓ Branch 1 taken 2098513 times.
|
2118210 | if (!y) |
914 | 19697 | continue; | |
915 | |||
916 |
2/2✓ Branch 0 taken 29614012 times.
✓ Branch 1 taken 2098513 times.
|
31712525 | for (x = x0 ? x0: 0; x < x_end; x += (DEBLOCK_STEP << hs)) { |
917 | 29614012 | int32_t bs[4], beta[4], tc[4], all_zero_bs = 1; | |
918 | uint8_t max_len_p[4], max_len_q[4]; | ||
919 | |||
920 |
2/2✓ Branch 0 taken 65729696 times.
✓ Branch 1 taken 29614012 times.
|
95343708 | for (int i = 0; i < DEBLOCK_STEP >> (2 - hs); i++) { |
921 | 65729696 | const int dx = i << 2; | |
922 | |||
923 |
1/2✓ Branch 0 taken 65729696 times.
✗ Branch 1 not taken.
|
65729696 | bs[i] = (x + dx < x_end) ? TAB_BS(fc->tab.horizontal_bs[c_idx], x + dx, y) : 0; |
924 |
2/2✓ Branch 0 taken 4752239 times.
✓ Branch 1 taken 60977457 times.
|
65729696 | if (bs[i]) { |
925 | 4752239 | src = &fc->frame->data[c_idx][(y >> vs) * fc->frame->linesize[c_idx] + (((x + dx)>> hs) << fc->ps.sps->pixel_shift)]; | |
926 | 4752239 | qp = get_qp(fc, src, x + dx, y, c_idx, 0); | |
927 | |||
928 | 4752239 | beta[i] = betatable[av_clip(qp + beta_offset, 0, MAX_QP)]; | |
929 | |||
930 | 4752239 | max_filter_length(fc, x + dx, y, c_idx, 0, horizontal_ctu_edge, bs[i], &max_len_p[i], &max_len_q[i]); | |
931 | 4752239 | all_zero_bs = 0; | |
932 | } | ||
933 |
2/2✓ Branch 0 taken 4752239 times.
✓ Branch 1 taken 60977457 times.
|
65729696 | tc[i] = bs[i] ? TC_CALC(qp, bs[i]) : 0; |
934 | } | ||
935 |
2/2✓ Branch 0 taken 2085439 times.
✓ Branch 1 taken 27528573 times.
|
29614012 | if (!all_zero_bs) { |
936 | 2085439 | src = &fc->frame->data[c_idx][(y >> vs) * fc->frame->linesize[c_idx] + ((x >> hs) << fc->ps.sps->pixel_shift)]; | |
937 |
2/2✓ Branch 0 taken 1597466 times.
✓ Branch 1 taken 487973 times.
|
2085439 | if (!c_idx) { |
938 | 1597466 | fc->vvcdsp.lf.filter_luma[0](src, fc->frame->linesize[c_idx], | |
939 | beta, tc, no_p, no_q, max_len_p, max_len_q, horizontal_ctu_edge); | ||
940 | } else { | ||
941 | 487973 | fc->vvcdsp.lf.filter_chroma[0](src, fc->frame->linesize[c_idx], | |
942 | beta, tc, no_p, no_q, max_len_p, max_len_q, hs); | ||
943 | } | ||
944 | } | ||
945 | } | ||
946 | } | ||
947 | } | ||
948 | 42891 | } | |
949 | |||
950 | 539494 | static void alf_copy_border(uint8_t *dst, const uint8_t *src, | |
951 | const int pixel_shift, int width, const int height, const ptrdiff_t dst_stride, const ptrdiff_t src_stride) | ||
952 | { | ||
953 | 539494 | width <<= pixel_shift; | |
954 |
2/2✓ Branch 0 taken 27311486 times.
✓ Branch 1 taken 539494 times.
|
27850980 | for (int i = 0; i < height; i++) { |
955 | 27311486 | memcpy(dst, src, width); | |
956 | 27311486 | dst += dst_stride; | |
957 | 27311486 | src += src_stride; | |
958 | } | ||
959 | 539494 | } | |
960 | |||
961 | 8043 | static void alf_extend_vert(uint8_t *_dst, const uint8_t *_src, | |
962 | const int pixel_shift, const int width, const int height, ptrdiff_t stride) | ||
963 | { | ||
964 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8043 times.
|
8043 | if (pixel_shift == 0) { |
965 | ✗ | for (int i = 0; i < height; i++) { | |
966 | ✗ | memset(_dst, *_src, width); | |
967 | ✗ | _src += stride; | |
968 | ✗ | _dst += stride; | |
969 | } | ||
970 | } else { | ||
971 | 8043 | const uint16_t *src = (const uint16_t *)_src; | |
972 | 8043 | uint16_t *dst = (uint16_t *)_dst; | |
973 | 8043 | stride >>= pixel_shift; | |
974 | |||
975 |
2/2✓ Branch 0 taken 786360 times.
✓ Branch 1 taken 8043 times.
|
794403 | for (int i = 0; i < height; i++) { |
976 |
2/2✓ Branch 0 taken 2034740 times.
✓ Branch 1 taken 786360 times.
|
2821100 | for (int j = 0; j < width; j++) |
977 | 2034740 | dst[j] = *src; | |
978 | 786360 | src += stride; | |
979 | 786360 | dst += stride; | |
980 | } | ||
981 | } | ||
982 | 8043 | } | |
983 | |||
984 | 38675 | static void alf_extend_horz(uint8_t *dst, const uint8_t *src, | |
985 | const int pixel_shift, int width, const int height, const ptrdiff_t stride) | ||
986 | { | ||
987 | 38675 | width <<= pixel_shift; | |
988 |
2/2✓ Branch 0 taken 95612 times.
✓ Branch 1 taken 38675 times.
|
134287 | for (int i = 0; i < height; i++) { |
989 | 95612 | memcpy(dst, src, width); | |
990 | 95612 | dst += stride; | |
991 | } | ||
992 | 38675 | } | |
993 | |||
994 | 101992 | static void alf_copy_ctb_to_hv(VVCFrameContext *fc, const uint8_t *src, const ptrdiff_t src_stride, | |
995 | const int x, const int y, const int width, const int height, const int rx, const int ry, const int c_idx) | ||
996 | { | ||
997 | 101992 | const int ps = fc->ps.sps->pixel_shift; | |
998 | 101992 | const int w = fc->ps.pps->width >> fc->ps.sps->hshift[c_idx]; | |
999 | 101992 | const int h = fc->ps.pps->height >> fc->ps.sps->vshift[c_idx]; | |
1000 |
2/2✓ Branch 0 taken 34344 times.
✓ Branch 1 taken 67648 times.
|
101992 | const int border_pixels = (c_idx == 0) ? ALF_BORDER_LUMA : ALF_BORDER_CHROMA; |
1001 | 101992 | const int offset_h[] = { 0, height - border_pixels }; | |
1002 | 101992 | const int offset_v[] = { 0, width - border_pixels }; | |
1003 | |||
1004 | /* copy horizontal edges */ | ||
1005 |
2/2✓ Branch 0 taken 203984 times.
✓ Branch 1 taken 101992 times.
|
305976 | for (int i = 0; i < FF_ARRAY_ELEMS(offset_h); i++) { |
1006 | 203984 | alf_copy_border(fc->tab.alf_pixel_buffer_h[c_idx][i] + ((border_pixels * ry * w + x)<< ps), | |
1007 | 203984 | src + offset_h[i] * src_stride, ps, width, border_pixels, w << ps, src_stride); | |
1008 | } | ||
1009 | /* copy vertical edges */ | ||
1010 |
2/2✓ Branch 0 taken 203984 times.
✓ Branch 1 taken 101992 times.
|
305976 | for (int i = 0; i < FF_ARRAY_ELEMS(offset_v); i++) { |
1011 | 203984 | alf_copy_border(fc->tab.alf_pixel_buffer_v[c_idx][i] + ((h * rx + y) * (border_pixels << ps)), | |
1012 | 203984 | src + (offset_v[i] << ps), ps, border_pixels, height, border_pixels << ps, src_stride); | |
1013 | } | ||
1014 | 101992 | } | |
1015 | |||
1016 | 77080 | static void alf_fill_border_h(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, const ptrdiff_t src_stride, | |
1017 | const uint8_t *border, const int width, const int border_pixels, const int ps, const int edge) | ||
1018 | { | ||
1019 |
2/2✓ Branch 0 taken 14591 times.
✓ Branch 1 taken 62489 times.
|
77080 | if (edge) |
1020 | 14591 | alf_extend_horz(dst, border, ps, width, border_pixels, dst_stride); | |
1021 | else | ||
1022 | 62489 | alf_copy_border(dst, src, ps, width, border_pixels, dst_stride, src_stride); | |
1023 | 77080 | } | |
1024 | |||
1025 | 77080 | static void alf_fill_border_v(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, | |
1026 | const uint8_t *border, const int border_pixels, const int height, const int pixel_shift, const int *edges, const int edge) | ||
1027 | { | ||
1028 | 77080 | const ptrdiff_t src_stride = (border_pixels << pixel_shift); | |
1029 | |||
1030 |
2/2✓ Branch 0 taken 8043 times.
✓ Branch 1 taken 69037 times.
|
77080 | if (edge) { |
1031 | 8043 | alf_extend_vert(dst, border, pixel_shift, border_pixels, height + 2 * border_pixels, dst_stride); | |
1032 | 8043 | return; | |
1033 | } | ||
1034 | |||
1035 | //left/right | ||
1036 | 69037 | alf_copy_border(dst + dst_stride * border_pixels * edges[TOP], src + src_stride * border_pixels * edges[TOP], | |
1037 | 69037 | pixel_shift, border_pixels, height + (!edges[TOP] + !edges[BOTTOM]) * border_pixels, dst_stride, src_stride); | |
1038 | |||
1039 | //top left/right | ||
1040 |
2/2✓ Branch 0 taken 10827 times.
✓ Branch 1 taken 58210 times.
|
69037 | if (edges[TOP]) |
1041 | 10827 | alf_extend_horz(dst, dst + dst_stride * border_pixels, pixel_shift, border_pixels, border_pixels, dst_stride); | |
1042 | |||
1043 | //bottom left/right | ||
1044 |
2/2✓ Branch 0 taken 13257 times.
✓ Branch 1 taken 55780 times.
|
69037 | if (edges[BOTTOM]) { |
1045 | 13257 | dst += dst_stride * (border_pixels + height); | |
1046 | 13257 | alf_extend_horz(dst, dst - dst_stride, pixel_shift, border_pixels, border_pixels, dst_stride); | |
1047 | } | ||
1048 | } | ||
1049 | |||
1050 | 38540 | static void alf_prepare_buffer(VVCFrameContext *fc, uint8_t *_dst, const uint8_t *_src, const int x, const int y, | |
1051 | const int rx, const int ry, const int width, const int height, const ptrdiff_t dst_stride, const ptrdiff_t src_stride, | ||
1052 | const int c_idx, const int *edges) | ||
1053 | { | ||
1054 | 38540 | const int ps = fc->ps.sps->pixel_shift; | |
1055 | 38540 | const int w = fc->ps.pps->width >> fc->ps.sps->hshift[c_idx]; | |
1056 | 38540 | const int h = fc->ps.pps->height >> fc->ps.sps->vshift[c_idx]; | |
1057 |
2/2✓ Branch 0 taken 17959 times.
✓ Branch 1 taken 20581 times.
|
38540 | const int border_pixels = c_idx == 0 ? ALF_BORDER_LUMA : ALF_BORDER_CHROMA; |
1058 | uint8_t *dst, *src; | ||
1059 | |||
1060 | 38540 | copy_ctb(_dst, _src, width << ps, height, dst_stride, src_stride); | |
1061 | |||
1062 | //top | ||
1063 | 38540 | src = fc->tab.alf_pixel_buffer_h[c_idx][1] + (((border_pixels * w) << ps) * (ry - 1) + (x << ps)); | |
1064 | 38540 | dst = _dst - border_pixels * dst_stride; | |
1065 | 38540 | alf_fill_border_h(dst, dst_stride, src, w << ps, _dst, width, border_pixels, ps, edges[TOP]); | |
1066 | |||
1067 | //bottom | ||
1068 | 38540 | src = fc->tab.alf_pixel_buffer_h[c_idx][0] + (((border_pixels * w) << ps) * (ry + 1) + (x << ps)); | |
1069 | 38540 | dst = _dst + height * dst_stride; | |
1070 | 38540 | alf_fill_border_h(dst, dst_stride, src, w << ps, _dst + (height - 1) * dst_stride, width, border_pixels, ps, edges[BOTTOM]); | |
1071 | |||
1072 | |||
1073 | //left | ||
1074 | 38540 | src = fc->tab.alf_pixel_buffer_v[c_idx][1] + (h * (rx - 1) + y - border_pixels) * (border_pixels << ps); | |
1075 | 38540 | dst = _dst - (border_pixels << ps) - border_pixels * dst_stride; | |
1076 | 38540 | alf_fill_border_v(dst, dst_stride, src, dst + (border_pixels << ps), border_pixels, height, ps, edges, edges[LEFT]); | |
1077 | |||
1078 | //right | ||
1079 | 38540 | src = fc->tab.alf_pixel_buffer_v[c_idx][0] + (h * (rx + 1) + y - border_pixels) * (border_pixels << ps); | |
1080 | 38540 | dst = _dst + (width << ps) - border_pixels * dst_stride; | |
1081 | 38540 | alf_fill_border_v(dst, dst_stride, src, dst - (1 << ps), border_pixels, height, ps, edges, edges[RIGHT]); | |
1082 | 38540 | } | |
1083 | |||
1084 | #define ALF_MAX_BLOCKS_IN_CTU (MAX_CTU_SIZE * MAX_CTU_SIZE / ALF_BLOCK_SIZE / ALF_BLOCK_SIZE) | ||
1085 | #define ALF_MAX_FILTER_SIZE (ALF_MAX_BLOCKS_IN_CTU * ALF_NUM_COEFF_LUMA) | ||
1086 | |||
1087 | 17481 | static void alf_get_coeff_and_clip(VVCLocalContext *lc, int16_t *coeff, int16_t *clip, | |
1088 | const uint8_t *src, ptrdiff_t src_stride, int width, int height, int vb_pos, ALFParams *alf) | ||
1089 | { | ||
1090 | 17481 | const VVCFrameContext *fc = lc->fc; | |
1091 | 17481 | const H266RawSliceHeader *rsh = lc->sc->sh.r; | |
1092 | 17481 | uint8_t fixed_clip_set[ALF_NUM_FILTERS_LUMA][ALF_NUM_COEFF_LUMA] = { 0 }; | |
1093 | const int16_t *coeff_set; | ||
1094 | const uint8_t *clip_idx_set; | ||
1095 | const uint8_t *class_to_filt; | ||
1096 | 17481 | const int size = width * height / ALF_BLOCK_SIZE / ALF_BLOCK_SIZE; | |
1097 | int class_idx[ALF_MAX_BLOCKS_IN_CTU]; | ||
1098 | int transpose_idx[ALF_MAX_BLOCKS_IN_CTU]; | ||
1099 | |||
1100 |
2/2✓ Branch 0 taken 2356 times.
✓ Branch 1 taken 15125 times.
|
17481 | if (alf->ctb_filt_set_idx_y < 16) { |
1101 | 2356 | coeff_set = &ff_vvc_alf_fix_filt_coeff[0][0]; | |
1102 | 2356 | clip_idx_set = &fixed_clip_set[0][0]; | |
1103 | 2356 | class_to_filt = ff_vvc_alf_class_to_filt_map[alf->ctb_filt_set_idx_y]; | |
1104 | } else { | ||
1105 | 15125 | const int id = rsh->sh_alf_aps_id_luma[alf->ctb_filt_set_idx_y - 16]; | |
1106 | 15125 | const VVCALF *aps = fc->ps.alf_list[id]; | |
1107 | 15125 | coeff_set = &aps->luma_coeff[0][0]; | |
1108 | 15125 | clip_idx_set = &aps->luma_clip_idx[0][0]; | |
1109 | 15125 | class_to_filt = ff_vvc_alf_aps_class_to_filt_map; | |
1110 | } | ||
1111 | 17481 | fc->vvcdsp.alf.classify(class_idx, transpose_idx, src, src_stride, width, height, | |
1112 | 17481 | vb_pos, lc->alf_gradient_tmp); | |
1113 | 17481 | fc->vvcdsp.alf.recon_coeff_and_clip(coeff, clip, class_idx, transpose_idx, size, | |
1114 | coeff_set, clip_idx_set, class_to_filt); | ||
1115 | 17481 | } | |
1116 | |||
1117 | 17481 | static void alf_filter_luma(VVCLocalContext *lc, uint8_t *dst, const uint8_t *src, | |
1118 | const ptrdiff_t dst_stride, const ptrdiff_t src_stride, const int x0, const int y0, | ||
1119 | const int width, const int height, const int _vb_pos, ALFParams *alf) | ||
1120 | { | ||
1121 | 17481 | const VVCFrameContext *fc = lc->fc; | |
1122 | 17481 | int vb_pos = _vb_pos - y0; | |
1123 | 17481 | int16_t *coeff = (int16_t*)lc->tmp; | |
1124 | 17481 | int16_t *clip = (int16_t *)lc->tmp1; | |
1125 | |||
1126 | av_assert0(ALF_MAX_FILTER_SIZE <= sizeof(lc->tmp)); | ||
1127 | av_assert0(ALF_MAX_FILTER_SIZE * sizeof(int16_t) <= sizeof(lc->tmp1)); | ||
1128 | |||
1129 | 17481 | alf_get_coeff_and_clip(lc, coeff, clip, src, src_stride, width, height, vb_pos, alf); | |
1130 | 17481 | fc->vvcdsp.alf.filter[LUMA](dst, dst_stride, src, src_stride, width, height, coeff, clip, vb_pos); | |
1131 | 17481 | } | |
1132 | |||
1133 | 123486 | static int alf_clip_from_idx(const VVCFrameContext *fc, const int idx) | |
1134 | { | ||
1135 | 123486 | const VVCSPS *sps = fc->ps.sps; | |
1136 | 123486 | const int offset[] = {0, 3, 5, 7}; | |
1137 | |||
1138 | 123486 | return 1 << (sps->bit_depth - offset[idx]); | |
1139 | } | ||
1140 | |||
1141 | 20581 | static void alf_filter_chroma(VVCLocalContext *lc, uint8_t *dst, const uint8_t *src, | |
1142 | const ptrdiff_t dst_stride, const ptrdiff_t src_stride, const int c_idx, | ||
1143 | const int width, const int height, const int vb_pos, ALFParams *alf) | ||
1144 | { | ||
1145 | 20581 | VVCFrameContext *fc = lc->fc; | |
1146 | 20581 | const H266RawSliceHeader *rsh = lc->sc->sh.r; | |
1147 | 20581 | const VVCALF *aps = fc->ps.alf_list[rsh->sh_alf_aps_id_chroma]; | |
1148 | 20581 | const int idx = alf->alf_ctb_filter_alt_idx[c_idx - 1]; | |
1149 | 20581 | const int16_t *coeff = aps->chroma_coeff[idx]; | |
1150 | int16_t clip[ALF_NUM_COEFF_CHROMA]; | ||
1151 | |||
1152 |
2/2✓ Branch 0 taken 123486 times.
✓ Branch 1 taken 20581 times.
|
144067 | for (int i = 0; i < ALF_NUM_COEFF_CHROMA; i++) |
1153 | 123486 | clip[i] = alf_clip_from_idx(fc, aps->chroma_clip_idx[idx][i]); | |
1154 | |||
1155 | 20581 | fc->vvcdsp.alf.filter[CHROMA](dst, dst_stride, src, src_stride, width, height, coeff, clip, vb_pos); | |
1156 | 20581 | } | |
1157 | |||
1158 | 8352 | static void alf_filter_cc(VVCLocalContext *lc, uint8_t *dst, const uint8_t *luma, | |
1159 | const ptrdiff_t dst_stride, const ptrdiff_t luma_stride, const int c_idx, | ||
1160 | const int width, const int height, const int hs, const int vs, const int vb_pos, ALFParams *alf) | ||
1161 | { | ||
1162 | 8352 | const VVCFrameContext *fc = lc->fc; | |
1163 | 8352 | const H266RawSliceHeader *rsh = lc->sc->sh.r; | |
1164 | 8352 | const int idx = c_idx - 1; | |
1165 |
2/2✓ Branch 0 taken 4332 times.
✓ Branch 1 taken 4020 times.
|
8352 | const int cc_aps_id = c_idx == CB ? rsh->sh_alf_cc_cb_aps_id : rsh->sh_alf_cc_cr_aps_id; |
1166 | 8352 | const VVCALF *aps = fc->ps.alf_list[cc_aps_id]; | |
1167 | |||
1168 |
1/2✓ Branch 0 taken 8352 times.
✗ Branch 1 not taken.
|
8352 | if (aps) { |
1169 | 8352 | const int16_t *coeff = aps->cc_coeff[idx][alf->ctb_cc_idc[idx] - 1]; | |
1170 | |||
1171 | 8352 | fc->vvcdsp.alf.filter_cc(dst, dst_stride, luma, luma_stride, width, height, hs, vs, coeff, vb_pos); | |
1172 | } | ||
1173 | 8352 | } | |
1174 | |||
1175 | 34344 | void ff_vvc_alf_copy_ctu_to_hv(VVCLocalContext* lc, const int x0, const int y0) | |
1176 | { | ||
1177 | 34344 | VVCFrameContext *fc = lc->fc; | |
1178 | 34344 | const int rx = x0 >> fc->ps.sps->ctb_log2_size_y; | |
1179 | 34344 | const int ry = y0 >> fc->ps.sps->ctb_log2_size_y; | |
1180 | 34344 | const int ctb_size_y = fc->ps.sps->ctb_size_y; | |
1181 | 34344 | const int ps = fc->ps.sps->pixel_shift; | |
1182 |
2/2✓ Branch 0 taken 33824 times.
✓ Branch 1 taken 520 times.
|
34344 | const int c_end = fc->ps.sps->r->sps_chroma_format_idc ? VVC_MAX_SAMPLE_ARRAYS : 1; |
1183 | |||
1184 |
2/2✓ Branch 0 taken 101992 times.
✓ Branch 1 taken 34344 times.
|
136336 | for (int c_idx = 0; c_idx < c_end; c_idx++) { |
1185 | 101992 | const int hs = fc->ps.sps->hshift[c_idx]; | |
1186 | 101992 | const int vs = fc->ps.sps->vshift[c_idx]; | |
1187 | 101992 | const int x = x0 >> hs; | |
1188 | 101992 | const int y = y0 >> vs; | |
1189 | 101992 | const int width = FFMIN(fc->ps.pps->width - x0, ctb_size_y) >> hs; | |
1190 | 101992 | const int height = FFMIN(fc->ps.pps->height - y0, ctb_size_y) >> vs; | |
1191 | |||
1192 | 101992 | const int src_stride = fc->frame->linesize[c_idx]; | |
1193 | 101992 | uint8_t* src = &fc->frame->data[c_idx][y * src_stride + (x << ps)]; | |
1194 | |||
1195 | 101992 | alf_copy_ctb_to_hv(fc, src, src_stride, x, y, width, height, rx, ry, c_idx); | |
1196 | } | ||
1197 | 34344 | } | |
1198 | |||
1199 | 34344 | void ff_vvc_alf_filter(VVCLocalContext *lc, const int x0, const int y0) | |
1200 | { | ||
1201 | 34344 | VVCFrameContext *fc = lc->fc; | |
1202 | 34344 | const VVCSPS *sps = fc->ps.sps; | |
1203 | 34344 | const VVCPPS *pps = fc->ps.pps; | |
1204 | 34344 | const int rx = x0 >> fc->ps.sps->ctb_log2_size_y; | |
1205 | 34344 | const int ry = y0 >> fc->ps.sps->ctb_log2_size_y; | |
1206 | 34344 | const int ctb_size_y = fc->ps.sps->ctb_size_y; | |
1207 | 34344 | const int ps = fc->ps.sps->pixel_shift; | |
1208 | 34344 | const int padded_stride = EDGE_EMU_BUFFER_STRIDE << ps; | |
1209 | 34344 | const int padded_offset = padded_stride * ALF_PADDING_SIZE + (ALF_PADDING_SIZE << ps); | |
1210 |
2/2✓ Branch 0 taken 33824 times.
✓ Branch 1 taken 520 times.
|
34344 | const int c_end = fc->ps.sps->r->sps_chroma_format_idc ? VVC_MAX_SAMPLE_ARRAYS : 1; |
1211 | 34344 | const int subpic_idx = lc->sc->sh.r->curr_subpic_idx; | |
1212 | 34344 | ALFParams *alf = &CTB(fc->tab.alf, rx, ry); | |
1213 | 34344 | int edges[MAX_EDGES] = { rx == 0, ry == 0, rx == pps->ctb_width - 1, ry == pps->ctb_height - 1 }; | |
1214 | |||
1215 |
2/2✓ Branch 0 taken 31509 times.
✓ Branch 1 taken 2835 times.
|
34344 | if (!pps->r->pps_loop_filter_across_tiles_enabled_flag) { |
1216 |
4/4✓ Branch 0 taken 28462 times.
✓ Branch 1 taken 3047 times.
✓ Branch 2 taken 333 times.
✓ Branch 3 taken 28129 times.
|
31509 | edges[LEFT] = edges[LEFT] || (lc->boundary_flags & BOUNDARY_LEFT_TILE); |
1217 |
4/4✓ Branch 0 taken 26039 times.
✓ Branch 1 taken 5470 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 25757 times.
|
31509 | edges[TOP] = edges[TOP] || (lc->boundary_flags & BOUNDARY_UPPER_TILE); |
1218 |
4/4✓ Branch 0 taken 28462 times.
✓ Branch 1 taken 3047 times.
✓ Branch 2 taken 333 times.
✓ Branch 3 taken 28129 times.
|
31509 | edges[RIGHT] = edges[RIGHT] || pps->ctb_to_col_bd[rx] != pps->ctb_to_col_bd[rx + 1]; |
1219 |
4/4✓ Branch 0 taken 26039 times.
✓ Branch 1 taken 5470 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 25757 times.
|
31509 | edges[BOTTOM] = edges[BOTTOM] || pps->ctb_to_row_bd[ry] != pps->ctb_to_row_bd[ry + 1]; |
1220 | } | ||
1221 | |||
1222 |
2/2✓ Branch 0 taken 31509 times.
✓ Branch 1 taken 2835 times.
|
34344 | if (!pps->r->pps_loop_filter_across_slices_enabled_flag) { |
1223 |
3/4✓ Branch 0 taken 28129 times.
✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28129 times.
|
31509 | edges[LEFT] = edges[LEFT] || (lc->boundary_flags & BOUNDARY_LEFT_SLICE); |
1224 |
4/4✓ Branch 0 taken 25757 times.
✓ Branch 1 taken 5752 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 25727 times.
|
31509 | edges[TOP] = edges[TOP] || (lc->boundary_flags & BOUNDARY_UPPER_SLICE); |
1225 |
3/4✓ Branch 0 taken 28129 times.
✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28129 times.
|
31509 | edges[RIGHT] = edges[RIGHT] || CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx + 1, ry); |
1226 |
4/4✓ Branch 0 taken 25757 times.
✓ Branch 1 taken 5752 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 25727 times.
|
31509 | edges[BOTTOM] = edges[BOTTOM] || CTB(fc->tab.slice_idx, rx, ry) != CTB(fc->tab.slice_idx, rx, ry + 1); |
1227 | } | ||
1228 | |||
1229 |
1/2✓ Branch 0 taken 34344 times.
✗ Branch 1 not taken.
|
34344 | if (!sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx]) { |
1230 |
3/4✓ Branch 0 taken 30775 times.
✓ Branch 1 taken 3569 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30775 times.
|
34344 | edges[LEFT] = edges[LEFT] || (lc->boundary_flags & BOUNDARY_LEFT_SUBPIC); |
1231 |
3/4✓ Branch 0 taken 28247 times.
✓ Branch 1 taken 6097 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28247 times.
|
34344 | edges[TOP] = edges[TOP] || (lc->boundary_flags & BOUNDARY_UPPER_SUBPIC); |
1232 |
3/4✓ Branch 0 taken 30775 times.
✓ Branch 1 taken 3569 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30775 times.
|
34344 | edges[RIGHT] = edges[RIGHT] || fc->ps.sps->r->sps_subpic_ctu_top_left_x[subpic_idx] + fc->ps.sps->r->sps_subpic_width_minus1[subpic_idx] == rx; |
1233 |
3/4✓ Branch 0 taken 28247 times.
✓ Branch 1 taken 6097 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28247 times.
|
34344 | edges[BOTTOM] = edges[BOTTOM] || fc->ps.sps->r->sps_subpic_ctu_top_left_y[subpic_idx] + fc->ps.sps->r->sps_subpic_height_minus1[subpic_idx] == ry; |
1234 | } | ||
1235 | |||
1236 |
2/2✓ Branch 0 taken 101992 times.
✓ Branch 1 taken 34344 times.
|
136336 | for (int c_idx = 0; c_idx < c_end; c_idx++) { |
1237 | 101992 | const int hs = fc->ps.sps->hshift[c_idx]; | |
1238 | 101992 | const int vs = fc->ps.sps->vshift[c_idx]; | |
1239 | 101992 | const int ctb_size_h = ctb_size_y >> hs; | |
1240 | 101992 | const int ctb_size_v = ctb_size_y >> vs; | |
1241 | 101992 | const int x = x0 >> hs; | |
1242 | 101992 | const int y = y0 >> vs; | |
1243 | 101992 | const int pic_width = fc->ps.pps->width >> hs; | |
1244 | 101992 | const int pic_height = fc->ps.pps->height >> vs; | |
1245 | 101992 | const int width = FFMIN(pic_width - x, ctb_size_h); | |
1246 | 101992 | const int height = FFMIN(pic_height - y, ctb_size_v); | |
1247 | 101992 | const int src_stride = fc->frame->linesize[c_idx]; | |
1248 | 101992 | uint8_t *src = &fc->frame->data[c_idx][y * src_stride + (x << ps)]; | |
1249 | uint8_t *padded; | ||
1250 | |||
1251 |
8/8✓ Branch 0 taken 63930 times.
✓ Branch 1 taken 38062 times.
✓ Branch 2 taken 16863 times.
✓ Branch 3 taken 47067 times.
✓ Branch 4 taken 16455 times.
✓ Branch 5 taken 408 times.
✓ Branch 6 taken 70 times.
✓ Branch 7 taken 16385 times.
|
101992 | if (alf->ctb_flag[c_idx] || (!c_idx && (alf->ctb_cc_idc[0] || alf->ctb_cc_idc[1]))) { |
1252 |
2/2✓ Branch 0 taken 20581 times.
✓ Branch 1 taken 17959 times.
|
38540 | padded = (c_idx ? lc->alf_buffer_chroma : lc->alf_buffer_luma) + padded_offset; |
1253 | 38540 | alf_prepare_buffer(fc, padded, src, x, y, rx, ry, width, height, | |
1254 | padded_stride, src_stride, c_idx, edges); | ||
1255 | } | ||
1256 |
2/2✓ Branch 0 taken 38062 times.
✓ Branch 1 taken 63930 times.
|
101992 | if (alf->ctb_flag[c_idx]) { |
1257 |
2/2✓ Branch 0 taken 17481 times.
✓ Branch 1 taken 20581 times.
|
38062 | if (!c_idx) { |
1258 | 17481 | alf_filter_luma(lc, src, padded, src_stride, padded_stride, x, y, | |
1259 | 17481 | width, height, y + ctb_size_v - ALF_VB_POS_ABOVE_LUMA, alf); | |
1260 | } else { | ||
1261 | 20581 | alf_filter_chroma(lc, src, padded, src_stride, padded_stride, c_idx, | |
1262 | width, height, ctb_size_v - ALF_VB_POS_ABOVE_CHROMA, alf); | ||
1263 | } | ||
1264 | } | ||
1265 |
4/4✓ Branch 0 taken 67648 times.
✓ Branch 1 taken 34344 times.
✓ Branch 2 taken 8352 times.
✓ Branch 3 taken 59296 times.
|
101992 | if (c_idx && alf->ctb_cc_idc[c_idx - 1]) { |
1266 | 8352 | padded = lc->alf_buffer_luma + padded_offset; | |
1267 | 8352 | alf_filter_cc(lc, src, padded, src_stride, padded_stride, c_idx, | |
1268 | 8352 | width, height, hs, vs, (ctb_size_v << vs) - ALF_VB_POS_ABOVE_LUMA, alf); | |
1269 | } | ||
1270 | |||
1271 | 101992 | alf->applied[c_idx] = 1; | |
1272 | } | ||
1273 | 34344 | } | |
1274 | |||
1275 | |||
1276 | 42891 | void ff_vvc_lmcs_filter(const VVCLocalContext *lc, const int x, const int y) | |
1277 | { | ||
1278 | 42891 | const SliceContext *sc = lc->sc; | |
1279 | 42891 | const VVCFrameContext *fc = lc->fc; | |
1280 | 42891 | const int ctb_size = fc->ps.sps->ctb_size_y; | |
1281 | 42891 | const int width = FFMIN(fc->ps.pps->width - x, ctb_size); | |
1282 | 42891 | const int height = FFMIN(fc->ps.pps->height - y, ctb_size); | |
1283 | 42891 | uint8_t *data = fc->frame->data[LUMA] + y * fc->frame->linesize[LUMA] + (x << fc->ps.sps->pixel_shift); | |
1284 |
2/2✓ Branch 0 taken 18592 times.
✓ Branch 1 taken 24299 times.
|
42891 | if (sc->sh.r->sh_lmcs_used_flag) |
1285 | 18592 | fc->vvcdsp.lmcs.filter(data, fc->frame->linesize[LUMA], width, height, &fc->ps.lmcs.inv_lut); | |
1286 | 42891 | } | |
1287 |