Coverage Report

Created: 2026-08-31 06:20

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