Coverage Report

Created: 2026-05-16 06:28

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