Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/dav1d/src/lf_mask.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 <string.h>
31
32
#include "common/intops.h"
33
34
#include "src/ctx.h"
35
#include "src/levels.h"
36
#include "src/lf_mask.h"
37
#include "src/tables.h"
38
39
static void decomp_tx(uint8_t (*const txa)[2 /* txsz, step */][32 /* y */][32 /* x */],
40
                      const enum RectTxfmSize from,
41
                      const int depth,
42
                      const int y_off, const int x_off,
43
                      const uint16_t *const tx_masks)
44
272k
{
45
272k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
46
272k
    const int is_split = (from == (int) TX_4X4 || depth > 1) ? 0 :
47
272k
        (tx_masks[depth] >> (y_off * 4 + x_off)) & 1;
48
49
272k
    if (is_split) {
50
20.3k
        const enum RectTxfmSize sub = t_dim->sub;
51
20.3k
        const int htw4 = t_dim->w >> 1, hth4 = t_dim->h >> 1;
52
53
20.3k
        decomp_tx(txa, sub, depth + 1, y_off * 2 + 0, x_off * 2 + 0, tx_masks);
54
20.3k
        if (t_dim->w >= t_dim->h)
55
16.7k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][0][htw4],
56
16.7k
                      sub, depth + 1, y_off * 2 + 0, x_off * 2 + 1, tx_masks);
57
20.3k
        if (t_dim->h >= t_dim->w) {
58
14.5k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][0],
59
14.5k
                      sub, depth + 1, y_off * 2 + 1, x_off * 2 + 0, tx_masks);
60
14.5k
            if (t_dim->w >= t_dim->h)
61
10.8k
                decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][htw4],
62
10.8k
                          sub, depth + 1, y_off * 2 + 1, x_off * 2 + 1, tx_masks);
63
14.5k
        }
64
252k
    } else {
65
252k
        const int lw = imin(2, t_dim->lw), lh = imin(2, t_dim->lh);
66
67
252k
#define set_ctx(rep_macro) \
68
1.15M
        for (int y = 0; y < t_dim->h; y++) { \
69
904k
            rep_macro(txa[0][0][y], 0, lw); \
70
904k
            rep_macro(txa[1][0][y], 0, lh); \
71
904k
            txa[0][1][y][0] = t_dim->w; \
72
904k
        } \
73
252k
        rep_macro(txa[1][1][0], 0, t_dim->h);
74
252k
        case_set_upto16(t_dim->lw);
75
252k
#undef set_ctx
76
252k
    }
77
272k
}
78
79
static inline void mask_edges_inter(uint16_t (*const masks)[32][3][2],
80
                                    const int by4, const int bx4,
81
                                    const int w4, const int h4, const int skip,
82
                                    const enum RectTxfmSize max_tx,
83
                                    const uint16_t *const tx_masks,
84
                                    uint8_t *const a, uint8_t *const l)
85
175k
{
86
175k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[max_tx];
87
175k
    int y, x;
88
89
175k
    ALIGN_STK_16(uint8_t, txa, 2 /* edge */, [2 /* txsz, step */][32 /* y */][32 /* x */]);
90
359k
    for (int y_off = 0, y = 0; y < h4; y += t_dim->h, y_off++)
91
393k
        for (int x_off = 0, x = 0; x < w4; x += t_dim->w, x_off++)
92
210k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][y][x],
93
210k
                      max_tx, 0, y_off, x_off, tx_masks);
94
95
    // left block edge
96
175k
    unsigned mask = 1U << by4;
97
862k
    for (y = 0; y < h4; y++, mask <<= 1) {
98
687k
        const int sidx = mask >= 0x10000;
99
687k
        const unsigned smask = mask >> (sidx << 4);
100
687k
        masks[0][bx4][imin(txa[0][0][y][0], l[y])][sidx] |= smask;
101
687k
    }
102
103
    // top block edge
104
879k
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
105
704k
        const int sidx = mask >= 0x10000;
106
704k
        const unsigned smask = mask >> (sidx << 4);
107
704k
        masks[1][by4][imin(txa[1][0][0][x], a[x])][sidx] |= smask;
108
704k
    }
