Coverage Report

Created: 2026-09-02 06:43

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