Coverage Report

Created: 2026-09-14 06:39

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
592k
{
45
592k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
46
592k
    const int is_split = (from == (int) TX_4X4 || depth > 1) ? 0 :
47
592k
        (tx_masks[depth] >> (y_off * 4 + x_off)) & 1;
48
49
592k
    if (is_split) {
50
43.0k
        const enum RectTxfmSize sub = t_dim->sub;
51
43.0k
        const int htw4 = t_dim->w >> 1, hth4 = t_dim->h >> 1;
52
53
43.0k
        decomp_tx(txa, sub, depth + 1, y_off * 2 + 0, x_off * 2 + 0, tx_masks);
54
43.0k
        if (t_dim->w >= t_dim->h)
55
32.4k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][0][htw4],
56
32.4k
                      sub, depth + 1, y_off * 2 + 0, x_off * 2 + 1, tx_masks);
57
43.0k
        if (t_dim->h >= t_dim->w) {
58
32.4k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][0],
59
32.4k
                      sub, depth + 1, y_off * 2 + 1, x_off * 2 + 0, tx_masks);
60
32.4k
            if (t_dim->w >= t_dim->h)
61
21.8k
                decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][hth4][htw4],
62
21.8k
                          sub, depth + 1, y_off * 2 + 1, x_off * 2 + 1, tx_masks);
63
32.4k
        }
64
549k
    } else {
65
549k
        const int lw = imin(2, t_dim->lw), lh = imin(2, t_dim->lh);
66
67
549k
#define set_ctx(rep_macro) \
68
2.95M
        for (int y = 0; y < t_dim->h; y++) { \
69
2.40M
            rep_macro(txa[0][0][y], 0, lw); \
70
2.40M
            rep_macro(txa[1][0][y], 0, lh); \
71
2.40M
            txa[0][1][y][0] = t_dim->w; \
72
2.40M
        }
73
549k
        case_set_upto16(t_dim->lw);
74
549k
#undef set_ctx
75
549k
        dav1d_memset_pow2[t_dim->lw](txa[1][1][0], t_dim->h);
76
549k
    }
77
592k
}
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
439k
{
86
439k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[max_tx];
87
439k
    int y, x;
88
89
439k
    ALIGN_STK_16(uint8_t, txa, 2 /* edge */, [2 /* txsz, step */][32 /* y */][32 /* x */]);
90
887k
    for (int y_off = 0, y = 0; y < h4; y += t_dim->h, y_off++)
91
910k
        for (int x_off = 0, x = 0; x < w4; x += t_dim->w, x_off++)
92
462k
            decomp_tx((uint8_t(*)[2][32][32]) &txa[0][0][y][x],
93
462k
                      max_tx, 0, y_off, x_off, tx_masks);
94
95
    // left block edge
96
439k
    unsigned mask = 1U << by4;
97
2.45M
    for (y = 0; y < h4; y++, mask <<= 1) {
98
2.01M
        const int sidx = mask >= 0x10000;
99
2.01M
        const unsigned smask = mask >> (sidx << 4);
100
2.01M
        masks[0][bx4][imin(txa[0][0][y][0], l[y])][sidx] |= smask;
101
2.01M
    }
102
103
    // top block edge
104
1.67M
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
105
1.23M
        const int sidx = mask >= 0x10000;
106
1.23M
        const unsigned smask = mask >> (sidx << 4);
107
1.23M
        masks[1][by4][imin(txa[1][0][0][x], a[x])][sidx] |= smask;
108
1.23M
    }
