Coverage Report

Created: 2026-10-28 06:15

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
309k
{
45
309k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
46
309k
    const int is_split = (from == (int) TX_4X4 || depth > 1) ? 0 :
47
309k
        (tx_masks[depth] >> (y_off * 4 + x_off)) & 1;
48
49
309k
    if (is_split) {
50
32.3k
        const enum RectTxfmSize sub = t_dim->sub;
51
32.3k
        const int htw4 = t_dim->w >> 1, hth4 = t_dim->h >> 1;
52
53
32.3k
        decomp_tx(txa, sub, depth + 1, y_off * 2 + 0, x_off * 2 + 0, tx_masks);
54
32.3k
        if (t_dim->w >= t_dim->h)
55
25.0k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][0][htw4],
56
25.0k
                      sub, depth + 1, y_off * 2 + 0, x_off * 2 + 1, tx_masks);
57
32.3k
        if (t_dim->h >= t_dim->w) {
58
22.7k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][0],
59
22.7k
                      sub, depth + 1, y_off * 2 + 1, x_off * 2 + 0, tx_masks);
60
22.7k
            if (t_dim->w >= t_dim->h)
61
15.4k
                decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][htw4],
62
15.4k
                          sub, depth + 1, y_off * 2 + 1, x_off * 2 + 1, tx_masks);
63
22.7k
        }
64
277k
    } else {
65
277k
        const int lw = imin(2, t_dim->lw), lh = imin(2, t_dim->lh);
66
67
277k
#define set_ctx(rep_macro) \
68
1.05M
        for (int y = 0; y < t_dim->h; y++) { \
69
778k
            rep_macro(txa[0][0][y], 0, lw); \
70
778k
            rep_macro(txa[1][0][y], 0, lh); \
71
778k
            txa[0][1][y][0] = t_dim->w; \
72
778k
        } \
73
277k
        rep_macro(txa[1][1][0], 0, t_dim->h);
74
277k
        case_set_upto16(t_dim->lw);
75
277k
#undef set_ctx
76
277k
    }
77
309k
}
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
200k
{
86
200k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[max_tx];
87
200k
    int y, x;
88
89
200k
    ALIGN_STK_16(uint8_t, txa, 2 /* edge */, [2 /* txsz, step */][32 /* y */][32 /* x */]);
90
403k
    for (int y_off = 0, y = 0; y < h4; y += t_dim->h, y_off++)
91
417k
        for (int x_off = 0, x = 0; x < w4; x += t_dim->w, x_off++)
92
214k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][y][x],
93
214k
                      max_tx, 0, y_off, x_off, tx_masks);
94
95
    // left block edge
96
200k
    unsigned mask = 1U << by4;
97
864k
    for (y = 0; y < h4; y++, mask <<= 1) {
98
663k
        const int sidx = mask >= 0x10000;
99
663k
        const unsigned smask = mask >> (sidx << 4);
100
663k
        masks[0][bx4][imin(txa[0][0][y][0], l[y])][sidx] |= smask;
101
663k
    }
102
103
    // top block edge
104
841k
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
105
640k
        const int sidx = mask >= 0x10000;
106
640k
        const unsigned smask = mask >> (sidx << 4);
107
640k
        masks[1][by4][imin(txa[1][0][0][x], a[x])][sidx] |= smask;
108
640k
    }
109
110
200k
    if (!skip) {
111
        // inner (tx) left|right edges
112
664k
        for (y = 0, mask = 1U << by4; y < h4; y++, mask <<= 1) {
113
508k
            const int sidx = mask >= 0x10000U;
114
508k
            const unsigned smask = mask >> (sidx << 4);
115
508k
            int ltx = txa[0][0][y][0];
116
508k
            int step = txa[0][1][y][0];
117
587k
            for (x = step; x < w4; x += step) {
118
78.9k
                const int rtx = txa[0][0][y][x];
119
78.9k
                masks[0][bx4 + x][imin(rtx, ltx)][sidx] |= smask;
120
78.9k
                ltx = rtx;
121
78.9k
                step = txa[0][1][y][x];
122
78.9k
            }
123
508k
        }
124
125
        //            top
126
        // inner (tx) --- edges
127
        //           bottom
128
658k
        for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
129
503k
            const int sidx = mask >= 0x10000U;
130
503k
            const unsigned smask = mask >> (sidx << 4);
131
503k
            int ttx = txa[1][0][0][x];
132
503k
            int step = txa[1][1][0][x];
133
577k
            for (y = step; y < h4; y += step) {
134
74.1k
                const int btx = txa[1][0][y][x];
135
74.1k
                masks[1][by4 + y][imin(ttx, btx)][sidx] |= smask;
136
74.1k
                ttx = btx;
137
74.1k
                step = txa[1][1][y][x];
138
74.1k
            }
139
503k
        }
