Coverage Report

Created: 2026-10-28 06:12

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