109
110
439k
    if (!skip) {
111
        // inner (tx) left|right edges
112
1.15M
        for (y = 0, mask = 1U << by4; y < h4; y++, mask <<= 1) {
113
935k
            const int sidx = mask >= 0x10000U;
114
935k
            const unsigned smask = mask >> (sidx << 4);
115
935k
            int ltx = txa[0][0][y][0];
116
935k
            int step = txa[0][1][y][0];
117
1.03M
            for (x = step; x < w4; x += step) {
118
99.5k
                const int rtx = txa[0][0][y][x];
119
99.5k
                masks[0][bx4 + x][imin(rtx, ltx)][sidx] |= smask;
120
99.5k
                ltx = rtx;
121
99.5k
                step = txa[0][1][y][x];
122
99.5k
            }
123
935k
        }
124
125
        //            top
126
        // inner (tx) --- edges
127
        //           bottom
128
912k
        for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
129
693k
            const int sidx = mask >= 0x10000U;
130
693k
            const unsigned smask = mask >> (sidx << 4);
131
693k
            int ttx = txa[1][0][0][x];
132
693k
            int step = txa[1][1][0][x];
133
788k
            for (y = step; y < h4; y += step) {
134
94.6k
                const int btx = txa[1][0][y][x];
135
94.6k
                masks[1][by4 + y][imin(ttx, btx)][sidx] |= smask;
136
94.6k
                ttx = btx;
137
94.6k
                step = txa[1][1][y][x];
138
94.6k
            }
139
693k
        }
140
219k
    }
141
142
2.45M
    for (y = 0; y < h4; y++)
143
2.01M
        l[y] = txa[0][0][y][w4 - 1];
144
439k
    memcpy(a, txa[1][0][h4 - 1], w4);
