Coverage Report

Created: 2026-10-17 06:55

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