109
110
175k
    if (!skip) {
111
        // inner (tx) left|right edges
112
531k
        for (y = 0, mask = 1U << by4; y < h4; y++, mask <<= 1) {
113
415k
            const int sidx = mask >= 0x10000U;
114
415k
            const unsigned smask = mask >> (sidx << 4);
115
415k
            int ltx = txa[0][0][y][0];
116
415k
            int step = txa[0][1][y][0];
117
530k
            for (x = step; x < w4; x += step) {
118
115k
                const int rtx = txa[0][0][y][x];
119
115k
                masks[0][bx4 + x][imin(rtx, ltx)][sidx] |= smask;
120
115k
                ltx = rtx;
121
115k
                step = txa[0][1][y][x];
122
115k
            }
123
415k
        }
124
125
        //            top
126
        // inner (tx) --- edges
127
        //           bottom
128
565k
        for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
129
450k
            const int sidx = mask >= 0x10000U;
130
450k
            const unsigned smask = mask >> (sidx << 4);
131
450k
            int ttx = txa[1][0][0][x];
132
450k
            int step = txa[1][1][0][x];
133
554k
            for (y = step; y < h4; y += step) {
134
103k
                const int btx = txa[1][0][y][x];
135
103k
                masks[1][by4 + y][imin(ttx, btx)][sidx] |= smask;
136
103k
                ttx = btx;
137
103k
                step = txa[1][1][y][x];
138
103k
            }
139
450k
        }
140
115k
    }
141
142
862k
    for (y = 0; y < h4; y++)
143
687k
        l[y] = txa[0][0][y][w4 - 1];
144
175k
    memcpy(a, txa[1][0][h4 - 1], w4);
145
175k
}
146
147
static inline void mask_edges_intra(uint16_t (*const masks)[32][3][2],
148
                                    const int by4, const int bx4,
149
                                    const int w4, const int h4,
150
                                    const enum RectTxfmSize tx,
151
                                    uint8_t *const a, uint8_t *const l)
152
1.61M
{
153
1.61M
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
154
1.61M
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
155
1.61M
    const int twl4c = imin(2, twl4), thl4c = imin(2, thl4);
156
1.61M
    int y, x;
157
158
    // left block edge
159
1.61M
    unsigned mask = 1U << by4;
160
9.70M
    for (y = 0; y < h4; y++, mask <<= 1) {
161
8.09M
        const int sidx = mask >= 0x10000;
162
8.09M
        const unsigned smask = mask >> (sidx << 4);
163
8.09M
        masks[0][bx4][imin(twl4c, l[y])][sidx] |= smask;
164
8.09M
    }
165
166
    // top block edge
167
8.50M
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
168
6.89M
        const int sidx = mask >= 0x10000;
169
6.89M
        const unsigned smask = mask >> (sidx << 4);
170
6.89M
        masks[1][by4][imin(thl4c, a[x])][sidx] |= smask;
171
6.89M
    }
172
173
    // inner (tx) left|right edges
174
1.61M
    const int hstep = t_dim->w;
175
1.61M
    unsigned t = 1U << by4;
176
1.61M
    unsigned inner = (unsigned) ((((uint64_t) t) << h4) - t);
177
1.61M
    unsigned inner1 = inner & 0xffff, inner2 = inner >> 16;
178
1.99M
    for (x = hstep; x < w4; x += hstep) {
179
386k
        if (inner1) masks[0][bx4 + x][twl4c][0] |= inner1;
180
386k
        if (inner2) masks[0][bx4 + x][twl4c][1] |= inner2;
181
386k
    }
182
183
    //            top
184
    // inner (tx) --- edges
185
    //           bottom
186
1.61M
    const int vstep = t_dim->h;
187
1.61M
    t = 1U << bx4;
188
1.61M
    inner = (unsigned) ((((uint64_t) t) << w4) - t);
189
1.61M
    inner1 = inner & 0xffff;
190
1.61M
    inner2 = inner >> 16;
191
2.07M
    for (y = vstep; y < h4; y += vstep) {
192
461k
        if (inner1) masks[1][by4 + y][thl4c][0] |= inner1;
193
461k
        if (inner2) masks[1][by4 + y][thl4c][1] |= inner2;
194
461k
    }
195
196
1.61M
    dav1d_memset_likely_pow2(a, thl4c, w4);
197
1.61M
    dav1d_memset_likely_pow2(l, twl4c, h4);
198
1.61M
}
199
200
static void mask_edges_chroma(uint16_t (*const masks)[32][2][2],
201
                              const int cby4, const int cbx4,
202
                              const int cw4, const int ch4,
203
                              const int skip_inter,
204
                              const enum RectTxfmSize tx,
205
                              uint8_t *const a, uint8_t *const l,
206
                              const int ss_hor, const int ss_ver)