145
439k
}
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
412k
{
153
412k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
154
412k
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
155
412k
    const int twl4c = imin(2, twl4), thl4c = imin(2, thl4);
156
412k
    int y, x;
157
158
    // left block edge
159
412k
    unsigned mask = 1U << by4;
160
2.05M
    for (y = 0; y < h4; y++, mask <<= 1) {
161
1.64M
        const int sidx = mask >= 0x10000;
162
1.64M
        const unsigned smask = mask >> (sidx << 4);
163
1.64M
        masks[0][bx4][imin(twl4c, l[y])][sidx] |= smask;
164
1.64M
    }
165
166
    // top block edge
167
1.88M
    for (x = 0, mask = 1U << bx4; x < w4; x++, mask <<= 1) {
168
1.46M
        const int sidx = mask >= 0x10000;
169
1.46M
        const unsigned smask = mask >> (sidx << 4);
170
1.46M
        masks[1][by4][imin(thl4c, a[x])][sidx] |= smask;
171
1.46M
    }
172
173
    // inner (tx) left|right edges
174
412k
    const int hstep = t_dim->w;
175
412k
    unsigned t = 1U << by4;
176
412k
    unsigned inner = (unsigned) ((((uint64_t) t) << h4) - t);
177
412k
    unsigned inner1 = inner & 0xffff, inner2 = inner >> 16;
178
520k
    for (x = hstep; x < w4; x += hstep) {
179
107k
        if (inner1) masks[0][bx4 + x][twl4c][0] |= inner1;
180
107k
        if (inner2) masks[0][bx4 + x][twl4c][1] |= inner2;
181
107k
    }
182
183
    //            top
184
    // inner (tx) --- edges
185
    //           bottom
186
412k
    const int vstep = t_dim->h;
187
412k
    t = 1U << bx4;
188
412k
    inner = (unsigned) ((((uint64_t) t) << w4) - t);
189
412k
    inner1 = inner & 0xffff;
190
412k
    inner2 = inner >> 16;
191
540k
    for (y = vstep; y < h4; y += vstep) {
192
128k
        if (inner1) masks[1][by4 + y][thl4c][0] |= inner1;
193
128k
        if (inner2) masks[1][by4 + y][thl4c][1] |= inner2;
194
128k
    }
195
196
412k
    dav1d_memset_likely_pow2(a, thl4c, w4);
197
412k
    dav1d_memset_likely_pow2(l, twl4c, h4);
198
412k
}
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
621k
{
208
621k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[tx];
209
621k
    const int twl4 = t_dim->lw, thl4 = t_dim->lh;
210
621k
    const int twl4c = !!twl4, thl4c = !!thl4;
211
621k
    int y, x;
212
621k
    const int vbits = 4 - ss_ver, hbits = 4 - ss_hor;
213
621k
    const int vmask = 16 >> ss_ver, hmask = 16 >> ss_hor;
214
621k
    const unsigned vmax = 1 << vmask, hmax = 1 << hmask;
215
216
    // left block edge
217
621k
    unsigned mask = 1U << cby4;
218
2.77M
    for (y = 0; y < ch4; y++, mask <<= 1) {
219
2.15M
        const int sidx = mask >= vmax;
220
2.15M
        const unsigned smask = mask >> (sidx << vbits);
221
2.15M
        masks[0][cbx4][imin(twl4c, l[y])][sidx] |= smask;
222
2.15M
    }
223
224
    // top block edge
225
2.38M
    for (x = 0, mask = 1U << cbx4; x < cw4; x++, mask <<= 1) {
226
1.76M
        const int sidx = mask >= hmax;
227
1.76M
        const unsigned smask = mask >> (sidx << hbits);
228
1.76M
        masks[1][cby4][imin(thl4c, a[x])][sidx] |= smask;
229
1.76M
    }
230
231
621k
    if (!skip_inter) {
232
        // inner (tx) left|right edges
233
492k
        const int hstep = t_dim->w;
234
492k
        unsigned t = 1U << cby4;
235
492k
        unsigned inner = (unsigned) ((((uint64_t) t) << ch4) - t);
236
492k
        unsigned inner1 = inner & ((1 << vmask) - 1), inner2 = inner >> vmask;
237
554k
        for (x = hstep; x < cw4; x += hstep) {
238
62.3k
            if (inner1) masks[0][cbx4 + x][twl4c][0] |= inner1;
239
62.3k
            if (inner2) masks[0][cbx4 + x][twl4c][1] |= inner2;
240
62.3k
        }
241
242
        //            top
243
        // inner (tx) --- edges
244
        //           bottom
245
492k
        const int vstep = t_dim->h;
246
492k
        t = 1U << cbx4;
247
492k
        inner = (unsigned) ((((uint64_t) t) << cw4) - t);
248
492k
        inner1 = inner & ((1 << hmask) - 1), inner2 = inner >> hmask;
249
559k
        for (y = vstep; y < ch4; y += vstep) {
250
66.8k
            if (inner1) masks[1][cby4 + y][thl4c][0] |= inner1;
251
66.8k
            if (inner2) masks[1][cby4 + y][thl4c][1] |= inner2;
252
66.8k
        }
253
492k
    }
254
255
621k
    dav1d_memset_likely_pow2(a, thl4c, cw4);
256
621k
    dav1d_memset_likely_pow2(l, twl4c, ch4);
257
621k
}
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
499k
{
272
499k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
273
499k
    const int bw4 = imin(iw - bx, b_dim[0]);
274
499k
    const int bh4 = imin(ih - by, b_dim[1]);
275
499k
    const int bx4 = bx & 31;
276
499k
    const int by4 = by & 31;
277
499k
    assert(bw4 >= 0 && bh4 >= 0);
278
279
499k
    if (bw4 && bh4) {
280
412k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
281
2.05M
        for (int y = 0; y < bh4; y++) {
282
9.79M
            for (int x = 0; x < bw4; x++) {
283
8.14M
                level_cache_ptr[x][0] = filter_level[0][0][0];
284
8.14M
                level_cache_ptr[x][1] = filter_level[1][0][0];
285
8.14M
            }
286
1.64M
            level_cache_ptr += b4_stride;
287
1.64M
        }
288
289
412k
        mask_edges_intra(lflvl->filter_y, by4, bx4, bw4, bh4, ytx, ay, ly);
290
412k
    }
291
292
499k
    if (!auv) return;
293
294
384k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
295
384k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
296
384k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
297
384k
                          (b_dim[0] + ss_hor) >> ss_hor);
298
384k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
299
384k
                          (b_dim[1] + ss_ver) >> ss_ver);
300
384k
    assert(cbw4 >= 0 && cbh4 >= 0);