140
155k
    }
141
142
864k
    for (y = 0; y < h4; y++)
143
663k
        l[y] = txa[0][0][y][w4 - 1];
144
200k
    memcpy(a, txa[1][0][h4 - 1], w4);
145
200k
}
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
699k
{
153
699k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
154
699k
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
155
699k
    const int twl4c = imin(2, twl4), thl4c = imin(2, thl4);
156
699k
    int y, x;
157
158
    // left block edge
159
699k
    unsigned mask = 1U << by4;
160
4.68M
    for (y = 0; y < h4; y++, mask <<= 1) {
161
3.98M
        const int sidx = mask >= 0x10000;
162
3.98M
        const unsigned smask = mask >> (sidx << 4);
163
3.98M
        masks[0][bx4][imin(twl4c, l[y])][sidx] |= smask;
164
3.98M
    }
165
166
    // top block edge
167
3.45M
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
168
2.75M
        const int sidx = mask >= 0x10000;
169
2.75M
        const unsigned smask = mask >> (sidx << 4);
170
2.75M
        masks[1][by4][imin(thl4c, a[x])][sidx] |= smask;
171
2.75M
    }
172
173
    // inner (tx) left|right edges
174
699k
    const int hstep = t_dim->w;
175
699k
    unsigned t = 1U << by4;
176
699k
    unsigned inner = (unsigned) ((((uint64_t) t) << h4) - t);
177
699k
    unsigned inner1 = inner & 0xffff, inner2 = inner >> 16;
178
842k
    for (x = hstep; x < w4; x += hstep) {
179
142k
        if (inner1) masks[0][bx4 + x][twl4c][0] |= inner1;
180
142k
        if (inner2) masks[0][bx4 + x][twl4c][1] |= inner2;
181
142k
    }
182
183
    //            top
184
    // inner (tx) --- edges
185
    //           bottom
186
699k
    const int vstep = t_dim->h;
187
699k
    t = 1U << bx4;
188
699k
    inner = (unsigned) ((((uint64_t) t) << w4) - t);
189
699k
    inner1 = inner & 0xffff;
190
699k
    inner2 = inner >> 16;
191
952k
    for (y = vstep; y < h4; y += vstep) {
192
253k
        if (inner1) masks[1][by4 + y][thl4c][0] |= inner1;
193
253k
        if (inner2) masks[1][by4 + y][thl4c][1] |= inner2;
194
253k
    }
195
196
699k
    dav1d_memset_likely_pow2(a, thl4c, w4);
197
699k
    dav1d_memset_likely_pow2(l, twl4c, h4);