207
1.00M
{
208
1.00M
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
209
1.00M
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
210
1.00M
    const int twl4c = !!twl4, thl4c = !!thl4;
211
1.00M
    int y, x;
212
1.00M
    const int vbits = 4 - ss_ver, hbits = 4 - ss_hor;
213
1.00M
    const int vmask = 16 >> ss_ver, hmask = 16 >> ss_hor;
214
1.00M
    const unsigned vmax = 1 << vmask, hmax = 1 << hmask;
215
216
    // left block edge
217
1.00M
    unsigned mask = 1U << cby4;
218
4.03M
    for (y = 0; y < ch4; y++, mask <<= 1) {
219
3.02M
        const int sidx = mask >= vmax;
220
3.02M
        const unsigned smask = mask >> (sidx << vbits);
221
3.02M
        masks[0][cbx4][imin(twl4c, l[y])][sidx] |= smask;
222
3.02M
    }
223
224
    // top block edge
225
3.79M
    for (x = 0, mask = 1U << cbx4; x < cw4; x++, mask <<= 1) {
226
2.78M
        const int sidx = mask >= hmax;
227
2.78M
        const unsigned smask = mask >> (sidx << hbits);
228
2.78M
        masks[1][cby4][imin(thl4c, a[x])][sidx] |= smask;
229
2.78M
    }
230
231
1.00M
    if (!skip_inter) {
232
        // inner (tx) left|right edges
233
999k
        const int hstep = t_dim->w;
234
999k
        unsigned t = 1U << cby4;
235
999k
        unsigned inner = (unsigned) ((((uint64_t) t) << ch4) - t);
236
999k
        unsigned inner1 = inner & ((1 << vmask) - 1), inner2 = inner >> vmask;
237
1.07M
        for (x = hstep; x < cw4; x += hstep) {
238
72.5k
            if (inner1) masks[0][cbx4 + x][twl4c][0] |= inner1;
239
72.5k
            if (inner2) masks[0][cbx4 + x][twl4c][1] |= inner2;
240
72.5k
        }
241
242
        //            top
243
        // inner (tx) --- edges
244
        //           bottom
245
999k
        const int vstep = t_dim->h;
246
999k
        t = 1U << cbx4;
247
999k
        inner = (unsigned) ((((uint64_t) t) << cw4) - t);
248
999k
        inner1 = inner & ((1 << hmask) - 1), inner2 = inner >> hmask;
249
1.08M
        for (y = vstep; y < ch4; y += vstep) {
250
81.5k
            if (inner1) masks[1][cby4 + y][thl4c][0] |= inner1;
251
81.5k
            if (inner2) masks[1][cby4 + y][thl4c][1] |= inner2;
252
81.5k
        }
253
999k
    }
254
255
1.00M
    dav1d_memset_likely_pow2(a, thl4c, cw4);
256
1.00M
    dav1d_memset_likely_pow2(l, twl4c, ch4);
257
1.00M
}
258
259
static void fill_levelcache_block(uint8_t (*level_cache_ptr)[4],
260
                                  const ptrdiff_t b_stride,
261
                                  const int bw, const int bh,
262
                                  const unsigned v0,
263
                                  const unsigned v1)
264
2.79M
{
265
2.79M
    union alias16 v = (union alias16) { .u8 = { v0, v1 }};
266
267
14.5M
    for (int y = 0; y < bh; y++) {
268
94.4M
        for (int x = 0; x < bw; x++)
269
82.6M
            ((union alias16 *) &level_cache_ptr[x][0])->u16 = v.u16;
270
11.7M
        level_cache_ptr += b_stride;
271
11.7M
    }
272
2.79M
}
273
274
void dav1d_create_lf_mask_intra(Av1Filter *const lflvl,
275
                                uint8_t (*const level_cache)[4],
276
                                const ptrdiff_t b4_stride,
277
                                const uint8_t (*filter_level)[8][2],
278
                                const int bx, const int by,
279
                                const int iw, const int ih,
280
                                const enum BlockSize bs,
281
                                const enum RectTxfmSize ytx,
282
                                const enum RectTxfmSize uvtx,
283
                                const enum Dav1dPixelLayout layout,
284
                                uint8_t *const ay, uint8_t *const ly,
285
                                uint8_t *const auv, uint8_t *const luv)