301
302
384k
    if (!cbw4 || !cbh4) return;
303
304
332k
    const int cbx4 = bx4 >> ss_hor;
305
332k
    const int cby4 = by4 >> ss_ver;
306
307
332k
    uint8_t (*level_cache_ptr)[4] =
308
332k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
309
1.57M
    for (int y = 0; y < cbh4; y++) {
310
7.11M
        for (int x = 0; x < cbw4; x++) {
311
5.88M
            level_cache_ptr[x][2] = filter_level[2][0][0];
312
5.88M
            level_cache_ptr[x][3] = filter_level[3][0][0];
313
5.88M
        }
314
1.23M
        level_cache_ptr += b4_stride;
315
1.23M
    }
316
317
332k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, 0, uvtx,
318
332k
                      auv, luv, ss_hor, ss_ver);
319
332k
}
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
480k
{
335
480k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
336
480k
    const int bw4 = imin(iw - bx, b_dim[0]);
337
480k
    const int bh4 = imin(ih - by, b_dim[1]);
338
480k
    const int bx4 = bx & 31;
339
480k
    const int by4 = by & 31;
340
480k
    assert(bw4 >= 0 && bh4 >= 0);
341
342
480k
    if (bw4 && bh4) {
343
440k
        uint8_t (*level_cache_ptr)[4] = level_cache + by * b4_stride + bx;
344
2.45M
        for (int y = 0; y < bh4; y++) {
345
8.73M
            for (int x = 0; x < bw4; x++) {
346
6.71M
                level_cache_ptr[x][0] = filter_level[0][0][0];
347
6.71M
                level_cache_ptr[x][1] = filter_level[1][0][0];
348
6.71M
            }
349
2.01M
            level_cache_ptr += b4_stride;
350
2.01M
        }
351
352
440k
        mask_edges_inter(lflvl->filter_y, by4, bx4, bw4, bh4, skip,
353
440k
                         max_ytx, tx_masks, ay, ly);
354
440k
    }
355
356
480k
    if (!auv) return;
357
358
289k
    const int ss_ver = layout == DAV1D_PIXEL_LAYOUT_I420;
359
289k
    const int ss_hor = layout != DAV1D_PIXEL_LAYOUT_I444;
360
289k
    const int cbw4 = imin(((iw + ss_hor) >> ss_hor) - (bx >> ss_hor),
361
289k
                          (b_dim[0] + ss_hor) >> ss_hor);
362
289k
    const int cbh4 = imin(((ih + ss_ver) >> ss_ver) - (by >> ss_ver),
363
289k
                          (b_dim[1] + ss_ver) >> ss_ver);
364
289k
    assert(cbw4 >= 0 && cbh4 >= 0);
365
366
289k
    if (!cbw4 || !cbh4) return;
367
368
287k
    const int cbx4 = bx4 >> ss_hor;
369
287k
    const int cby4 = by4 >> ss_ver;
370
371
287k
    uint8_t (*level_cache_ptr)[4] =
372
287k
        level_cache + (by >> ss_ver) * b4_stride + (bx >> ss_hor);
373
1.20M
    for (int y = 0; y < cbh4; y++) {
374
3.52M
        for (int x = 0; x < cbw4; x++) {
375
2.60M
            level_cache_ptr[x][2] = filter_level[2][0][0];
376
2.60M
            level_cache_ptr[x][3] = filter_level[3][0][0];
377
2.60M
        }
378
915k
        level_cache_ptr += b4_stride;
379
915k
    }
380
381
287k
    mask_edges_chroma(lflvl->filter_uv, cby4, cbx4, cbw4, cbh4, skip, uvtx,
382
287k
                      auv, luv, ss_hor, ss_ver);
383
287k
}
384
385
56.2k
void dav1d_calc_eih(Av1FilterLUT *const lim_lut, const int filter_sharpness) {
386
    // set E/I/H values from loopfilter level
387
56.2k
    const int sharp = filter_sharpness;
388
3.65M
    for (int level = 0; level < 64; level++) {
389
3.59M
        int limit = level;
390
391
3.59M
        if (sharp > 0) {
392
2.21M
            limit >>= (sharp + 3) >> 2;
393
2.21M
            limit = imin(limit, 9 - sharp);
394
2.21M
        }
395
3.59M
        limit = imax(limit, 1);
396
397
3.59M
        lim_lut->i[level] = limit;
398
3.59M
        lim_lut->e[level] = 2 * (level + 2) + limit;
399
3.59M
    }
400
56.2k
    lim_lut->sharp[0] = (sharp + 3) >> 2;
401
56.2k
    lim_lut->sharp[1] = sharp ? 9 - sharp : 0xff;
402
56.2k
}
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
1.88M
{
409
1.88M
    const int base = iclip(iclip(base_lvl + lf_delta, 0, 63) + seg_delta, 0, 63);
410
411
1.88M
    if (!mr_delta) {
412
1.62M
        memset(lflvl_values, base, sizeof(*lflvl_values) * 8);
413
1.62M
    } else {
414
254k
        const int sh = base >= 32;
415
254k
        lflvl_values[0][0] = lflvl_values[0][1] =
416
254k
            iclip(base + (mr_delta->ref_delta[0] * (1 << sh)), 0, 63);
417
2.03M
        for (int r = 1; r < 8; r++) {
418
5.33M
            for (int m = 0; m < 2; m++) {
419
3.55M
                const int delta =
420
3.55M
                    mr_delta->mode_delta[m] + mr_delta->ref_delta[r];
421
3.55M
                lflvl_values[r][m] = iclip(base + (delta * (1 << sh)), 0, 63);
422
3.55M
            }
423
1.77M
        }
424
254k
    }
425
1.88M
}
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
1.09M
{
432
1.09M
    if (!base_lvl)
433
302k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * 8);
434
790k
    else
