Coverage Report

Created: 2026-08-13 07:23

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
463k
{
45
463k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
46
463k
    const int is_split = (from == (int) TX_4X4 || depth > 1) ? 0 :
47
463k
        (tx_masks[depth] >> (y_off * 4 + x_off)) & 1;
48
49
463k
    if (is_split) {
50
10.5k
        const enum RectTxfmSize sub = t_dim->sub;
51
10.5k
        const int htw4 = t_dim->w >> 1, hth4 = t_dim->h >> 1;
52
53
10.5k
        decomp_tx(txa, sub, depth + 1, y_off * 2 + 0, x_off * 2 + 0, tx_masks);
54
10.5k
        if (t_dim->w >= t_dim->h)
55
7.48k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][0][htw4],
56
7.48k
                      sub, depth + 1, y_off * 2 + 0, x_off * 2 + 1, tx_masks);
57
10.5k
        if (t_dim->h >= t_dim->w) {
58
9.30k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][0],
59
9.30k
                      sub, depth + 1, y_off * 2 + 1, x_off * 2 + 0, tx_masks);
60
9.30k
            if (t_dim->w >= t_dim->h)
61
6.28k
                decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][htw4],
62
6.28k
                          sub, depth + 1, y_off * 2 + 1, x_off * 2 + 1, tx_masks);
63
9.30k
        }
64
452k
    } else {
65
452k
        const int lw = imin(2, t_dim->lw), lh = imin(2, t_dim->lh);
66
67
452k
#define set_ctx(rep_macro) \
68
1.65M
        for (int y = 0; y < t_dim->h; y++) { \
69
1.20M
            rep_macro(txa[0][0][y], 0, lw); \
70
1.20M
            rep_macro(txa[1][0][y], 0, lh); \
71
1.20M
            txa[0][1][y][0] = t_dim->w; \
72
1.20M
        }
73
452k
        case_set_upto16(t_dim->lw);
74
452k
#undef set_ctx
75
452k
        dav1d_memset_pow2[t_dim->lw](txa[1][1][0], t_dim->h);
76
452k
    }
77
463k
}
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
408k
    for (int y_off = 0, y = 0; y < h4; y += t_dim->h, y_off++)
91
662k
        for (int x_off = 0, x = 0; x < w4; x += t_dim->w, x_off++)
92
429k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][y][x],
93
429k
                      max_tx, 0, y_off, x_off, tx_masks);
94
95
    // left block edge
96
175k
    unsigned mask = 1U << by4;
97
932k
    for (y = 0; y < h4; y++, mask <<= 1) {
98
756k
        const int sidx = mask >= 0x10000;
99
756k
        const unsigned smask = mask >> (sidx << 4);
100
756k
        masks[0][bx4][imin(txa[0][0][y][0], l[y])][sidx] |= smask;
101
756k
    }
102
103
    // top block edge
104
752k
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
105
576k
        const int sidx = mask >= 0x10000;
106
576k
        const unsigned smask = mask >> (sidx << 4);
107
576k
        masks[1][by4][imin(txa[1][0][0][x], a[x])][sidx] |= smask;
108
576k
    }
109
110
175k
    if (!skip) {
111
        // inner (tx) left|right edges
112
561k
        for (y = 0, mask = 1U << by4; y < h4; y++, mask <<= 1) {
113
455k
            const int sidx = mask >= 0x10000U;
114
455k
            const unsigned smask = mask >> (sidx << 4);
115
455k
            int ltx = txa[0][0][y][0];
116
455k
            int step = txa[0][1][y][0];
117
629k
            for (x = step; x < w4; x += step) {
118
174k
                const int rtx = txa[0][0][y][x];
119
174k
                masks[0][bx4 + x][imin(rtx, ltx)][sidx] |= smask;
120
174k
                ltx = rtx;
121
174k
                step = txa[0][1][y][x];
122
174k
            }
123
455k
        }
124
125
        //            top
126
        // inner (tx) --- edges
127
        //           bottom
128
404k
        for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
129
298k
            const int sidx = mask >= 0x10000U;
130
298k
            const unsigned smask = mask >> (sidx << 4);
131
298k
            int ttx = txa[1][0][0][x];
132
298k
            int step = txa[1][1][0][x];
133
489k
            for (y = step; y < h4; y += step) {
134
191k
                const int btx = txa[1][0][y][x];
135
191k
                masks[1][by4 + y][imin(ttx, btx)][sidx] |= smask;
136
191k
                ttx = btx;
137
191k
                step = txa[1][1][y][x];
138
191k
            }
139
298k
        }