286
1.65M
{
287
1.65M
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
288
1.65M
    const int bw4 = imin(iw - bx, b_dim[0]);
289
1.65M
    const int bh4 = imin(ih - by, b_dim[1]);
290
1.65M
    const int bx4 = bx & 31;
291
1.65M
    const int by4 = by & 31;
292
1.65M
    assert(bw4 >= 0 && bh4 >= 0);
293
294
1.65M
    if (bw4 && bh4) {
295
1.61M
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
296
297
1.61M
        fill_levelcache_block(level_cache_ptr, b4_stride, bw4, bh4,
298
1.61M
                              filter_level[0][0][0], filter_level[1][0][0]);
299
1.61M
        mask_edges_intra(lflvl->filter_y, by4, bx4, bw4, bh4, ytx, ay, ly);
300
1.61M
    }
301
302
1.65M
    if (!auv) return;
303
304
978k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
305
978k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
306
978k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
307
978k
                          (b_dim[0] + ss_hor) >> ss_hor);
308
978k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
309
978k
                          (b_dim[1] + ss_ver) >> ss_ver);
310
978k
    assert(cbw4 >= 0 && cbh4 >= 0);
311
312
978k
    if (!cbw4 || !cbh4) return;
313
314
970k
    const int cbx4 = bx4 >> ss_hor;
315
970k
    const int cby4 = by4 >> ss_ver;
316
317
970k
    uint8_t (*level_cache_ptr)[4] =
318
970k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
319
320
970k
    fill_levelcache_block((uint8_t(*)[4]) &level_cache_ptr[0][2], b4_stride,
321
970k
                          cbw4, cbh4, filter_level[2][0][0],
322
970k
                          filter_level[3][0][0]);
323
970k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, 0, uvtx,
324
970k
                      auv, luv, ss_hor, ss_ver);
325
970k
}
326
327
void dav1d_create_lf_mask_inter(Av1Filter *const lflvl,
328
                                uint8_t (*const level_cache)[4],
329
                                const ptrdiff_t b4_stride,
330
                                const uint8_t (*filter_level)[8][2],
331
                                const int bx, const int by,
332
                                const int iw, const int ih,
333
                                const int skip, const enum BlockSize bs,
334
                                const enum RectTxfmSize max_ytx,
335
                                const uint16_t *const tx_masks,
336
                                const enum RectTxfmSize uvtx,
337
                                const enum Dav1dPixelLayout layout,
338
                                uint8_t *const ay, uint8_t *const ly,
339
                                uint8_t *const auv, uint8_t *const luv)
340
185k
{
341
185k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
342
185k
    const int bw4 = imin(iw - bx, b_dim[0]);
343
185k
    const int bh4 = imin(ih - by, b_dim[1]);
344
185k
    const int bx4 = bx & 31;
345
185k
    const int by4 = by & 31;
346
185k
    assert(bw4 >= 0 && bh4 >= 0);
347
348
185k
    if (bw4 && bh4) {
349
175k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
350
351
175k
        fill_levelcache_block(level_cache_ptr, b4_stride, bw4, bh4,
352
175k
                              filter_level[0][0][0], filter_level[1][0][0]);
353
175k
        mask_edges_inter(lflvl->filter_y, by4, bx4, bw4, bh4, skip,
354
175k
                         max_ytx, tx_masks, ay, ly);
355
175k
    }
356
357
185k
    if (!auv) return;
358
359
40.4k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
360
40.4k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
361
40.4k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
362
40.4k
                          (b_dim[0] + ss_hor) >> ss_hor);
363
40.4k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
364
40.4k
                          (b_dim[1] + ss_ver) >> ss_ver);
365
40.4k
    assert(cbw4 >= 0 && cbh4 >= 0);
366
367
40.4k
    if (!cbw4 || !cbh4) return;
368
369
38.4k
    const int cbx4 = bx4 >> ss_hor;
370
38.4k
    const int cby4 = by4 >> ss_ver;
371
372
38.4k
    uint8_t (*level_cache_ptr)[4] =
373
38.4k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
374
375
38.4k
    fill_levelcache_block((uint8_t(*)[4]) &level_cache_ptr[0][2], b4_stride,
376
38.4k
                          cbw4, cbh4, filter_level[2][0][0],
377
38.4k
                          filter_level[3][0][0]);
378
38.4k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, skip, uvtx,
379
38.4k
                      auv, luv, ss_hor, ss_ver);