435
790k
        calc_lf_value(lflvl_values, base_lvl, lf_delta, seg_delta, mr_delta);
436
1.09M
}
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
133k
{
442
133k
    const int n_seg = hdr->segmentation.enabled ? 8 : 1;
443
444
133k
    if (!hdr->loopfilter.level_y[0] && !hdr->loopfilter.level_y[1]) {
445
13.8k
        memset(lflvl_values, 0, sizeof(*lflvl_values) * n_seg);
446
13.8k
        return;
447
13.8k
    }
448
449
119k
    const Dav1dLoopfilterModeRefDeltas *const mr_deltas =
450
119k
        hdr->loopfilter.mode_ref_delta_enabled ?
451
119k
        &hdr->loopfilter.mode_ref_deltas : NULL;
452
666k
    for (int s = 0; s < n_seg; s++) {
453
546k
        const Dav1dSegmentationData *const segd =
454
546k
            hdr->segmentation.enabled ? &hdr->segmentation.seg_data.d[s] : NULL;
455
456
546k
        calc_lf_value(lflvl_values[s][0], hdr->loopfilter.level_y[0],
457
546k
                      lf_delta[0], segd ? segd->delta_lf_y_v : 0, mr_deltas);
458
546k
        calc_lf_value(lflvl_values[s][1], hdr->loopfilter.level_y[1],
459
546k
                      lf_delta[hdr->delta.lf.multi ? 1 : 0],
460
546k
                      segd ? segd->delta_lf_y_h : 0, mr_deltas);
461
546k
        calc_lf_value_chroma(lflvl_values[s][2], hdr->loopfilter.level_u,
462
546k
                             lf_delta[hdr->delta.lf.multi ? 2 : 0],
463
546k
                             segd ? segd->delta_lf_u : 0, mr_deltas);
464
546k
        calc_lf_value_chroma(lflvl_values[s][3], hdr->loopfilter.level_v,
465
546k
                             lf_delta[hdr->delta.lf.multi ? 3 : 0],
466
546k
                             segd ? segd->delta_lf_v : 0, mr_deltas);
467
546k
    }
468
119k
}