198
699k
}
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
690k
{
208
690k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
209
690k
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
210
690k
    const int twl4c = !!twl4, thl4c = !!thl4;
211
690k
    int y, x;
212
690k
    const int vbits = 4 - ss_ver, hbits = 4 - ss_hor;
213
690k
    const int vmask = 16 >> ss_ver, hmask = 16 >> ss_hor;
214
690k
    const unsigned vmax = 1 << vmask, hmax = 1 << hmask;
215
216
    // left block edge
217
690k
    unsigned mask = 1U << cby4;
218
3.06M
    for (y = 0; y < ch4; y++, mask <<= 1) {
219
2.37M
        const int sidx = mask >= vmax;
220
2.37M
        const unsigned smask = mask >> (sidx << vbits);
221
2.37M
        masks[0][cbx4][imin(twl4c, l[y])][sidx] |= smask;
222
2.37M
    }
223
224
    // top block edge
225
2.51M
    for (x = 0, mask = 1U << cbx4; x < cw4; x++, mask <<= 1) {
226
1.82M
        const int sidx = mask >= hmax;
227
1.82M
        const unsigned smask = mask >> (sidx << hbits);
228
1.82M
        masks[1][cby4][imin(thl4c, a[x])][sidx] |= smask;
229
1.82M
    }
230
231
690k
    if (!skip_inter) {
232
        // inner (tx) left|right edges
233
657k
        const int hstep = t_dim->w;
234
657k
        unsigned t = 1U << cby4;
235
657k
        unsigned inner = (unsigned) ((((uint64_t) t) << ch4) - t);
236
657k
        unsigned inner1 = inner & ((1 << vmask) - 1), inner2 = inner >> vmask;
237
679k
        for (x = hstep; x < cw4; x += hstep) {
238
21.7k
            if (inner1) masks[0][cbx4 + x][twl4c][0] |= inner1;
239
21.7k
            if (inner2) masks[0][cbx4 + x][twl4c][1] |= inner2;
240
21.7k
        }
241
242
        //            top
243
        // inner (tx) --- edges
244
        //           bottom
245
657k
        const int vstep = t_dim->h;
246
657k
        t = 1U << cbx4;
247
657k
        inner = (unsigned) ((((uint64_t) t) << cw4) - t);
248
657k
        inner1 = inner & ((1 << hmask) - 1), inner2 = inner >> hmask;
249
700k
        for (y = vstep; y < ch4; y += vstep) {
250
42.6k
            if (inner1) masks[1][cby4 + y][thl4c][0] |= inner1;
251
42.6k
            if (inner2) masks[1][cby4 + y][thl4c][1] |= inner2;
252
42.6k
        }
253
657k
    }
254
255
690k
    dav1d_memset_likely_pow2(a, thl4c, cw4);
256
690k
    dav1d_memset_likely_pow2(l, twl4c, ch4);
257
690k
}
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
1.59M
{
265
1.59M
    union alias16 v = (union alias16) { .u8 = { v0, v1 }};
266
267
8.61M
    for (int y = 0; y < bh; y++) {
268
42.9M
        for (int x = 0; x < bw; x++)
269
35.9M
            ((union alias16 *) &level_cache_ptr[x][0])->u16 = v.u16;
270
7.02M
        level_cache_ptr += b_stride;
271
7.02M
    }
272
1.59M
}
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
766k
{
287
766k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
288
766k
    const int bw4 = imin(iw - bx, b_dim[0]);
289
766k
    const int bh4 = imin(ih - by, b_dim[1]);
290
766k
    const int bx4 = bx & 31;
291
766k
    const int by4 = by & 31;
292
766k
    assert(bw4 >= 0 && bh4 >= 0);
293
294
766k
    if (bw4 && bh4) {
295
699k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
296
297
699k
        fill_levelcache_block(level_cache_ptr, b4_stride, bw4, bh4,
298
699k
                              filter_level[0][0][0], filter_level[1][0][0]);
299
699k
        mask_edges_intra(lflvl->filter_y, by4, bx4, bw4, bh4, ytx, ay, ly);
300
699k
    }
301
302
766k
    if (!auv) return;
303
304
553k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
305
553k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
306
553k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
307
553k
                          (b_dim[0] + ss_hor) >> ss_hor);
308
553k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
309
553k
                          (b_dim[1] + ss_ver) >> ss_ver);
310
553k
    assert(cbw4 >= 0 && cbh4 >= 0);
311
312
553k
    if (!cbw4 || !cbh4) return;
313
314
543k
    const int cbx4 = bx4 >> ss_hor;
315
543k
    const int cby4 = by4 >> ss_ver;
316
317
543k
    uint8_t (*level_cache_ptr)[4] =
318
543k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
319
320
543k
    fill_levelcache_block((uint8_t(*)[4]) &level_cache_ptr[0][2], b4_stride,
321
543k
                          cbw4, cbh4, filter_level[2][0][0],
322
543k
                          filter_level[3][0][0]);
323
543k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, 0, uvtx,
324
543k
                      auv, luv, ss_hor, ss_ver);
325
543k
}
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
206k
{
341
206k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
342
206k
    const int bw4 = imin(iw - bx, b_dim[0]);
343
206k
    const int bh4 = imin(ih - by, b_dim[1]);
344
206k
    const int bx4 = bx & 31;
345
206k
    const int by4 = by & 31;
346
206k
    assert(bw4 >= 0 && bh4 >= 0);
347
348
206k
    if (bw4 && bh4) {
349
200k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
350
351
200k
        fill_levelcache_block(level_cache_ptr, b4_stride, bw4, bh4,
352
200k
                              filter_level[0][0][0], filter_level[1][0][0]);
353
200k
        mask_edges_inter(lflvl->filter_y, by4, bx4, bw4, bh4, skip,
354
200k
                         max_ytx, tx_masks, ay, ly);
355
200k
    }
356
357
206k
    if (!auv) return;
358
359
149k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
360
149k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
361
149k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
362
149k
                          (b_dim[0] + ss_hor) >> ss_hor);
363
149k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
364
149k
                          (b_dim[1] + ss_ver) >> ss_ver);
365
149k
    assert(cbw4 >= 0 && cbh4 >= 0);
366
367
149k
    if (!cbw4 || !cbh4) return;
368
369
147k
    const int cbx4 = bx4 >> ss_hor;
370
147k
    const int cby4 = by4 >> ss_ver;