380
38.4k
}
381
382
26.6k
void dav1d_calc_eih(Av1FilterLUT *const lim_lut, const int filter_sharpness) {
383
    // set E/I/H values from loopfilter level
384
26.6k
    const int sharp = filter_sharpness;
385
1.73M
    for (int level = 0; level < 64; level++) {
386
1.70M
        int limit = level;
387
388
1.70M
        if (sharp > 0) {
389
1.03M
            limit >>= (sharp + 3) >> 2;
390
1.03M
            limit = imin(limit, 9 - sharp);
391
1.03M
        }
392
1.70M
        limit = imax(limit, 1);
393
394
1.70M
        lim_lut->i[level] = limit;
395
1.70M
        lim_lut->e[level] = 2 * (level + 2) + limit;
396
1.70M
    }
397
26.6k
    lim_lut->sharp[0] = (sharp + 3) >> 2;
398
26.6k
    lim_lut->sharp[1] = sharp ? 9 - sharp : 0xff;
399
26.6k
}
400
401
static void calc_lf_value(uint8_t (*const lflvl_values)[2],
402
                          const int base_lvl, const int lf_delta,
403
                          const int seg_delta,
404
                          const Dav1dLoopfilterModeRefDeltas *const mr_delta)
405
483k
{
406
483k
    const int base = iclip(iclip(base_lvl + lf_delta, 0, 63) + seg_delta, 0, 63);
407
408
483k
    if (!mr_delta) {
409
237k
        memset(lflvl_values, base, sizeof(*lflvl_values) * 8);
410
245k
    } else {
411
245k
        const int sh = base >= 32;
412
245k
        lflvl_values[0][0] = lflvl_values[0][1] =
413
245k
            iclip(base + (mr_delta->ref_delta[0] * (1 << sh)), 0, 63);
414
1.96M
        for (int r = 1; r < 8; r++) {
415
5.15M
            for (int m = 0; m < 2; m++) {
416
3.43M
                const int delta =
417
3.43M
                    mr_delta->mode_delta[m] + mr_delta->ref_delta[r];
418
3.43M
                lflvl_values[r][m] = iclip(base + (delta * (1 << sh)), 0, 63);
419
3.43M
            }
420
1.71M
        }
421
245k
    }
422
483k
}
423
424
static inline void calc_lf_value_chroma(uint8_t (*const lflvl_values)[2],
425
                                        const int base_lvl, const int lf_delta,
426
                                        const int seg_delta,
427
                                        const Dav1dLoopfilterModeRefDeltas *const mr_delta)
428
295k
{
429
295k
    if (!base_lvl)
430
107k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * 8);
431
187k
    else
432
187k
        calc_lf_value(lflvl_values, base_lvl, lf_delta, seg_delta, mr_delta);
433
295k
}
434
435
void dav1d_calc_lf_values(uint8_t (*const lflvl_values)[4][8][2],
436
                          const Dav1dFrameHeader *const hdr,
437
                          const int8_t lf_delta[4])
438
39.0k
{
439
39.0k
    const int n_seg = hdr->segmentation.enabled ? 8 : 1;
440
441
39.0k
    if (!hdr->loopfilter.level_y[0] && !hdr->loopfilter.level_y[1]) {
442
7.49k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * n_seg);
443
7.49k
        return;
444
7.49k
    }
445
446
31.5k
    const Dav1dLoopfilterModeRefDeltas *const mr_deltas =
447
31.5k
        hdr->loopfilter.mode_ref_delta_enabled ?
448
31.5k
        &hdr->loopfilter.mode_ref_deltas : NULL;
449
179k
    for (int s = 0; s < n_seg; s++) {
450
147k
        const Dav1dSegmentationData *const segd =
451
147k
            hdr->segmentation.enabled ? &hdr->segmentation.seg_data.d[s] : NULL;
452
453
147k
        calc_lf_value(lflvl_values[s][0], hdr->loopfilter.level_y[0],
454
147k
                      lf_delta[0], segd ? segd->delta_lf_y_v : 0, mr_deltas);
455
147k
        calc_lf_value(lflvl_values[s][1], hdr->loopfilter.level_y[1],
456
147k
                      lf_delta[hdr->delta.lf.multi ? 1 : 0],
457
147k
                      segd ? segd->delta_lf_y_h : 0, mr_deltas);
458
147k
        calc_lf_value_chroma(lflvl_values[s][2], hdr->loopfilter.level_u,
459
147k
                             lf_delta[hdr->delta.lf.multi ? 2 : 0],
460
147k
                             segd ? segd->delta_lf_u : 0, mr_deltas);
461
147k
        calc_lf_value_chroma(lflvl_values[s][3], hdr->loopfilter.level_v,
462
147k
                             lf_delta[hdr->delta.lf.multi ? 3 : 0],
463
147k
                             segd ? segd->delta_lf_v : 0, mr_deltas);
464
147k
    }
465
31.5k
}