140
105k
    }
141
142
932k
    for (y = 0; y < h4; y++)
143
756k
        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
632k
{
153
632k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
154
632k
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
155
632k
    const int twl4c = imin(2, twl4), thl4c = imin(2, thl4);
156
632k
    int y, x;
157
158
    // left block edge
159
632k
    unsigned mask = 1U << by4;
160
3.43M
    for (y = 0; y < h4; y++, mask <<= 1) {
161
2.79M
        const int sidx = mask >= 0x10000;
162
2.79M
        const unsigned smask = mask >> (sidx << 4);
163
2.79M
        masks[0][bx4][imin(twl4c, l[y])][sidx] |= smask;
164
2.79M
    }
165
166
    // top block edge
167
3.33M
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
168
2.70M
        const int sidx = mask >= 0x10000;
169
2.70M
        const unsigned smask = mask >> (sidx << 4);
170
2.70M
        masks[1][by4][imin(thl4c, a[x])][sidx] |= smask;
171
2.70M
    }
172
173
    // inner (tx) left|right edges
174
632k
    const int hstep = t_dim->w;
175
632k
    unsigned t = 1U << by4;
176
632k
    unsigned inner = (unsigned) ((((uint64_t) t) << h4) - t);
177
632k
    unsigned inner1 = inner & 0xffff, inner2 = inner >> 16;
178
768k
    for (x = hstep; x < w4; x += hstep) {
179
135k
        if (inner1) masks[0][bx4 + x][twl4c][0] |= inner1;
180
135k
        if (inner2) masks[0][bx4 + x][twl4c][1] |= inner2;
181
135k
    }
182
183
    //            top
184
    // inner (tx) --- edges
185
    //           bottom
186
632k
    const int vstep = t_dim->h;
187
632k
    t = 1U << bx4;
188
632k
    inner = (unsigned) ((((uint64_t) t) << w4) - t);
189
632k
    inner1 = inner & 0xffff;
190
632k
    inner2 = inner >> 16;
191
773k
    for (y = vstep; y < h4; y += vstep) {
192
140k
        if (inner1) masks[1][by4 + y][thl4c][0] |= inner1;
193
140k
        if (inner2) masks[1][by4 + y][thl4c][1] |= inner2;
194
140k
    }
195
196
632k
    dav1d_memset_likely_pow2(a, thl4c, w4);
197
632k
    dav1d_memset_likely_pow2(l, twl4c, h4);