371
372
147k
    uint8_t (*level_cache_ptr)[4] =
373
147k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
374
375
147k
    fill_levelcache_block((uint8_t(*)[4]) &level_cache_ptr[0][2], b4_stride,
376
147k
                          cbw4, cbh4, filter_level[2][0][0],
377
147k
                          filter_level[3][0][0]);
378
147k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, skip, uvtx,
379
147k
                      auv, luv, ss_hor, ss_ver);
380
147k
}
381
382
35.1k
void dav1d_calc_eih(Av1FilterLUT *const lim_lut, const int filter_sharpness) {
383
    // set E/I/H values from loopfilter level
384
35.1k
    const int sharp = filter_sharpness;
385
2.28M
    for (int level = 0; level < 64; level++) {
386
2.25M
        int limit = level;
387
388
2.25M
        if (sharp > 0) {
389
1.03M
            limit >>= (sharp + 3) >> 2;
390
1.03M
            limit = imin(limit, 9 - sharp);
391
1.03M
        }
392
2.25M
        limit = imax(limit, 1);
393
394
2.25M
        lim_lut->i[level] = limit;
395
2.25M
        lim_lut->e[level] = 2 * (level + 2) + limit;
396
2.25M
    }
397
35.1k
    lim_lut->sharp[0] = (sharp + 3) >> 2;
398
35.1k
    lim_lut->sharp[1] = sharp ? 9 - sharp : 0xff;
399
35.1k
}
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
693k
{
406
693k
    const int base = iclip(iclip(base_lvl + lf_delta, 0, 63) + seg_delta, 0, 63);
407
408
693k
    if (!mr_delta) {
409
244k
        memset(lflvl_values, base, sizeof(*lflvl_values) * 8);
410
448k
    } else {
411
448k
        const int sh = base >= 32;
412
448k
        lflvl_values[0][0] = lflvl_values[0][1] =
413
448k
            iclip(base + (mr_delta->ref_delta[0] * (1 << sh)), 0, 63);
414
3.58M
        for (int r = 1; r < 8; r++) {
415
9.41M
            for (int m = 0; m < 2; m++) {
416
6.27M
                const int delta =
417
6.27M
                    mr_delta->mode_delta[m] + mr_delta->ref_delta[r];
418
6.27M
                lflvl_values[r][m] = iclip(base + (delta * (1 << sh)), 0, 63);
419
6.27M
            }
420
3.13M
        }
421
448k
    }
422
693k
}
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
381k
{
429
381k
    if (!base_lvl)
430
69.4k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * 8);
431
312k
    else
432
312k
        calc_lf_value(lflvl_values, base_lvl, lf_delta, seg_delta, mr_delta);
433
381k
}
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
51.5k
{
439
51.5k
    const int n_seg = hdr->segmentation.enabled ? 8 : 1;
440
441
51.5k
    if (!hdr->loopfilter.level_y[0] && !hdr->loopfilter.level_y[1]) {
442
14.6k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * n_seg);
443
14.6k
        return;
444
14.6k
    }
445
446
36.8k
    const Dav1dLoopfilterModeRefDeltas *const mr_deltas =
447
36.8k
        hdr->loopfilter.mode_ref_delta_enabled ?
448
36.8k
        &hdr->loopfilter.mode_ref_deltas : NULL;
449
227k
    for (int s = 0; s < n_seg; s++) {
450
190k
        const Dav1dSegmentationData *const segd =
451
190k
            hdr->segmentation.enabled ? &hdr->segmentation.seg_data.d[s] : NULL;
452
453
190k
        calc_lf_value(lflvl_values[s][0], hdr->loopfilter.level_y[0],
454
190k
                      lf_delta[0], segd ? segd->delta_lf_y_v : 0, mr_deltas);
455
190k
        calc_lf_value(lflvl_values[s][1], hdr->loopfilter.level_y[1],
456
190k
                      lf_delta[hdr->delta.lf.multi ? 1 : 0],
457
190k
                      segd ? segd->delta_lf_y_h : 0, mr_deltas);
458
190k
        calc_lf_value_chroma(lflvl_values[s][2], hdr->loopfilter.level_u,
459
190k
                             lf_delta[hdr->delta.lf.multi ? 2 : 0],
460
190k
                             segd ? segd->delta_lf_u : 0, mr_deltas);
461
190k
        calc_lf_value_chroma(lflvl_values[s][3], hdr->loopfilter.level_v,
462
190k
                             lf_delta[hdr->delta.lf.multi ? 3 : 0],
463
190k
                             segd ? segd->delta_lf_v : 0, mr_deltas);
464
190k
    }
465
36.8k
}