198
632k
}
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
632k
{
208
632k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
209
632k
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
210
632k
    const int twl4c = !!twl4, thl4c = !!thl4;
211
632k
    int y, x;
212
632k
    const int vbits = 4 - ss_ver, hbits = 4 - ss_hor;
213
632k
    const int vmask = 16 >> ss_ver, hmask = 16 >> ss_hor;
214
632k
    const unsigned vmax = 1 << vmask, hmax = 1 << hmask;
215
216
    // left block edge
217
632k
    unsigned mask = 1U << cby4;
218
2.50M
    for (y = 0; y < ch4; y++, mask <<= 1) {
219
1.87M
        const int sidx = mask >= vmax;
220
1.87M
        const unsigned smask = mask >> (sidx << vbits);
221
1.87M
        masks[0][cbx4][imin(twl4c, l[y])][sidx] |= smask;
222
1.87M
    }
223
224
    // top block edge
225
2.40M
    for (x = 0, mask = 1U << cbx4; x < cw4; x++, mask <<= 1) {
226
1.77M
        const int sidx = mask >= hmax;
227
1.77M
        const unsigned smask = mask >> (sidx << hbits);
228
1.77M
        masks[1][cby4][imin(thl4c, a[x])][sidx] |= smask;
229
1.77M
    }
230
231
632k
    if (!skip_inter) {
232
        // inner (tx) left|right edges
233
595k
        const int hstep = t_dim->w;
234
595k
        unsigned t = 1U << cby4;
235
595k
        unsigned inner = (unsigned) ((((uint64_t) t) << ch4) - t);
236
595k
        unsigned inner1 = inner & ((1 << vmask) - 1), inner2 = inner >> vmask;
237
660k
        for (x = hstep; x < cw4; x += hstep) {
238
65.3k
            if (inner1) masks[0][cbx4 + x][twl4c][0] |= inner1;
239
65.3k
            if (inner2) masks[0][cbx4 + x][twl4c][1] |= inner2;
240
65.3k
        }
241
242
        //            top
243
        // inner (tx) --- edges
244
        //           bottom
245
595k
        const int vstep = t_dim->h;
246
595k
        t = 1U << cbx4;
247
595k
        inner = (unsigned) ((((uint64_t) t) << cw4) - t);
248
595k
        inner1 = inner & ((1 << hmask) - 1), inner2 = inner >> hmask;
249
662k
        for (y = vstep; y < ch4; y += vstep) {
250
67.1k
            if (inner1) masks[1][cby4 + y][thl4c][0] |= inner1;
251
67.1k
            if (inner2) masks[1][cby4 + y][thl4c][1] |= inner2;
252
67.1k
        }
253
595k
    }
254
255
632k
    dav1d_memset_likely_pow2(a, thl4c, cw4);
256
632k
    dav1d_memset_likely_pow2(l, twl4c, ch4);
257
632k
}
258
259
void dav1d_create_lf_mask_intra(Av1Filter *const lflvl,
260
                                uint8_t (*const level_cache)[4],
261
                                const ptrdiff_t b4_stride,
262
                                const uint8_t (*filter_level)[8][2],
263
                                const int bx, const int by,
264
                                const int iw, const int ih,
265
                                const enum BlockSize bs,
266
                                const enum RectTxfmSize ytx,
267
                                const enum RectTxfmSize uvtx,
268
                                const enum Dav1dPixelLayout layout,
269
                                uint8_t *const ay, uint8_t *const ly,
270
                                uint8_t *const auv, uint8_t *const luv)
271
638k
{
272
638k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
273
638k
    const int bw4 = imin(iw - bx, b_dim[0]);
274
638k
    const int bh4 = imin(ih - by, b_dim[1]);
275
638k
    const int bx4 = bx & 31;
276
638k
    const int by4 = by & 31;
277
638k
    assert(bw4 >= 0 && bh4 >= 0);
278
279
638k
    if (bw4 && bh4) {
280
632k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
281
3.42M
        for (int y = 0; y < bh4; y++) {
282
25.2M
            for (int x = 0; x < bw4; x++) {
283
22.4M
                level_cache_ptr[x][0] = filter_level[0][0][0];
284
22.4M
                level_cache_ptr[x][1] = filter_level[1][0][0];
285
22.4M
            }
286
2.79M
            level_cache_ptr += b4_stride;
287
2.79M
        }
288
289
632k
        mask_edges_intra(lflvl->filter_y, by4, bx4, bw4, bh4, ytx, ay, ly);
290
632k
    }
291
292
638k
    if (!auv) return;
293
294
514k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
295
514k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
296
514k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
297
514k
                          (b_dim[0] + ss_hor) >> ss_hor);
298
514k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
299
514k
                          (b_dim[1] + ss_ver) >> ss_ver);
300
514k
    assert(cbw4 >= 0 && cbh4 >= 0);
301
302
514k
    if (!cbw4 || !cbh4) return;
303
304
511k
    const int cbx4 = bx4 >> ss_hor;
305
511k
    const int cby4 = by4 >> ss_ver;
306
307
511k
    uint8_t (*level_cache_ptr)[4] =
308
511k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
309
1.90M
    for (int y = 0; y < cbh4; y++) {
310
8.92M
        for (int x = 0; x < cbw4; x++) {
311
7.53M
            level_cache_ptr[x][2] = filter_level[2][0][0];
312
7.53M
            level_cache_ptr[x][3] = filter_level[3][0][0];
313
7.53M
        }
314
1.39M
        level_cache_ptr += b4_stride;
315
1.39M
    }
316
317
511k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, 0, uvtx,
318
511k
                      auv, luv, ss_hor, ss_ver);
319
511k
}
320
321
void dav1d_create_lf_mask_inter(Av1Filter *const lflvl,
322
                                uint8_t (*const level_cache)[4],
323
                                const ptrdiff_t b4_stride,
324
                                const uint8_t (*filter_level)[8][2],
325
                                const int bx, const int by,
326
                                const int iw, const int ih,
327
                                const int skip, const enum BlockSize bs,
328
                                const enum RectTxfmSize max_ytx,
329
                                const uint16_t *const tx_masks,
330
                                const enum RectTxfmSize uvtx,
331
                                const enum Dav1dPixelLayout layout,
332
                                uint8_t *const ay, uint8_t *const ly,
333
                                uint8_t *const auv, uint8_t *const luv)
334
190k
{
335
190k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
336
190k
    const int bw4 = imin(iw - bx, b_dim[0]);
337
190k
    const int bh4 = imin(ih - by, b_dim[1]);
338
190k
    const int bx4 = bx & 31;
339
190k
    const int by4 = by & 31;
340
190k
    assert(bw4 >= 0 && bh4 >= 0);
341
342
190k
    if (bw4 && bh4) {
343
175k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
344
932k
        for (int y = 0; y < bh4; y++) {
345
4.83M
            for (int x = 0; x < bw4; x++) {
346
4.08M
                level_cache_ptr[x][0] = filter_level[0][0][0];
347
4.08M
                level_cache_ptr[x][1] = filter_level[1][0][0];
348
4.08M
            }
349
756k
            level_cache_ptr += b4_stride;
350
756k
        }
351
352
175k
        mask_edges_inter(lflvl->filter_y, by4, bx4, bw4, bh4, skip,
353
175k
                         max_ytx, tx_masks, ay, ly);
354
175k
    }
355
356
190k
    if (!auv) return;
357
358
129k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
359
129k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
360
129k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
361
129k
                          (b_dim[0] + ss_hor) >> ss_hor);
362
129k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
363
129k
                          (b_dim[1] + ss_ver) >> ss_ver);
364
129k
    assert(cbw4 >= 0 && cbh4 >= 0);
365
366
129k
    if (!cbw4 || !cbh4) return;
367
368
121k
    const int cbx4 = bx4 >> ss_hor;
369
121k
    const int cby4 = by4 >> ss_ver;
370
371
121k
    uint8_t (*level_cache_ptr)[4] =
372
121k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
373
601k
    for (int y = 0; y < cbh4; y++) {
374
3.50M
        for (int x = 0; x < cbw4; x++) {
375
3.02M
            level_cache_ptr[x][2] = filter_level[2][0][0];
376
3.02M
            level_cache_ptr[x][3] = filter_level[3][0][0];
377
3.02M
        }
378
480k
        level_cache_ptr += b4_stride;
379
480k
    }
380
381
121k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, skip, uvtx,
382
121k
                      auv, luv, ss_hor, ss_ver);
383
121k
}
384
385
21.8k
void dav1d_calc_eih(Av1FilterLUT *const lim_lut, const int filter_sharpness) {
386
    // set E/I/H values from loopfilter level
387
21.8k
    const int sharp = filter_sharpness;
388
1.42M
    for (int level = 0; level < 64; level++) {
389
1.39M
        int limit = level;
390
391
1.39M
        if (sharp > 0) {
392
1.24M
            limit >>= (sharp + 3) >> 2;
393
1.24M
            limit = imin(limit, 9 - sharp);
394
1.24M
        }
395
1.39M
        limit = imax(limit, 1);
396
397
1.39M
        lim_lut->i[level] = limit;
398
1.39M
        lim_lut->e[level] = 2 * (level + 2) + limit;
399
1.39M
    }
400
21.8k
    lim_lut->sharp[0] = (sharp + 3) >> 2;
401
21.8k
    lim_lut->sharp[1] = sharp ? 9 - sharp : 0xff;
402
21.8k
}
403
404
static void calc_lf_value(uint8_t (*const lflvl_values)[2],
405
                          const int base_lvl, const int lf_delta,
406
                          const int seg_delta,
407
                          const Dav1dLoopfilterModeRefDeltas *const mr_delta)
408
744k
{
409
744k
    const int base = iclip(iclip(base_lvl + lf_delta, 0, 63) + seg_delta, 0, 63);
410
411
744k
    if (!mr_delta) {
412
711k
        memset(lflvl_values, base, sizeof(*lflvl_values) * 8);
413
711k
    } else {
414
32.5k
        const int sh = base >= 32;
415
32.5k
        lflvl_values[0][0] = lflvl_values[0][1] =
416
32.5k
            iclip(base + (mr_delta->ref_delta[0] * (1 << sh)), 0, 63);
417
260k
        for (int r = 1; r < 8; r++) {
418
683k
            for (int m = 0; m < 2; m++) {
419
455k
                const int delta =
420
455k
                    mr_delta->mode_delta[m] + mr_delta->ref_delta[r];
421
455k
                lflvl_values[r][m] = iclip(base + (delta * (1 << sh)), 0, 63);
422
455k
            }
423
227k
        }
424
32.5k
    }
425
744k
}
426
427
static inline void calc_lf_value_chroma(uint8_t (*const lflvl_values)[2],
428
                                        const int base_lvl, const int lf_delta,
429
                                        const int seg_delta,
430
                                        const Dav1dLoopfilterModeRefDeltas *const mr_delta)
431
402k
{
432
402k
    if (!base_lvl)
433
60.6k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * 8);
434
341k
    else
435
341k
        calc_lf_value(lflvl_values, base_lvl, lf_delta, seg_delta, mr_delta);
436
402k
}
437
438
void dav1d_calc_lf_values(uint8_t (*const lflvl_values)[4][8][2],
439
                          const Dav1dFrameHeader *const hdr,
440
                          const int8_t lf_delta[4])
441
72.5k
{
442
72.5k
    const int n_seg = hdr->segmentation.enabled ? 8 : 1;
443
444
72.5k
    if (!hdr->loopfilter.level_y[0] && !hdr->loopfilter.level_y[1]) {
445
1.32k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * n_seg);
446
1.32k
        return;
447
1.32k
    }
448
449
71.1k
    const Dav1dLoopfilterModeRefDeltas *const mr_deltas =
450
71.1k
        hdr->loopfilter.mode_ref_delta_enabled ?
451
71.1k
        &hdr->loopfilter.mode_ref_deltas : NULL;
452
272k
    for (int s = 0; s < n_seg; s++) {
453
201k
        const Dav1dSegmentationData *const segd =
454
201k
            hdr->segmentation.enabled ? &hdr->segmentation.seg_data.d[s] : NULL;
455
456
201k
        calc_lf_value(lflvl_values[s][0], hdr->loopfilter.level_y[0],
457
201k
                      lf_delta[0], segd ? segd->delta_lf_y_v : 0, mr_deltas);
458
201k
        calc_lf_value(lflvl_values[s][1], hdr->loopfilter.level_y[1],
459
201k
                      lf_delta[hdr->delta.lf.multi ? 1 : 0],
460
201k
                      segd ? segd->delta_lf_y_h : 0, mr_deltas);
461
201k
        calc_lf_value_chroma(lflvl_values[s][2], hdr->loopfilter.level_u,
462
201k
                             lf_delta[hdr->delta.lf.multi ? 2 : 0],
463
201k
                             segd ? segd->delta_lf_u : 0, mr_deltas);
464
201k
        calc_lf_value_chroma(lflvl_values[s][3], hdr->loopfilter.level_v,
465
201k
                             lf_delta[hdr->delta.lf.multi ? 3 : 0],
466
201k
                             segd ? segd->delta_lf_v : 0, mr_deltas);
467
201k
    }
468
71.1k
}